-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathindex.html
More file actions
1631 lines (1363 loc) · 117 KB
/
index.html
File metadata and controls
1631 lines (1363 loc) · 117 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<!DOCTYPE html>
<html>
<head>
<!-- hexo-inject:begin --><!-- hexo-inject:end --><meta charset="utf-8">
<title>莫文之家</title>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<meta property="og:type" content="website">
<meta property="og:title" content="莫文之家">
<meta property="og:url" content="https://morvenyang.github.io/index.html">
<meta property="og:site_name" content="莫文之家">
<meta property="og:locale" content="default">
<meta name="twitter:card" content="summary">
<meta name="twitter:title" content="莫文之家">
<link rel="alternate" href="/atom.xml" title="莫文之家" type="application/atom+xml">
<link rel="icon" href="/favicon.png">
<link href="//fonts.googleapis.com/css?family=Source+Code+Pro" rel="stylesheet" type="text/css">
<link rel="stylesheet" href="/css/style.css"><!-- hexo-inject:begin --><!-- hexo-inject:end -->
</head>
<body>
<!-- hexo-inject:begin --><!-- hexo-inject:end --><div id="container">
<div id="wrap">
<header id="header">
<div id="banner"></div>
<div id="header-outer" class="outer">
<div id="header-title" class="inner">
<h1 id="logo-wrap">
<a href="/" id="logo">莫文之家</a>
</h1>
</div>
<div id="header-inner" class="inner">
<nav id="main-nav">
<a id="main-nav-toggle" class="nav-icon"></a>
<a class="main-nav-link" href="/">Home</a>
<a class="main-nav-link" href="/archives">Archives</a>
</nav>
<nav id="sub-nav">
<a id="nav-rss-link" class="nav-icon" href="/atom.xml" title="RSS Feed"></a>
<a id="nav-search-btn" class="nav-icon" title="Search"></a>
</nav>
<div id="search-form-wrap">
<form action="//google.com/search" method="get" accept-charset="UTF-8" class="search-form"><input type="search" name="q" class="search-form-input" placeholder="Search"><button type="submit" class="search-form-submit"></button><input type="hidden" name="sitesearch" value="https://morvenyang.github.io"></form>
</div>
</div>
</div>
</header>
<div class="outer">
<section id="main">
<article id="post-编写可读代码的艺术" class="article article-type-post" itemscope itemprop="blogPost">
<div class="article-meta">
<a href="/2018/10/04/编写可读代码的艺术/" class="article-date">
<time datetime="2018-10-04T14:23:03.000Z" itemprop="datePublished">2018-10-04</time>
</a>
</div>
<div class="article-inner">
<header class="article-header">
<h1 itemprop="name">
<a class="article-title" href="/2018/10/04/编写可读代码的艺术/">编写可读代码的艺术</a>
</h1>
</header>
<div class="article-entry" itemprop="articleBody">
<h2 id="代码应当易于理解"><a href="#代码应当易于理解" class="headerlink" title="代码应当易于理解"></a>代码应当易于理解</h2><h3 id="是什么让代码变得“更好”"><a href="#是什么让代码变得“更好”" class="headerlink" title="是什么让代码变得“更好”"></a>是什么让代码变得“更好”</h3><p>大多数程序员依靠直觉和灵感来决定如何编程。</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">for</span> (Node *node = list -> head; node != NULL; node = node -> next)</span><br><span class="line"> Print(node -> data);</span><br></pre></td></tr></table></figure>
<p>VS</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">Node *node = list -> head;</span><br><span class="line"><span class="keyword">if</span> (node == NULL) <span class="keyword">return</span>;</span><br><span class="line"><span class="keyword">while</span>(node -> nex != NULL) {</span><br><span class="line"> Print(node -> data);</span><br><span class="line"> node = node -> next;</span><br><span class="line">}</span><br><span class="line"><span class="keyword">if</span> (node != NULL) Print(node -> data);</span><br></pre></td></tr></table></figure>
<h3 id="可读性基本定理"><a href="#可读性基本定理" class="headerlink" title="可读性基本定理"></a>可读性基本定理</h3><p>代码的写法应当使别人理解它所需要的时间最小化。</p>
<h3 id="总是越小越好吗"><a href="#总是越小越好吗" class="headerlink" title="总是越小越好吗"></a>总是越小越好吗</h3><p>一般来讲,你解决问题所用的代码越少就越好,但少的代码并不总是更好!<br>尽管减少代码行数是一个好目标,但把理解代码所需要的时间最小化是一个更好的目标。</p>
<h3 id="理解代码所需的时间是否与其他目标有冲突"><a href="#理解代码所需的时间是否与其他目标有冲突" class="headerlink" title="理解代码所需的时间是否与其他目标有冲突"></a>理解代码所需的时间是否与其他目标有冲突</h3><p>不冲突!就算是在需要高度优化代码的领域,还是有办法能让代码同时可读性更高。并且让你的代码容易理解往往会把它引向好的架构且容易测试。</p>
<h2 id="表面层次的改进"><a href="#表面层次的改进" class="headerlink" title="表面层次的改进"></a>表面层次的改进</h2><p>选择好的名字、写好的注释以及把代码整洁地写成更好的格式。</p>
<h3 id="把信息装到名字里"><a href="#把信息装到名字里" class="headerlink" title="把信息装到名字里"></a>把信息装到名字里</h3><p>选择一个好的名字可以让它承载很多信息。</p>
<h4 id="选择专业的词"><a href="#选择专业的词" class="headerlink" title="选择专业的词"></a>选择专业的词</h4><p>选择非常专业的词,并且避免使用“空洞”的词。</p>
<p>举例,“get”这个词就非常不专业,在下面的例子中:<br><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">GetPage</span><span class="params">(url)</span>:</span> ...</span><br></pre></td></tr></table></figure></p>
<p>“get”这个词没有表达出很多信息。这个方法是从本地的缓存中得到一个页面,还是从数据库中,或者从互联网中?如果是从互联网中,更专业的名字可以是FetchPage()或者DownloadPage()。</p>
<p>下面是一个BinaryTree类的例子:<br><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">BinaryTree</span></span></span><br><span class="line"><span class="class">{</span></span><br><span class="line"> <span class="function"><span class="keyword">int</span> <span class="title">Size</span><span class="params">()</span></span>;</span><br><span class="line"> ...</span><br><span class="line">};</span><br></pre></td></tr></table></figure></p>
<p>你期望Size()方法返回什么呢?树的高度,节点数,还是树在内存中所占的空间?<br>问题是Size()没有承载很多信息。更专业的词可以是Height()、NumNodes()或者MemoryBytes()。</p>
<h4 id="找到更有表现力的词"><a href="#找到更有表现力的词" class="headerlink" title="找到更有表现力的词"></a>找到更有表现力的词</h4><p>清晰和精确比装可爱好。</p>
<div class="table-container">
<table>
<thead>
<tr>
<th>单词</th>
<th>更多选择</th>
</tr>
</thead>
<tbody>
<tr>
<td>send</td>
<td>deliver, dispatch, announce, distribute, route</td>
</tr>
<tr>
<td>find</td>
<td>search, extract, locate, recover</td>
</tr>
<tr>
<td>start</td>
<td>launch, create, begin, open</td>
</tr>
<tr>
<td>make</td>
<td>create, set up, build, generate, compose, add, new</td>
</tr>
</tbody>
</table>
</div>
<h4 id="避免像tmp和retval这样泛泛的名字"><a href="#避免像tmp和retval这样泛泛的名字" class="headerlink" title="避免像tmp和retval这样泛泛的名字"></a>避免像tmp和retval这样泛泛的名字</h4><blockquote>
<p>retval这个名字没有包含很多信息。用一个描述该变量的值的名字来代替它。<br>tmp这个名字只应用于短期存在且临时性为其主要存在因素的变量。</p>
</blockquote>
<h4 id="循环迭代器"><a href="#循环迭代器" class="headerlink" title="循环迭代器"></a>循环迭代器</h4><p>像i、j、iter和it等名字常用做索引和循环迭代器。尽管这些名字很空泛,但是大家都知道它们的意思是“我是一个迭代器”。<br>但有时会有比i、j、k更贴切的迭代器命名。</p>
<h4 id="对于空泛名字的裁定"><a href="#对于空泛名字的裁定" class="headerlink" title="对于空泛名字的裁定"></a>对于空泛名字的裁定</h4><p>在某些情况下空泛的名字也有用处,如果你要使用像tmp、it或者retval这样空泛的名字,那么你要有个好的理由。</p>
<h4 id="用具体的名字代替抽象的名字"><a href="#用具体的名字代替抽象的名字" class="headerlink" title="用具体的名字代替抽象的名字"></a>用具体的名字代替抽象的名字</h4><p>假设你有一个内部方法叫做ServerCanStart(),它检测服务是否可以监听某个给定的TCP/IP端口。然而ServerCanStart()有点抽象。CanListenOnPort()就更具体一些。这个名字直接地描述了这个方法要做什么事情。</p>
<h4 id="为名字附带更多信息"><a href="#为名字附带更多信息" class="headerlink" title="为名字附带更多信息"></a>为名字附带更多信息</h4><blockquote>
<p>带单位的值:如果你的变量是一个度量的话(如时间长度或者字节数),那么最好把名字带上它的单位。</p>
</blockquote>
<div class="table-container">
<table>
<thead>
<tr>
<th>函数参数</th>
<th>带单位的参数</th>
</tr>
</thead>
<tbody>
<tr>
<td>Start(int delay)</td>
<td>delay -> delay_secs</td>
</tr>
<tr>
<td>CreateCache(int size)</td>
<td>size -> size_mb</td>
</tr>
<tr>
<td>ThrottleDownload(float limit)</td>
<td>limit -> max_kbps</td>
</tr>
<tr>
<td>Rotate(float angle)</td>
<td>angle -> degrees_cw</td>
</tr>
</tbody>
</table>
</div>
<blockquote>
<p>附带其他重要属性</p>
</blockquote>
<div class="table-container">
<table>
<thead>
<tr>
<th>情形</th>
<th>变量名</th>
<th>更好的名字</th>
</tr>
</thead>
<tbody>
<tr>
<td>一个“纯文本”格式的密码,需要加密后才能进一步使用</td>
<td>password</td>
<td>plaintext_password</td>
</tr>
<tr>
<td>一条用户提供的注释,需要转译之后才能用于显示</td>
<td>comment</td>
<td>unescaped_comment</td>
</tr>
<tr>
<td>已转化为UTF-8格式的html字节</td>
<td>html</td>
<td>html_utf8</td>
</tr>
<tr>
<td>以“url方式编码”的输入数据</td>
<td>data</td>
<td>data_urlenc</td>
</tr>
</tbody>
</table>
</div>
<blockquote>
<p>标识变量的任何关键属性,如果需要的话以易读的方式把它加到名字里。</p>
</blockquote>
<h4 id="名字应该有多长"><a href="#名字应该有多长" class="headerlink" title="名字应该有多长"></a>名字应该有多长</h4><blockquote>
<p>在小的作用域里可以使用短的名字<br>输入长名字——不再是个问题:单词补全功能<br>首字母缩略词和缩写<br>丢掉没用的词:例如,ConverToString()就不如ToString()这个更短的名字,而且没有丢失任何有用的信息。</p>
</blockquote>
<h4 id="利用名字的格式来传递含义"><a href="#利用名字的格式来传递含义" class="headerlink" title="利用名字的格式来传递含义"></a>利用名字的格式来传递含义</h4><p>对不同的实体使用不同的格式就像语法高亮显示的形式一样,能帮助你更容易地阅读代码。</p>
<blockquote>
<p>使用CamelCase来表示类名<br>使用lower<em>separated来表示变量名<br>常量的格式是kConstantName而不是CONST_NAME<br>类成员变量和普通变量一样,但必须以一条下划线结尾,如offset</em></p>
</blockquote>
<h4 id="其他格式规范"><a href="#其他格式规范" class="headerlink" title="其他格式规范"></a>其他格式规范</h4><blockquote>
<p>构造函数应该首字母大写而普通函数首字母小写<br>当调用jQuery库函数时,一条非常有用的规范是,给jQuery返回的结果也加上$作为前缀<br>当给一个HTML标记加id或者class属性时,下划线和连字符都是合法的值。一个可能的规范是用下划线来分开ID中的单词,用连字符来分开class中的单词</p>
</blockquote>
<h3 id="不会误解的名字"><a href="#不会误解的名字" class="headerlink" title="不会误解的名字"></a>不会误解的名字</h3><blockquote>
<p>要多问自己几遍:“这个名字会被别人解读成其他的含义吗?”要仔细审视这个名字。</p>
</blockquote>
<h4 id="推荐用min和max来表示(包含)极限"><a href="#推荐用min和max来表示(包含)极限" class="headerlink" title="推荐用min和max来表示(包含)极限"></a>推荐用min和max来表示(包含)极限</h4><p>命名极限最清楚的方式是在要限制的东西前加上max<em>或者min</em>。</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">MAX_ITEMS_IN_CART = <span class="number">10</span></span><br><span class="line"><span class="keyword">if</span> shopping_cart.num_items() > MAX_ITEMS_IN_CART:</span><br><span class="line"> Error(<span class="string">"Too many items in cart."</span>)</span><br></pre></td></tr></table></figure>
<h4 id="推荐用first和last来表示包含的范围"><a href="#推荐用first和last来表示包含的范围" class="headerlink" title="推荐用first和last来表示包含的范围"></a>推荐用first和last来表示包含的范围</h4><div align="center">
<img src="/2018/10/04/编写可读代码的艺术/QQ20181006-093536@2x.png" width="400">
</div>
<h4 id="推荐使用begin和end来表示包含-排除范围"><a href="#推荐使用begin和end来表示包含-排除范围" class="headerlink" title="推荐使用begin和end来表示包含/排除范围"></a>推荐使用begin和end来表示包含/排除范围</h4><div align="center">
<img src="/2018/10/04/编写可读代码的艺术/QQ20181006-093633@2x.png" width="400">
</div>
<h4 id="给布尔值命名"><a href="#给布尔值命名" class="headerlink" title="给布尔值命名"></a>给布尔值命名</h4><blockquote>
<p>当为布尔变量或者返回布尔值的函数选择名字时,要确保返回true和false的意义很明确。<br>通常来讲,加上像is、has、can或should这样的词,可以把布尔值变得更明确。<br>最好避免使用反义名字。例如,不要用:<code>bool disable_ssl = false;</code>,而更简单易读的表示方式是:<code>bool use_ssl = true;</code></p>
</blockquote>
<h4 id="与使用者的期望相匹配"><a href="#与使用者的期望相匹配" class="headerlink" title="与使用者的期望相匹配"></a>与使用者的期望相匹配</h4><p>有些名字之所以会让人误解是因为用户对它们的含义有先入为主的印象,就算你的本意并非如此。这种情况下,最好放弃这个名字而改用一个不会让人误解的名字。</p>
<blockquote>
<p>例子:get*()<br>例子:list::size()<br>例子:如何权衡多个备选名字</p>
</blockquote>
<h3 id="审美"><a href="#审美" class="headerlink" title="审美"></a>审美</h3><blockquote>
<p>好的源代码应当“看上去养眼”。</p>
</blockquote>
<ul>
<li>使用一致的布局,让读者很快就习惯这种风格。</li>
</ul>
<ul>
<li>让相似的代码看上去相似。</li>
</ul>
<ul>
<li>把相关的代码行分组,形成代码块。</li>
</ul>
<h4 id="为什么审美这么重要"><a href="#为什么审美这么重要" class="headerlink" title="为什么审美这么重要"></a>为什么审美这么重要</h4><p>使用从审美角度讲让人愉悦的代码更容易。<br>试想一下,你编程的大部分时间都花在看代码上!浏览代码的速度越快,人们就越容易使用它。</p>
<h4 id="重新安排换行来保持一致和紧凑"><a href="#重新安排换行来保持一致和紧凑" class="headerlink" title="重新安排换行来保持一致和紧凑"></a>重新安排换行来保持一致和紧凑</h4><h4 id="用方法来整理不规则的东西"><a href="#用方法来整理不规则的东西" class="headerlink" title="用方法来整理不规则的东西"></a>用方法来整理不规则的东西</h4><ul>
<li>消除了原来代码中大量的重复,让代码变得更紧凑;</li>
</ul>
<ul>
<li>每个测试用例重要的部分变得很直白;</li>
</ul>
<ul>
<li>添加新的测试更简单。</li>
</ul>
<h4 id="在需要时使用列对齐"><a href="#在需要时使用列对齐" class="headerlink" title="在需要时使用列对齐"></a>在需要时使用列对齐</h4><h4 id="选一个有意义的顺序,始终一致地使用它"><a href="#选一个有意义的顺序,始终一致地使用它" class="headerlink" title="选一个有意义的顺序,始终一致地使用它"></a>选一个有意义的顺序,始终一致地使用它</h4><ul>
<li>从“最重要”到“最不重要”排序;</li>
</ul>
<ul>
<li>按字母顺序排序。</li>
</ul>
<h4 id="把声明按块组织起来"><a href="#把声明按块组织起来" class="headerlink" title="把声明按块组织起来"></a>把声明按块组织起来</h4><h4 id="把代码分成“段落”"><a href="#把代码分成“段落”" class="headerlink" title="把代码分成“段落”"></a>把代码分成“段落”</h4><ul>
<li>它是一种把相似的想法放在一起并与其他想法分开的方法;</li>
</ul>
<ul>
<li>它提供了可见的“脚印”,如果没有它,会很容易找不到你读到哪里了;</li>
</ul>
<ul>
<li>它便于段落之间的导航。</li>
</ul>
<h4 id="个人风格与一致性"><a href="#个人风格与一致性" class="headerlink" title="个人风格与一致性"></a>个人风格与一致性</h4><p>一致的风格比“正确”的风格更重要。</p>
<h4 id="总结"><a href="#总结" class="headerlink" title="总结"></a>总结</h4><blockquote>
<p>如果多个代码块做相似的事情,尝试让它们有同样的剪影;<br>把代码按”列“对齐可以让代码更易浏览;<br>如果在一段代码中提到A、B和C,那么不要在另一段中说B、C和A。选择一个有意义的顺序,并始终用这样的顺序;<br>用空行来把大块代码分成逻辑上的“段落”。</p>
</blockquote>
<h3 id="该写什么样的注释"><a href="#该写什么样的注释" class="headerlink" title="该写什么样的注释"></a>该写什么样的注释</h3><p>注释的目的是尽量帮助读者了解得和作者一样多。</p>
<h4 id="什么不需要注释"><a href="#什么不需要注释" class="headerlink" title="什么不需要注释"></a>什么不需要注释</h4><blockquote>
<p>不要为那些从代码本身就能快速推断的事实写注释。</p>
<p>不要为了注释而注释</p>
</blockquote>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// Find the Node in the given subtree, with the given name, using the given depth.</span></span><br><span class="line">Node* FindNodeInSubtree(Node* subtree, string name, int depth);</span><br></pre></td></tr></table></figure>
<blockquote>
<p>不要给不好的名字加注释——应该把名字改好</p>
</blockquote>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// Enforce limits on the Reply as stated in the Request,</span></span><br><span class="line"><span class="comment">// such as the number of items returned, or total byte size, etc.</span></span><br><span class="line"><span class="keyword">void</span> CleanReply(Request request, Reply reply);</span><br></pre></td></tr></table></figure>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// Make sure 'reply' meets the count/byte/etc. limits from the 'request'</span></span><br><span class="line"><span class="keyword">void</span> EnforceLimitsFromRequest(Request request, Reply reply);</span><br></pre></td></tr></table></figure>
<p><strong>好代码 > 坏代码 + 好注释</strong></p>
<h4 id="记录你的思想"><a href="#记录你的思想" class="headerlink" title="记录你的思想"></a>记录你的思想</h4><blockquote>
<p>加入“导演评论”<br><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 这个类正在变得越来越乱</span></span><br><span class="line"><span class="comment">// 也许我们应该建立一个'ResourceNode'子类来帮助整理</span></span><br></pre></td></tr></table></figure></p>
<p>为代码中的暇疵写注释<br><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// <span class="doctag">TODO:</span>采用更快算法</span></span><br><span class="line"><span class="comment">// TODO(dustin): 处理除JPEG以外的图像格式</span></span><br></pre></td></tr></table></figure></p>
</blockquote>
<div class="table-container">
<table>
<thead>
<tr>
<th>标记</th>
<th>通常的意义</th>
</tr>
</thead>
<tbody>
<tr>
<td>TODO:</td>
<td>我还没有处理的事情</td>
</tr>
<tr>
<td>FIXME:</td>
<td>已知的无法运行的代码</td>
</tr>
<tr>
<td>HACK:</td>
<td>对一个问题不得不采用的比较粗糙的解决方案</td>
</tr>
<tr>
<td>xxx:</td>
<td>危险!这里有重要的问题</td>
</tr>
</tbody>
</table>
</div>
<blockquote>
<p>给常量加注释</p>
</blockquote>
<h4 id="站在读者的角度"><a href="#站在读者的角度" class="headerlink" title="站在读者的角度"></a>站在读者的角度</h4><blockquote>
<p>意料之中的提问</p>
</blockquote>
<figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">Recorder</span> {</span></span><br><span class="line"> <span class="built_in">vector</span> <<span class="keyword">float</span>> data;</span><br><span class="line"> ...</span><br><span class="line"> <span class="function"><span class="keyword">void</span> <span class="title">Clear</span><span class="params">()</span> </span>{</span><br><span class="line"> <span class="built_in">vector</span> <<span class="keyword">float</span>>().swap(data); <span class="comment">// Huh? Whiy not just data.clear()?</span></span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="comment">// Force vector to relinquish its memory (look up "STL swap trick")</span></span><br><span class="line"><span class="built_in">vector</span> <<span class="keyword">float</span>>().swap(data);</span><br></pre></td></tr></table></figure>
<blockquote>
<p>公布可能的陷阱</p>
</blockquote>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 运行时间将达到 O(number_tags * average_tag_depth),所以小心严重嵌套的输入。</span></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">FixBrokenHtml</span><span class="params">(html)</span>:</span></span><br><span class="line"> ...</span><br></pre></td></tr></table></figure>
<blockquote>
<p>“全局观”注释</p>
</blockquote>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 这个文件包含一些辅助函数,为我们的文件系统提供了更便利的接口</span></span><br><span class="line"><span class="comment">// 它处理了文件权限及其他基本的细节。</span></span><br></pre></td></tr></table></figure>
<p>不要对于写庞大的正式文档这种想法不知所措。几句精心选择的话比什么都没有强。</p>
<blockquote>
<p>总结性注释</p>
</blockquote>
<p>可以做任何能帮助读者更容易理解代码的事。这可能也会包含对于“做什么”、“怎么做”或为什么“的注释。</p>
<h4 id="最后的思考——克服“作者心理阻滞”"><a href="#最后的思考——克服“作者心理阻滞”" class="headerlink" title="最后的思考——克服“作者心理阻滞”"></a>最后的思考——克服“作者心理阻滞”</h4><p>写注释可以分为几个简单的步骤:</p>
<ul>
<li>不管你心里想什么,先把它写下来。</li>
</ul>
<ul>
<li>读一下这段注释,看看有没有什么地方可以改进。</li>
</ul>
<ul>
<li>不断改进。</li>
</ul>
<h3 id="写出言简意赅的注释"><a href="#写出言简意赅的注释" class="headerlink" title="写出言简意赅的注释"></a>写出言简意赅的注释</h3><p>注释应当有很高的信息/空间率</p>
<h4 id="让注释保持紧凑"><a href="#让注释保持紧凑" class="headerlink" title="让注释保持紧凑"></a>让注释保持紧凑</h4><h4 id="避免使用不明确的代词"><a href="#避免使用不明确的代词" class="headerlink" title="避免使用不明确的代词"></a>避免使用不明确的代词</h4><h4 id="润色粗糙的句子"><a href="#润色粗糙的句子" class="headerlink" title="润色粗糙的句子"></a>润色粗糙的句子</h4><h4 id="精确地描述函数的行为"><a href="#精确地描述函数的行为" class="headerlink" title="精确地描述函数的行为"></a>精确地描述函数的行为</h4><h4 id="用输入-输出例子来说明特别的情况"><a href="#用输入-输出例子来说明特别的情况" class="headerlink" title="用输入/输出例子来说明特别的情况"></a>用输入/输出例子来说明特别的情况</h4><h4 id="声明代码的意图"><a href="#声明代码的意图" class="headerlink" title="声明代码的意图"></a>声明代码的意图</h4><h4 id="“具名函数参数”的注释"><a href="#“具名函数参数”的注释" class="headerlink" title="“具名函数参数”的注释"></a>“具名函数参数”的注释</h4><h4 id="采用信息含量高的词"><a href="#采用信息含量高的词" class="headerlink" title="采用信息含量高的词"></a>采用信息含量高的词</h4><h2 id="简化循环和逻辑"><a href="#简化循环和逻辑" class="headerlink" title="简化循环和逻辑"></a>简化循环和逻辑</h2><h3 id="把控制流变得易读"><a href="#把控制流变得易读" class="headerlink" title="把控制流变得易读"></a>把控制流变得易读</h3><p>把条件、循环以及其他对控制流的改变做得越“自然”越好。运用一种方式使读者不用停下来重读你的代码。</p>
<h4 id="条件语句中参数的顺序"><a href="#条件语句中参数的顺序" class="headerlink" title="条件语句中参数的顺序"></a>条件语句中参数的顺序</h4><div class="table-container">
<table>
<thead>
<tr>
<th>比较的左侧</th>
<th>比较的右侧</th>
</tr>
</thead>
<tbody>
<tr>
<td>“被询问的”表达式,它的值更倾向于不断变化</td>
<td>用来做比较的表达式,它的值更倾向于常量</td>
</tr>
</tbody>
</table>
</div>
<h4 id="if-else语句块的顺序"><a href="#if-else语句块的顺序" class="headerlink" title="if/else语句块的顺序"></a>if/else语句块的顺序</h4><blockquote>
<p>首先处理正确逻辑而不是负逻辑的情况,例如,用if(debug)而不是if(!debug)。<br>先处理掉简单的情况。<br>先处理有趣的或者是可疑的情况。</p>
</blockquote>
<h4 id="?-条件表达式(又名“三目运算符”)"><a href="#?-条件表达式(又名“三目运算符”)" class="headerlink" title="?:条件表达式(又名“三目运算符”)"></a>?:条件表达式(又名“三目运算符”)</h4><p>相对于追求最小化代码行数,一个更好的度量方法是最小化人们理解它所需的时间。</p>
<p>默认情况下都用if/else。三目运算符?:只有在最简单的情况下使用。</p>
<h4 id="避免do-while循环"><a href="#避免do-while循环" class="headerlink" title="避免do/while循环"></a>避免do/while循环</h4><blockquote>
<p>do/while的奇怪之处是一个代码块是否会执行是由其后的一个条件决定的。<br>另一个要避免do/while循环的原因是其中的continue语句会让人迷惑。</p>
</blockquote>
<h4 id="从函数中提前返回"><a href="#从函数中提前返回" class="headerlink" title="从函数中提前返回"></a>从函数中提前返回</h4><div class="table-container">
<table>
<thead>
<tr>
<th>语言</th>
<th>清理代码的结构化术语</th>
</tr>
</thead>
<tbody>
<tr>
<td>C++</td>
<td>析构函数</td>
</tr>
<tr>
<td>Java、Python</td>
<td>try finally</td>
</tr>
<tr>
<td>Python</td>
<td>with</td>
</tr>
<tr>
<td>C#</td>
<td>using</td>
</tr>
</tbody>
</table>
</div>
<h4 id="臭名昭著的goto"><a href="#臭名昭著的goto" class="headerlink" title="臭名昭著的goto"></a>臭名昭著的goto</h4><p>对goto最简单、最单纯的使用就是在函数结尾有单个exit</p>
<p>当有多个goto的目标时可能会有问题,尤其当这些路径交叉时,需要特别指出的是,向前goto可能会产生真正的意大利面条式代码,并且它们肯定可以被结构化的循环替代。大多数时候都应该避免使用goto。</p>
<h4 id="最小化嵌套"><a href="#最小化嵌套" class="headerlink" title="最小化嵌套"></a>最小化嵌套</h4><blockquote>
<p>嵌套是如何累积而成的:当你对代码做改动时,从全新的角度审视它,把它作为一个整体来看待。<br>通过提早返回来减少嵌套<br>减少循环内的嵌套</p>
</blockquote>
<h4 id="你能理解执行的流程吗"><a href="#你能理解执行的流程吗" class="headerlink" title="你能理解执行的流程吗"></a>你能理解执行的流程吗</h4><h3 id="拆分超长的表达式"><a href="#拆分超长的表达式" class="headerlink" title="拆分超长的表达式"></a>拆分超长的表达式</h3><p>把你的超长表达式拆分成更容易理解的小块。</p>
<h4 id="用做解释的变量"><a href="#用做解释的变量" class="headerlink" title="用做解释的变量"></a>用做解释的变量</h4><p>拆分表达式最简单的方法就是引入一个额外的变量,让它来表示一个小一点的子表达式。</p>
<h4 id="总结变量"><a href="#总结变量" class="headerlink" title="总结变量"></a>总结变量</h4><p>用一个短很多的名字来代替一大块代码,这个名字会更容易管理和思考。</p>
<h4 id="使用德摩根定理"><a href="#使用德摩根定理" class="headerlink" title="使用德摩根定理"></a>使用德摩根定理</h4><p>分别取反,转换与/或。</p>
<h4 id="滥用短路逻辑"><a href="#滥用短路逻辑" class="headerlink" title="滥用短路逻辑"></a>滥用短路逻辑</h4><p>要小心“智能”的小代码段——它们往往以后会让别人读起来感到困惑。</p>
<h4 id="拆分巨大的语句"><a href="#拆分巨大的语句" class="headerlink" title="拆分巨大的语句"></a>拆分巨大的语句</h4><blockquote>
<p>帮助避免录入错误<br>进一步缩短了行的宽度,使代码更容易快速阅读<br>如果类的名字需要改变,只需要改一个地方即可。</p>
</blockquote>
<h3 id="变量与可读性"><a href="#变量与可读性" class="headerlink" title="变量与可读性"></a>变量与可读性</h3><p>变量越多,就越难全部跟踪它们的动向。</p>
<p>变量的作用域越大,就需要跟踪它的动向越久。</p>
<p>变量改变得越频繁,就越难以跟踪它的当前值。</p>
<h4 id="减少变量"><a href="#减少变量" class="headerlink" title="减少变量"></a>减少变量</h4><blockquote>
<p>没有价值的临时变量<br>减少中间结果<br>减少控制流变量</p>
</blockquote>
<h4 id="缩小变量的作用域"><a href="#缩小变量的作用域" class="headerlink" title="缩小变量的作用域"></a>缩小变量的作用域</h4><p>让你的变量对尽量少的代码行可见。</p>
<blockquote>
<p>JavaScript全局作用域:如果你在变量定义中省略var关键字,这个变量会放在全局作用域中。<br>在Python和JavaScript中没有嵌套的作用域<br>把定义向下移</p>
</blockquote>
<h4 id="只写一次的变量更好"><a href="#只写一次的变量更好" class="headerlink" title="只写一次的变量更好"></a>只写一次的变量更好</h4><p>操作一个变量的地方越多,越难确定它的当前值。</p>
<h2 id="重新组织代码"><a href="#重新组织代码" class="headerlink" title="重新组织代码"></a>重新组织代码</h2><h3 id="抽取不相关的子问题"><a href="#抽取不相关的子问题" class="headerlink" title="抽取不相关的子问题"></a>抽取不相关的子问题</h3><p>积极地发现并抽取出不相关的子逻辑</p>
</div>
<footer class="article-footer">
<a data-url="https://morvenyang.github.io/2018/10/04/编写可读代码的艺术/" data-id="ck0riazyk000j1qtg0azomrxk" class="article-share-link">Share</a>
</footer>
</div>
</article>
<article id="post-常用算法学习" class="article article-type-post" itemscope itemprop="blogPost">
<div class="article-meta">
<a href="/2018/10/02/常用算法学习/" class="article-date">
<time datetime="2018-10-02T02:41:36.000Z" itemprop="datePublished">2018-10-02</time>
</a>
</div>
<div class="article-inner">
<header class="article-header">
<h1 itemprop="name">
<a class="article-title" href="/2018/10/02/常用算法学习/">常用算法学习</a>
</h1>
</header>
<div class="article-entry" itemprop="articleBody">
<h2 id="算法是程序的灵魂"><a href="#算法是程序的灵魂" class="headerlink" title="算法是程序的灵魂"></a>算法是程序的灵魂</h2><blockquote>
<p>所谓算法(algorithm)就是定义良好的计算过程,它取一个或一组值作为输入,并产生出一个或一组值作为输出。<br>算法就是一系列的计算步骤,用来将输入数据转换成输出结果。<br>算法指的是一种解决问题的方法,也就是程序的“灵魂”。</p>
</blockquote>
<h3 id="开始学习算法"><a href="#开始学习算法" class="headerlink" title="开始学习算法"></a>开始学习算法</h3><h4 id="算法的特征和发展由来"><a href="#算法的特征和发展由来" class="headerlink" title="算法的特征和发展由来"></a>算法的特征和发展由来</h4><p>算法的特征:</p>
<ul>
<li>有穷性</li>
</ul>
<ul>
<li>确切性</li>
</ul>
<ul>
<li>输入</li>
</ul>
<ul>
<li>输出</li>
</ul>
<ul>
<li>可行性</li>
</ul>
<h4 id="何为算法"><a href="#何为算法" class="headerlink" title="何为算法"></a>何为算法</h4><p>算法是指在有限步骤内求解某一问题所使用的一组定义明确的规则。通俗点说,就是计算机解题过程中,无论是形成解题思路还是编写程序,都是实施某种算法。前者是推理实现的算法,后者是操作实现的算法。</p>
<h4 id="算法分析"><a href="#算法分析" class="headerlink" title="算法分析"></a>算法分析</h4><p>算法分析即指对一个算法所需要的资源进行预测。对于一个给定的问题,通过分析几种候选算法,可以很容易地从中选出一个最有效的算法。</p>
<h3 id="计算机中的算法"><a href="#计算机中的算法" class="headerlink" title="计算机中的算法"></a>计算机中的算法</h3><h4 id="计算机算法分类"><a href="#计算机算法分类" class="headerlink" title="计算机算法分类"></a>计算机算法分类</h4><ul>
<li>数值运算算法:求解数值;</li>
</ul>
<ul>
<li>非数值运算算法:事务管理领域。</li>
</ul>
<h4 id="表示算法的方法"><a href="#表示算法的方法" class="headerlink" title="表示算法的方法"></a>表示算法的方法</h4><ul>
<li>用流程图来表示算法</li>
</ul>
<ul>
<li>用N-S流程图来表示算法</li>
</ul>
<ul>
<li>用计算机语言表示算法</li>
</ul>
<h4 id="学好算法的秘诀"><a href="#学好算法的秘诀" class="headerlink" title="学好算法的秘诀"></a>学好算法的秘诀</h4><ul>
<li>学得要深入,基础要扎实</li>
</ul>
<ul>
<li>恒心、演练、举一反三</li>
</ul>
<ul>
<li>在语言之争的时代要学会坚持</li>
</ul>
<h2 id="分析妙趣横生的算法思想"><a href="#分析妙趣横生的算法思想" class="headerlink" title="分析妙趣横生的算法思想"></a>分析妙趣横生的算法思想</h2><h3 id="八大算法思想"><a href="#八大算法思想" class="headerlink" title="八大算法思想"></a>八大算法思想</h3><p>枚举、递推、递归、分治、贪心、试探法、动态迭代和模拟算法思想。</p>
<h4 id="比较“笨”的枚举算法思想"><a href="#比较“笨”的枚举算法思想" class="headerlink" title="比较“笨”的枚举算法思想"></a>比较“笨”的枚举算法思想</h4><ul>
<li>定义<br>在进行归纳推理时,如果逐个考察了某类事件的所有可能情况,因而得出一般结论,那么该结论是可靠的,这种归纳方法叫做枚举法。</li>
</ul>
<ul>
<li>思想<br>将问题的所有可能的答案一一列举,然后根据条件判断此答案是否合适,保留合适的,丢弃不合适的。</li>
</ul>
<ul>
<li>步骤<br>(1)题解的可能范围,不能遗漏任何一个真正解,也要避免有重复;<br>(2)判断是否是真正解的方法;<br>(3)使可能解的范围降至最小,以便提高解决问题的效率。</li>
</ul>
<div align="center">
<img src="/2018/10/02/常用算法学习/QQ20181002-112904@2x.png" width="400">
<center><font color="grey">枚举算法流程图</font></center>
</div>
</div>
<footer class="article-footer">
<a data-url="https://morvenyang.github.io/2018/10/02/常用算法学习/" data-id="ck0riazy6000a1qtgbq2dtee6" class="article-share-link">Share</a>
</footer>
</div>
</article>
<article id="post-结构思考力" class="article article-type-post" itemscope itemprop="blogPost">
<div class="article-meta">
<a href="/2018/09/09/结构思考力/" class="article-date">
<time datetime="2018-09-09T03:19:49.000Z" itemprop="datePublished">2018-09-09</time>
</a>
</div>
<div class="article-inner">
<header class="article-header">
<h1 itemprop="name">
<a class="article-title" href="/2018/09/09/结构思考力/">结构思考力</a>
</h1>
</header>
<div class="article-entry" itemprop="articleBody">
<h3 id="何为结构思考力?"><a href="#何为结构思考力?" class="headerlink" title="何为结构思考力?"></a>何为结构思考力?</h3><p>结构可以说是万物之本。大到宇宙星系,小到颗粒尘埃,无论是高楼大厦、动物与植物、机器与网络、思想与观念、人与社会,任何事物都有其特定的结构,这些事物也是通过其特定的结构来体现其存在的价值和意义。</p>
<p>结构存在于每个整体与局部关系的无穷变化中,每个局部表现整体,而局部的意义又由整体来决定。因此,当我们面临一个问题时,如果可以从结构的视角去审视和思考,一定可以让我们看得更全面、更清晰。</p>
<h4 id="Why——结构思考力的作用非凡"><a href="#Why——结构思考力的作用非凡" class="headerlink" title="Why——结构思考力的作用非凡"></a>Why——结构思考力的作用非凡</h4><p><strong>1.所有人都需要具备的核心技能</strong></p>
<div class="table-container">
<table>
<thead>
<tr>
<th>类别</th>
<th>具备结构思考力的特点</th>
<th>不具备结构思考力的特点</th>
</tr>
</thead>
<tbody>
<tr>
<td>解决问题</td>
<td>迅速抓住主要矛盾,忙而不乱应付任何问题</td>
<td>难以把握问题关键,经常遗漏关键要素</td>
</tr>
<tr>
<td>决策</td>
<td>能快速理出重点,果敢且科学做出决策</td>
<td>瞻前顾后,难以割舍,犹豫不决</td>
</tr>
<tr>
<td>写作</td>
<td>主题明确,结构严谨,层次清晰</td>
<td>找不到重点,大量文字和数字堆砌,结构混乱</td>
</tr>
<tr>
<td>表达、沟通</td>
<td>语言准确,思路清晰,能快速总结说话要点</td>
<td>很难把想要表达的思想在短时间内表达清楚</td>
</tr>
<tr>
<td>辅导</td>
<td>快速确定辅导目标,制定明确计划,理清核心</td>
<td>目标不明确,随机性较强,被辅导者难于理解</td>
</tr>
</tbody>
</table>
</div>
<ul>
<li>结构思考力是开展所有工作的基础</li>
</ul>
<ul>
<li>很多专业岗位对于结构思考力有更高的要求</li>
</ul>
<ul>
<li>所有管理者必备的管理技能</li>
</ul>
<div align="center">
<img src="/2018/09/09/结构思考力/QQ20180909-204842@2x.png" width="400">
<center><font color="grey">高效管理者的三大技能</font></center>
</div>
<ul>
<li>助力职业发展的重要保障</li>
</ul>
<p><strong>2.通过统一标准,提升整个组织的工作效率</strong></p>
<ul>
<li>结构思考力可以统一思考和表达的标准</li>
</ul>
<ul>
<li>结构思考力可以提升整个组织的管理效率</li>
</ul>
<p>汇报工作说结果,检讨工作说流程,请示工作说方案</p>
<ul>
<li>在中国企业里尤其需要结构思考力</li>
</ul>
<p>结构思考力是一种“先总后分”的思考与表达方式,强调先框架后细节,先总结后具体,先结论后原因,先重要后次要。</p>
<p><strong>3.对于全民素质的提升有着非凡的意义</strong></p>
<ul>
<li>传统教育缺乏对思考力的专门训练</li>
</ul>
<ul>
<li>结构思考力有助于提升国民素质</li>
</ul>
</div>
<footer class="article-footer">
<a data-url="https://morvenyang.github.io/2018/09/09/结构思考力/" data-id="ck0riazym000n1qtgej5j0243" class="article-share-link">Share</a>
</footer>
</div>
</article>
<article id="post-软件架构" class="article article-type-post" itemscope itemprop="blogPost">
<div class="article-meta">
<a href="/2018/09/08/软件架构/" class="article-date">
<time datetime="2018-09-08T03:13:01.000Z" itemprop="datePublished">2018-09-08</time>
</a>
</div>
<div class="article-inner">
<header class="article-header">
<h1 itemprop="name">
<a class="article-title" href="/2018/09/08/软件架构/">软件架构原理</a>
</h1>
</header>
<div class="article-entry" itemprop="articleBody">
<h3 id="软件架构的定义"><a href="#软件架构的定义" class="headerlink" title="软件架构的定义"></a>软件架构的定义</h3><p>架构是一个系统的基本组织结构,涵盖所包含的组件、组件之间的关系、组件与环境的关系,以及指导架构设计和演进的原则等内容。</p>
<h4 id="软件架构与设计"><a href="#软件架构与设计" class="headerlink" title="软件架构与设计"></a>软件架构与设计</h4><ul>
<li>架构关注如何对系统中的结构和交互进行较高级别的描述,它关注的是那些与系统骨架相关的决策问题,例如,功能、组织、技术、业务和质量属性等。</li>
</ul>
<ul>
<li>设计关注构成系统的部件或组件,以及子系统是如何组织的,这里关注的问题通常更接近所讨论的代码或模块自身,例如:将代码分成哪些模块?如何组织?给不同的功能分配哪些类?在运行时对象之间是如何交互的?传递什么消息?如何实施交互?等等。</li>
</ul>
<h4 id="软件架构相关的几个方面"><a href="#软件架构相关的几个方面" class="headerlink" title="软件架构相关的几个方面"></a>软件架构相关的几个方面</h4><ul>
<li>系统<br>系统是以特定方式组织的组件集合,以实现特定的功能。软件系统是其软件组件的集合。一个系统通常可以划分成若干个子系统。</li>
</ul>
<ul>
<li>结构<br>结构是根据某个指导规则或原则来组合或组织在一起的一组元素的集合。元素可以是软件或硬件系统。软件架构可以根据观察者的上下文展示各个层次的结构。</li>
</ul>
<ul>
<li>环境<br>软件系统所在的上下文或环境对其软件架构有直接的影响。这样的上下文因素可以是技术、商业、专业、操作等。</li>
</ul>
<ul>
<li>利益相关者<br>任何对某个系统及其成功与否感兴趣或关心的个体或团体,都是利益相关者。例如,架构师、开发团队、客户、项目经理和营销团队等。</li>
</ul>
<h3 id="软件架构的特征"><a href="#软件架构的特征" class="headerlink" title="软件架构的特征"></a>软件架构的特征</h3><h4 id="用架构来定义一种结构"><a href="#用架构来定义一种结构" class="headerlink" title="用架构来定义一种结构"></a>用架构来定义一种结构</h4><p>结构(structure)提供了一种深入理解架构的视角,也提供一种独特的视角来分析架构及其质量属性。</p>
<ul>
<li>运行时结构<br>在运行时创建的对象及其之间的交互方式经常决定部署架构(deployment archiecture)。</li>
</ul>
<ul>
<li>模块结构<br>为了分解任务,如何拆分代码并把代码组织到模块和包中,这与系统的可维护性和可修改性(可扩展性)密切相关。</li>
</ul>
<h4 id="由架构来挑选一组核心元素"><a href="#由架构来挑选一组核心元素" class="headerlink" title="由架构来挑选一组核心元素"></a>由架构来挑选一组核心元素</h4><p>一个定义良好的架构只会捕获那些构建系统核心功能所需的核心结构元素,这些核心结构元素一般会对系统有持久的影响,绝不是像流水账似地记录系统每个组件的所有细节。</p>
<h4 id="由架构来捕获早期的设计决策"><a href="#由架构来捕获早期的设计决策" class="headerlink" title="由架构来捕获早期的设计决策"></a>由架构来捕获早期的设计决策</h4><p>早期的设计决策需要在仔细分析需求之后才能做出,同时满足一些约束和限制条件。这些约束和限制条件包括组织的、技术的、人员的和时间的,等等。</p>
<h4 id="由架构来管理利益相关者的需求"><a href="#由架构来管理利益相关者的需求" class="headerlink" title="由架构来管理利益相关者的需求"></a>由架构来管理利益相关者的需求</h4><p>架构提供了利益相关者之间的一种通用的语言,使利益相关者能够通过这种约束性的表达来进行有效的沟通,并帮助架构师实现可最有效捕获这些需求和平衡点的架构。</p>
<h4 id="架构影响着组织结构"><a href="#架构影响着组织结构" class="headerlink" title="架构影响着组织结构"></a>架构影响着组织结构</h4><p>架构描述的系统结构通常可以直接映射到系统构建团队的结构。</p>
<h4 id="架构受到环境的影响"><a href="#架构受到环境的影响" class="headerlink" title="架构受到环境的影响"></a>架构受到环境的影响</h4><p>环境(environment)会对架构施加外部约束或限制,架构必须在这样的环境中发挥作用。</p>
<h4 id="架构是对系统的文档化"><a href="#架构是对系统的文档化" class="headerlink" title="架构是对系统的文档化"></a>架构是对系统的文档化</h4><p>架构文档化的最简单方法是为系统和组织架构的不同方面创建图表,包括组件架构、部署架构、通信架构以及团队或企业架构。</p>
<h4 id="架构通常会遵循某个模式"><a href="#架构通常会遵循某个模式" class="headerlink" title="架构通常会遵循某个模式"></a>架构通常会遵循某个模式</h4><p>大多数架构都遵循一定的风格,这些风格在实践中取得了很大的成功,它们被称为架构模式。</p>
<h3 id="软件架构的重要性"><a href="#软件架构的重要性" class="headerlink" title="软件架构的重要性"></a>软件架构的重要性</h3><div class="table-container">
<table>
<thead>
<tr>
<th>方面</th>
<th>见解/影响</th>
<th>例子</th>
</tr>
</thead>
<tbody>
<tr>
<td>根据架构来选择能对系统进行优化的质量属性</td>
<td>系统的可扩展性、可用性、可修改性、安全性等方面取决于在选择架构时的早期决策和权衡,经常会牺牲一个属性来提升另一个属性</td>
<td>必须使用分散式架构来开发针对可扩展性进行优化的系统,其中元素不紧密耦合,例如,微服务、代理</td>
</tr>
<tr>
<td>架构促进早期原型设计</td>
<td>定义架构以允许开发组织尝试构建早期原型,这位系统的行为提供了宝贵的洞察视角,而无需构建完整的系统</td>
<td>许多组织会构建服务的快速原型——通常只构建这些服务的外部API,而忽视其余的行为,这使得早期集成测试可以执行,也能更早发现架构中的交互问题</td>
</tr>
<tr>
<td>架构允许系统以组件化方式构建</td>
<td>具有明确定义的架构允许重用和组合现有的易于使用的组件来实现功能,而无需从头开始实现所有内容</td>
<td>为服务提供可立即使用的构建模块的库或框架技术</td>
</tr>
<tr>
<td>架构有助于管理系统变更</td>
<td>架构师会根据架构分离出在修改中受影响的组件和不受影响的组件,这有助于在实施新功能、性能修复等操作时对系统的变更保持最低程度</td>
<td>如果正确实现了架构,对于系统数据库读取的性能修改,只需对数据库和数据访问层进行修改即可,根本不需要触及应用程序的代码,这就是大多数现代Web框架的构建方式</td>
</tr>
</tbody>
</table>
</div>
<h3 id="系统架构与企业架构"><a href="#系统架构与企业架构" class="headerlink" title="系统架构与企业架构"></a>系统架构与企业架构</h3><p>企业架构师考虑一个组织或机构的整体业务和组织策略,并应用架构原理和实践来指导该组织或机构通过业务、信息、流程和技术变更需求执行策略。</p>
<ul>
<li>技术架构师<br>关注一个组织或机构使用的核心技术(硬件、软件、网络)。</li>
</ul>
<ul>
<li>安全架构师<br>创建或调整应用程序使用的安全策略,以适应团队的信息安全目标。</li>
</ul>
<ul>
<li>信息架构师<br>提出了架构解决方案,以使输入应用程序的信息或者从应用程序中获得的信息可用,从而促进团队的业务目标得以实现。</li>
</ul>
<ul>
<li>系统架构师<br>通常具有较高的技术关注度和较低的策略关注度。</li>
</ul>
<ul>
<li>解决方案架构师<br>通常跨越策略与技术关注点、组织与项目范围,处在中间位置。</li>
</ul>
<div align="center">
<img src="/2018/09/08/软件架构/QQ20180909-083702@2x.png" width="400">
</div>
<h3 id="架构的质量属性"><a href="#架构的质量属性" class="headerlink" title="架构的质量属性"></a>架构的质量属性</h3><h4 id="可修改性"><a href="#可修改性" class="headerlink" title="可修改性"></a>可修改性</h4><h4 id="可测试性"><a href="#可测试性" class="headerlink" title="可测试性"></a>可测试性</h4><h4 id="可扩展性-性能"><a href="#可扩展性-性能" class="headerlink" title="可扩展性/性能"></a>可扩展性/性能</h4><h4 id="安全性"><a href="#安全性" class="headerlink" title="安全性"></a>安全性</h4><h4 id="可部署性"><a href="#可部署性" class="headerlink" title="可部署性"></a>可部署性</h4><blockquote>
<p>摘抄自《软件架构:Python语言实现》</p>
</blockquote>
</div>
<footer class="article-footer">
<a data-url="https://morvenyang.github.io/2018/09/08/软件架构/" data-id="ck0riazyo000o1qtgxrjojc65" class="article-share-link">Share</a>
<ul class="article-tag-list"><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/软件架构/">软件架构</a></li></ul>
</footer>
</div>
</article>
<article id="post-大数据笔记" class="article article-type-post" itemscope itemprop="blogPost">
<div class="article-meta">
<a href="/2018/09/02/大数据笔记/" class="article-date">
<time datetime="2018-09-02T02:56:49.000Z" itemprop="datePublished">2018-09-02</time>
</a>
</div>
<div class="article-inner">
<header class="article-header">
<h1 itemprop="name">
<a class="article-title" href="/2018/09/02/大数据笔记/">大数据笔记</a>
</h1>
</header>
<div class="article-entry" itemprop="articleBody">
<h2 id="《大数据架构商业之路——从业务需求到技术方案》"><a href="#《大数据架构商业之路——从业务需求到技术方案》" class="headerlink" title="《大数据架构商业之路——从业务需求到技术方案》"></a>《大数据架构商业之路——从业务需求到技术方案》</h2><h3 id="数据收集"><a href="#数据收集" class="headerlink" title="数据收集"></a>数据收集</h3><h4 id="1-互联网数据收集"><a href="#1-互联网数据收集" class="headerlink" title="1. 互联网数据收集"></a>1. 互联网数据收集</h4><ul>
<li>网络爬虫<br>主要的工作流程是从一个或若干个初始网页的地址URL开始,获得初始网页上的URL列表。然后在抓取网页的过程中,不断地从当前页面上抽取新的URL放入待爬行队列,直到满足系统的停止条件为止。</li>
</ul>
<p>如何有效地获取新的URL,对于爬虫执行成功与否非常关键,从这个角度可以将网页获取的策略分为几个大类:深度优先、宽度优先和最佳优先三种。</p>
<blockquote>
<p>PageRank算法:在随机访问的过程中,越是被频繁访问对链接越重要。</p>
<p>HITS算法:将每张网页节点的值分为两个,包括权威值(authority)和中心值(hub)。</p>
</blockquote>
<div align="center">
<img src="/2018/09/02/大数据笔记/QQ20181005-150152@2x.png" width="400">
<center><font color="grey">爬虫的基本架构和工作流程</font></center>
</div>
<p>对于创业公司而言,利用现有对外部资源是飞速发展的捷径。因此,网络爬虫将被广泛地运用在互联网世界的数据获取上。例如,对于O2O电商创业而言,可以让爬虫获取某些地区的气候数据,以便于之后做基于天气预报的个性化推荐和精准营销。此外,爬虫还可以从主流电商网站爬取其商品目录结构,以及最新的市场价格,等等。</p>
<h4 id="2-Apache-Nutch简介"><a href="#2-Apache-Nutch简介" class="headerlink" title="2. Apache Nutch简介"></a>2. Apache Nutch简介</h4><p>它是一个开源的、基于Java编程语言实现的搜索引擎,诞生于2002年8月。<br>在Nutch的进化过程中,还衍生了Hadoop、Tika、Gora和Crawler Commons四个重量级的Java开源项目。</p>
<p>Nutch不仅仅是一个爬虫系统,它还提供了运行搜索引擎所需的主要工具,包括全文索引和搜索。</p>
<p>主要组成部分为爬虫(Crawler)、索引器(Indexer)和查询器(Searcher)。</p>
<p>数据文件主要包括三类,分别是网络数据库(Web Database)、分段(Segment)和索引(Index)</p>
<h4 id="3-Heritrix简介"><a href="#3-Heritrix简介" class="headerlink" title="3. Heritrix简介"></a>3. Heritrix简介</h4><p>Heritrix也是一个开源的、使用Java编程语言开发的网络爬虫,始于2003年年初,最初用于对网上的资源进行归档,建立网络数字图书馆。</p>
<p>爬虫主要通过可视化的Web用户界面启动、监控和调整,允许弹性地定义要获取的网页链接,可扩展性良好,方便用户实现自己的抓取逻辑。</p>
<p>Heritrix主要有以下组件:</p>
<ul>
<li>爬取范围</li>
</ul>
<ul>
<li>边界开拓</li>
</ul>
<ul>
<li>处理器链</li>
</ul>
<ul>
<li>预取器</li>
</ul>
<ul>
<li>获取器</li>
</ul>
<ul>
<li>抽取器</li>
</ul>
<ul>
<li>写入器</li>
</ul>
<ul>
<li>后处理器</li>
</ul>
<ul>
<li>爬虫命令处理</li>
</ul>
<ul>
<li>服务器缓存(Servercache)</li>
</ul>
<h3 id="内部数据收集"><a href="#内部数据收集" class="headerlink" title="内部数据收集"></a>内部数据收集</h3><p>内部数据的收集主要分为推送(Push)和拉取(Pull)两大类。</p>
<div align="center">
<img src="/2018/09/02/大数据笔记/QQ20181005-154121@2x.png" width="400">
<center><font color="grey">推送的收集方式</font></center>
</div>
<div align="center">
<img src="/2018/09/02/大数据笔记/QQ20181005-154306@2x.png" width="400">
<center><font color="grey">拉取的收集方式</font></center>
</div>
<h4 id="1-Apache-Flume简介"><a href="#1-Apache-Flume简介" class="headerlink" title="1. Apache Flume简介"></a>1. Apache Flume简介</h4><p>Flume(<a href="http://flume.apache.org/)是一个分布式、可靠和高可用的海量数据收集系统。它同时采用推送和拉取两种采集模式,其能力受到了业界的认可与广泛应用。" target="_blank" rel="noopener">http://flume.apache.org/)是一个分布式、可靠和高可用的海量数据收集系统。它同时采用推送和拉取两种采集模式,其能力受到了业界的认可与广泛应用。</a></p>
<p>Flume的核心模块有三个:</p>
<blockquote>
<p>源头(Source):负责接收数据的模块,它定义了数据的源头,从源头收集数据,传递给通道。</p>
<p>沉淀器(Sink):批量地从通道读取并移除数据,并将所读取的内容存储到指定的位置。</p>
<p>通道(Channel):作为一个管道或队列,连接源头和沉淀器。</p>
</blockquote>
<div align="center">
<img src="/2018/09/02/大数据笔记/QQ20181005-155546@2x.png" width="400">
<center><font color="grey">Flume工作的基本流程</font></center>
</div>
</div>
<footer class="article-footer">
<a data-url="https://morvenyang.github.io/2018/09/02/大数据笔记/" data-id="ck0riazxy00061qtgwicf5da0" class="article-share-link">Share</a>
<ul class="article-tag-list"><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/大数据/">大数据</a></li></ul>
</footer>
</div>
</article>
<article id="post-C语言笔记" class="article article-type-post" itemscope itemprop="blogPost">
<div class="article-meta">
<a href="/2018/09/02/C语言笔记/" class="article-date">
<time datetime="2018-09-02T01:00:19.000Z" itemprop="datePublished">2018-09-02</time>
</a>
</div>
<div class="article-inner">
<header class="article-header">
<h1 itemprop="name">
<a class="article-title" href="/2018/09/02/C语言笔记/">C语言笔记</a>
</h1>
</header>
<div class="article-entry" itemprop="articleBody">
<h3 id="C语言基础知识"><a href="#C语言基础知识" class="headerlink" title="C语言基础知识"></a>C语言基础知识</h3><p>C程序必须有一个main函数,它是程序执行的起点。</p>
<p>函数的标量参数通过传值的方式进行传递,而数组名参数则具有传址调用的语义。</p>
<p>字符串是一串由NUL字节结尾的字符,并且有一组库函数以不同方式专门用于操作字符串。</p>
<p>printf函数执行格式化输出,scanf函数用于格式化输入,getchar和putchar分别执行非格式化字符的输入和输出。</p>
<p>if和while语句在C语言中的用途跟它们在其他语言中的用途差不多。</p>
<p>使用#include指令避免重复声明。</p>
<p>使用#define指令给常量值取名。</p>
<p>在#include文件中放置函数原型。</p>
<p>在使用下标前先检查它们的值。</p>
<p>在while或if表达式中蕴含赋值操作。</p>
<p>始终要进行检查,确保数组不越界。</p>
<p>一个C程序的源代码保存在一个或多个源文件中,但一个函数只能完整地出现在同一个源文件中。</p>
<p>把相关的函数放在用一个文件内是一种好策略。</p>
<p>每个源文件都分别编译,产生对应的目标文件。然后,目标文件被链接在一起,形成可执行文件。</p>
<p>编译和最终运行程序的机器有可能相同,也可能不同。</p>
<p>程序必须载入到内存中才能执行。在宿主式环境中,这个任务由操作系统完成。</p>
<p>在自由式环境中,程序常常永久存储于ROM中。</p>
<p>经过初始化的静态变量中程序执行前能获得它们的值。</p>
<p>绝大多数环境使用堆栈来存储局部变量和其他数据。</p>
<p>C编译器所使用的字符集必须包括某些特定的字符。如果你使用的字符集缺少某些字符,可以使用三字母词来代替。</p>
<p>转义序列使某些无法打印的字符得以表达,例如程序中包含某些空白字符。</p>
<p>注释以/<em>开始,以</em>/结束,它不允许嵌套。注释将被预处理器去除。</p>
<p>标识符由字母、数字和下划线组成,但不能以数字开头。在标识符中,大写字母和小写字母是不一样的。</p>
<p>关键字由系统保留,不能作为标识符使用。</p>
<p>良好的程序风格和文档将使程序更容易阅读和维护。</p>
<p>具有external链接属性的实体在其他语言的术语里称为全局(global)实体,所有源文件中的所有函数均可以访问它。</p>
<p>只要变量并非声明于代码块或函数定义内部,它在缺省情况下的链接属性即为external。</p>
<p>如果一个变量声明于代码块内部,在它前面添加extern关键字将使它所引用的是全局变量而非局部变量。</p>
<p>具有external链接属性的实体总是具有静态存储类型。</p>
<p>全局变量在程序开始执行前创建,并在程序整个执行过程中始终存在。</p>
<p>从属于函数的局部变量在函数开始执行时创建,在函数执行完毕后销毁,但用于执行函数的机器指令在程序的生命周期内一直存在。</p>
<p>局部变量由函数内部使用,不能被其他函数通过名字引用。它在缺省情况下的存储类型为自动,这是基于两个原因:其一,当这些变量需要时才为它们分配存储,这样可以减少内存的总需求量。其二,在堆栈上为它们分配存储可以有效地实现递归。</p>
<p>为了保持最佳的可移植性,把字符的值限制在有符号和无符号字符范围的交集之内,或者不要在字符上执行算术运算。</p>
<p>不要把整型值和枚举值混在一起使用。</p>
<p>不要依赖隐式声明。</p>
<p>在定义类型的新名字时,使用typedef而不是#define</p>
<p>用const声明其值不会修改的变量。</p>
<p>使用名字常量而不是字面值常量。</p>
<p>不要在嵌套的代码块之间使用相同的变量名。</p>
<p>除了实体的具体定义位置之外,在它的其他声明位置使用extern关键字。</p>
</div>
<footer class="article-footer">
<a data-url="https://morvenyang.github.io/2018/09/02/C语言笔记/" data-id="ck0riazxr00021qtgg8nvcfo1" class="article-share-link">Share</a>
<ul class="article-tag-list"><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/C语言/">C语言</a></li></ul>
</footer>
</div>
</article>
<article id="post-数学笔记" class="article article-type-post" itemscope itemprop="blogPost">
<div class="article-meta">
<a href="/2018/08/30/数学笔记/" class="article-date">
<time datetime="2018-08-30T09:45:33.000Z" itemprop="datePublished">2018-08-30</time>
</a>
</div>
<div class="article-inner">
<header class="article-header">
<h1 itemprop="name">
<a class="article-title" href="/2018/08/30/数学笔记/">数学笔记</a>
</h1>
</header>
<div class="article-entry" itemprop="articleBody">
<h3 id="《解题-cdot-成长-cdot-快乐——陶哲轩教你学数学》"><a href="#《解题-cdot-成长-cdot-快乐——陶哲轩教你学数学》" class="headerlink" title="《解题$\cdot$成长$\cdot$快乐——陶哲轩教你学数学》"></a>《解题$\cdot$成长$\cdot$快乐——陶哲轩教你学数学》</h3><p>古希腊哲学家普罗克洛斯(Proclus)曾说过:“这,就是数学:她提醒你灵魂有不可见的形态;她赋予自己的发现以生命;她唤醒悟性,澄清思维;她照亮了我们内心的思想;她涤尽我们有生以来的矇昧与无知…..“。</p>
<blockquote>
<p>一个三角形的三条边的垂直平分线是共点。</p>
</blockquote>
<ul>
<li><blockquote>
<p>(自然约束) $\alpha,\beta, \gamma, t>0和b>d$。不失一般性地,我们还可以假设$d\geq0$.</p>