-
Notifications
You must be signed in to change notification settings - Fork 0
/
atom.xml
500 lines (296 loc) · 396 KB
/
atom.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
<title>博客</title>
<link href="/atom.xml" rel="self"/>
<link href="http://www.shaoyong.online/"/>
<updated>2020-11-16T14:02:46.702Z</updated>
<id>http://www.shaoyong.online/</id>
<author>
<name>Shaoyong</name>
</author>
<generator uri="http://hexo.io/">Hexo</generator>
<entry>
<title>千万级数据拆分与迁移</title>
<link href="http://www.shaoyong.online/posts/47bc30b3/"/>
<id>http://www.shaoyong.online/posts/47bc30b3/</id>
<published>2020-11-13T13:50:18.876Z</published>
<updated>2020-11-16T14:02:46.702Z</updated>
<content type="html"><![CDATA[<p> 将数据从一张表中迁移到另一张表中,在数据量少的情况下很容易实现,而且方法也有很多,但当数据量到了百万、千万级时,不同方法在效率上会有很大差别。</p><a id="more"></a><h2 id="业务场景"><a href="#业务场景" class="headerlink" title="业务场景"></a>业务场景</h2><p>项目在运行时会存储实时数据,主表每秒插入2,3条数据,一条主数据对应10条左右明细数据,现在数据库中,主表1千万条,明细8千万;需求是要根据主表中的<code>type</code>字段进行分类,将主表和明细表拆再拆出2张表。</p><h2 id="实现"><a href="#实现" class="headerlink" title="实现"></a>实现</h2><p>项目在运行,实时会有数据存入,所以分为3个阶段;原表<code>alarm</code>为主表,<code>alarm_detail</code>为明细表;</p><p>1、将数据按类型从原表中导出为文件,再导入到对应的新建表中</p><p>2、项目暂停,执行替换sql,更新代码,重启项目</p><p>3、将在导入导出期间产生的数据再次按类型插入到新表中</p><h3 id="一、项目正常运行,代码未更新"><a href="#一、项目正常运行,代码未更新" class="headerlink" title="一、项目正常运行,代码未更新"></a>一、项目正常运行,代码未更新</h3><h4 id="复制alarm-与-alarm-detail-表"><a href="#复制alarm-与-alarm-detail-表" class="headerlink" title="复制alarm 与 alarm_detail 表"></a>复制alarm 与 alarm_detail 表</h4><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">CREATE TABLE alarm_copy1 LIKE alarm;</span><br><span class="line">CREATE TABLE alarm_detail_copy1 LIKE alarm_detail;</span><br></pre></td></tr></table></figure><h4 id="新建alarm-2表与明细表alarm-2-detail"><a href="#新建alarm-2表与明细表alarm-2-detail" class="headerlink" title="新建alarm_2表与明细表alarm_2_detail"></a>新建alarm_2表与明细表alarm_2_detail</h4><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line">CREATE TABLE `alarm_2` (</span><br><span class="line"> `id` bigint(20) NOT NULL AUTO_INCREMENT,</span><br><span class="line"> `alarmId` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '告警Id',</span><br><span class="line"> `type` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,</span><br><span class="line"> PRIMARY KEY (`id`) USING BTREE,</span><br><span class="line"> UNIQUE INDEX `alarmId`(`alarmId`) USING BTREE</span><br><span class="line">) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '主表' ROW_FORMAT = Dynamic;</span><br><span class="line"></span><br><span class="line">CREATE TABLE `alarm_2_detail` (</span><br><span class="line"> `id` bigint(20) NOT NULL AUTO_INCREMENT,</span><br><span class="line"> `iotId` bigint(20) NOT NULL,</span><br><span class="line"> `paramValue` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,</span><br><span class="line"> PRIMARY KEY (`id`) USING BTREE,</span><br><span class="line"> INDEX `iotId`(`iotId`) USING BTREE,</span><br><span class="line">CONSTRAINT `fk_iotId` FOREIGN KEY (`iotId`) REFERENCES `alarm_2` (`id`) ON DELETE CASCADE</span><br><span class="line">) ENGINE = InnoDB AUTO_INCREMENT = 0 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '明细表' ROW_FORMAT = Compact;</span><br></pre></td></tr></table></figure><h4 id="获取原表主键最大id"><a href="#获取原表主键最大id" class="headerlink" title="获取原表主键最大id"></a>获取原表主键最大id</h4><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">SELECT @maxId:=MAX(id) FROM alarm;</span><br></pre></td></tr></table></figure><h4 id="导出出A类型主数据,再导入新表"><a href="#导出出A类型主数据,再导入新表" class="headerlink" title="导出出A类型主数据,再导入新表"></a>导出出A类型主数据,再导入新表</h4><p><code>FIELDS TERMINATED BY ','</code>表示字段间用<code>,</code>分割</p><p><code>OPTIONALLY ENCLOSED BY '"'</code>表示所有字符用<code>"</code>包裹</p><p><code>ESCAPED BY '*'</code>表示用<code>*</code>代表转义字符</p><p><code>LINES TERMINATED BY '\r\n'</code>表示每条数据用空格加回车结束</p><figure class="highlight plain"><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">SELECT * FROM alarm WHERE id<@maxId AND type='A' INTO OUTFILE 'alarm_2.txt' FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"' ESCAPED BY '*' LINES TERMINATED BY '\r\n';</span><br><span class="line">#导入</span><br><span class="line">LOAD DATA INFILE 'alarm_2.txt' INTO TABLE alarm_2 FIELDS TERMINATED BY ',' ENCLOSED BY '"' ESCAPED BY '*' LINES TERMINATED BY '\r\n';</span><br></pre></td></tr></table></figure><h4 id="导出出A类型明细数据,再导入新表"><a href="#导出出A类型明细数据,再导入新表" class="headerlink" title="导出出A类型明细数据,再导入新表"></a>导出出A类型明细数据,再导入新表</h4><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">SELECT ad.* FROM alarm_detail ad WHERE EXISTS (SELECT iotId FROM alarm a WHERE ad.iotId=a.id) INTO OUTFILE 'alarm_2_detail.txt' FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"' ESCAPED BY '*' LINES TERMINATED BY '\r\n';</span><br><span class="line">LOAD DATA INFILE 'alarm_2_detail.txt' INTO TABLE alarm_2_detail FIELDS TERMINATED BY ',' ENCLOSED BY '"' ESCAPED BY '*' LINES TERMINATED BY '\r\n';</span><br></pre></td></tr></table></figure><h4 id="导出出B类型主数据,再导入copy表"><a href="#导出出B类型主数据,再导入copy表" class="headerlink" title="导出出B类型主数据,再导入copy表"></a>导出出B类型主数据,再导入copy表</h4><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">SELECT * FROM alarm WHERE id<@maxId AND type='A' INTO OUTFILE 'alarm_copy1.txt' FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"' ESCAPED BY '*' LINES TERMINATED BY '\r\n';</span><br><span class="line">LOAD DATA INFILE 'alarm_copy1.txt' INTO TABLE alarm_copy1 FIELDS TERMINATED BY ',' ENCLOSED BY '"' ESCAPED BY '*' LINES TERMINATED BY '\r\n';</span><br></pre></td></tr></table></figure><h4 id="导出出B类型明细数据,再导入新表"><a href="#导出出B类型明细数据,再导入新表" class="headerlink" title="导出出B类型明细数据,再导入新表"></a>导出出B类型明细数据,再导入新表</h4><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">SELECT ad.* FROM alarm_detail ad WHERE EXISTS (SELECT iotId FROM alarm_copy1 ac WHERE ac.iotId=ad.id) INTO OUTFILE 'alarm_detail_copy1.txt' FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"' ESCAPED BY '*' LINES TERMINATED BY '\r\n';</span><br><span class="line">LOAD DATA INFILE 'alarm_detail_copy1.txt' INTO TABLE alarm_detail_copy1 FIELDS TERMINATED BY ',' ENCLOSED BY '"' ESCAPED BY '*' LINES TERMINATED BY '\r\n';</span><br></pre></td></tr></table></figure><h3 id="二、项目暂停、更新代码"><a href="#二、项目暂停、更新代码" class="headerlink" title="二、项目暂停、更新代码"></a>二、项目暂停、更新代码</h3><p>项目需要暂停几分钟,修改表名并更新代码</p><h4 id="修改表名称"><a href="#修改表名称" class="headerlink" title="修改表名称"></a>修改表名称</h4><p>将*_copy1表名与原表互换</p><figure class="highlight plain"><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">ALTER TABLE alarm RENAME TO alarm_temp;</span><br><span class="line">ALTER TABLE alarm_detail RENAME TO alarm_detail_temp;</span><br><span class="line">ALTER TABLE alarm_copy1 RENAME TO alarm;</span><br><span class="line">ALTER TABLE alarm_detail_copy1 RENAME TO alarm_detail;</span><br><span class="line">ALTER TABLE alarm_temp RENAME TO alarm_copy1;</span><br><span class="line">ALTER TABLE alarm_detail_temp RENAME TO alarm_detail_copy1;</span><br></pre></td></tr></table></figure><h4 id="修改自增数"><a href="#修改自增数" class="headerlink" title="修改自增数"></a>修改自增数</h4><p>为了保证在新数据插入新表后不会与暂未拆分数据主键冲突,需要将所有表的自增值改为原表自增数大小,</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">#创建存储过程修改自增值</span><br><span class="line">DROP PROCEDURE IF EXISTS copy_auto_increment;</span><br><span class="line">CREATE PROCEDURE `copy_auto_increment`(IN `sourceTable` varchar(50),IN `targetTable` varchar(50))</span><br><span class="line">BEGIN</span><br><span class="line">DECLARE num BIGINT;</span><br><span class="line">DECLARE alterSql VARCHAR(250);</span><br><span class="line">SELECT AUTO_INCREMENT INTO num FROM information_schema.tables WHERE table_name = sourceTable AND table_schema = DATABASE();</span><br><span class="line">SET num=num+100;</span><br><span class="line">SET alterSql=CONCAT('ALTER TABLE ',targetTable,' AUTO_INCREMENT=',num);</span><br><span class="line">EXECUTE alterSql;</span><br><span class="line">END;</span><br></pre></td></tr></table></figure><p>修改<code>alarm</code>、<code>alarm_detail</code>、<code>alarm_2</code>、<code>alarm_2_detail</code>的自增数(大于原表目前的自增数值即可)</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">#调用</span><br><span class="line">CALL copy_auto_increment('iot_alarm_copy1','iot_alarm');</span><br><span class="line">CALL copy_auto_increment('iot_alarm_copy1','iot_alarm_fault');</span><br><span class="line">CALL copy_auto_increment('iot_alarm_detail_copy1','iot_alarm_detail');</span><br><span class="line">CALL copy_auto_increment('iot_alarm_detail_copy1','iot_alarm_detail_fault');</span><br></pre></td></tr></table></figure><h4 id="查询已拆分数据的最大id-并记录"><a href="#查询已拆分数据的最大id-并记录" class="headerlink" title="查询已拆分数据的最大id,并记录"></a>查询已拆分数据的最大id,并记录</h4><figure class="highlight plain"><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">SELECT @maxId:=MAX(a.id) MAXId FROM(</span><br><span class="line">SELECT MAX(id) id FROM iot_alarm</span><br><span class="line">UNION</span><br><span class="line">SELECT MAX(id) id FROM iot_alarm_fault)a;</span><br></pre></td></tr></table></figure><h3 id="三、代码更新完成,项目启动"><a href="#三、代码更新完成,项目启动" class="headerlink" title="三、代码更新完成,项目启动"></a>三、代码更新完成,项目启动</h3><p>现在在*_copy1表中还有未拆分的数据,现在再进行拆分</p><h4 id="创建拆分存储过程"><a href="#创建拆分存储过程" class="headerlink" title="创建拆分存储过程"></a>创建拆分存储过程</h4><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br></pre></td><td class="code"><pre><span class="line">DROP PROCEDURE IF EXISTS post_alarm_split;</span><br><span class="line">CREATE PROCEDURE `post_alarm_split`(IN `maxId` bigint)</span><br><span class="line">BEGIN</span><br><span class="line">-- 定义接收游标数据的变量 </span><br><span class="line">DECLARE done BOOLEAN DEFAULT 0;</span><br><span class="line">DECLARE var_id BIGINT DEFAULT 0;</span><br><span class="line">DECLARE var_alarmId VARCHAR(50);</span><br><span class="line">DECLARE var_type VARCHAR(50);</span><br><span class="line"></span><br><span class="line">DECLARE cur_alarm CURSOR FOR (SELECT id,alarmId,type FROM iot_alarm_copy1 WHERE id>=maxId ORDER BY id);</span><br><span class="line">#退出标志</span><br><span class="line">DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done = 1 ;</span><br><span class="line">OPEN cur_alarm;</span><br><span class="line"></span><br><span class="line">REPEAT</span><br><span class="line">FETCH cur_alarm INTO var_id,var_alarmId,var_type;</span><br><span class="line">IF NOT done THEN</span><br><span class="line">#A类</span><br><span class="line">IF var_type='A' THEN</span><br><span class="line">INSERT INTO alarm_2 VALUES(var_id,var_alarmId,var_type);</span><br><span class="line">INSERT INTO alarm_2_detail (SELECT id,iotId,paramValue FROM alarm_detail_copy1 WHERE iotId = var_id);</span><br><span class="line">#B类</span><br><span class="line">ELSE</span><br><span class="line">INSERT INTO alarm VALUES(var_id,var_alarmId,var_type);</span><br><span class="line">INSERT INTO alarm_detail (SELECT id,iotId,paramValue FROM alarm_detail_copy1 WHERE iotId = var_id);</span><br><span class="line">END IF;</span><br><span class="line">END IF;</span><br><span class="line">UNTIL done END REPEAT;</span><br><span class="line">CLOSE cur_alarm;</span><br><span class="line">END;</span><br></pre></td></tr></table></figure><h4 id="执行拆分"><a href="#执行拆分" class="headerlink" title="执行拆分"></a>执行拆分</h4><p><code>@maxId</code>为之前已拆分过数据的最大主键id+1</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">#后置拆分</span><br><span class="line">CALL post_alarm_split(@maxId);</span><br></pre></td></tr></table></figure><h2 id="总结"><a href="#总结" class="headerlink" title="总结"></a>总结</h2><p>1、这种拆分方式适合主键<code>id</code>自增的情况</p><p>2、项目重启后的拆分也可以使用导入导出的方式拆,重点是记录好已拆分的<code>id</code></p><p>3、利用导出导入的方式可以大大提高数据迁移的效率</p><p>4、如果预计某些表数据量会很大时,可以考虑在表创建时就进行分区、或分表</p><h3 id="备注"><a href="#备注" class="headerlink" title="备注"></a>备注</h3><p>导出时生成的文件在mysql的Data目录下,可以删除,节省服务器存储空间</p>]]></content>
<summary type="html">
<p> 将数据从一张表中迁移到另一张表中,在数据量少的情况下很容易实现,而且方法也有很多,但当数据量到了百万、千万级时,不同方法在效率上会有很大差别。</p>
</summary>
<category term="笔记" scheme="http://www.shaoyong.online/categories/%E7%AC%94%E8%AE%B0/"/>
<category term="Mysql" scheme="http://www.shaoyong.online/tags/Mysql/"/>
</entry>
<entry>
<title>Activiti6.0流程模型导入</title>
<link href="http://www.shaoyong.online/posts/73fc1757/"/>
<id>http://www.shaoyong.online/posts/73fc1757/</id>
<published>2020-04-12T07:19:33.628Z</published>
<updated>2020-04-12T10:51:52.056Z</updated>
<content type="html"><![CDATA[<p>Activiti是一个开源的工作流程引擎,而在流程引擎上执行的便是符合BPMN2.0规范的流程模型。在我们系统集成Activiti后,自然需要提供流程模型的导入功能。</p><a id="more"></a><h1 id="导入模型"><a href="#导入模型" class="headerlink" title="导入模型"></a>导入模型</h1><p>思路:后台接受前端传来的文件,读取为XML文件,然后转为BpmnModel,再获取其中的流程数据,最后保存为Model。</p><h1 id="POJO"><a href="#POJO" class="headerlink" title="POJO"></a>POJO</h1><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * 流程模型基本参数</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="meta">@Data</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">ModelParam</span></span>{</span><br><span class="line"> <span class="meta">@ApiModelProperty</span>(value = <span class="string">"模型名称"</span>,required = <span class="keyword">true</span>)</span><br><span class="line"> <span class="keyword">private</span> String name;</span><br><span class="line"> <span class="meta">@ApiModelProperty</span>(value = <span class="string">"模型key"</span>,required = <span class="keyword">true</span>)</span><br><span class="line"> <span class="keyword">private</span> String key;</span><br><span class="line"> <span class="meta">@ApiModelProperty</span>(<span class="string">"模型描述"</span>)</span><br><span class="line"> <span class="keyword">private</span> String description;</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h2 id="controller"><a href="#controller" class="headerlink" title="controller"></a>controller</h2><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@PostMapping</span>(<span class="string">"model/import"</span>)</span><br><span class="line"><span class="meta">@ApiOperation</span>(value = <span class="string">"导入模型"</span>)</span><br><span class="line"><span class="meta">@ResponseBody</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> AjaxResult <span class="title">importModel</span><span class="params">(HttpServletRequest request)</span></span>{</span><br><span class="line">List<MultipartFile> file = ((MultipartHttpServletRequest) request).getFiles(<span class="string">"file"</span>);</span><br><span class="line"><span class="keyword">if</span> (Collections.isEmpty(file)){</span><br><span class="line"><span class="keyword">throw</span> <span class="keyword">new</span> CustomException(<span class="string">"文件为空,上传失败!"</span>);</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> modelService.importModelFiles(file);</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h2 id="ServiceImpl"><a href="#ServiceImpl" class="headerlink" title="ServiceImpl"></a>ServiceImpl</h2><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Override</span></span><br><span class="line"><span class="meta">@Transactional</span>(rollbackFor = Exception.class)</span><br><span class="line"><span class="function"><span class="keyword">public</span> AjaxResult <span class="title">importModelFiles</span><span class="params">(List<MultipartFile> modelFiles)</span> </span>{</span><br><span class="line"> <span class="keyword">try</span> {</span><br><span class="line"> <span class="keyword">for</span> (MultipartFile modelFile : modelFiles) {</span><br><span class="line"></span><br><span class="line"> <span class="keyword">byte</span>[] bytes = modelFile.getBytes();</span><br><span class="line"> String xml = <span class="keyword">new</span> String(bytes, Charsets.UTF_8);</span><br><span class="line"> <span class="comment">//创建转换对象</span></span><br><span class="line"> BpmnXMLConverter converter = <span class="keyword">new</span> BpmnXMLConverter();</span><br><span class="line"> XMLInputFactory factory = XMLInputFactory.newInstance();</span><br><span class="line"> <span class="comment">// 字节方式</span></span><br><span class="line"> XMLStreamReader reader = factory.createXMLStreamReader(<span class="keyword">new</span> ByteArrayInputStream(xml.getBytes()));</span><br><span class="line"> <span class="comment">//将xml文件转换成BpmnModel</span></span><br><span class="line"> BpmnModel bpmnModel = converter.convertToBpmnModel(reader);</span><br><span class="line"> <span class="comment">//流程数据</span></span><br><span class="line"> Process process = bpmnModel.getMainProcess();</span><br><span class="line"> String modelKey = process.getId();</span><br><span class="line"> <span class="comment">//判断导入的模型key是否重复</span></span><br><span class="line"> List<Model> modelList = repositoryService.createModelQuery().modelKey(modelKey).list();</span><br><span class="line"> <span class="keyword">if</span> (CollectionUtils.isNotEmpty(modelList)) {</span><br><span class="line"> <span class="keyword">return</span> AjaxResult.error(modelFile.getOriginalFilename() + <span class="string">",模型Key已存在,导入失败!"</span>);</span><br><span class="line"> }</span><br><span class="line"> ModelParam modelParam = <span class="keyword">new</span> ModelParam();</span><br><span class="line"> modelParam.setKey(process.getId());</span><br><span class="line"> modelParam.setName(process.getName());</span><br><span class="line"> modelParam.setDescription(process.getDocumentation());</span><br><span class="line"> <span class="comment">//创建模型</span></span><br><span class="line"> String modelId =<span class="keyword">this</span>.createModel(modelParam);</span><br><span class="line"> <span class="comment">//转为json格式保存</span></span><br><span class="line"> BpmnJsonConverter jsonConverter = <span class="keyword">new</span> BpmnJsonConverter();</span><br><span class="line"> ObjectNode jsonNodes = jsonConverter.convertToJson(bpmnModel);</span><br><span class="line"> repositoryService.addModelEditorSource(modelId, jsonNodes.toString().getBytes(Charsets.UTF_8));</span><br><span class="line"> }</span><br><span class="line"> } <span class="keyword">catch</span> (IOException | XMLStreamException e) {</span><br><span class="line"> logger.error(<span class="string">"模型导入异常:{}"</span>, e.getMessage());</span><br><span class="line"> <span class="keyword">throw</span> <span class="keyword">new</span> CustomException(<span class="string">"导入异常,请联系管理员!"</span>);</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> AjaxResult.success(<span class="string">"导入成功!"</span>);</span><br><span class="line">}</span><br></pre></td></tr></table></figure><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment">* 创建模型</span></span><br><span class="line"><span class="comment">*/</span></span><br><span class="line"><span class="function"><span class="keyword">private</span> String <span class="title">createModel</span><span class="params">(ModelParam modelParam)</span> </span>{</span><br><span class="line"> <span class="keyword">if</span> (StringUtils.isBlank(modelParam.getKey()) || StringUtils.isBlank(modelParam.getName())) {</span><br><span class="line"> <span class="keyword">return</span> AjaxResult.error(<span class="string">"参数错误,模型创建失败!"</span>);</span><br><span class="line"> }</span><br><span class="line"> List<Model> list = <span class="keyword">this</span>.repositoryService.createModelQuery().modelKey(modelParam.getKey()).list();</span><br><span class="line"> <span class="keyword">if</span> (CollectionUtils.isNotEmpty(list)) {</span><br><span class="line"> <span class="keyword">return</span> AjaxResult.error(<span class="string">"模型Key重复!"</span>);</span><br><span class="line"> }</span><br><span class="line"> Model model = <span class="keyword">this</span>.repositoryService.newModel();</span><br><span class="line"> ObjectNode modelNode = objectMapper.createObjectNode();</span><br><span class="line"> modelNode.put(ModelDataJsonConstants.MODEL_NAME, modelParam.getName());</span><br><span class="line"> modelNode.put(ModelDataJsonConstants.MODEL_DESCRIPTION, modelParam.getDescription());</span><br><span class="line"> modelNode.put(ModelDataJsonConstants.MODEL_REVISION, <span class="number">1</span>);</span><br><span class="line"> model.setName(modelParam.getName());</span><br><span class="line"> model.setKey(modelParam.getKey());</span><br><span class="line"> model.setMetaInfo(modelNode.toString());</span><br><span class="line"> <span class="keyword">this</span>.repositoryService.saveModel(model);</span><br><span class="line"> <span class="keyword">this</span>.createObjectNode(model);</span><br><span class="line"> logger.info(<span class="string">"创建模型结束,返回模型ID:{}"</span>, model.getId());</span><br><span class="line"> <span class="keyword">return</span> model.getId();</span><br><span class="line">}</span><br></pre></td></tr></table></figure><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * 创建模型时完善ModelEditorSource</span></span><br><span class="line"><span class="comment"> *</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@param</span> model</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="meta">@SuppressWarnings</span>(<span class="string">"deprecation"</span>)</span><br><span class="line"><span class="function"><span class="keyword">private</span> <span class="keyword">void</span> <span class="title">createObjectNode</span><span class="params">(Model model)</span> </span>{</span><br><span class="line"> logger.info(<span class="string">"创建模型完善ModelEditorSource入参模型ID:{}"</span>, model.getId());</span><br><span class="line"> ObjectNode editorNode = objectMapper.createObjectNode();</span><br><span class="line"> editorNode.put(<span class="string">"id"</span>, <span class="string">"canvas"</span>);</span><br><span class="line"> editorNode.put(<span class="string">"resourceId"</span>, <span class="string">"canvas"</span>);</span><br><span class="line"> ObjectNode stencilSetNode = objectMapper.createObjectNode();</span><br><span class="line"> stencilSetNode.put(<span class="string">"namespace"</span>, <span class="string">"http://b3mn.org/stencilset/bpmn2.0#"</span>);</span><br><span class="line"> ObjectNode propertiesNode = objectMapper.createObjectNode();</span><br><span class="line"> propertiesNode.put(<span class="string">"process_id"</span>, model.getKey());</span><br><span class="line"> propertiesNode.put(<span class="string">"name"</span>, model.getName());</span><br><span class="line"> editorNode.put(<span class="string">"properties"</span>, propertiesNode);</span><br><span class="line"> editorNode.put(<span class="string">"stencilset"</span>, stencilSetNode);</span><br><span class="line"> <span class="keyword">try</span> {</span><br><span class="line"> <span class="keyword">this</span>.repositoryService.addModelEditorSource(model.getId(), editorNode.toString().getBytes(Charsets.UTF_8));</span><br><span class="line"> } <span class="keyword">catch</span> (Exception e) {</span><br><span class="line"> logger.info(<span class="string">"创建模型时完善ModelEditorSource服务异常:{}"</span>, e);</span><br><span class="line"> <span class="keyword">throw</span> <span class="keyword">new</span> CustomException(<span class="string">"模型创建失败"</span>);</span><br><span class="line"> }</span><br><span class="line"> logger.info(<span class="string">"创建模型完善ModelEditorSource结束"</span>);</span><br><span class="line">}</span><br></pre></td></tr></table></figure>]]></content>
<summary type="html">
<p>Activiti是一个开源的工作流程引擎,而在流程引擎上执行的便是符合BPMN2.0规范的流程模型。在我们系统集成Activiti后,自然需要提供流程模型的导入功能。</p>
</summary>
<category term="笔记" scheme="http://www.shaoyong.online/categories/%E7%AC%94%E8%AE%B0/"/>
<category term="Java" scheme="http://www.shaoyong.online/tags/Java/"/>
<category term="Activiti6.0" scheme="http://www.shaoyong.online/tags/Activiti6-0/"/>
</entry>
<entry>
<title>编写一个简单的EasyExcel枚举类转换器</title>
<link href="http://www.shaoyong.online/posts/a0a2f7b9/"/>
<id>http://www.shaoyong.online/posts/a0a2f7b9/</id>
<published>2020-04-11T13:30:30.187Z</published>
<updated>2020-05-13T16:07:28.623Z</updated>
<content type="html"><![CDATA[<p>最近项目中用到了阿里的<a href="https://github.com/alibaba/easyexcel" target="_blank" rel="noopener">EasyExcel</a>,一个简单方便读写excel的工具。</p><a id="more"></a><h1 id="需求场景"><a href="#需求场景" class="headerlink" title="需求场景"></a>需求场景</h1><p>在项目中会定义一些枚举类来保存一些状态值,在存储进数据库时保存的是code,而我们在生成excel时需要展示对应的值。</p><h1 id="代码实现"><a href="#代码实现" class="headerlink" title="代码实现"></a>代码实现</h1><h2 id="原"><a href="#原" class="headerlink" title="原"></a>原</h2><p>需要写入excel的对象</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Data</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">TestExcel</span> </span>{</span><br><span class="line"></span><br><span class="line"> <span class="comment">/**</span></span><br><span class="line"><span class="comment"> * 状态</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"> <span class="meta">@ExcelProperty</span>(value = <span class="string">"状态"</span>,converter = StatusEnumConvert.class)</span><br><span class="line"> <span class="keyword">private</span> String status;</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>枚举类</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">enum</span> StatusEnum {</span><br><span class="line"> WAIT_COMMIT(<span class="string">"1"</span>,<span class="string">"待提交"</span>),</span><br><span class="line"> WAIT_AUDIT(<span class="string">"2"</span>,<span class="string">"待审核"</span>),</span><br><span class="line"> AUDITED(<span class="string">"3"</span>,<span class="string">"已审核"</span>),</span><br><span class="line"> RETURNED(<span class="string">"4"</span>,<span class="string">"已退回"</span>);</span><br><span class="line"></span><br><span class="line"> <span class="keyword">private</span> <span class="keyword">final</span> String code;</span><br><span class="line"> <span class="keyword">private</span> <span class="keyword">final</span> String info;</span><br><span class="line"></span><br><span class="line"> StatusEnum(String code, String info)</span><br><span class="line"> {</span><br><span class="line"> <span class="keyword">this</span>.code = code;</span><br><span class="line"> <span class="keyword">this</span>.info = info;</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">public</span> String <span class="title">getCode</span><span class="params">()</span></span></span><br><span class="line"><span class="function"> </span>{</span><br><span class="line"> <span class="keyword">return</span> code;</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">public</span> String <span class="title">getInfo</span><span class="params">()</span></span></span><br><span class="line"><span class="function"> </span>{</span><br><span class="line"> <span class="keyword">return</span> info;</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="comment">/**</span></span><br><span class="line"><span class="comment"> * 根据code获取info</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> String <span class="title">getInfoByCode</span><span class="params">(String code)</span></span>{</span><br><span class="line"> <span class="keyword">for</span> (StatusEnum statusEnum : StatusEnum.values()) {</span><br><span class="line"> <span class="keyword">if</span> (statusEnum.getCode().equals(code)){</span><br><span class="line"> <span class="keyword">return</span> statusEnum.getInfo();</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> <span class="keyword">null</span>;</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> String <span class="title">getCodeByInfo</span><span class="params">(String info)</span></span>{</span><br><span class="line"> <span class="keyword">for</span> (StatusEnum statusEnum : StatusEnum.values()) {</span><br><span class="line"> <span class="keyword">if</span> (statusEnum.getInfo().equals(info)){</span><br><span class="line"> <span class="keyword">return</span> statusEnum.getCode();</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> <span class="keyword">null</span>;</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>转换器</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">StatusEnumConvert</span> <span class="keyword">implements</span> <span class="title">Converter</span><<span class="title">String</span>> </span>{</span><br><span class="line"></span><br><span class="line"> <span class="meta">@Override</span></span><br><span class="line"> <span class="function"><span class="keyword">public</span> Class <span class="title">supportJavaTypeKey</span><span class="params">()</span> </span>{</span><br><span class="line"> <span class="keyword">return</span> String.class;</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="meta">@Override</span></span><br><span class="line"> <span class="function"><span class="keyword">public</span> CellDataTypeEnum <span class="title">supportExcelTypeKey</span><span class="params">()</span> </span>{</span><br><span class="line"> <span class="keyword">return</span> CellDataTypeEnum.STRING;</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="meta">@Override</span></span><br><span class="line"> <span class="function"><span class="keyword">public</span> String <span class="title">convertToJavaData</span><span class="params">(CellData cellData, ExcelContentProperty excelContentProperty, GlobalConfiguration globalConfiguration)</span> <span class="keyword">throws</span> Exception </span>{</span><br><span class="line"> String info = cellData.toString();</span><br><span class="line"> <span class="keyword">return</span> StatusEnum.getCodeByInfo(info);</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="meta">@Override</span></span><br><span class="line"> <span class="function"><span class="keyword">public</span> CellData <span class="title">convertToExcelData</span><span class="params">(String s, ExcelContentProperty excelContentProperty, GlobalConfiguration globalConfiguration)</span> <span class="keyword">throws</span> Exception </span>{</span><br><span class="line"> <span class="keyword">return</span> <span class="keyword">new</span> CellData(Objects.requireNonNull(StatusEnum.getInfoByCode(s)));</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure><hr><p>应网友反馈,使用注解和反射改进了转换器,提高复用性;</p><h2 id="改进后"><a href="#改进后" class="headerlink" title="改进后"></a>改进后</h2><p>先自定义一个注解</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Target</span>(ElementType.FIELD)</span><br><span class="line"><span class="meta">@Retention</span>(RetentionPolicy.RUNTIME)</span><br><span class="line"><span class="keyword">public</span> <span class="meta">@interface</span> TargetEnum {</span><br><span class="line"> Class<? extends Enum> targetEnum();</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>需要转换的枚举类</p><p>不再需要<code>getCodeByInfo()</code>与<code>getInfoById()</code>方法</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">enum</span> StatusEnum implements GetEnum {</span><br><span class="line"> WAIT_COMMIT(<span class="string">"1"</span>,<span class="string">"待提交"</span>),</span><br><span class="line"> WAIT_AUDIT(<span class="string">"2"</span>,<span class="string">"待审核"</span>),</span><br><span class="line"> AUDITED(<span class="string">"3"</span>,<span class="string">"已审核"</span>),</span><br><span class="line"> RETURNED(<span class="string">"4"</span>,<span class="string">"已退回"</span>);</span><br><span class="line"></span><br><span class="line"> <span class="keyword">private</span> <span class="keyword">final</span> String code;</span><br><span class="line"> <span class="keyword">private</span> <span class="keyword">final</span> String info;</span><br><span class="line"></span><br><span class="line"> StatusEnum(String code, String info)</span><br><span class="line"> {</span><br><span class="line"> <span class="keyword">this</span>.code = code;</span><br><span class="line"> <span class="keyword">this</span>.info = info;</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">public</span> String <span class="title">getCode</span><span class="params">()</span></span></span><br><span class="line"><span class="function"> </span>{</span><br><span class="line"> <span class="keyword">return</span> code;</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">public</span> String <span class="title">getInfo</span><span class="params">()</span></span></span><br><span class="line"><span class="function"> </span>{</span><br><span class="line"> <span class="keyword">return</span> info;</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>需要写入excel的对象</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Data</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">TestExcel</span> </span>{</span><br><span class="line"> <span class="comment">//加上自定义注解,并写上对应的枚举类作为参数</span></span><br><span class="line"> <span class="meta">@TargetEnum</span>(targetEnum = StatusEnum.class)</span><br><span class="line"> <span class="meta">@ExcelProperty</span>(value = <span class="string">"状态"</span>,converter = StatusEnumConverter.class)</span><br><span class="line"> <span class="keyword">private</span> String status;</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>修改后的转换器</p><p>利用反射获取字段上注解的枚举类型,然后调用<code>get..()</code>方法取值</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">StatusEnumConverter</span> <span class="keyword">implements</span> <span class="title">Converter</span><<span class="title">String</span>> </span>{</span><br><span class="line"> <span class="meta">@Override</span></span><br><span class="line"> <span class="function"><span class="keyword">public</span> Class <span class="title">supportJavaTypeKey</span><span class="params">()</span> </span>{</span><br><span class="line"> <span class="keyword">return</span> String.class;</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="meta">@Override</span></span><br><span class="line"> <span class="function"><span class="keyword">public</span> CellDataTypeEnum <span class="title">supportExcelTypeKey</span><span class="params">()</span> </span>{</span><br><span class="line"> <span class="keyword">return</span> CellDataTypeEnum.STRING;</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="meta">@Override</span></span><br><span class="line"> <span class="function"><span class="keyword">public</span> String <span class="title">convertToJavaData</span><span class="params">(CellData cellData, ExcelContentProperty excelContentProperty, GlobalConfiguration globalConfiguration)</span> <span class="keyword">throws</span> Exception </span>{</span><br><span class="line"> String code=<span class="string">""</span>;</span><br><span class="line"> String info = cellData.toString();</span><br><span class="line"> Field field = excelContentProperty.getField();</span><br><span class="line"> TargetEnum annotation = field.getDeclaredAnnotation(TargetEnum.class);</span><br><span class="line"> Class clazz = annotation.targetEnum();</span><br><span class="line"> Object[] enumConstants = clazz.getEnumConstants();</span><br><span class="line"> Method getInfo = clazz.getMethod(<span class="string">"getInfo"</span>);</span><br><span class="line"> Method getCode = clazz.getMethod(<span class="string">"getCode"</span>);</span><br><span class="line"> <span class="keyword">for</span> (Object enumConstant : enumConstants) {</span><br><span class="line"> <span class="keyword">if</span> (getInfo.invoke(enumConstant, <span class="keyword">null</span>).equals(info)) {</span><br><span class="line"> code = (String) getCode.invoke(enumConstant, <span class="keyword">null</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 class="keyword">return</span> code;</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="meta">@Override</span></span><br><span class="line"> <span class="function"><span class="keyword">public</span> CellData <span class="title">convertToExcelData</span><span class="params">(String s, ExcelContentProperty excelContentProperty, GlobalConfiguration globalConfiguration)</span> <span class="keyword">throws</span> Exception </span>{</span><br><span class="line"> String info = <span class="string">""</span>;</span><br><span class="line"> Field field = excelContentProperty.getField();</span><br><span class="line"> TargetEnum annotation = field.getDeclaredAnnotation(TargetEnum.class);</span><br><span class="line"> Class clazz = annotation.targetEnum();</span><br><span class="line"> Object[] enumConstants = clazz.getEnumConstants();</span><br><span class="line"> Method getInfo = clazz.getMethod(<span class="string">"getInfo"</span>);</span><br><span class="line"> Method getCode = clazz.getMethod(<span class="string">"getCode"</span>);</span><br><span class="line"> <span class="keyword">for</span> (Object enumConstant : enumConstants) {</span><br><span class="line"> <span class="keyword">if</span> (getCode.invoke(enumConstant, <span class="keyword">null</span>).equals(s)) {</span><br><span class="line"> info = (String) getInfo.invoke(enumConstant, <span class="keyword">null</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 class="keyword">return</span> <span class="keyword">new</span> CellData(info);</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>调用</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">EasyExcel.write(filePath,TestExcel.class).sheet(<span class="string">"枚举转换器"</span>).doWrite(dataList());</span><br></pre></td></tr></table></figure><h1 id="效果"><a href="#效果" class="headerlink" title="效果"></a>效果</h1><p><img src="https://imagebed.shaoyong.online/images/2020_04_11/1.png" alt></p>]]></content>
<summary type="html">
<p>最近项目中用到了阿里的<a href="https://github.com/alibaba/easyexcel" target="_blank" rel="noopener">EasyExcel</a>,一个简单方便读写excel的工具。</p>
</summary>
<category term="笔记" scheme="http://www.shaoyong.online/categories/%E7%AC%94%E8%AE%B0/"/>
<category term="Java" scheme="http://www.shaoyong.online/tags/Java/"/>
<category term="EasyExcel" scheme="http://www.shaoyong.online/tags/EasyExcel/"/>
</entry>
<entry>
<title>使用微信测试账号实现web端扫码登录</title>
<link href="http://www.shaoyong.online/posts/78864db2/"/>
<id>http://www.shaoyong.online/posts/78864db2/</id>
<published>2019-11-05T07:12:39.456Z</published>
<updated>2020-11-13T13:52:25.366Z</updated>
<content type="html"><![CDATA[<p>一般网站应用使用微信扫码登录使用的是<a href="https://developers.weixin.qq.com/doc/oplatform/Mobile_App/Resource_Center_Homepage.html" target="_blank" rel="noopener">微信开放平台</a>的接口,但注册开放平台需要提供企业信息,而且开放平台并没有提供测试账号,个人想要直接通过开放平台实现微信授权登录是不可行的。</p><p>微信在公众号中提供了<a href="https://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=sandbox/login" target="_blank" rel="noopener">测试账号</a>,我们可以通过公众号实现微信授权;</p><a id="more"></a><p><img src="https://imagebed.shaoyong.online/images/2019_11_5/1.png" alt="请求过程"></p><h1 id="准备工作"><a href="#准备工作" class="headerlink" title="准备工作"></a>准备工作</h1><p>1.申请微信公众号测试账号</p><p>2.设置授权回调页面地址</p><p><img src="https://imagebed.shaoyong.online/images/2019_11_5/2.png" alt></p><p><img src="https://imagebed.shaoyong.online/images/2019_11_5/3.png" alt></p><p>3.内网穿透</p><p> 可以使用<a href="https://natapp.cn" target="_blank" rel="noopener">natapp</a>实现内网穿透</p><p>4.引入依赖</p><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"><!--WeChat公众号--></span></span><br><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.github.binarywang<span class="tag"></<span class="name">groupId</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">artifactId</span>></span>weixin-java-mp<span class="tag"></<span class="name">artifactId</span>></span></span><br><span class="line"><span class="tag"></<span class="name">dependency</span>></span></span><br></pre></td></tr></table></figure><h1 id="代码实现"><a href="#代码实现" class="headerlink" title="代码实现"></a>代码实现</h1><p>jsp页面</p><figure class="highlight"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br></pre></td><td class="code"><pre><span class="line"><%@ page language=<span class="string">"java"</span> contentType=<span class="string">"text/html; charset=UTF-8"</span> pageEncoding=<span class="string">"UTF-8"</span> %></span><br><span class="line"><html></span><br><span class="line"><head></span><br><span class="line"> <script type="text/javascript" src="${pageContext.request.contextPath}/js/jquery-1.8.3.js"></script></span><br><span class="line"> <script type="text/javascript" src="${pageContext.request.contextPath}/js/jquery.qrcode.min.js"></script></span><br><span class="line"> <script></span><br><span class="line"> <span class="comment">//二维码边长</span></span><br><span class="line"> <span class="keyword">var</span> CODE_SIDE=<span class="number">200</span>;</span><br><span class="line"> <span class="keyword">var</span> timer;</span><br><span class="line"> $(function () {</span><br><span class="line"> reload_qrCode();</span><br><span class="line"> });</span><br><span class="line"></span><br><span class="line"> <span class="comment">//重新加载二维码</span></span><br><span class="line"> <span class="function">function <span class="title">reload_qrCode</span><span class="params">()</span> </span>{</span><br><span class="line"> <span class="comment">//清空上次生成的二维码</span></span><br><span class="line"> $(<span class="string">"#qrcode"</span>).html(<span class="string">""</span>);</span><br><span class="line"> <span class="comment">//清除定时器</span></span><br><span class="line"> clearInterval(timer);</span><br><span class="line"> $.get(<span class="string">"${pageContext.request.contextPath}/wx/authorization?"</span> + <span class="keyword">new</span> Date(), function (data) {</span><br><span class="line"> console.info(data.url);</span><br><span class="line"> <span class="comment">//生成二维码</span></span><br><span class="line"> $(<span class="string">"#qrcode"</span>).qrcode({</span><br><span class="line"> render: <span class="string">"canvas"</span>,</span><br><span class="line"> width: CODE_SIDE,</span><br><span class="line"> height: CODE_SIDE,</span><br><span class="line"> text: data.url</span><br><span class="line"> });</span><br><span class="line"> add_icon(<span class="string">"Wechat.png"</span>,<span class="number">72</span>,<span class="number">88</span>);</span><br><span class="line"> timer = setInterval(function () {</span><br><span class="line"> ajax_wx_login_status(data.uuid);</span><br><span class="line"> }, <span class="number">1000</span>);</span><br><span class="line"> },<span class="string">"json"</span>);</span><br><span class="line"> }</span><br><span class="line"> <span class="comment">//轮询登录状态</span></span><br><span class="line"> <span class="function">function <span class="title">ajax_wx_login_status</span><span class="params">(uuid)</span> </span>{</span><br><span class="line"> $.post(<span class="string">"${pageContext.request.contextPath}/wx/checkLogin"</span>,</span><br><span class="line"> {uuid: uuid},</span><br><span class="line"> function (res) {</span><br><span class="line"> <span class="keyword">if</span> (res.status == <span class="number">200</span>) { <span class="comment">//登录状态200,登录成功</span></span><br><span class="line"> <span class="comment">//进行相应业务代码的编写,或者直接进行页面跳转.</span></span><br><span class="line"> <span class="comment">//alert("登录成功");</span></span><br><span class="line"> clearInterval(timer);</span><br><span class="line"> window.location.href = <span class="string">"${pageContext.request.contextPath}/index"</span>; <span class="comment">//页面跳转</span></span><br><span class="line"> }<span class="keyword">if</span> (res.status==<span class="number">402</span>){</span><br><span class="line"> clearInterval(timer);</span><br><span class="line"> console.info(<span class="string">"二维码过期"</span>);</span><br><span class="line"> <span class="keyword">var</span> context = $(<span class="string">"#qrcode canvas"</span>)[<span class="number">0</span>].getContext(<span class="string">'2d'</span>);</span><br><span class="line"> context.fillStyle=<span class="string">'rgba(160, 160, 160, 0.8)'</span>;</span><br><span class="line"> context.fillRect(<span class="number">0</span>,<span class="number">0</span>,CODE_SIDE,CODE_SIDE);</span><br><span class="line"> context.fillStyle=<span class="string">'rgba(0, 0, 0)'</span>;</span><br><span class="line"> add_icon(<span class="string">"reload.png"</span>,<span class="number">48</span>,<span class="number">41</span>);</span><br><span class="line"> context.font=<span class="string">"14px Arial"</span>;</span><br><span class="line"> context.fillText(<span class="string">"二维码过期,请刷新"</span>,<span class="number">45</span>,<span class="number">140</span>);</span><br><span class="line"> }</span><br><span class="line"> }, <span class="string">"JSON"</span>);</span><br><span class="line"> }</span><br><span class="line"> <span class="comment">//在二维码中间加入微信图标</span></span><br><span class="line"> <span class="function">function <span class="title">add_icon</span><span class="params">(image_name, height, width)</span> </span>{</span><br><span class="line"> <span class="keyword">var</span> image = <span class="keyword">new</span> Image();</span><br><span class="line"> image.src=<span class="string">"${pageContext.request.contextPath}/images/"</span>+image_name;</span><br><span class="line"> <span class="keyword">var</span> context = $(<span class="string">"#qrcode canvas"</span>)[<span class="number">0</span>].getContext(<span class="string">'2d'</span>);</span><br><span class="line"> $(image).load(function(){</span><br><span class="line"> context.drawImage(image,(CODE_SIDE-width)/<span class="number">2</span>,(CODE_SIDE-height)/<span class="number">2</span>);</span><br><span class="line"> });</span><br><span class="line"> }</span><br><span class="line"> </script></span><br><span class="line"></head></span><br><span class="line"><body></span><br><span class="line"><div id="qrcode" onclick="reload_qrCode()"></div></span><br><span class="line"></body></span><br><span class="line"></html></span><br></pre></td></tr></table></figure><p>controller</p><p>前端发起请求到后端,后端生成带uuid的授权链接,返回链接与uuid到前端页面,<br>并将uuid作为key存入redis中,前端页面生成二维码,用户扫描二维码,授权登录,微信回调当前接口<br>传来uuid与code,通过code再调用微信接口获得用户信息,将用户的openid或者user对象作为value保存到redis和数据库中,<br>前端获得二维码图片后轮询redis,查看redis中是否有user对象或openid,有则跳转,实现扫码登录</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Controller</span></span><br><span class="line"><span class="meta">@RequestMapping</span>(<span class="string">"/wx"</span>)</span><br><span class="line"><span class="meta">@Slf</span>4j</span><br><span class="line"><span class="meta">@PropertySource</span>(value = <span class="string">"classpath:conf/wx.properties"</span>, ignoreResourceNotFound = <span class="keyword">true</span>)</span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">WxController</span> </span>{</span><br><span class="line"></span><br><span class="line"> <span class="meta">@Autowired</span></span><br><span class="line"> <span class="keyword">private</span> WxMpService wxMpService;</span><br><span class="line"> <span class="meta">@Autowired</span></span><br><span class="line"> <span class="keyword">private</span> JedisClient jedisClient;</span><br><span class="line"> <span class="meta">@Autowired</span></span><br><span class="line"> <span class="keyword">private</span> BuyerService buyerService;</span><br><span class="line"> <span class="comment">/**</span></span><br><span class="line"><span class="comment"> * redis中保存登录用uuid的前缀</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"> <span class="keyword">private</span> <span class="keyword">static</span> <span class="keyword">final</span> String REDIS_LOGIN_UUID_PRE = <span class="string">"LOGIN_UUID"</span>;</span><br><span class="line"> <span class="comment">/**</span></span><br><span class="line"><span class="comment"> * uuid有效时长/二维码有效期</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"> <span class="keyword">private</span> <span class="keyword">static</span> <span class="keyword">final</span> <span class="keyword">int</span> LOGIN_EXPIRE = <span class="number">15</span>;</span><br><span class="line"> <span class="comment">/**</span></span><br><span class="line"><span class="comment"> * 外网地址</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"> <span class="meta">@Value</span>(<span class="string">"XXXXXXX.nat300.top"</span>)</span><br><span class="line"> <span class="keyword">private</span> String URL;</span><br><span class="line"></span><br><span class="line"> <span class="meta">@GetMapping</span>(<span class="string">"/portal"</span>)</span><br><span class="line"> <span class="meta">@ResponseBody</span></span><br><span class="line"> <span class="function"><span class="keyword">public</span> String <span class="title">portal</span><span class="params">(String echostr, String timestamp, String nonce, String signature)</span> </span>{</span><br><span class="line"> log.info(<span class="string">"WeChat校验"</span>);</span><br><span class="line"> <span class="keyword">if</span> (!wxMpService.checkSignature(timestamp, nonce, signature)) {</span><br><span class="line"> <span class="comment">// 消息签名不正确,说明不是公众平台发过来的消息</span></span><br><span class="line"> log.warn(<span class="string">"非法请求"</span>);</span><br><span class="line"> <span class="keyword">return</span> <span class="string">"false"</span>;</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">if</span> (StringUtils.isNotBlank(echostr)) {</span><br><span class="line"> <span class="comment">// 说明是一个仅仅用来验证的请求,回显echostr</span></span><br><span class="line"> log.info(echostr);</span><br><span class="line"> <span class="keyword">return</span> echostr;</span><br><span class="line"> }</span><br><span class="line"> log.warn(<span class="string">"未知请求"</span>);</span><br><span class="line"> <span class="keyword">return</span> <span class="keyword">null</span>;</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="comment">/**</span></span><br><span class="line"><span class="comment"> * 生成用户授权链接</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"> <span class="meta">@GetMapping</span>(value = <span class="string">"/authorization"</span>, produces = <span class="string">"application/json;charset=UTF-8"</span>)</span><br><span class="line"> <span class="meta">@ResponseBody</span></span><br><span class="line"> <span class="function"><span class="keyword">public</span> String <span class="title">authorization</span><span class="params">()</span> </span>{</span><br><span class="line"> String url = URL + <span class="string">"/wx/getUserInfo"</span>;</span><br><span class="line"> String UUIDParam = UUID.randomUUID().toString().replace(<span class="string">"-"</span>, <span class="string">""</span>);</span><br><span class="line"> url = url + <span class="string">"/"</span> + UUIDParam;</span><br><span class="line"> String authorizationUrl = wxMpService.oauth2buildAuthorizationUrl(url, WxConsts.OAuth2Scope.SNSAPI_USERINFO, <span class="keyword">null</span>);</span><br><span class="line"> log.info(<span class="string">"authorizationUrl:"</span> + authorizationUrl);</span><br><span class="line"> String json = <span class="string">"{\"uuid\":\""</span> + UUIDParam + <span class="string">"\",\"url\":\""</span> + authorizationUrl + <span class="string">"\"}"</span>;</span><br><span class="line"> <span class="comment">//将uuid存到redis,默认值为NULL</span></span><br><span class="line"> jedisClient.set(REDIS_LOGIN_UUID_PRE + <span class="string">":"</span> + UUIDParam + <span class="string">":BASE"</span>, <span class="string">"NULL"</span>);</span><br><span class="line"> <span class="comment">//设置有效时长</span></span><br><span class="line"> jedisClient.expire(REDIS_LOGIN_UUID_PRE + <span class="string">":"</span> + UUIDParam + <span class="string">":BASE"</span>, LOGIN_EXPIRE);</span><br><span class="line"> <span class="keyword">return</span> json;</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="comment">/**</span></span><br><span class="line"><span class="comment"> * 用户扫码回调的方法,获得用户信息</span></span><br><span class="line"><span class="comment"> *</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@param</span> code</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"> <span class="meta">@GetMapping</span>(value = <span class="string">"/getUserInfo/{uuid}"</span>)</span><br><span class="line"> <span class="function"><span class="keyword">public</span> String <span class="title">getUserInfo</span><span class="params">(String code, @PathVariable String uuid, Model model)</span> </span>{</span><br><span class="line"> <span class="keyword">if</span> (StringUtils.isBlank(uuid) || StringUtils.isBlank(code)) {</span><br><span class="line"> model.addAttribute(<span class="string">"result"</span>, GMResult.build(<span class="number">400</span>, <span class="string">"登录失败"</span>));</span><br><span class="line"> <span class="keyword">return</span> <span class="string">"wx/loginStats"</span>;</span><br><span class="line"> }</span><br><span class="line"> System.out.println(uuid);</span><br><span class="line"> String redisPre = REDIS_LOGIN_UUID_PRE + <span class="string">":"</span> + uuid + <span class="string">":BASE"</span>;</span><br><span class="line"> log.info(<span class="string">"code:"</span> + code);</span><br><span class="line"> <span class="keyword">try</span> {</span><br><span class="line"> <span class="comment">//code只能用一次,再次使用会抛异常</span></span><br><span class="line"> WxMpOAuth2AccessToken token = wxMpService.oauth2getAccessToken(code);</span><br><span class="line"> WxMpUser wxMpUser = wxMpService.oauth2getUserInfo(token, <span class="keyword">null</span>);</span><br><span class="line"> <span class="comment">//检查是否存在</span></span><br><span class="line"> <span class="keyword">if</span> (!jedisClient.exists(redisPre)) {</span><br><span class="line"> model.addAttribute(<span class="string">"result"</span>, GMResult.build(<span class="number">402</span>, <span class="string">"二维码已过期"</span>));</span><br><span class="line"> <span class="keyword">return</span> <span class="string">"wx/loginStats"</span>;</span><br><span class="line"> }</span><br><span class="line"> <span class="comment">//当redis中对应uuid未被使用</span></span><br><span class="line"> <span class="keyword">if</span> (<span class="string">"NULL"</span>.equals(jedisClient.get(redisPre))) {</span><br><span class="line"> <span class="comment">//将用户信息保存到redis中</span></span><br><span class="line"> jedisClient.set(redisPre, JsonUtils.objectToJson(wxMpUser));</span><br><span class="line"> <span class="comment">//设置有效时长</span></span><br><span class="line"> jedisClient.expire(redisPre, LOGIN_EXPIRE);</span><br><span class="line"> log.info(wxMpUser.toString());</span><br><span class="line"> model.addAttribute(<span class="string">"result"</span>, GMResult.build(<span class="number">200</span>, <span class="string">"登录成功"</span>));</span><br><span class="line"> <span class="keyword">return</span> <span class="string">"wx/loginStats"</span>;</span><br><span class="line"> }</span><br><span class="line"> } <span class="keyword">catch</span> (WxErrorException e) {</span><br><span class="line"> e.printStackTrace();</span><br><span class="line"> model.addAttribute(<span class="string">"result"</span>, GMResult.build(<span class="number">401</span>, <span class="string">"请勿重复登录"</span>));</span><br><span class="line"> <span class="keyword">return</span> <span class="string">"wx/loginStats"</span>;</span><br><span class="line"> }</span><br><span class="line"> model.addAttribute(<span class="string">"result"</span>, GMResult.build(<span class="number">403</span>, <span class="string">"二维码已使用"</span>));</span><br><span class="line"> System.out.println(<span class="string">"登录失败"</span>);</span><br><span class="line"> <span class="keyword">return</span> <span class="string">"wx/loginStats"</span>;</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"> <span class="comment">/**</span></span><br><span class="line"><span class="comment"> * 查询用户是否授权</span></span><br><span class="line"><span class="comment"> *</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@param</span> uuid</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@param</span> session</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@return</span></span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"> <span class="meta">@PostMapping</span>(value = <span class="string">"/checkLogin"</span>, produces = <span class="string">"application/json;charset=UTF-8"</span>)</span><br><span class="line"> <span class="meta">@ResponseBody</span></span><br><span class="line"> <span class="function"><span class="keyword">public</span> GMResult <span class="title">checkLogin</span><span class="params">(String uuid, HttpSession session)</span> </span>{</span><br><span class="line"> String redisPre=REDIS_LOGIN_UUID_PRE + <span class="string">":"</span> + uuid + <span class="string">":BASE"</span>;</span><br><span class="line"> <span class="comment">//根据uuid查询redis中是否存在用户且授权</span></span><br><span class="line"> <span class="keyword">if</span> (!jedisClient.exists(redisPre)){</span><br><span class="line"> <span class="keyword">return</span> GMResult.build(<span class="number">402</span>, <span class="string">"二维码已过期"</span>);</span><br><span class="line"> }</span><br><span class="line"> String json = jedisClient.get(redisPre);</span><br><span class="line"> System.out.println(<span class="string">"等待登录。。。。。json:"</span> + json);</span><br><span class="line"> <span class="keyword">if</span> (!<span class="string">"NULL"</span>.equals(json)) {</span><br><span class="line"> <span class="comment">//如果值不为默认值,转成user对象</span></span><br><span class="line"> WxMpUser wxMpUser = JsonUtils.jsonToPojo(json, WxMpUser.class);</span><br><span class="line"> System.out.println(wxMpUser.toString());</span><br><span class="line"> Buyer buyer=buyerService.wxLogin(wxMpUser);</span><br><span class="line"> <span class="comment">//存在则跳转到登录成功页,并将user放入session中</span></span><br><span class="line"> session.setAttribute(<span class="string">"user"</span>, buyer);</span><br><span class="line"> <span class="keyword">return</span> GMResult.ok();</span><br><span class="line"> }</span><br><span class="line"> <span class="comment">//否则返回false</span></span><br><span class="line"> <span class="keyword">return</span> GMResult.build(<span class="number">400</span>, <span class="string">"登录失败"</span>);</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure>]]></content>
<summary type="html">
<p>一般网站应用使用微信扫码登录使用的是<a href="https://developers.weixin.qq.com/doc/oplatform/Mobile_App/Resource_Center_Homepage.html" target="_blank" rel="noopener">微信开放平台</a>的接口,但注册开放平台需要提供企业信息,而且开放平台并没有提供测试账号,个人想要直接通过开放平台实现微信授权登录是不可行的。</p>
<p>微信在公众号中提供了<a href="https://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=sandbox/login" target="_blank" rel="noopener">测试账号</a>,我们可以通过公众号实现微信授权;</p>
</summary>
<category term="java" scheme="http://www.shaoyong.online/categories/java/"/>
<category term="微信" scheme="http://www.shaoyong.online/tags/%E5%BE%AE%E4%BF%A1/"/>
</entry>
<entry>
<title>IDEA中自定义骨架(archetype)</title>
<link href="http://www.shaoyong.online/posts/ceb2a2ec/"/>
<id>http://www.shaoyong.online/posts/ceb2a2ec/</id>
<published>2019-10-12T06:05:49.854Z</published>
<updated>2019-10-12T08:48:08.648Z</updated>
<content type="html"><![CDATA[<p>IDEA中可以使用archetype快速生成一个项目骨架,但自带的archetype太精简了,并不一定合适我们,我们可以自定义一个合适我们的骨架。</p><a id="more"></a><h1 id="创建archetype"><a href="#创建archetype" class="headerlink" title="创建archetype"></a>创建archetype</h1><h2 id="创建一个maven项目"><a href="#创建一个maven项目" class="headerlink" title="创建一个maven项目"></a>创建一个maven项目</h2><p>可以使用已存在的archetype,也可以不使用</p><p><img src="http://imagebed.shaoyong.online/images/2019_10_12/1.png" alt></p><p><img src="http://imagebed.shaoyong.online/images/2019_10_12/2.png" alt></p><p><img src="http://imagebed.shaoyong.online/images/2019_10_12/3.png" alt></p><h2 id="修改项目"><a href="#修改项目" class="headerlink" title="修改项目"></a>修改项目</h2><p>可以在创建的项目中加入复用性高的配置与依赖(下面是以web项目为例)</p><p><img src="http://imagebed.shaoyong.online/images/2019_10_12/4.png" alt></p><p><strong>注意:包内要有文件占位,否则在生成archetype时会丢弃这个包</strong></p><h2 id="生成archetype"><a href="#生成archetype" class="headerlink" title="生成archetype"></a>生成archetype</h2><p>在IDEA中按<kbd>Alt</kbd> + <kbd>F12</kbd>,打开Terminal视图,直接进入当前项目的根目录,输入<code>mvn archetype:create-from-project</code> 创建archetype</p><p><img src="http://imagebed.shaoyong.online/images/2019_10_12/5.png" alt></p><p>执行完后会出现target目录</p><p><img src="http://imagebed.shaoyong.online/images/2019_10_12/6.png" alt></p><h1 id="安装archetype"><a href="#安装archetype" class="headerlink" title="安装archetype"></a>安装archetype</h1><p>执行<code>cd target\generated-sources\archetype</code>进入创建的archetype 项目目录</p><p><img src="http://imagebed.shaoyong.online/images/2019_10_12/7.png" alt></p><p>执行<code>mvn clean install</code>安装archetype </p><p><img src="http://imagebed.shaoyong.online/images/2019_10_12/8.png" alt></p><p>生成记录文件(可选),执行<code>mvn archetype:crawl</code></p><p>执行完后可以在本地仓库里找到生成的archetype-catalog.xml文件</p><p><img src="http://imagebed.shaoyong.online/images/2019_10_12/10.png" alt></p><p>打开这个文件,可以看到我们自定义的archetype信息</p><p><img src="http://imagebed.shaoyong.online/images/2019_10_12/9.png" alt></p><h1 id="将archetype加入IDEA"><a href="#将archetype加入IDEA" class="headerlink" title="将archetype加入IDEA"></a>将archetype加入IDEA</h1><p>在IDEA中进入New Project界面,选择Add Archetype,填入我们的archetype信息,点击ok</p><p><img src="http://imagebed.shaoyong.online/images/2019_10_12/11.png" alt></p><p>到这就完成了在IDEA中自定义archetype了,以后就可以在创建项目时直接选中使用了。</p><h1 id="删除IDEA中自定义的archetype"><a href="#删除IDEA中自定义的archetype" class="headerlink" title="删除IDEA中自定义的archetype"></a>删除IDEA中自定义的archetype</h1><h2 id="从本地仓库中删除archetype"><a href="#从本地仓库中删除archetype" class="headerlink" title="从本地仓库中删除archetype"></a>从本地仓库中删除archetype</h2><p>删除不再需要的archetype的文件夹</p><p><img src="http://imagebed.shaoyong.online/images/2019_10_12/13.png" alt></p><h2 id="从IDEA中删除archetype"><a href="#从IDEA中删除archetype" class="headerlink" title="从IDEA中删除archetype"></a>从IDEA中删除archetype</h2><p>打开目录<code>C:/Users/(用户名)/.IntelliJIdea(版本号)/system/Maven/Indices</code></p><p><img src="http://imagebed.shaoyong.online/images/2019_10_12/14.png" alt></p><p>其中UserArchetypes.xml文件中记录了用户自定义的archetype,删除不需要的archetype所在行就搞定了。</p><p><img src="http://imagebed.shaoyong.online/images/2019_10_12/15.png" alt></p>]]></content>
<summary type="html">
<p>IDEA中可以使用archetype快速生成一个项目骨架,但自带的archetype太精简了,并不一定合适我们,我们可以自定义一个合适我们的骨架。</p>
</summary>
<category term="笔记" scheme="http://www.shaoyong.online/categories/%E7%AC%94%E8%AE%B0/"/>
<category term="IDEA" scheme="http://www.shaoyong.online/tags/IDEA/"/>
</entry>
<entry>
<title>使用原生js实现轮播图</title>
<link href="http://www.shaoyong.online/posts/616/"/>
<id>http://www.shaoyong.online/posts/616/</id>
<published>2019-09-14T12:49:22.742Z</published>
<updated>2019-09-15T12:29:26.464Z</updated>
<content type="html"><![CDATA[<p>使用原生JS实现轮播图,下面先看看成品;</p><iframe style="padding:0;border: 0; width: 100%;height: 260px" src="https://imagebed.shaoyong.online/demo/viewPager_s.html"></iframe><a id="more"></a><h2 id="实现的效果"><a href="#实现的效果" class="headerlink" title="实现的效果"></a>实现的效果</h2><ol><li>图片自动滑动切换,鼠标移动到图片上则停止切换;</li><li>鼠标移动到圆点时切换到相应的图片;</li><li>点击箭头切换到下一张图片;</li><li>鼠标离开图片,则隐藏箭头;</li><li>默认是3张图片,需要更多图片时,只需追加<code><img></code>标签;</li></ol><h2 id="实现逻辑"><a href="#实现逻辑" class="headerlink" title="实现逻辑"></a>实现逻辑</h2><p>将图片连接成条形,像胶卷一样,给个图片大小的窗口,左右移动图片条,完成切换;</p><h2 id="实现代码"><a href="#实现代码" class="headerlink" title="实现代码"></a>实现代码</h2><h3 id="HTML"><a href="#HTML" class="headerlink" title="HTML"></a>HTML</h3><p>基本的HTML框架</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta"><!DOCTYPE html></span></span><br><span class="line"><span class="tag"><<span class="name">html</span> <span class="attr">lang</span>=<span class="string">"en"</span>></span></span><br><span class="line"><span class="tag"><<span class="name">head</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">meta</span> <span class="attr">charset</span>=<span class="string">"UTF-8"</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">title</span>></span>轮播图<span class="tag"></<span class="name">title</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">link</span> <span class="attr">rel</span>=<span class="string">"stylesheet"</span> <span class="attr">href</span>=<span class="string">"css/slide.css"</span>></span></span><br><span class="line"><span class="tag"></<span class="name">head</span>></span></span><br><span class="line"><span class="tag"><<span class="name">body</span>></span></span><br><span class="line"><span class="tag"><<span class="name">div</span> <span class="attr">class</span>=<span class="string">"box"</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">div</span> <span class="attr">id</span>=<span class="string">"pic_box"</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">img</span> <span class="attr">src</span>=<span class="string">"img/arrow_left.png"</span> <span class="attr">id</span>=<span class="string">"arrow-left"</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">img</span> <span class="attr">src</span>=<span class="string">"img/arrow_right.png"</span> <span class="attr">id</span>=<span class="string">"arrow-right"</span>></span></span><br><span class="line"> <span class="comment"><!--放圆点用--></span></span><br><span class="line"> <span class="tag"><<span class="name">ul</span> <span class="attr">id</span>=<span class="string">"multi-circles"</span>></span><span class="tag"></<span class="name">ul</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">div</span> <span class="attr">id</span>=<span class="string">"multi-images"</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">img</span> <span class="attr">src</span>=<span class="string">"img/1.jpg"</span>></span><span class="tag"><<span class="name">img</span> <span class="attr">src</span>=<span class="string">"img/2.jpg"</span>></span><span class="tag"><<span class="name">img</span> <span class="attr">src</span>=<span class="string">"img/3.jpg"</span>></span></span><br><span class="line"> <span class="tag"></<span class="name">div</span>></span></span><br><span class="line"> <span class="tag"></<span class="name">div</span>></span></span><br><span class="line"><span class="tag"></<span class="name">div</span>></span></span><br><span class="line"><span class="tag"><<span class="name">script</span> <span class="attr">src</span>=<span class="string">"js/slide.js"</span>></span><span class="tag"></<span class="name">script</span>></span></span><br><span class="line"><span class="tag"></<span class="name">body</span>></span></span><br><span class="line"><span class="tag"></<span class="name">html</span>></span></span><br></pre></td></tr></table></figure><h3 id="CSS"><a href="#CSS" class="headerlink" title="CSS"></a>CSS</h3><p>使用绝对定位对各个元素布局。</p><figure class="highlight css"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/*定义图片大小与默认图片数*/</span></span><br><span class="line"><span class="selector-pseudo">:root</span> {</span><br><span class="line"> <span class="attribute">--imageWidth</span>: <span class="number">800px</span>;</span><br><span class="line"> <span class="attribute">--imageHeight</span>: <span class="number">240px</span>;</span><br><span class="line"> <span class="attribute">--imageNum</span>: <span class="number">3</span>;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="selector-class">.box</span> {</span><br><span class="line"> <span class="attribute">margin</span>: <span class="number">0</span> auto;</span><br><span class="line"> <span class="attribute">width</span>: <span class="number">800px</span>;</span><br><span class="line">}</span><br><span class="line"><span class="comment">/*只显示图片大小的窗口展示单张图片*/</span></span><br><span class="line"><span class="selector-id">#pic_box</span> {</span><br><span class="line"> <span class="attribute">position</span>: relative;</span><br><span class="line"> <span class="attribute">width</span>: <span class="built_in">var</span>(--imageWidth);</span><br><span class="line"> <span class="attribute">height</span>: <span class="built_in">var</span>(--imageHeight);</span><br><span class="line"> <span class="attribute">overflow</span>: hidden;</span><br><span class="line">}</span><br><span class="line"><span class="comment">/*绝对定位圆点的位置*/</span></span><br><span class="line"><span class="selector-id">#multi-circles</span> {</span><br><span class="line"> <span class="attribute">position</span>: absolute;</span><br><span class="line"> <span class="attribute">right</span>: <span class="number">30px</span>;</span><br><span class="line"> <span class="attribute">bottom</span>: <span class="number">10px</span>;</span><br><span class="line"> <span class="attribute">z-index</span>: <span class="number">2</span>;</span><br><span class="line">}</span><br><span class="line"><span class="comment">/*设置圆点的格式并使圆点横排*/</span></span><br><span class="line"><span class="selector-id">#multi-circles</span> <span class="selector-tag">li</span> {</span><br><span class="line"> <span class="attribute">width</span>: <span class="number">25px</span>;</span><br><span class="line"> <span class="attribute">list-style</span>: none;</span><br><span class="line"> <span class="attribute">font-size</span>: <span class="number">24px</span>;</span><br><span class="line"> <span class="attribute">float</span>: left;</span><br><span class="line"> <span class="attribute">color</span>: white;</span><br><span class="line">}</span><br><span class="line"><span class="comment">/*设置计算图片条的长度*/</span></span><br><span class="line"><span class="selector-id">#multi-images</span> {</span><br><span class="line"> <span class="attribute">position</span>: absolute;</span><br><span class="line"> <span class="attribute">left</span>: <span class="number">0</span>;</span><br><span class="line"> <span class="attribute">top</span>: <span class="number">0</span>;</span><br><span class="line"> <span class="attribute">z-index</span>: <span class="number">1</span>;</span><br><span class="line"> <span class="attribute">width</span>: <span class="built_in">calc</span>(var(--imageWidth) * <span class="built_in">var</span>(--imageNum));</span><br><span class="line"> <span class="attribute">height</span>: <span class="built_in">var</span>(--imageHeight);</span><br><span class="line"> <span class="attribute">transition</span>: <span class="number">1s</span>;</span><br><span class="line">}</span><br><span class="line"><span class="comment">/*设置左右箭头图标的位置*/</span></span><br><span class="line"><span class="selector-id">#arrow-right</span>, <span class="selector-id">#arrow-left</span> {</span><br><span class="line"> <span class="attribute">position</span>: absolute;</span><br><span class="line"> <span class="attribute">top</span>: <span class="number">50%</span>;</span><br><span class="line"> <span class="attribute">margin-top</span>: -<span class="number">24px</span>;</span><br><span class="line"> <span class="attribute">height</span>: <span class="number">48px</span>;</span><br><span class="line"> <span class="attribute">z-index</span>: <span class="number">3</span>;</span><br><span class="line"> <span class="attribute">background</span>: <span class="built_in">rgba</span>(159, 180, 179, 0.38);</span><br><span class="line"> <span class="attribute">display</span>: none;</span><br><span class="line"> <span class="attribute">cursor</span>: pointer;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="selector-id">#arrow-right</span> {</span><br><span class="line"> <span class="attribute">right</span>: <span class="number">0</span>;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="selector-id">#arrow-left</span> {</span><br><span class="line"> <span class="attribute">left</span>: <span class="number">0</span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h3 id="JS"><a href="#JS" class="headerlink" title="JS"></a>JS</h3><p>核心步骤:</p><ol><li>获取图片个数。</li><li>添加圆点。</li><li>设置“图片条”长度。</li><li>添加圆点、箭头的鼠标与点击事件;</li><li>设置图片轮播定时器;</li></ol><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//获得html组件</span></span><br><span class="line"><span class="keyword">var</span> arrowLeft = <span class="built_in">document</span>.getElementById(<span class="string">"arrow-left"</span>);</span><br><span class="line"><span class="keyword">var</span> arrowRight = <span class="built_in">document</span>.getElementById(<span class="string">"arrow-right"</span>);</span><br><span class="line"><span class="keyword">var</span> multiImages = <span class="built_in">document</span>.getElementById(<span class="string">"multi-images"</span>);</span><br><span class="line"><span class="keyword">var</span> circles = <span class="built_in">document</span>.getElementById(<span class="string">"multi-circles"</span>);</span><br><span class="line"><span class="keyword">var</span> picBox = <span class="built_in">document</span>.getElementById(<span class="string">"pic_box"</span>);</span><br><span class="line"><span class="comment">//图片个数</span></span><br><span class="line"><span class="keyword">var</span> picNum = multiImages.getElementsByTagName(<span class="string">"img"</span>).length;</span><br><span class="line"><span class="comment">//根据图片数量添加圆点</span></span><br><span class="line"><span class="keyword">for</span> (<span class="keyword">var</span> i = <span class="number">0</span>; i < picNum; i++) {</span><br><span class="line"> <span class="keyword">var</span> liElement = <span class="built_in">document</span>.createElement(<span class="string">"li"</span>);</span><br><span class="line"> liElement.innerHTML = <span class="string">"●"</span>;</span><br><span class="line"> circles.appendChild(liElement);</span><br><span class="line">}</span><br><span class="line"><span class="comment">//在html设置图片数量</span></span><br><span class="line"><span class="built_in">document</span>.documentElement.style.setProperty(<span class="string">"--imageNum"</span>, picNum);</span><br><span class="line"><span class="comment">//获取css中设置的图片宽度</span></span><br><span class="line"><span class="keyword">var</span> imageWidth = getComputedStyle(<span class="built_in">document</span>.documentElement).getPropertyValue(<span class="string">"--imageWidth"</span>);</span><br><span class="line">imageWidth = imageWidth.substring(<span class="number">0</span>, imageWidth.indexOf(<span class="string">"px"</span>));</span><br><span class="line"><span class="comment">//设置轮播图片总长度</span></span><br><span class="line">multiImages.style.width = picNum * imageWidth + <span class="string">"px"</span>;</span><br><span class="line"><span class="comment">//获取li列表对象</span></span><br><span class="line">circles = <span class="built_in">document</span>.getElementById(<span class="string">"multi-circles"</span>).getElementsByTagName(<span class="string">"li"</span>);</span><br><span class="line"><span class="comment">//最大下标</span></span><br><span class="line"><span class="keyword">var</span> maxIndex = picNum - <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="keyword">var</span> currentIndex = <span class="number">0</span>;</span><br><span class="line"><span class="comment">//为箭头和圆点绑定事件</span></span><br><span class="line">arrowLeft.addEventListener(<span class="string">"click"</span>, preMove);</span><br><span class="line">arrowRight.addEventListener(<span class="string">"click"</span>, nextMove);</span><br><span class="line"><span class="keyword">for</span> (<span class="keyword">var</span> i = <span class="number">0</span>; i < circles.length; i++) {</span><br><span class="line"> circles[i].setAttribute(<span class="string">"id"</span>, i);</span><br><span class="line"> circles[i].addEventListener(<span class="string">"mouseenter"</span>, overCircle);</span><br><span class="line">}</span><br><span class="line"><span class="comment">//第一次载入,第一个圆是红色</span></span><br><span class="line">circles[<span class="number">0</span>].style.color = <span class="string">"#ff0000"</span>;</span><br><span class="line"><span class="comment">//定时器,每2秒移动</span></span><br><span class="line"><span class="keyword">var</span> time = setInterval(nextMove, <span class="number">2000</span>);</span><br><span class="line"></span><br><span class="line"><span class="comment">//滑过圆点</span></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">overCircle</span>(<span class="params"></span>) </span>{</span><br><span class="line"> <span class="keyword">var</span> preIndex = currentIndex;</span><br><span class="line"> currentIndex = <span class="built_in">parseInt</span>(<span class="keyword">this</span>.id);</span><br><span class="line"> moveImage();</span><br><span class="line"> changeCircleColor(preIndex, currentIndex)</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="comment">//左箭头</span></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">preMove</span>(<span class="params"></span>) </span>{</span><br><span class="line"> <span class="keyword">var</span> preIndex = currentIndex;</span><br><span class="line"> <span class="keyword">if</span> (currentIndex !== <span class="number">0</span>) {</span><br><span class="line"> currentIndex--;</span><br><span class="line"> } <span class="keyword">else</span> {</span><br><span class="line"> currentIndex = maxIndex;</span><br><span class="line"> }</span><br><span class="line"> moveImage();</span><br><span class="line"> changeCircleColor(preIndex, currentIndex)</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="comment">//右箭头</span></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">nextMove</span>(<span class="params"></span>) </span>{</span><br><span class="line"> <span class="keyword">var</span> preIndex = currentIndex;</span><br><span class="line"> <span class="keyword">if</span> (currentIndex !== maxIndex) {</span><br><span class="line"> currentIndex++;</span><br><span class="line"> } <span class="keyword">else</span> {</span><br><span class="line"> currentIndex = <span class="number">0</span>;</span><br><span class="line"> }</span><br><span class="line"> moveImage();</span><br><span class="line"> changeCircleColor(preIndex, currentIndex)</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="comment">//移动图片</span></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">moveImage</span>(<span class="params"></span>) </span>{</span><br><span class="line"> multiImages.style.left = -currentIndex * imageWidth + <span class="string">"px"</span>;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="comment">//改变圆点颜色</span></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">changeCircleColor</span>(<span class="params">preIndex, currentIndex</span>) </span>{</span><br><span class="line"> circles[preIndex].style.color = <span class="string">"#ffffff"</span>;</span><br><span class="line"> circles[currentIndex].style.color = <span class="string">"#ff0000"</span></span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="comment">//鼠标移动到图片上时显示箭头</span></span><br><span class="line">picBox.addEventListener(<span class="string">"mouseover"</span>, <span class="function"><span class="keyword">function</span> (<span class="params">ev</span>) </span>{</span><br><span class="line"> arrowRight.style.display = <span class="string">"block"</span>;</span><br><span class="line"> arrowLeft.style.display = <span class="string">"block"</span>;</span><br><span class="line"> clearInterval(time);</span><br><span class="line">});</span><br><span class="line"><span class="comment">//鼠标离开图片上时隐藏箭头</span></span><br><span class="line">picBox.addEventListener(<span class="string">"mouseleave"</span>, <span class="function"><span class="keyword">function</span> (<span class="params">ev</span>) </span>{</span><br><span class="line"> arrowRight.style.display = <span class="string">"none"</span>;</span><br><span class="line"> arrowLeft.style.display = <span class="string">"none"</span>;</span><br><span class="line"> time = setInterval(nextMove, <span class="number">2000</span>);</span><br><span class="line">});</span><br></pre></td></tr></table></figure><h2 id="遇到的bug"><a href="#遇到的bug" class="headerlink" title="遇到的bug"></a>遇到的bug</h2><ol><li>第二张图片显示不完整,而且左边有白边,而第三张图片不显示。</li></ol><p><img src="https://imagebed.shaoyong.online/images/2019_9_14/1.png" alt></p><p><img src="https://imagebed.shaoyong.online/images/2019_9_14/2.png" alt></p><p> 在浏览器中检查发现两张图片之间有缝隙,导致第三张图片被强行换行,看起来第三张图片位置空白;尝试设置bored、margin、padding为0,并没有效果。看看HTML,<del>看起来没什么问题</del>;</p><p><img src="https://imagebed.shaoyong.online/images/2019_9_14/3.png" alt></p><p><strong>解决办法</strong>:将<code><img></code>标签间的回车去掉,写成一行;或者将图片设置为左浮动,<code>style="display:block; float:left"</code>;</p><p><img src="https://imagebed.shaoyong.online/images/2019_9_14/4.png" alt></p><p><strong>原因</strong>:<code><img></code>标签是行内元素,默认排版为 inline-block;而所有的inline-block元素之间都会有空白。</p><ol start="2"><li>在获取css文件中设置的图片宽高时,“获取”不到值;</li></ol><p>使用<code>document.documentElement.style.getPropertyValue("--imageWidth");</code>得到的值为空;</p><p><strong>解决办法</strong>:改用<code>getComputedStyle(document.documentElement).getPropertyValue("--imageWidth");</code>才能拿到<code>:root</code>选择器中设置的值;</p><p><img src="https://imagebed.shaoyong.online/images/2019_9_14/6.png" alt></p><p><strong>原因</strong>:</p><blockquote><p><code>document.documentElement.style.getPropertyValue</code>只能获取内联式样的值;<br>而<code>getComputedStyle(document.documentElement).getPropertyValue</code>获取到的始终是实际的值;</p></blockquote><h2 id="注意事项"><a href="#注意事项" class="headerlink" title="注意事项"></a>注意事项</h2><p>轮播图默认大小为800*240,图片大小一致时无需修改任何css、js;使用自定义大小的图片时需要修改css文件中<code>:root</code>中<code>--imageWidth</code>、<code>--imageHeight</code>的值;</p><h2 id="参考链接"><a href="#参考链接" class="headerlink" title="参考链接"></a>参考链接</h2><p><a href="https://segmentfault.com/a/1190000018176394" target="_blank" rel="noopener">css变量赋值和取值的四种方式</a> <a href="https://segmentfault.com/a/1190000018718279" target="_blank" rel="noopener">原生JS实现滑动轮播图</a></p>]]></content>
<summary type="html">
<p>使用原生JS实现轮播图,下面先看看成品;</p>
<iframe style="padding:0;border: 0; width: 100%;height: 260px" src="https://imagebed.shaoyong.online/demo/viewPager_s.html"></iframe>
</summary>
<category term="JavaScript" scheme="http://www.shaoyong.online/categories/JavaScript/"/>
<category term="轮播图" scheme="http://www.shaoyong.online/tags/%E8%BD%AE%E6%92%AD%E5%9B%BE/"/>
</entry>
<entry>
<title>java中Map、Collection接口常用实现类源码浅析</title>
<link href="http://www.shaoyong.online/posts/43684/"/>
<id>http://www.shaoyong.online/posts/43684/</id>
<published>2019-08-29T14:08:58.441Z</published>
<updated>2019-09-15T10:34:46.062Z</updated>
<content type="html"><![CDATA[<p>在Java中集合是常用的数据结构,而<code>Map</code>与<code>Collection</code>的实现类有很多,我们常见的有<code>HashMap</code>、<code>HashTable</code>、<code>TreeMap</code>、<code>LinkedHashMap</code>、<code>ArrayList</code>、<code>Linkedlist</code>、<code>Vector</code>、<code>HashSet</code>、<code>TreeSet</code>、<code>LinkedHashSet</code>;</p><p>下面从源码的层面简析这些实现类的特性;</p><a id="more"></a><h1 id="Map"><a href="#Map" class="headerlink" title="Map"></a>Map</h1><p>先看看<code>Map</code>接口的继承关系图</p><p><img src="https://imagebed.shaoyong.online/images/2019_08_30/Interface_Map.png" alt></p><p>Map是顶级接口,声明了通用的抽象方法,如获取所有键值对的方法——<code>entrySet</code>;以及还有静态的内部接口<code>Entry</code>;使用<code>entrySet</code>遍历Map集合的方式效率高于使用<code>keySet</code>遍历方式;<code>keySet</code>会遍历两次集合,第一次将集合转为<code>Iterator</code>对象,第二次重<code>hashMap</code>中取出key所对应的<code>entrySet</code>;而<code>entrySet</code>只是遍历一次就把key和value放入了<code>entry</code>中。如果是在JDK8,使用<code>Map.forEach</code>方法更好。</p><p><code>values()</code>返回的是 V 值集合,是一个 list 集合对象;<code>keySet()</code>返回的是 K 值集合,是一个 Set 集合对象;<code>entrySet()</code>返回的是 K-V 值组合集合。</p><p><img src="https://imagebed.shaoyong.online/images/2019_08_30/Map1.png" alt></p><h2 id="AbstractMap"><a href="#AbstractMap" class="headerlink" title="AbstractMap"></a>AbstractMap</h2><p>抽象类<code>AbstractMap</code>实现了<code>Map</code>接口的”骨干”方法,目的是减少实现<code>Map</code>接口的时需要重写的方法。</p><p>如其中实现的<code>keySet</code>方法用于获得<code>Map</code>中的所有Key值Set集合,内部创建<code>AbstractSet</code>的匿名子类实例存放key值;实现的<code>values</code>方法中,创建了<code>AbstractCollection</code>匿名子类实例,用于存放<code>map</code>中value值;</p><p><img src="https://imagebed.shaoyong.online/images/2019_08_30/AbstractMap.png" alt="keySet()方法"></p><h3 id="HashMap"><a href="#HashMap" class="headerlink" title="HashMap"></a>HashMap</h3><p><code>HashMap</code>继承自<code>AbstractMap</code>并实现了<code>Map</code>等接口,<code>HashMap</code>中定义了名为<code>Node</code>的静态内部类,<code>Node</code>实现了<code>Map.Entry</code>接口,是一个单向链表,然后使用<code>Node[]</code>数组,完成了<code>HashMap</code>的存储结构(数组+链表/红黑树)。</p><p><img src="https://imagebed.shaoyong.online/images/2019_08_30/HashMap1.png" alt></p><p><img src="https://imagebed.shaoyong.online/images/2019_08_30/HashMap_Node%5B%5D.png" alt></p><p><code>HashMap</code>中还定义了一个静态内部类,<code>TreeNode</code>,<code>TreeNode</code>继承自<code>LinkedHashMap.Entry</code>,<code>TreeNode</code>实现了红黑树数据结构。</p><p><img src="https://imagebed.shaoyong.online/images/2019_08_30/HashMap_TreeNode.png" alt></p><p>在计算Key的Hash值时,如果Key为空,则Hash值为0</p><p><img src="https://imagebed.shaoyong.online/images/2019_08_30/HashMap_Hash().png" alt></p><h4 id="put"><a href="#put" class="headerlink" title="put()"></a>put()</h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> V <span class="title">put</span><span class="params">(K key, V value)</span> </span>{</span><br><span class="line"> <span class="comment">//1.对Key计算Hash值</span></span><br><span class="line"> <span class="keyword">return</span> putVal(hash(key), key, value, <span class="keyword">false</span>, <span class="keyword">true</span>);</span><br><span class="line"> }</span><br><span class="line"><span class="function"><span class="keyword">final</span> V <span class="title">putVal</span><span class="params">(<span class="keyword">int</span> hash, K key, V value, <span class="keyword">boolean</span> onlyIfAbsent,</span></span></span><br><span class="line"><span class="function"><span class="params"> <span class="keyword">boolean</span> evict)</span> </span>{</span><br><span class="line"> Node<K,V>[] tab; Node<K,V> p; <span class="keyword">int</span> n, i;</span><br><span class="line"> <span class="comment">//2.检查Hash表是否为空,如果是空则调用resize扩容</span></span><br><span class="line"> <span class="keyword">if</span> ((tab = table) == <span class="keyword">null</span> || (n = tab.length) == <span class="number">0</span>)</span><br><span class="line"> n = (tab = resize()).length;</span><br><span class="line"> <span class="comment">//3.计算下标,并检查是否存在,不存在则在数组中直接添加一个节点,并放入key,value</span></span><br><span class="line"> <span class="keyword">if</span> ((p = tab[i = (n - <span class="number">1</span>) & hash]) == <span class="keyword">null</span>)</span><br><span class="line"> tab[i] = newNode(hash, key, value, <span class="keyword">null</span>);</span><br><span class="line"> <span class="keyword">else</span> {</span><br><span class="line"> Node<K,V> e; K k;</span><br><span class="line"> <span class="comment">//4.Hash值、key相同时,替换旧值</span></span><br><span class="line"> <span class="keyword">if</span> (p.hash == hash &&</span><br><span class="line"> ((k = p.key) == key || (key != <span class="keyword">null</span> && key.equals(k))))</span><br><span class="line"> e = p;</span><br><span class="line"> <span class="keyword">else</span> <span class="keyword">if</span> (p <span class="keyword">instanceof</span> TreeNode)</span><br><span class="line"> e = ((TreeNode<K,V>)p).putTreeVal(<span class="keyword">this</span>, tab, hash, key, value);</span><br><span class="line"> <span class="keyword">else</span> {</span><br><span class="line"> <span class="comment">//4.Hash值相同,Key不同时,则以链表的的方式连接到后面</span></span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">int</span> binCount = <span class="number">0</span>; ; ++binCount) {</span><br><span class="line"> <span class="keyword">if</span> ((e = p.next) == <span class="keyword">null</span>) {</span><br><span class="line"> p.next = newNode(hash, key, value, <span class="keyword">null</span>);</span><br><span class="line"> <span class="comment">//5.如果链表长度超过阀值(TREEIFY_THRESHOLD=8),则把链表转换成红黑树</span></span><br><span class="line"> <span class="keyword">if</span> (binCount >= TREEIFY_THRESHOLD= - <span class="number">1</span>) <span class="comment">// -1 for 1st</span></span><br><span class="line"> treeifyBin(tab, hash);</span><br><span class="line"> <span class="keyword">break</span>;</span><br><span class="line"> }</span><br><span class="line"> <span class="comment">//链表中包含要插入的键值对时,终止插入</span></span><br><span class="line"> <span class="keyword">if</span> (e.hash == hash &&</span><br><span class="line"> ((k = e.key) == key || (key != <span class="keyword">null</span> && key.equals(k))))</span><br><span class="line"> <span class="keyword">break</span>;</span><br><span class="line"> p = e;</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> <span class="comment">//判断要插入的值是否存在HashMap中</span></span><br><span class="line"> <span class="keyword">if</span> (e != <span class="keyword">null</span>) { <span class="comment">// existing mapping for key</span></span><br><span class="line"> V oldValue = e.value;</span><br><span class="line"> <span class="keyword">if</span> (!onlyIfAbsent || oldValue == <span class="keyword">null</span>)</span><br><span class="line"> e.value = value;</span><br><span class="line"> afterNodeAccess(e);</span><br><span class="line"> <span class="keyword">return</span> oldValue;</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> ++modCount;</span><br><span class="line"> <span class="comment">//键值对数量超过阀值时扩容</span></span><br><span class="line"> <span class="keyword">if</span> (++size > threshold)</span><br><span class="line"> resize();</span><br><span class="line"> afterNodeInsertion(evict);</span><br><span class="line"> <span class="keyword">return</span> <span class="keyword">null</span>;</span><br><span class="line"> }</span><br></pre></td></tr></table></figure><p>方法的入口是<code>put(K,V)</code>,但核心逻辑是在<code>putVal(int, K k, V , boolean ,boolean)</code>;核心做了以下工作:</p><ol><li>计算下标</li><li>判断Hash表状态,表容量不够则扩容</li><li>查找要插入的键值对是否存在,不存在则直接放入,键相同时,用链表的方式连接到相应的Hash值后面</li><li>如果链表长度超过阈值,将链表转换成红黑树</li><li>如果键存在,则更新旧值</li></ol><h4 id="get"><a href="#get" class="headerlink" title="get()"></a>get()</h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> V <span class="title">get</span><span class="params">(Object key)</span> </span>{</span><br><span class="line"> Node<K,V> e;</span><br><span class="line"> <span class="comment">//1.根据Key计算Hash值,再调用getNode方法</span></span><br><span class="line"> <span class="keyword">return</span> (e = getNode(hash(key), key)) == <span class="keyword">null</span> ? <span class="keyword">null</span> : e.value;</span><br><span class="line"> }</span><br><span class="line"><span class="function"><span class="keyword">final</span> Node<K,V> <span class="title">getNode</span><span class="params">(<span class="keyword">int</span> hash, Object key)</span> </span>{</span><br><span class="line"> Node<K,V>[] tab; Node<K,V> first, e; <span class="keyword">int</span> n; K k;</span><br><span class="line"> <span class="comment">//2.节点数组判空,并根据Hash值找到头结点</span></span><br><span class="line"> <span class="keyword">if</span> ((tab = table) != <span class="keyword">null</span> && (n = tab.length) > <span class="number">0</span> &&</span><br><span class="line"> (first = tab[(n - <span class="number">1</span>) & hash]) != <span class="keyword">null</span>) {</span><br><span class="line"> <span class="comment">//3.检查头节点是否为要找的节点</span></span><br><span class="line"> <span class="keyword">if</span> (first.hash == hash && <span class="comment">// always check first node</span></span><br><span class="line"> ((k = first.key) == key || (key != <span class="keyword">null</span> && key.equals(k))))</span><br><span class="line"> <span class="keyword">return</span> first;</span><br><span class="line"> <span class="comment">//4.遍历链表,找到节点并返回</span></span><br><span class="line"> <span class="keyword">if</span> ((e = first.next) != <span class="keyword">null</span>) {</span><br><span class="line"> <span class="keyword">if</span> (first <span class="keyword">instanceof</span> TreeNode)</span><br><span class="line"> <span class="keyword">return</span> ((TreeNode<K,V>)first).getTreeNode(hash, key);</span><br><span class="line"> <span class="keyword">do</span> {</span><br><span class="line"> <span class="keyword">if</span> (e.hash == hash &&</span><br><span class="line"> ((k = e.key) == key || (key != <span class="keyword">null</span> && key.equals(k))))</span><br><span class="line"> <span class="keyword">return</span> e;</span><br><span class="line"> } <span class="keyword">while</span> ((e = e.next) != <span class="keyword">null</span>);</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> <span class="comment">//5.找不到返回空</span></span><br><span class="line"> <span class="keyword">return</span> <span class="keyword">null</span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p><code>get()</code>方法相比<code>put()</code>更简单,先计算Hash值,再根据Hash值遍历后面的链表,调用<code>Key.equals()</code>方法进行匹配。</p><h4 id="小结"><a href="#小结" class="headerlink" title="小结"></a>小结</h4><p><code>HashMap</code>使用Hash表作为数据结构,线程不安全,键值可以为空,自定义对象作为键时,需要重写<code>equals()</code>和<code>HashCode()</code>方法;如果需要满足线程安全,可以用 <code>Collections</code> 的 <code>synchronizedMap</code> 方法使<br><code>HashMap</code> 具有线程安全的能力,或者使用 <code>ConcurrentHashMap</code>。</p><h3 id="LinkedHashMap"><a href="#LinkedHashMap" class="headerlink" title="LinkedHashMap"></a>LinkedHashMap</h3><p><code>LinkedHashMap</code>继承自<code>HashMap</code>,并实现了<code>Map</code>接口,其中定义的静态内部类<code>Entry</code>继承自<code>HashMap.Node</code>类,在<code>Entry</code>中定义了前后节点,实现了Hash表和双向链表数据结构。通过双向链表,保证了数据存取顺序一致。</p><p><img src="https://imagebed.shaoyong.online/images/2019_08_30/LinkedHashMap_Entry.png" alt></p><h3 id="TreeMap"><a href="#TreeMap" class="headerlink" title="TreeMap"></a>TreeMap</h3><p>TreeMap继承自<code>AbstractMap</code>,直接实现了<code>NavigableMap</code>接口,<code>NavigableMap</code>是<code>Map</code>的间接子接口;TreeMap中定义的静态内部类<code>Entry</code>实现了<code>Map.Entry</code>接口,并添加了父、左右还有节点属性,实现了红黑树结构;TreeMap内部自动自然排序,如果要存储自定义对象需要创建比较器(实现<code>Comparator</code>接口)或自定义类实现<code>Comparable</code>接口,重写<code>compareTo</code>方法;</p><p><img src="https://imagebed.shaoyong.online/images/2019_08_30/TreeMap_Entry.png" alt></p><h2 id="Hashtable"><a href="#Hashtable" class="headerlink" title="Hashtable"></a>Hashtable</h2><p><code>Hashtable</code>继承自<code>Dictionary</code>,实现了<code>Map</code>接口。其中的私有静态内部类<code>Entry</code>实现了<code>Map.Entry</code>接口,并增加了增加了<code>hash</code>、<code>key</code>、<code>value</code>、<code>next</code>成员属性,实现了单向链表结构,再结合数组,实现了<code>Hash</code>表存储结构。</p><p><img src="https://imagebed.shaoyong.online/images/2019_08_30/HashTable_Entry.png" alt></p><p><img src="https://imagebed.shaoyong.online/images/2019_08_30/Hashtable_Entry%5B%5D.png" alt></p><p>其中的<code>public</code>成员方法都使用了<code>synchronized</code>修饰,所以线程安全但效率相对较低。</p><p><img src="https://imagebed.shaoyong.online/images/2019_08_30/Hashtable_synchronized.png" alt></p><p>键值都不可以为null。</p><h1 id="Collection"><a href="#Collection" class="headerlink" title="Collection"></a>Collection</h1><p><img src="https://imagebed.shaoyong.online/images/2019_08_30/Collection.png" alt></p><blockquote><p>Collection 层次结构中的根接口。Collection 表示一组对象,这些对象也称为 collection 的元素。一些 collection 允许有重复的元素,而另一些则不允许。一些 collection 是有序的,而另一些则是无序的。JDK 不提供此接口的任何直接实现:它提供更具体的子接口(如 <code>Set</code> 和 <code>List</code>)实现。此接口通常用来传递 collection,并在需要最大普遍性的地方操作这些 collection。</p></blockquote><h2 id="AbstractCollection"><a href="#AbstractCollection" class="headerlink" title="AbstractCollection"></a>AbstractCollection</h2><p><code>AbstractCollection</code>抽象类提供了<code>Collection</code>接口的骨干实现,减少子类需要实现的方法,如<code>contains()</code>;</p><p><img src="https://imagebed.shaoyong.online/images/2019_08_30/AbstractCollection_contains.png" alt></p><h2 id="List"><a href="#List" class="headerlink" title="List"></a>List</h2><p><code>List</code>接口继承自<code>Collection</code>接口,该接口下的实现类为有序列表,可以根据索引访问其中的元素,可以有多个null元素。</p><h3 id="LinkedList"><a href="#LinkedList" class="headerlink" title="LinkedList"></a>LinkedList</h3><p><code>LinkedList</code>继承自<code>AbstractCollection</code>的子类<code>AbstractSequentialList</code>;<code>LinkedList</code>中定义了静态内部类<code>Node</code>,<code>Node</code>中定义了前驱与后继节点(<code>Node</code>),这实现了单向链表数据结构,单向链表的特性就是增删快。</p><p><img src="https://imagebed.shaoyong.online/images/2019_08_30/LinkedList_Node.png" alt></p><h4 id="get-1"><a href="#get-1" class="headerlink" title="get()"></a>get()</h4><p>先检查索引(下标)是否存在,不存在则抛出索引(下标)越界异常,</p><p><img src="https://imagebed.shaoyong.online/images/2019_08_30/LinkedList_get().png" alt></p><p><img src="https://imagebed.shaoyong.online/images/2019_08_30/LinkedList_checkElementIndex.png" alt></p><p>下标存在则调用<code>node(inde)</code>方法,这个方法会先判断下标是在前半还在是后半,在前半就从前往后遍历,在后半就从后往前遍历,这说明如果要找的索引在两头时,效率是很高的。</p><p><img src="https://imagebed.shaoyong.online/images/2019_08_30/LinkedList_node().png" alt></p><h4 id="set"><a href="#set" class="headerlink" title="set()"></a>set()</h4><p><code>set()</code>方法很简单,先根据索引遍历列表,获得<code>Node</code>后替换成新值。</p><p><img src="https://imagebed.shaoyong.online/images/2019_08_30/LinkedList_set().png" alt></p><h4 id="add"><a href="#add" class="headerlink" title="add()"></a>add()</h4><p><code>add()</code>方法被重载过,当只有一个参数时,直调用<code>linkLast()</code>将元素链接到链表最后面;</p><p><img src="https://imagebed.shaoyong.online/images/2019_08_30/LinkedList_add(e).png" alt></p><p><img src="https://imagebed.shaoyong.online/images/2019_08_30/LinkedList_linkLast.png" alt></p><p>两个参数时,先判断是不是尾节点,是位节点直接调用<code>linkLast()</code>方法;不是尾节点则调用<code>linkBefore()</code>方法;</p><p><img src="https://imagebed.shaoyong.online/images/2019_08_30/LinkedList_add(index,e).png" alt></p><p>查找到索引值处的节点(node),判断是不是头结点,最后就是链表的插入操作。</p><p><img src="https://imagebed.shaoyong.online/images/2019_08_30/LinkedList_linkBefore.png" alt></p><p><code>LinkedList</code>线程不安全,查询慢。由于定义了表头与表尾元素,所以也可以当做堆栈、队列和双向队列使用。</p><h3 id="ArrayList"><a href="#ArrayList" class="headerlink" title="ArrayList"></a>ArrayList</h3><p><code>ArrayList</code>继承自<code>AbstractList</code>并实现了<code>List</code>等接口。通过<code>ArrayList</code>提供的构造方法可已看出来,<code>ArrayList</code>是通过数组实现的;</p><p><img src="https://imagebed.shaoyong.online/images/2019_08_30/ArraayList_DTEE.png" alt></p><p><img src="https://imagebed.shaoyong.online/images/2019_08_30/ArrayList_().png" alt="ArrayList构造方法"></p><h4 id="get-2"><a href="#get-2" class="headerlink" title="get()"></a>get()</h4><p><code>get()</code>方法直接是通过数组索引(下标)取值</p><p><img src="https://imagebed.shaoyong.online/images/2019_08_30/ArrayList_get().png" alt></p><h4 id="set-1"><a href="#set-1" class="headerlink" title="set()"></a>set()</h4><p><code>set()</code>方法也是通过通过数组索引(下标)直接赋值</p><p><img src="https://imagebed.shaoyong.online/images/2019_08_30/ArrayList_set().png" alt></p><h4 id="add-1"><a href="#add-1" class="headerlink" title="add()"></a>add()</h4><p>两个<code>add()</code>方法在插入元素前都会对数组容量进行检查,容量不够时进行扩容;扩容完成后对数组进行复制;</p><p><img src="https://imagebed.shaoyong.online/images/2019_08_30/ArrayList_add().png" alt></p><p>扩容后的长度是之前长度的1.5倍+1。</p><p><img src="https://imagebed.shaoyong.online/images/2019_08_30/ArrayList_grow().png" alt></p><p><code>ArrayList</code>数据查询快,增删慢,线程不安全。</p><h3 id="Vector"><a href="#Vector" class="headerlink" title="Vector"></a>Vector</h3><p><code>Vector</code>继承自<code>AbstractList</code>并实现了<code>List</code>等接口;<code>Vector</code>与<code>ArrayList</code>基本一致,也是使用数组实现的;但是<code>Vector</code>的构造方法可以指定扩容参数</p><p><img src="https://imagebed.shaoyong.online/images/2019_08_30/Vector_().png" alt></p><p>在扩容方法<code>grow()</code>中,默认扩展一倍大小,也可增加指定大小</p><p><img src="https://imagebed.shaoyong.online/images/2019_08_30/Vector_grow().png" alt></p><p><code>Vector</code>与<code>ArrayList</code>最大的区别是,<code>Vector</code>的<code>public</code>方法都使用了<code>synchronized</code>来实现线程安全,这就降低了<code>Vector</code>的速度。</p><h2 id="Set"><a href="#Set" class="headerlink" title="Set"></a>Set</h2><p><code>Set</code>接口也继承自<code>Collection</code>接口,Set的实现类是不包含重复元素的集合,最多只能包含一个null元素;</p><h3 id="TreeSet"><a href="#TreeSet" class="headerlink" title="TreeSet"></a>TreeSet</h3><p><code>TreeSet</code>继承自<code>AbstractSet</code>实现了<code>Set</code>的子孙接口(<code>NavigableSet</code>),通过<code>TreeSet</code>的构造方法,可以发现,<code>TreeSet</code>内部是用<code>TreeMap</code>实现的,那么底层也是使用了二叉树做数据结构;自动内排序;</p><p><img src="https://imagebed.shaoyong.online/images/2019_08_30/TreeSet_().png" alt></p><h4 id="add-2"><a href="#add-2" class="headerlink" title="add()"></a>add()</h4><p><code>add()</code>方法其实调用的是<code>Map</code>的<code>put()</code>方法,<code>map</code>的key是需要存放的元素,而value是一个Object对象。这也是为什么<code>TreeSet</code>不能存放重复值得原因。</p><p><img src="https://imagebed.shaoyong.online/images/2019_08_30/TreeSet_add().png" alt></p><p><code>TreeSet</code>中的其他方法内也是对<code>Map</code>方法的调用。TreeMap的key不可以为空,value可以为空;</p><h3 id="HashSet"><a href="#HashSet" class="headerlink" title="HashSet"></a>HashSet</h3><p><code>HashSet</code>继承自<code>AbstractSet</code>并实现了<code>Set</code>等接口;通过构造方法,可以看出来,<code>HashSet</code>内部是使用<code>HashMap</code>实现的,底层也是使用了Hash表作为数据结构;</p><p><img src="https://imagebed.shaoyong.online/images/2019_08_30/HashSet_().png" alt></p><h4 id="add-3"><a href="#add-3" class="headerlink" title="add()"></a>add()</h4><p><code>HashSet</code>的<code>add()</code>方法使用的是<code>HashMap</code>的<code>put()</code>方法;</p><p><img src="https://imagebed.shaoyong.online/images/2019_08_30/HashSet_add().png" alt></p><p><code>HashSet</code>的其他方法也使用的是<code>HashMap</code>的响应方法进行封装。</p><h4 id="小结-1"><a href="#小结-1" class="headerlink" title="小结"></a>小结</h4><p><code>HashSet</code>不保证存取顺序一致,允许一个null,值唯一。</p><h2 id="LinkedHashSet"><a href="#LinkedHashSet" class="headerlink" title="LinkedHashSet"></a>LinkedHashSet</h2><p><code>LinkedHashSet</code>继承自<code>HashSet</code>,并实现了<code>Set</code>等接口;其构造方法直接调用了父类的3个参数的构造方法,在父类的构造方法中创建<code>LinkedHashMap</code>对象;可以看出来<code>LinkedHashSet</code>底层使用了链表加Hash表作为数据结构。既保证数据的存取顺序,也保证了值得唯一性;</p><p><img src="https://imagebed.shaoyong.online/images/2019_08_30/LinkedHashSet_().png" alt></p>]]></content>
<summary type="html">
<p>在Java中集合是常用的数据结构,而<code>Map</code>与<code>Collection</code>的实现类有很多,我们常见的有<code>HashMap</code>、<code>HashTable</code>、<code>TreeMap</code>、<code>LinkedHashMap</code>、<code>ArrayList</code>、<code>Linkedlist</code>、<code>Vector</code>、<code>HashSet</code>、<code>TreeSet</code>、<code>LinkedHashSet</code>;</p>
<p>下面从源码的层面简析这些实现类的特性;</p>
</summary>
<category term="Java" scheme="http://www.shaoyong.online/categories/Java/"/>
<category term="Map" scheme="http://www.shaoyong.online/tags/Map/"/>
<category term="Collection" scheme="http://www.shaoyong.online/tags/Collection/"/>
</entry>
<entry>
<title>Java 设计模式之桥接模式</title>
<link href="http://www.shaoyong.online/posts/2375/"/>
<id>http://www.shaoyong.online/posts/2375/</id>
<published>2019-08-23T08:08:50.380Z</published>
<updated>2019-09-15T10:34:45.985Z</updated>
<content type="html"><![CDATA[<blockquote><p>桥接(Bridge)是用于把抽象化与实现化解耦,使得二者可以独立变化。这种类型的设计模式属于结构型模式,它通过提供抽象化和实现化之间的桥接结构,来实现二者的解耦。</p></blockquote><p>简单来说,可以通过桥接模式实现使用相同的抽象方法、不同的桥接实现类获得不同的结果。</p><a id="more"></a><p>猪八戒转世成为猪,孙悟空是转世成为猴子,他们的“灵魂”是同类的,但“肉身”不同。下面用代码来模拟这种关系;</p><h2 id="类继承-实现关系简图"><a href="#类继承-实现关系简图" class="headerlink" title="类继承/实现关系简图"></a>类继承/实现关系简图</h2><p><img src="https://imagebed.shaoyong.online/images/2019_08_23/bridge.png" alt></p><h2 id="具体实现"><a href="#具体实现" class="headerlink" title="具体实现"></a>具体实现</h2><ol><li><p>创建转世接口</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">interface</span> <span class="title">TurnAPI</span> </span>{</span><br><span class="line"> <span class="comment">/** 转世肉体 */</span></span><br><span class="line"> <span class="function"><span class="keyword">public</span> String <span class="title">body</span><span class="params">()</span></span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure></li><li><p>创建转世接口的实现类</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Pig</span> <span class="keyword">implements</span> <span class="title">TurnAPI</span> </span>{</span><br><span class="line"> <span class="meta">@Override</span></span><br><span class="line"> <span class="function"><span class="keyword">public</span> String <span class="title">body</span><span class="params">()</span> </span>{</span><br><span class="line"> <span class="keyword">return</span> <span class="string">"猪!"</span>;</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Monkey</span> <span class="keyword">implements</span> <span class="title">TurnAPI</span> </span>{</span><br><span class="line"> <span class="meta">@Override</span></span><br><span class="line"> <span class="function"><span class="keyword">public</span> String <span class="title">body</span><span class="params">()</span> </span>{</span><br><span class="line"> <span class="keyword">return</span> <span class="string">"猴子!"</span>;</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure></li><li><p>创建抽象灵魂类</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><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">public</span> <span class="keyword">abstract</span> <span class="class"><span class="keyword">class</span> <span class="title">Soul</span> </span>{</span><br><span class="line"> <span class="comment">/** 将TurnAPI作为属性注入Soul,这是实现桥接的关键 */</span></span><br><span class="line"> <span class="keyword">protected</span> TurnAPI turnAPI;</span><br><span class="line"> <span class="keyword">private</span> String name;</span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="title">Soul</span><span class="params">(String name, TurnAPI turnAPI)</span> </span>{</span><br><span class="line"> <span class="keyword">this</span>.name = name;</span><br><span class="line"> <span class="keyword">this</span>.turnAPI=turnAPI;</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">public</span> String <span class="title">getName</span><span class="params">()</span> </span>{</span><br><span class="line"> <span class="keyword">return</span> name;</span><br><span class="line"> }</span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">abstract</span> String <span class="title">body</span><span class="params">()</span></span>;</span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">abstract</span> String <span class="title">type</span><span class="params">()</span></span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure></li><li><p>创建抽象灵魂类的子类</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">God</span> <span class="keyword">extends</span> <span class="title">Soul</span></span>{</span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="title">God</span><span class="params">(String name, TurnAPI turnAPI)</span> </span>{</span><br><span class="line"> <span class="keyword">super</span>(name, turnAPI);</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="meta">@Override</span></span><br><span class="line"> <span class="function"><span class="keyword">public</span> String <span class="title">body</span><span class="params">()</span> </span>{</span><br><span class="line"> <span class="keyword">return</span> turnAPI.body();</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="meta">@Override</span></span><br><span class="line"> <span class="function"><span class="keyword">public</span> String <span class="title">type</span><span class="params">()</span> </span>{</span><br><span class="line"> <span class="keyword">return</span> <span class="string">"神"</span>;</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Monster</span> <span class="keyword">extends</span> <span class="title">Soul</span></span>{</span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="title">Monster</span><span class="params">(String name, TurnAPI turnAPI)</span> </span>{</span><br><span class="line"> <span class="keyword">super</span>(name, turnAPI);</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="meta">@Override</span></span><br><span class="line"> <span class="function"><span class="keyword">public</span> String <span class="title">body</span><span class="params">()</span> </span>{</span><br><span class="line"> <span class="keyword">return</span> turnAPI.body();</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="meta">@Override</span></span><br><span class="line"> <span class="function"><span class="keyword">public</span> String <span class="title">type</span><span class="params">()</span> </span>{</span><br><span class="line"> <span class="keyword">return</span> <span class="string">"妖"</span>;</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure></li><li><p>创建测试类</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Test</span> </span>{</span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>{</span><br><span class="line"> Soul tianPeng = <span class="keyword">new</span> God(<span class="string">"猪八戒"</span>, <span class="keyword">new</span> Pig());</span><br><span class="line"> Soul monkeyKing = <span class="keyword">new</span> God(<span class="string">"孙悟空"</span>, <span class="keyword">new</span> Monkey());</span><br><span class="line"> Soul sixEar = <span class="keyword">new</span> Monster(<span class="string">"六耳猕猴"</span>, <span class="keyword">new</span> Monkey());</span><br><span class="line"> System.out.println(<span class="string">"灵魂:"</span> + tianPeng.getName() + <span class="string">",肉身:"</span> + tianPeng.body()+<span class="string">",属性:"</span>+tianPeng.type());</span><br><span class="line"> System.out.println(<span class="string">"灵魂:"</span> + monkeyKing.getName() + <span class="string">",肉身:"</span> + monkeyKing.body()+<span class="string">",属性:"</span>+monkeyKing.type());</span><br><span class="line"> System.out.println(<span class="string">"灵魂:"</span> + sixEar.getName() + <span class="string">",肉身:"</span> + sixEar.body()+<span class="string">",属性:"</span>+sixEar.type());</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>执行结果</p><p><img src="https://imagebed.shaoyong.online/images/2019_08_23/test_result.png" alt></p></li></ol><h2 id="小结"><a href="#小结" class="headerlink" title="小结"></a>小结</h2><p>通过上面代码,实现了将猪八戒的灵魂放进了猪的肉体内,将孙悟空的灵魂放进了猴子的肉体内;灵魂的具体类也有妖和神的区别,上面也实现了将六耳猕猴的灵魂放进猴子肉体中,当然也可以放进猪内;</p><p>由上可知,桥接模式适用于两个独立变化的维度之间。通过桥接模式,我们可以将不同的实现类和不同的接口实现进行连接。使用桥接模式避免了抽象类实现接口,抽象与实现分离;由于桥接模式是在抽象层面建立关联关系,这也加大了系统的设计与理解难度。</p>]]></content>
<summary type="html">
<blockquote>
<p>桥接(Bridge)是用于把抽象化与实现化解耦,使得二者可以独立变化。这种类型的设计模式属于结构型模式,它通过提供抽象化和实现化之间的桥接结构,来实现二者的解耦。</p>
</blockquote>
<p>简单来说,可以通过桥接模式实现使用相同的抽象方法、不同的桥接实现类获得不同的结果。</p>
</summary>
<category term="Java" scheme="http://www.shaoyong.online/categories/Java/"/>
<category term="设计模式" scheme="http://www.shaoyong.online/categories/Java/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/"/>
<category term="Bridge Pattern" scheme="http://www.shaoyong.online/tags/Bridge-Pattern/"/>
</entry>
<entry>
<title>Java 设计模式之适配器模式</title>
<link href="http://www.shaoyong.online/posts/21579/"/>
<id>http://www.shaoyong.online/posts/21579/</id>
<published>2019-08-22T08:55:57.189Z</published>
<updated>2019-09-15T10:34:45.988Z</updated>
<content type="html"><![CDATA[<p>适配器模式(Adapter Pattern)是不兼容接口之间的桥梁,可以使一个类加入独立的或不兼容的接口功能。比如计算机通过适配器读取之前无法读取的TF卡;下面用Java模拟这一过程的实现;</p><a id="more"></a><p>计算机本身可以读取SD卡,通过适配器读取TF卡。</p><h2 id="类继承-实现关系简图"><a href="#类继承-实现关系简图" class="headerlink" title="类继承/实现关系简图"></a>类继承/实现关系简图</h2><p><img src="https://imagebed.shaoyong.online/images/2019_8_22/adapter_patterns_example.png" alt></p><h2 id="具体实现"><a href="#具体实现" class="headerlink" title="具体实现"></a>具体实现</h2><ol><li><p>先创建个SD卡接口</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">interface</span> <span class="title">SdCard</span> </span>{</span><br><span class="line"> <span class="comment">/**读sd卡*/</span></span><br><span class="line"> <span class="function">String <span class="title">readSdCard</span><span class="params">()</span></span>;</span><br><span class="line"></span><br><span class="line"> <span class="comment">/** 写sd卡*/</span></span><br><span class="line"> <span class="function"><span class="keyword">int</span> <span class="title">writeSdCard</span><span class="params">(String msg)</span></span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure></li><li><p>创建SD卡接口的实现类,模拟SD卡功能</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">SdCardImpl</span> <span class="keyword">implements</span> <span class="title">SdCard</span> </span>{</span><br><span class="line"> <span class="meta">@Override</span></span><br><span class="line"> <span class="function"><span class="keyword">public</span> String <span class="title">readSdCard</span><span class="params">()</span> </span>{</span><br><span class="line"> <span class="keyword">return</span> <span class="string">"欢迎使用Sd卡"</span>;</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="meta">@Override</span></span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">writeSdCard</span><span class="params">(String msg)</span> </span>{</span><br><span class="line"> System.out.println(<span class="string">"SD写入信息:"</span>+msg);</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><br></pre></td></tr></table></figure></li><li><p>创建个计算机接口</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">interface</span> <span class="title">Computer</span> </span>{</span><br><span class="line"> <span class="comment">/**读取SD卡*/</span></span><br><span class="line"> <span class="function">String <span class="title">readSdCard</span><span class="params">(SdCard sdCard)</span></span>;</span><br><span class="line"></span><br><span class="line"> <span class="comment">/**写入sd卡*/</span></span><br><span class="line"> <span class="function"><span class="keyword">void</span> <span class="title">writeSdCard</span><span class="params">(SdCard sdCard,String msg)</span></span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure></li><li><p>创建计算机接口的实现类,模拟计算机对SD卡的读写操作</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">MacComputer</span> <span class="keyword">implements</span> <span class="title">Computer</span> </span>{</span><br><span class="line"> <span class="meta">@Override</span></span><br><span class="line"> <span class="function"><span class="keyword">public</span> String <span class="title">readSdCard</span><span class="params">(SdCard sdCard)</span> </span>{</span><br><span class="line"> <span class="keyword">if</span> (sdCard == <span class="keyword">null</span>) {</span><br><span class="line"> <span class="keyword">throw</span> <span class="keyword">new</span> NullPointerException(<span class="string">"未放入sd卡!"</span>);</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> sdCard.readSdCard();</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="meta">@Override</span></span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">writeSdCard</span><span class="params">(SdCard sdCard, String msg)</span> </span>{</span><br><span class="line"> <span class="keyword">if</span> (sdCard == <span class="keyword">null</span> || msg.isEmpty()) {</span><br><span class="line"> <span class="keyword">throw</span> <span class="keyword">new</span> NullPointerException(<span class="string">"写入sd卡失败!"</span>);</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">if</span> (sdCard.writeSdCard(msg)==<span class="number">1</span>) {</span><br><span class="line"> System.out.println(<span class="string">"写入完成!"</span>);</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure></li><li><p>现在创建一个测试类,模拟计算机读取SD卡</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Test</span> </span>{</span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>{</span><br><span class="line"> Computer macComputer = <span class="keyword">new</span> MacComputer();</span><br><span class="line"> SdCard sdCard = <span class="keyword">new</span> SdCardImpl();</span><br><span class="line"> System.out.println(<span class="string">"读出信息:"</span>+macComputer.readSdCard(sdCard));</span><br><span class="line"> macComputer.writeSdCard(sdCard,<span class="string">"sd写入测试。。。"</span>);</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>执行结果</p><p><img src="https://imagebed.shaoyong.online/images/2019_8_22/testSd.png" alt></p></li></ol><p>计算机已经读取SD卡成功,下面在不改变计算机读取SD卡接口的前提下,使用适配器实现读取TF卡;</p><ol start="6"><li><p>创建TF卡接口</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">interface</span> <span class="title">TfCard</span> </span>{</span><br><span class="line"> <span class="comment">/** 读Tf卡 */</span></span><br><span class="line"> <span class="function">String <span class="title">readTfCard</span><span class="params">()</span></span>;</span><br><span class="line"></span><br><span class="line"> <span class="comment">/** 写入Tf卡*/</span></span><br><span class="line"> <span class="function"><span class="keyword">int</span> <span class="title">writeTfCard</span><span class="params">(String msg)</span></span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure></li><li><p>创建TF卡接口的实现类,同样模拟TF卡功能</p> <figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">TfCardImpl</span> <span class="keyword">implements</span> <span class="title">TfCard</span> </span>{</span><br><span class="line"> <span class="meta">@Override</span></span><br><span class="line"> <span class="function"><span class="keyword">public</span> String <span class="title">readTfCard</span><span class="params">()</span> </span>{</span><br><span class="line"> <span class="keyword">return</span> <span class="string">"欢迎使用TF卡"</span>;</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="meta">@Override</span></span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">writeTfCard</span><span class="params">(String msg)</span> </span>{</span><br><span class="line"> System.out.println(<span class="string">"TF写入信息:"</span>+msg);</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><br></pre></td></tr></table></figure></li><li><p>创建SD适配TF的适配器</p> <figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">SdAdapterTf</span> <span class="keyword">implements</span> <span class="title">SdCard</span> </span>{</span><br><span class="line"> <span class="comment">/**将TfCard作为属性引入适配器*/</span></span><br><span class="line"> <span class="keyword">private</span> TfCard tfCard;</span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="title">SdAdapterTf</span><span class="params">(TfCard tfCard)</span> </span>{</span><br><span class="line"> <span class="keyword">this</span>.tfCard = tfCard;</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="meta">@Override</span></span><br><span class="line"> <span class="function"><span class="keyword">public</span> String <span class="title">readSdCard</span><span class="params">()</span> </span>{</span><br><span class="line"> System.out.println(<span class="string">"适配器读TF卡"</span>);</span><br><span class="line"> <span class="keyword">return</span> tfCard.readTfCard();</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="meta">@Override</span></span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">writeSdCard</span><span class="params">(String msg)</span> </span>{</span><br><span class="line"> System.out.println(<span class="string">"适配器写TF卡"</span>);</span><br><span class="line"> tfCard.writeTfCard(msg);</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><br></pre></td></tr></table></figure></li><li><p>测试,模拟计算机读取TF卡</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Test</span> </span>{</span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>{</span><br><span class="line"> Computer macComputer = <span class="keyword">new</span> MacComputer();</span><br><span class="line"> SdCard sdCard = <span class="keyword">new</span> SdCardImpl();</span><br><span class="line"> System.out.println(<span class="string">"读出信息:"</span>+macComputer.readSdCard(sdCard));</span><br><span class="line"> macComputer.writeSdCard(sdCard,<span class="string">"sd写入测试。。。"</span>);</span><br><span class="line"> System.out.println(<span class="string">"================================"</span>);</span><br><span class="line"> TfCard tfCard = <span class="keyword">new</span> TfCardImpl();</span><br><span class="line"> SdAdapterTf sdAdapterTf = <span class="keyword">new</span> SdAdapterTf(tfCard);</span><br><span class="line"> System.out.println(<span class="string">"读出信息:"</span>+macComputer.readSdCard(sdAdapterTf));</span><br><span class="line"> macComputer.writeSdCard(sdAdapterTf,<span class="string">"Tf写入测试"</span>);</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>执行结果</p><p><img src="https://imagebed.shaoyong.online/images/2019_8_22/testTf.png" alt></p></li></ol><h2 id="小结"><a href="#小结" class="headerlink" title="小结"></a>小结</h2><p>因为不能改变<code>computer</code>类的<code>SDCard</code>接口,所以适配器需要实现<code>SDCard</code>接口,保证适配器能“插入”<code>computer</code>,而将<code>TFCard</code>作为私有属性引入适配器,实现了将<code>TFCard</code>插入适配器,通过以上过程,TF卡成功被计算机读取;</p><p>适配器模式是Java多态的完美体现,不仅拓展了功能,还对原有代码无侵入性。但是,适配器并不适合在程序设计时应用,因为当适配器变多后,对接口的调用不再清晰,如对接口A的调用,可能在A内调用了B接口,这将导致接口混乱。更好的使用情况是在系统正常运行时,为了兼容新接口而有机的使用。</p>]]></content>
<summary type="html">
<p>适配器模式(Adapter Pattern)是不兼容接口之间的桥梁,可以使一个类加入独立的或不兼容的接口功能。比如计算机通过适配器读取之前无法读取的TF卡;下面用Java模拟这一过程的实现;</p>
</summary>
<category term="Java" scheme="http://www.shaoyong.online/categories/Java/"/>
<category term="设计模式" scheme="http://www.shaoyong.online/categories/Java/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/"/>
<category term="Adapter Pattern" scheme="http://www.shaoyong.online/tags/Adapter-Pattern/"/>
</entry>
<entry>
<title>IntelliJ IDEA中常见的Icon代表什么意义</title>
<link href="http://www.shaoyong.online/posts/47185/"/>
<id>http://www.shaoyong.online/posts/47185/</id>
<published>2019-08-19T05:20:29.845Z</published>
<updated>2019-09-15T10:34:45.982Z</updated>
<content type="html"><![CDATA[<p>在使用IDEA时发现有些Icon不知道是什么意思,什么时候会出现,下面是常遇到的一些Icon,在此记录一下。</p><p>摘自IntelliJ IDEA 2019.2<a href="https://www.jetbrains.com/help/idea/symbols.html#Symbols.xml" target="_blank" rel="noopener">官方帮助文档</a>。</p><a id="more"></a><h1 id="common"><a href="#common" class="headerlink" title="common"></a>common</h1><table><thead><tr><th align="center">Icon</th><th>Description</th></tr></thead><tbody><tr><td align="center"><img src="https://www.jetbrains.com/help/img/idea/2019.2/[email protected]" width="32" alt="class"></td><td>java编译后生成的字节码文件</td></tr><tr><td align="center"><img src="https://www.jetbrains.com/help/img/idea/2019.2/[email protected]" width="32" alt="Abstract class"></td><td>抽象类</td></tr><tr><td align="center"><img src="https://www.jetbrains.com/help/img/idea/2019.2/[email protected]" width="32" alt="Annotation"></td><td>注解类</td></tr><tr><td align="center"><img src="https://www.jetbrains.com/help/img/idea/2019.2/[email protected]" width="32" alt="Enumeration"></td><td>枚举类</td></tr><tr><td align="center"><img src="https://www.jetbrains.com/help/img/idea/2019.2/[email protected]" width="32" alt="Exception"></td><td>异常类</td></tr><tr><td align="center"><img src="https://www.jetbrains.com/help/img/idea/2019.2/[email protected]" width="32" alt="Final Java class"></td><td><code>final</code>修饰的类 如<code>String</code>类</td></tr><tr><td align="center"><img src="https://www.jetbrains.com/help/img/idea/2019.2/[email protected]" width="32" alt="Interface"></td><td>接口</td></tr><tr><td align="center"><img alt="Java class with the Main method" src="https://www.jetbrains.com/help/img/idea/2019.2/classTypeMain.png" width="32" class="inline-icon-15"></td><td>含<code>main()</code>方法的类</td></tr><tr><td align="center"><img alt="Test case" src="https://www.jetbrains.com/help/img/idea/2019.2/classTypeTestCase.png" width="32"></td><td>测试用例</td></tr><tr><td align="center"><img src="https://www.jetbrains.com/help/img/idea/2019.2/[email protected]" width="32" alt="Method"></td><td>方法</td></tr><tr><td align="center"><img src="https://www.jetbrains.com/help/img/idea/2019.2/[email protected]" width="32" alt="Abstract method"></td><td>抽象方法</td></tr><tr><td align="center"><img src="https://www.jetbrains.com/help/img/idea/2019.2/[email protected]" width="32" alt="Field"></td><td>字段(成员变量)</td></tr><tr><td align="center"><img src="https://www.jetbrains.com/help/img/idea/2019.2/[email protected]" width="32" alt="Variable"></td><td>变量(局部变量)</td></tr><tr><td align="center"><img src="https://www.jetbrains.com/help/img/idea/2019.2/[email protected]" width="32" alt="Parameter"></td><td>参数</td></tr><tr><td align="center"><img alt="Element" src="https://www.jetbrains.com/help/img/idea/2019.2/xml_element.png" width="32" height="12" class="inline-icon-15"></td><td>元素</td></tr><tr><td align="center"><img src="https://www.jetbrains.com/help/img/idea/2019.2/[email protected]" width="32" alt="Directory"></td><td>目录</td></tr><tr><td align="center"><img src="https://www.jetbrains.com/help/img/idea/2019.2/[email protected]" width="32" alt="Module"></td><td>模块</td></tr><tr><td align="center"><img src="https://www.jetbrains.com/help/img/idea/2019.2/[email protected]" width="32" alt="Group of modules"></td><td>模块组</td></tr><tr><td align="center"><img src="https://www.jetbrains.com/help/img/idea/2019.2/[email protected]" width="32" alt="Package"></td><td>包</td></tr><tr><td align="center"><img src="https://www.jetbrains.com/help/img/idea/2019.2/[email protected]" width="32" alt="Sources Root"></td><td>源文件根目录</td></tr><tr><td align="center"><img src="https://www.jetbrains.com/help/img/idea/2019.2/[email protected]" width="32" alt="Test Root"></td><td>测试根目录</td></tr><tr><td align="center"><img src="https://www.jetbrains.com/help/img/idea/2019.2/[email protected]" width="32" alt="Excluded root"></td><td>不编译的根目录,一般存放编译后的<code>.class</code>文件</td></tr><tr><td align="center"><img src="https://www.jetbrains.com/help/img/idea/2019.2/[email protected]" width="32" alt="Resources Root"></td><td>资源根目录,一般存放配置文件和web页面相关文件如<code>.ftl</code>、<code>.js</code>、<code>.css</code></td></tr><tr><td align="center"><img src="https://www.jetbrains.com/help/img/idea/2019.2/[email protected]" width="32" alt="Test Resources Root"></td><td>测试用资源根目录</td></tr></tbody></table><h1 id="Visibility-modifiers"><a href="#Visibility-modifiers" class="headerlink" title="Visibility modifiers"></a>Visibility modifiers</h1><p>对类或方法的修饰符</p><table><thead><tr><th align="center">Icon</th><th>Description</th></tr></thead><tbody><tr><td align="center"><img src="https://www.jetbrains.com/help/img/idea/2019.2/[email protected]" width="32" alt="Read-only class"></td><td>只读的类,如引入的外部Jar包</td></tr><tr><td align="center"><img src="https://www.jetbrains.com/help/img/idea/2019.2/[email protected]" width="32" alt="Private"></td><td>私有的</td></tr><tr><td align="center"><img src="https://www.jetbrains.com/help/img/idea/2019.2/[email protected]" width="32" alt="Protected"></td><td>受保护的</td></tr><tr><td align="center"><img alt="package protected" src="https://www.jetbrains.com/help/img/idea/2019.2/package_protected.png" id="e0a644f7" width="18" height="12"></td><td>包内可访问的</td></tr><tr><td align="center"><img src="https://www.jetbrains.com/help/img/idea/2019.2/[email protected]" width="32" alt="Static"></td><td>静态的</td></tr><tr><td align="center"><img src="https://www.jetbrains.com/help/img/idea/2019.2/[email protected]" width="32" alt="Public"></td><td>公开的</td></tr></tbody></table>]]></content>
<summary type="html">
<p>在使用IDEA时发现有些Icon不知道是什么意思,什么时候会出现,下面是常遇到的一些Icon,在此记录一下。</p>
<p>摘自IntelliJ IDEA 2019.2<a href="https://www.jetbrains.com/help/idea/symbols.html#Symbols.xml" target="_blank" rel="noopener">官方帮助文档</a>。</p>
</summary>
<category term="笔记" scheme="http://www.shaoyong.online/categories/%E7%AC%94%E8%AE%B0/"/>
<category term="IDEA" scheme="http://www.shaoyong.online/tags/IDEA/"/>
</entry>
<entry>
<title>Java 中使用Lambda表达式</title>
<link href="http://www.shaoyong.online/posts/38346/"/>
<id>http://www.shaoyong.online/posts/38346/</id>
<published>2019-08-16T02:11:16.618Z</published>
<updated>2019-09-15T10:34:46.033Z</updated>
<content type="html"><![CDATA[<blockquote><p>Lambda表达式是一个可传递的代码块,可以在以后执行一次或多次。使用Lambda表达式的重点是<strong>延迟执行</strong>(<em>deferred execution</em>)。</p></blockquote><h3 id="语法"><a href="#语法" class="headerlink" title="语法"></a>语法</h3><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">(Type param1,Type param2,Type param3) -> {</span><br><span class="line"><span class="comment">//TODO</span></span><br><span class="line">}</span><br></pre></td></tr></table></figure><ol><li>参数类型可以省略,编译器可以根据上下文推导;但并不是所有类型都能推导出来,有时需要声明参数类型;</li><li>当参数只有一个时,小/圆括号可以省略;</li><li>当主体只有一条语句时,大括号可以省略;</li><li>当主体只有一条语句时,<code>return</code>可以省略;</li></ol><h3 id="实例"><a href="#实例" class="headerlink" title="实例"></a>实例</h3><p>参考自<a href="https://www.runoob.com/java/java8-lambda-expressions.html" target="_blank" rel="noopener">runoob.com</a>。</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Java8Test</span> </span>{</span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>{</span><br><span class="line"> Java8Test test = <span class="keyword">new</span> Java8Test();</span><br><span class="line"> <span class="comment">//函数式接口实例</span></span><br><span class="line"> <span class="comment">//类型声明</span></span><br><span class="line"> MathOperation addition = (<span class="keyword">int</span> a, <span class="keyword">int</span> b) -> a + b;</span><br><span class="line"> <span class="comment">//不用类型声明</span></span><br><span class="line"> MathOperation subtraction = (a, b) -> a - b;</span><br><span class="line"> <span class="comment">//大括号中有返回语句</span></span><br><span class="line"> MathOperation multiplication = (a, b) -> {</span><br><span class="line"> <span class="keyword">return</span> a * b;</span><br><span class="line"> };</span><br><span class="line"> <span class="comment">//没有大括号及返回语句</span></span><br><span class="line"> MathOperation division = (<span class="keyword">int</span> a, <span class="keyword">int</span> b) -> a / b;</span><br><span class="line"></span><br><span class="line"> <span class="comment">//函数式编程,将函数作为参数传入一个方法</span></span><br><span class="line"> System.out.println(<span class="string">"10+5="</span> + test.operate(<span class="number">10</span>, <span class="number">5</span>, addition));</span><br><span class="line"> System.out.println(<span class="string">"10-5="</span> + test.operate(<span class="number">10</span>, <span class="number">5</span>, subtraction));</span><br><span class="line"> System.out.println(<span class="string">"10*b="</span> + test.operate(<span class="number">10</span>, <span class="number">5</span>, multiplication));</span><br><span class="line"> System.out.println(<span class="string">"10/5="</span> + test.operate(<span class="number">10</span>, <span class="number">5</span>, division));</span><br><span class="line"></span><br><span class="line"> <span class="comment">//单个参数可以省略括号</span></span><br><span class="line"> GreetingService greetingService1 = message -> System.out.println(<span class="string">"Hello"</span> + message);</span><br><span class="line"> <span class="comment">//不省略括号</span></span><br><span class="line"> GreetingService greetingService2 = (message) -> System.out.println(<span class="string">"Hello"</span> + message);</span><br><span class="line"> greetingService1.sayMessage(<span class="string">"World"</span>);</span><br><span class="line"> greetingService2.sayMessage(<span class="string">"Lambda"</span>);</span><br><span class="line"> }</span><br><span class="line"> </span><br><span class="line"> <span class="class"><span class="keyword">interface</span> <span class="title">MathOperation</span> </span>{</span><br><span class="line"> <span class="function"><span class="keyword">int</span> <span class="title">operation</span><span class="params">(<span class="keyword">int</span> a, <span class="keyword">int</span> b)</span></span>;</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="meta">@FunctionalInterface</span></span><br><span class="line"> <span class="class"><span class="keyword">interface</span> <span class="title">GreetingService</span> </span>{</span><br><span class="line"> <span class="function"><span class="keyword">void</span> <span class="title">sayMessage</span><span class="params">(String message)</span></span>;</span><br><span class="line"> <span class="comment">//void sayMessage(String name,String message);</span></span><br><span class="line"> <span class="meta">@Override</span></span><br><span class="line"> <span class="function">String <span class="title">toString</span><span class="params">()</span></span>;</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">private</span> <span class="keyword">int</span> <span class="title">operate</span><span class="params">(<span class="keyword">int</span> a, <span class="keyword">int</span> b, MathOperation mathOperation)</span> </span>{</span><br><span class="line"> <span class="keyword">return</span> mathOperation.operation(a, b);</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p> 上面的实例中,将<code>MathOperation</code>接口(函数)做为参数传递给<code>operate</code>方法,返回的也是一个方法(函数),这在java 8 之前是无法做到的。这也是java 8的另一新特性,函数式编程;支持函数式编程的语言有很多,如Python、JavaScript等。</p><blockquote><p><strong>在java中Lambda表达式是对象,它必须依附于一类特别的对象类型——函数式接口(Functional Interface)</strong></p></blockquote><p> 函数式接口的定义:如果一个接口中,有且只有一个抽象的方法(Object类中的方法不包括在内),那这个接口就可以被看做是函数式接口。</p><p> 回到上面的实例中,<code>MathOperation</code>接口与<code>GreetingService</code>接口都是函数式接口,其中<code>GreetingService</code>内重写了<code>Object</code>类的<code>toString</code>方法,注解<code>@FunctionalInterface</code>用于声明该接口为函数式接口,如果某个接口(如<code>MathOperation</code>)满足函数式接口定义,编译器也会认为这是一个函数式接口;函数式接口内的方法不可以重载;</p><h3 id="变量作用域"><a href="#变量作用域" class="headerlink" title="变量作用域"></a>变量作用域</h3><ol><li>Lambda 表达式只能引用声明为<code>final</code>的外层局部变量。</li><li>Lambda 表达式中使用局部变量时,该局部变量可以不用声明为<code>final</code>,但是必须不可被后面的代码修改(即隐性的具有<code>final</code>的语义)。</li><li>在 Lambda 表达式当中不允许声明一个与局部变量同名的参数或者局部变量。</li><li>在 Lambda 表达式中使用<code>this</code>关键字时,是指创建这个Lambda表达式的方法的<code>this</code>参数。</li></ol>]]></content>
<summary type="html">
Lambda 是Java 8引入的新特性之一
</summary>
<category term="Java" scheme="http://www.shaoyong.online/categories/Java/"/>
<category term="Lambda" scheme="http://www.shaoyong.online/tags/Lambda/"/>
<category term="Java 8新特性" scheme="http://www.shaoyong.online/tags/Java-8%E6%96%B0%E7%89%B9%E6%80%A7/"/>
</entry>
<entry>
<title>Python 3 实现常见排序算法</title>
<link href="http://www.shaoyong.online/posts/59966/"/>
<id>http://www.shaoyong.online/posts/59966/</id>
<published>2019-08-10T14:23:53.747Z</published>
<updated>2019-09-15T10:34:46.046Z</updated>
<content type="html"><![CDATA[<h5 id="直接插入排序"><a href="#直接插入排序" class="headerlink" title="直接插入排序"></a>直接插入排序</h5><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">insertion_sort</span><span class="params">(arr)</span>:</span></span><br><span class="line"> <span class="string">"""直接插入排序"""</span></span><br><span class="line"> <span class="keyword">for</span> i <span class="keyword">in</span> range(<span class="number">1</span>, len(arr)):</span><br><span class="line"> <span class="keyword">for</span> j <span class="keyword">in</span> range(<span class="number">0</span>, i):</span><br><span class="line"> <span class="keyword">if</span> arr[i] < arr[j]:</span><br><span class="line"> arr.insert(j, arr.pop(i))</span><br><span class="line"> print(<span class="string">"第{}轮排序后结果为:{}"</span>.format(i, arr))</span><br><span class="line"> <span class="keyword">return</span> arr</span><br></pre></td></tr></table></figure><h5 id="快速排序"><a href="#快速排序" class="headerlink" title="快速排序"></a>快速排序</h5><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">quick_partition</span><span class="params">(arr, low, high)</span>:</span></span><br><span class="line"> i = (low - <span class="number">1</span>) <span class="comment"># 最小元素索引</span></span><br><span class="line"> pivot = arr[high]</span><br><span class="line"> <span class="keyword">for</span> j <span class="keyword">in</span> range(low, high):</span><br><span class="line"> <span class="comment"># 当前元素小于或等于 pivot</span></span><br><span class="line"> <span class="keyword">if</span> arr[j] <= pivot:</span><br><span class="line"> i = i + <span class="number">1</span></span><br><span class="line"> arr[i], arr[j] = arr[j], arr[i]</span><br><span class="line"> arr[i + <span class="number">1</span>], arr[high] = arr[high], arr[i + <span class="number">1</span>]</span><br><span class="line"> <span class="keyword">return</span> i + <span class="number">1</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">quick_sort</span><span class="params">(arr, low, high)</span>:</span></span><br><span class="line"> <span class="string">"""快速排序"""</span></span><br><span class="line"> <span class="keyword">if</span> low < high:</span><br><span class="line"> temp = quick_partition(arr, low, high)</span><br><span class="line"> quick_sort(arr, low, temp - <span class="number">1</span>)</span><br><span class="line"> quick_sort(arr, temp + <span class="number">1</span>, high)</span><br></pre></td></tr></table></figure><h5 id="选择排序"><a href="#选择排序" class="headerlink" title="选择排序"></a>选择排序</h5><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">select_sort</span><span class="params">(arr)</span>:</span></span><br><span class="line"> <span class="string">"""选择排序"""</span></span><br><span class="line"> sort_list = []</span><br><span class="line"> min_index = <span class="number">0</span></span><br><span class="line"> <span class="keyword">while</span> len(arr) != <span class="number">0</span>:</span><br><span class="line"> <span class="comment"># 取出余下数列中最小的值的索引</span></span><br><span class="line"> <span class="keyword">for</span> i <span class="keyword">in</span> range(<span class="number">0</span>, len(arr)):</span><br><span class="line"> <span class="keyword">if</span> arr[i] < arr[min_index]:</span><br><span class="line"> min_index = i</span><br><span class="line"> <span class="comment"># 将值取出放入新数组</span></span><br><span class="line"> sort_list.append(arr.pop(min_index))</span><br><span class="line"> <span class="comment"># 归零索引</span></span><br><span class="line"> min_index = <span class="number">0</span></span><br><span class="line"> <span class="keyword">return</span> sort_list</span><br></pre></td></tr></table></figure><h5 id="冒泡排序"><a href="#冒泡排序" class="headerlink" title="冒泡排序"></a>冒泡排序</h5><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">bubble_sort</span><span class="params">(arr)</span>:</span></span><br><span class="line"> <span class="string">"""冒泡排序"""</span></span><br><span class="line"> <span class="keyword">for</span> t <span class="keyword">in</span> range(len(arr) - <span class="number">1</span>):</span><br><span class="line"> <span class="keyword">for</span> i <span class="keyword">in</span> range(len(arr) - <span class="number">1</span> - t):</span><br><span class="line"> <span class="keyword">if</span> arr[i] > arr[i + <span class="number">1</span>]:</span><br><span class="line"> arr[i], arr[i + <span class="number">1</span>] = arr[i + <span class="number">1</span>], arr[i]</span><br><span class="line"> <span class="keyword">return</span> arr</span><br></pre></td></tr></table></figure><h5 id="归并排序"><a href="#归并排序" class="headerlink" title="归并排序"></a>归并排序</h5><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">merge_sort</span><span class="params">(arr)</span>:</span></span><br><span class="line"> <span class="string">"""归并排序"""</span></span><br><span class="line"> <span class="comment"># 计算中值</span></span><br><span class="line"> mid = len(arr) // <span class="number">2</span></span><br><span class="line"> <span class="comment"># 切割左右数组</span></span><br><span class="line"> left = arr[:mid]</span><br><span class="line"> right = arr[mid:]</span><br><span class="line"> merge = []</span><br><span class="line"> <span class="comment"># 左边数组元素个数大于1时归并排序</span></span><br><span class="line"> <span class="keyword">if</span> len(left) > <span class="number">1</span>:</span><br><span class="line"> left = merge_sort(left)</span><br><span class="line"> <span class="comment"># 右边数组元素个数大于1时归并排序</span></span><br><span class="line"> <span class="keyword">if</span> len(right) > <span class="number">1</span>:</span><br><span class="line"> right = merge_sort(right)</span><br><span class="line"> <span class="comment"># 归并左右数组</span></span><br><span class="line"> <span class="keyword">while</span> left <span class="keyword">and</span> right:</span><br><span class="line"> <span class="keyword">if</span> right[<span class="number">0</span>] <= left[<span class="number">0</span>]:</span><br><span class="line"> merge.append(right.pop(<span class="number">0</span>))</span><br><span class="line"> <span class="keyword">else</span>:</span><br><span class="line"> merge.append(left.pop(<span class="number">0</span>))</span><br><span class="line"> merge.extend(left)</span><br><span class="line"> merge.extend(right)</span><br><span class="line"> <span class="keyword">return</span> merge</span><br></pre></td></tr></table></figure><h5 id="堆排序"><a href="#堆排序" class="headerlink" title="堆排序"></a>堆排序</h5><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">heap_sort</span><span class="params">(arr)</span>:</span></span><br><span class="line"> <span class="string">"""堆排序"""</span></span><br><span class="line"> result = []</span><br><span class="line"> <span class="keyword">while</span> arr:</span><br><span class="line"> <span class="comment"># 初始化堆</span></span><br><span class="line"> arr = min_heap(arr)</span><br><span class="line"> <span class="comment"># 取出堆顶元素</span></span><br><span class="line"> result.append(arr.pop(<span class="number">0</span>))</span><br><span class="line"> <span class="keyword">return</span> result</span><br></pre></td></tr></table></figure><h6 id="建最小堆"><a href="#建最小堆" class="headerlink" title="建最小堆"></a>建最小堆</h6><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">min_heap</span><span class="params">(arr)</span>:</span></span><br><span class="line"> <span class="string">"""建最小堆"""</span></span><br><span class="line"> arr = list(arr)</span><br><span class="line"> le = len(arr)</span><br><span class="line"> mid = le // <span class="number">2</span></span><br><span class="line"> <span class="keyword">for</span> i <span class="keyword">in</span> range(<span class="number">0</span>, mid):</span><br><span class="line"> temp = mid - i</span><br><span class="line"> <span class="comment"># 判断是否有右支</span></span><br><span class="line"> <span class="keyword">if</span> <span class="number">2</span> * temp == le:</span><br><span class="line"> <span class="comment"># 无右支,比较左支并交换</span></span><br><span class="line"> <span class="keyword">if</span> arr[temp - <span class="number">1</span>] > arr[temp * <span class="number">2</span> - <span class="number">1</span>]:</span><br><span class="line"> arr[temp - <span class="number">1</span>], arr[temp * <span class="number">2</span> - <span class="number">1</span>] = arr[temp * <span class="number">2</span> - <span class="number">1</span>], arr[temp - <span class="number">1</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="keyword">if</span> arr[temp * <span class="number">2</span> - <span class="number">1</span>] > arr[temp * <span class="number">2</span>]:</span><br><span class="line"> min_index = temp * <span class="number">2</span></span><br><span class="line"> <span class="keyword">else</span>:</span><br><span class="line"> min_index = temp * <span class="number">2</span> - <span class="number">1</span></span><br><span class="line"> <span class="keyword">if</span> arr[temp - <span class="number">1</span>] > arr[min_index]:</span><br><span class="line"> arr[temp - <span class="number">1</span>], arr[min_index] = arr[min_index], arr[temp - <span class="number">1</span>]</span><br><span class="line"> <span class="keyword">return</span> arr</span><br></pre></td></tr></table></figure><h5 id="希尔排序"><a href="#希尔排序" class="headerlink" title="希尔排序"></a>希尔排序</h5><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">shell_sort</span><span class="params">(arr)</span>:</span></span><br><span class="line"> <span class="string">"""希尔排序"""</span></span><br><span class="line"> n = len(arr)</span><br><span class="line"> gap = n // <span class="number">2</span></span><br><span class="line"> <span class="keyword">while</span> gap > <span class="number">0</span>:</span><br><span class="line"> <span class="keyword">for</span> i <span class="keyword">in</span> range(gap, n):</span><br><span class="line"> temp = arr[i]</span><br><span class="line"> j = i</span><br><span class="line"> <span class="keyword">while</span> j >= gap <span class="keyword">and</span> arr[j - gap] > temp:</span><br><span class="line"> arr[j] = arr[j - gap]</span><br><span class="line"> j -= gap</span><br><span class="line"> arr[j] = temp</span><br><span class="line"> gap = gap // <span class="number">2</span></span><br><span class="line"> <span class="keyword">return</span> arr</span><br></pre></td></tr></table></figure>]]></content>
<summary type="html">
直接插入排序 快速排序 选择排序 冒泡排序 归并排序 堆排序 希尔排序
</summary>
<category term="Python 3" scheme="http://www.shaoyong.online/categories/Python-3/"/>
<category term="Sort" scheme="http://www.shaoyong.online/tags/Sort/"/>
</entry>
<entry>
<title>Python 3 实例</title>
<link href="http://www.shaoyong.online/posts/50958/"/>
<id>http://www.shaoyong.online/posts/50958/</id>
<published>2019-08-02T14:21:22.724Z</published>
<updated>2019-09-15T10:34:46.065Z</updated>
<content type="html"><![CDATA[<ol><li><h6 id="摄氏度转华氏度"><a href="#摄氏度转华氏度" class="headerlink" title="摄氏度转华氏度"></a>摄氏度转华氏度</h6></li></ol><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">a = float(input(<span class="string">"输入摄氏度:"</span>))</span><br><span class="line">b = a * <span class="number">1.8</span> + <span class="number">32</span></span><br><span class="line">print(<span class="string">"摄氏度:{}℃ = 华氏度:{}℉"</span>.format(a, b))</span><br></pre></td></tr></table></figure><ol start="2"><li><h6 id="求园的面积"><a href="#求园的面积" class="headerlink" title="求园的面积"></a>求园的面积</h6></li></ol><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">r = float(input(<span class="string">"输入园半径:"</span>))</span><br><span class="line">area = math.pi*r**<span class="number">2</span></span><br><span class="line">print(<span class="string">"半径为{}的园面积为{}"</span>.format(r, area))</span><br></pre></td></tr></table></figure><ol start="3"><li><h6 id="开平方根"><a href="#开平方根" class="headerlink" title="开平方根"></a>开平方根</h6></li></ol><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">num1 = float(input(<span class="string">"输入一个数:"</span>))</span><br><span class="line">result = num1 ** <span class="number">0.5</span></span><br><span class="line">print(<span class="string">"{}开平方={}"</span>.format(num1, result))</span><br></pre></td></tr></table></figure><ol start="4"><li><h6 id="求三角形面积"><a href="#求三角形面积" class="headerlink" title="求三角形面积"></a>求三角形面积</h6></li></ol><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">a = float(input(<span class="string">"输入边长:"</span>))</span><br><span class="line">b = float(input(<span class="string">"输入边长:"</span>))</span><br><span class="line">c = float(input(<span class="string">"输入边长:"</span>))</span><br><span class="line">p = (a + b + c) / <span class="number">2</span></span><br><span class="line">s = (p * (p - a) * (p - b) * (p - c)) ** <span class="number">0.5</span></span><br><span class="line">print(<span class="string">"边长为{},{},{} 的三角形面积为{}"</span>.format(a, b, c, s))</span><br></pre></td></tr></table></figure><ol start="5"><li><h6 id="判断输入字符串是否为数字"><a href="#判断输入字符串是否为数字" class="headerlink" title="判断输入字符串是否为数字"></a>判断输入字符串是否为数字</h6></li></ol><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">is_number</span><span class="params">(s)</span>:</span></span><br><span class="line"> <span class="string">"""判断输入字符串是否为数字"""</span></span><br><span class="line"> <span class="keyword">try</span>:</span><br><span class="line"> float(s)</span><br><span class="line"> <span class="keyword">return</span> <span class="literal">True</span></span><br><span class="line"> <span class="keyword">except</span> ValueError:</span><br><span class="line"> <span class="keyword">pass</span></span><br><span class="line"> <span class="keyword">try</span>:</span><br><span class="line"> <span class="keyword">import</span> unicodedata</span><br><span class="line"> <span class="keyword">for</span> i <span class="keyword">in</span> s:</span><br><span class="line"> unicodedata.numeric(i)</span><br><span class="line"> <span class="keyword">return</span> <span class="literal">True</span></span><br><span class="line"> <span class="keyword">except</span> (ValueError, TypeError):</span><br><span class="line"> <span class="keyword">pass</span></span><br><span class="line"> <span class="keyword">return</span> <span class="literal">False</span></span><br></pre></td></tr></table></figure><ol start="6"><li><h6 id="判断是否是奇数"><a href="#判断是否是奇数" class="headerlink" title="判断是否是奇数"></a>判断是否是奇数</h6></li></ol><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">is_odd</span><span class="params">(n)</span>:</span></span><br><span class="line"> <span class="string">"""判断是否是奇数"""</span></span><br><span class="line"> <span class="keyword">try</span>:</span><br><span class="line"> <span class="keyword">if</span> float(n) % <span class="number">2</span> == <span class="number">1</span>:</span><br><span class="line"> print(<span class="string">"奇数"</span>)</span><br><span class="line"> <span class="keyword">return</span> <span class="literal">True</span></span><br><span class="line"> <span class="keyword">else</span>:</span><br><span class="line"> print(<span class="string">"偶数"</span>)</span><br><span class="line"> <span class="keyword">except</span> ValueError:</span><br><span class="line"> print(<span class="string">"参数错误"</span>)</span><br><span class="line"> <span class="keyword">pass</span></span><br><span class="line"> <span class="keyword">return</span> <span class="literal">False</span></span><br></pre></td></tr></table></figure><ol start="7"><li><h6 id="判断是否为闰年"><a href="#判断是否为闰年" class="headerlink" title="判断是否为闰年"></a>判断是否为闰年</h6></li></ol><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">is_leap_year</span><span class="params">(year)</span>:</span></span><br><span class="line"> <span class="string">"""判断是否为闰年"""</span></span><br><span class="line"> <span class="keyword">try</span>:</span><br><span class="line"> year = float(year)</span><br><span class="line"> <span class="keyword">if</span> year % <span class="number">4</span> == <span class="number">0</span> <span class="keyword">and</span> year % <span class="number">100</span> != <span class="number">0</span> <span class="keyword">or</span> year % <span class="number">400</span> == <span class="number">0</span>:</span><br><span class="line"> <span class="keyword">return</span> <span class="literal">True</span></span><br><span class="line"> <span class="keyword">else</span>:</span><br><span class="line"> <span class="keyword">return</span> <span class="literal">False</span></span><br><span class="line"> <span class="keyword">except</span> ValueError:</span><br><span class="line"> print(<span class="string">"参数错误"</span>)</span><br><span class="line"> <span class="keyword">pass</span></span><br></pre></td></tr></table></figure><ol start="8"><li><h6 id="获取最大值"><a href="#获取最大值" class="headerlink" title="获取最大值"></a>获取最大值</h6></li></ol><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">max_num</span><span class="params">(s)</span>:</span></span><br><span class="line"> <span class="string">"""获取最大值"""</span></span><br><span class="line"> <span class="keyword">return</span> max(s)</span><br></pre></td></tr></table></figure><ol start="9"><li><h6 id="判断是否为质数"><a href="#判断是否为质数" class="headerlink" title="判断是否为质数"></a>判断是否为质数</h6></li></ol><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">is_prime</span><span class="params">(num)</span>:</span></span><br><span class="line"> <span class="string">"""判断是否为质数"""</span></span><br><span class="line"> <span class="keyword">try</span>:</span><br><span class="line"> num = int(num)</span><br><span class="line"> <span class="keyword">for</span> i <span class="keyword">in</span> range(<span class="number">2</span>, num):</span><br><span class="line"> <span class="keyword">if</span> num % i == <span class="number">0</span>:</span><br><span class="line"> <span class="keyword">return</span> <span class="literal">False</span></span><br><span class="line"> <span class="keyword">else</span>:</span><br><span class="line"> <span class="keyword">return</span> <span class="literal">True</span></span><br><span class="line"> <span class="keyword">except</span> ValueError:</span><br><span class="line"> <span class="keyword">pass</span></span><br></pre></td></tr></table></figure><ol start="10"><li><h6 id="输出指定范围内的质数"><a href="#输出指定范围内的质数" class="headerlink" title="输出指定范围内的质数"></a>输出指定范围内的质数</h6></li></ol><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">scope_prime</span><span class="params">(min, max)</span>:</span></span><br><span class="line"> <span class="string">"""输出指定范围内的质数"""</span></span><br><span class="line"> <span class="keyword">try</span>:</span><br><span class="line"> min = int(min)</span><br><span class="line"> max = int(max)</span><br><span class="line"> prime = set()</span><br><span class="line"> <span class="keyword">for</span> i <span class="keyword">in</span> range(min, max + <span class="number">1</span>):</span><br><span class="line"> <span class="keyword">for</span> j <span class="keyword">in</span> range(<span class="number">2</span>, i):</span><br><span class="line"> <span class="keyword">if</span> i % j == <span class="number">0</span>:</span><br><span class="line"> <span class="keyword">break</span></span><br><span class="line"> <span class="keyword">else</span>:</span><br><span class="line"> prime.add(i)</span><br><span class="line"> <span class="keyword">return</span> prime</span><br><span class="line"> <span class="keyword">except</span> (TypeError, ValueError):</span><br><span class="line"> <span class="keyword">pass</span></span><br></pre></td></tr></table></figure><ol start="11"><li><h6 id="阶乘"><a href="#阶乘" class="headerlink" title="阶乘"></a>阶乘</h6></li></ol><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">factorial</span><span class="params">(num)</span>:</span></span><br><span class="line"> <span class="string">"""阶乘"""</span></span><br><span class="line"> <span class="keyword">try</span>:</span><br><span class="line"> num = int(num)</span><br><span class="line"> <span class="keyword">if</span> num == <span class="number">1</span>:</span><br><span class="line"> <span class="keyword">return</span> <span class="number">1</span></span><br><span class="line"> <span class="keyword">else</span>:</span><br><span class="line"> <span class="comment"># 递归实现</span></span><br><span class="line"> <span class="keyword">return</span> num * factorial(num - <span class="number">1</span>)</span><br><span class="line"> <span class="comment"># 非递归实现</span></span><br><span class="line"> <span class="comment"># factorial = 1</span></span><br><span class="line"> <span class="comment"># for i in range(1, num + 1):</span></span><br><span class="line"> <span class="comment"># factorial *= i</span></span><br><span class="line"> <span class="comment"># return factorial</span></span><br><span class="line"> <span class="keyword">except</span>(TypeError, ValueError):</span><br><span class="line"> <span class="keyword">pass</span></span><br></pre></td></tr></table></figure><ol start="12"><li><h6 id="乘法表"><a href="#乘法表" class="headerlink" title="乘法表"></a>乘法表</h6></li></ol><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">get_multiplication</span><span class="params">()</span>:</span></span><br><span class="line"> <span class="string">"""乘法表"""</span></span><br><span class="line"> <span class="keyword">for</span> i <span class="keyword">in</span> range(<span class="number">1</span>, <span class="number">10</span>):</span><br><span class="line"> <span class="keyword">for</span> j <span class="keyword">in</span> range(<span class="number">1</span>, i + <span class="number">1</span>):</span><br><span class="line"> print(<span class="string">"{}x{}={}\t"</span>.format(i, j, i * j), end=<span class="string">""</span>)</span><br><span class="line"> print()</span><br></pre></td></tr></table></figure><ol start="13"><li><h6 id="斐波那契数列"><a href="#斐波那契数列" class="headerlink" title="斐波那契数列"></a>斐波那契数列</h6></li></ol><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">get_fibonacci</span><span class="params">(n)</span>:</span></span><br><span class="line"> <span class="string">"""斐波那契数列(0,1,1,2,3,5..)"""</span></span><br><span class="line"> fib_list = [<span class="number">0</span>, <span class="number">1</span>]</span><br><span class="line"> <span class="keyword">if</span> n == <span class="number">1</span>:</span><br><span class="line"> <span class="keyword">return</span> [<span class="number">0</span>, ]</span><br><span class="line"> <span class="keyword">for</span> i <span class="keyword">in</span> range(<span class="number">2</span>, n):</span><br><span class="line"> fib_list.append(fib_list[i - <span class="number">2</span>] + fib_list[i - <span class="number">1</span>])</span><br><span class="line"> <span class="keyword">return</span> fib_list</span><br></pre></td></tr></table></figure><ol start="14"><li><h6 id="阿姆斯特朗数"><a href="#阿姆斯特朗数" class="headerlink" title="阿姆斯特朗数"></a>阿姆斯特朗数</h6></li></ol><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">get_armstrong</span><span class="params">(n)</span>:</span></span><br><span class="line"> <span class="string">"""阿姆斯特朗数"""</span></span><br><span class="line"> a = []</span><br><span class="line"> b = []</span><br><span class="line"> <span class="keyword">for</span> i <span class="keyword">in</span> range(<span class="number">1</span>, n + <span class="number">1</span>):</span><br><span class="line"> temp = i</span><br><span class="line"> count = <span class="number">0</span></span><br><span class="line"> sum_num = <span class="number">0</span></span><br><span class="line"> a.clear()</span><br><span class="line"> <span class="keyword">while</span> int(temp % <span class="number">10</span>) != <span class="number">0</span> <span class="keyword">or</span> int(temp / <span class="number">10</span>) != <span class="number">0</span>:</span><br><span class="line"> a.append(int(temp % <span class="number">10</span>))</span><br><span class="line"> temp /= <span class="number">10</span></span><br><span class="line"> count += <span class="number">1</span></span><br><span class="line"> <span class="keyword">for</span> j <span class="keyword">in</span> iter(a):</span><br><span class="line"> sum_num += j ** count</span><br><span class="line"> <span class="keyword">if</span> sum_num == i:</span><br><span class="line"> b.append(i)</span><br><span class="line"> <span class="keyword">return</span> b</span><br></pre></td></tr></table></figure><ol start="15"><li><h6 id="进制转"><a href="#进制转" class="headerlink" title="进制转"></a>进制转</h6></li></ol><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">change_type</span><span class="params">(num)</span>:</span></span><br><span class="line"> <span class="comment"># 十进制转二进制</span></span><br><span class="line"> print(<span class="string">"二进制为:{}"</span>.format(bin(num)))</span><br><span class="line"> <span class="comment"># 十进制转八进制</span></span><br><span class="line"> print(<span class="string">"八进制为:{}"</span>.format(oct(num)))</span><br><span class="line"> <span class="comment"># 十进制转十六进制</span></span><br><span class="line"> print(<span class="string">"十六进制为:{}"</span>.format(hex(num)))</span><br><span class="line"> <span class="comment"># 字符转ASCII码</span></span><br><span class="line"> print(<span class="string">"ASCII码为:{}"</span>.format(ord(num)))</span><br><span class="line"> <span class="comment"># ASCII码转字符</span></span><br><span class="line"> print(<span class="string">"字符为:{}"</span>.format(chr(num)))</span><br></pre></td></tr></table></figure><ol start="16"><li><h6 id="最大公约数"><a href="#最大公约数" class="headerlink" title="最大公约数"></a>最大公约数</h6></li></ol><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">get_max_divisor</span><span class="params">(x, y)</span>:</span></span><br><span class="line"> <span class="string">"""最大公约数"""</span></span><br><span class="line"> <span class="keyword">if</span> x > y:</span><br><span class="line"> x, y = y, x</span><br><span class="line"> <span class="keyword">for</span> i <span class="keyword">in</span> range(<span class="number">1</span>, x + <span class="number">1</span>):</span><br><span class="line"> <span class="keyword">if</span> x % i == <span class="number">0</span> <span class="keyword">and</span> y % i == <span class="number">0</span>:</span><br><span class="line"> divisor = i</span><br><span class="line"> <span class="keyword">return</span> divisor</span><br></pre></td></tr></table></figure><ol start="17"><li><h6 id="最小公倍数"><a href="#最小公倍数" class="headerlink" title="最小公倍数"></a>最小公倍数</h6></li></ol><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">get_min_multiple</span><span class="params">(x, y)</span>:</span></span><br><span class="line"> <span class="string">"""最小公倍数"""</span></span><br><span class="line"> <span class="keyword">if</span> x < y:</span><br><span class="line"> x, y = y, x</span><br><span class="line"> multiple = y</span><br><span class="line"> <span class="keyword">while</span> multiple % x != <span class="number">0</span> <span class="keyword">or</span> multiple % y != <span class="number">0</span>:</span><br><span class="line"> multiple += <span class="number">1</span></span><br><span class="line"> <span class="keyword">return</span> multiple</span><br></pre></td></tr></table></figure><ol start="18"><li><h6 id="日历"><a href="#日历" class="headerlink" title="日历"></a>日历</h6></li></ol><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">my_calendar</span><span class="params">(year, month)</span>:</span></span><br><span class="line"> <span class="string">"""日历"""</span></span><br><span class="line"> print(calendar.month(year, month))</span><br></pre></td></tr></table></figure><ol start="19"><li><h6 id="递归-斐波那契数列"><a href="#递归-斐波那契数列" class="headerlink" title="递归 斐波那契数列"></a>递归 斐波那契数列</h6></li></ol><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">recur_fibo</span><span class="params">(n)</span>:</span></span><br><span class="line"> <span class="string">"""递归 斐波那契数列"""</span></span><br><span class="line"> <span class="keyword">if</span> n <= <span class="number">1</span>:</span><br><span class="line"> <span class="keyword">return</span> n</span><br><span class="line"> <span class="keyword">else</span>:</span><br><span class="line"> <span class="keyword">return</span> recur_fibo(n - <span class="number">1</span>) + recur_fibo(n - <span class="number">2</span>)</span><br></pre></td></tr></table></figure><ol start="20"><li><h6 id="文件输入输出"><a href="#文件输入输出" class="headerlink" title="文件输入输出"></a>文件输入输出</h6></li></ol><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">file_test</span><span class="params">(file_name, my_input)</span>:</span></span><br><span class="line"> <span class="string">"""文件输入输出"""</span></span><br><span class="line"> <span class="keyword">with</span> open(file_name, <span class="string">'w+'</span>) <span class="keyword">as</span> file:</span><br><span class="line"> file.write(my_input)</span><br><span class="line"> <span class="keyword">with</span> open(file_name, <span class="string">'r'</span>) <span class="keyword">as</span> file:</span><br><span class="line"> output = file.read()</span><br><span class="line"> <span class="keyword">return</span> output</span><br></pre></td></tr></table></figure><ol start="21"><li><h6 id="字符串大小写转换"><a href="#字符串大小写转换" class="headerlink" title="字符串大小写转换"></a>字符串大小写转换</h6></li></ol><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">up2down_or_down2up</span><span class="params">(my_str)</span>:</span></span><br><span class="line"> <span class="string">"""字符串大小写转换"""</span></span><br><span class="line"> my_str = str(my_str)</span><br><span class="line"> print(my_str.upper())</span><br><span class="line"> print(my_str.lower())</span><br><span class="line"> print(my_str.title())</span><br><span class="line"> print(my_str.capitalize())</span><br></pre></td></tr></table></figure><ol start="22"><li><h6 id="获得昨天日期"><a href="#获得昨天日期" class="headerlink" title="获得昨天日期"></a>获得昨天日期</h6></li></ol><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">get_yesterday</span><span class="params">()</span>:</span></span><br><span class="line"> <span class="string">"""获得昨天日期"""</span></span><br><span class="line"> today = datetime.date.today()</span><br><span class="line"> one_day = datetime.timedelta(days=<span class="number">1</span>)</span><br><span class="line"> yesterday = today - one_day</span><br><span class="line"> <span class="keyword">return</span> yesterday</span><br></pre></td></tr></table></figure><ol start="23"><li><h6 id="约瑟夫环"><a href="#约瑟夫环" class="headerlink" title="约瑟夫环"></a>约瑟夫环</h6></li></ol><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">joseph</span><span class="params">()</span>:</span></span><br><span class="line"> <span class="string">"""约瑟夫环"""</span></span><br><span class="line"> people = []</span><br><span class="line"> <span class="keyword">for</span> i <span class="keyword">in</span> range(<span class="number">0</span>, <span class="number">30</span>):</span><br><span class="line"> <span class="comment"># 1,在船上,0,落水</span></span><br><span class="line"> people.append(<span class="number">1</span>)</span><br><span class="line"> <span class="comment"># 报数</span></span><br><span class="line"> check = <span class="number">0</span></span><br><span class="line"> <span class="comment"># 落水人数</span></span><br><span class="line"> num = <span class="number">0</span></span><br><span class="line"> <span class="comment"># 指针</span></span><br><span class="line"> index = <span class="number">-1</span></span><br><span class="line"> <span class="keyword">while</span> num < <span class="number">15</span>:</span><br><span class="line"> <span class="comment"># 报数</span></span><br><span class="line"> check = check + <span class="number">1</span></span><br><span class="line"> index = index + <span class="number">1</span></span><br><span class="line"> index = index % <span class="number">30</span></span><br><span class="line"> <span class="keyword">while</span> people[index] == <span class="number">0</span>:</span><br><span class="line"> index = index + <span class="number">1</span></span><br><span class="line"> index = index % <span class="number">30</span></span><br><span class="line"> <span class="keyword">if</span> check == <span class="number">9</span>:</span><br><span class="line"> people[index] = <span class="number">0</span></span><br><span class="line"> print(<span class="string">'{}号下船'</span>.format(index + <span class="number">1</span>))</span><br><span class="line"> num = num + <span class="number">1</span></span><br><span class="line"> check = <span class="number">0</span></span><br><span class="line"> <span class="comment"># print(str(people))</span></span><br></pre></td></tr></table></figure><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">joseph2</span><span class="params">()</span>:</span></span><br><span class="line"> <span class="string">"""约瑟夫环"""</span></span><br><span class="line"> people = list(range(<span class="number">30</span>))</span><br><span class="line"> <span class="keyword">while</span> len(people) > <span class="number">15</span>:</span><br><span class="line"> i = <span class="number">1</span></span><br><span class="line"> <span class="keyword">while</span> i < <span class="number">9</span>:</span><br><span class="line"> people.append(people.pop(<span class="number">0</span>))</span><br><span class="line"> i += <span class="number">1</span></span><br><span class="line"> print(<span class="string">'{:2d}号下船了'</span>.format(people.pop(<span class="number">0</span>)))</span><br></pre></td></tr></table></figure><ol start="24"><li><h6 id="秒表功能实现"><a href="#秒表功能实现" class="headerlink" title="秒表功能实现"></a>秒表功能实现</h6></li></ol><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">stopwatch</span><span class="params">()</span>:</span></span><br><span class="line"> <span class="string">"""秒表功能实现"""</span></span><br><span class="line"> print(<span class="string">'按下回车开始计时,按下Ctrl+c停止计时'</span>)</span><br><span class="line"> <span class="keyword">while</span> <span class="literal">True</span>:</span><br><span class="line"> <span class="keyword">try</span>:</span><br><span class="line"> input()</span><br><span class="line"> starttime = time.time()</span><br><span class="line"> print(<span class="string">'开始'</span>)</span><br><span class="line"> <span class="keyword">while</span> <span class="literal">True</span>:</span><br><span class="line"> print(<span class="string">'计时:'</span>, round(time.time() - starttime, <span class="number">0</span>), <span class="string">'秒'</span>, end=<span class="string">'\r'</span>)</span><br><span class="line"> time.sleep(<span class="number">1</span>)</span><br><span class="line"> <span class="keyword">except</span> KeyboardInterrupt:</span><br><span class="line"> print(<span class="string">'结束'</span>)</span><br><span class="line"> endtime = time.time()</span><br><span class="line"> print(<span class="string">'总共的时间为:'</span>, round(endtime - starttime, <span class="number">2</span>), <span class="string">'secs'</span>)</span><br><span class="line"> <span class="keyword">break</span></span><br></pre></td></tr></table></figure><ol start="25"><li><h6 id="计算n个自然数的立方和"><a href="#计算n个自然数的立方和" class="headerlink" title="计算n个自然数的立方和"></a>计算n个自然数的立方和</h6></li></ol><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">cube_sum</span><span class="params">(n)</span>:</span></span><br><span class="line"> <span class="string">"""计算n个自然数的立方和"""</span></span><br><span class="line"> <span class="keyword">return</span> sum([num ** <span class="number">3</span> <span class="keyword">for</span> num <span class="keyword">in</span> range(<span class="number">1</span>, n + <span class="number">1</span>)])</span><br></pre></td></tr></table></figure><ol start="26"><li><h6 id="数组翻转指定个数元素"><a href="#数组翻转指定个数元素" class="headerlink" title="数组翻转指定个数元素"></a>数组翻转指定个数元素</h6></li></ol><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">list_flip</span><span class="params">(arr, n)</span>:</span></span><br><span class="line"> <span class="string">"""数组翻转指定个数元素"""</span></span><br><span class="line"> arr = list(arr)</span><br><span class="line"> <span class="keyword">for</span> i <span class="keyword">in</span> range(n):</span><br><span class="line"> arr.append(arr.pop(<span class="number">0</span>))</span><br><span class="line"> <span class="keyword">return</span> arr</span><br></pre></td></tr></table></figure><ol start="27"><li><h6 id="数组首尾对调"><a href="#数组首尾对调" class="headerlink" title="数组首尾对调"></a>数组首尾对调</h6></li></ol><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">list_exchange</span><span class="params">(arr)</span>:</span></span><br><span class="line"> <span class="string">"""数组首尾对调"""</span></span><br><span class="line"> arr[<span class="number">0</span>], arr[len(arr) - <span class="number">1</span>] = arr[len(arr) - <span class="number">1</span>], arr[<span class="number">0</span>]</span><br><span class="line"> <span class="keyword">return</span> arr</span><br></pre></td></tr></table></figure><ol start="28"><li><h6 id="指定位置对调"><a href="#指定位置对调" class="headerlink" title="指定位置对调"></a>指定位置对调</h6></li></ol><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">list_exchange</span><span class="params">(arr, x, y)</span>:</span></span><br><span class="line"> <span class="comment"># 数组指定位置对调</span></span><br><span class="line"> arr[x], arr[y] = arr[y], arr[x]</span><br><span class="line"> <span class="comment"># 判断数组中是否有3</span></span><br><span class="line"> <span class="keyword">if</span> <span class="number">3</span> <span class="keyword">in</span> arr:</span><br><span class="line"> print(<span class="string">"数组中包含3"</span>)</span><br><span class="line"> <span class="comment"># 计算数组中元素出现的次数</span></span><br><span class="line"> print(<span class="string">'数组中元素2出现了:{}次'</span>.format(arr.count(<span class="number">2</span>)))</span><br><span class="line"> <span class="comment"># 翻转数组</span></span><br><span class="line"> <span class="keyword">return</span> [ele <span class="keyword">for</span> ele <span class="keyword">in</span> reversed(arr)]</span><br></pre></td></tr></table></figure><ol start="29"><li><h6 id="正则表达式获取字符串中的url"><a href="#正则表达式获取字符串中的url" class="headerlink" title="正则表达式获取字符串中的url"></a>正则表达式获取字符串中的url</h6></li></ol><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">get_url</span><span class="params">(str)</span>:</span></span><br><span class="line"> <span class="string">"""正则表达式获取字符串中的url"""</span></span><br><span class="line"> exp = <span class="string">r'https?://(?:[-\w.]|(?:%[\da-fA-F]{2}))+'</span></span><br><span class="line"> url = re.findall(exp, str)</span><br><span class="line"> <span class="keyword">return</span> url</span><br></pre></td></tr></table></figure><ol start="30"><li><h6 id="按key-value排序"><a href="#按key-value排序" class="headerlink" title="按key/value排序"></a>按key/value排序</h6></li></ol><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">sort_dic</span><span class="params">()</span>:</span></span><br><span class="line"> <span class="string">"""按key/value排序"""</span></span><br><span class="line"> key_value = {<span class="number">2</span>: <span class="number">56</span>, <span class="number">1</span>: <span class="number">2</span>, <span class="number">5</span>: <span class="number">12</span>, <span class="number">4</span>: <span class="number">24</span>, <span class="number">6</span>: <span class="number">18</span>, <span class="number">3</span>: <span class="number">323</span>}</span><br><span class="line"> key_value2 = {<span class="number">7</span>: <span class="number">23</span>, <span class="number">8</span>: <span class="number">54</span>}</span><br><span class="line"> print(<span class="string">"按key排序"</span>)</span><br><span class="line"> print(sorted(key_value.items()))</span><br><span class="line"> <span class="comment"># for i in sorted(key_value):</span></span><br><span class="line"> <span class="comment"># print((i, key_value[i]), end=' ')</span></span><br><span class="line"> print(<span class="string">"\n按value排序"</span>)</span><br><span class="line"> print(sorted(key_value.items(), key=<span class="keyword">lambda</span> kv: (kv[<span class="number">1</span>], kv[<span class="number">0</span>])))</span><br><span class="line"> print(<span class="string">"字典值之和为:{}"</span>.format(sum(key_value.values())))</span><br><span class="line"> <span class="comment"># 将字典2加入字典1</span></span><br><span class="line"> key_value.update(key_value2)</span><br><span class="line"> print(<span class="string">"两字典合并,key_value:{}, key_value2:{}"</span>.format(key_value, key_value2))</span><br></pre></td></tr></table></figure><ol start="31"><li><h6 id="时间转换"><a href="#时间转换" class="headerlink" title="时间转换"></a>时间转换</h6></li></ol><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">a1 = <span class="string">"2019-7-20 23:40:00"</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 先转换为时间数组</span></span><br><span class="line">timeArray = time.strptime(a1, <span class="string">"%Y-%m-%d %H:%M:%S"</span>)</span><br><span class="line"><span class="comment"># 转换为时间戳</span></span><br><span class="line">timeStamp = int(time.mktime(timeArray))</span><br><span class="line">print(timeStamp)</span><br><span class="line"><span class="comment"># 格式转换 - 转为 /</span></span><br><span class="line">otherStyleTime = time.strftime(<span class="string">"%Y/%m/%d %H:%M:%S"</span>, timeArray)</span><br><span class="line">print(otherStyleTime)</span><br><span class="line">print(<span class="string">"now:{}"</span>.format(datetime.datetime.now()))</span><br></pre></td></tr></table></figure><ol start="32"><li><h6 id="二分查找"><a href="#二分查找" class="headerlink" title="二分查找"></a>二分查找</h6></li></ol><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">binary_search</span><span class="params">(arr, x)</span>:</span></span><br><span class="line"> <span class="string">"""二分查找,在有序数组arr中查找x所在的索引,找不到时返回-1"""</span></span><br><span class="line"> left, right = <span class="number">0</span>, len(arr) - <span class="number">1</span></span><br><span class="line"> <span class="keyword">while</span> <span class="literal">True</span>:</span><br><span class="line"> <span class="keyword">if</span> right - left == <span class="number">1</span>:</span><br><span class="line"> <span class="keyword">if</span> arr[right] == x:</span><br><span class="line"> <span class="keyword">return</span> right</span><br><span class="line"> <span class="keyword">elif</span> arr[left] == x:</span><br><span class="line"> <span class="keyword">return</span> left</span><br><span class="line"> <span class="keyword">else</span>:</span><br><span class="line"> <span class="keyword">return</span> <span class="number">-1</span></span><br><span class="line"> <span class="keyword">else</span>:</span><br><span class="line"> mid = int((right + left) / <span class="number">2</span>)</span><br><span class="line"> <span class="keyword">if</span> x == arr[mid]:</span><br><span class="line"> <span class="keyword">return</span> mid</span><br><span class="line"> <span class="keyword">elif</span> x > arr[mid]:</span><br><span class="line"> left = mid</span><br><span class="line"> <span class="keyword">continue</span></span><br><span class="line"> <span class="keyword">elif</span> x < arr[mid]:</span><br><span class="line"> right = mid</span><br><span class="line"> <span class="keyword">continue</span></span><br></pre></td></tr></table></figure><ol start="33"><li><h6 id="线性查找"><a href="#线性查找" class="headerlink" title="线性查找"></a>线性查找</h6></li></ol><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">linear_search</span><span class="params">(arr, c)</span>:</span></span><br><span class="line"> <span class="string">"""线性查找"""</span></span><br><span class="line"> <span class="keyword">for</span> i <span class="keyword">in</span> range(len(arr)):</span><br><span class="line"> <span class="keyword">if</span> arr[i] == c:</span><br><span class="line"> <span class="keyword">return</span> i</span><br><span class="line"> <span class="keyword">return</span> <span class="number">-1</span></span><br></pre></td></tr></table></figure><ol start="34"><li><h6 id="打印杨辉三角"><a href="#打印杨辉三角" class="headerlink" title="打印杨辉三角"></a>打印杨辉三角</h6></li></ol><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">pascal_triangles</span><span class="params">(n)</span>:</span></span><br><span class="line"> triangles = {}</span><br><span class="line"> n += <span class="number">1</span></span><br><span class="line"> <span class="string">"""杨辉三角"""</span></span><br><span class="line"> <span class="keyword">for</span> i <span class="keyword">in</span> range(<span class="number">1</span>, n):</span><br><span class="line"> <span class="keyword">for</span> j <span class="keyword">in</span> range(<span class="number">1</span>, i + <span class="number">1</span>):</span><br><span class="line"> ij = str(i) + str(j)</span><br><span class="line"> <span class="keyword">if</span> j == <span class="number">1</span>:</span><br><span class="line"> triangles[ij] = <span class="number">1</span></span><br><span class="line"> print(<span class="string">" "</span> * (n - i - <span class="number">1</span>), end=<span class="string">''</span>)</span><br><span class="line"> print(<span class="number">1</span>, end=<span class="string">''</span>)</span><br><span class="line"> <span class="keyword">elif</span> j == i:</span><br><span class="line"> triangles[ij] = <span class="number">1</span></span><br><span class="line"> print(<span class="number">1</span>, end=<span class="string">''</span>)</span><br><span class="line"> <span class="keyword">else</span>:</span><br><span class="line"> ul = str(i - <span class="number">1</span>) + str(j - <span class="number">1</span>)</span><br><span class="line"> ur = str(i - <span class="number">1</span>) + str(j)</span><br><span class="line"> triangles[ij] = triangles[ul] + triangles[ur]</span><br><span class="line"> print(triangles[ij], end=<span class="string">''</span>)</span><br><span class="line"> print(<span class="string">" "</span>, end=<span class="string">''</span>)</span><br><span class="line"> print()</span><br><span class="line"> <span class="keyword">return</span> triangles</span><br></pre></td></tr></table></figure><ol start="35"><li><h6 id="白鸡百钱"><a href="#白鸡百钱" class="headerlink" title="白鸡百钱"></a>白鸡百钱</h6></li></ol><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">chicken_question</span><span class="params">()</span>:</span></span><br><span class="line"> <span class="string">"""百鸡百钱"""</span></span><br><span class="line"> <span class="string">"""</span></span><br><span class="line"><span class="string"> 鸡翁一值钱五,鸡母一值钱三,鸡雏三值钱一。百钱买百鸡,问鸡翁、鸡母、鸡雏各几何?</span></span><br><span class="line"><span class="string"> """</span></span><br><span class="line"> <span class="keyword">for</span> x <span class="keyword">in</span> range(<span class="number">0</span>, <span class="number">101</span>):</span><br><span class="line"> <span class="keyword">for</span> y <span class="keyword">in</span> range(<span class="number">0</span>, <span class="number">101</span>):</span><br><span class="line"> <span class="keyword">if</span> <span class="number">5</span> * x + <span class="number">3</span> * y + (<span class="number">100</span> - x - y) / <span class="number">3</span> == <span class="number">100</span>:</span><br><span class="line"> print(<span class="string">"鸡翁:{}、鸡母:{}、鸡雏:{}"</span>.format(x, y, <span class="number">100</span> - x - y))</span><br></pre></td></tr></table></figure><ol start="36"><li><h6 id="完全数"><a href="#完全数" class="headerlink" title="完全数"></a>完全数</h6></li></ol><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">perfect_number</span><span class="params">(n)</span>:</span></span><br><span class="line"> <span class="string">"""完全数"""</span></span><br><span class="line"> temp = []</span><br><span class="line"> perfect = []</span><br><span class="line"> <span class="keyword">for</span> i <span class="keyword">in</span> range(<span class="number">1</span>, n):</span><br><span class="line"> <span class="keyword">for</span> j <span class="keyword">in</span> range(<span class="number">1</span>, i):</span><br><span class="line"> <span class="keyword">if</span> i % j == <span class="number">0</span> <span class="keyword">and</span> i != j:</span><br><span class="line"> temp.append(j)</span><br><span class="line"> <span class="keyword">if</span> sum(temp) == i:</span><br><span class="line"> perfect.append(i)</span><br><span class="line"> temp.clear()</span><br><span class="line"> <span class="keyword">return</span> perfect</span><br></pre></td></tr></table></figure><h5 id="小游戏"><a href="#小游戏" class="headerlink" title="小游戏"></a>小游戏</h5><h6 id="Craps赌博游戏"><a href="#Craps赌博游戏" class="headerlink" title="Craps赌博游戏"></a>Craps赌博游戏</h6><p>玩家摇两颗色子 如果第一次摇出7点或11点 玩家胜<br>如果摇出2点 3点 12点 庄家胜 其他情况游戏继续<br>玩家再次要色子 如果摇出7点 庄家胜<br>如果摇出第一次摇的点数 玩家胜<br>否则游戏继续 玩家继续摇色子<br>玩家进入游戏时有1000元的赌注 全部输光游戏结束</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> random</span><br><span class="line"></span><br><span class="line">money = <span class="number">1000</span></span><br><span class="line"><span class="keyword">while</span> money > <span class="number">0</span>:</span><br><span class="line"> bet = int(input(<span class="string">"请下注:"</span>))</span><br><span class="line"> <span class="keyword">while</span> bet > money <span class="keyword">or</span> bet <= <span class="number">0</span>:</span><br><span class="line"> bet = int(input(<span class="string">"请重新下注:"</span>))</span><br><span class="line"> money -= bet</span><br><span class="line"> first_num = random.randint(<span class="number">2</span>, <span class="number">12</span>)</span><br><span class="line"> print(<span class="string">"第一次:{}"</span>.format(first_num))</span><br><span class="line"> <span class="keyword">if</span> first_num <span class="keyword">in</span> [<span class="number">7</span>, <span class="number">11</span>]:</span><br><span class="line"> money += bet * <span class="number">2</span></span><br><span class="line"> print(<span class="string">"1.玩家胜出,获得:{},剩余金币:【{}】"</span>.format(bet * <span class="number">2</span>, money))</span><br><span class="line"> <span class="keyword">continue</span></span><br><span class="line"> <span class="keyword">elif</span> first_num <span class="keyword">in</span> [<span class="number">2</span>, <span class="number">3</span>, <span class="number">12</span>]:</span><br><span class="line"> print(<span class="string">"2.庄家胜出,重新开始,剩余金币:【{}】"</span>.format(money))</span><br><span class="line"> <span class="keyword">continue</span></span><br><span class="line"> <span class="keyword">else</span>:</span><br><span class="line"> <span class="keyword">while</span> <span class="literal">True</span>:</span><br><span class="line"> next_num = random.randint(<span class="number">2</span>, <span class="number">12</span>)</span><br><span class="line"> print(<span class="string">"这一次:{}"</span>.format(next_num))</span><br><span class="line"> <span class="keyword">if</span> next_num == <span class="number">7</span>:</span><br><span class="line"> print(<span class="string">"3.庄家胜出,重新开始,剩余金币:【{}】"</span>.format(money))</span><br><span class="line"> <span class="keyword">break</span></span><br><span class="line"> <span class="keyword">elif</span> next_num == first_num:</span><br><span class="line"> money += bet * <span class="number">2</span></span><br><span class="line"> print(<span class="string">"4.玩家胜出,获得:{},剩余金币:【{}】"</span>.format(bet * <span class="number">2</span>, money))</span><br><span class="line"> <span class="keyword">break</span></span><br><span class="line"> <span class="comment"># input()</span></span><br><span class="line">print(<span class="string">"金币为零,游戏结束"</span>)</span><br></pre></td></tr></table></figure><h6 id="21点"><a href="#21点" class="headerlink" title="21点"></a>21点</h6><p>基于<a href="https://github.com/jackfrued/Python-100-Days/blob/master/Day01-15/09.%E9%9D%A2%E5%90%91%E5%AF%B9%E8%B1%A1%E8%BF%9B%E9%98%B6.md#%E6%A1%88%E4%BE%8B2%E6%89%91%E5%85%8B%E6%B8%B8%E6%88%8F" target="_blank" rel="noopener">Python-100-Days的扑克游戏</a>编写</p><p>游戏规则(简化版):</p><p> 开局时,庄家给每个玩家(又称闲家)牌面向上发两张牌(明牌),再给庄家自己发两张牌,一张明牌,一张暗牌(牌面朝下)。<br> 当所有的初始牌分发完毕后,如果玩家拿到的是A和T(无论顺序),就拥有黑杰克(Black Jack);若庄家的明牌为T,且暗牌为A,应直接翻开并拥有Black Jack;如果庄家没有Black Jack则保持暗牌,玩家继续游戏。若玩家为Black Jack且庄家为其他,玩家赢得1.5倍(或2倍,1赔2时)赌注;若庄家为Black Jack且玩家为其他,庄家赢得赌注;若庄家和玩家均为Black Jack,平局,玩家拿回自己的赌注。<br> 接下来是正常的拿牌流程:首名非黑杰克玩家选择拿牌(Hit)、停牌(Stand)、加倍(Double)或投降(Surrender,庄家赢得一半赌注);若选择拿牌,则后续只能选择拿牌或停牌。在发牌的过程中,如果玩家的牌点数的和超过21,玩家就输了——叫爆掉(Bust),庄家赢得赌注(无论庄家之后的点数是多少)。假如玩家没爆掉,又决定不再要牌了(停牌,或因加倍、投降而终止),则轮到下一名非黑杰克玩家选择。<br> 当所有玩家停止拿牌后,庄家翻开暗牌,并持续拿牌直至点数不小于17(若有A,按最大而尽量不爆计算)。假如庄家爆掉了,那他就输了,玩家赢得1倍赌注;否则那么比点数大小,大为赢。点数相同为平局,玩家拿回自己的赌注。</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br><span class="line">141</span><br><span class="line">142</span><br><span class="line">143</span><br><span class="line">144</span><br><span class="line">145</span><br><span class="line">146</span><br><span class="line">147</span><br><span class="line">148</span><br><span class="line">149</span><br><span class="line">150</span><br><span class="line">151</span><br><span class="line">152</span><br><span class="line">153</span><br><span class="line">154</span><br><span class="line">155</span><br><span class="line">156</span><br><span class="line">157</span><br><span class="line">158</span><br><span class="line">159</span><br><span class="line">160</span><br><span class="line">161</span><br><span class="line">162</span><br><span class="line">163</span><br><span class="line">164</span><br><span class="line">165</span><br><span class="line">166</span><br><span class="line">167</span><br><span class="line">168</span><br><span class="line">169</span><br><span class="line">170</span><br><span class="line">171</span><br><span class="line">172</span><br><span class="line">173</span><br><span class="line">174</span><br><span class="line">175</span><br><span class="line">176</span><br><span class="line">177</span><br><span class="line">178</span><br><span class="line">179</span><br><span class="line">180</span><br><span class="line">181</span><br><span class="line">182</span><br><span class="line">183</span><br><span class="line">184</span><br><span class="line">185</span><br><span class="line">186</span><br><span class="line">187</span><br><span class="line">188</span><br><span class="line">189</span><br><span class="line">190</span><br><span class="line">191</span><br><span class="line">192</span><br><span class="line">193</span><br><span class="line">194</span><br><span class="line">195</span><br><span class="line">196</span><br><span class="line">197</span><br><span class="line">198</span><br><span class="line">199</span><br><span class="line">200</span><br><span class="line">201</span><br><span class="line">202</span><br><span class="line">203</span><br><span class="line">204</span><br><span class="line">205</span><br><span class="line">206</span><br><span class="line">207</span><br><span class="line">208</span><br><span class="line">209</span><br><span class="line">210</span><br><span class="line">211</span><br><span class="line">212</span><br><span class="line">213</span><br><span class="line">214</span><br><span class="line">215</span><br><span class="line">216</span><br><span class="line">217</span><br><span class="line">218</span><br><span class="line">219</span><br><span class="line">220</span><br><span class="line">221</span><br><span class="line">222</span><br><span class="line">223</span><br><span class="line">224</span><br><span class="line">225</span><br><span class="line">226</span><br><span class="line">227</span><br><span class="line">228</span><br><span class="line">229</span><br><span class="line">230</span><br><span class="line">231</span><br><span class="line">232</span><br><span class="line">233</span><br><span class="line">234</span><br><span class="line">235</span><br><span class="line">236</span><br><span class="line">237</span><br><span class="line">238</span><br><span class="line">239</span><br><span class="line">240</span><br><span class="line">241</span><br><span class="line">242</span><br><span class="line">243</span><br><span class="line">244</span><br><span class="line">245</span><br><span class="line">246</span><br><span class="line">247</span><br><span class="line">248</span><br><span class="line">249</span><br><span class="line">250</span><br><span class="line">251</span><br><span class="line">252</span><br><span class="line">253</span><br><span class="line">254</span><br><span class="line">255</span><br><span class="line">256</span><br><span class="line">257</span><br><span class="line">258</span><br><span class="line">259</span><br><span class="line">260</span><br><span class="line">261</span><br><span class="line">262</span><br><span class="line">263</span><br><span class="line">264</span><br><span class="line">265</span><br><span class="line">266</span><br><span class="line">267</span><br><span class="line">268</span><br><span class="line">269</span><br><span class="line">270</span><br><span class="line">271</span><br><span class="line">272</span><br><span class="line">273</span><br><span class="line">274</span><br><span class="line">275</span><br><span class="line">276</span><br><span class="line">277</span><br><span class="line">278</span><br><span class="line">279</span><br><span class="line">280</span><br><span class="line">281</span><br><span class="line">282</span><br><span class="line">283</span><br><span class="line">284</span><br><span class="line">285</span><br><span class="line">286</span><br><span class="line">287</span><br><span class="line">288</span><br><span class="line">289</span><br><span class="line">290</span><br><span class="line">291</span><br><span class="line">292</span><br><span class="line">293</span><br><span class="line">294</span><br><span class="line">295</span><br><span class="line">296</span><br><span class="line">297</span><br><span class="line">298</span><br><span class="line">299</span><br><span class="line">300</span><br><span class="line">301</span><br><span class="line">302</span><br><span class="line">303</span><br><span class="line">304</span><br><span class="line">305</span><br><span class="line">306</span><br><span class="line">307</span><br><span class="line">308</span><br><span class="line">309</span><br><span class="line">310</span><br><span class="line">311</span><br><span class="line">312</span><br><span class="line">313</span><br><span class="line">314</span><br><span class="line">315</span><br><span class="line">316</span><br><span class="line">317</span><br><span class="line">318</span><br><span class="line">319</span><br><span class="line">320</span><br><span class="line">321</span><br><span class="line">322</span><br><span class="line">323</span><br><span class="line">324</span><br><span class="line">325</span><br><span class="line">326</span><br><span class="line">327</span><br><span class="line">328</span><br><span class="line">329</span><br><span class="line">330</span><br><span class="line">331</span><br><span class="line">332</span><br><span class="line">333</span><br><span class="line">334</span><br><span class="line">335</span><br><span class="line">336</span><br><span class="line">337</span><br><span class="line">338</span><br><span class="line">339</span><br><span class="line">340</span><br><span class="line">341</span><br><span class="line">342</span><br><span class="line">343</span><br><span class="line">344</span><br><span class="line">345</span><br><span class="line">346</span><br><span class="line">347</span><br><span class="line">348</span><br><span class="line">349</span><br><span class="line">350</span><br><span class="line">351</span><br><span class="line">352</span><br><span class="line">353</span><br><span class="line">354</span><br><span class="line">355</span><br><span class="line">356</span><br><span class="line">357</span><br><span class="line">358</span><br><span class="line">359</span><br><span class="line">360</span><br><span class="line">361</span><br><span class="line">362</span><br><span class="line">363</span><br><span class="line">364</span><br><span class="line">365</span><br><span class="line">366</span><br><span class="line">367</span><br><span class="line">368</span><br><span class="line">369</span><br><span class="line">370</span><br><span class="line">371</span><br><span class="line">372</span><br><span class="line">373</span><br><span class="line">374</span><br><span class="line">375</span><br><span class="line">376</span><br><span class="line">377</span><br><span class="line">378</span><br><span class="line">379</span><br><span class="line">380</span><br><span class="line">381</span><br><span class="line">382</span><br><span class="line">383</span><br><span class="line">384</span><br><span class="line">385</span><br><span class="line">386</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> random</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Card</span><span class="params">(object)</span>:</span></span><br><span class="line"> <span class="string">"""一张牌"""</span></span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">__init__</span><span class="params">(self, suite, face)</span>:</span></span><br><span class="line"> self._suite = suite</span><br><span class="line"> self._face = face</span><br><span class="line"></span><br><span class="line"><span class="meta"> @property</span></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">face</span><span class="params">(self)</span>:</span></span><br><span class="line"> <span class="keyword">return</span> self._face</span><br><span class="line"></span><br><span class="line"><span class="meta"> @property</span></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">suite</span><span class="params">(self)</span>:</span></span><br><span class="line"> <span class="keyword">return</span> self._suite</span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">__str__</span><span class="params">(self)</span>:</span></span><br><span class="line"> <span class="keyword">if</span> self._face == <span class="number">1</span>:</span><br><span class="line"> face_str = <span class="string">'A'</span></span><br><span class="line"> <span class="keyword">elif</span> self._face == <span class="number">11</span>:</span><br><span class="line"> face_str = <span class="string">'J'</span></span><br><span class="line"> <span class="keyword">elif</span> self._face == <span class="number">12</span>:</span><br><span class="line"> face_str = <span class="string">'Q'</span></span><br><span class="line"> <span class="keyword">elif</span> self._face == <span class="number">13</span>:</span><br><span class="line"> face_str = <span class="string">'K'</span></span><br><span class="line"> <span class="keyword">else</span>:</span><br><span class="line"> face_str = str(self._face)</span><br><span class="line"> <span class="keyword">return</span> <span class="string">'%s%s'</span> % (self._suite, face_str)</span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">__repr__</span><span class="params">(self)</span>:</span></span><br><span class="line"> <span class="keyword">return</span> self.__str__()</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Poker</span><span class="params">(object)</span>:</span></span><br><span class="line"> <span class="string">"""一副牌"""</span></span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">__init__</span><span class="params">(self)</span>:</span></span><br><span class="line"> self._cards = [Card(suite, face)</span><br><span class="line"> <span class="keyword">for</span> suite <span class="keyword">in</span> <span class="string">'♠♥♣♦'</span></span><br><span class="line"> <span class="keyword">for</span> face <span class="keyword">in</span> range(<span class="number">1</span>, <span class="number">14</span>)]</span><br><span class="line"> self._current = <span class="number">0</span></span><br><span class="line"></span><br><span class="line"><span class="meta"> @property</span></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">cards</span><span class="params">(self)</span>:</span></span><br><span class="line"> <span class="keyword">return</span> self._cards</span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">shuffle</span><span class="params">(self)</span>:</span></span><br><span class="line"> <span class="string">"""洗牌(随机乱序)"""</span></span><br><span class="line"> self._current = <span class="number">0</span></span><br><span class="line"> random.shuffle(self._cards)</span><br><span class="line"></span><br><span class="line"><span class="meta"> @property</span></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">next</span><span class="params">(self)</span>:</span></span><br><span class="line"> <span class="string">"""发牌"""</span></span><br><span class="line"> card = self._cards[self._current]</span><br><span class="line"> self._current += <span class="number">1</span></span><br><span class="line"> <span class="keyword">return</span> card</span><br><span class="line"></span><br><span class="line"><span class="meta"> @property</span></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">has_next</span><span class="params">(self)</span>:</span></span><br><span class="line"> <span class="string">"""还有没有牌"""</span></span><br><span class="line"> <span class="keyword">return</span> self._current < len(self._cards)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Player</span><span class="params">(object)</span>:</span></span><br><span class="line"> <span class="string">"""玩家"""</span></span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">__init__</span><span class="params">(self, name)</span>:</span></span><br><span class="line"> self._name = name</span><br><span class="line"> self._cards_on_hand = []</span><br><span class="line"></span><br><span class="line"><span class="meta"> @property</span></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">name</span><span class="params">(self)</span>:</span></span><br><span class="line"> <span class="keyword">return</span> self._name</span><br><span class="line"></span><br><span class="line"><span class="meta"> @property</span></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">cards_on_hand</span><span class="params">(self)</span>:</span></span><br><span class="line"> <span class="keyword">return</span> self._cards_on_hand</span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">get</span><span class="params">(self, card)</span>:</span></span><br><span class="line"> <span class="string">"""摸牌"""</span></span><br><span class="line"> self._cards_on_hand.append(card)</span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">arrange</span><span class="params">(self, card_key)</span>:</span></span><br><span class="line"> <span class="string">"""玩家整理手上的牌"""</span></span><br><span class="line"> self._cards_on_hand.sort(key=card_key)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment"># 排序规则-先根据花色再根据点数排序</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Black_Jack</span><span class="params">(Player)</span>:</span></span><br><span class="line"> <span class="string">"""21点"""</span></span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">__init__</span><span class="params">(self, name)</span>:</span></span><br><span class="line"> super().__init__(name)</span><br><span class="line"> <span class="comment"># 停牌</span></span><br><span class="line"> self._stand = <span class="literal">False</span></span><br><span class="line"> <span class="comment"># 爆掉</span></span><br><span class="line"> self._bust = <span class="literal">False</span></span><br><span class="line"></span><br><span class="line"><span class="meta"> @property</span></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">stand</span><span class="params">(self)</span>:</span></span><br><span class="line"> <span class="keyword">return</span> self._stand</span><br><span class="line"></span><br><span class="line"><span class="meta"> @stand.setter</span></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">stand</span><span class="params">(self, state)</span>:</span></span><br><span class="line"> <span class="string">"""停牌"""</span></span><br><span class="line"> self._stand = state</span><br><span class="line"></span><br><span class="line"><span class="meta"> @property</span></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">bust</span><span class="params">(self)</span>:</span></span><br><span class="line"> <span class="keyword">return</span> self._bust</span><br><span class="line"></span><br><span class="line"><span class="meta"> @bust.setter</span></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">bust</span><span class="params">(self, state)</span>:</span></span><br><span class="line"> <span class="string">"""爆掉"""</span></span><br><span class="line"> self._bust = state</span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">is_stand</span><span class="params">(self)</span>:</span></span><br><span class="line"> <span class="string">"""是否停牌"""</span></span><br><span class="line"> <span class="keyword">return</span> self.black_jack_total() == <span class="number">21</span> <span class="keyword">or</span> self.face_total() >= <span class="number">17</span></span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">is_bust</span><span class="params">(self)</span>:</span></span><br><span class="line"> <span class="string">"""是否爆掉"""</span></span><br><span class="line"> <span class="keyword">return</span> self.face_total() > <span class="number">21</span></span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">open_hand</span><span class="params">(self, i)</span>:</span></span><br><span class="line"> <span class="string">"""明牌"""</span></span><br><span class="line"> <span class="keyword">return</span> self.cards_on_hand[i]</span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">clean_hand</span><span class="params">(self)</span>:</span></span><br><span class="line"> <span class="string">"""清空手牌并清空状态"""</span></span><br><span class="line"> self.cards_on_hand.clear()</span><br><span class="line"> self.stand = <span class="literal">False</span></span><br><span class="line"> self.bust = <span class="literal">False</span></span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">face_total</span><span class="params">(self)</span>:</span></span><br><span class="line"> <span class="string">"""手牌总点数"""</span></span><br><span class="line"> temp = [card.face <span class="keyword">for</span> card <span class="keyword">in</span> self.cards_on_hand]</span><br><span class="line"> j_count = temp.count(<span class="number">11</span>)</span><br><span class="line"> q_count = temp.count(<span class="number">12</span>)</span><br><span class="line"> k_count = temp.count(<span class="number">13</span>)</span><br><span class="line"> total = sum(temp) - j_count - q_count * <span class="number">2</span> - k_count * <span class="number">3</span></span><br><span class="line"> <span class="keyword">return</span> total</span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">black_jack_total</span><span class="params">(self)</span>:</span></span><br><span class="line"> <span class="string">"""21点计数"""</span></span><br><span class="line"> temp = [card.face <span class="keyword">for</span> card <span class="keyword">in</span> self.cards_on_hand]</span><br><span class="line"> a_count = temp.count(<span class="number">1</span>)</span><br><span class="line"> j_count = temp.count(<span class="number">11</span>)</span><br><span class="line"> q_count = temp.count(<span class="number">12</span>)</span><br><span class="line"> k_count = temp.count(<span class="number">13</span>)</span><br><span class="line"> total = sum(temp) - j_count - q_count * <span class="number">2</span> - k_count * <span class="number">3</span></span><br><span class="line"> <span class="keyword">for</span> i <span class="keyword">in</span> range(a_count):</span><br><span class="line"> <span class="keyword">if</span> total < <span class="number">21</span>:</span><br><span class="line"> total += <span class="number">10</span></span><br><span class="line"> <span class="keyword">if</span> total > <span class="number">21</span>:</span><br><span class="line"> total -= <span class="number">10</span></span><br><span class="line"> <span class="keyword">return</span> total</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Black_Jack_Player</span><span class="params">(Black_Jack)</span>:</span></span><br><span class="line"> <span class="string">"""21点玩家"""</span></span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">__init__</span><span class="params">(self, name)</span>:</span></span><br><span class="line"> super().__init__(name)</span><br><span class="line"> <span class="comment"># 玩家初始赌注</span></span><br><span class="line"> self._money = <span class="number">1000</span></span><br><span class="line"> <span class="comment"># 下注额</span></span><br><span class="line"> self._bet = <span class="number">0</span></span><br><span class="line"></span><br><span class="line"><span class="meta"> @property</span></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">money</span><span class="params">(self)</span>:</span></span><br><span class="line"> <span class="keyword">return</span> self._money</span><br><span class="line"></span><br><span class="line"><span class="meta"> @money.setter</span></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">money</span><span class="params">(self, money)</span>:</span></span><br><span class="line"> <span class="string">"""下注"""</span></span><br><span class="line"> self._money = money</span><br><span class="line"></span><br><span class="line"><span class="meta"> @property</span></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">bet</span><span class="params">(self)</span>:</span></span><br><span class="line"> <span class="keyword">return</span> self._bet</span><br><span class="line"></span><br><span class="line"><span class="meta"> @bet.setter</span></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">bet</span><span class="params">(self, bet)</span>:</span></span><br><span class="line"> <span class="string">"""下注"""</span></span><br><span class="line"> self._bet = bet</span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">double</span><span class="params">(self)</span>:</span></span><br><span class="line"> <span class="string">"""加倍"""</span></span><br><span class="line"> self._bet *= <span class="number">2</span></span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">surrender</span><span class="params">(self)</span>:</span></span><br><span class="line"> <span class="string">"""投降"""</span></span><br><span class="line"> self._bet /= <span class="number">2</span></span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">__str__</span><span class="params">(self)</span>:</span></span><br><span class="line"> <span class="keyword">return</span> <span class="string">"【%s】筹码:%d,点数:%d,牌面:%s"</span> % (</span><br><span class="line"> self._name, self._money, self.black_jack_total(), self.cards_on_hand)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Banker</span><span class="params">(Black_Jack)</span>:</span></span><br><span class="line"> <span class="string">"""庄家"""</span></span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">__init__</span><span class="params">(self, name)</span>:</span></span><br><span class="line"> super().__init__(name)</span><br><span class="line"></span><br><span class="line"> <span class="comment"># 是否是黑杰克</span></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">is_black_jack</span><span class="params">(self)</span>:</span></span><br><span class="line"> <span class="keyword">return</span> self.cards_on_hand[<span class="number">0</span>].face <span class="keyword">in</span> [<span class="number">10</span>, <span class="number">11</span>, <span class="number">12</span>, <span class="number">13</span>] <span class="keyword">and</span> self.cards_on_hand[<span class="number">1</span>].face == <span class="number">1</span></span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">__str__</span><span class="params">(self)</span>:</span></span><br><span class="line"> <span class="keyword">return</span> <span class="string">"【%s】点数:%d,牌面:%s"</span> % (self._name, self.black_jack_total(), self.cards_on_hand)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">get_key</span><span class="params">(card)</span>:</span></span><br><span class="line"> <span class="keyword">return</span> card.suite, card.face</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">main</span><span class="params">()</span>:</span></span><br><span class="line"> p = Poker()</span><br><span class="line"> <span class="comment"># print(p.cards)</span></span><br><span class="line"> banker = Banker(<span class="string">'庄家'</span>)</span><br><span class="line"> <span class="comment"># 电脑玩家</span></span><br><span class="line"> com_players = [Black_Jack_Player(<span class="string">'东邪'</span>), Black_Jack_Player(<span class="string">'西毒'</span>), Black_Jack_Player(<span class="string">'南帝'</span>),</span><br><span class="line"> Black_Jack_Player(<span class="string">'北丐'</span>)]</span><br><span class="line"> player = Black_Jack_Player(<span class="string">'玩家'</span>)</span><br><span class="line"> <span class="keyword">while</span> <span class="literal">True</span>:</span><br><span class="line"> <span class="comment"># 洗牌</span></span><br><span class="line"> p.shuffle()</span><br><span class="line"> <span class="comment"># 下注</span></span><br><span class="line"> <span class="keyword">for</span> com_player <span class="keyword">in</span> com_players:</span><br><span class="line"> com_player.bet = random.randint(<span class="number">1</span>, com_player.money)</span><br><span class="line"> print(<span class="string">"【{}】下注:{}"</span>.format(com_player.name, com_player.bet))</span><br><span class="line"> print(<span class="string">'玩家当前筹码:{}'</span>.format(player.money))</span><br><span class="line"></span><br><span class="line"> ok = <span class="literal">False</span></span><br><span class="line"> <span class="keyword">while</span> <span class="keyword">not</span> ok:</span><br><span class="line"> <span class="keyword">try</span>:</span><br><span class="line"> player.bet = int(input(<span class="string">"玩家请下注:"</span>))</span><br><span class="line"> <span class="keyword">if</span> player.bet > player.money:</span><br><span class="line"> <span class="keyword">raise</span> ValueError</span><br><span class="line"> ok = <span class="literal">True</span></span><br><span class="line"> <span class="keyword">except</span> ValueError:</span><br><span class="line"> <span class="comment"># 下注异常</span></span><br><span class="line"> print(<span class="string">'输入有误'</span>)</span><br><span class="line"> ok = <span class="literal">False</span></span><br><span class="line"> <span class="keyword">for</span> i <span class="keyword">in</span> range(<span class="number">2</span>):</span><br><span class="line"> <span class="comment"># 庄家拿牌</span></span><br><span class="line"> banker.get(p.next)</span><br><span class="line"> <span class="comment"># 玩家拿牌</span></span><br><span class="line"> player.get(p.next)</span><br><span class="line"> print(<span class="string">'玩家拿牌:{}'</span>.format(player.cards_on_hand[i]))</span><br><span class="line"> <span class="comment"># 电脑拿牌</span></span><br><span class="line"> <span class="keyword">for</span> com_player <span class="keyword">in</span> com_players:</span><br><span class="line"> com_player.get(p.next)</span><br><span class="line"> <span class="comment"># 本轮是否结束标志</span></span><br><span class="line"> END = <span class="literal">False</span></span><br><span class="line"> <span class="comment"># 庄家明牌</span></span><br><span class="line"> print(<span class="string">"庄家明牌为:{}"</span>.format(banker.open_hand(<span class="number">0</span>)))</span><br><span class="line"> <span class="keyword">if</span> banker.is_black_jack():</span><br><span class="line"> print(<span class="string">"\n庄家有Black Jack:{}"</span>.format(banker.cards_on_hand))</span><br><span class="line"> <span class="comment"># 庄家停牌</span></span><br><span class="line"> banker.stand = <span class="literal">True</span></span><br><span class="line"> <span class="comment"># 直接结算筹码,结束本轮</span></span><br><span class="line"> END = <span class="literal">True</span></span><br><span class="line"> <span class="comment"># 玩家轮流拿牌/停牌</span></span><br><span class="line"> <span class="keyword">while</span> <span class="keyword">not</span> END:</span><br><span class="line"> <span class="keyword">for</span> com_player <span class="keyword">in</span> com_players:</span><br><span class="line"> <span class="comment"># 如果电脑玩家没停牌和爆掉则拿牌</span></span><br><span class="line"> <span class="comment"># print('抽牌前:{}, stand:{}, bust:{}'.format(com_player.name, com_player.stand, com_player.bust))</span></span><br><span class="line"> <span class="keyword">if</span> <span class="keyword">not</span> com_player.stand <span class="keyword">and</span> <span class="keyword">not</span> com_player.bust:</span><br><span class="line"> <span class="keyword">if</span> com_player.is_stand():</span><br><span class="line"> com_player.stand = <span class="literal">True</span></span><br><span class="line"> print(<span class="string">"【{}】:\"停牌!\""</span>.format(com_player.name))</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="keyword">if</span> com_player.face_total <span class="keyword">in</span> [<span class="number">10</span>, <span class="number">11</span>, <span class="number">12</span>] <span class="keyword">and</span> com_player.money >= com_player.bet * <span class="number">2</span>:</span><br><span class="line"> com_player.double()</span><br><span class="line"> print(<span class="string">"【{}】:\"运气不错,加倍!\""</span>.format(com_player.name))</span><br><span class="line"> print(<span class="string">"【{}】拿牌"</span>.format(com_player.name))</span><br><span class="line"> com_player.get(p.next)</span><br><span class="line"> <span class="keyword">if</span> com_player.is_bust():</span><br><span class="line"> com_player.bust = <span class="literal">True</span></span><br><span class="line"> print(<span class="string">"【{}】爆掉!!"</span>.format(com_player.name))</span><br><span class="line"> <span class="comment"># elif com_player.is_stand():</span></span><br><span class="line"> <span class="comment"># com_player.stand = True</span></span><br><span class="line"> <span class="comment"># print("【{}】:\"停牌!\"".format(com_player.name))</span></span><br><span class="line"> <span class="comment"># print('抽牌后:{}, stand:{}, bust:{}'.format(com_player.name, com_player.stand, com_player.bust))</span></span><br><span class="line"> <span class="keyword">if</span> <span class="keyword">not</span> player.bust <span class="keyword">and</span> <span class="keyword">not</span> player.stand:</span><br><span class="line"> <span class="keyword">while</span> <span class="literal">True</span>:</span><br><span class="line"> print(<span class="string">"当前手牌:{},庄家明牌为:{}"</span>.format(player.cards_on_hand, banker.cards_on_hand[<span class="number">0</span>]))</span><br><span class="line"> print(<span class="string">"请选择:1.拿牌,2.停牌,3.加倍"</span>)</span><br><span class="line"> choose = int(input(<span class="string">"选择:"</span>))</span><br><span class="line"> <span class="keyword">if</span> choose == <span class="number">1</span> <span class="keyword">or</span> choose == <span class="number">3</span>:</span><br><span class="line"> <span class="keyword">if</span> choose == <span class="number">3</span> <span class="keyword">and</span> player.money >= player.bet * <span class="number">2</span>:</span><br><span class="line"> player.double()</span><br><span class="line"> <span class="keyword">elif</span> choose == <span class="number">3</span>:</span><br><span class="line"> print(<span class="string">'筹码不足,无法加倍!'</span>)</span><br><span class="line"> player.get(p.next)</span><br><span class="line"> <span class="keyword">if</span> player.is_bust():</span><br><span class="line"> player.bust = <span class="literal">True</span></span><br><span class="line"> print(<span class="string">'庄家发牌,当前手牌:{}'</span>.format(player.cards_on_hand))</span><br><span class="line"> <span class="keyword">break</span></span><br><span class="line"> <span class="keyword">elif</span> choose == <span class="number">2</span>:</span><br><span class="line"> player.stand = <span class="literal">True</span></span><br><span class="line"> <span class="keyword">break</span></span><br><span class="line"> <span class="comment"># 投降</span></span><br><span class="line"> <span class="comment"># elif choose == 4:</span></span><br><span class="line"> <span class="comment"># player.surrender()</span></span><br><span class="line"> <span class="comment"># player.stand = True</span></span><br><span class="line"> <span class="comment"># break</span></span><br><span class="line"> <span class="keyword">else</span>:</span><br><span class="line"> print(<span class="string">"选择错误,请重新选择"</span>)</span><br><span class="line"> temp = <span class="number">0</span></span><br><span class="line"> <span class="keyword">for</span> com_player <span class="keyword">in</span> com_players:</span><br><span class="line"></span><br><span class="line"> <span class="keyword">if</span> com_player.stand <span class="keyword">or</span> com_player.bust:</span><br><span class="line"> temp += <span class="number">1</span></span><br><span class="line"> <span class="keyword">if</span> temp == len(com_players) <span class="keyword">and</span> (player.bust <span class="keyword">or</span> player.stand):</span><br><span class="line"> END = <span class="literal">True</span></span><br><span class="line"></span><br><span class="line"> <span class="comment"># 庄家抽牌</span></span><br><span class="line"> <span class="keyword">while</span> <span class="keyword">not</span> banker.bust <span class="keyword">and</span> <span class="keyword">not</span> banker.stand:</span><br><span class="line"> banker.get(p.next)</span><br><span class="line"> <span class="keyword">if</span> banker.is_bust():</span><br><span class="line"> banker.bust = <span class="literal">True</span></span><br><span class="line"> <span class="keyword">elif</span> banker.is_stand():</span><br><span class="line"> banker.stand = <span class="literal">True</span></span><br><span class="line"> <span class="comment"># 结算筹码</span></span><br><span class="line"> <span class="keyword">if</span> banker.bust:</span><br><span class="line"> <span class="keyword">for</span> com_player <span class="keyword">in</span> com_players:</span><br><span class="line"> <span class="keyword">if</span> <span class="keyword">not</span> com_player.bust:</span><br><span class="line"> com_player.money += com_player.bet</span><br><span class="line"> <span class="keyword">else</span>:</span><br><span class="line"> com_player.money -= com_player.bet</span><br><span class="line"> <span class="keyword">if</span> <span class="keyword">not</span> player.bust:</span><br><span class="line"> player.money += player.bet</span><br><span class="line"> <span class="keyword">else</span>:</span><br><span class="line"> player.money -= player.bet</span><br><span class="line"> <span class="keyword">else</span>:</span><br><span class="line"> <span class="keyword">for</span> com_player <span class="keyword">in</span> com_players:</span><br><span class="line"> <span class="keyword">if</span> com_player.black_jack_total() > banker.black_jack_total() <span class="keyword">and</span> <span class="keyword">not</span> com_player.bust:</span><br><span class="line"> <span class="comment"># 玩家为21点时赢得1.5倍赌注</span></span><br><span class="line"> <span class="keyword">if</span> com_player.black_jack_total() == <span class="number">21</span>:</span><br><span class="line"> com_player.bet *= <span class="number">1.5</span></span><br><span class="line"> com_player.money += com_player.bet</span><br><span class="line"> <span class="keyword">elif</span> com_player.black_jack_total() == banker.black_jack_total() <span class="keyword">and</span> <span class="keyword">not</span> com_player.bust:</span><br><span class="line"> <span class="keyword">pass</span></span><br><span class="line"> <span class="keyword">else</span>:</span><br><span class="line"> com_player.money -= com_player.bet</span><br><span class="line"> <span class="keyword">if</span> player.black_jack_total() > banker.black_jack_total() <span class="keyword">and</span> <span class="keyword">not</span> player.bust:</span><br><span class="line"> <span class="comment"># 玩家为21点时赢得1.5倍赌注</span></span><br><span class="line"> <span class="keyword">if</span> player.black_jack_total() == <span class="number">21</span>:</span><br><span class="line"> player.bet *= <span class="number">1.5</span></span><br><span class="line"> player.money += player.bet</span><br><span class="line"> <span class="keyword">elif</span> player.black_jack_total() == banker.black_jack_total() <span class="keyword">and</span> <span class="keyword">not</span> player.bust:</span><br><span class="line"> <span class="keyword">pass</span></span><br><span class="line"> <span class="keyword">else</span>:</span><br><span class="line"> player.money -= player.bet</span><br><span class="line"> <span class="comment"># 结束一轮</span></span><br><span class="line"> print(<span class="string">"="</span> * <span class="number">45</span>)</span><br><span class="line"> print(banker)</span><br><span class="line"> banker.clean_hand()</span><br><span class="line"> <span class="keyword">for</span> com_player <span class="keyword">in</span> com_players:</span><br><span class="line"> <span class="comment"># 清空手牌</span></span><br><span class="line"> print(com_player, end=<span class="string">''</span>)</span><br><span class="line"> com_player.clean_hand()</span><br><span class="line"> <span class="comment"># 筹码为零则离席</span></span><br><span class="line"> <span class="keyword">if</span> com_player.money == <span class="number">0</span>:</span><br><span class="line"> com_players.remove(com_player)</span><br><span class="line"> print(<span class="string">"\n【{}】倾家荡产,被保安拖走..."</span>.format(com_player.name))</span><br><span class="line"> print()</span><br><span class="line"> print(player)</span><br><span class="line"> player.clean_hand()</span><br><span class="line"> print(<span class="string">"="</span> * <span class="number">45</span>)</span><br><span class="line"> input(<span class="string">"本轮结束,请按回车继续"</span>)</span><br><span class="line"> <span class="keyword">if</span> player.money <= <span class="number">0</span>:</span><br><span class="line"> <span class="keyword">break</span></span><br><span class="line"> print(<span class="string">"筹码已用完,游戏结束!!"</span>)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> __name__ == <span class="string">'__main__'</span>:</span><br><span class="line"> main()</span><br></pre></td></tr></table></figure>]]></content>
<summary type="html">
使用Python 3时编写的简单实例
</summary>
<category term="Python 3" scheme="http://www.shaoyong.online/categories/Python-3/"/>
<category term="实例" scheme="http://www.shaoyong.online/tags/%E5%AE%9E%E4%BE%8B/"/>
<category term="练习" scheme="http://www.shaoyong.online/tags/%E7%BB%83%E4%B9%A0/"/>
</entry>
<entry>
<title>面试题</title>
<link href="http://www.shaoyong.online/posts/27055/"/>
<id>http://www.shaoyong.online/posts/27055/</id>
<published>2019-07-30T12:43:58.909Z</published>
<updated>2019-09-15T10:34:46.053Z</updated>
<content type="html"><![CDATA[<p> 在笔试中经常会遇到很多需要手写代码的题,如果能完整的写出来最好,但如果不习惯手写或时间不够,可已选择写伪码,主要描述清楚关键的实现步骤。</p><h1 id="笔试"><a href="#笔试" class="headerlink" title="笔试"></a>笔试</h1><ol><li><p>写出<code>Collection</code>接口的实现</p><p>Collection<br>├List<br>│├LinkedList<br>│├ArrayList<br>│└Vector<br>│ └Stack<br>└Set<br>Map<br>├Hashtable<br>├HashMap<br>└WeakHashMap</p></li></ol><ol start="2"><li><p>运行时获取<code>class</code>的磁盘路径</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><YOUR CLASS>.class.getProtectionDomain().getCodeSource().getSource().getLocation()</span><br></pre></td></tr></table></figure></li></ol><ol start="3"><li><p>Java多态的表现形式,代码如何实现</p><p>重写<code>Overriding</code>是父类与子类之间多态性的一种表现,重载<code>Overloading</code>是一个类中多态性的一种表现;不同的对象调用同一个方法的到不同的结果。</p><ol><li><p>继承父类</p></li><li><p>重写父类方法</p></li><li><p>向上转型</p></li></ol></li></ol><ol start="4"><li><p>在工作中遇到或使用过的设计模式,手写实现一个设计模式(除了单例模式)</p><p>Factory(工厂模式), Builder(建造模式), Factory Method(工厂方法模式),<br>Prototype(原始模型模式),Singleton(单例模式), Facade(门面模式),<br>Adapter(适配器模式), Bridge(桥梁模式), Composite(合成模式),<br>Decorator(装饰模式), Flyweight(享元模式), Proxy(代理模式),<br>Command(命令模式), Interpreter(解释器模式), Visitor(访问者模式),<br>Iterator(迭代子模式), Mediator(调停者模式), Memento(备忘录模式),<br>Observer(观察者模式), State(状态模式), Strategy(策略模式),<br>Template Method(模板方法模式), Chain Of Responsibleity(责任链模式)<br>工厂模式:工厂模式是一种经常被使用到的模式,根据工厂模式实现的类可以根据提供的数据生成一组类中某一个类的实例,通常这一组类有一个公共的抽象父类并且实现了相同的方法,但是这些方法针对不同的数据进行了不同的操作。首先需要定义一个基类,该类的子类通过不同的方法实现了基类中的方法。然后需要定义一个工厂类,工厂类可以根据条件生成不同的子类实例。当得到子类的实例后,开发人员可以调用基类中的方法而不必考虑到底返回的是哪一个子类的实例。<a href="https://www.runoob.com/design-pattern/factory-pattern.html" target="_blank" rel="noopener">具体实现代码</a></p></li></ol><ol start="5"><li><p>手写代码,实现多线程对一整型对象递增,且数值不重复</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Test</span> </span>{</span><br><span class="line"> <span class="keyword">private</span> <span class="keyword">static</span> <span class="keyword">int</span> num = <span class="number">1</span>;</span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>{</span><br><span class="line"> Test test = <span class="keyword">new</span> Test();</span><br><span class="line"> Increasing inc = test.new Increasing();</span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">int</span> i=<span class="number">0</span>;i<=<span class="number">10</span>;i++){</span><br><span class="line"> Thread thread=<span class="keyword">new</span> Thread(inc);</span><br><span class="line"> thread.start();</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">private</span> <span class="keyword">synchronized</span> <span class="keyword">void</span> <span class="title">add</span><span class="params">()</span></span>{</span><br><span class="line"> num+=<span class="number">1</span>;</span><br><span class="line"> System.out.println(num);</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="class"><span class="keyword">class</span> <span class="title">Increasing</span> <span class="keyword">implements</span> <span class="title">Runnable</span></span>{</span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">run</span><span class="params">()</span></span>{</span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> i=<span class="number">0</span>;i<<span class="number">20</span>;i++){</span><br><span class="line"> add();</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></li></ol><ol start="6"><li><p>快速获得数组<code>int[] a = {1,2, 3, 5, 6, 12, 4, 7, 14, 9, 8}</code>中第二大的数,写出关键代码</p><p>下面代码的时间复杂度为O(n),不一定是最快的,但只需遍历一次</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">int</span> <span class="title">getSecondMax</span><span class="params">(<span class="keyword">int</span>[] a)</span> </span>{</span><br><span class="line"> <span class="keyword">int</span> max = a[<span class="number">0</span>];</span><br><span class="line"> <span class="keyword">int</span> second = a[a.length - <span class="number">1</span>];</span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i < a.length; i++) {</span><br><span class="line"> <span class="keyword">if</span> (a[i] > max) {</span><br><span class="line"> second = max;</span><br><span class="line"> max = a[i];</span><br><span class="line"> } <span class="keyword">else</span> <span class="keyword">if</span> (a[i] > second && a[i] < max) {</span><br><span class="line"> second = a[i];</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> second;</span><br><span class="line">}</span><br></pre></td></tr></table></figure></li><li><p>进程和线程的区别和联系?</p><p>进程 - 操作系统分配内存的基本单位 - 一个进程可以包含一个或多个线程<br>线程 - 操作系统分配CPU的基本单位</p></li></ol><h1 id="面试"><a href="#面试" class="headerlink" title="面试"></a>面试</h1><ol><li>在之前项目中遇到什么问题,怎么解决。</li><li>mysql分页语句。</li><li>线程同步有哪几种方式。</li><li>eclipse的中查找类被调用的快捷键是什么。</li></ol>]]></content>
<summary type="html">
遇到的笔试与面试题
</summary>
<category term="面试" scheme="http://www.shaoyong.online/categories/%E9%9D%A2%E8%AF%95/"/>
<category term="Java" scheme="http://www.shaoyong.online/tags/Java/"/>
<category term="面试" scheme="http://www.shaoyong.online/tags/%E9%9D%A2%E8%AF%95/"/>
<category term="笔试题" scheme="http://www.shaoyong.online/tags/%E7%AC%94%E8%AF%95%E9%A2%98/"/>
</entry>
<entry>
<title>Python3与Java的简单对比之面向对象</title>
<link href="http://www.shaoyong.online/posts/44973/"/>
<id>http://www.shaoyong.online/posts/44973/</id>
<published>2019-07-28T13:00:11.252Z</published>
<updated>2019-09-15T10:34:46.060Z</updated>
<content type="html"><![CDATA[<blockquote><p>类(class)是构造对象的模板或蓝图。由类构造(construct)对象的过程称为创建类的实例(instance)。</p><footer><strong>Java核心技术</strong></footer></blockquote><hr><blockquote><p>类提供了一种组合数据和功能的方法。创建一个新类意味着创建一个新类型的对象,从而允许创建一个该类型的新实例。 </p><footer><strong>Python3.7.4文档</strong></footer></blockquote><hr><p>在对于类的定义上,Python3与Java定义一致。</p><h1 id="类"><a href="#类" class="headerlink" title="类"></a>类</h1><p> 下面分别用Java和Python3编写一个<code>People</code>类。</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * People</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">People</span> </span>{</span><br><span class="line"> <span class="comment">//实例域(成员变量)</span></span><br><span class="line"> <span class="keyword">private</span> String name;</span><br><span class="line"> <span class="keyword">private</span> <span class="keyword">int</span> age;</span><br><span class="line"> <span class="keyword">private</span> String gender;</span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">public</span> String <span class="title">getName</span><span class="params">()</span> </span>{</span><br><span class="line"> <span class="keyword">return</span> name;</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">setName</span><span class="params">(String name)</span> </span>{</span><br><span class="line"> <span class="keyword">this</span>.name = name;</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">getAge</span><span class="params">()</span> </span>{</span><br><span class="line"> <span class="keyword">return</span> age;</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">setAge</span><span class="params">(<span class="keyword">int</span> age)</span> </span>{</span><br><span class="line"> <span class="keyword">this</span>.age = age;</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">public</span> String <span class="title">getGender</span><span class="params">()</span> </span>{</span><br><span class="line"> <span class="keyword">return</span> gender;</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">setGender</span><span class="params">(String gender)</span> </span>{</span><br><span class="line"> <span class="keyword">this</span>.gender = gender;</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="comment">//无参构造器</span></span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="title">People</span><span class="params">()</span> </span>{</span><br><span class="line"> System.out.println(<span class="string">"【JPeople】无参构造器"</span>);</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="comment">//带参构造器</span></span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="title">People</span><span class="params">(String name, <span class="keyword">int</span> age, String gender)</span> </span>{</span><br><span class="line"> System.out.println(<span class="string">"【JPeople】带参构造器"</span>);</span><br><span class="line"> <span class="keyword">this</span>.name = name;</span><br><span class="line"> <span class="keyword">this</span>.age = age;</span><br><span class="line"> <span class="keyword">this</span>.gender = gender;</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="comment">//静态方法</span></span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">f</span><span class="params">()</span> </span>{</span><br><span class="line"> System.out.println(<span class="string">"【JPeople】静态方法"</span>);</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="comment">//实例方法</span></span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">sayHello</span><span class="params">()</span> </span>{</span><br><span class="line"> System.out.println(<span class="string">"【JPeople】"</span>+<span class="keyword">this</span>.name + <span class="string">" say:\"Hello\""</span>);</span><br><span class="line"> pf();</span><br><span class="line"> }</span><br><span class="line"> </span><br><span class="line"> <span class="comment">//私有方法</span></span><br><span class="line"> <span class="function"><span class="keyword">private</span> <span class="keyword">void</span> <span class="title">pf</span><span class="params">()</span></span>{</span><br><span class="line"> System.out.println(<span class="string">"【JPeople】私有方法"</span>);</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">PeopleTest</span> </span>{</span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>{</span><br><span class="line"> People tom = <span class="keyword">new</span> People(<span class="string">"tom"</span>, <span class="number">18</span>, <span class="string">"male"</span>);</span><br><span class="line"> tom.sayHello();</span><br><span class="line"> People.f();</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p> Java执行结果</p><p><img src="http://imagebed.shaoyong.online/images/2019_7_29/1.png" alt></p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">People</span>:</span></span><br><span class="line"> <span class="string">"""People"""</span></span><br><span class="line"> <span class="comment"># 私有属性</span></span><br><span class="line"> __gift = <span class="number">100</span></span><br><span class="line"> <span class="comment"># 类属性</span></span><br><span class="line"> name = <span class="string">''</span></span><br><span class="line"> age = <span class="number">0</span></span><br><span class="line"> </span><br><span class="line"> <span class="comment"># 限定对象只能绑定_gender属性</span></span><br><span class="line"> <span class="comment"># __slots__=('_gender')</span></span><br><span class="line"> </span><br><span class="line"> <span class="comment"># 实例化方法</span></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">__init__</span><span class="params">(self, name, age, gender)</span>:</span></span><br><span class="line"> print(<span class="string">"【PPeople】构造方法"</span>)</span><br><span class="line"> self.name = name</span><br><span class="line"> self.age = age</span><br><span class="line"> self._gender = gender</span><br><span class="line"></span><br><span class="line"> <span class="comment"># getter方法</span></span><br><span class="line"><span class="meta"> @property</span></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">gender</span><span class="params">(self)</span>:</span></span><br><span class="line"> <span class="keyword">return</span> self._gender</span><br><span class="line"> </span><br><span class="line"> <span class="comment"># setter方法</span></span><br><span class="line"><span class="meta"> @gender.setter</span></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">gender</span><span class="params">(self,gender)</span>:</span></span><br><span class="line"> self._gender=gender</span><br><span class="line"> </span><br><span class="line"> <span class="comment"># 静态方法</span></span><br><span class="line"><span class="meta"> @staticmethod</span></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">sf</span><span class="params">()</span>:</span></span><br><span class="line"> print(<span class="string">"【PPeople】静态方法"</span>)</span><br><span class="line"></span><br><span class="line"> <span class="comment"># 类方法</span></span><br><span class="line"><span class="meta"> @classmethod</span></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">cf</span><span class="params">(cls)</span>:</span></span><br><span class="line"> print(<span class="string">"【PPeople】类方法"</span>)</span><br><span class="line"></span><br><span class="line"> <span class="comment"># 实例方法</span></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">say_hello</span><span class="params">(self)</span>:</span></span><br><span class="line"> print(<span class="string">"【PPeople】{} say:\"Hello!\",gift={}"</span>.format(self.name, self.__gift))</span><br><span class="line"> self.__pf()</span><br><span class="line"></span><br><span class="line"> <span class="comment"># 私有方法</span></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">__pf</span><span class="params">(self)</span>:</span></span><br><span class="line"> print(<span class="string">"【PPeople】私有方法"</span>)</span><br><span class="line"></span><br><span class="line">People.age += <span class="number">1</span></span><br><span class="line">print(People.age)</span><br><span class="line">People.sf()</span><br><span class="line">tom = People(<span class="string">'Tom'</span>, <span class="number">18</span>, <span class="string">'male'</span>)</span><br><span class="line">tom.gender=<span class="string">"female"</span></span><br><span class="line">print(tom.gender)</span><br><span class="line">tom.say_hello()</span><br></pre></td></tr></table></figure><p> Python执行结果</p><p><img src="http://imagebed.shaoyong.online/images/2019_7_29/2.png" alt></p><h2 id="小结"><a href="#小结" class="headerlink" title="小结"></a>小结</h2><table><thead><tr><th></th><th>Java</th><th>Python</th></tr></thead><tbody><tr><td>私有属性</td><td>(成员变量)使用<code>private</code>关键字修饰</td><td>属性名双下划线开头<code>__</code>;不建议将属性设置为私有,建议以<code>_</code>(单下划线)开头,暗示属性为受保护的,不建议外部直接访问,建议使用getter、setter进行操作</td></tr><tr><td>类属性</td><td>使用<code>static</code>修饰的变量</td><td>类和对象都可以访问</td></tr><tr><td>构造方法</td><td>有参、无参构造器;方法名与类名相同</td><td>(实例化方法)方法名固定<code>__init__</code></td></tr><tr><td>实例方法</td><td>对象访问</td><td>(普通方法)对象访问,默认有参<code>self</code></td></tr><tr><td>私有方法</td><td>使用<code>private</code>关键字修饰</td><td>方法名双下划线开头<code>__</code></td></tr><tr><td>静态方法</td><td>使用<code>static</code>关键字修饰</td><td>使用<code>@staticmethod</code>装饰器,可以无参</td></tr><tr><td>类方法</td><td>同静态方法</td><td>使用<code>@classmethod</code>装饰器,类和对象访问,默认参数<code>cls</code></td></tr></tbody></table><h1 id="继承"><a href="#继承" class="headerlink" title="继承"></a>继承</h1><p> 在Java中类只能单继承继承,因为Java的设计者认为,多继承会让语言本身变得非常复杂(如同C++),效率也会降低(如同Eiffrl),而为了让程序设计更加灵活,Java中就有了接口(<code>interface</code>),接口之间可以多继承。而Python的类可以多继承,也就没必要有接口;下面分别使用Java和Python 3实现<code>Student</code>子类</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Student</span> <span class="keyword">extends</span> <span class="title">People</span></span>{</span><br><span class="line"></span><br><span class="line"> <span class="comment">//学号</span></span><br><span class="line"> <span class="keyword">private</span> String studentNumber;</span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">public</span> String <span class="title">getStudentNumber</span><span class="params">()</span> </span>{</span><br><span class="line"> <span class="keyword">return</span> studentNumber;</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">setStudentNumber</span><span class="params">(String studentNumber)</span> </span>{</span><br><span class="line"> <span class="keyword">this</span>.studentNumber = studentNumber;</span><br><span class="line"> }</span><br><span class="line"> <span class="comment">//子类无参构造器</span></span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="title">Student</span><span class="params">()</span> </span>{</span><br><span class="line"></span><br><span class="line"> }</span><br><span class="line"> <span class="comment">//带参构造器</span></span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="title">Student</span><span class="params">(String name, <span class="keyword">int</span> age, String gender, String studentNumber)</span> </span>{</span><br><span class="line"> <span class="comment">//调用父类带参构造器</span></span><br><span class="line"> <span class="keyword">super</span>(name, age, gender);</span><br><span class="line"> System.out.println(<span class="string">"【JStudent】带参构造器"</span>);</span><br><span class="line"> <span class="keyword">this</span>.studentNumber = studentNumber;</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="comment">//重写父类方法</span></span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">sayHello</span><span class="params">()</span></span>{</span><br><span class="line"> System.out.println(<span class="string">"【JStudent】"</span>+<span class="keyword">this</span>.getName() + <span class="string">" say:\"Hello\""</span>);</span><br><span class="line"> }</span><br><span class="line"> </span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>{</span><br><span class="line"> Student student_1 = <span class="keyword">new</span> Student(<span class="string">"Jerry"</span>, <span class="number">17</span>, <span class="string">"male"</span>, <span class="string">"0021"</span>);</span><br><span class="line"> student_1.sayHello();</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p> Java执行结果</p><p><img src="http://imagebed.shaoyong.online/images/2019_7_29/3.png" alt></p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 单继承</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Student</span><span class="params">(People)</span>:</span></span><br><span class="line"> <span class="comment"># 子类构造方法</span></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">__init__</span><span class="params">(self, name, age, gender, student_number)</span>:</span></span><br><span class="line"> print(<span class="string">"【PStudent】构造方法--开始"</span>)</span><br><span class="line"> <span class="comment"># 调用超类构造方法</span></span><br><span class="line"> super(Student, self).__init__(name, age, gender)</span><br><span class="line"> self.student_number = student_number</span><br><span class="line"> print(<span class="string">"【PStudent】构造方法--结束"</span>)</span><br><span class="line"></span><br><span class="line"> <span class="comment"># 重写父类方法</span></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">say_hello</span><span class="params">(self)</span>:</span></span><br><span class="line"> print(<span class="string">"【PStudent】{} say:\"Hello!\""</span>.format(self.name))</span><br><span class="line"> </span><br><span class="line"><span class="comment"># Child类,为多继承做准备</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Child</span>:</span></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">__init__</span><span class="params">(self, name, mom, dad)</span>:</span></span><br><span class="line"> print(<span class="string">"【PChild】构造方法"</span>)</span><br><span class="line"> self.name = name</span><br><span class="line"> self.mom = mom</span><br><span class="line"> self.dad = dad</span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">cry</span><span class="params">(self)</span>:</span></span><br><span class="line"> print(<span class="string">'【PChild】'</span>+self.name + <span class="string">":\'wow wow\'"</span>)</span><br><span class="line"></span><br><span class="line"><span class="comment"># 多重继承</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Kid</span><span class="params">(Student, Child)</span>:</span></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">__init__</span><span class="params">(self, name, age, gender, student_number, mom, dad)</span>:</span></span><br><span class="line"> print(<span class="string">"【PKid】构造方法--开始"</span>)</span><br><span class="line"> Student.__init__(self, name, age, gender, student_number)</span><br><span class="line"> Child.__init__(self, name, mom, dad)</span><br><span class="line"> print(<span class="string">"【PKid】构造方法--结束"</span>)</span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">info</span><span class="params">(self)</span>:</span></span><br><span class="line"> print(<span class="string">'【PKid】'</span>+<span class="string">', '</span>.join([<span class="string">'%s:%s'</span> % item <span class="keyword">for</span> item <span class="keyword">in</span> self.__dict__.items()]))</span><br><span class="line"></span><br><span class="line"><span class="comment"># 创建一个Student对象</span></span><br><span class="line">jerry = Student(<span class="string">"Jerry"</span>, <span class="number">17</span>, <span class="string">'male'</span>, <span class="string">'0021'</span>)</span><br><span class="line">print(jerry.name)</span><br><span class="line">jerry.say_hello()</span><br><span class="line"><span class="comment"># 创建一个Kid对象</span></span><br><span class="line">kid = Kid(<span class="string">"小明"</span>, <span class="number">12</span>, <span class="string">"男"</span>, <span class="string">"0023"</span>, <span class="string">"Tom"</span>, <span class="string">"Jerry"</span>)</span><br><span class="line">kid.info()</span><br></pre></td></tr></table></figure><p> Python执行结果</p><p><img src="http://imagebed.shaoyong.online/images/2019_7_29/4.png" alt></p><h2 id="小结-1"><a href="#小结-1" class="headerlink" title="小结"></a>小结</h2><p> Java与Python 3 在掉用构造方法时顺序是一致的,但是Java在构造方法内调用父类构造方法,语句<code>super()</code>必须放在方法体的第一句;而Python 3,对象是由 <code>__new__()</code>和<code>__init__()</code>协作构造完成,实例通过<code>__new__</code>方法被创建,使用<code>__init__</code>方法进行初始化;所以在调用父类方法之前,可以对参数进行定制修改。Python 3 的多继承,在搜索从父类继承的方法/属性时,可以简单认为是深度优先、从左至右;但为了保持单次调用,实际在调用时是<a href="https://www.python.org/download/releases/2.3/mro/" target="_blank" rel="noopener">动态</a>的;</p><h1 id="多态"><a href="#多态" class="headerlink" title="多态"></a>多态</h1><p> 实现多态的步骤:1.继承父类 2.重写父类方法 3.向上转型</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**1.Teacher继承自People**/</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Teacher</span> <span class="keyword">extends</span> <span class="title">People</span> </span>{</span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="title">Teacher</span><span class="params">()</span> </span>{</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="title">Teacher</span><span class="params">(String name, <span class="keyword">int</span> age, String gender)</span> </span>{</span><br><span class="line"> <span class="keyword">super</span>(name, age, gender);</span><br><span class="line"> }</span><br><span class="line"> <span class="comment">//2.重写sayHello方法</span></span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">sayHello</span><span class="params">()</span> </span>{</span><br><span class="line"> System.out.println(<span class="string">"【JTeacher】"</span>+<span class="keyword">this</span>.getName() + <span class="string">":\" 同学们早上好!\""</span>);</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Test</span> </span>{</span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>{</span><br><span class="line"> <span class="comment">//3.向上转型</span></span><br><span class="line"> People teacher= <span class="keyword">new</span> Teacher(<span class="string">"王阳明"</span>,<span class="number">45</span>,<span class="string">"男"</span>);</span><br><span class="line"> teacher.sayHello();</span><br><span class="line"> People student =<span class="keyword">new</span> Student(<span class="string">"小明"</span>, <span class="number">17</span>, <span class="string">"男"</span>, <span class="string">"0021"</span>);</span><br><span class="line"> student.sayHello();</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>java运行结果:</p><p><img src="http://imagebed.shaoyong.online/images/2019_7_29/5.png" alt></p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Teacher</span><span class="params">(People)</span>:</span></span><br><span class="line"> <span class="string">"""继承自People"""</span></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">__init__</span><span class="params">(self, name, age, gender)</span>:</span></span><br><span class="line"> print(<span class="string">"【PTeacher】构造方法--开始"</span>)</span><br><span class="line"> super(Teacher, self).__init__(name, age, gender)</span><br><span class="line"> print(<span class="string">"【PTeacher】构造方法--结束"</span>)</span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">say_hello</span><span class="params">(self)</span>:</span></span><br><span class="line"> print(<span class="string">"【PTeacher】{} say:\"同学们好!\""</span>.format(self.name))</span><br><span class="line"> </span><br><span class="line">people_1 = Student(<span class="string">"小明"</span>, <span class="number">12</span>, <span class="string">"男"</span>, <span class="string">"0023"</span>)</span><br><span class="line">people_1.say_hello()</span><br><span class="line">people_2 = Teacher(<span class="string">"王阳明"</span>, <span class="number">45</span>, <span class="string">"男"</span>)</span><br><span class="line">people_2.say_hello()</span><br></pre></td></tr></table></figure><p>Python运行结果:</p><p><img src="http://imagebed.shaoyong.online/images/2019_7_29/6.png" alt></p><h2 id="小结-2"><a href="#小结-2" class="headerlink" title="小结"></a>小结</h2><blockquote><p>Python从语法层面并没有像Java那样提供对抽象类的支持,但是我们可以通过<code>abc</code>模块的<code>ABCMeta</code>元类和<code>abstractmethod</code>(<code>class CLASSNAME(metaclass=ABCMeta):</code>)包装器来达到抽象类的效果,如果一个类中存在抽象方法那么这个类就不能够实例化。</p></blockquote>]]></content>
<summary type="html">
这里记录下Python3与Java在面向对象方面的区别
</summary>
<category term="笔记" scheme="http://www.shaoyong.online/categories/%E7%AC%94%E8%AE%B0/"/>
<category term="Java" scheme="http://www.shaoyong.online/tags/Java/"/>
<category term="Python3" scheme="http://www.shaoyong.online/tags/Python3/"/>
<category term="OOP" scheme="http://www.shaoyong.online/tags/OOP/"/>
</entry>
<entry>
<title>CentOS7查杀nanoWath挖矿木马</title>
<link href="http://www.shaoyong.online/posts/34761/"/>
<id>http://www.shaoyong.online/posts/34761/</id>
<published>2019-07-21T11:09:09.301Z</published>
<updated>2019-09-15T10:34:46.025Z</updated>
<content type="html"><![CDATA[<p>前几天在查看服务器时状态时发现cpu占用率达到了103%</p><p><img src="http://imagebed.shaoyong.online/images/2019_7_21/1.png" alt></p><p>这个VPS主要是拿来玩玩,平时上面并没有什么大的服务再运行,不可能会占满CPU的;用shell客户端连上VPS,执行<code>ps aux</code>,其中一个叫nanoWatch的进程cpu占用率达到了99.5%</p><p><img src="http://imagebed.shaoyong.online/images/2019_7_21/2.png" alt></p><p>直接杀掉这个进程<code>kill -9 17305</code>,再检查进程,没发现异常</p><p>过了没几分钟,cpu占用又满了,查看进程,这个进程又出现了;</p><p>找到<code>/tmp/nanoWatch</code>这个文件,删掉这个文件,再杀掉进程,过了几分钟,进进程再次出现。</p><p>我怀疑是定时启动的任务, <code>crontab -l</code>查看cron计划任务,显示出来了两个定时任务,每5分钟和7分钟执行一次下载文件,我手动把这个文件下下来,是一个脚本</p><p><img src="http://imagebed.shaoyong.online/images/2019_7_21/3.png" alt></p><p>删除定时任务<code>crontab -r</code>,删掉文件,杀掉进程,<del>结束了</del>。</p><p><img src="http://imagebed.shaoyong.online/images/2019_7_21/4.png" alt></p><hr><p>过了两天,又出现CPU占用异常。</p><p><img src="http://imagebed.shaoyong.online/images/2019_7_21/5.png" alt></p><p>我之前一直是用root用户并使用20端口进行ssh连接,这是非常不安全的行为,很容易被端口扫描暴力破解密码登录服务器。简单的解决办法如下</p><p>[TOC]</p><h1 id="修改ssh连接端口"><a href="#修改ssh连接端口" class="headerlink" title="修改ssh连接端口"></a>修改ssh连接端口</h1><p>用 root 用户进入 <code>/etc/ssh/</code> </p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">cd</span> /etc/ssh/</span><br><span class="line"><span class="comment">#用 vi 打开 sshd_config 文件</span></span><br><span class="line">vim sshd_config</span><br><span class="line"><span class="comment">#添加端口20022(22号是默认端口,注释掉也是默认开启的),并解开22端口注释</span></span><br></pre></td></tr></table></figure><p><img src="http://imagebed.shaoyong.online/images/2019_7_21/6.png" alt></p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">#重启ssh </span></span><br><span class="line">systemctl restart sshd</span><br><span class="line"><span class="comment">#查看防火墙规则</span></span><br><span class="line">firewall-cmd --permanent --list-port</span><br><span class="line"><span class="comment">#向防火墙中添加端口</span></span><br><span class="line">firewall-cmd --zone=public --add-port=20022/tcp --permanent</span><br><span class="line">reaload </span><br><span class="line"><span class="comment">#重新加载防火墙规则</span></span><br><span class="line">firewall-cmd --reload</span><br></pre></td></tr></table></figure><p><img src="http://imagebed.shaoyong.online/images/2019_7_21/7.png" alt></p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">#查看20022端口是否添加成功</span></span><br><span class="line">firewall-cmd --zone=public --query-port=20022/tcp</span><br></pre></td></tr></table></figure><p><img src="http://imagebed.shaoyong.online/images/2019_7_21/8.png" alt></p><p>断开ssh连接,换用<code>20022</code>端口连接<br>修改<code>/etc/ssh/sshd_config</code>将<code>22</code>号端口注释掉</p><p><img src="http://imagebed.shaoyong.online/images/2019_7_21/9.png" alt></p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">#重启ssh</span></span><br><span class="line">systemctl restart sshd</span><br><span class="line"><span class="comment">#查看ssh监听的端口</span></span><br><span class="line">ss -tnlp|grep ssh</span><br></pre></td></tr></table></figure><p><img src="http://imagebed.shaoyong.online/images/2019_7_21/10.png" alt></p><h1 id="禁用root登入,使用普通用户登入"><a href="#禁用root登入,使用普通用户登入" class="headerlink" title="禁用root登入,使用普通用户登入"></a>禁用root登入,使用普通用户登入</h1><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">#先创建一个普通用户test,同时给test用户设置密码</span></span><br><span class="line">adduser <span class="built_in">test</span></span><br><span class="line">passwd <span class="built_in">test</span></span><br><span class="line"><span class="comment">#接着禁用root登录(修改sshd_config文件)</span></span><br><span class="line">vi /etc/ssh/sshd_config</span><br></pre></td></tr></table></figure><p><img src="http://imagebed.shaoyong.online/images/2019_7_21/11.png" alt></p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">#重启ssh</span></span><br><span class="line">Systemctl restart sshd.service</span><br></pre></td></tr></table></figure><hr>]]></content>
<summary type="html">
挖矿木马查杀与服务器安全的简单配置
</summary>
<category term="服务器安全" scheme="http://www.shaoyong.online/categories/%E6%9C%8D%E5%8A%A1%E5%99%A8%E5%AE%89%E5%85%A8/"/>
<category term="SSH" scheme="http://www.shaoyong.online/tags/SSH/"/>
<category term="CentOS7" scheme="http://www.shaoyong.online/tags/CentOS7/"/>
</entry>
<entry>
<title>Docker启动Redis</title>
<link href="http://www.shaoyong.online/posts/61166/"/>
<id>http://www.shaoyong.online/posts/61166/</id>
<published>2019-07-21T05:10:08.771Z</published>
<updated>2019-09-15T10:34:46.023Z</updated>
<content type="html"><![CDATA[<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">#docker中启动redis并设置密码</span></span><br><span class="line">docker run -d --name myredis -p 6379:6379 redis --requirepass <span class="string">"mypassword"</span></span><br></pre></td></tr></table></figure>]]></content>
<summary type="html">
docker启动redis并设置密码
</summary>
<category term="笔记" scheme="http://www.shaoyong.online/categories/%E7%AC%94%E8%AE%B0/"/>
<category term="Docker" scheme="http://www.shaoyong.online/categories/%E7%AC%94%E8%AE%B0/Docker/"/>
<category term="Redis" scheme="http://www.shaoyong.online/tags/Redis/"/>
</entry>
<entry>
<title>Docker安装RabbitMq</title>
<link href="http://www.shaoyong.online/posts/62858/"/>
<id>http://www.shaoyong.online/posts/62858/</id>
<published>2019-07-21T05:00:51.454Z</published>
<updated>2019-09-15T10:34:46.030Z</updated>
<content type="html"><![CDATA[<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">#设置rabbit默认用户与密码</span></span><br><span class="line">docker run -d --hostname rabbit-host --name rabbitMq -e RABBITMQ_DEFAULT_USER=username -e RABBITMQ_DEFAULT_PASS=password -p 5672:5672 -p 15672:15672 rabbitmq:3.7.3-management</span><br></pre></td></tr></table></figure><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">#在docker中停止rabbitMq</span></span><br><span class="line">docker stop rabbitMq</span><br></pre></td></tr></table></figure>]]></content>
<summary type="html">
Docker中安装rabbitMq
</summary>
<category term="笔记" scheme="http://www.shaoyong.online/categories/%E7%AC%94%E8%AE%B0/"/>
<category term="Docker" scheme="http://www.shaoyong.online/categories/%E7%AC%94%E8%AE%B0/Docker/"/>
<category term="RabbitMq" scheme="http://www.shaoyong.online/tags/RabbitMq/"/>
</entry>
<entry>
<title>Docker安装Mysql5.7</title>
<link href="http://www.shaoyong.online/posts/57388/"/>
<id>http://www.shaoyong.online/posts/57388/</id>
<published>2019-07-21T04:26:59.572Z</published>
<updated>2019-09-15T10:34:46.028Z</updated>
<content type="html"><![CDATA[<p>在Docker中mysql5.7安装和设置与8.0基本一致</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># docker 中下载 mysql</span></span><br><span class="line">docker pull mysql:5.7</span><br><span class="line"></span><br><span class="line"><span class="comment">#启动并设置root密码</span></span><br><span class="line">docker run --name mysql -p 3306:3306 -e MYSQL_ROOT_PASSWORD=your_password -d mysql:5.7</span><br><span class="line"></span><br><span class="line"><span class="comment">#进入容器</span></span><br><span class="line">docker <span class="built_in">exec</span> -it mysql bash</span><br><span class="line"></span><br><span class="line"><span class="comment">#登录mysql</span></span><br><span class="line">mysql -u root -p</span><br><span class="line"><span class="comment">#设置root用户密码</span></span><br><span class="line">ALTER USER <span class="string">'root'</span>@<span class="string">'localhost'</span> IDENTIFIED BY <span class="string">'your_password'</span>;</span><br><span class="line"></span><br><span class="line"><span class="comment">#添加远程登录用户</span></span><br><span class="line">CREATE USER <span class="string">'your_username'</span>@<span class="string">'%'</span> IDENTIFIED WITH mysql_native_password BY <span class="string">'your_password'</span>;</span><br><span class="line">GRANT ALL PRIVILEGES ON *.* TO <span class="string">'your_password'</span>@<span class="string">'%'</span>;</span><br></pre></td></tr></table></figure>]]></content>
<summary type="html">
Docker中安装mysql5.7/8.0并设置密码和远程登入
</summary>
<category term="笔记" scheme="http://www.shaoyong.online/categories/%E7%AC%94%E8%AE%B0/"/>
<category term="Docker" scheme="http://www.shaoyong.online/categories/%E7%AC%94%E8%AE%B0/Docker/"/>
<category term="Mysql" scheme="http://www.shaoyong.online/tags/Mysql/"/>
</entry>
<entry>
<title>在IDEA中使用Dockerfile</title>
<link href="http://www.shaoyong.online/posts/55214/"/>
<id>http://www.shaoyong.online/posts/55214/</id>
<published>2019-07-21T03:34:32.425Z</published>
<updated>2019-09-15T10:34:46.049Z</updated>
<content type="html"><![CDATA[<p>在IDEA中使用Dockerfile简单步骤</p><ol><li><p>在项目根目录创建Dockerfile文件</p></li><li><p>在Dockerfile中写入</p><figure class="highlight dockerfile"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">#引用基础镜像</span></span><br><span class="line"><span class="keyword">FROM</span> java:<span class="number">8</span>-jre</span><br><span class="line"></span><br><span class="line"><span class="comment">#将需要在Docker中运行的jar包复制到镜像中</span></span><br><span class="line"><span class="keyword">ADD</span><span class="bash"> target/*.jar applicationName.jar</span></span><br><span class="line"></span><br><span class="line"><span class="comment">#暴露端口</span></span><br><span class="line"><span class="keyword">EXPOSE</span> <span class="number">8888</span></span><br><span class="line"></span><br><span class="line"><span class="comment">#容器启动时执行的命令</span></span><br><span class="line"><span class="keyword">ENTRYPOINT</span><span class="bash"> [<span class="string">"java"</span>, <span class="string">"-jar"</span>, <span class="string">"applicationName.jar"</span>, <span class="string">"--server.port=8888"</span>]</span></span><br></pre></td></tr></table></figure></li><li><p>使用maven打包项目,运行Dockerfile文件</p></li></ol><p><strong>ps:启动前需要配置IDEA与Docker服务器的连接</strong></p>]]></content>
<summary type="html">
一个简单的Dockerfile文件
</summary>
<category term="笔记" scheme="http://www.shaoyong.online/categories/%E7%AC%94%E8%AE%B0/"/>
<category term="Docker" scheme="http://www.shaoyong.online/categories/%E7%AC%94%E8%AE%B0/Docker/"/>
<category term="IDEA" scheme="http://www.shaoyong.online/tags/IDEA/"/>
<category term="Dockerflie" scheme="http://www.shaoyong.online/tags/Dockerflie/"/>
</entry>
</feed>