-
Notifications
You must be signed in to change notification settings - Fork 1
/
atom.xml
790 lines (624 loc) · 118 KB
/
atom.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
<title>Kimown's Blog</title>
<link href="/atom.xml" rel="self"/>
<link href="https://kimown.github.io/"/>
<updated>2016-09-20T12:54:26.041Z</updated>
<id>https://kimown.github.io/</id>
<author>
<name>kimown</name>
</author>
<generator uri="http://hexo.io/">Hexo</generator>
<entry>
<title>阿里云code配置ssh</title>
<link href="https://kimown.github.io/2016/09/20/%E9%98%BF%E9%87%8C%E4%BA%91code%E9%85%8D%E7%BD%AEssh/"/>
<id>https://kimown.github.io/2016/09/20/阿里云code配置ssh/</id>
<published>2016-09-20T10:27:28.000Z</published>
<updated>2016-09-20T12:54:26.041Z</updated>
<content type="html"><![CDATA[<p> <a href="https://code.aliyun.com/" target="_blank" rel="external">阿里云Code</a><br> <a id="more"></a></p>
<p>今天无意在网络上发现了<a href="https://code.aliyun.com/users/sign_in" target="_blank" rel="external">阿里云Code</a>,这是在<a href="https://about.gitlab.com/" target="_blank" rel="external">GitLab</a>进行再开发的,所以一些使用体验和内网部署的GitLab是一致的.</p>
<h2 id="生成SSH-key"><a href="#生成SSH-key" class="headerlink" title="生成SSH key"></a>生成SSH key</h2><p>参考GitHub这篇文章 <a href="https://help.github.com/articles/generating-a-new-ssh-key-and-adding-it-to-the-ssh-agent/" target="_blank" rel="external">Generating a new SSH key and adding it to the ssh-agent - User Documentation</a><br><figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div></pre></td><td class="code"><pre><div class="line">google@H:~/.ssh$ ssh-keygen -t rsa -b 4096 -C <span class="string">"your_email@example.com"</span></div><div class="line">Generating public/private rsa key pair.</div><div class="line">Enter file <span class="keyword">in</span> <span class="built_in">which</span> to save the key (/home/google/.ssh/id_rsa): id_rsa_code_aliyun</div><div class="line">Enter passphrase (empty <span class="keyword">for</span> no passphrase):</div><div class="line">Enter same passphrase again:</div><div class="line">Your identification has been saved <span class="keyword">in</span> id_rsa_code_aliyun.</div><div class="line">Your public key has been saved <span class="keyword">in</span> id_rsa_code_aliyun.pub.</div><div class="line">The key fingerprint is:</div><div class="line">ff:af:52:d0:e8:23:4f:84:40:ae:5e:44:6a:cb:a7:0c your_email@example.com</div><div class="line">The key<span class="string">'s randomart image is:</span></div><div class="line">+--[ RSA 4096]----+</div><div class="line">| .o |</div><div class="line">| +. |</div><div class="line">| o o. . o |</div><div class="line">| o + . + . |</div><div class="line">| E + o So . |</div><div class="line">| + + ..+ . |</div><div class="line">| + +.o |</div><div class="line">| o. |</div><div class="line">| .oo. |</div><div class="line">+-----------------+</div><div class="line">google@H:~/.ssh$ ls id_rsa_code_aliyun* -a</div><div class="line">id_rsa_code_aliyun id_rsa_code_aliyun.pub</div></pre></td></tr></table></figure></p>
<p>id_rsa_code_aliyun是SSH中的私钥,id_rsa_code_aliyun.pub则是SSH中对应的公钥,我们要把公钥的内容发布出去,自己保留私钥就可以了.</p>
<h2 id="添加公钥id-rsa-code-aliyun-pub到阿里云Code"><a href="#添加公钥id-rsa-code-aliyun-pub到阿里云Code" class="headerlink" title="添加公钥id_rsa_code_aliyun.pub到阿里云Code"></a>添加公钥id_rsa_code_aliyun.pub到阿里云Code</h2><p>这里我建议使用gedit打开文件后CTRL+A CTRL+C复制,因为vi里面复制的话会带有空格.</p>
<h2 id="配置-ssh-config文件"><a href="#配置-ssh-config文件" class="headerlink" title="配置.ssh config文件"></a>配置.ssh config文件</h2><p>可以参考阿里云ssh的<a href="https://code.aliyun.com/help/ssh/README" target="_blank" rel="external">README</a></p>
<p>文件地址 ~/.ssh/config ,如果没有的话 touch config 即可,然后在里面添加下面的内容<br><figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div></pre></td><td class="code"><pre><div class="line">Host code.aliyun.com</div><div class="line"> HostName code.aliyun.com</div><div class="line"> IdentityFIle ~/.ssh/id_rsa_code_aliyun</div></pre></td></tr></table></figure></p>
<h2 id="验证连通成功"><a href="#验证连通成功" class="headerlink" title="验证连通成功"></a>验证连通成功</h2><p>继续参考GitHub <a href="https://help.github.com/articles/testing-your-ssh-connection/" target="_blank" rel="external">Testing your SSH connection - User Documentation</a></p>
<p>如果连接成功,<br><figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div></pre></td><td class="code"><pre><div class="line">google@H:~/.ssh$ ssh -T git@code.aliyun.com</div><div class="line"></div><div class="line"> **** Welcome to aliyun Code ****</div><div class="line"></div><div class="line"> Hi <span class="variable">${your_email}</span>, you have successfully connected over SSH.</div><div class="line"></div><div class="line"> To <span class="built_in">clone</span> a hosted Git repository, use:</div><div class="line"></div><div class="line"> git <span class="built_in">clone</span> git@localhost/REPOSITORY_NAME.git</div></pre></td></tr></table></figure></p>
<p>如果没有配置config文件,报错如下:</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div></pre></td><td class="code"><pre><div class="line">google@H:~/.ssh$ ssh -T git@code.aliyun.com</div><div class="line">The authenticity of host <span class="string">'code.aliyun.com (120.55.150.20)'</span> can<span class="string">'t be established.</span></div><div class="line">RSA key fingerprint is 69:ab:cb:07:eb:a3:e1:f3:0b:2e:f4:23:b0:c1:c6:9a.</div><div class="line">Are you sure you want to continue connecting (yes/no)? yes</div><div class="line">Warning: Permanently added 'code.aliyun.com,120.55.150.20<span class="string">' (RSA) to the list of known hosts.</span></div><div class="line">Received disconnect from 120.55.150.20: 2: Too many authentication failures</div></pre></td></tr></table></figure>
<p>EOF</p>
]]></content>
<summary type="html">
<p> <a href="https://code.aliyun.com/">阿里云Code</a><br>
</summary>
<category term="Linux" scheme="https://kimown.github.io/tags/Linux/"/>
</entry>
<entry>
<title>Hangman代码整体思路</title>
<link href="https://kimown.github.io/2016/09/18/Hangman%E4%BB%A3%E7%A0%81%E6%95%B4%E4%BD%93%E6%80%9D%E8%B7%AF/"/>
<id>https://kimown.github.io/2016/09/18/Hangman代码整体思路/</id>
<published>2016-09-18T10:48:58.000Z</published>
<updated>2016-09-20T12:54:48.713Z</updated>
<content type="html"><![CDATA[<p> 题目地址是<a href="https://github.com/strikingly/strikingly-interview-test-instructions" target="_blank" rel="external">这里</a>,大意是通过一个RESTful接口进行猜词.</p>
<a id="more"></a>
<p>这里我对<a href="https://github.com/kimown/gist/tree/0aa59b271110e792bfd34fe8e6ee8a60eae3792a/hangman-game" target="_blank" rel="external">当前最新的commit进行分析</a>,以后的代码结构有可能会变化</p>
<h2 id="代码思路"><a href="#代码思路" class="headerlink" title="代码思路"></a>代码思路</h2><p>使用一个单词字典,首先根据长度过滤单词,找到出现频率(一个单词内重复字符只计数一次)最高的字符,如果字符猜测正确,根据已知的字符过滤下单词字典,如果字符猜测错误,排除掉所有含有错误字符的单词, 然后重新统计单词字典中字符的频率,如果发送次数大于20次,下一个单词;如果错误次数超过限定值,下一个单词.</p>
<h2 id="注意点"><a href="#注意点" class="headerlink" title="注意点:"></a>注意点:</h2><ul>
<li><h3 id="英文字典的选取:"><a href="#英文字典的选取:" class="headerlink" title="英文字典的选取:"></a>英文字典的选取:</h3><p>起初我使用的是一个<a href="http://www-01.sil.org/linguistics/wordlists/english/" target="_blank" rel="external">1M大的小字典</a>,还有<a href="http://www-personal.umich.edu/~jlawler/wordlist" target="_blank" rel="external">这个</a>,但后来发现一个情况,有一个单词10个字符已经猜中了9个,还有最后一个字符迟迟猜不中,后来直接google查了下类似的单词,只找到一个对应的,在小词典里面根本没有这个单词,于是只能换一个更大的<a href="http://stackoverflow.com/questions/6441975/where-can-i-download-english-dictionary-database-in-a-text-fomat" target="_blank" rel="external">词典</a>,而且,这个词典里面还有一些单词格式不符合常见的格式,所以我按照字符过滤了下,<a href="https://github.com/kimown/gist/blob/0aa59b271110e792bfd34fe8e6ee8a60eae3792a/hangman-game/common/scripts.js#L36" target="_blank" rel="external">过滤规则</a>是两个,分别是过滤含有非大小写字符的单词和类似”AAA”或”aaaa”这种由相同字符组成的单词,这里使用正则过滤,如果使用字符串比较的话效率非常非常低,而且循环比较的时候程序很容易异常退出.</p>
</li>
<li><h3 id="分数的考虑"><a href="#分数的考虑" class="headerlink" title="分数的考虑"></a>分数的考虑</h3><p>因为是对抗游戏,所以<a href="https://github.com/strikingly/strikingly-interview-test-instructions#5-submit-your-result" target="_blank" rel="external">游戏分数</a>当然越高越好,计分规格:correctWordCount*20-totalWrongGuessCount*1.猜对一个单词,得分20,猜错一次字符,扣1分.这个得分规则决定了一个单词的收益最高20,那么限制一个单词的猜词次数不能超过20次是一个理想的选择(最坏情况:kimow* 最后一个字符n是最后一次猜对的,单词收益-1),否则直接跳过这个单词,进行下一轮.</p>
</li>
</ul>
<h2 id="代码整体结构"><a href="#代码整体结构" class="headerlink" title="代码整体结构:"></a>代码整体结构:</h2><h2 id="Dependencies"><a href="#Dependencies" class="headerlink" title="Dependencies"></a>Dependencies</h2><ul>
<li><a href="https://github.com/Unitech/pm2" target="_blank" rel="external">pm2</a> #确保程序24*7运行</li>
<li><a href="https://github.com/babel/babel/blob/master/packages/babel-register/README.md" target="_blank" rel="external">babel-register</a> #在后端使用最新ES语法</li>
<li><a href="https://github.com/request/request" target="_blank" rel="external">request</a> #向后台发送POST请求</li>
<li><a href="https://github.com/winstonjs/winston" target="_blank" rel="external">winston</a> #统一的日志库</li>
</ul>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div></pre></td><td class="code"><pre><div class="line">$ tree -L 1</div><div class="line">.</div><div class="line">├── babel-present-latest <span class="comment">#项目无关</span></div><div class="line">├── created-logfile.log <span class="comment">#记录了当前游戏的日志,这次猜词结果是成功还是失败,添加到.gitignore里面,不纳入git管理</span></div><div class="line">├── created-logfile-score.log <span class="comment">#记录了所有游戏最后的分数</span></div><div class="line">├── hangman-game <span class="comment">#游戏代码</span></div><div class="line">├── LICENSE</div><div class="line">├── loggerfile.js <span class="comment">#输出日志到文件</span></div><div class="line">├── logger.js <span class="comment">#对外console输出日志 #在游戏里面,每次猜测的字符都会从这里输出到console台里面</span></div><div class="line">├── node_modules</div><div class="line">├── package.json</div><div class="line">├── tmp</div><div class="line">└── util.js <span class="comment">#工具方法</span></div></pre></td></tr></table></figure>
<p><a href="https://github.com/kimown/gist/blob/0aa59b271110e792bfd34fe8e6ee8a60eae3792a/created-logfile-score.log" target="_blank" rel="external">created-logfile-score.log</a>:可以看到所有的得分,这样可以后台24*7刷分,最后到这个文件里面找到分数最高的就可以了<br>util.js : 为了保证项目代码的对依赖的便于替换,使用到的第三方依赖都是统一在<a href="https://github.com/kimown/gist/blob/0aa59b271110e792bfd34fe8e6ee8a60eae3792a/util.js" target="_blank" rel="external">util.js</a>这个工具类方法里面使用的,然后暴露对外的使用方法.例如我日志库不想使用winston而想使用<a href="https://github.com/nomiddlename/log4js-node" target="_blank" rel="external">log4js</a>,那么只需要在这里替换对应的库就可以了.想了下,这里如果封装自己的方法可以更好,这算是个优化点.</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div></pre></td><td class="code"><pre><div class="line">$ tree /tmp/gist/hangman-game/</div><div class="line">├── app.js <span class="comment">#主程序</span></div><div class="line">├── common</div><div class="line">│ ├── config.json <span class="comment">#配置文件</span></div><div class="line">│ ├── config-path.js <span class="comment">#将通用的路径统一暴露出去,便于维护</span></div><div class="line">│ ├── index.js <span class="comment">#对外暴露的公共方法</span></div><div class="line">│ ├── init-user-data.js <span class="comment">#初始化用户数据,包括读取字典文件,参考flux架构起到只有一个store的作用</span></div><div class="line">│ ├── operate-user-data.js <span class="comment">#对用户数据的读写操作</span></div><div class="line">│ ├── script_index.js</div><div class="line">│ └── scripts.js</div><div class="line">├── enwiktionary-latest-all-titles-in-ns0</div><div class="line">├── enwiktionary-latest-all-titles-in-ns0-filter.txt <span class="comment">#字典文件</span></div><div class="line">├── index.js <span class="comment">#使用babel-register启动的入口文件</span></div><div class="line">├── package.json</div><div class="line">└── README.md</div><div class="line"></div><div class="line">1 directory, 13 files</div></pre></td></tr></table></figure>
<p>script_index.js和scripts.js:是工具文件,对原始文件enwiktionary-latest-all-titles-in-ns0操作后,生成最后读取的enwiktionary-latest-all-titles-in-ns0-filter.txt字典文件,和主程序无关.</p>
]]></content>
<summary type="html">
<p> 题目地址是<a href="https://github.com/strikingly/strikingly-interview-test-instructions">这里</a>,大意是通过一个RESTful接口进行猜词.</p>
</summary>
<category term="Node.js" scheme="https://kimown.github.io/tags/Node-js/"/>
</entry>
<entry>
<title>使用jigdo下载ubuntu镜像</title>
<link href="https://kimown.github.io/2016/09/18/%E4%BD%BF%E7%94%A8jigdo%E4%B8%8B%E8%BD%BDubuntu%E9%95%9C%E5%83%8F/"/>
<id>https://kimown.github.io/2016/09/18/使用jigdo下载ubuntu镜像/</id>
<published>2016-09-18T05:32:06.000Z</published>
<updated>2016-09-18T06:42:56.252Z</updated>
<content type="html"><![CDATA[<p> ubuntu14 ISO镜像的增量下载</p>
<a id="more"></a>
<p> 今天在知乎上看到一篇<a href="https://zhuanlan.zhihu.com/p/22383854" target="_blank" rel="external">jigdo增量下载debian的文章</a>,当有老的ISO镜像时,增量下载可以大大的减少下载时间.</p>
<p>jigdo的<a href="http://atterer.org/jigdo/#how" target="_blank" rel="external">官方地址</a>,上面说支持debian和fedora,但是我想要下载的是ubuntu,而且<a href="http://mirrors.aliyun.com/ubuntu-releases/14.04.5/" target="_blank" rel="external">下载页面</a>也有.jigdo文件.</p>
<p>这里我用ubuntu-14.04.4-server-i386.iso和ubuntu-14.04.5-server-i386.iso为例,[下载地址].<br>可以看到,ubuntu-14.04.4-server-i386.iso 大小近583M,ubuntu-14.04.5-server-i386.iso近623M,两个镜像的.jigdo地址是:</p>
<p><a href="http://mirrors.aliyun.com/ubuntu-releases/14.04/ubuntu-14.04.4-server-i386.jigdo" target="_blank" rel="external">http://mirrors.aliyun.com/ubuntu-releases/14.04/ubuntu-14.04.4-server-i386.jigdo</a><br><a href="http://mirrors.aliyun.com/ubuntu-releases/14.04.5/ubuntu-14.04.5-server-i386.jigdo" target="_blank" rel="external">http://mirrors.aliyun.com/ubuntu-releases/14.04.5/ubuntu-14.04.5-server-i386.jigdo</a></p>
<h2 id="安装jigdo"><a href="#安装jigdo" class="headerlink" title="安装jigdo"></a>安装jigdo</h2><figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div></pre></td><td class="code"><pre><div class="line">https://help.ubuntu.com/community/JigdoDownloadHowto</div><div class="line">jigdo-lite</div></pre></td></tr></table></figure>
<p>下载完毕后,是这几个文件.<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">jigdo-file-cache.db ubuntu-14.04.4-server-i386.iso.list ubuntu-14.04.4-server-i386.iso.tmp ubuntu-14.04.4-server-i386.jigdo ubuntu-14.04.4-server-i386.template</div></pre></td></tr></table></figure></p>
<p>恩,jigdo下载ubuntu后没有办法合并,下载失败了.</p>
<p>结论:ubuntu镜像还是使用老办法wget直接http下载吧,如果想要下载debian还是可以用一用jigdo的.</p>
]]></content>
<summary type="html">
<p> ubuntu14 ISO镜像的增量下载</p>
</summary>
<category term="Linux" scheme="https://kimown.github.io/tags/Linux/"/>
</entry>
<entry>
<title>小米max刷国际版</title>
<link href="https://kimown.github.io/2016/09/16/%E5%B0%8F%E7%B1%B3max%E5%88%B7%E5%9B%BD%E9%99%85%E7%89%88/"/>
<id>https://kimown.github.io/2016/09/16/小米max刷国际版/</id>
<published>2016-09-16T04:01:12.000Z</published>
<updated>2016-09-19T02:58:54.329Z</updated>
<content type="html"><![CDATA[<p>MIUI外号ADUI,小米max到手的第一件事刷国际版MIUI,毕竟外国的MIUI比较圆.</p>
<a id="more"></a>
<ul>
<li><a href="http://www.miui.com/unlock/" target="_blank" rel="external">申请解锁</a>,审核成功后会有短信通知</li>
<li><a href="http://www.miui.com/download-315.html" target="_blank" rel="external">由稳定版卡刷MIUI开发板</a>,<a href="http://www.miui.com/shuaji-329.html" target="_blank" rel="external">教程</a></li>
<li><a href="http://www.miui.com/thread-3367802-1-1.html" target="_blank" rel="external">Fastboot解锁</a>,注意要先安装<a href="http://zhushou.xiaomi.com/" target="_blank" rel="external">小米助手</a>,否则解锁工具不识别手机,还有手机上要登陆小米账号</li>
<li>安全中心开启root权限</li>
<li><p>下载<a href="http://en.miui.com/download-302.html" target="_blank" rel="external">国际版ROM包</a>,放到内置存储卡<br>- 安装<a href="http://www.miui.com/thread-4939281-1-1.html" target="_blank" rel="external">Flashify</a>,音量键+&电源键进入 TWRP界面<br>- 双清后安装zip包,重启,如果页面一直是loading状态,在重启一次,然后显示安装的进度条<br>- 当进度条到顶时,ok</p>
</li>
<li><p>下面在刷<a href="http://en.miui.com/thread-293031-1-1.html" target="_blank" rel="external">TWRP</a>,整体思路来自这篇<a href="http://en.miui.com/thread-287609-1-1.html" target="_blank" rel="external">回复</a><br>-<br>-<br>-<br>-<br>-<br>-</p>
</li>
</ul>
<p>References:</p>
<ul>
<li><a href="http://www.miui.com/thread-4939281-1-1.html" target="_blank" rel="external">http://www.miui.com/thread-4939281-1-1.html</a></li>
<li><a href="http://bbs.xiaomi.cn/t-12334298" target="_blank" rel="external">http://bbs.xiaomi.cn/t-12334298</a></li>
<li><a href="http://www.miui.com/thread-4324518-1-1.html" target="_blank" rel="external">http://www.miui.com/thread-4324518-1-1.html</a></li>
<li><a href="http://stackoverflow.com/questions/27017453/fastboot-and-adb-not-working-with-sudo" target="_blank" rel="external">http://stackoverflow.com/questions/27017453/fastboot-and-adb-not-working-with-sudo</a></li>
<li><a href="https://securitycafe.ro/2014/12/16/how-to-install-android-5-0-1-lollipop-on-samsung-galaxy-s4/" target="_blank" rel="external">https://securitycafe.ro/2014/12/16/how-to-install-android-5-0-1-lollipop-on-samsung-galaxy-s4/</a></li>
</ul>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div></pre></td><td class="code"><pre><div class="line">sudo $(which fastboot) devices</div><div class="line">sudo $(which fastboot) flash recovery recovery.img</div><div class="line"></div><div class="line">sudo $(which fastboot) boot recovery.img</div></pre></td></tr></table></figure>
]]></content>
<summary type="html">
<p>MIUI外号ADUI,小米max到手的第一件事刷国际版MIUI,毕竟外国的MIUI比较圆.</p>
</summary>
<category term="Life" scheme="https://kimown.github.io/tags/Life/"/>
</entry>
<entry>
<title>Node后端使用ES7语法</title>
<link href="https://kimown.github.io/2016/09/13/Node%E5%90%8E%E7%AB%AF%E4%BD%BF%E7%94%A8ES7%E8%AF%AD%E6%B3%95/"/>
<id>https://kimown.github.io/2016/09/13/Node后端使用ES7语法/</id>
<published>2016-09-13T11:43:54.000Z</published>
<updated>2016-09-18T06:48:38.700Z</updated>
<content type="html"><![CDATA[<p>前端由于webpack和babel的结合使用,已经可以广泛的使用最新的<a href="https://babeljs.io/docs/learn-es2015/" target="_blank" rel="external">ES6</a>和<a href="http://babeljs.io/docs/plugins/preset-es2017/" target="_blank" rel="external">ES7</a>特性,但是在服务器端,当然可以编写ES6语法,然后通过打包代码到ES5的方式来运行,但是这样做的话会出现问题debug会很麻烦。</p>
<a id="more"></a>
<h2 id="babel-node"><a href="#babel-node" class="headerlink" title="babel-node"></a>babel-node</h2><p> 之前看过f8app导入<a href="https://github.com/fbsamples/f8app/blob/master/scripts/import-data-from-parse.js" target="_blank" rel="external">mongodb数据库</a>的小脚本,里面使用了await和async语法,其实最终是通过使用了<a href="https://babeljs.io/docs/usage/cli/" target="_blank" rel="external">babel-node</a>启动的,但是官方也说明了内存占用高,不适合用于生产环境,但是写写小程序的话极为方便。</p>
<p> 在<a href="https://github.com/babel/babel/releases/tag/v6.14.0" target="_blank" rel="external">babel v6.14.0</a>中,出现了一个新的preset:<a href="https://babeljs.io/docs/plugins/preset-latest/" target="_blank" rel="external">babel-preset-latest</a>,可以解析ES2015, ES2016, ES2017语法,真的是很方便的一个包。</p>
<p>这是babel的使用<a href="http://babeljs.io/docs/plugins/preset-latest/" target="_blank" rel="external">教程</a>,我就用fs模块写了一个小<a href="https://github.com/kimown/gist/tree/master/babel-present-latest/babel-node" target="_blank" rel="external">demo</a>;</p>
<p>由于我使用的是alinode,所以这里还需要给node做一个软链接,否则会报错: /usr/bin/env: node: No such file or directory,解决方法是<a href="http://stackoverflow.com/questions/30281057/node-forever-usr-bin-env-node-no-such-file-or-directory" target="_blank" rel="external">给alinode做一个软连接</a>。<br><figure class="highlight js"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">sudo ln -s <span class="string">"$(which nodejs)"</span> /usr/bin/node</div></pre></td></tr></table></figure></p>
<p>注意这里是双引号,在bash里面单引号和双引号还是有区别的.</p>
<p>现在说下babel-node结合WebStorm进行断点调试的功能,我现在WebStorm的版本是2016.2.2。我的建议是全局安装babel-cli,<br> <figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">npm install --global babel-cli</div></pre></td></tr></table></figure></p>
<p>然后让Node interpreter: 指向全局安装的babel-node的位置:~/.tnvm/versions/alinode/v1.6.0/lib/node_modules/babel-cli/bin/babel-node.js ,然后右键,Debug ‘${File Name}’ 即可。如果全部安装的babel-node的版本和package.json里面的babel-node的版本不一致,那就把Node interpreter: 的路径指向node_modules里面 ${ProjectPath}/node_modules/babel-cli/bin/babel-node.js 的位置。</p>
<h2 id="require-hook"><a href="#require-hook" class="headerlink" title="require-hook"></a>require-hook</h2><p> 另外一种是使用babel提供的require-hook方法,源于我在stackoverflow看到的<a href="http://stackoverflow.com/questions/29170589/debug-nodejs-es6-app-webstorm" target="_blank" rel="external">一篇回复</a>,里面介绍使用引入 ‘babel/register’这个库来debug程序,这篇回复的日期是15年3月份,现在babel官方已经使用babel-register这个新的库来代替,只能说前端发展太迅速了,很多学习的内容转眼间就outdated。</p>
<p> 整体思路来自于<a href="http://stackoverflow.com/a/35002082/5074324" target="_blank" rel="external">这篇回复</a>,但是这个回复不怎么简洁,自己又重新组织了下代码,上面一样又是一个fs的小<a href="https://github.com/kimown/gist/tree/master/babel-present-latest/babel-register" target="_blank" rel="external">demo</a></p>
<p>这篇文章的核心全部在上面两个小demo上,以上,EOF</p>
]]></content>
<summary type="html">
<p>前端由于webpack和babel的结合使用,已经可以广泛的使用最新的<a href="https://babeljs.io/docs/learn-es2015/">ES6</a>和<a href="http://babeljs.io/docs/plugins/preset-es2017/">ES7</a>特性,但是在服务器端,当然可以编写ES6语法,然后通过打包代码到ES5的方式来运行,但是这样做的话会出现问题debug会很麻烦。</p>
</summary>
<category term="Node.js" scheme="https://kimown.github.io/tags/Node-js/"/>
</entry>
<entry>
<title>PyCon2016感想</title>
<link href="https://kimown.github.io/2016/09/10/PyCon2016%E6%84%9F%E6%83%B3/"/>
<id>https://kimown.github.io/2016/09/10/PyCon2016感想/</id>
<published>2016-09-10T14:24:24.000Z</published>
<updated>2016-09-19T02:58:35.625Z</updated>
<content type="html"><![CDATA[<p>第一次知道 Conf大会 这个词是在几个月前cnodejs首页置顶的一篇关于<a href="https://cnodejs.org/topic/575e70ef4a43c1cb159ffe25" target="_blank" rel="external">JSConf China 2016的文章</a>,当时并没有意识到它的意义吧。就这样,前几天的南京的JSConf2016我就万分悲痛的失之交臂了,现在回想,作为一个立志在JavaScript有长远发展的程序员,好心痛。
</p>
<a id="more"></a>
<p>由于家里的一些原因,9月初我离开了南京,仔细算来,其实我也已经工作两年多了,作为一个把大量时间专注于代码事业的程序员,一些想法还是很朴素滴:一线二线城市对我而言,并没有区别,唯一的区别也许就是换个地儿Coding而已,唯一在意的就是工作环境和周围相处的人吧,这一点排第一。在家呆了几天后,毅然踏上了魔都(ZHAO GONG ZUO)之旅。9月7号达到上海,由于是找工作,时间肯定不会拖太长的,就用了airbnb短租到了9月底。其实9月初离开上家公司时,是裸辞的,怎么说呢,虽然相比于南京,上海的工作岗位在数量上,肯定是高于南京的,这一点可以在拉钩或者其他垂直语言论坛的招聘板块,都可以看的出来,但是如果呢,我也不想把找工作这件事变成一场持久战。</p>
<p>昨天是9号星期五,是来魔都这里的第一次面试,面试官是交大本科毕业,技术还是很强的,这一点从面试的几个问题都感觉的出来,也不知道是工作几年了,没问。不过后来,几个nodejs语言的细节问题没答上来,再加上当时让写一个斐波那契数列,我也不怕丢人了,这是我第一次遇到编写这种问题代码的面试,之前写过这个代码,但是在这两年多的工作中,工作中几乎没有写过算法题和类似的编程题。面试前我也没做任何准备,反正我当时也紧张了,一片空白,直接说自己写不出来。无论是当时还是现在,想想这件事,作为一个程序员,还是觉得很是丢脸的。由于这个原因,面试官怀疑我能不能写代码的能力了,定薪也和我的预期不合,就拒绝了。不过最后我还是挺感激他的,起码让我认识到了自身基础的重要性了。<br>回去第一件事,刷书。</p>
<p>这次参加PyCon也是偶然,当天晚上,知道南京原项目组的一个前辈要参加PyCon,我就屁颠屁颠的凑过来了,再加上白天面试对自己的小小打击,就果断报了PyCon2016的名。</p>
<p>其实吧,作为一个python从未写过一行的程序员,我原以为自己应该都听不懂的,但是后来发现了,会议中关于语言细节的描述很少,大多是关于项目的整体思路,其实很多东西,如果换成另外一种高级语言,只考虑实现的话,其他语言都是可以做到的,只是由于代码是由python写的而已。</p>
<p>其实在我现在的水平,觉得最有收货的是新答答的分享:<a href="https://tech.imdada.cn/2015/11/04/%E9%AB%98%E6%80%A7%E8%83%BD%E6%9C%8D%E5%8A%A1%E7%AB%AF%E4%BC%98%E5%8C%96%E4%B9%8B%E8%B7%AF/" target="_blank" rel="external">达达-高性能服务端优化之路</a>,尤其是在应对数据量直线上升的情况下,对mysql的三种处理方法,印象远比其他内容记得牢,在现场听讲和纯看ppt真的有很大差距。</p>
<p>其他我也不评论了,记得之前我了解过V8 gc的内容,所以当时朴零大大做<a href="https://yq.aliyun.com/edu/lesson/play/333" target="_blank" rel="external">alinode的分享</a>时,虽然是大部分是宣传,但是最后的几个对mem cpu的分析,简直醍醐灌顶。很多分享内容里面的核心的可以用简短几句概括,如果讲师讲的内容自己没有演示过,肯定只能看个门道。所以倒是知道了提前了解讲师内容的重要性了,否则参加这些conf大会就纯属聊天听故事了。 </p>
]]></content>
<summary type="html">
<p>第一次知道 Conf大会 这个词是在几个月前cnodejs首页置顶的一篇关于<a href="https://cnodejs.org/topic/575e70ef4a43c1cb159ffe25">JSConf China 2016的文章</a>,当时并没有意识到它的意义吧。就这样,前几天的南京的JSConf2016我就万分悲痛的失之交臂了,现在回想,作为一个立志在JavaScript有长远发展的程序员,好心痛。
</p>
</summary>
<category term="Life" scheme="https://kimown.github.io/tags/Life/"/>
</entry>
<entry>
<title>isp流量劫持</title>
<link href="https://kimown.github.io/2016/09/02/isp%E6%B5%81%E9%87%8F%E5%8A%AB%E6%8C%81/"/>
<id>https://kimown.github.io/2016/09/02/isp流量劫持/</id>
<published>2016-09-02T03:49:57.000Z</published>
<updated>2016-09-19T02:58:12.397Z</updated>
<content type="html"><![CDATA[<p>用chrome搜索关键字时时,经常出现这一种 Did you mean to got {<a href="http://**}" target="_blank" rel="external">http://**}</a> 的提示,超级烦人。</p>
<a id="more"></a>
<p><img src="https://cloud.githubusercontent.com/assets/7932380/18192123/c90a387e-7103-11e6-80c4-d68ceb5e23ec.png" alt=""></p>
<p><img src="https://cloud.githubusercontent.com/assets/7932380/18192171/62fab40e-7104-11e6-9a82-942ff9863cfe.png" alt=""></p>
<p>具体的现象是:在chrome搜索框输入关键字后,搜索框有一端莫名奇妙的提示,点击提示链接后,有很明显的页面跳转行为,然后重定向到一个 悠悠导航 的网站<br><img src="https://cloud.githubusercontent.com/assets/7932380/18192193/a3f87928-7104-11e6-96a1-26432cfddf0c.png" alt=""></p>
<p>根据<a href="https://www.quora.com/How-can-I-get-Chrome-to-stop-asking-Did-you-mean-to-go-to" target="_blank" rel="external">quora</a>和<a href="https://productforums.google.com/forum/#!topic/chrome/LGepU6tPPWs" target="_blank" rel="external">google论坛</a>的两篇讨论的内容,<br>当我搜索 lookup 这个关键词后,chrome会对这个关键字进行以此dns查询。但是,ips运营商会为了展示自定义的错误页面或者广告页面,会返回一个统一的错误的地址。我们使用Node.js的dns模块可以看到错误地址的具体ip。</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">const</span> dns = <span class="built_in">require</span>(<span class="string">'dns'</span>);</div><div class="line"></div><div class="line">dns.lookup(<span class="string">'lookup'</span>, (err, addresses, family) => {</div><div class="line"> <span class="built_in">console</span>.log(<span class="string">'addresses:'</span>, addresses);</div></pre></td></tr></table></figure>
<p><img src="https://cloud.githubusercontent.com/assets/7932380/18192466/10c57022-7107-11e6-9d40-44c96cd0d14d.png" alt="">,从查询结果我们可以看到返回的ip地址是 202.102.110.203 ,当点击 Did you mean to got {<a href="http://**}" target="_blank" rel="external">http://**}</a> 里面的具体链接后,<br>chrome会直接访问这个ip地址,对应上面代码里面dns lookup的查询结果。(但是这个具体的域名 <a href="http://look/" target="_blank" rel="external">http://look/</a> 怎么出来的,没搞清楚,但应该是和ip地址一起返回的??)</p>
<p><img src="https://cloud.githubusercontent.com/assets/7932380/18192500/7507f5fa-7107-11e6-83d6-d8c701aa0984.png" alt="">,看下响应里面的代码,恩,做了代码压缩,一些js方法的使用值得学习下。<br><figure class="highlight html"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div></pre></td><td class="code"><pre><div class="line"><span class="tag"><<span class="name">html</span>></span><span class="tag"><<span class="name">head</span>></span><span class="tag"></<span class="name">head</span>></span><span class="tag"><<span class="name">script</span> <span class="attr">type</span>=<span class="string">"text/javascript"</span>></span><span class="javascript"></span></div><div class="line"><span class="keyword">var</span> sa = <span class="string">"http://202.102.110.207:8080/"</span>; <span class="keyword">var</span> pp = <span class="string">"108&pre="</span>+(<span class="keyword">new</span> <span class="built_in">Date</span>()).getTime();</div><div class="line"><span class="keyword">var</span> s=<span class="built_in">String</span>(<span class="built_in">window</span>.location.href); <span class="keyword">var</span> host=<span class="built_in">escape</span>(s.substring(<span class="number">7</span>,s.indexOf(<span class="string">'/'</span>,<span class="number">7</span>)));</div><div class="line"><span class="keyword">var</span> ref=<span class="built_in">escape</span>(<span class="built_in">document</span>.referrer); <span class="keyword">var</span> su = s+<span class="string">"&host="</span>+host+<span class="string">"&refer="</span>+ref+<span class="string">"&server="</span>+pp;</div><div class="line">s = <span class="built_in">escape</span>(s); <span class="function"><span class="keyword">function</span> <span class="title">loadfr</span>(<span class="params"></span>)</span>{ <span class="built_in">document</span>.getElementById(<span class="string">"fr1"</span>).src = sa+<span class="string">"3.htm?AIMT="</span>+su; }</div><div class="line"><span class="function"><span class="keyword">function</span> <span class="title">refreshPage</span>(<span class="params"></span>)</span>{ <span class="built_in">document</span>.location = sa+<span class="string">"2.htm?AIMT="</span>+su; }</div><div class="line"><span class="keyword">if</span> (self.location == top.location){ <span class="built_in">document</span>.location= sa+<span class="string">"1.htm?AIMT="</span>+su; }</div><div class="line"><span class="keyword">else</span> { refreshPage(); }<span class="tag"></<span class="name">script</span>></span><span class="tag"><<span class="name">frameset</span> <span class="attr">rows</span>=<span class="string">"*,0"</span>></span><span class="tag"><<span class="name">frame</span> <span class="attr">id</span>=<span class="string">"main"</span> <span class="attr">src</span>=<span class="string">""</span>></span></div><div class="line"><span class="tag"><<span class="name">frame</span> <span class="attr">id</span>=<span class="string">"fr1"</span> <span class="attr">src</span>=<span class="string">""</span>></span><span class="tag"></<span class="name">frameset</span>></span><span class="tag"><<span class="name">body</span>></span><span class="tag"></<span class="name">body</span>></span><span class="tag"></<span class="name">html</span>></span></div></pre></td></tr></table></figure></p>
<p><img src="https://cloud.githubusercontent.com/assets/7932380/18192580/2aa62260-7108-11e6-97b6-40c52b4d1e82.png" alt=""></p>
<p>代码里面有一个refreshPage方法,意思是如果是内嵌iframe类型的,会跳转到另外的一个地址,不过这种类型的跳转没见过,不知道在哪种场景会用到。</p>
<p>最后跳转的是类似 <a href="http://202.102.110.207:8080/1.htm?AIMT=http://look/&host=look&refer=&server=108&pre=1472787468116" target="_blank" rel="external">http://202.102.110.207:8080/1.htm?AIMT=http://look/&host=look&refer=&server=108&pre=1472787468116</a> 这样的地址,用postman看下响应,</p>
<p><img src="https://cloud.githubusercontent.com/assets/7932380/18192973/9e289fc6-710b-11e6-81d6-cca098a679d5.png" alt="">.</p>
<p>用curl模拟下浏览器行为,此时后台根据不同请求来源输出不同的响应,这里是302暂时重定向,最终指向的不是长长的带有ip地址的url,而是直接 悠悠导航 的域名。</p>
<p><img src="https://cloud.githubusercontent.com/assets/7932380/18193238/2953c7fe-710e-11e6-82de-fd466a514757.png" alt=""><br> 就是上面看到的 悠悠导航。</p>
<p> 有个问题也没有搞清楚:</p>
<ul>
<li><a href="http://look/" target="_blank" rel="external">http://look/</a> 是怎么出来的</li>
</ul>
<p>最终的解决方案,修改本机的dns,<a href="https://developers.google.com/speed/public-dns/docs/using?csw=1" target="_blank" rel="external">修改方法</a>,其实最好的方法是直接投诉运营商。</p>
]]></content>
<summary type="html">
<p>用chrome搜索关键字时时,经常出现这一种 Did you mean to got {<a href="http://**}">http://**}</a> 的提示,超级烦人。</p>
</summary>
<category term="Life" scheme="https://kimown.github.io/tags/Life/"/>
</entry>
<entry>
<title>reinstall ubuntu14,配置环境</title>
<link href="https://kimown.github.io/2016/08/27/reinstall-ubuntu14-%E9%85%8D%E7%BD%AE%E7%8E%AF%E5%A2%83/"/>
<id>https://kimown.github.io/2016/08/27/reinstall-ubuntu14-配置环境/</id>
<published>2016-08-27T05:56:15.000Z</published>
<updated>2016-08-27T12:15:06.513Z</updated>
<content type="html"><![CDATA[<p>//TODO</p>
<a id="more"></a>
<p>昨天看到了深度看图V1.0,看样子linux下能看的软件又多了一个,由于深度没有提供二进制包,只能自己源码安装,结果被那复杂的依赖关系搞蒙了头,装了它的一堆依赖,结果还是报错,怒摔键盘,不想浪费时间折腾它了。结果今天早上一起来,开机后,发现触摸板失灵,情况是鼠标只悬浮在桌面中央,无论怎么操作都不能移动。网上搜了一堆资料,无果。只能重装下ubuntu系统。</p>
<h2 id="tmux"><a href="#tmux" class="headerlink" title="tmux"></a>tmux</h2><h2 id="vim"><a href="#vim" class="headerlink" title="vim"></a>vim</h2><figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">sudo apt-get install vim</div></pre></td></tr></table></figure>
<h2 id="修改源地址"><a href="#修改源地址" class="headerlink" title="修改源地址"></a>修改源地址</h2><figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div></pre></td><td class="code"><pre><div class="line">sudo mv /etc/apt/sources.list /etc/apt/sources.list.old</div><div class="line">sudo touch /etc/apt/sources.list</div><div class="line"> vi /etc/apt/sources.list</div></pre></td></tr></table></figure>
<p>填入下面内容</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div></pre></td><td class="code"><pre><div class="line">deb http://mirrors.aliyun.com/ubuntu/ trusty main restricted universe multiverse</div><div class="line">deb http://mirrors.aliyun.com/ubuntu/ trusty-security main restricted universe multiverse</div><div class="line">deb http://mirrors.aliyun.com/ubuntu/ trusty-updates main restricted universe multiverse</div><div class="line">deb http://mirrors.aliyun.com/ubuntu/ trusty-proposed main restricted universe multiverse</div><div class="line">deb http://mirrors.aliyun.com/ubuntu/ trusty-backports main restricted universe multiverse</div><div class="line">deb-src http://mirrors.aliyun.com/ubuntu/ trusty main restricted universe multiverse</div><div class="line">deb-src http://mirrors.aliyun.com/ubuntu/ trusty-security main restricted universe multiverse</div><div class="line">deb-src http://mirrors.aliyun.com/ubuntu/ trusty-updates main restricted universe multiverse</div><div class="line">deb-src http://mirrors.aliyun.com/ubuntu/ trusty-proposed main restricted universe multiverse</div><div class="line">deb-src http://mirrors.aliyun.com/ubuntu/ trusty-backports main restricted universe multiverse</div></pre></td></tr></table></figure>
<p>后执行 sudo apt-get update</p>
<h2 id="alinode-cnpm"><a href="#alinode-cnpm" class="headerlink" title="alinode cnpm"></a>alinode cnpm</h2><h2 id="hexo"><a href="#hexo" class="headerlink" title="hexo"></a>hexo</h2><h2 id="搜狗输入法"><a href="#搜狗输入法" class="headerlink" title="搜狗输入法"></a>搜狗输入法</h2><h2 id="chrome"><a href="#chrome" class="headerlink" title="chrome"></a>chrome</h2><h2 id="网易云音乐"><a href="#网易云音乐" class="headerlink" title="网易云音乐"></a>网易云音乐</h2><h2 id="webstorm-idea"><a href="#webstorm-idea" class="headerlink" title="webstorm idea"></a>webstorm idea</h2><h2 id="vmware安装osx虚拟机"><a href="#vmware安装osx虚拟机" class="headerlink" title="vmware安装osx虚拟机"></a>vmware安装osx虚拟机</h2>]]></content>
<summary type="html">
<p>//TODO</p>
</summary>
<category term="Linux" scheme="https://kimown.github.io/tags/Linux/"/>
</entry>
<entry>
<title>修改hexo主题landscape思路</title>
<link href="https://kimown.github.io/2016/08/24/%E4%BF%AE%E6%94%B9hexo%E4%B8%BB%E9%A2%98landscape%E6%80%9D%E8%B7%AF/"/>
<id>https://kimown.github.io/2016/08/24/修改hexo主题landscape思路/</id>
<published>2016-08-24T12:07:36.000Z</published>
<updated>2016-08-26T13:55:39.974Z</updated>
<content type="html"><![CDATA[<p> In all:描述下修改主题landscape文件的思路</p>
<a id="more"></a>
<p> 和有后台的web不一样,静态博客的速度取决于网络、Github Pages托管的静态文件的加载速度,记得有个经典的题目关于在浏览器中输入url到呈现网页过程中发生了什么,quora上有一个<a href="https://www.quora.com/What-are-the-series-of-steps-that-happen-when-an-URL-is-requested-from-the-address-field-of-a-browser" target="_blank" rel="external">回答</a>,大致流程都描述了出来,还有一篇更详细的<a href="http://fex.baidu.com/blog/2014/05/what-happen/" target="_blank" rel="external">文章</a> (擦,居然看到了R大)</p>
<p> 那么,按照quora的回答,优化静态博客的一些思路就显而易见了</p>
<ul>
<li>url尽可能短</li>
<li>预缓存dns查询结果,或者直接将修改hosts将域名和ip对应(本机环境)</li>
<li>如果不考虑到可读性,html 、js、css 等静态资源进行压缩、合并处理</li>
<li>考虑到<a href="https://www.zhihu.com/question/20474326" target="_blank" rel="external">浏览器并发问题</a>,将和博客主体无关的其他资源放置在cdn服务器上,不会上传多余的cookie,但会多出额外的DNS解析时间</li>
<li>使用https代替http</li>
<li>清空无用的引入的文件,例如专注于写博客的话,其他所有和博客无关的东西都可以去除</li>
<li>国内打开github有时会很慢,无解问题</li>
</ul>
<p>这是之前修改landscape的<a href="https://github.com/kimown/blog/blob/d8e0a13f216495abb2a44c3433a6e72be0bb02ab/themes/auto-update-theme-fs.js" target="_blank" rel="external">代码</a>,很槽糕的写法:代码重复度太高、可维护性极差、变量随意定义,只是单纯完成文件的替换功能,根本就没有考虑到以后扩展。</p>
<p>新的思路:</p>
<p>对于修改文件而言,主要两个参数:一是文件地址,统一下使用绝对路径,二是文件替换规则。替换规格可以利用string对象的<a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace" target="_blank" rel="external">repalce()</a>方法,传入一个regexp或被替换的字符串,第二个参数可以是替换的字符串或函数。<br>但是对于一个文本文件而言,没有办法精确到某一行,还需要结合文件的<a href="https://nodejs.org/dist/latest-v4.x/docs/api/os.html#os_os" target="_blank" rel="external">换行符</a>找到指定行,然后在用正则替换,现在linux,mac下是’\n’,window下是’\r\n’,<a href="https://www.zhihu.com/question/46542168" target="_blank" rel="external">详情</a></p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">var</span> a = [{</div><div class="line"> filePath: <span class="string">'/tmp/a.js'</span>,</div><div class="line"> rules: [{line: <span class="string">'number'</span>, old: <span class="string">'reg or substr'</span>, <span class="keyword">new</span>: <span class="string">'newSubStr'</span>}]</div><div class="line">}];</div><div class="line"><span class="built_in">JSON</span>.stringify(a,<span class="literal">null</span>,<span class="number">2</span>);</div></pre></td></tr></table></figure>
<p><a href="https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify#The_space_argument" target="_blank" rel="external">JSON.stringify格式化对象为字符串方法</a></p>
<p>修改内容配置文件是类似下面格式的数据:<br><figure class="highlight json"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div></pre></td><td class="code"><pre><div class="line">[</div><div class="line"> {</div><div class="line"> <span class="attr">"filePath"</span>: <span class="string">"/tmp/a.js"</span>,</div><div class="line"> <span class="attr">"rules"</span>: [</div><div class="line"> {</div><div class="line"> <span class="attr">"line"</span>: <span class="number">233</span>,</div><div class="line"> <span class="attr">"old"</span>: <span class="string">"reg or substr"</span>,</div><div class="line"> <span class="attr">"new"</span>: <span class="string">"newSubStr"</span></div><div class="line"> }</div><div class="line"> ]</div><div class="line"> }</div><div class="line">]</div></pre></td></tr></table></figure></p>
<p>重构后的<a href="https://github.com/kimown/blog/blob/master/themes/auto-update-theme-fs.js" target="_blank" rel="external">代码地址</a> 。</p>
<p>这里没有使用<a href="https://babeljs.io/docs/usage/require/" target="_blank" rel="external">babel-register</a>,而是使用了bebel-node来启动,这样的话既可以使用es6或es7语法,很明显整个代码结构和之前相比清晰明了多了。</p>
]]></content>
<summary type="html">
<p> In all:描述下修改主题landscape文件的思路</p>
</summary>
<category term="Node.js" scheme="https://kimown.github.io/tags/Node-js/"/>
</entry>
<entry>
<title>加快create-react-app的下载速度</title>
<link href="https://kimown.github.io/2016/08/23/%E5%8A%A0%E5%BF%ABcreate-react-app%E7%9A%84%E4%B8%8B%E8%BD%BD%E9%80%9F%E5%BA%A6/"/>
<id>https://kimown.github.io/2016/08/23/加快create-react-app的下载速度/</id>
<published>2016-08-23T10:36:39.000Z</published>
<updated>2016-08-23T15:20:37.857Z</updated>
<content type="html"><![CDATA[<p>修改<a href="https://github.com/facebookincubator/create-react-app" target="_blank" rel="external">create-react-app</a>的安装源为<a href="https://cnpmjs.org/" target="_blank" rel="external">cnpm</a>,加快下载速度.</p>
<a id="more"></a>
<p>我们在命令行使用的<a href="https://github.com/facebookincubator/create-react-app/blob/master/README.md#tldr" target="_blank" rel="external">create-react-app my-app</a>是调用的package.json里面<a href="https://github.com/facebookincubator/create-react-app/blob/master/global-cli/package.json#L17" target="_blank" rel="external">bin的命令</a>,当使用 npm install -g create-react-app 命令后,其实我们安装的的是一个cli工具,就是这个<a href="https://github.com/facebookincubator/create-react-app/blob/master/global-cli/index.js" target="_blank" rel="external">index.js</a>文件,注意这个js文件在首部添加了</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line"><span class="comment">#!/usr/bin/env node</span></div></pre></td></tr></table></figure>
<p>说明它已经是一个可执行文件。</p>
<p>当我们调用 create-react-app my-app 时,会先安装<a href="https://www.npmjs.com/package/react-scripts" target="_blank" rel="external">react-scripts</a>,见<a href="https://github.com/facebookincubator/create-react-app/blob/master/global-cli/index.js#L134" target="_blank" rel="external">134行</a>的</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">var</span> packageToInstall = <span class="string">'react-scripts'</span>;</div></pre></td></tr></table></figure>
<p>然后在<a href="https://github.com/facebookincubator/create-react-app/blob/master/global-cli/index.js#L112" target="_blank" rel="external">112行</a>进行 npm install的命令。</p>
<p>然后,程序执行<a href="https://github.com/facebookincubator/create-react-app/blob/master/scripts/init.js" target="_blank" rel="external">init函数</a>,从<a href="https://github.com/facebookincubator/create-react-app/tree/master/template" target="_blank" rel="external">template目录</a>下的模板文件生成代码后,执行 <a href="https://github.com/facebookincubator/create-react-app/blob/master/scripts/init.js#L79" target="_blank" rel="external">npm</a>安装依赖。</p>
<p>因此,只要在inde.js的<a href="https://github.com/facebookincubator/create-react-app/blob/master/global-cli/index.js#L106" target="_blank" rel="external">106行</a>,init.js的<a href="https://github.com/facebookincubator/create-react-app/blob/master/scripts/init.js#L76" target="_blank" rel="external">76行</a>之后,添加</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">--registry=https://registry.npm.taobao.org</div></pre></td></tr></table></figure>
<p>即可.</p>
<p>由于react-scripts是在创建文件后运行的,这里无法通过修改registry的地址来加快下载速度,如果觉得从npmjs下载react-scripts的依赖很慢,可以直接ctrl+c退出node进程后,直接使用 cnpm i 就可以了</p>
]]></content>
<summary type="html">
<p>修改<a href="https://github.com/facebookincubator/create-react-app">create-react-app</a>的安装源为<a href="https://cnpmjs.org/">cnpm</a>,加快下载速度.</p>
</summary>
<category term="Node.js" scheme="https://kimown.github.io/tags/Node-js/"/>
</entry>
<entry>
<title>openshift使用alinode</title>
<link href="https://kimown.github.io/2016/08/20/openshift%E4%BD%BF%E7%94%A8alinode/"/>
<id>https://kimown.github.io/2016/08/20/openshift使用alinode/</id>
<published>2016-08-20T15:59:05.000Z</published>
<updated>2016-08-21T02:09:41.815Z</updated>
<content type="html"><![CDATA[<p> <a href="https://kimown.github.io/2016/08/13/openshift%E6%90%AD%E5%BB%BA%E5%BA%94%E7%94%A8/">衔接上文</a></p>
<a id="more"></a>
<h2 id="安装alinode"><a href="#安装alinode" class="headerlink" title="安装alinode"></a>安装alinode</h2><p>下面是在openshift里面自定义使用alinode作为启动应用的版本,整体的思路很简单,看了下<a href="https://raw.githubusercontent.com/aliyun-node/tnvm/master/install.sh" target="_blank" rel="external">install.sh</a>的代码,大致意思是在$HOME目录下创建一个.tnvm目录,然后git下载对应的代码,最终运行的tnvm命令在<a href="https://github.com/aliyun-node/tnvm/blob/master/tnvm.sh" target="_blank" rel="external">tnvm.sh</a>。那我们只要把$OPENSHIFT_DATA_DIR目录作为$HOME目录就可以了。</p>
<p><img src="https://cloud.githubusercontent.com/assets/7932380/17834611/9ccd5b24-677b-11e6-8564-fa4b79fc3d0b.png" alt=""></p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div></pre></td><td class="code"><pre><div class="line"><span class="built_in">export</span> HOME=<span class="variable">$OPENSHIFT_DATA_DIR</span></div><div class="line"><span class="built_in">cd</span> <span class="variable">$HOME</span></div><div class="line">wget -O- https://raw.githubusercontent.com/aliyun-node/tnvm/master/install.sh | bash</div><div class="line"><span class="built_in">source</span> <span class="variable">$HOME</span>/.bash_profile</div><div class="line">tnvm ls-remote alinode</div><div class="line">tnvm install alinode-v1.6.0</div></pre></td></tr></table></figure>
<p>注意openshift下载alinode的速度很慢,注意下tnvm.sh <a href="https://github.com/aliyun-node/tnvm/blob/master/tnvm.sh#L467" target="_blank" rel="external">467行</a>和 <a href="https://github.com/aliyun-node/tnvm/blob/master/tnvm.sh#L474" target="_blank" rel="external">474行</a>,这里会针对不同的操作系统下载我们自定义输入的<a href="http://alinode.aliyun.com/dist/new-alinode" target="_blank" rel="external">alinode的版本</a>。<br>下载完毕后,测试下node的版本,更新下npm的版本。</p>
<p><img src="https://cloud.githubusercontent.com/assets/7932380/17834737/a4a852ea-6780-11e6-9f52-012483aedf01.png" alt=""></p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div></pre></td><td class="code"><pre><div class="line">tnvm use alinode-v1.6.0</div><div class="line">node -p <span class="string">'process.alinode'</span></div><div class="line"><span class="built_in">which</span> node</div><div class="line"><span class="built_in">which</span> npm</div><div class="line">npm install npm -g</div><div class="line">npm -v</div></pre></td></tr></table></figure>
<p>node 的目录在$OPENSHIFT_DATA_DIR/.tnvm/versions/alinode/v1.6.0/bin这个目录下。<br>注意 tnvm是通过修改path路径的方法来使用alinode的,但是除$OPENSHIFT_DATA_DIR目录外,我们在openshift上的修改是临时的,所以下次登陆时本次修改会失效,唯一保留的是.tnvm里面的下载的文件</p>
<h2 id="使用alinode"><a href="#使用alinode" class="headerlink" title="使用alinode"></a>使用alinode</h2><p>修改start代码,主要是各个命令的路径问题,如果是VPS的话就没有这么多事了。<br><figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div></pre></td><td class="code"><pre><div class="line"><span class="meta">#!/bin/bash</span></div><div class="line"><span class="comment"># The logic to start up your application should be put in this</span></div><div class="line"><span class="comment"># script. The application will work only if it binds to</span></div><div class="line"><span class="comment"># $OPENSHIFT_DIY_IP:8080</span></div><div class="line"><span class="comment">#nohup $OPENSHIFT_REPO_DIR/diy/testrubyserver.rb $OPENSHIFT_DIY_IP $OPENSHIFT_REPO_DIR/diy |& /usr/bin/logshifter -tag diy &</span></div><div class="line"></div><div class="line"></div><div class="line"><span class="built_in">export</span> ALINODEPATH=<span class="variable">$OPENSHIFT_DATA_DIR</span>/.tnvm/versions/alinode/v1.6.0</div><div class="line"><span class="built_in">export</span> PATH=<span class="variable">$ALINODEPATH</span>/bin:<span class="variable">$PATH</span></div><div class="line"></div><div class="line"><span class="built_in">export</span> npm_config_cache=<span class="variable">$OPENSHIFT_REPO_DIR</span>/diy/.npm</div><div class="line"><span class="built_in">export</span> npm_config_userconfig=<span class="variable">$OPENSHIFT_REPO_DIR</span>/diy/.npmrc</div><div class="line"></div><div class="line"></div><div class="line"><span class="built_in">source</span> <span class="variable">$OPENSHIFT_DATA_DIR</span>/.bash_profile</div><div class="line">tnvm use alinode-v1.6.0</div><div class="line"><span class="built_in">echo</span> $(node -v)</div><div class="line"></div><div class="line"><span class="built_in">cd</span> <span class="variable">$OPENSHIFT_REPO_DIR</span>/diy</div><div class="line">npm install</div><div class="line">nohup node <span class="variable">$OPENSHIFT_REPO_DIR</span>/diy/index.js &</div></pre></td></tr></table></figure></p>
<p><img src="https://cloud.githubusercontent.com/assets/7932380/17834822/c38bc382-6784-11e6-8034-d575334da976.png" alt=""></p>
<p>红框里面是 tnvm.sh<a href="https://github.com/aliyun-node/tnvm/blob/master/tnvm.sh#L755" target="_blank" rel="external">755行</a>,$HOME和$OPENSHIFT_DATA_DIR不相等导致的,一个办法是直接修改tnvm.sh里面的$HOME目录为$OPENSHIFT_DATA_DIR,但不修改的话也不影响使用。<br>下面是使用alinode的版本,对应上面代码16行,然后 echo $(node -v) 打印出alinode对应的node的版本号,对应上面代码17行,<a href="https://alinode.aliyun.com/doc/alinode_versions" target="_blank" rel="external">详细对应版本参考</a></p>
<p>如果出现下面的输出,说明代码已经成功运行在openshift上面了<br><img src="https://cloud.githubusercontent.com/assets/7932380/17834865/6cabb746-6786-11e6-9574-c8e52d4b8f68.png" alt=""></p>
<p>打开<a href="https://node-kimown.rhcloud.com/" target="_blank" rel="external">https://node-kimown.rhcloud.com/</a>,输出结果<br><img src="https://cloud.githubusercontent.com/assets/7932380/17834872/ccd07fe4-6786-11e6-80df-043a2bbf9e48.png" alt=""><br>对应 <a href="https://kimown.github.io/2016/08/13/openshift%E6%90%AD%E5%BB%BA%E5%BA%94%E7%94%A8/">openshift搭建应用</a>里面express的代码<br><img src="https://cloud.githubusercontent.com/assets/7932380/17834883/349beed8-6787-11e6-9340-2e8ac430af12.png" alt=""></p>
<p>EOF</p>
]]></content>
<summary type="html">
<p> <a href="https://kimown.github.io/2016/08/13/openshift%E6%90%AD%E5%BB%BA%E5%BA%94%E7%94%A8/">衔接上文</a></p>
</summary>
<category term="Node.js" scheme="https://kimown.github.io/tags/Node-js/"/>
</entry>
<entry>
<title>译-一个有趣的JavaScript内存泄露情况</title>
<link href="https://kimown.github.io/2016/08/16/%E8%AF%91-%E4%B8%80%E4%B8%AA%E6%9C%89%E8%B6%A3%E7%9A%84JavaScript%E5%86%85%E5%AD%98%E6%B3%84%E9%9C%B2%E6%83%85%E5%86%B5/"/>
<id>https://kimown.github.io/2016/08/16/译-一个有趣的JavaScript内存泄露情况/</id>
<published>2016-08-16T14:07:21.000Z</published>
<updated>2016-08-16T14:24:01.970Z</updated>
<content type="html"><![CDATA[<p>原文: <a href="http://info.meteor.com/blog/an-interesting-kind-of-javascript-memory-leak" target="_blank" rel="external">http://info.meteor.com/blog/an-interesting-kind-of-javascript-memory-leak</a></p>
<pre><code>//TODO
</code></pre> <a id="more"></a>
<p>最近, Avi和David在追踪一个在Metror实时HTML模板渲染系统的内存泄露问题。这将会在0.6.5 release版本修复(现在QA的最后阶段)</p>
<p>我在网上用 javascript闭包内存泄露作为关键词搜索,结果没找到任何相关的信息,所以看起来是JavaScript上下文的一个相对少见的问题。(所能查找到的信息,大多关于在IE老版本中糟糕的GC算法,但是这个问题却影响我现在安装的所以Chrome浏览器)。<br>之后我找到了一个由V8开发者的<a href="http://mrale.ph/blog/2012/09/23/grokking-v8-closures-for-fun.html" target="_blank" rel="external">文章</a>,但看起来现在大部分JavaScript开发者并不知道他们需要小心这个问题。</p>
<p>JavaScript是一个函数编程语言,它的函数都是封闭的:函数对象可以接触到它们作用域里面的变量,即使这个作用域结束了。</p>
]]></content>
<summary type="html">
<p>原文: <a href="http://info.meteor.com/blog/an-interesting-kind-of-javascript-memory-leak">http://info.meteor.com/blog/an-interesting-kind-of-javascript-memory-leak</a></p>
<pre><code>//TODO
</code></pre>
</summary>
<category term="译" scheme="https://kimown.github.io/tags/%E8%AF%91/"/>
</entry>
<entry>
<title>译:理解GC,解决Node.js内存泄露问题</title>
<link href="https://kimown.github.io/2016/08/14/%E8%AF%91-%E7%90%86%E8%A7%A3GC%EF%BC%8C%E8%A7%A3%E5%86%B3Node-js%E5%86%85%E5%AD%98%E6%B3%84%E9%9C%B2%E9%97%AE%E9%A2%98/"/>
<id>https://kimown.github.io/2016/08/14/译-理解GC,解决Node-js内存泄露问题/</id>
<published>2016-08-14T13:42:38.000Z</published>
<updated>2016-09-02T13:35:15.034Z</updated>
<content type="html"><![CDATA[<p>原文: <a href="http://apmblog.dynatrace.com/2015/11/04/understanding-garbage-collection-and-hunting-memory-leaks-in-node-js" target="_blank" rel="external">http://apmblog.dynatrace.com/2015/11/04/understanding-garbage-collection-and-hunting-memory-leaks-in-node-js</a></p>
<pre><code>//TODO
</code></pre> <a id="more"></a>
<p>无论何时Node.js总有一个负面新闻,通常与Node.js的性能问题有关。这不意味着和其他技术相比,Node.js更容易产生问题,作为一个开发者,我们必须要知道Node.js是怎么工作的。<br>虽然Node.js的相关技术有十分平滑的学习曲线,但是使Node.js运转的机器却十分复杂,你必须提前了解这些内容以避免踏入性能陷阱。如果使用Node.js的过程中发生了问题,你需要知道怎样迅速的解决它。</p>
<p>在这篇文章中,我将要介绍Node.js怎样管理内存,怎样追踪定位内存相关问题。和其他类似PHP的平台不同,Node.js应用是长时间运行的线程。当然这个特性拥有很多优点,例如只建立一次数据库连接,然后在之后所有的请求里面复用,当然这样可能会引起其他问题。但是首先,让我们介绍一些Node.js的基础知识。</p>
<p><img src="http://apmblog.dynatrace.com/wp-content/uploads/2015/11/DK_1.png" alt=""></p>
<blockquote>
<p>一个在奥地利的垃圾收集车</p>
</blockquote>
<h2 id="Node-js是被V8控制的C-程序"><a href="#Node-js是被V8控制的C-程序" class="headerlink" title="Node.js是被V8控制的C++程序"></a>Node.js是被V8控制的C++程序</h2><p><a href="https://developers.google.com/v8/" target="_blank" rel="external">Google V8</a>起初是用于Google Chrome的JavaScript引擎,但是它也可以独立使用。这使得V8特别适合用于Node.js,并且成为Node.js平台上唯一深入理解JavaScript的一部分。V8将JavaScript编译机器码后执行。执行期间,V8会分配和释放不必要的内存。这意味着如果我们讨论Node.js中的内存管理,那就是我们在讨论V8的原因。</p>
<p>请阅读<a href="https://developers.google.com/v8/get_started" target="_blank" rel="external">这篇文章</a>,里面包含了一个从C++角度怎样使用V8的案例,</p>
<h2 id="V8的内存模式"><a href="#V8的内存模式" class="headerlink" title="V8的内存模式"></a>V8的内存模式</h2><p>一个运行中的程序总是通过分配在内存里面空间表现的。这个空间称为<em>Resident Set</em>(实际使用物理内存).V8使用了类似Java虚拟机的相同的模式,那就是将内存分代。</p>
<ul>
<li>代码:执行的实际代码</li>
<li>栈:包含所有的数据类型(例如整型integer和布尔型Boolean等基本类型),以及指向堆内对象的指针,还有定义程序控制流的指针</li>
<li>堆:一个被用于存储引用类型,例如对象objects,字符串strings和闭包closures的内存块</li>
</ul>
<p><img src="http://apmblog.dynatrace.com/wp-content/uploads/2015/11/DK_2.png" alt=""></p>
<blockquote>
<p>V8的内存模式</p>
</blockquote>
<p>在Node.js里面,可以很轻易的调用<a href="https://nodejs.org/api/process.html#process_process_memoryusage" target="_blank" rel="external">process.memoryUsage()</a>方法来查询内存使用情况。</p>
<p>这个函数会返回一个对象,包含:</p>
<ul>
<li>Resident Set Size 实际使用物理内存</li>
<li>Total Size of the Heap 所有的堆内存</li>
<li>Heap actually Used 已使用的堆内存</li>
</ul>
<p>我们可以使用这个函数来记录内存的使用情况,然后创建一个图表,很完美的展示V8的内存管理是怎么工作的</p>
<p><img src="http://apmblog.dynatrace.com/wp-content/uploads/2015/11/DK_32.png" alt=""></p>
<blockquote>
<p>过去一段时间Node.js的内存管理情况</p>
</blockquote>
<p>我们可以看到,已使用堆内存是很不确定的,但是始终维持着一个恒定的界线,来保证平均值是一个常量。这个分配、释放堆内存的机制称之为<em>garbage collection</em>(垃圾回收).</p>
<h2 id="深入垃圾回收"><a href="#深入垃圾回收" class="headerlink" title="深入垃圾回收"></a>深入垃圾回收</h2><p>所有程序都会使用内存,这就需要一个保存和释放内存的机制。在C和C++中,例如下面的例子所展示的,是通过<em>malloc()</em>和<em>free()</em>函数来实现的。</p>
<p>我们都知道作为一个程序员,有必要是释放不再使用的堆内存.如果一个程序一直分配内存,但却不释放,堆内存会一直增长,直到可用的内存被消耗殆尽,引起程序崩溃。我们称之为内存泄露。</p>
<p>在上文我们谈到,在Node.js中,V8会将JavaScript编译成机器码,编译出来的机器码的数据结构和它的原始表达语句没有什么关系,并且这些机器码完全是由V8管理的。<br>这就是在JavaScript中我们不能主动分配、释放内存的原因。V8使用一个广为人知的机制来解决这个问题:垃圾回收。</p>
<p>GC背后的理论十分简单:如果一个内存块不再被任何地方引用,我们就可以假设它不会被使用,因此可以被释放掉。但是,检索和维护这些信息却十分复杂,因为实际情况下,它可能是链式引用,或者从一个复杂的图形结构间接引用。</p>
<p><img src="http://apmblog.dynatrace.com/wp-content/uploads/2015/11/memory_graph.png" alt=""></p>
<blockquote>
<p>堆图。只有当红色对象没有任何引用时,它才可以被释放</p>
</blockquote>
<p>GC是相当昂贵的过程,因为它会中断程序的执行,自然而然的这会影响到程序性能。为了改善这个情况,V8使用了两种不同的GC策略:<br>(PS:这里可参考朴灵大大的《深入浅出Node.js》第05章:内存控制)</p>
<ul>
<li>Scavenge ,速度快,但不完全</li>
<li>Mark-Sweep,相对慢,但是会释放掉所有没有引用的内存</li>
</ul>
<p>一个非常精彩的关于V8 GC的信息,<a href="http://jayconrod.com/posts/55/a-tour-of-v8-garbage-collection" target="_blank" rel="external">点击这里</a></p>
<p>再次查看我们从process.memoryUsage() 收集到的数据,我们可以很清晰的辨别出不同的GC策略:锯齿状的模式是由Scavenge运行产生的,断崖式的下降是由Mark-Sweep运行产生的。</p>
<p>通过使用原生模块<a href="https://github.com/bretcope/node-gc-profiler" target="_blank" rel="external">node-gc-profiler</a>我们可以收集到更多关于GC运行的消息。这个模块会订阅V8触发GC的事件,然后将这些信息暴露给JavaScript.</p>
<p>返回的对象会显示GC类型和持续时间。同样,我们可以很容易将这些信息用图表表示,来更好的理解V8怎么工作的。</p>
<p><img src="http://apmblog.dynatrace.com/wp-content/uploads/2015/11/DK_5-1024x463.png" alt=""></p>
<blockquote>
<p>GC运行的持续时间和频率</p>
</blockquote>
<p>我们可以看到Scavenge Compact比Mark-Sweep运行更频繁。取决于程序的复杂度,持续时间也会发生变化。有趣的是,上面的图表也展示了 Mark-Sweep运行频繁,时间相对简短,这个功能是我之前没有确定的。</p>
<h2 id="当糟糕的事情发生后"><a href="#当糟糕的事情发生后" class="headerlink" title="当糟糕的事情发生后"></a>当糟糕的事情发生后</h2><p>如果GC清理内存,是不是意味着我们根本不用关心内存的使用?实际上,仍然可能并且很简单的就可以模拟在你的日志突然发生的内存泄露现象。</p>
<p><img src="http://apmblog.dynatrace.com/wp-content/uploads/2015/11/DK_6-1024x476.png" alt=""></p>
<blockquote>
<p>内存泄露引起的异常</p>
</blockquote>
<p>引用我们之前介绍的图表,我们可以看到内存使用在在不断上升</p>
<p><img src="http://apmblog.dynatrace.com/wp-content/uploads/2015/11/DK_7-1024x524.png" alt=""></p>
<blockquote>
<p>在程序中的内存泄露情况</p>
</blockquote>
<p>GC每次运行时,会尽可能的释放掉内存,但是每次GC运行后,我们可以看到内存使用还在持续上升,这是内存泄露的显著标志。这些指标都是异常检测的一个很好的起点,在讨论怎么追踪内存泄露的问题,首先让我们回顾下怎么构造出内存泄露。</p>
<h2 id="构造泄露"><a href="#构造泄露" class="headerlink" title="构造泄露"></a>构造泄露</h2><p>一些泄露情况是很显而易见的,例如在进程的全局变量上存储数据,一个简单的例子是在一个数组中存储每次访问者的IP地址。而其他的一些问题更隐蔽,例如著名的<a href="https://www.joyent.com/blog/walmart-node-js-memory-leak" target="_blank" rel="external"> Walmart memory leak</a>,它是由于在Node.js核心代码里面缺失语句导致的,然后花费了数周的时间来追踪它。</p>
<p>我不想在这里谈论核心代码的错误。相反,让我们构造一个在你自己JavaScript代码里很容易复现但是很难追踪的内存泄露问题,这是我在<a href="http://info.meteor.com/blog/an-interesting-kind-of-javascript-memory-leak" target="_blank" rel="external">Meteor’s blog</a>找到的。</p>
<p><img src="http://apmblog.dynatrace.com/wp-content/uploads/2015/11/DK_8-1024x631.png" alt=""></p>
<blockquote>
<p>在你自己的代码中重现泄露问题</p>
</blockquote>
<p>第一眼看来,代码都是OK的。我们都认为每次调用replaceThing方法,theThing这个变量都会被覆盖。问题是someMethod方法拥有自己的作用域作为上下文。这意味着unused()方法在someMethod()内部是可以访问的,尽管unused()方法没有被调用,但是它<br>阻止了GC回收originalThing对象。这里由于有太多间接引用,很难定位查找问题。这并不是一个bug,但是它会造成一个难以追查的内存泄露问题。</p>
<p>所以,如果我们可以深入了解到堆里面的情况就好了?幸运的是,可以。V8提供了一个导出堆情况的方法,V8-profiler把这个功能暴露给了JavaScript.</p>
<p>这个简单的模块在内存使用持续上升的情况下导出堆快照。当然,还有一些其他复杂的方法来侦测异常情况,但是,从我们的目的而言,它已经足够了。如果有一次内存泄露,你最后会有多个这样的快照文件。所以你需要仔细监测这些,并给这些模块添加一些警报功能。chrome同样带有分析堆快照的功能,<br>你可以使用chrome开发者工具分析V8。</p>
<p><img src="http://apmblog.dynatrace.com/wp-content/uploads/2015/11/DK_91-1024x670.png" alt=""></p>
<blockquote>
<p>Chrome开发者工具</p>
</blockquote>
<p>一个堆快照文件并不一定能帮助到你,因为它不能随时间变化展示堆的变化情况。这就是chrome开发者工具允许你比较不同堆快照的原因。通过比较两个堆快照,我们可以找到哪种结构在增长。</p>
<p><img src="http://apmblog.dynatrace.com/wp-content/uploads/2015/11/DK_10-1024x679.png" alt=""></p>
<blockquote>
<p>堆快照的比较展示了内存泄露</p>
</blockquote>
<p>这里我们遇到了一个问题。一个叫longStr的变量包含了一大串星号,它被originalThing引用,originalThing被一些方法引用,这个方法又被….引用。好吧,明白了,这个很长路径的嵌套引用和闭包作用域阻止了longStr被垃圾回收。</p>
<p>1.定时创建一些堆文件,期间要有内存的分配<br>2.比较一些快照文件,找到是什么在增长</p>
]]></content>
<summary type="html">
<p>原文: <a href="http://apmblog.dynatrace.com/2015/11/04/understanding-garbage-collection-and-hunting-memory-leaks-in-node-js">http://apmblog.dynatrace.com/2015/11/04/understanding-garbage-collection-and-hunting-memory-leaks-in-node-js</a></p>
<pre><code>//TODO
</code></pre>
</summary>
<category term="译" scheme="https://kimown.github.io/tags/%E8%AF%91/"/>
</entry>
<entry>
<title>openshift搭建应用</title>
<link href="https://kimown.github.io/2016/08/13/openshift%E6%90%AD%E5%BB%BA%E5%BA%94%E7%94%A8/"/>
<id>https://kimown.github.io/2016/08/13/openshift搭建应用/</id>
<published>2016-08-13T03:08:05.000Z</published>
<updated>2016-08-20T15:58:21.641Z</updated>
<content type="html"><![CDATA[<p>恩,最后感谢openshift,aliyun友情提供。</p>
<a id="more"></a>
<h2 id="创建应用"><a href="#创建应用" class="headerlink" title="创建应用"></a>创建应用</h2><p>首先在openshift上添加一个应用,然后选择自定义应用。<br><img src="https://cloud.githubusercontent.com/assets/7932380/17831726/7a94b83e-6723-11e6-9c5c-5a800d06cba6.png" alt=""><br><img src="https://cloud.githubusercontent.com/assets/7932380/17831733/b200f198-6723-11e6-9e02-49d27825b7a3.png" alt=""><br>修改Public URL的为自定义的名字,然后点击Create Application,注意下这里创建的速度的很慢,一个字:等<br><img src="https://cloud.githubusercontent.com/assets/7932380/17831740/0c8acf8a-6724-11e6-9f81-14307bd6df6f.png" alt=""></p>
<h2 id="上传代码"><a href="#上传代码" class="headerlink" title="上传代码"></a>上传代码</h2><p>创建应用完毕后,按照页面指示clone,添加一个package.json文件,commit,push一份demo代码到openshift.<br><figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div></pre></td><td class="code"><pre><div class="line">git <span class="built_in">clone</span> ssh://<span class="variable">${YOUR CUSTOM PATH}</span>/~/git/node.git/</div><div class="line"><span class="built_in">cd</span> node/</div><div class="line">npm init -y</div><div class="line">git add package.json</div><div class="line">git commit -m <span class="string">'My changes'</span></div><div class="line">git push</div></pre></td></tr></table></figure></p>
<p><img src="https://cloud.githubusercontent.com/assets/7932380/17831789/8cc6c0c2-6725-11e6-9c0b-73b8c1366964.png" alt=""><br>此时页面是这样,注意页面html源代码在diy目录下的index.html<br><img src="https://cloud.githubusercontent.com/assets/7932380/17831799/fd2a0536-6725-11e6-9a1f-ad16cafc71a9.png" alt=""></p>
<h2 id="创建一个express应用"><a href="#创建一个express应用" class="headerlink" title="创建一个express应用"></a>创建一个express应用</h2><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div></pre></td><td class="code"><pre><div class="line">cd diy/</div><div class="line">npm i ejs --save</div><div class="line">npm i express --save</div><div class="line">touch index.js</div></pre></td></tr></table></figure>
<p>index.js的代码是<br><figure class="highlight js"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div><div class="line">28</div><div class="line">29</div><div class="line">30</div><div class="line">31</div><div class="line">32</div><div class="line">33</div><div class="line">34</div></pre></td><td class="code"><pre><div class="line"><span class="comment">/**</span></div><div class="line"> * Created by kimown on 16-8-13.</div><div class="line"> */</div><div class="line"></div><div class="line"><span class="keyword">var</span> express = <span class="built_in">require</span>(<span class="string">'express'</span>);</div><div class="line"><span class="keyword">var</span> app = express();</div><div class="line"><span class="keyword">var</span> pkgjson = <span class="built_in">require</span>(<span class="string">'./package.json'</span>);</div><div class="line">app.set(<span class="string">'port'</span>, (process.env.PORT || <span class="number">5000</span>));</div><div class="line"></div><div class="line">app.use(express.static(__dirname + <span class="string">'/public'</span>));</div><div class="line"></div><div class="line"><span class="comment">// views is directory for all template files</span></div><div class="line">app.set(<span class="string">'views'</span>, __dirname + <span class="string">'/views'</span>);</div><div class="line">app.set(<span class="string">'view engine'</span>, <span class="string">'ejs'</span>);</div><div class="line"></div><div class="line">app.get(<span class="string">'/'</span>, <span class="function"><span class="keyword">function</span>(<span class="params">request, response</span>) </span>{</div><div class="line"> response.json({</div><div class="line"> alinode:process.alinode,</div><div class="line"> version:process.version,</div><div class="line"> pkgjson:pkgjson.name</div><div class="line"> });</div><div class="line">});</div><div class="line"></div><div class="line"></div><div class="line"></div><div class="line"><span class="comment">// Get the environment variables we need.</span></div><div class="line"><span class="keyword">var</span> ipaddr = process.env.OPENSHIFT_DIY_IP||<span class="string">'127.0.0.1'</span>;</div><div class="line"><span class="keyword">var</span> port = process.env.OPENSHIFT_DIY_PORT || <span class="number">8080</span>;</div><div class="line"></div><div class="line"></div><div class="line"><span class="comment">// And start the app on that interface (and port).</span></div><div class="line">app.listen(port, ipaddr, <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>{</div><div class="line"> <span class="built_in">console</span>.log(<span class="string">'%s: Node (version: %s) %s started on %s:%d ...'</span>, <span class="built_in">Date</span>(<span class="built_in">Date</span>.now() ), process.version, process.argv[<span class="number">1</span>], ipaddr, port);</div><div class="line">});</div></pre></td></tr></table></figure></p>
<p>这里的代码逻辑很简单,主要是读取openshift预设值的环境变量得到ip和port,然后打印出node的版本,可以使用 node index.js 本地查看。</p>
<h2 id="hook-openshift启动应用进程"><a href="#hook-openshift启动应用进程" class="headerlink" title="hook openshift启动应用进程"></a>hook openshift启动应用进程</h2><p>在<a href="https://blog.openshift.com/a-paas-that-runs-anything-http-getting-started-with-diy-applications-on-openshift/" target="_blank" rel="external">这篇文章</a>,介绍了如何启动应用的过程,是通过使用.openshift/action_hooks目录下start和stop两个可执行文件实现启动应用,停止应用的,里面没有什么神秘的,里面都是预设置的shell脚本文件。</p>
<p>依葫芦画瓢修改两个可执行文件<br>start<br><figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div></pre></td><td class="code"><pre><div class="line"><span class="meta">#!/bin/bash</span></div><div class="line"><span class="comment"># The logic to start up your application should be put in this</span></div><div class="line"><span class="comment"># script. The application will work only if it binds to</span></div><div class="line"><span class="comment"># $OPENSHIFT_DIY_IP:8080</span></div><div class="line"><span class="comment">#nohup $OPENSHIFT_REPO_DIR/diy/testrubyserver.rb $OPENSHIFT_DIY_IP $OPENSHIFT_REPO_DIR/diy |& /usr/bin/logshifter -tag diy &</span></div><div class="line">npm install</div><div class="line">nohup node <span class="variable">$OPENSHIFT_REPO_DIR</span>/index.js &</div></pre></td></tr></table></figure></p>
<p>stop<br><figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div></pre></td><td class="code"><pre><div class="line"><span class="meta">#!/bin/bash</span></div><div class="line"><span class="built_in">source</span> <span class="variable">$OPENSHIFT_CARTRIDGE_SDK_BASH</span></div><div class="line"></div><div class="line"><span class="comment"># The logic to stop your application should be put in this script.</span></div><div class="line"><span class="comment">#if [ -z "$(ps -ef | grep testrubyserver.rb | grep -v grep)" ]</span></div><div class="line"><span class="comment">#then</span></div><div class="line"><span class="comment"># client_result "Application is already stopped"</span></div><div class="line"><span class="comment">#else</span></div><div class="line"><span class="comment"># kill `ps -ef | grep testrubyserver.rb | grep -v grep | awk '{ print $2 }'` > /dev/null 2>&1</span></div><div class="line"><span class="comment">#fi</span></div><div class="line"></div><div class="line"></div><div class="line"><span class="keyword">if</span> [ -z <span class="string">"<span class="variable">$(ps -ef | grep index.js | grep -v grep)</span>"</span> ]</div><div class="line"><span class="keyword">then</span></div><div class="line"> client_result <span class="string">"Application is already stopped"</span></div><div class="line"><span class="keyword">else</span></div><div class="line"> <span class="built_in">kill</span> `ps -ef | grep index.js | grep -v grep | awk <span class="string">'{ print $2 }'</span>` > /dev/null 2>&1</div><div class="line"><span class="keyword">fi</span></div></pre></td></tr></table></figure></p>
<p>注意这里我们需要设置npm的位置,因为在openshift里面,我们没有root权限,唯一可以持久化文件的目录是$OPENSHIFT_DATA_DIR这个目录,如果想在其他目录操作会报权限不足这个错误,详细的各个环境变量的文档,<a href="https://developers.openshift.com/managing-your-applications/environment-variables.html" target="_blank" rel="external">点击这里</a>.<br><img src="https://cloud.githubusercontent.com/assets/7932380/17832039/89ceafa4-672c-11e6-9b33-f5cfc123b232.png" alt=""><br><img src="https://cloud.githubusercontent.com/assets/7932380/17832137/58500688-672e-11e6-98ac-f08b35bfd956.png" alt=""></p>
<p>所以,start文件需要修改,指定npm的一些目录,在<a href="https://docs.npmjs.com/files/npmrc" target="_blank" rel="external">npm文档</a>描述了,.npmrc文件的4种位置,<br>那我们在package.json目录下创建.npmrc和.npm文件就可以避免没有权限问题了。<br>start修改如下<br><figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div></pre></td><td class="code"><pre><div class="line"><span class="meta">#!/bin/bash</span></div><div class="line"><span class="comment"># The logic to start up your application should be put in this</span></div><div class="line"><span class="comment"># script. The application will work only if it binds to</span></div><div class="line"><span class="comment"># $OPENSHIFT_DIY_IP:8080</span></div><div class="line"><span class="comment">#nohup $OPENSHIFT_REPO_DIR/diy/testrubyserver.rb $OPENSHIFT_DIY_IP $OPENSHIFT_REPO_DIR/diy |& /usr/bin/logshifter -tag diy &</span></div><div class="line"></div><div class="line"></div><div class="line"><span class="built_in">export</span> npm_config_cache=<span class="variable">$OPENSHIFT_REPO_DIR</span>/diy/.npm</div><div class="line"><span class="built_in">export</span> npm_config_userconfig=<span class="variable">$OPENSHIFT_REPO_DIR</span>/diy/.npmrc</div><div class="line"></div><div class="line"><span class="built_in">cd</span> <span class="variable">$OPENSHIFT_REPO_DIR</span>/diy</div><div class="line">npm install</div><div class="line">nohup node <span class="variable">$OPENSHIFT_REPO_DIR</span>/index.js &</div></pre></td></tr></table></figure></p>
<p><img src="https://cloud.githubusercontent.com/assets/7932380/17832233/5c0e9ad0-6730-11e6-8c8b-d5c5920decc0.png" alt=""><br>这里可以看到是由于node自身的版本太低了,ejs找不到对应可用的版本,那只能使用自定义node的版本了,下面一篇文章我会讲到使用alinode来启动应用.</p>
]]></content>
<summary type="html">
<p>恩,最后感谢openshift,aliyun友情提供。</p>
</summary>
<category term="Node.js" scheme="https://kimown.github.io/tags/Node-js/"/>
</entry>
<entry>
<title>移动web蒙层下滚动问题</title>
<link href="https://kimown.github.io/2016/08/09/%E7%A7%BB%E5%8A%A8web%E8%92%99%E5%B1%82%E4%B8%8B%E6%BB%9A%E5%8A%A8%E9%97%AE%E9%A2%98/"/>
<id>https://kimown.github.io/2016/08/09/移动web蒙层下滚动问题/</id>
<published>2016-08-09T05:30:36.000Z</published>
<updated>2016-08-13T02:35:21.450Z</updated>
<content type="html"><![CDATA[<p>移动web上,当页面弹出蒙层时,如果用户在蒙层上面滑动,会导致蒙层下面body的滚动,配合使用css和js解决问题。</p>
<a id="more"></a>
<p>先说下解决问题使用的关键词吧,移动web 蒙层 滚动 - Google Search,找到了<br><a href="https://segmentfault.com/q/1010000003075681" target="_blank" rel="external">javascript - 移动端禁止遮罩层以下屏幕滑动 - SegmentFault</a>这篇文章,它直接给出了解决问题的思路。</p>
<blockquote>
<p> <br>就让页面fixed住,然后在点击事件触发的时候获取window的offsetTop,然后设置成负值赋给页面元素</p>
</blockquote>
<p>然后<a href="http://www.jianshu.com/p/29d0fe0e7c4c" target="_blank" rel="external">这篇文章</a>给出了使用overflow和position属性解决滑动问题,但是这里没有提到fixed属性会滑动到页面顶部的问题。</p>
<p>position fixed scroll to top - Google Search找到了<a href="http://stackoverflow.com/questions/20230435/prevent-page-scrolling-to-top-upon-adding-fixed-position" target="_blank" rel="external">javascript - Prevent page scrolling to top upon adding fixed position - Stack Overflow</a><br>,最佳答案是使用top属性固定住页面的方法。</p>
<figure class="highlight html"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line"><span class="tag"><<span class="name">div</span> <span class="attr">class</span>=<span class="string">"main"</span> <span class="attr">style</span>=<span class="string">"position: fixed; top: -400px"</span>></span><span class="tag"></<span class="name">div</span>></span></div></pre></td></tr></table></figure>
<p>最后的解决方案:<br>当用户点击按钮时,通过document.body.scrollTop属性获取当前页面滚动位置scrollTop,在body元素上将position置为fixed,overflow置为hidden,然后,将当前页面滚动位置scrollTop为负值赋给top属性,这样的话避免了页面滑动问题。<br>当用户点击蒙层时,取消原先给body的所有赋值,同时将页面滑动到原先的scrollTop位置上。</p>
<p>下面是<a href="http://sandbox.runjs.cn/show/lsyqlilo" target="_blank" rel="external">实例地址</a>,chrome快捷键CTRL+Shift+I打开mobile调试模式</p>
<p>代码:<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div></pre></td><td class="code"><pre><div class="line"><span class="function"><span class="keyword">function</span> <span class="title">say_hello</span>(<span class="params"></span>) </span>{</div><div class="line"> <span class="keyword">var</span> scrollTop = <span class="built_in">window</span>.document.body.scrollTop;</div><div class="line"> layer.open({</div><div class="line"> content: <span class="string">'可以尝试滑动蒙层,页面没有滚动'</span>,</div><div class="line"> style: <span class="string">'background-color:#09C1FF; color:#fff; border:none;'</span>,</div><div class="line"> end: ()=> {</div><div class="line"> $(<span class="string">'body'</span>).css(<span class="string">'overflow'</span>, <span class="string">''</span>).css(<span class="string">'position'</span>, <span class="string">''</span>).css(<span class="string">'top'</span>, <span class="string">''</span>);</div><div class="line"> <span class="built_in">window</span>.document.body.scrollTop = scrollTop;</div><div class="line"> },</div><div class="line"> success: ()=> {</div><div class="line"> $(<span class="string">'body'</span>).css(<span class="string">'overflow'</span>, <span class="string">'hidden'</span>).css(<span class="string">'position'</span>, <span class="string">'fixed'</span>).css(<span class="string">'top'</span>, -scrollTop);</div><div class="line"></div><div class="line"> }</div><div class="line"></div><div class="line"> });</div><div class="line"></div><div class="line">}</div></pre></td></tr></table></figure></p>
<p>EOF</p>
]]></content>
<summary type="html">
<p>移动web上,当页面弹出蒙层时,如果用户在蒙层上面滑动,会导致蒙层下面body的滚动,配合使用css和js解决问题。</p>
</summary>
<category term="web" scheme="https://kimown.github.io/tags/web/"/>
</entry>
<entry>
<title>ubuntu下f8app环境搭建</title>
<link href="https://kimown.github.io/2016/08/07/ubuntu%E4%B8%8Bf8app%E7%8E%AF%E5%A2%83%E6%90%AD%E5%BB%BA/"/>
<id>https://kimown.github.io/2016/08/07/ubuntu下f8app环境搭建/</id>
<published>2016-08-07T06:29:33.000Z</published>
<updated>2016-08-07T10:35:41.671Z</updated>
<content type="html"><![CDATA[<p> 完成f8app ubuntu14.04下的环境搭建</p>
<a id="more"></a>
<h2 id="安装MongoDB"><a href="#安装MongoDB" class="headerlink" title="安装MongoDB"></a>安装MongoDB</h2><p> 官方文档<a href="https://docs.mongodb.com/manual/tutorial/install-mongodb-on-ubuntu/#install-mongodb-community-edition" target="_blank" rel="external">地址</a></p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div></pre></td><td class="code"><pre><div class="line">sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv EA312927</div><div class="line"><span class="built_in">echo</span> <span class="string">"deb http://repo.mongodb.org/apt/ubuntu trusty/mongodb-org/3.2 multiverse"</span> | sudo tee /etc/apt/sources.list.d/mongodb-org-3.2.list</div><div class="line">sudo apt-get update</div><div class="line">sudo apt-get install -y mongodb-org</div><div class="line">sudo service mongod start</div></pre></td></tr></table></figure>
<p>f8app <a href="">README.MD</a> 使用下面的命令检查mongo进程是否存在</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div></pre></td><td class="code"><pre><div class="line">lsof -iTCP:27017 <span class="_">-s</span>TCP:LISTEN //或者</div><div class="line">lsof -i:27017</div><div class="line">ps -ax | grep mongo</div></pre></td></tr></table></figure>
<p>如果不是在root用户下,这些命令使无法看到mongo进程的.原因:<br><a href="http://askubuntu.com/questions/696395/how-to-find-out-on-which-port-mongo-is" target="_blank" rel="external">Not all processes could be identified, non-owned process info will not be shown, you would have to be root to see it all.</a></p>
<p>idea系列中自带了对db的支持,但是很遗憾这个功能没有引入webstrom中,因此我们需要装一个webstorm的<a href="https://plugins.jetbrains.com/plugin/7141" target="_blank" rel="external">插件</a></p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div></pre></td><td class="code"><pre><div class="line">google@H:/usr/bin$ ps -ax|grep mongo</div><div class="line"> 2579 pts/38 S+ 0:00 grep --color=auto mongo</div><div class="line">32022 ? Ssl 0:07 /usr/bin/mongod --config /etc/mongod.conf</div></pre></td></tr></table></figure>
<p>查看下mongo的安装目录,在/usr/bin/mongod目录下,将路径/usr/bin/mongod输入到Path to Mongo Shell,点击Test。<br><img src="https://cloud.githubusercontent.com/assets/7932380/17461133/c2424ba8-5cb3-11e6-8b13-e3a53836677e.png" alt="SUCCESS"></p>
<p>至此,mongodb的安装完结,下面转到<a href="https://github.com/fbsamples/f8app" target="_blank" rel="external">README.md上面</a></p>
<h2 id="导入数据到mongodb"><a href="#导入数据到mongodb" class="headerlink" title="导入数据到mongodb"></a>导入数据到mongodb</h2><p>导入前:</p>
<ul>
<li>Parse Dashboard: <a href="http://localhost:8080/dashboard" target="_blank" rel="external">http://localhost:8080/dashboard</a></li>
<li>Graph<em>i</em>QL: <a href="http://localhost:8080/graphql?query=query+%7B%0A++schedule+%7B%0A++++title%0A++++speakers+%7B%0A++++++name%0A++++++title%0A++++%7D%0A++++location+%7B%0A++++++name%0A++++%7D%0A++%7D%0A%7D" target="_blank" rel="external">http://localhost:8080/graphql</a></li>
</ul>
<p>数据库表:<br><img src="https://cloud.githubusercontent.com/assets/7932380/17461206/10f4487a-5cb7-11e6-974b-a413fffe7820.png" alt="before"><br>Dashboard:<br><img src="https://cloud.githubusercontent.com/assets/7932380/17461220/b1018828-5cb7-11e6-966d-65698c998697.png" alt="before"><br>GraphiQL:<br><img src="https://cloud.githubusercontent.com/assets/7932380/17461233/04d5ffa6-5cb8-11e6-85fb-5de57af3e4ad.png" alt="before"></p>
<p>导入后<br><img src="https://cloud.githubusercontent.com/assets/7932380/17461208/288b74ea-5cb7-11e6-966e-ad075f5f7730.png" alt="after"><br>Dashboard:<br><img src="https://cloud.githubusercontent.com/assets/7932380/17461222/b9d47fa0-5cb7-11e6-80a5-91547ef9440f.png" alt="after"><br>GraphiQL:<br><img src="https://cloud.githubusercontent.com/assets/7932380/17461234/06137736-5cb8-11e6-85f7-f43060726a6b.png" alt="before"></p>
<p>这些只要运行 npm run import-data 这个命令就可以了,注意:<br>执行命令后如果一直卡在Loading Speakers,需要<a href="https://github.com/fbsamples/f8app/issues/4#issuecomment-209906785" target="_blank" rel="external">重新运行 npm start 命令</a>,注意下端口占用问题。</p>
<p><img src="https://cloud.githubusercontent.com/assets/7932380/17461239/3670c37a-5cb8-11e6-9825-9449c8822a96.png" alt=""></p>
<h2 id="在安卓上面运行"><a href="#在安卓上面运行" class="headerlink" title="在安卓上面运行"></a>在安卓上面运行</h2><p>CyanogenMod 的开发者选项中自带了网络ADB调试,使用adb连接,开启wifi调试模式,如果直接使用usb连接步骤更简单<br><img src="https://cloud.githubusercontent.com/assets/7932380/17461295/f26857e0-5cb9-11e6-91f2-2b349c5accb4.png" alt=""></p>
<p>运行 react-native run-android ,报错 failed to find Build Tools revision 23.0.2<br><img src="https://cloud.githubusercontent.com/assets/7932380/17461335/b12d6728-5cbb-11e6-9649-3494e5e53edb.png" alt="err"></p>
<p> 打开Android Studio],<a href="https://github.com/fbsamples/f8app/issues/68" target="_blank" rel="external">勾选上需要的sdk</a>.<br> <img src="https://cloud.githubusercontent.com/assets/7932380/17461352/45b1c11e-5cbc-11e6-981d-35fffaa5da35.png" alt=""><br> 安装完毕<br> <img src="https://cloud.githubusercontent.com/assets/7932380/17461362/b38f42ec-5cbc-11e6-950c-29353e792995.png" alt=""><br> 再次执行 react-native run-android,报错: Cannot evaluate module react-native-fbsdk : Configuration with name ‘default’ not found<br> 找到相关的<a href="https://github.com/facebook/react-native-fbsdk/issues/205" target="_blank" rel="external">issue</a>,osx不区分路径的大小写,而linux系统下路径区分大小写。<br> 安装的node_modules中 react-native-fbsdk 的路径图<br> <img src="https://cloud.githubusercontent.com/assets/7932380/17461697/e1d010c2-5cc7-11e6-83bb-9811ec8c326b.png" alt=""></p>
<p>在<a href="https://github.com/fbsamples/f8app/blob/master/android/settings.gradle#L13" target="_blank" rel="external">settings.gradle</a> 文件13行,路径是大写。<br><img src="https://cloud.githubusercontent.com/assets/7932380/17461709/25a96a00-5cc8-11e6-82bf-d2f19b9f02b3.png" alt=""></p>
<p>将其修改为小写的android,问题解决,apk也通过adb命令成功安装。</p>
<p><img src="https://cloud.githubusercontent.com/assets/7932380/17461762/1e737756-5cca-11e6-95b7-4818955b5bf9.png" alt=""><br>因为是使用wifi调试模式,点击Menu键->Dev Settings->Debug server host & port for device 输入 192.168.1.106:8081<br>192.168.1.105是安卓的ip地址,192.168.1.106是我们本机开发环境的IP地址,如果不知道可以使用ifconfig查看。<br>具体调试文档<a href="https://facebook.github.io/react-native/docs/running-on-device-android.html" target="_blank" rel="external">参考这里</a></p>
<p>执行 react-native start 命令,安卓重新Reload,后台输出日志<br><img src="https://cloud.githubusercontent.com/assets/7932380/17461870/db98eabc-5ccc-11e6-8cb7-22a6994dd2c9.png" alt=""></p>
<p>最后展示下结果<br><img src="https://cloud.githubusercontent.com/assets/7932380/17461893/589393be-5ccd-11e6-9740-baed49713f67.png" alt=""></p>
<p>EOF</p>
]]></content>
<summary type="html">
<p> 完成f8app ubuntu14.04下的环境搭建</p>
</summary>
<category term="React" scheme="https://kimown.github.io/tags/React/"/>
</entry>
<entry>
<title>ubuntu技巧.md</title>
<link href="https://kimown.github.io/2016/07/30/ubuntu%E6%8A%80%E5%B7%A7/"/>
<id>https://kimown.github.io/2016/07/30/ubuntu技巧/</id>
<published>2016-07-30T11:17:10.000Z</published>
<updated>2016-07-30T11:47:06.909Z</updated>
<content type="html"><![CDATA[<p> 把现在遇到的问题,记录下来,避免重复搜索</p>
<a id="more"></a>
<ul>
<li><h2 id="ubuntu和网易云音乐切换下一首音乐的快捷键冲突"><a href="#ubuntu和网易云音乐切换下一首音乐的快捷键冲突" class="headerlink" title="ubuntu和网易云音乐切换下一首音乐的快捷键冲突"></a>ubuntu和网易云音乐切换下一首音乐的快捷键冲突</h2><blockquote>
<p><a href="http://stackoverflow.com/questions/13455397/disable-ubuntu-keyboard-shortcuts" target="_blank" rel="external">http://stackoverflow.com/questions/13455397/disable-ubuntu-keyboard-shortcuts</a><br>在右上角-System Settings-Keyboard-Shortcuts-Navigation,选中被占用的快捷键,先按下Enter键,出现New accelerator后,再按下Backspace键。</p>
</blockquote>
</li>
</ul>
]]></content>
<summary type="html">
<p> 把现在遇到的问题,记录下来,避免重复搜索</p>
</summary>
<category term="Linux" scheme="https://kimown.github.io/tags/Linux/"/>
</entry>
<entry>
<title>react-native填坑</title>
<link href="https://kimown.github.io/2016/07/30/react-native%E5%A1%AB%E5%9D%91/"/>
<id>https://kimown.github.io/2016/07/30/react-native填坑/</id>
<published>2016-07-30T09:19:01.000Z</published>
<updated>2016-07-30T12:45:36.861Z</updated>
<content type="html"><![CDATA[<p>记录下刚开始接触react-native遇到的一些问题</p>
<a id="more"></a>
<h2 id="网络问题"><a href="#网络问题" class="headerlink" title="网络问题"></a>网络问题</h2><p>使用react-native-cli初始化AwesomeProject项目时,会使用npm安装第三方依赖,会从<a href="http://npmjs.com/" target="_blank" rel="external">npm官方</a>下载,这里我们改用<a href="https://cnpmjs.org/" target="_blank" rel="external">cnpm镜像</a>.</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div></pre></td><td class="code"><pre><div class="line">google@H:/tmp$ <span class="built_in">which</span> react-native</div><div class="line">/home/mdk/node/bin/react-native</div><div class="line">google@H:/tmp$ ll /home/mdk/node/bin/react-native</div><div class="line">lrwxrwxrwx 1 google google 45 6月 18 10:44 /home/mdk/node/bin/react-native -> ../lib/node_modules/react-native-cli/index.js*</div><div class="line">google@H:/tmp$ <span class="built_in">cd</span> /home/mdk/node/lib/node_modules/react-native-cli/</div><div class="line">google@H:/home/mdk/node/lib/node_modules/react-native-cli$ l</div><div class="line">index.js* node_modules/ package.json README.md</div><div class="line">google@H:/home/mdk/node/lib/node_modules/react-native-cli$ vi index.js</div></pre></td></tr></table></figure>
<p>这里看下react-native-cli代码,详细模式<br>运行npm在<a href="https://github.com/facebook/react-native/blob/master/react-native-cli/index.js#L232" target="_blank" rel="external">232行</a>,<br>由源代码</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">var</span> proc = spawn(<span class="string">'npm'</span>, [<span class="string">'install'</span>, <span class="string">'--verbose'</span>, <span class="string">'--save'</span>, <span class="string">'--save-exact'</span>, getInstallPackage(rnPackage)], {stdio: <span class="string">'inherit'</span>});</div></pre></td></tr></table></figure>
<p>修改为</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">var</span> proc = spawn(<span class="string">'npm'</span>, [<span class="string">'install'</span>,<span class="string">'--registry=https://registry.npm.taobao.org'</span>, <span class="string">'--verbose'</span>, <span class="string">'--save'</span>, <span class="string">'--save-exact'</span>, getInstallPackage(rnPackage)], {stdio: <span class="string">'inherit'</span>});</div></pre></td></tr></table></figure>
<p>正常模式运行npm在<a href="https://github.com/facebook/react-native/blob/master/react-native-cli/index.js#L216" target="_blank" rel="external">216行</a>,<br>由源代码</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">exec(<span class="string">'npm install --save --save-exact '</span> + getInstallPackage(rnPackage), <span class="function"><span class="keyword">function</span>(<span class="params">e, stdout, stderr</span>) </span>{</div></pre></td></tr></table></figure>
<p>修改为</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">exec(<span class="string">'npm install --save --save-exact --registry=https://registry.npm.taobao.org '</span> + getInstallPackage(rnPackage), <span class="function"><span class="keyword">function</span>(<span class="params">e, stdout, stderr</span>) </span>{</div></pre></td></tr></table></figure>
<h2 id="null-is-not-an-object-evaluating-‘this-state-showText’"><a href="#null-is-not-an-object-evaluating-‘this-state-showText’" class="headerlink" title="null is not an object(evaluating ‘this.state.showText’)"></a>null is not an object(evaluating ‘this.state.showText’)</h2><p>虽然react hot实现了热更新,但是例如我在constructor中添加了一个state的属性值,保存后,页面热更新,会报上面的提示信息的错误。<br>原先:react-native的热更新无法替换整个state,无法实时反馈state的变化<br>解决方法:手动Reload页面</p>
]]></content>
<summary type="html">
<p>记录下刚开始接触react-native遇到的一些问题</p>
</summary>
<category term="React" scheme="https://kimown.github.io/tags/React/"/>
</entry>
<entry>
<title>blog主题的修改内容</title>
<link href="https://kimown.github.io/2016/07/23/blog%E4%B8%BB%E9%A2%98%E7%9A%84%E4%BF%AE%E6%94%B9%E5%86%85%E5%AE%B9/"/>
<id>https://kimown.github.io/2016/07/23/blog主题的修改内容/</id>
<published>2016-07-23T14:35:46.000Z</published>
<updated>2016-08-24T04:03:27.824Z</updated>
<content type="html"><![CDATA[<h2 id="代码的修改逻辑"><a href="#代码的修改逻辑" class="headerlink" title="代码的修改逻辑"></a>代码的<a href="https://github.com/kimown/blog/blob/master/themes/auto-update-theme-fs.js" target="_blank" rel="external">修改逻辑</a></h2> <a id="more"></a>
<ul>
<li><p>2016-08-24 11:02</p>
<ul>
<li>google公共库地址为<a href="http://libs.useso.com/" target="_blank" rel="external">360CDN服务</a>,但不支持https,作罢</li>
<li>修改google公共库地址为<a href="https://servers.ustclug.org/2014/06/blog-googlefonts-speedup/" target="_blank" rel="external">科大加速服务</a>,修改文件:<a href="https://github.com/hexojs/hexo-theme-landscape/blob/master/layout/_partial/head.ejs#L32" target="_blank" rel="external">head.ejs</a>,<a href="https://github.com/hexojs/hexo-theme-landscape/blob/master/layout/_partial/after-footer.ejs#L17" target="_blank" rel="external">after-footer.ejs</a></li>
<li>修改fontawesome-webfont<a href="https://github.com/hexojs/hexo-theme-landscape/blob/master/source/css/_variables.styl#L29" target="_blank" rel="external">路径</a>为<a href="http://www.bootcdn.cn/font-awesome/" target="_blank" rel="external">cdn</a>,不走github pages</li>
</ul>
</li>
<li><p>2016-08-23 22:24</p>
<ul>
<li>去除横幅背景图片,在<a href="https://github.com/hexojs/hexo-theme-landscape/blob/master/source/css/_variables.styl#L39" target="_blank" rel="external">_variables.styl</a>去除</li>
</ul>
</li>
</ul>
<ul>
<li>2016-08-24 21:01<ul>
<li>修改了landscape的背景色,在<a href="https://github.com/hexojs/hexo-theme-landscape/blob/master/source/css/_variables.styl#L10" target="_blank" rel="external">_variables.styl</a>,将背景色修改为<a href="https://hexo.io/" target="_blank" rel="external">https://hexo.io/</a>主页的颜色</li>
</ul>
</li>
</ul>
<figure class="highlight stylus"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line"><span class="attribute">color</span>-background = <span class="number">#eee</span></div></pre></td></tr></table></figure>
<p>修改成<br><figure class="highlight stylus"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line"><span class="attribute">color</span>-background = <span class="number">#171f26</span></div></pre></td></tr></table></figure></p>
<ul>
<li>在<a href="https://github.com/hexojs/hexo-theme-landscape/blob/master/source/css/style.styl#L65" target="_blank" rel="external">style.styl</a>去除背景色的赋值</li>
</ul>
<p> </p>
]]></content>
<summary type="html">
<h2 id="代码的修改逻辑"><a href="#代码的修改逻辑" class="headerlink" title="代码的修改逻辑"></a>代码的<a href="https://github.com/kimown/blog/blob/master/themes/auto-update-theme-fs.js">修改逻辑</a></h2>
</summary>
<category term="Hexo" scheme="https://kimown.github.io/tags/Hexo/"/>
</entry>
<entry>
<title>chrome二维码扩展</title>
<link href="https://kimown.github.io/2016/07/23/chrome%E4%BA%8C%E7%BB%B4%E7%A0%81%E6%89%A9%E5%B1%95/"/>
<id>https://kimown.github.io/2016/07/23/chrome二维码扩展/</id>
<published>2016-07-23T13:40:24.000Z</published>
<updated>2016-09-02T05:16:18.831Z</updated>
<content type="html"><![CDATA[<p> 在做移动web开发的时候,经常有pc上启动前端服务,然后使用手机扫描二维码的要求。最初的时候,直接使用一些网站提供的二维码生成服务,后来这个方法太麻烦了,就在chrome商店里面找到二维码相关的扩展。</p>
<a id="more"></a>
<p> 但是之前的这个扩展,只能实现只展示当前页面URL二维码的功能,并不能提供自定义文字生成二维码的要求,搜了下,总觉得商店里面二维码的一些图标都不怎么好看,自己也懒得一个一个找,干脆自己做一个chrome扩展,一是练练手,二是熟悉下浏览器扩展,算是实现自己起初接触浏览器,自己想做一个浏览器扩展的想法吧。
</p>
<p> 二维码的生成主要用到了<a href="https://github.com/davidshimjs/qrcodejs" target="_blank" rel="external">qrocejs</a>,这里感谢作者提供这个很优秀二维码的js库,二维码的生成都是依靠它。</p>
<p> 预览图:<br> <img src="https://raw.githubusercontent.com/kimown/qrcodetools/master/resources/preview.gif" alt="preview"></p>
<p> 总结下,很大一部分时间都在阅读官方的<a href="https://developer.chrome.com/extensions" target="_blank" rel="external">文档</a>,不过感到很欣喜的是,文档描述,案例代码都很清晰简单,所以做这个小工具的时候基本没有遇到卡壳的时候,就是注册chrome扩展开发者的时候,需要信用卡,由于谷歌退出中国(⊙﹏⊙b,什么时候回来啊),没有国内银联卡的填写项,后来自己申请一个招行的全币种信用卡,扣了5美元,算是注册成功了。</p>
<p> 最后,顺便发下扩展的github地址: <a href="https://github.com/kimown/qrcodetools" target="_blank" rel="external">qrcodeTools</a></p>
<p> 还有扩展商店安装地址 : <a href="https://chrome.google.com/webstore/detail/qr-code-tools/ocbhppgblkpojkpebamblimobggeaobi" target="_blank" rel="external">chrome webstore</a></p>
]]></content>
<summary type="html">
<p> 在做移动web开发的时候,经常有pc上启动前端服务,然后使用手机扫描二维码的要求。最初的时候,直接使用一些网站提供的二维码生成服务,后来这个方法太麻烦了,就在chrome商店里面找到二维码相关的扩展。</p>
</summary>
<category term="Tool" scheme="https://kimown.github.io/tags/Tool/"/>
</entry>
</feed>