-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathatom.xml
More file actions
527 lines (285 loc) · 144 KB
/
atom.xml
File metadata and controls
527 lines (285 loc) · 144 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
<title>Zehai'blog</title>
<link href="/atom.xml" rel="self"/>
<link href="http://zehai.info/"/>
<updated>2021-08-16T08:19:18.747Z</updated>
<id>http://zehai.info/</id>
<author>
<name>Zhang Zehai</name>
</author>
<generator uri="http://hexo.io/">Hexo</generator>
<entry>
<title>Leetcode233</title>
<link href="http://zehai.info/2021/08/13/2021-08-13-Leetcode233/"/>
<id>http://zehai.info/2021/08/13/2021-08-13-Leetcode233/</id>
<published>2021-08-13T03:54:52.000Z</published>
<updated>2021-08-16T08:19:18.747Z</updated>
<content type="html"><![CDATA[<h4 id="233-数字-1-的个数"><a href="#233-数字-1-的个数" class="headerlink" title="233. 数字 1 的个数"></a><a href="https://leetcode-cn.com/problems/number-of-digit-one/">233. 数字 1 的个数</a></h4><p>难度困难303收藏分享切换为英文接收动态反馈</p><p>给定一个整数 <code>n</code>,计算所有小于等于 <code>n</code> 的非负整数中数字 <code>1</code> 出现的个数。</p><p><strong>示例 1:</strong></p><figure class="highlight plaintext"><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">输入:n = 13</span><br><span class="line">输出:6</span><br></pre></td></tr></table></figure><p><strong>示例 2:</strong></p><figure class="highlight plaintext"><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">输入:n = 0</span><br><span class="line">输出:0</span><br></pre></td></tr></table></figure><p><strong>提示:</strong></p><ul><li><code>0 <= n <= 2 * 109</code></li></ul><h1 id="Solution"><a href="#Solution" class="headerlink" title="Solution"></a>Solution</h1><p>拿到题目很奇怪,这道题暴力解答也就是个稍稍大于o(n)的复杂度,作为hard题目出现,只能说明暴力会超时</p><p>那么先回顾一下整体的超时代码段</p><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></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@param <span class="type">{number}</span> <span class="variable">n</span></span></span></span><br><span class="line"><span class="comment"> * <span class="doctag">@return <span class="type">{number}</span></span></span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">var</span> countDigitOne = <span class="function"><span class="keyword">function</span> (<span class="params">n</span>) </span>{</span><br><span class="line"> <span class="keyword">let</span> counter = <span class="number">0</span>;</span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">let</span> i = n; i > <span class="number">0</span>; i--) {</span><br><span class="line"> <span class="keyword">let</span> num = i;</span><br><span class="line"> <span class="keyword">while</span> (num > <span class="number">0</span>) {</span><br><span class="line"> <span class="keyword">if</span> (num % <span class="number">10</span> === <span class="number">1</span>) {</span><br><span class="line"> counter++;</span><br><span class="line"> }</span><br><span class="line"> num = <span class="built_in">Math</span>.floor(num / <span class="number">10</span>);</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> counter</span><br><span class="line">};</span><br></pre></td></tr></table></figure><p>超时之后我就开始找规律,个位1只会出现1次,十位只会出现10次,百位是100次,之后是数学方法就不解了(懒orz),答案的主要部分</p><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">for</span> (<span class="keyword">let</span> k = <span class="number">0</span>; n >= mulk; ++k) {</span><br><span class="line"> ans += (<span class="built_in">Math</span>.floor(n / (mulk * <span class="number">10</span>))) * mulk + <span class="built_in">Math</span>.min(<span class="built_in">Math</span>.max(n % (mulk * <span class="number">10</span>) - mulk + <span class="number">1</span>, <span class="number">0</span>), mulk);</span><br><span class="line"> mulk *= <span class="number">10</span>;</span><br><span class="line"> }</span><br></pre></td></tr></table></figure>]]></content>
<summary type="html">
<h4 id="233-数字-1-的个数"><a href="#233-数字-1-的个数" class="headerlink" title="233. 数字 1 的个数"></a><a href="https://leetcode-cn.com/problems/number-
</summary>
<category term="LeetCode" scheme="http://zehai.info/categories/LeetCode/"/>
<category term="Hard" scheme="http://zehai.info/tags/Hard/"/>
</entry>
<entry>
<title>Leetcode133</title>
<link href="http://zehai.info/2021/08/13/2021-08-13-Leetcode133/"/>
<id>http://zehai.info/2021/08/13/2021-08-13-Leetcode133/</id>
<published>2021-08-13T03:48:19.000Z</published>
<updated>2021-08-13T03:55:24.571Z</updated>
<content type="html"><![CDATA[<h4 id="133-克隆图"><a href="#133-克隆图" class="headerlink" title="133. 克隆图"></a><a href="https://leetcode-cn.com/problems/clone-graph/">133. 克隆图</a></h4><p>难度中等390收藏分享切换为英文接收动态反馈</p><p>给你无向 <strong><a href="https://baike.baidu.com/item/连通图/6460995?fr=aladdin">连通</a></strong> 图中一个节点的引用,请你返回该图的 <a href="https://baike.baidu.com/item/深拷贝/22785317?fr=aladdin"><strong>深拷贝</strong></a>(克隆)。</p><p>图中的每个节点都包含它的值 <code>val</code>(<code>int</code>) 和其邻居的列表(<code>list[Node]</code>)。</p><h1 id="Solution"><a href="#Solution" class="headerlink" title="Solution"></a>Solution</h1><p>dfs就可以解决</p><p>题目提供了索引就是val,所以map的key可以使用val来简化体积</p><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></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * // Definition for a Node.</span></span><br><span class="line"><span class="comment"> * function Node(val, neighbors) {</span></span><br><span class="line"><span class="comment"> * this.val = val === undefined ? 0 : val;</span></span><br><span class="line"><span class="comment"> * this.neighbors = neighbors === undefined ? [] : neighbors;</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><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@param <span class="type">{Node}</span> <span class="variable">node</span></span></span></span><br><span class="line"><span class="comment"> * <span class="doctag">@return <span class="type">{Node}</span></span></span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">var</span> cloneGraph = <span class="function"><span class="keyword">function</span> (<span class="params">node</span>) </span>{</span><br><span class="line"> <span class="keyword">if</span> (!node) <span class="keyword">return</span>;</span><br><span class="line"> <span class="keyword">let</span> isVisit = <span class="keyword">new</span> <span class="built_in">Map</span>();</span><br><span class="line"> <span class="comment">//dfs</span></span><br><span class="line"> <span class="keyword">const</span> dfs = <span class="function"><span class="keyword">function</span> (<span class="params">item</span>) </span>{</span><br><span class="line"> <span class="keyword">const</span> newNode = <span class="keyword">new</span> Node(item.val);</span><br><span class="line"> isVisit.set(item.val, newNode);</span><br><span class="line"> <span class="comment">// console.log('isVist===>',isVisit)</span></span><br><span class="line"> <span class="comment">// deep clone</span></span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">let</span> neighbor <span class="keyword">of</span> item.neighbors) {</span><br><span class="line"> <span class="keyword">if</span> (!isVisit.has(neighbor.val)) {</span><br><span class="line"> dfs(neighbor);</span><br><span class="line"> }</span><br><span class="line"> newNode.neighbors.push(isVisit.get(neighbor.val))</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> dfs(node);</span><br><span class="line"> <span class="keyword">return</span> isVisit.get(node.val);</span><br><span class="line">};</span><br></pre></td></tr></table></figure>]]></content>
<summary type="html">
<h4 id="133-克隆图"><a href="#133-克隆图" class="headerlink" title="133. 克隆图"></a><a href="https://leetcode-cn.com/problems/clone-graph/">133. 克隆图
</summary>
<category term="LeetCode" scheme="http://zehai.info/categories/LeetCode/"/>
<category term="Medium" scheme="http://zehai.info/tags/Medium/"/>
</entry>
<entry>
<title>LeetCode611</title>
<link href="http://zehai.info/2021/08/04/2021-08-04-LeetCode611/"/>
<id>http://zehai.info/2021/08/04/2021-08-04-LeetCode611/</id>
<published>2021-08-04T07:37:34.000Z</published>
<updated>2021-08-04T07:50:16.771Z</updated>
<content type="html"><![CDATA[<h4 id="611-有效三角形的个数"><a href="#611-有效三角形的个数" class="headerlink" title="611. 有效三角形的个数"></a><a href="https://leetcode-cn.com/problems/valid-triangle-number/">611. 有效三角形的个数</a></h4><p>难度中等230收藏分享切换为英文接收动态反馈</p><p>给定一个包含非负整数的数组,你的任务是统计其中可以组成三角形三条边的三元组个数。</p><p><strong>示例 1:</strong></p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">输入: [2,2,3,4]</span><br><span class="line">输出: 3</span><br><span class="line">解释:</span><br><span class="line">有效的组合是: </span><br><span class="line">2,3,4 (使用第一个 2)</span><br><span class="line">2,3,4 (使用第二个 2)</span><br><span class="line">2,2,3</span><br></pre></td></tr></table></figure><p><strong>注意:</strong></p><ol><li>数组长度不超过1000。</li><li>数组里整数的范围为 [0, 1000]。</li></ol><h1 id="Solution"><a href="#Solution" class="headerlink" title="Solution"></a>Solution</h1><p>排序后根据,a+b>c 套两层for循环确定ab,理论上还可以再套一层for循环确定c,但是复杂度太高,达到o(n^3)的复杂度,我们可以通过二分法,找到a+b<c 和a+b>c的极限值,极限左边都是符合要求的数据,从而n降为lgn的复杂度</p><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></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@param <span class="type">{number[]}</span> <span class="variable">nums</span></span></span></span><br><span class="line"><span class="comment"> * <span class="doctag">@return <span class="type">{number}</span></span></span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">var</span> triangleNumber = <span class="function"><span class="keyword">function</span>(<span class="params">nums</span>) </span>{</span><br><span class="line"> <span class="keyword">if</span> (nums.length < <span class="number">3</span>) <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line"> <span class="keyword">let</span> ans = <span class="number">0</span>;</span><br><span class="line"> nums = nums.sort();</span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">let</span> i = <span class="number">0</span>; i < nums.length ; i++) {</span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">let</span> j = i + <span class="number">1</span>; j < nums.length ; j++) {</span><br><span class="line"> <span class="comment">// 二分</span></span><br><span class="line"> <span class="keyword">let</span> left = j + <span class="number">1</span>, right = nums.length - <span class="number">1</span>, k = j;</span><br><span class="line"> <span class="keyword">while</span> (left <= right) {</span><br><span class="line"> <span class="keyword">const</span> mid = <span class="built_in">Math</span>.floor((left + right) / <span class="number">2</span>);</span><br><span class="line"> <span class="keyword">if</span> (nums[mid] < nums[i] + nums[j]) {</span><br><span class="line"> k = mid;</span><br><span class="line"> left = mid + <span class="number">1</span>;</span><br><span class="line"> } <span class="keyword">else</span> {</span><br><span class="line"> right = mid - <span class="number">1</span>;</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> ans += k - j;</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> ans;</span><br><span class="line">};</span><br></pre></td></tr></table></figure>]]></content>
<summary type="html">
<h4 id="611-有效三角形的个数"><a href="#611-有效三角形的个数" class="headerlink" title="611. 有效三角形的个数"></a><a href="https://leetcode-cn.com/problems/valid-t
</summary>
<category term="LeetCode" scheme="http://zehai.info/categories/LeetCode/"/>
<category term="Medium" scheme="http://zehai.info/tags/Medium/"/>
</entry>
<entry>
<title>Leetcode581</title>
<link href="http://zehai.info/2021/08/03/2021-08-03-Leetcode581/"/>
<id>http://zehai.info/2021/08/03/2021-08-03-Leetcode581/</id>
<published>2021-08-03T08:12:31.000Z</published>
<updated>2021-08-03T08:17:25.973Z</updated>
<content type="html"><![CDATA[<h4 id="581-最短无序连续子数组"><a href="#581-最短无序连续子数组" class="headerlink" title="581. 最短无序连续子数组"></a><a href="https://leetcode-cn.com/problems/shortest-unsorted-continuous-subarray/">581. 最短无序连续子数组</a></h4><p>难度中等609收藏分享切换为英文接收动态反馈</p><p>给你一个整数数组 <code>nums</code> ,你需要找出一个 <strong>连续子数组</strong> ,如果对这个子数组进行升序排序,那么整个数组都会变为升序排序。</p><p>请你找出符合题意的 <strong>最短</strong> 子数组,并输出它的长度。</p><p><strong>示例 1:</strong></p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">输入:nums = [2,6,4,8,10,9,15]</span><br><span class="line">输出:5</span><br><span class="line">解释:你只需要对 [6, 4, 8, 10, 9] 进行升序排序,那么整个表都会变为升序排序。</span><br></pre></td></tr></table></figure><p><strong>示例 2:</strong></p><figure class="highlight plaintext"><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">输入:nums = [1,2,3,4]</span><br><span class="line">输出:0</span><br></pre></td></tr></table></figure><p><strong>示例 3:</strong></p><figure class="highlight plaintext"><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">输入:nums = [1]</span><br><span class="line">输出:0</span><br></pre></td></tr></table></figure><p><strong>提示:</strong></p><ul><li><code>1 <= nums.length <= 104</code></li><li><code>-105 <= nums[i] <= 105</code></li></ul><p><strong>进阶:</strong>你可以设计一个时间复杂度为 <code>O(n)</code> 的解决方案吗?</p><h1 id="Solution"><a href="#Solution" class="headerlink" title="Solution"></a>Solution</h1><p>目前想到的方法</p><ul><li>偏数学,找到最大最小值为界</li><li>排序找差别,确定子数组两边下标</li><li>排序后用二分(稍微提升)</li></ul><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></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@param <span class="type">{number[]}</span> <span class="variable">nums</span></span></span></span><br><span class="line"><span class="comment"> * <span class="doctag">@return <span class="type">{number}</span></span></span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">var</span> findUnsortedSubarray = <span class="function"><span class="keyword">function</span> (<span class="params">nums</span>) </span>{</span><br><span class="line"> <span class="keyword">let</span> start, end = -<span class="number">1</span>, point = <span class="number">0</span>;</span><br><span class="line"> <span class="keyword">let</span> max = -<span class="number">100000</span>, min = <span class="number">10000</span>;<span class="comment">//题目给的大小区间</span></span><br><span class="line"> <span class="keyword">while</span> (point < nums.length) {</span><br><span class="line"> <span class="comment">// 找分界点</span></span><br><span class="line"> max > nums[point] ? end = point : max = nums[point]</span><br><span class="line"> min < nums[nums.length - point - <span class="number">1</span>] ? start = nums.length - point - <span class="number">1</span> : min = nums[nums.length - point - <span class="number">1</span>]</span><br><span class="line"> point++;</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> end === -<span class="number">1</span> ? <span class="number">0</span> : end - start + <span class="number">1</span>;</span><br><span class="line">};</span><br></pre></td></tr></table></figure>]]></content>
<summary type="html">
<h4 id="581-最短无序连续子数组"><a href="#581-最短无序连续子数组" class="headerlink" title="581. 最短无序连续子数组"></a><a href="https://leetcode-cn.com/problems/shor
</summary>
<category term="LeetCode" scheme="http://zehai.info/categories/LeetCode/"/>
<category term="Medium" scheme="http://zehai.info/tags/Medium/"/>
</entry>
<entry>
<title>2021-08-02-Leetcode743</title>
<link href="http://zehai.info/2021/08/02/2021-08-02-Leetcode743/"/>
<id>http://zehai.info/2021/08/02/2021-08-02-Leetcode743/</id>
<published>2021-08-02T13:21:52.000Z</published>
<updated>2021-08-02T15:05:45.408Z</updated>
<content type="html"><![CDATA[<h4 id="743-网络延迟时间"><a href="#743-网络延迟时间" class="headerlink" title="743. 网络延迟时间"></a><a href="https://leetcode-cn.com/problems/network-delay-time/">743. 网络延迟时间</a></h4><p>难度中等371收藏分享切换为英文接收动态反馈</p><p>有 <code>n</code> 个网络节点,标记为 <code>1</code> 到 <code>n</code>。</p><p>给你一个列表 <code>times</code>,表示信号经过 <strong>有向</strong> 边的传递时间。 <code>times[i] = (ui, vi, wi)</code>,其中 <code>ui</code> 是源节点,<code>vi</code> 是目标节点, <code>wi</code> 是一个信号从源节点传递到目标节点的时间。</p><p>现在,从某个节点 <code>K</code> 发出一个信号。需要多久才能使所有节点都收到信号?如果不能使所有节点收到信号,返回 <code>-1</code> 。</p><p><strong>示例 1:</strong></p><p><img src="https://assets.leetcode.com/uploads/2019/05/23/931_example_1.png" alt="img"></p><figure class="highlight plaintext"><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">输入:times = [[2,1,1],[2,3,1],[3,4,1]], n = 4, k = 2</span><br><span class="line">输出:2</span><br></pre></td></tr></table></figure><p><strong>示例 2:</strong></p><figure class="highlight plaintext"><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">输入:times = [[1,2,1]], n = 2, k = 1</span><br><span class="line">输出:1</span><br></pre></td></tr></table></figure><p><strong>示例 3:</strong></p><figure class="highlight plaintext"><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">输入:times = [[1,2,1]], n = 2, k = 2</span><br><span class="line">输出:-1</span><br></pre></td></tr></table></figure><p><strong>提示:</strong></p><ul><li><code>1 <= k <= n <= 100</code></li><li><code>1 <= times.length <= 6000</code></li><li><code>times[i].length == 3</code></li><li><code>1 <= ui, vi <= n</code></li><li><code>ui != vi</code></li><li><code>0 <= wi <= 100</code></li><li>所有 <code>(ui, vi)</code> 对都 <strong>互不相同</strong>(即,不含重复边)</li></ul><h2 id="Solution"><a href="#Solution" class="headerlink" title="Solution"></a>Solution</h2><p>明显的思路,</p><ul><li>Dijkstra</li></ul><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> networkDelayTime = <span class="function"><span class="keyword">function</span> (<span class="params">times, n, k</span>) </span>{</span><br><span class="line"> <span class="keyword">const</span> INF = <span class="built_in">Number</span>.MAX_SAFE_INTEGER;<span class="comment">// max value</span></span><br><span class="line"> <span class="keyword">const</span> g = <span class="keyword">new</span> <span class="built_in">Array</span>(n).fill(INF).map(<span class="function">() =></span> <span class="keyword">new</span> <span class="built_in">Array</span>(n).fill(INF));</span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">const</span> t <span class="keyword">of</span> times) {</span><br><span class="line"> <span class="keyword">const</span> x = t[<span class="number">0</span>] - <span class="number">1</span>, y = t[<span class="number">1</span>] - <span class="number">1</span>;</span><br><span class="line"> g[x][y] = t[<span class="number">2</span>];<span class="comment">// 赋值</span></span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="keyword">const</span> dist = <span class="keyword">new</span> <span class="built_in">Array</span>(n).fill(INF);<span class="comment">//distance</span></span><br><span class="line"> dist[k - <span class="number">1</span>] = <span class="number">0</span>;<span class="comment">//k 本身为0</span></span><br><span class="line"> <span class="keyword">const</span> used = <span class="keyword">new</span> <span class="built_in">Array</span>(n).fill(<span class="literal">false</span>);<span class="comment">//遍历标记</span></span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">let</span> i = <span class="number">0</span>; i < n; ++i) {<span class="comment">//遍历每个顶点</span></span><br><span class="line"> <span class="keyword">let</span> x = -<span class="number">1</span>;</span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">let</span> y = <span class="number">0</span>; y < n; ++y) {</span><br><span class="line"> <span class="comment">// 未标记过并且(x为-1 或者 y的距离小于x的距离) 准备需要更新的节点</span></span><br><span class="line"> <span class="keyword">if</span> (!used[y] && (x === -<span class="number">1</span> || dist[y] < dist[x])) {</span><br><span class="line"> x = y;</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> used[x] = <span class="literal">true</span>;<span class="comment">//遍历标记</span></span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">let</span> y = <span class="number">0</span>; y < n; ++y) {</span><br><span class="line"> <span class="comment">// k到x的最小值</span></span><br><span class="line"> dist[y] = <span class="built_in">Math</span>.min(dist[y], dist[x] + g[x][y]);</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="keyword">let</span> ans = <span class="built_in">Math</span>.max(...dist);<span class="comment">//最小值的最大值</span></span><br><span class="line"> <span class="keyword">return</span> ans === INF ? -<span class="number">1</span> : ans;</span><br><span class="line">};</span><br><span class="line"><span class="built_in">console</span>.log(networkDelayTime([[<span class="number">2</span>, <span class="number">1</span>, <span class="number">1</span>], [<span class="number">2</span>, <span class="number">3</span>, <span class="number">1</span>], [<span class="number">3</span>, <span class="number">4</span>, <span class="number">1</span>]], <span class="number">4</span>, <span class="number">2</span>))</span><br></pre></td></tr></table></figure>]]></content>
<summary type="html">
<h4 id="743-网络延迟时间"><a href="#743-网络延迟时间" class="headerlink" title="743. 网络延迟时间"></a><a href="https://leetcode-cn.com/problems/network-delay
</summary>
<category term="LeetCode" scheme="http://zehai.info/categories/LeetCode/"/>
<category term="Medium" scheme="http://zehai.info/tags/Medium/"/>
</entry>
<entry>
<title>mongodbTransaction</title>
<link href="http://zehai.info/2021/08/02/2021-08-02-mongodbTransaction/"/>
<id>http://zehai.info/2021/08/02/2021-08-02-mongodbTransaction/</id>
<published>2021-08-02T01:34:41.000Z</published>
<updated>2021-08-02T01:36:53.496Z</updated>
<content type="html"><![CDATA[<p>前几天面试官说mongodb5出了事务,就赶紧来看看,毕竟业务层处理还是挺麻烦的,以前只支持操作的原子性</p>]]></content>
<summary type="html">
<p>前几天面试官说mongodb5出了事务,就赶紧来看看,毕竟业务层处理还是挺麻烦的,以前只支持操作的原子性</p>
</summary>
<category term="mongoDB" scheme="http://zehai.info/categories/mongoDB/"/>
<category term="transactions" scheme="http://zehai.info/tags/transactions/"/>
</entry>
<entry>
<title>Leetcode144</title>
<link href="http://zehai.info/2021/07/31/2021-07-31-Leetcode144/"/>
<id>http://zehai.info/2021/07/31/2021-07-31-Leetcode144/</id>
<published>2021-07-31T15:49:38.000Z</published>
<updated>2021-07-31T16:13:20.143Z</updated>
<content type="html"><![CDATA[<h4 id="144-二叉树的前序遍历"><a href="#144-二叉树的前序遍历" class="headerlink" title="144. 二叉树的前序遍历"></a><a href="https://leetcode-cn.com/problems/binary-tree-preorder-traversal/">144. 二叉树的前序遍历</a></h4><p>总体思路递归,easy等级</p><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></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * Definition for a binary tree node.</span></span><br><span class="line"><span class="comment"> * function TreeNode(val, left, right) {</span></span><br><span class="line"><span class="comment"> * this.val = (val===undefined ? 0 : val)</span></span><br><span class="line"><span class="comment"> * this.left = (left===undefined ? null : left)</span></span><br><span class="line"><span class="comment"> * this.right = (right===undefined ? null : right)</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="comment"> * <span class="doctag">@param <span class="type">{TreeNode}</span> <span class="variable">root</span></span></span></span><br><span class="line"><span class="comment"> * <span class="doctag">@return <span class="type">{number[]}</span></span></span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">var</span> preorderTraversal = <span class="function"><span class="keyword">function</span> (<span class="params">root</span>) </span>{</span><br><span class="line"> <span class="keyword">const</span> ans = [];</span><br><span class="line"> recursion(root, ans);</span><br><span class="line"> <span class="keyword">return</span> ans</span><br><span class="line">};</span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">recursion</span>(<span class="params">root, ans</span>) </span>{</span><br><span class="line"> <span class="keyword">if</span> (root === <span class="literal">null</span>) <span class="keyword">return</span>;</span><br><span class="line"> ans.push(root.val);</span><br><span class="line"> recursion(root.left, ans)</span><br><span class="line"> recursion(root.right, ans)</span><br><span class="line">}</span><br></pre></td></tr></table></figure>]]></content>
<summary type="html">
<h4 id="144-二叉树的前序遍历"><a href="#144-二叉树的前序遍历" class="headerlink" title="144. 二叉树的前序遍历"></a><a href="https://leetcode-cn.com/problems/binary-
</summary>
<category term="LeetCode" scheme="http://zehai.info/categories/LeetCode/"/>
<category term="Easy" scheme="http://zehai.info/tags/Easy/"/>
</entry>
<entry>
<title>second-minimum-node-in-a-binary-tree</title>
<link href="http://zehai.info/2021/07/27/2021-07-27-second-minimum-node-in-a-binary-tree/"/>
<id>http://zehai.info/2021/07/27/2021-07-27-second-minimum-node-in-a-binary-tree/</id>
<published>2021-07-27T13:53:51.000Z</published>
<updated>2021-07-31T16:13:27.295Z</updated>
<content type="html"><![CDATA[<h1 id="Leetcode-671"><a href="#Leetcode-671" class="headerlink" title="Leetcode 671"></a>Leetcode 671</h1><h4 id="671-二叉树中第二小的节点"><a href="#671-二叉树中第二小的节点" class="headerlink" title="671. 二叉树中第二小的节点"></a><a href="https://leetcode-cn.com/problems/second-minimum-node-in-a-binary-tree/">671. 二叉树中第二小的节点</a></h4><p>难度简单198收藏分享切换为英文接收动态反馈</p><p>给定一个非空特殊的二叉树,每个节点都是正数,并且每个节点的子节点数量只能为 <code>2</code> 或 <code>0</code>。如果一个节点有两个子节点的话,那么该节点的值等于两个子节点中较小的一个。</p><p>更正式地说,<code>root.val = min(root.left.val, root.right.val)</code> 总成立。</p><p>给出这样的一个二叉树,你需要输出所有节点中的<strong>第二小的值。</strong>如果第二小的值不存在的话,输出 -1 <strong>。</strong></p><p><strong>示例 1:</strong></p><p><img src="https://assets.leetcode.com/uploads/2020/10/15/smbt1.jpg" alt="img"></p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">输入:root = [2,2,5,null,null,5,7]</span><br><span class="line">输出:5</span><br><span class="line">解释:最小的值是 2 ,第二小的值是 5 。</span><br></pre></td></tr></table></figure><p><strong>示例 2:</strong></p><p><img src="https://assets.leetcode.com/uploads/2020/10/15/smbt2.jpg" alt="img"></p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">输入:root = [2,2,2]</span><br><span class="line">输出:-1</span><br><span class="line">解释:最小的值是 2, 但是不存在第二小的值。</span><br></pre></td></tr></table></figure><p><strong>提示:</strong></p><ul><li>树中节点数目在范围 <code>[1, 25]</code> 内</li><li><code>1 <= Node.val <= 231 - 1</code></li><li>对于树中每个节点 <code>root.val == min(root.left.val, root.right.val)</code></li></ul><h1 id="Solution"><a href="#Solution" class="headerlink" title="Solution"></a>Solution</h1><p>如题意,父节点就是最小值,借鉴了答案,递归条件写错了</p><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></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * Definition for a binary tree node.</span></span><br><span class="line"><span class="comment"> * function TreeNode(val, left, right) {</span></span><br><span class="line"><span class="comment"> * this.val = (val===undefined ? 0 : val)</span></span><br><span class="line"><span class="comment"> * this.left = (left===undefined ? null : left)</span></span><br><span class="line"><span class="comment"> * this.right = (right===undefined ? null : right)</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="comment"> * <span class="doctag">@param <span class="type">{TreeNode}</span> <span class="variable">root</span></span></span></span><br><span class="line"><span class="comment"> * <span class="doctag">@return <span class="type">{number}</span></span></span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">var</span> findSecondMinimumValue = <span class="function"><span class="keyword">function</span> (<span class="params">root</span>) </span>{</span><br><span class="line"></span><br><span class="line"> <span class="keyword">let</span> ans = -<span class="number">1</span>;</span><br><span class="line"> <span class="keyword">const</span> parentValue = root.val;<span class="comment">//root value</span></span><br><span class="line"></span><br><span class="line"> <span class="keyword">const</span> dfs = <span class="function">(<span class="params">node</span>) =></span> {</span><br><span class="line"> <span class="keyword">if</span> (node === <span class="literal">null</span>) {</span><br><span class="line"> <span class="keyword">return</span>;</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">if</span> (ans !== -<span class="number">1</span> && node.val >= ans) {</span><br><span class="line"> <span class="keyword">return</span>;</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">if</span> (node.val > parentValue) {</span><br><span class="line"> ans = node.val;</span><br><span class="line"> }</span><br><span class="line"> dfs(node.left);</span><br><span class="line"> dfs(node.right);</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> dfs(root);</span><br><span class="line"> <span class="keyword">return</span> ans;</span><br><span class="line">};</span><br></pre></td></tr></table></figure>]]></content>
<summary type="html">
<h1 id="Leetcode-671"><a href="#Leetcode-671" class="headerlink" title="Leetcode 671"></a>Leetcode 671</h1><h4 id="671-二叉树中第二小的节点"><a href="
</summary>
<category term="LeetCode" scheme="http://zehai.info/categories/LeetCode/"/>
<category term="Easy" scheme="http://zehai.info/tags/Easy/"/>
</entry>
<entry>
<title>1109. 航班预订统计</title>
<link href="http://zehai.info/2021/07/26/2021-07-26-%E8%88%AA%E7%8F%AD%E9%A2%84%E8%AE%A2%E7%BB%9F%E8%AE%A1/"/>
<id>http://zehai.info/2021/07/26/2021-07-26-航班预订统计/</id>
<published>2021-07-26T08:59:16.000Z</published>
<updated>2021-07-27T14:51:25.175Z</updated>
<content type="html"><![CDATA[<p>#Leetcode-<a href="https://leetcode-cn.com/problems/corporate-flight-bookings/">1109. 航班预订统计</a></p><p>难度中等157收藏分享切换为英文接收动态反馈</p><p>这里有 <code>n</code> 个航班,它们分别从 <code>1</code> 到 <code>n</code> 进行编号。</p><p>有一份航班预订表 <code>bookings</code> ,表中第 <code>i</code> 条预订记录 <code>bookings[i] = [firsti, lasti, seatsi]</code> 意味着在从 <code>firsti</code> 到 <code>lasti</code> (<strong>包含</strong> <code>firsti</code> 和 <code>lasti</code> )的 <strong>每个航班</strong> 上预订了 <code>seatsi</code> 个座位。</p><p>请你返回一个长度为 <code>n</code> 的数组 <code>answer</code>,其中 <code>answer[i]</code> 是航班 <code>i</code> 上预订的座位总数。</p><p><strong>示例 1:</strong></p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">输入:bookings = [[1,2,10],[2,3,20],[2,5,25]], n = 5</span><br><span class="line">输出:[10,55,45,25,25]</span><br><span class="line">解释:</span><br><span class="line">航班编号 1 2 3 4 5</span><br><span class="line">预订记录 1 : 10 10</span><br><span class="line">预订记录 2 : 20 20</span><br><span class="line">预订记录 3 : 25 25 25 25</span><br><span class="line">总座位数: 10 55 45 25 25</span><br><span class="line">因此,answer = [10,55,45,25,25]</span><br></pre></td></tr></table></figure><p><strong>示例 2:</strong></p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">输入:bookings = [[1,2,10],[2,2,15]], n = 2</span><br><span class="line">输出:[10,25]</span><br><span class="line">解释:</span><br><span class="line">航班编号 1 2</span><br><span class="line">预订记录 1 : 10 10</span><br><span class="line">预订记录 2 : 15</span><br><span class="line">总座位数: 10 25</span><br><span class="line">因此,answer = [10,25]</span><br></pre></td></tr></table></figure><p><strong>提示:</strong></p><ul><li><code>1 <= n <= 2 * 104</code></li><li><code>1 <= bookings.length <= 2 * 104</code></li><li><code>bookings[i].length == 3</code></li><li><code>1 <= firsti <= lasti <= n</code></li><li><code>1 <= seatsi <= 104</code></li></ul><h1 id="Solution"><a href="#Solution" class="headerlink" title="Solution"></a>Solution</h1><p>题目到是很简单,主要做的就是一维数组做个累加,时间复杂度O(N^2)</p><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> corpFlightBookings = <span class="function"><span class="keyword">function</span> (<span class="params">bookings, n</span>) </span>{</span><br><span class="line"> <span class="keyword">const</span> answer = [];</span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">let</span> i = <span class="number">0</span>; i < n; i++)answer.push(<span class="number">0</span>);</span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">let</span> item <span class="keyword">of</span> bookings) {</span><br><span class="line"> <span class="keyword">const</span> [first, last, seats] = item;</span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">let</span> j = first; j <= last; j++) {</span><br><span class="line"> answer[j-<span class="number">1</span>] += seats;</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> answer;</span><br><span class="line"></span><br><span class="line">};</span><br><span class="line"><span class="built_in">console</span>.log(corpFlightBookings([[<span class="number">1</span>, <span class="number">2</span>, <span class="number">10</span>], [<span class="number">2</span>, <span class="number">3</span>, <span class="number">20</span>], [<span class="number">2</span>, <span class="number">5</span>, <span class="number">25</span>]], <span class="number">5</span>))</span><br></pre></td></tr></table></figure><p>但是时间只超过了50%,就考虑问题</p><p>问题应该在O^2的复杂度上</p><p>后来想遍历的时候</p><ul><li>Array(n).fill(0) 代码更优美</li><li>把<strong>增量</strong>加在数组里,最后走for循环跑一次就可以降一层for循环</li></ul><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> [first, last, seats] = item;</span><br><span class="line">answer[first - <span class="number">1</span>] += seats;</span><br><span class="line"><span class="keyword">if</span> (last < n) answer[last] -= seats;</span><br></pre></td></tr></table></figure>]]></content>
<summary type="html">
<p>#Leetcode-<a href="https://leetcode-cn.com/problems/corporate-flight-bookings/">1109. 航班预订统计</a></p>
<p>难度中等157收藏分享切换为英文接收动态反馈</p>
<p>这里有
</summary>
<category term="LeetCode" scheme="http://zehai.info/categories/LeetCode/"/>
<category term="Medium" scheme="http://zehai.info/tags/Medium/"/>
</entry>
<entry>
<title>Leetcode剑指offer53</title>
<link href="http://zehai.info/2021/07/16/2021-07-16-Leetcode%E5%89%91%E6%8C%8753/"/>
<id>http://zehai.info/2021/07/16/2021-07-16-Leetcode剑指53/</id>
<published>2021-07-16T15:50:55.000Z</published>
<updated>2021-07-31T16:13:38.672Z</updated>
<content type="html"><![CDATA[<h1 id="LeetCode:剑指-Offer-53"><a href="#LeetCode:剑指-Offer-53" class="headerlink" title="LeetCode:剑指 Offer 53"></a>LeetCode:<a href="https://leetcode-cn.com/problems/zai-pai-xu-shu-zu-zhong-cha-zhao-shu-zi-lcof/">剑指 Offer 53</a></h1><p>打开网页,突然看到日推是easy难度,本来想就几行代码的事情,弄完了就休息了,提交后–傻了眼–:cry:,居然只打败了6.27%的人,草率了</p><p>题目:</p><blockquote><h4 id="剑指-Offer-53-I-在排序数组中查找数字-I"><a href="#剑指-Offer-53-I-在排序数组中查找数字-I" class="headerlink" title="剑指 Offer 53 - I. 在排序数组中查找数字 I"></a><a href="https://leetcode-cn.com/problems/zai-pai-xu-shu-zu-zhong-cha-zhao-shu-zi-lcof/">剑指 Offer 53 - I. 在排序数组中查找数字 I</a></h4><p>统计一个数字在排序数组中出现的次数。</p><p>示例 1:</p><p>输入: nums = [5,7,7,8,8,10], target = 8<br>输出: 2<br>示例 2:</p><p>输入: nums = [5,7,7,8,8,10], target = 6<br>输出: 0</p><p>限制:</p><p>0 <= 数组长度 <= 50000</p></blockquote><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// first commit</span></span><br><span class="line"><span class="comment">// 执行用时:2 ms, 在所有 Java 提交中击败了6.27%的用户</span></span><br><span class="line"><span class="comment">// 内存消耗:40.8 MB, 在所有 Java 提交中击败了98.84%的用户</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> </span>{</span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">search</span><span class="params">(<span class="keyword">int</span>[] nums, <span class="keyword">int</span> target)</span> </span>{</span><br><span class="line"> <span class="keyword">if</span>(nums==<span class="keyword">null</span>||nums.length<<span class="number">0</span>){</span><br><span class="line"> <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">int</span> count = <span class="number">0</span>;</span><br><span class="line"> <span class="keyword">for</span> (Integer num : nums) {</span><br><span class="line"> <span class="keyword">if</span>(num>target)<span class="keyword">break</span>;</span><br><span class="line"> <span class="keyword">if</span> (target == num)</span><br><span class="line"> count++;</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> count;</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>找到了耗时1ms的答案一看,是foreach替换成了for循环 果然下标访问更快一些</p><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></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> </span>{</span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">search</span><span class="params">(<span class="keyword">int</span>[] nums, <span class="keyword">int</span> target)</span> </span>{</span><br><span class="line"> <span class="comment">// 就是left right 更快的定位,总体复杂度差不多,不过</span></span><br><span class="line"> <span class="keyword">int</span> left = getRight(nums,target-<span class="number">1</span>);</span><br><span class="line"> <span class="keyword">int</span> right = getRight(nums,target);</span><br><span class="line"> <span class="keyword">return</span> right-left;</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">getRight</span><span class="params">(<span class="keyword">int</span>[] nums ,<span class="keyword">int</span> target)</span></span>{</span><br><span class="line"> <span class="keyword">int</span> left = <span class="number">0</span>;</span><br><span class="line"> <span class="keyword">int</span> right = nums.length-<span class="number">1</span>;</span><br><span class="line"></span><br><span class="line"> <span class="keyword">while</span>(left<=right){</span><br><span class="line"> <span class="keyword">int</span> mid = (left+right)/<span class="number">2</span>;</span><br><span class="line"> <span class="keyword">if</span>(nums[mid]>target){</span><br><span class="line"> right = mid-<span class="number">1</span>;</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">else</span> <span class="keyword">if</span>(nums[mid]<=target){</span><br><span class="line"> left = mid + <span class="number">1</span>;</span><br><span class="line"> }</span><br><span class="line"> } </span><br><span class="line"> <span class="keyword">return</span> left;</span><br><span class="line"> }</span><br><span class="line"> </span><br><span class="line">}</span><br></pre></td></tr></table></figure>]]></content>
<summary type="html">
<h1 id="LeetCode:剑指-Offer-53"><a href="#LeetCode:剑指-Offer-53" class="headerlink" title="LeetCode:剑指 Offer 53"></a>LeetCode:<a href="https://
</summary>
<category term="LeetCode" scheme="http://zehai.info/categories/LeetCode/"/>
<category term="Easy" scheme="http://zehai.info/tags/Easy/"/>
</entry>
<entry>
<title>prototype</title>
<link href="http://zehai.info/2021/03/07/2021-03-07-prototype/"/>
<id>http://zehai.info/2021/03/07/2021-03-07-prototype/</id>
<published>2021-03-07T06:55:02.000Z</published>
<updated>2021-07-27T07:09:41.900Z</updated>
<content type="html"><![CDATA[<h1 id="Prototype"><a href="#Prototype" class="headerlink" title="Prototype"></a>Prototype</h1><p>含义:proto(/ˈproʊtə/)原始, 原型, 原始的</p><p>目的:补充JavaScript对于对象的支持,通过protype来实现class中的method</p><p>过程:熟悉实例对象<--->构造函数<--->原型 三者之间的关系</p><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></pre></td><td class="code"><pre><span class="line"><span class="comment">//构造函数 创建对象</span></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">Dog</span>(<span class="params"></span>) </span>{</span><br><span class="line"></span><br><span class="line">}</span><br><span class="line"><span class="keyword">var</span> dog = <span class="keyword">new</span> Dog();<span class="comment">//Person 为构造函数,person为实例对象</span></span><br><span class="line">dog.name = <span class="string">'柯基'</span>;</span><br><span class="line"><span class="built_in">console</span>.log(dog.name) <span class="comment">// 柯基</span></span><br></pre></td></tr></table></figure><ul><li>构造函数通过prototype访问原型(一个类的属性,对象都可以访问)</li><li>实例对象通过 <code>_proto_</code> 访问原型 === 构造函数通过<code>prototype</code>访问原型(原型也有<code>_proto_</code>)</li><li>实例原型通过<code>constructor</code>访问构造函数(Dog=== Dog.prototype.constructor)</li></ul><p><img src="../img/image-20210224154735705.png" alt="image-20210224154735705"></p><ul><li>原型遵循向上原则,即找不到就不断向上(prototype)查询</li><li>原型因为不停延长形成链,称作原型链,但是 <code>Object.prototype.__proto__</code> 的值为 null 跟 Object.prototype 没有原型</li><li>原型链大概实现了类(Class)以及继承(Extend)的问题,但它并不是复制,是建立一种关联,通过<code>prototype</code>/<code>_proto_</code> 来访问其他对象的属性和方法,属于委托/借用</li></ul><h1 id="Extend"><a href="#Extend" class="headerlink" title="Extend"></a>Extend</h1><p>一共分为6种</p><ul><li>原型链继承</li><li>借用构造函数(经典继承)</li><li>组合继承</li><li>原型式继承</li><li>寄生式继承</li><li>寄生组合式继承</li></ul><h2 id="原型链继承"><a href="#原型链继承" class="headerlink" title="原型链继承"></a>原型链继承</h2><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></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">Parent</span> (<span class="params"></span>) </span>{</span><br><span class="line"> <span class="built_in">this</span>.names = [<span class="string">'kevin'</span>, <span class="string">'daisy'</span>];</span><br><span class="line">}</span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">Child</span> (<span class="params"></span>) </span>{}</span><br><span class="line">Child.prototype = <span class="keyword">new</span> Parent();</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> child1 = <span class="keyword">new</span> Child();</span><br><span class="line"></span><br><span class="line">child1.names.push(<span class="string">'yayu'</span>);</span><br><span class="line"></span><br><span class="line"><span class="built_in">console</span>.log(child1.names); <span class="comment">// ["kevin", "daisy", "yayu"]</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> child2 = <span class="keyword">new</span> Child();</span><br><span class="line"></span><br><span class="line"><span class="built_in">console</span>.log(child2.names); <span class="comment">// ["kevin", "daisy", "yayu"]</span></span><br></pre></td></tr></table></figure><p>问题:</p><ul><li>属性被所有child共享</li><li>创建child实例时,不能向parent传参</li></ul><h2 id="借用构造函数"><a href="#借用构造函数" class="headerlink" title="借用构造函数"></a>借用构造函数</h2><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></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">Parent</span> (<span class="params">name</span>) </span>{</span><br><span class="line"> <span class="built_in">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">function</span> <span class="title">Child</span> (<span class="params">name</span>) </span>{</span><br><span class="line"> Parent.call(<span class="built_in">this</span>, name);</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> child1 = <span class="keyword">new</span> Child(<span class="string">'kevin'</span>);</span><br><span class="line"></span><br><span class="line"><span class="built_in">console</span>.log(child1.name); <span class="comment">// kevin</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> child2 = <span class="keyword">new</span> Child(<span class="string">'daisy'</span>);</span><br><span class="line"></span><br><span class="line"><span class="built_in">console</span>.log(child2.name); <span class="comment">// daisy</span></span><br></pre></td></tr></table></figure><p>有点:</p><ul><li>避免引用类型的属性被所有实例共享</li><li>可以在Child中间parent传参</li></ul><p>缺点:</p><ul><li>方法在构造函数中定义,每次创建势力都会创建一遍方法</li></ul><h2 id="组合继承"><a href="#组合继承" class="headerlink" title="组合继承"></a>组合继承</h2><p>以上两种方法的组合,为最常用的继承方式</p><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></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">Parent</span> (<span class="params">name</span>) </span>{</span><br><span class="line"> <span class="built_in">this</span>.name = name;</span><br><span class="line"> <span class="built_in">this</span>.colors = [<span class="string">'red'</span>, <span class="string">'blue'</span>, <span class="string">'green'</span>];</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">Parent.prototype.getName = <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>{</span><br><span class="line"> <span class="built_in">console</span>.log(<span class="built_in">this</span>.name)</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">Child</span> (<span class="params">name, age</span>) </span>{</span><br><span class="line"> Parent.call(<span class="built_in">this</span>, name);</span><br><span class="line"> <span class="built_in">this</span>.age = age;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">Child.prototype = <span class="keyword">new</span> Parent();</span><br><span class="line">Child.prototype.constructor = Child;</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> child1 = <span class="keyword">new</span> Child(<span class="string">'kevin'</span>, <span class="string">'18'</span>);</span><br><span class="line"></span><br><span class="line">child1.colors.push(<span class="string">'black'</span>);</span><br><span class="line"><span class="built_in">console</span>.log(child1.name); <span class="comment">// kevin</span></span><br><span class="line"><span class="built_in">console</span>.log(child1.age); <span class="comment">// 18</span></span><br><span class="line"><span class="built_in">console</span>.log(child1.colors); <span class="comment">// ["red", "blue", "green", "black"]</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> child2 = <span class="keyword">new</span> Child(<span class="string">'daisy'</span>, <span class="string">'20'</span>);</span><br><span class="line"></span><br><span class="line"><span class="built_in">console</span>.log(child2.name); <span class="comment">// daisy</span></span><br><span class="line"><span class="built_in">console</span>.log(child2.age); <span class="comment">// 20</span></span><br><span class="line"><span class="built_in">console</span>.log(child2.colors); <span class="comment">// ["red", "blue", "green"]</span></span><br></pre></td></tr></table></figure>]]></content>
<summary type="html">
<h1 id="Prototype"><a href="#Prototype" class="headerlink" title="Prototype"></a>Prototype</h1><p>含义:proto(/ˈproʊtə/)原始, 原型, 原始的</p>
<p>目的:补
</summary>
<category term="JavaScript" scheme="http://zehai.info/categories/JavaScript/"/>
<category term="prototype" scheme="http://zehai.info/tags/prototype/"/>
</entry>
<entry>
<title>dockerMysql</title>
<link href="http://zehai.info/2021/02/10/2021-02-10-dockerMysql/"/>
<id>http://zehai.info/2021/02/10/2021-02-10-dockerMysql/</id>
<published>2021-02-10T06:54:33.000Z</published>
<updated>2021-07-27T07:09:41.899Z</updated>
<content type="html"><![CDATA[<blockquote><p>link:<a href="https://hub.docker.com/_/mysql?tab=description&page=1&ordering=last_updated">mysql-docker</a></p></blockquote><h1 id="支持标签"><a href="#支持标签" class="headerlink" title="支持标签"></a>支持标签</h1><ul><li><a href="https://github.com/docker-library/mysql/blob/2966bfbd71cf370770cd880aa45f3c8f155d0aae/8.0/Dockerfile.debian"><code>8.0.23</code>, <code>8.0</code>, <code>8</code>, <code>latest</code></a></li><li><a href="https://github.com/docker-library/mysql/blob/2966bfbd71cf370770cd880aa45f3c8f155d0aae/5.7/Dockerfile.debian"><code>5.7.33</code>, <code>5.7</code>, <code>5</code></a></li><li><a href="https://github.com/docker-library/mysql/blob/2966bfbd71cf370770cd880aa45f3c8f155d0aae/5.6/Dockerfile.debian"><code>5.6.51</code>, <code>5.6</code></a></li></ul><h1 id="快速手册"><a href="#快速手册" class="headerlink" title="快速手册"></a>快速手册</h1><ul><li><strong>issues</strong>: <a href="https://github.com/docker-library/mysql/issues">https://github.com/docker-library/mysql/issues</a></li><li><strong>支持平台</strong>: (<a href="https://github.com/docker-library/official-images#architectures-other-than-amd64">more info</a>) <a href="https://hub.docker.com/r/amd64/mysql/"><code>amd64</code></a></li><li><strong>发布image 详情</strong>: <a href="https://github.com/docker-library/repo-info/blob/master/repos/mysql">repo-info repo’s <code>repos/mysql/</code> directory</a> (<a href="https://github.com/docker-library/repo-info/commits/master/repos/mysql">history</a>) (image metadata, transfer size, etc)</li><li><strong>Image 更新</strong>: <a href="https://github.com/docker-library/official-images/issues?q=label%3Alibrary%2Fmysql">official-images repo’s <code>library/mysql</code> label</a><br><a href="https://github.com/docker-library/official-images/blob/master/library/mysql">official-images repo’s <code>library/mysql</code> file</a> (<a href="https://github.com/docker-library/official-images/commits/master/library/mysql">history</a>)</li><li><strong>描述来源</strong>: <a href="https://github.com/docker-library/docs/tree/master/mysql">docs repo’s <code>mysql/</code> directory</a> (<a href="https://github.com/docker-library/docs/commits/master/mysql">history</a>)</li></ul><h1 id="什么是-MySQL"><a href="#什么是-MySQL" class="headerlink" title="什么是 MySQL?"></a>什么是 MySQL?</h1><p>MySQL 是最受欢迎的,开源的数据库. 凭借被验证过的性能表现,可靠性,易用性, MySQL已经成为基于web的应用程序的 主要选择,包括完整得个人项目和网站项目(电子上午,信息服务),也包括优秀的Facebook Facebook, Twitter, YouTube, Yahoo! </p><h1 id="如何使用mysql-image"><a href="#如何使用mysql-image" class="headerlink" title="如何使用mysql image"></a>如何使用mysql image</h1><h2 id="创建-mysql-服务实例"><a href="#创建-mysql-服务实例" class="headerlink" title="创建 mysql 服务实例"></a>创建 <code>mysql</code> 服务实例</h2><p>启动 MySQL 比较简单:</p><figure class="highlight sh"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ docker run --name some-mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:tag</span><br></pre></td></tr></table></figure><ul><li>some-mysql 容器名称</li><li>my-secret-pw 是root账户的密码</li><li>tag 是mysql的版本</li></ul><h2 id="通过mysql命令行连接mysql"><a href="#通过mysql命令行连接mysql" class="headerlink" title="通过mysql命令行连接mysql"></a>通过mysql命令行连接mysql</h2><p>以下命令可以启动mysql容器并运行终端,执行SQL语句</p><figure class="highlight sh"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ docker run -it --network some-network --rm mysql mysql -hsome-mysql -uexample-user -p</span><br></pre></td></tr></table></figure><ul><li>some-mysql 容器名称</li><li>some-network 连接网络(方便容器间访问)</li></ul><p>也可以直接运行客户端,访问远程数据库</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ docker run -it --rm mysql mysql -hsome.mysql.host -usome-mysql-user -p</span><br></pre></td></tr></table></figure><p>更多命令请访问 <a href="http://dev.mysql.com/doc/en/mysql.html">MySQL documentation</a></p><h2 id="使用docker-stack-或docker-compose部署"><a href="#使用docker-stack-或docker-compose部署" class="headerlink" title="使用docker stack 或docker-compose部署"></a>使用docker stack 或docker-compose部署</h2><p>示例<code>stack.yml</code></p><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># Use root/example as user/password credentials</span></span><br><span class="line"><span class="attr">version:</span> <span class="string">'3.1'</span></span><br><span class="line"><span class="attr">services:</span></span><br><span class="line"></span><br><span class="line"> <span class="attr">db:</span></span><br><span class="line"> <span class="attr">image:</span> <span class="string">mysql</span></span><br><span class="line"> <span class="attr">command:</span> <span class="string">--default-authentication-plugin=mysql_native_password</span></span><br><span class="line"> <span class="attr">restart:</span> <span class="string">always</span></span><br><span class="line"> <span class="attr">environment:</span></span><br><span class="line"> <span class="attr">MYSQL_ROOT_PASSWORD:</span> <span class="string">example</span></span><br><span class="line"></span><br><span class="line"> <span class="attr">adminer:</span></span><br><span class="line"> <span class="attr">image:</span> <span class="string">adminer</span></span><br><span class="line"> <span class="attr">restart:</span> <span class="string">always</span></span><br><span class="line"> <span class="attr">ports:</span></span><br><span class="line"> <span class="bullet">-</span> <span class="number">8080</span><span class="string">:8080</span></span><br></pre></td></tr></table></figure><ul><li><code>docker stack deploy -c stack.yml mysql</code> </li><li><code>docker-compose -f stack.yml up</code></li></ul><p>启动后, 访问 <code>http://swarm-ip:8080</code>, <code>http://localhost:8080</code>, or <code>http://host-ip:8080</code> </p><h2 id="shell访问查看-MySQL-日志"><a href="#shell访问查看-MySQL-日志" class="headerlink" title="shell访问查看 MySQL 日志"></a>shell访问查看 MySQL 日志</h2><p>使用 <code>docker exec</code> 可以让你在容器内执行命令,命令如下 </p><figure class="highlight sh"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ docker <span class="built_in">exec</span> -it some-mysql bash</span><br></pre></td></tr></table></figure><p>容器日志:</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ docker logs some-mysql</span><br></pre></td></tr></table></figure><h2 id="自定义-MySQL-配置文件"><a href="#自定义-MySQL-配置文件" class="headerlink" title="自定义 MySQL 配置文件"></a>自定义 MySQL 配置文件</h2><p>mysql默认配置文件在 <code>/etc/mysql/my.cnf</code>, 也可能指定了额外文件如: <code>/etc/mysql/conf.d</code> or <code>/etc/mysql/mysql.conf.d</code>. 请检查mysqlimage本身的相关文件和目录以了解更多信息</p><p>如果 <code>/my/custom/config-file.cnf</code> 是你自定义的文件未知和名字, 你可以这样启动你的<code>mysql</code> 容器 </p><figure class="highlight sh"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ docker run --name some-mysql -v /my/custom:/etc/mysql/conf.d -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:tag</span><br></pre></td></tr></table></figure><p>你会启动一个用你自定义配置 <code>/etc/mysql/my.cnf</code> and <code>/etc/mysql/conf.d/config-file.cnf</code>, 的mysql容器</p><h3 id="不使用cnf-文件配置"><a href="#不使用cnf-文件配置" class="headerlink" title="不使用cnf 文件配置"></a>不使用<code>cnf</code> 文件配置</h3><p>很多配置都可以传给 <code>mysqld</code>. 使你自定义容器而不需要 <code>cnf</code> 文件. 如当你想改变默认编码和排序规则,使用 UTF-8 (<code>utf8mb4</code>) 只需要执行如下命令:</p><figure class="highlight sh"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ docker run --name some-mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:tag --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci</span><br></pre></td></tr></table></figure><p>如果你想看到所有的配置项,只需要执行:</p><figure class="highlight sh"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ docker run -it --rm mysql:tag --verbose --<span class="built_in">help</span></span><br></pre></td></tr></table></figure><h2 id="环境变量"><a href="#环境变量" class="headerlink" title="环境变量"></a>环境变量</h2><p>docker run 时,可以一个或多个参数进行配置. 不过需要注意,如果使用已经包含数据库的数据目录启动容器,以下变量不会产生影响,在启动时,任何预先存在的数据库都保持不变,任何之前存在的数据库在容器启动时将保持不变.</p><h3 id="MYSQL-ROOT-PASSWORD"><a href="#MYSQL-ROOT-PASSWORD" class="headerlink" title="MYSQL_ROOT_PASSWORD"></a><code>MYSQL_ROOT_PASSWORD</code></h3><p>该变量是必须的,是root账户的密码.</p><h3 id="MYSQL-DATABASE"><a href="#MYSQL-DATABASE" class="headerlink" title="MYSQL_DATABASE"></a><code>MYSQL_DATABASE</code></h3><p>该变量可选,允许在启动时,指定数据库的名称. 如果提供了用户名/密码,用户会被赋予超级权限.</p><h3 id="MYSQL-USER-MYSQL-PASSWORD"><a href="#MYSQL-USER-MYSQL-PASSWORD" class="headerlink" title="MYSQL_USER, MYSQL_PASSWORD"></a><code>MYSQL_USER</code>, <code>MYSQL_PASSWORD</code></h3><p>可选变量,用于创建新用户和密码,用户将获得超级管理员权限,两个参数都是必须的.</p><p>注意:不需要使用该机制来创建root超级用户,默认使用 <code>MYSQL_ROOT_PASSWORD</code> 来创建密码</p><h3 id="MYSQL-ALLOW-EMPTY-PASSWORD"><a href="#MYSQL-ALLOW-EMPTY-PASSWORD" class="headerlink" title="MYSQL_ALLOW_EMPTY_PASSWORD"></a><code>MYSQL_ALLOW_EMPTY_PASSWORD</code></h3><p>可选变量,设置非空值(如yes),允许root用户无密码启动容器. <em>注意</em>: 除非你知道你在做什么,否则不建议设置为 <code>yes</code> ,因为这将使mysql实例完全不受保护,允许所有人获得完全的超级用户权限.</p><h3 id="MYSQL-RANDOM-ROOT-PASSWORD"><a href="#MYSQL-RANDOM-ROOT-PASSWORD" class="headerlink" title="MYSQL_RANDOM_ROOT_PASSWORD"></a><code>MYSQL_RANDOM_ROOT_PASSWORD</code></h3><p>可选变量,设置非空值(如yes),使用pwgen , 为root用户随机生成密码 .密码将被打印.</p><h3 id="MYSQL-ONETIME-PASSWORD"><a href="#MYSQL-ONETIME-PASSWORD" class="headerlink" title="MYSQL_ONETIME_PASSWORD"></a><code>MYSQL_ONETIME_PASSWORD</code></h3><p>设置用户 初始化完成后过期,在首次登录时候强制修改密码. 任何非空值将激活这个配置,注意:仅支持5.6+版本,以下版本会报错</p><h3 id="MYSQL-INITDB-SKIP-TZINFO"><a href="#MYSQL-INITDB-SKIP-TZINFO" class="headerlink" title="MYSQL_INITDB_SKIP_TZINFO"></a><code>MYSQL_INITDB_SKIP_TZINFO</code></h3><p>默认,entrypoint脚本自动加载<code>CONVERT_TZ()</code>函数需要的时区数据,如果不需要,任何非空值都将禁用时区加载</p><h2 id="Docker-Secrets"><a href="#Docker-Secrets" class="headerlink" title="Docker Secrets"></a>Docker Secrets</h2><p>通过环境变量传递敏感信息,还有另一种方法, <code>_FILE</code> 可以附加到前面列的环境变量,使得可以从文件中的变量初始化脚本,特别是,这可以用于存在<code>/run/secrets/<secret_name></code>中的docker screts从加载密码, 如 :</p><figure class="highlight sh"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ docker run --name some-mysql -e MYSQL_ROOT_PASSWORD_FILE=/run/secrets/mysql-root -d mysql:tag</span><br></pre></td></tr></table></figure><p>目前仅支持: <code>MYSQL_ROOT_PASSWORD</code>, <code>MYSQL_ROOT_HOST</code>, <code>MYSQL_DATABASE</code>, <code>MYSQL_USER</code>, 和<code>MYSQL_PASSWORD</code>.</p><h1 id="初始化新实例"><a href="#初始化新实例" class="headerlink" title="初始化新实例"></a>初始化新实例</h1><p>刚启动容器,指定名字的新数据库会被创建,并且根据提供的变量初始化. 此外,它将执行扩展名为<code>.sh</code>, <code>.sql</code> 和 <code>.sql.gz</code> ( <code>/docker-entrypoint-initdb.d</code>文件夹中).文件将按照字幕顺序执行. 你可以轻松使用dump备份填充,. 默认情况下,sql文件将被保存在 <code>MYSQL_DATABASE</code> 指定的数据库中.</p><h1 id="Caveats-告诫"><a href="#Caveats-告诫" class="headerlink" title="Caveats//告诫"></a>Caveats//告诫</h1><h2 id="数据存储在哪里"><a href="#数据存储在哪里" class="headerlink" title="数据存储在哪里"></a>数据存储在哪里</h2><p>重要内容:有几种方式在容器运行时存储数据. 我们推荐 <code>mysql</code> 用户熟悉可用的选项,包括:</p><ul><li>让docker使用自己的内部volume 将数据库文件写入主机系统上的磁盘(而不在容器内)从而管理数据库数据的存储。这也是默认的配置,也非常简单透明。缺点是相比直接部署<strong>找文件困难</strong>.</li><li>在主机上创建一个数据目录,并将其装载到容器内部的一个目录中,使得数据库文件放置在主机已知的位置上,更轻松访问文件,缺点是需要确保目录存在,且有权限和安全机制</li></ul><p>Docker 文档是理解不同存储选项和变量的最好起步,并且有很多博客论坛讨论并提供建议,我们将简单展示基本过程:</p><ol><li><p>创建文件夹在主机如 <code>/my/own/datadir</code>.</p></li><li><p>启动 <code>mysql</code> 容器</p><figure class="highlight sh"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ docker run --name some-mysql -v /my/own/datadir:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:tag</span><br></pre></td></tr></table></figure><p><code>-v /my/own/datadir:/var/lib/mysql</code> 将 <code>/my/own/datadir</code> 目录从主机装入容器中作为 <code>/var/lib/mysql</code> 默认不传-v情况下,mysql将写入其他数据文件.</p></li></ol><h2 id="直到初始化完成才有连接"><a href="#直到初始化完成才有连接" class="headerlink" title="直到初始化完成才有连接"></a>直到初始化完成才有连接</h2><p>如果容器启动没有初始化数据库,则创建默认数据库. 初始化完成之前不会接受传入连接. 在使用自动化工具如 <code>docker-compose</code>同时启动多个容器时,这可能会导致问题.</p><p>如果应用尝试连接不提供服务的mysql,需要继续重试等待连接成功. 官方示例, 详见 <a href="https://github.com/docker-library/wordpress/blob/1b48b4bccd7adb0f7ea1431c7b470a40e186f3da/docker-entrypoint.sh#L195-L235">WordPress</a> or <a href="https://github.com/docker-library/docs/blob/9660a0cccb87d8db842f33bc0578d769caaf3ba9/bonita/stack.yml#L28-L44">Bonita</a>.</p><h2 id="现用数据库使用"><a href="#现用数据库使用" class="headerlink" title="现用数据库使用"></a>现用数据库使用</h2><p>如果在一个有mysql数据目录的volume启动mqsql,应省略 <code>$MYSQL_ROOT_PASSWORD</code>命令; 及时填写也不会生效, 且不会更改预先存在的数据库.</p><h2 id="以任意用户身份运行"><a href="#以任意用户身份运行" class="headerlink" title="以任意用户身份运行"></a>以任意用户身份运行</h2><p>如果你正确设置了目录权限,或者你需要使用特定的uid/gid运行mysqld,则可以通过 <code>--user</code> 设为任意值(root/0外)来实现所需的权限/配置:</p><figure class="highlight sh"><table><tr><td class="gutter"><pre><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">$ mkdir data</span><br><span class="line">$ ls -lnd data</span><br><span class="line">drwxr-xr-x 2 1000 1000 4096 Aug 27 15:54 data</span><br><span class="line">$ docker run -v <span class="string">"<span class="variable">$PWD</span>/data"</span>:/var/lib/mysql --user 1000:1000 --name some-mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:tag</span><br></pre></td></tr></table></figure><h2 id="创建备份"><a href="#创建备份" class="headerlink" title="创建备份"></a>创建备份</h2><p>大多数工具都会正常工作,尽管他们的使用在某些情况下可能有点复杂, 以确保可以访问mysqld服务器,确保这一点的一个简单方法是使用 <code>docker exec</code> 并从同一容器运行工具,如:</p><figure class="highlight sh"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ docker <span class="built_in">exec</span> some-mysql sh -c <span class="string">'exec mysqldump --all-databases -uroot -p"$MYSQL_ROOT_PASSWORD"'</span> > /some/path/on/your/host/all-databases.sql</span><br></pre></td></tr></table></figure><h2 id="从备份还原数据"><a href="#从备份还原数据" class="headerlink" title="从备份还原数据"></a>从备份还原数据</h2><figure class="highlight sh"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ docker <span class="built_in">exec</span> -i some-mysql sh -c <span class="string">'exec mysql -uroot -p"$MYSQL_ROOT_PASSWORD"'</span> < /some/path/on/your/host/all-databases.sqlwith any relevant licenses <span class="keyword">for</span> all software contained within.1</span><br></pre></td></tr></table></figure>]]></content>
<summary type="html">
<blockquote>
<p>link:<a href="https://hub.docker.com/_/mysql?tab=description&amp;page=1&amp;ordering=last_updated">mysql-docker</a></p>
</bl
</summary>
<category term="docker" scheme="http://zehai.info/categories/docker/"/>
<category term="mysql" scheme="http://zehai.info/tags/mysql/"/>
</entry>
<entry>
<title>currying</title>
<link href="http://zehai.info/2021/01/15/2021-01-15-currying/"/>
<id>http://zehai.info/2021/01/15/2021-01-15-currying/</id>
<published>2021-01-15T06:54:00.000Z</published>
<updated>2021-07-27T07:09:41.899Z</updated>
<content type="html"><![CDATA[<p>柯里化是一种将使用多个参数的一个函数转换成一系列使用一个参数的函数的技术</p><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></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">add</span>(<span class="params">a, b</span>) </span>{</span><br><span class="line"> <span class="keyword">return</span> a + b;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="comment">// 执行 add 函数,一次传入两个参数即可</span></span><br><span class="line">add(<span class="number">1</span>, <span class="number">2</span>) <span class="comment">// 3</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 假设有一个 curry 函数可以做到柯里化</span></span><br><span class="line"><span class="keyword">var</span> addCurry = curry(add);</span><br><span class="line">addCurry(<span class="number">1</span>)(<span class="number">2</span>) <span class="comment">// 3</span></span><br></pre></td></tr></table></figure>]]></content>
<summary type="html">
<p>柯里化是一种将使用多个参数的一个函数转换成一系列使用一个参数的函数的技术</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><
</summary>
<category term="JavaScript" scheme="http://zehai.info/categories/JavaScript/"/>
<category term="currying" scheme="http://zehai.info/tags/currying/"/>
</entry>
<entry>
<title>closure</title>
<link href="http://zehai.info/2021/01/08/2021-01-08-closure/"/>
<id>http://zehai.info/2021/01/08/2021-01-08-closure/</id>
<published>2021-01-08T06:53:22.000Z</published>
<updated>2021-07-27T07:09:41.899Z</updated>
<content type="html"><![CDATA[<p>前置知识:JavaScript是静态作用域</p><p>闭包:访问自由变量的函数</p><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> a = <span class="number">1</span>;<span class="comment">//既不是foo的局部变量,也不是foo函数的参数,a为自由变量</span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">foo</span>(<span class="params"></span>) </span>{</span><br><span class="line"> <span class="built_in">console</span>.log(a);</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">foo();<span class="comment">//1</span></span><br></pre></td></tr></table></figure><p>即使上下文被销毁,它仍然存在,因为在<strong>作用域链</strong>上被引用了,是js的一个特性,目前如PHP,Java不会原生支持</p><p><strong>面试题</strong></p><p>常见的新手面试题,我遇到过好几次(作用域+闭包考点)</p><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> data = [];</span><br><span class="line"></span><br><span class="line"><span class="keyword">for</span> (<span class="keyword">var</span> i = <span class="number">0</span>; i < <span class="number">3</span>; i++) {</span><br><span class="line"> data[i] = <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>{</span><br><span class="line"> <span class="built_in">console</span>.log(i);</span><br><span class="line"> };</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">data[<span class="number">0</span>]();</span><br><span class="line">data[<span class="number">1</span>]();</span><br><span class="line">data[<span class="number">2</span>]();</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment">//closure </span></span><br><span class="line"><span class="keyword">var</span> data = [];</span><br><span class="line"></span><br><span class="line"><span class="keyword">for</span> (<span class="keyword">var</span> i = <span class="number">0</span>; i < <span class="number">3</span>; i++) {</span><br><span class="line"> data[i] = (<span class="function"><span class="keyword">function</span> (<span class="params">i</span>) </span>{</span><br><span class="line"> <span class="keyword">return</span> <span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>{</span><br><span class="line"> <span class="built_in">console</span>.log(i);</span><br><span class="line"> }</span><br><span class="line"> })(i);</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">data[<span class="number">0</span>]();<span class="comment">//不用找global的i</span></span><br><span class="line">data[<span class="number">1</span>]();</span><br><span class="line">data[<span class="number">2</span>]();</span><br></pre></td></tr></table></figure>]]></content>
<summary type="html">
<p>前置知识:JavaScript是静态作用域</p>
<p>闭包:访问自由变量的函数</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span>
</summary>
<category term="JavaScript" scheme="http://zehai.info/categories/JavaScript/"/>
<category term="closure" scheme="http://zehai.info/tags/closure/"/>
</entry>
<entry>
<title>vscode访问服务器文件</title>
<link href="http://zehai.info/2021/01/05/2021-01-05-vscoderemote/"/>
<id>http://zehai.info/2021/01/05/2021-01-05-vscoderemote/</id>
<published>2021-01-05T06:49:27.000Z</published>
<updated>2021-07-27T07:09:41.899Z</updated>
<content type="html"><![CDATA[<p>1.install <code>remote ssh</code> in vscode</p><p>2.click <code>remote explorer</code> and select <code>ssh targets</code></p><p>3.click remote ssh <code>configure</code> or press <code>F1</code> and input remote-ssh:Open configuration file</p><p>4.selete path <code>~/.ssh/config</code>,and modify config file</p><p>if you dont have rsa ,please generate keys before</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">//optional</span><br><span class="line">ssh-keygen</span><br><span class="line"><span class="meta">#</span><span class="bash"> passphrase can be empty and <span class="keyword">then</span> generate keys <span class="keyword">in</span> `~/.ssh`</span></span><br><span class="line"><span class="meta">#</span><span class="bash"> put *.pub (public key) to your server (~/.ssh/) and excute `cat id_rsa.pub >> authorized_keys` to merge Previous file</span></span><br><span class="line"><span class="meta">#</span><span class="bash"> now rsa keys are ready</span></span><br><span class="line"></span><br></pre></td></tr></table></figure><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">Host alias</span><br><span class="line"> HostName 8.888.88.8</span><br><span class="line"> User root</span><br><span class="line"> IdentityFile ~/.ssh/id_rsa</span><br><span class="line"> RSAAuthentication yes</span><br><span class="line"> PubkeyAuthentication yes</span><br><span class="line"> PasswordAuthentication no</span><br></pre></td></tr></table></figure><ul><li>Host alias–>your remote server name</li><li>hostName–>server ip</li><li>User–>login username</li><li>IdentityFile–>private key path</li><li>RSAAuthentication–>optional</li><li>PubkeyAuthentication–>optional</li><li>PasswordAuthentication–>no password login</li></ul><p>5.login without password ready</p>]]></content>
<summary type="html">
<p>1.install <code>remote ssh</code> in vscode</p>
<p>2.click <code>remote explorer</code> and select <code>ssh targets</code></p>
<p>3.clic
</summary>
<category term="skills" scheme="http://zehai.info/categories/skills/"/>
<category term="vscode" scheme="http://zehai.info/tags/vscode/"/>
</entry>
<entry>
<title>2020-10-16-promise用法</title>
<link href="http://zehai.info/2020/10/16/2020-10-16-promise%E7%94%A8%E6%B3%95/"/>
<id>http://zehai.info/2020/10/16/2020-10-16-promise用法/</id>
<published>2020-10-16T10:42:09.000Z</published>
<updated>2021-07-27T07:09:41.898Z</updated>
<content type="html"><![CDATA[<h1 id="What"><a href="#What" class="headerlink" title="What"></a>What</h1><p>ECMAscript 6 原生提供了 Promise 对象。</p><p>Promise 对象代表了未来将要发生的事件,用来传递异步操作的消息。</p><h3 id="Promise-对象有以下两个特点"><a href="#Promise-对象有以下两个特点" class="headerlink" title="Promise 对象有以下两个特点:"></a>Promise 对象有以下两个特点:</h3><p>1、对象的状态不受外界影响。Promise 对象代表一个异步操作,有三种状态:</p><ul><li>pending: 初始状态,不是成功或失败状态。</li><li>fulfilled: 意味着操作成功完成。</li><li>rejected: 意味着操作失败。</li></ul><p>只有异步操作的结果,可以决定当前是哪一种状态,任何其他操作都无法改变这个状态。这也是 Promise 这个名字的由来,它的英语意思就是「承诺」,表示其他手段无法改变。</p><p>2、一旦状态改变,就不会再变,任何时候都可以得到这个结果。Promise 对象的状态改变,只有两种可能:从 Pending 变为 Resolved 和从 Pending 变为 Rejected。只要这两种情况发生,状态就凝固了,不会再变了,会一直保持这个结果。就算改变已经发生了,你再对 Promise 对象添加回调函数,也会立即得到这个结果。这与事件(Event)完全不同,事件的特点是,如果你错过了它,再去监听,是得不到结果的。</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">var promise = new Promise(function(resolve, reject) {</span><br><span class="line"> // 异步处理</span><br><span class="line"> // 处理结束后、调用resolve 或 reject</span><br><span class="line">});</span><br></pre></td></tr></table></figure><p>以上来自:<a href="https://www.runoob.com/w3cnote/javascript-promise-object.html">菜鸟https://www.runoob.com/w3cnote/javascript-promise-object.html</a></p><h1 id="Why"><a href="#Why" class="headerlink" title="Why"></a>Why</h1><p>因为在<a href="/2020/01/07/2020-01-07-%E5%85%B3%E4%BA%8EPromise%E7%9A%84%E6%80%9D%E8%80%83/">2020年01月07日有一篇文章</a>讲了使用promise实现延时队列的一道面试题,因为之前写业务没有用到过所以一直以为用处不大,但今天对接阿里的<code>录音文件识别</code>转文字的接口中,示例代码是一个setInterval轮询得到结果的一种方式,但是他带来了一个很严重的问题</p><blockquote><p>!!没有办法返回前端转文字的结果!!</p></blockquote><p>大概代码如下</p><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></pre></td><td class="code"><pre><span class="line"><span class="comment">//url:https://help.aliyun.com/document_detail/94242.html?spm=a2c4g.11174283.6.601.15eb7275a8rq00</span></span><br><span class="line"><span class="comment">// 这段代码会异步执行,可以得到结果,但是直接用这个代码返回给前端</span></span><br><span class="line">client.submitTask(taskParams, options).then(<span class="function">(<span class="params">response</span>) =></span> {</span><br><span class="line"> <span class="built_in">console</span>.log(response);</span><br><span class="line"> <span class="comment">// 服务端响应信息的状态描述StatusText。</span></span><br><span class="line"> <span class="keyword">var</span> statusText = response.StatusText;</span><br><span class="line"> <span class="keyword">if</span> (statusText != <span class="string">'SUCCESS'</span>) {</span><br><span class="line"> <span class="built_in">console</span>.log(<span class="string">'录音文件识别请求响应失败!'</span>)</span><br><span class="line"> <span class="keyword">return</span>;</span><br><span class="line"> }</span><br><span class="line"> <span class="built_in">console</span>.log(<span class="string">'录音文件识别请求响应成功!'</span>);</span><br><span class="line"> <span class="comment">// 获取录音文件识别请求任务的TaskId,以供识别结果查询使用。</span></span><br><span class="line"> <span class="keyword">var</span> taskId = response.TaskId;</span><br><span class="line"> <span class="comment">/**</span></span><br><span class="line"><span class="comment"> * 以TaskId为查询参数,提交识别结果查询请求。</span></span><br><span class="line"><span class="comment"> * 以轮询的方式进行识别结果的查询,直到服务端返回的状态描述为"SUCCESS"、SUCCESS_WITH_NO_VALID_FRAGMENT,</span></span><br><span class="line"><span class="comment"> * 或者为错误描述,则结束轮询。</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"> <span class="keyword">var</span> taskIdParams = {</span><br><span class="line"> <span class="attr">TaskId</span> : taskId</span><br><span class="line"> };</span><br><span class="line"> <span class="keyword">var</span> timer = <span class="built_in">setInterval</span>(<span class="function">() =></span> {</span><br><span class="line"> client.getTaskResult(taskIdParams).then(<span class="function">(<span class="params">response</span>) =></span> {</span><br><span class="line"> <span class="built_in">console</span>.log(<span class="string">'识别结果查询响应:'</span>);</span><br><span class="line"> <span class="built_in">console</span>.log(response);</span><br><span class="line"> <span class="keyword">var</span> statusText = response.StatusText;</span><br><span class="line"> <span class="keyword">if</span> (statusText == <span class="string">'RUNNING'</span> || statusText == <span class="string">'QUEUEING'</span>) {</span><br><span class="line"> <span class="comment">// 继续轮询,注意间隔周期。</span></span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">else</span> {</span><br><span class="line"> <span class="keyword">if</span> (statusText == <span class="string">'SUCCESS'</span> || statusText == <span class="string">'SUCCESS_WITH_NO_VALID_FRAGMENT'</span>) {</span><br><span class="line"> <span class="built_in">console</span>.log(<span class="string">'录音文件识别成功:'</span>);</span><br><span class="line"> <span class="keyword">var</span> sentences = response.Result;</span><br><span class="line"> <span class="built_in">console</span>.log(sentences);</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">else</span> {</span><br><span class="line"> <span class="built_in">console</span>.log(<span class="string">'录音文件识别失败!'</span>);</span><br><span class="line"> }</span><br><span class="line"> <span class="comment">// 退出轮询</span></span><br><span class="line"> <span class="built_in">clearInterval</span>(timer);</span><br><span class="line"> }</span><br><span class="line"> }).catch(<span class="function">(<span class="params">error</span>) =></span> {</span><br><span class="line"> <span class="built_in">console</span>.error(error);</span><br><span class="line"> <span class="comment">// 异常情况,退出轮询。</span></span><br><span class="line"> <span class="built_in">clearInterval</span>(timer);</span><br><span class="line"> });</span><br><span class="line"> }, <span class="number">10000</span>);</span><br><span class="line"> }).catch(<span class="function">(<span class="params">error</span>) =></span> {</span><br><span class="line"> <span class="built_in">console</span>.error(error);</span><br><span class="line"> });</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h1 id="How"><a href="#How" class="headerlink" title="How"></a>How</h1><p>使用promise进行包裹,等到promise内部的函数取到了结果在返回</p><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">if</span> (statusText == <span class="string">'SUCCESS'</span> || statusText == <span class="string">'SUCCESS_WITH_NO_VALID_FRAGMENT'</span>) {</span><br><span class="line"> <span class="built_in">console</span>.log(<span class="string">'录音文件识别成功:'</span>);</span><br><span class="line"> <span class="keyword">var</span> sentences = response.Result;</span><br><span class="line"> <span class="built_in">console</span>.log(sentences);</span><br><span class="line"> <span class="comment">//这里新增resolve</span></span><br><span class="line">} <span class="keyword">else</span> {</span><br><span class="line"> <span class="built_in">console</span>.log(<span class="string">'录音文件识别失败!'</span>);</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>外层通过如下代码实现</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><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">var promise = new Promise(function(resolve, reject) {</span><br><span class="line"> // 异步处理</span><br><span class="line"> // 处理结束后、调用resolve 或 reject</span><br><span class="line">});</span><br></pre></td></tr></table></figure><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">async</span> <span class="function"><span class="keyword">function</span> <span class="title">getWords</span>(<span class="params"></span>) </span>{</span><br><span class="line"> <span class="keyword">return</span> <span class="keyword">new</span> <span class="built_in">Promise</span>(<span class="function">(<span class="params">resolve, reject</span>) =></span> {</span><br><span class="line"> client</span><br><span class="line"> .submitTask(taskParams, options)</span><br><span class="line"> .then(<span class="function"><span class="params">response</span> =></span> {</span><br><span class="line"> <span class="built_in">console</span>.log(response);</span><br><span class="line"> <span class="comment">// 服务端响应信息的状态描述StatusText。</span></span><br><span class="line"> <span class="keyword">const</span> statusText = response.StatusText;</span><br><span class="line"> <span class="keyword">if</span> (statusText != <span class="string">'SUCCESS'</span>) {</span><br><span class="line"> <span class="built_in">console</span>.log(<span class="string">'录音文件识别请求响应失败!'</span>);</span><br><span class="line"> }</span><br><span class="line"> <span class="built_in">console</span>.log(<span class="string">'录音文件识别请求响应成功!'</span>);</span><br><span class="line"> <span class="comment">// 获取录音文件识别请求任务的TaskId,以供识别结果查询使用。</span></span><br><span class="line"> <span class="keyword">const</span> taskId = response.TaskId;</span><br><span class="line"> <span class="comment">/**</span></span><br><span class="line"><span class="comment"> * 以TaskId为查询参数,提交识别结果查询请求。</span></span><br><span class="line"><span class="comment"> * 以轮询的方式进行识别结果的查询,直到服务端返回的状态描述为"SUCCESS"、SUCCESS_WITH_NO_VALID_FRAGMENT,</span></span><br><span class="line"><span class="comment"> * 或者为错误描述,则结束轮询。</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"> <span class="keyword">const</span> taskIdParams = {</span><br><span class="line"> <span class="attr">TaskId</span>: taskId,</span><br><span class="line"> };</span><br><span class="line"></span><br><span class="line"> <span class="keyword">const</span> timer = <span class="built_in">setInterval</span>(<span class="function">() =></span> {</span><br><span class="line"> client</span><br><span class="line"> .getTaskResult(taskIdParams)</span><br><span class="line"> .then(<span class="function"><span class="params">response</span> =></span> {</span><br><span class="line"> <span class="built_in">console</span>.log(<span class="string">'识别结果查询响应:'</span>);</span><br><span class="line"> <span class="built_in">console</span>.log(response);</span><br><span class="line"> <span class="keyword">const</span> statusText = response.StatusText;</span><br><span class="line"> <span class="keyword">if</span> (statusText == <span class="string">'RUNNING'</span> || statusText == <span class="string">'QUEUEING'</span>) {</span><br><span class="line"> <span class="comment">// 继续轮询,注意间隔周期。</span></span><br><span class="line"> } <span class="keyword">else</span> {</span><br><span class="line"> <span class="keyword">if</span> (</span><br><span class="line"> statusText == <span class="string">'SUCCESS'</span> ||</span><br><span class="line"> statusText == <span class="string">'SUCCESS_WITH_NO_VALID_FRAGMENT'</span></span><br><span class="line"> ) {</span><br><span class="line"> <span class="built_in">console</span>.log(<span class="string">'录音文件识别成功:'</span>);</span><br><span class="line"> <span class="keyword">let</span> sentences = <span class="string">''</span>;</span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">const</span> s <span class="keyword">of</span> response.Result.Sentences) {</span><br><span class="line"> sentences += s.Text;</span><br><span class="line"> }</span><br><span class="line"> <span class="built_in">console</span>.log(response.Result);</span><br><span class="line"> resolve(sentences);<span class="comment">//**重点**//</span></span><br><span class="line"> <span class="comment">// return sentences;</span></span><br><span class="line"> } <span class="keyword">else</span> {</span><br><span class="line"> <span class="built_in">console</span>.log(<span class="string">'录音文件识别失败!'</span>);</span><br><span class="line"> }</span><br><span class="line"> <span class="comment">// 退出轮询</span></span><br><span class="line"> <span class="built_in">clearInterval</span>(timer);</span><br><span class="line"> }</span><br><span class="line"> })</span><br><span class="line"> .catch(<span class="function"><span class="params">error</span> =></span> {</span><br><span class="line"> <span class="built_in">console</span>.error(error);</span><br><span class="line"> <span class="comment">// 异常情况,退出轮询。</span></span><br><span class="line"> <span class="built_in">clearInterval</span>(timer);</span><br><span class="line"> });</span><br><span class="line"> }, <span class="number">10000</span>);</span><br><span class="line"> })</span><br><span class="line"> .catch(<span class="function"><span class="params">error</span> =></span> {</span><br><span class="line"> <span class="built_in">console</span>.error(error);</span><br><span class="line"> });</span><br><span class="line"> });</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> <span class="keyword">await</span> getWords();<span class="comment">//返回前端,翻译结果</span></span><br></pre></td></tr></table></figure><blockquote><p>另外记录一件事情,左侧单元图标地址:<a href="https://fontawesome.com/v4.7.0/icons/">https://fontawesome.com/v4.7.0/icons/</a></p></blockquote>]]></content>
<summary type="html">
<h1 id="What"><a href="#What" class="headerlink" title="What"></a>What</h1><p>ECMAscript 6 原生提供了 Promise 对象。</p>
<p>Promise 对象代表了未来将要发生的事件,用
</summary>
</entry>
<entry>
<title>NodeJS</title>
<link href="http://zehai.info/2020/09/27/2020-09-27-NodeJS/"/>
<id>http://zehai.info/2020/09/27/2020-09-27-NodeJS/</id>
<published>2020-09-27T10:42:36.000Z</published>
<updated>2021-07-27T07:09:41.898Z</updated>
<content type="html"><![CDATA[<blockquote><p><a href="https://github.com/theanarkh/understand-nodejs">https://github.com/theanarkh/understand-nodejs</a></p></blockquote><p>文档还是不错的</p>]]></content>
<summary type="html">
<blockquote>
<p><a href="https://github.com/theanarkh/understand-nodejs">https://github.com/theanarkh/understand-nodejs</a></p>
</blockquote
</summary>
</entry>
<entry>
<title>Jupyter</title>
<link href="http://zehai.info/2020/09/25/2020-09-25-Jupyter/"/>
<id>http://zehai.info/2020/09/25/2020-09-25-Jupyter/</id>
<published>2020-09-25T07:48:37.000Z</published>
<updated>2021-07-27T07:09:41.898Z</updated>
<content type="html"><![CDATA[<h1 id="what"><a href="#what" class="headerlink" title="what"></a>what</h1><p>Jupiter = Julia + Python + R</p><blockquote><p>Jupyter notebook(<a href="https://link.zhihu.com/?target=http%3A//jupyter.org/">http://jupyter.org/</a>) 是一种 Web 应用,能让用户将说明文本、数学方程、代码和可视化内容全部组合到一个易于共享的文档中。</p></blockquote><h1 id="why"><a href="#why" class="headerlink" title="why"></a>why</h1><ul><li>将代码和文档结合在一起,更直观的编写人工智能,大数据的代码</li><li>分块运行</li><li>直接运行shell不需要切换环境</li><li>so on</li></ul><h1 id="how"><a href="#how" class="headerlink" title="how"></a>how</h1><ol><li>Download images</li></ol><figure class="highlight plaintext"><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">$docker pull jupyter jupyter/scipy-notebook:latest</span><br><span class="line">$docker run -itd --rm -p 1000:8888 -e JUPYTER_ENABLE_LAB=yes -v /home/zehai/jupyter:/home/jovyan/work --name jupyter jupyter/scipy-notebook:latest</span><br></pre></td></tr></table></figure><ol start="2"><li>docker logs -f container’s ID and find token</li></ol><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">To access the notebook, open this file in a browser:</span><br><span class="line"> file:///home/jovyan/.local/share/jupyter/runtime/nbserver-6-open.html</span><br><span class="line">Or copy and paste one of these URLs:</span><br><span class="line"> http://896bb1e66101:8888/?token=fda8565a9b5cd5b8c621b45322ee72f716fd7ddea089fb51</span><br><span class="line"> or http://127.0.0.1:8888/?token=fda8565a9b5cd5b8c621b45322ee72f716fd7ddea089fb51</span><br></pre></td></tr></table></figure><ol start="3"><li>more info visit official <a href="https://jupyter-docker-stacks.readthedocs.io/en/latest/">docs</a></li><li>enjoy (pics powered by cherevero)</li></ol><p><img src="https://pics.tbjd.xyz/images/2020/09/25/3318a2fadaf085f2bee7f0de3b42971c.png" alt="3318a2fadaf085f2bee7f0de3b42971c.png"></p>]]></content>
<summary type="html">
<h1 id="what"><a href="#what" class="headerlink" title="what"></a>what</h1><p>Jupiter = Julia + Python + R</p>
<blockquote>
<p>Jupyter noteb
</summary>
</entry>
<entry>
<title>chevereto</title>
<link href="http://zehai.info/2020/09/15/2020-09-15-Chevereto/"/>
<id>http://zehai.info/2020/09/15/2020-09-15-Chevereto/</id>
<published>2020-09-15T02:16:33.000Z</published>
<updated>2021-07-27T07:09:41.898Z</updated>
<content type="html"><![CDATA[<h1 id="what"><a href="#what" class="headerlink" title="what"></a>what</h1><p>To solve some problems</p><ul><li>some web only use markdown and can’t upload pictures,such as v2ex.com</li><li>some pics you don’t want to give it to others for long time,such as your interesting story </li><li>give your blog’s can speed when download bigger pics</li><li>and so on</li></ul><p>Picture Bed can offer you a excellent platform to share your pictures and protect them, however it has a problem that you need a server to run the service,even though you can use 七牛云,alioss,weibo for free.</p><h1 id="why"><a href="#why" class="headerlink" title="why"></a>why</h1><p>Chevereto is aim what I find</p><ul><li>dockerhub has chevereto images</li><li>Combined with <a href="https://getsharex.com/">ShareX</a> (only for windows😢),chevereto can write markdown essay easily</li><li>it has api ,you can make it stronger</li><li>Chevereto Free v1.2.2 now</li><li>Something others you can discover by yourself</li></ul><h1 id="how"><a href="#how" class="headerlink" title="how"></a>how</h1><p>Chevereto is a php project , I use docker to run it </p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><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">docker pull nmtan/chevereto:latest</span><br><span class="line"></span><br><span class="line">//use docker-compose.yml(next block)</span><br><span class="line"></span><br><span class="line">// or docker run </span><br><span class="line">docker run -it --name chevereto -d -p 8000:80 -v "/home/xxx/images":/var/www/html/images -e "CHEVERETO_DB_HOST=127.0.0.1" -e "CHEVERETO_DB_USERNAME=root" -e "CHEVERETO_DB_PASSWORD=rootpass" -e "CHEVERETO_DB_NAME=chevereto" -e "CHEVERETO_DB_PREFIX=chv_" nmtan/chevereto</span><br><span class="line">//-v save photos in server instead of container</span><br><span class="line">//-e mysql:5.7.31 host,username,password,db_name(db must exist first)</span><br><span class="line">//open chrome and input 127.0.0.1:8000</span><br><span class="line"></span><br></pre></td></tr></table></figure><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><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">//this is docker-compose.yml</span><br><span class="line">version: '3'</span><br><span class="line"></span><br><span class="line">services:</span><br><span class="line"> db:</span><br><span class="line"> image: mariadb</span><br><span class="line"> volumes:</span><br><span class="line"> - ./database:/var/lib/mysql:rw</span><br><span class="line"> restart: always</span><br><span class="line"> networks:</span><br><span class="line"> - private</span><br><span class="line"> environment:</span><br><span class="line"> MYSQL_ROOT_PASSWORD: xxxxx</span><br><span class="line"> MYSQL_DATABASE: xxxxx</span><br><span class="line"> MYSQL_USER: xxxxx</span><br><span class="line"> MYSQL_PASSWORD: xxxxx</span><br><span class="line"></span><br><span class="line"> chevereto:</span><br><span class="line"> depends_on:</span><br><span class="line"> - db</span><br><span class="line"> image: nmtan/chevereto</span><br><span class="line"> restart: always</span><br><span class="line"> networks:</span><br><span class="line"> - private</span><br><span class="line"> environment:</span><br><span class="line"> CHEVERETO_DB_HOST: db</span><br><span class="line"> CHEVERETO_DB_USERNAME: xxxxxx</span><br><span class="line"> CHEVERETO_DB_PASSWORD: xxxxx</span><br><span class="line"> CHEVERETO_DB_NAME: xxxxx</span><br><span class="line"> CHEVERETO_DB_PREFIX: chv_</span><br><span class="line"> volumes:</span><br><span class="line"> - ./images:/var/www/html/images:rw</span><br><span class="line"> - ./php.ini:/usr/local/etc/php/php.ini:ro</span><br><span class="line"> ports:</span><br><span class="line"> - 8080:80</span><br><span class="line"></span><br><span class="line">networks:</span><br><span class="line"> private:</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">// start command</span><br><span class="line">nohup docker-compose up &> run.log &</span><br><span class="line">disown</span><br></pre></td></tr></table></figure><p>You maybe run into a stone wall when you first visit 127.0.0.1:8000</p><ul><li><p>Before you can use <code>docker exec -it chevereto bash</code> into container /var/www/html</p></li><li><p>no permission write phots to /home/xxx/images,you can use <code>chmod -R 777 /home/xxx/images</code></p></li><li>no permission update chevereto from 1.1.4 to1.2.2 ,<code>no update possible: /app/install/update/temp/ path</code>,that is no temp folder in /app/install/update/ under version 1.2.0,you can mkdir temp and then chmod -R 777 ./temp and then refresh the webpage ,the prics bed will update successfully</li></ul><p>So , you can use ip address to visit your chevereto . However , we usually use domain name such as example.com to visit web, a https isn ecessary as well</p><ul><li>1.Use <a href="https://yundunnext.console.aliyun.com/?spm=5176.2020520163.0.0.475556a7iLgQoU&p=cas">aliyun</a> to apply a free ssl license for a domain name such as pics.example.com</li><li>2.Download pem and keys to your server and put it in nginx conf folder</li><li>3.Use the conf as follows</li></ul><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><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">server {</span><br><span class="line"> listen 80;</span><br><span class="line"> server_name pics.example.com;</span><br><span class="line"> return 301 https://pics.example.com$request_uri;</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> server {</span><br><span class="line"> listen 443 ssl;</span><br><span class="line"> server_name pics.example.com;</span><br><span class="line"> gzip on; </span><br><span class="line"></span><br><span class="line"> ssl_certificate cert/xxxxxx9_pics.example.com.pem; # pem's filename</span><br><span class="line"> ssl_certificate_key cert/xxxxxx9_pics.example.com.key;# key's filename</span><br><span class="line"></span><br><span class="line"> location / {</span><br><span class="line"> proxy_redirect off;</span><br><span class="line"> proxy_pass http://dockername;</span><br><span class="line"></span><br><span class="line"> proxy_set_header Host $http_host;</span><br><span class="line"> proxy_set_header X-Real-IP $remote_addr;</span><br><span class="line"> proxy_set_header X-Forwarded-Ssl on;</span><br><span class="line"> proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;</span><br><span class="line"> proxy_set_header X-Forwarded-Proto $scheme;</span><br><span class="line"> proxy_set_header X-Frame-Options SAMEORIGIN;</span><br><span class="line"></span><br><span class="line"> client_max_body_size 100m;</span><br><span class="line"> client_body_buffer_size 128k;</span><br><span class="line"></span><br><span class="line"> proxy_buffer_size 4k;</span><br><span class="line"> proxy_buffers 4 32k;</span><br><span class="line"> proxy_busy_buffers_size 64k;</span><br><span class="line"> proxy_temp_file_write_size 64k;</span><br><span class="line"> }</span><br><span class="line"> }</span><br></pre></td></tr></table></figure><ul><li><ol start="4"><li>And then you can visit <code>https://pics.example.com</code> </li></ol></li></ul><p>That‘s my story that building pics bed ,and hope to help you.</p><p><code>2020-09-28 append</code></p><p>use <code>picgo</code>,upload pictures in typora to chevereto</p><ol><li><p>GitHub download picgo,mac use <a href="https://github.com/Molunerfinn/PicGo/releases/download/v2.3.0-beta.3/PicGo-2.3.0-beta.3.dmg">.dmp</a>,and then install it</p></li><li><p>open <code>插件设置</code>,search <code>chevereto</code> and install <code>chevereto 1.0.0</code></p></li><li><p>Open <code>图床设置>Chevereto Uploader</code> and put in params,</p><p>Url is your upload service ip/domain</p><p>Key is chevereto api in <code>Dashboard>Settings>API>API v1 key</code></p><p>param is not in use now</p></li></ol><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">Url:https://example.com/api/1/upload</span><br><span class="line">Key:xxx</span><br></pre></td></tr></table></figure><ol start="4"><li>Click <code>确定</code> and <code>设为默认图库</code></li><li>make sure server is on <code>PicGo设置>设置Server>点击设置</code>,if it is on ,noting should be done</li></ol><p>and then we modify config in typaro</p><ol><li>Open Typora and open ‘preferences>Images` </li><li>Choose Upload images in when Insert and check <code>apply above rules to local images</code> and <code>apply above rules to online images</code> in option, and I suggest you check both of them to approve all pics managed by chevereto</li><li>Choose <code>PicGo.app</code> in images Uploader and click <code>Test Uploader</code> to test your upload pictures automatically</li></ol><p>for more information ,youcan visit </p><ul><li><a href="https://github.com/Molunerfinn/PicGo">PicGo</a> and <a href="https://picgo.github.io/PicGo-Core-Doc/">PicGo-Core</a></li><li><a href="https://blog.csdn.net/qq_19564393/article/details/108506062">Upload your pictures in personal album instead of visitors’ albulm</a></li><li><a href="https://v3-docs.chevereto.com/API/V1.html#api-key">Chevereto API</a></li></ul><h1 id="thanks"><a href="#thanks" class="headerlink" title="thanks"></a>thanks</h1><ul><li><a href="https://chevereto.com/">Chevereto</a></li><li><a href="https://getsharex.com/">ShareX</a></li><li><a href="https://www.ioiox.com/archives/80.html">ioiox’s blog</a></li><li><a href="https://dana5haw.com/posts/Docker-Image-Hosting-Chevereto.html">dana5haw’s blog</a></li></ul>]]></content>
<summary type="html">
<h1 id="what"><a href="#what" class="headerlink" title="what"></a>what</h1><p>To solve some problems</p>
<ul>
<li>some web only use markdown
</summary>
<category term="Chevereto" scheme="http://zehai.info/categories/Chevereto/"/>
<category term="pictureBed" scheme="http://zehai.info/tags/pictureBed/"/>
</entry>
<entry>
<title>RabbitMQ</title>
<link href="http://zehai.info/2020/09/14/2020-09-14-RabbitMQ/"/>
<id>http://zehai.info/2020/09/14/2020-09-14-RabbitMQ/</id>
<published>2020-09-14T04:13:40.000Z</published>
<updated>2021-07-27T07:09:41.897Z</updated>
<content type="html"><![CDATA[<h1 id="what"><a href="#what" class="headerlink" title="what"></a>what</h1><p>MQ-message queue</p><p>三足鼎立</p><p>rocketmq -Made by Java 吞吐量高一些 阿里中间件</p><p>rabbitmq -Made by Erlang</p><p>Kafka-</p><p><img src="../img/mq.jpg" align='left'/></p><p>以后有更多的了解再补充性能/功能差距</p><h1 id="why"><a href="#why" class="headerlink" title="why"></a>why</h1><p>功能:解耦(双方通过mq交互)、异步、削峰</p><p>应用:</p><ul><li>阿里双11</li></ul><p>问题:</p><ul><li>处理好新增的复杂性</li><li>处理好系统可用性</li></ul><h1 id="how"><a href="#how" class="headerlink" title="how"></a>how</h1><p>之所以选择rabbitmq是因为rocketmq的nameserver所需要的内存太大了,更何况boker,对于1C2G的乞丐机器来说根本跑不起来</p><h2 id="1-docker-run"><a href="#1-docker-run" class="headerlink" title="1.docker run"></a>1.docker run</h2><p>Because of rocketmq need more than </p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><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">docker pull rabbitmq:management</span><br><span class="line"></span><br><span class="line">docker run -dit --name rabbitmq -e RABBITMQ_DEFAULT_USER=admin -e RABBITMQ_DEFAULT_PASS=admin -p 15672:15672 -p 5672:5672 rabbitmq:management</span><br><span class="line"></span><br><span class="line">--name containername</span><br><span class="line">-e RABBITMQ_DEFAULT_USER 参数用户名,密码同理</span><br><span class="line">-p 端口映射,主机:容器,15672-UI,5672-service</span><br><span class="line">rabbitmq:management image's name</span><br><span class="line"></span><br></pre></td></tr></table></figure><h2 id="2-Usage"><a href="#2-Usage" class="headerlink" title="2.Usage"></a>2.Usage</h2><p>1.open chrome and input ‘localhost:15672’ or ‘192.168.1.1:15672’ then you can touch rabbitmq UI</p><p>Overview–the queued msg, msg rate in your server, some global counts, your nodes stats (if u use the above method,you only see one node in the screen ),you also can build a cluster with more nodes</p><p>Connections–</p><p>Channels–</p><p>Exchanges–direct,fanout,headers,match,trace,topic</p><p>Queses–</p><p>Admin–users management with passport && permission</p><p>2.use 5672 in your code</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">amqp.connect({</span><br><span class="line"> <span class="attr">protocol</span>: <span class="string">'amqp'</span>,</span><br><span class="line"> <span class="attr">hostname</span>: <span class="string">'example.com'</span>,<span class="comment">//localhost</span></span><br><span class="line"> <span class="attr">port</span>: <span class="string">'5672'</span>,</span><br><span class="line"> <span class="attr">username</span>: <span class="string">'admin'</span>,</span><br><span class="line"> <span class="attr">password</span>: <span class="string">'xxx'</span>,</span><br><span class="line"> <span class="attr">vhost</span>: <span class="string">'/'</span>,<span class="comment">//important</span></span><br><span class="line"> })</span><br></pre></td></tr></table></figure><p>more in official docs–><a href="https://www.rabbitmq.com/tutorials/tutorial-one-javascript.html"> I’m doc</a></p><p>or some blogs–><a href="https://www.cnblogs.com/wukong-holmes/p/9306733.html">I’m blog</a></p><p>or my GitHub–><a href="https://github.com/ShawnGoethe/phones/tree/master/app/controller/pmq.js">click here</a></p>]]></content>
<summary type="html">
<h1 id="what"><a href="#what" class="headerlink" title="what"></a>what</h1><p>MQ-message queue</p>
<p>三足鼎立</p>
<p>rocketmq -Made by Java 吞
</summary>
<category term="MQ" scheme="http://zehai.info/categories/MQ/"/>
<category term="basic" scheme="http://zehai.info/tags/basic/"/>
</entry>
</feed>