-
Notifications
You must be signed in to change notification settings - Fork 1
/
index.html
2933 lines (1235 loc) · 221 KB
/
index.html
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 class="theme-next gemini use-motion" lang="zh-CN">
<head><meta name="generator" content="Hexo 3.9.0">
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=2">
<meta name="theme-color" content="#222">
<link rel="stylesheet" href="/lib/font-awesome/css/font-awesome.min.css?v=4.7.0">
<link rel="stylesheet" href="/css/main.css?v=7.1.2">
<link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon-next.png?v=7.1.2">
<link rel="icon" type="image/png" sizes="32x32" href="/images/favicon-32x32-next.png?v=7.1.2">
<link rel="icon" type="image/png" sizes="16x16" href="/images/favicon-16x16-next.png?v=7.1.2">
<link rel="mask-icon" href="/images/logo.svg?v=7.1.2" color="#222">
<script id="hexo.configurations">
var NexT = window.NexT || {};
var CONFIG = {
root: '/',
scheme: 'Gemini',
version: '7.1.2',
sidebar: {"position":"left","display":"post","offset":12,"onmobile":false,"dimmer":false},
back2top: true,
back2top_sidebar: false,
fancybox: false,
fastclick: false,
lazyload: false,
tabs: true,
motion: {"enable":true,"async":false,"transition":{"post_block":"fadeIn","post_header":"slideDownIn","post_body":"slideDownIn","coll_header":"slideLeftIn","sidebar":"slideUpIn"}},
algolia: {
applicationID: '',
apiKey: '',
indexName: '',
hits: {"per_page":10},
labels: {"input_placeholder":"Search for Posts","hits_empty":"We didn't find any results for the search: ${query}","hits_stats":"${hits} results found in ${time} ms"}
}
};
</script>
<meta name="description" content="分享钢哥人生路上的点点滴滴">
<meta name="keywords" content="个人成长 全栈 区块链">
<meta property="og:type" content="website">
<meta property="og:title" content="Keegan小钢">
<meta property="og:url" content="https://keeganlee.me/index.html">
<meta property="og:site_name" content="Keegan小钢">
<meta property="og:description" content="分享钢哥人生路上的点点滴滴">
<meta property="og:locale" content="zh-CN">
<meta name="twitter:card" content="summary">
<meta name="twitter:title" content="Keegan小钢">
<meta name="twitter:description" content="分享钢哥人生路上的点点滴滴">
<link rel="canonical" href="https://keeganlee.me/">
<script id="page.configurations">
CONFIG.page = {
sidebar: "",
};
</script>
<title>Keegan小钢</title>
<noscript>
<style>
.use-motion .motion-element,
.use-motion .brand,
.use-motion .menu-item,
.sidebar-inner,
.use-motion .post-block,
.use-motion .pagination,
.use-motion .comments,
.use-motion .post-header,
.use-motion .post-body,
.use-motion .collection-title { opacity: initial; }
.use-motion .logo,
.use-motion .site-title,
.use-motion .site-subtitle {
opacity: initial;
top: initial;
}
.use-motion .logo-line-before i { left: initial; }
.use-motion .logo-line-after i { right: initial; }
</style>
</noscript>
</head>
<body itemscope itemtype="http://schema.org/WebPage" lang="zh-CN">
<div class="container sidebar-position-left
page-home">
<div class="headband"></div>
<header id="header" class="header" itemscope itemtype="http://schema.org/WPHeader">
<div class="header-inner"><div class="site-brand-wrapper">
<div class="site-meta">
<div class="custom-logo-site-title">
<a href="/" class="brand" rel="start">
<span class="logo-line-before"><i></i></span>
<span class="site-title">Keegan小钢</span>
<span class="logo-line-after"><i></i></span>
</a>
</div>
<p class="site-subtitle">钢哥的个人博客</p>
</div>
<div class="site-nav-toggle">
<button aria-label="切换导航栏">
<span class="btn-bar"></span>
<span class="btn-bar"></span>
<span class="btn-bar"></span>
</button>
</div>
</div>
<nav class="site-nav">
<ul id="menu" class="menu">
<li class="menu-item menu-item-home menu-item-active">
<a href="/" rel="section"><i class="menu-item-icon fa fa-fw fa-home"></i> <br>首页</a>
</li>
<li class="menu-item menu-item-tags">
<a href="/tags/" rel="section"><i class="menu-item-icon fa fa-fw fa-tags"></i> <br>标签</a>
</li>
<li class="menu-item menu-item-categories">
<a href="/categories/" rel="section"><i class="menu-item-icon fa fa-fw fa-th"></i> <br>分类</a>
</li>
<li class="menu-item menu-item-archives">
<a href="/archives/" rel="section"><i class="menu-item-icon fa fa-fw fa-archive"></i> <br>归档</a>
</li>
</ul>
</nav>
</div>
</header>
<main id="main" class="main">
<div class="main-inner">
<div class="content-wrap">
<div id="content" class="content">
<section id="posts" class="posts-expand">
<article class="post post-type-normal" itemscope itemtype="http://schema.org/Article">
<div class="post-block">
<link itemprop="mainEntityOfPage" href="https://keeganlee.me/post/career/20200201/">
<span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
<meta itemprop="name" content="Keegan小钢">
<meta itemprop="description" content="分享钢哥人生路上的点点滴滴">
<meta itemprop="image" content="/images/avatar.gif">
</span>
<span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
<meta itemprop="name" content="Keegan小钢">
</span>
<header class="post-header">
<h1 class="post-title" itemprop="name headline">
<a href="/post/career/20200201/" class="post-title-link" itemprop="url">程序猿们那些可选的职业发展路线</a>
</h1>
<div class="post-meta">
<span class="post-meta-item">
<span class="post-meta-item-icon">
<i class="fa fa-calendar-o"></i>
</span>
<span class="post-meta-item-text">发表于</span>
<time title="创建时间:2020-02-01 14:55:00 / 修改时间:15:06:08" itemprop="dateCreated datePublished" datetime="2020-02-01T14:55:00+08:00">2020-02-01</time>
</span>
<span class="post-meta-item">
<span class="post-meta-item-icon">
<i class="fa fa-folder-o"></i>
</span>
<span class="post-meta-item-text">分类于</span>
<span itemprop="about" itemscope itemtype="http://schema.org/Thing"><a href="/categories/career/" itemprop="url" rel="index"><span itemprop="name">career</span></a></span>
</span>
<br>
</div>
</header>
<div class="post-body" itemprop="articleBody">
<p>原创文章,转载请注明:转载自<a href="http://keeganlee.me/">Keegan小钢</a><br>并标明原文链接:<a href="http://keeganlee.me/post/career/20200201"><strong>http://keeganlee.me/post/career/20200201</strong></a><br>微信公众号:名称:Keegan小钢;微信号:keeganlee_me<br>写于2020-02-01</p>
<hr>
<p>时不时会有一些做开发的小伙伴向我咨询一些职业发展的问题,比如:该不该跳槽?遇到了职业天花板该怎么破?如何才能成为架构师?等等。这些问题,说白了,其实都是如何选择职业发展路线的问题。那我们就来聊聊那些可选的职业发展路线,需要注意,每个人都并非只走一条路线。</p>
<h2 id="1-纵深发展"><a href="#1-纵深发展" class="headerlink" title="1. 纵深发展"></a>1. 纵深发展</h2><p>所谓纵深,就是纵向往技术深度发展,不管是 Android 开发、iOS 开发、前端开发,还是后端开发,都可以根据技术能力划分为初级、高级、资深、技术专家/架构师、高级技术专家/高级架构师、首席技术专家/首席架构师等级别。在阿里的话,技术专家/架构师一般为 P7,高级技术专家/高级架构师则一般为 P8。每个特定领域都有不少大牛在前方引路,Android 有<strong>朱凯、任玉刚、郭霖</strong>等,iOS 有<strong>唐巧、王巍(喵神)</strong>等,前端有<strong>阮一峰、尤雨溪</strong>等,后端的牛人就更多了,不同细分领域都有不同的牛人。</p>
<p>对这些牛人来说,所谓的职业天花板并不存在,中年危机也不怕,裁员也裁不到他们,实现年薪百万更不是事。这些不同领域的牛人向我们证明了,就算只往一个特定领域深耕技术,也可以发展出非凡的职业道路。</p>
<p>往纵深发展也是大部分程序猿毕业之后首选的路,但越往深会越难,就像登山一样,不是所有人都能登上山顶的,能登上珠穆朗玛峰山顶的人又有几个呢?</p>
<p>想要在纵深方向发展得好,尤其是想达到技术专家甚至以上级别,有几个基础能力要培养:</p>
<ol>
<li><strong>技术基础要扎实,这是基本功</strong>。就比如跑马拉松,如果你的耐力、肌肉、肺活量,任何一项不够,都很难支撑你跑完马拉松。而技术的基础无非就是数据结构、算法、语言基础、编程思想等。</li>
<li><strong>要掌握高效学习的能力,提高技术进步的速度</strong>。为什么程序猿会有中年危机?为什么年纪越大越容易被裁?为什么工作经验越多越难找到新工作?假如,面试者有两个技术能力处于同一水平的人(薪资水平也相同),一个是工作了三年,一个工作了十年,如果只能留一个,你觉得面试官更愿意留哪一个呢?</li>
<li><strong>要养成「知其然并探知其所以然」的思维习惯</strong>。优秀的程序猿,对某项技术,不会停留在只知道怎么用的程度上,而会去探究背后的原理。比如,很多人都会用 HashMap,但是否会去研究 HashMap 背后的数据结构、实现原理?比如,大家都知道 MVC/MVP/MVVM,但是否有深究过各自的优缺点、适用的场景?</li>
</ol>
<p>其实,后面讲到的任何发展路线,不管你选择了哪一条,以上三个基础能力都是必须培养的。</p>
<p>优秀的程序猿一般每 2~3 年就可以提升一个级别,用不了 10 年就可以达到技术专家/架构师的级别,我自己目前也是处于该级别。不过,优秀的程序猿一般也不会只在一个方向上发展。</p>
<h2 id="2-横向拓展"><a href="#2-横向拓展" class="headerlink" title="2. 横向拓展"></a>2. 横向拓展</h2><p>纵深发展是在特定领域的技术深度上进行深耕,而横向拓展则是开拓其他领域,从广度上拓宽自己的技术能力。比如,原本做 Android 开发的可以拓展 iOS 开发,也可以涉猎前端开发,还可以涉足 Java 后端开发。</p>
<p>横向拓展有什么好处呢?我们可以反过来看看,如果只专注于一个方向的纵深发展有什么弊端?第一个风险,请参考<strong>塞班(Symbian)</strong>。虽然中短期来看,Android 和 iOS 不会出现 Symbian 一样的下场,但未来谁也说不准。另外,随着跨平台框架(比如 <strong>Flutter</strong>)的不断完善和优化,原生开发的路是否会越来越窄呢?Java 也一样,随着区块链技术和人工智能的发展,越来越多公司和团队选择 <strong>Golang</strong> 和 <strong>Python</strong> 应用于这两个领域的开发,那 Java 生态是否也会慢慢没落呢?</p>
<p>俗话都说,不要在一棵树上吊死,不要把鸡蛋放在一个篮子里,所以,最好也不要只专注于发展单一的技术领域。</p>
<p>每个特定领域的开发者进行横向拓展时都可以有各种不同选择,具体到每个人,就要结合各自的具体能力水平、兴趣爱好、长远的职业规划等进行综合考虑,最终选定一个适合自己的拓展路径。我在这里给出一些建议,仅供参考。如果你是做 Android/iOS/Web 前端开发,除了继续在原有技术领域上纵深发展,横向上我建议首选 <strong>Flutter</strong>,往大前端方向发展,这是前端方向的必然趋势。Android 人员的第二选择我建议选择拓展 Java 后端,往 Java 全栈的方向去发展,后端的路相比会宽很多,慢慢就可以发展成既懂前端又懂后端的架构师、高级架构师等,这会比单纯只懂后端的架构师更有优势。iOS 和 Web 开发人员的第二选择我则建议直接从 Golang 或 Python 起步,尤其是 Golang,如果说未来 Java 真的没落了,那有望能取代 Java 的领头位置的,我觉得 Golang 最有潜力。</p>
<p>从长远来看,横向拓展不一定只拓展一个方向,可以逐步拓展多个方向,但刚开始不建议同时拓展多个方向,建议至少让拓展的第二领域达到高级或资深级别后再去拓展下一个方向的技术领域。以我自己为例,我一开始是做 Java 后端的,后来逐步拓展了 Android、iOS,近一年多则拓展了 Golang。</p>
<h2 id="3-管理方向"><a href="#3-管理方向" class="headerlink" title="3. 管理方向"></a>3. 管理方向</h2><p>不管是纵深发展,还是横向拓展,都只是在不断精进技术。有些技术极客会一直热衷于钻研技术,不太喜欢也不擅于与人沟通,更不擅于从事管理工作,我有部分前同事就是这样的人。但不少程序猿还是倾向于慢慢转向管理岗位,从<strong>主管</strong>到<strong>经理</strong>,再到<strong>总监</strong>,最后到 <strong>CTO</strong>,逐步向上攀爬。成为 CTO,成为一个公司的最高技术领导人,这是大部分技术人员在职业道路上的终极目标。</p>
<p>但管理之路的晋升,比技术之路难得多,尤其要成为 CTO,除了一些特例,一般需要熟悉<strong>全栈技术</strong>,需要精通<strong>架构设计</strong>,需要具备<strong>全局思维</strong>,需要懂<strong>商业模式</strong>,等等。做管理,不同于做技术,除了要管理团队,也要管理项目,其实就是管理人和事。管理人,核心在于<strong>管理人心</strong>;管理事,核心是要<strong>做正确的事</strong>。</p>
<p>大部分程序猿应该是在工作了 4~6 年、达到资深开发级别之后,才开始有机会步入管理岗位,担任技术主管或技术经理。在这之前,可能也会做一个小组长的角色,指导一些初高级程序猿,从中锻炼管理能力。在阿里,主管是 M1,对应于技术岗的 P6,经理是 M2,和 P7 相对应,再往上 M3 则是高级经理,M4 为总监。</p>
<p>每个垂直领域都可以做到总监级别,比如 Android,最高也可以做到 Android 总监,但只有大公司才会有这样细分领域的总监岗位,中小企业基本是没有的,中小企业的总监一般都特指后端的技术总监。还有很多小创业公司,整个公司就一个技术管理岗位,可能挂职技术总监或 CTO,总之就是一个技术负责人,除此之外,没有其他技术管理人员了。</p>
<p>想晋升为管理人员,首先需是出类拔萃的程序猿,不然,那么多程序猿中,领导为何要提拔你。低层管理,其实更多的还是偏技术,只是同时兼点管理职责。中层管理,一般就是技术和管理各占一半了。高层管理,则更偏管理了,对技术的要求主要在于广度和全局观,对技术深度则没多大要求了。</p>
<h2 id="4-转型产品"><a href="#4-转型产品" class="headerlink" title="4. 转型产品"></a>4. 转型产品</h2><p>从技术开发转型做产品设计,走产品经理的路线,也是一些人的选择。我的朋友中,就有一位本来做 iOS 开发的,后来转型产品经理;另一位本来做 Android 开发的,也转型做产品了。这两位朋友目前都在自主创业中。</p>
<p>就连马化腾也一直将自己定位为一个产品经理。我们都知道,马化腾、张小龙、张一鸣,都是国内顶尖的产品经理,但他们其实都是程序猿出身的。其实,很多程序猿出身的企业大佬,虽然不是挂着产品经理岗位,但都是「产品经理」。所以,不要将产品经理狭义地定义为具体的岗位,不管什么岗位,只要具备产品思维、主导或参与产品设计、产品决策的人,都可以称为产品经理。比如,我在公司担任的是技术负责人,但我将自己也同时定位为一个产品经理,因为公司里的产品目前主要是由我主导的,虽然我并不担任实际的产品岗位。</p>
<p>我一直推崇每个技术人员都应该学习下如何做产品,培养产品思维,不一定是为了转型做产品,但懂产品的技术人员是很受欢迎的。</p>
<p>要学习如何做产品,我推荐读过的几本书:《用户体验的要素》《启示录:打造用户喜爱的产品》《精益创业》《腾讯方法》。</p>
<p>如果是要转型做具体的产品岗位,那还要学习需求分析、原型设计等。</p>
<h2 id="5-开拓副业"><a href="#5-开拓副业" class="headerlink" title="5. 开拓副业"></a>5. 开拓副业</h2><p>我认识一些大佬,通过发展副业,当副业的稳定收入超过主业之后,毅然辞职,全身心投入到副业中,让人羡慕不已。</p>
<p>程序猿做副业也有很多选择,大部分会选择做自媒体,通过写文章吸粉,通过收费社群、付费内容或写书等实现知识变现,一旦实现稳定变现,就能够产生复利增长。做自媒体是一条漫长的路,需要坚持输出高质量内容,而且可能长时间都很难变现,但一旦形成了一定知名度和影响力,会有各种提升的机会向你招手,比如,有人邀你写书,有人邀你录制课程,有人给你推荐好工作,等等。做自媒体的价值不止在于知识变现,还存在很多隐形价值。</p>
<p>还有不少人会不定时接外包项目,可能自己一个人单独做一些开发工作,也可能和其他几个小伙伴一起组队,合作完成整个项目。接外包单次的收入相对会高一些,但并非总是长时间有外包项目可做,且较难实现复利增加,还会大量占用自己的休闲时间,还经常会遇到拖欠尾款的问题,又累又不稳定,所以大部分人都只是偶尔接一两单回来做,或只接一些短期、轻松的项目。对于长期接项目的人,更多情况是做着做着就自己成立外包公司了。</p>
<p>也有人会自己开发一些小产品,比如一些简单的 App 或网站,然后提供收费服务或直接卖产品源码。比如,我有个朋友就自己业余时间开发了一个给外国人用的招聘网站,对招聘企业收取服务费。还有另一个朋友会开发一些区块链游戏,然后卖给想要的人。</p>
<p>有一些大佬还会为企业或个人提供咨询服务,比如帮企业做架构设计,或为解决技术难题提供方案,或给人提供职业发展建议等。有一个平台叫「在行」,不少行家就通过该平台对外提供咨询服务。</p>
<p>还有兼职开滴滴或送外卖的,以及,这段时间社交电商很火,所以不少人也加入了其中,在朋友圈、微信群卖起货来了。</p>
<p>所以程序猿开拓副业,是有很多选择的,但我倾向于做那些能实现复利增长的副业,即要让自己投入的一份时间能卖多份,比如做自媒体、卖课程、卖服务、开发自己的产品等。</p>
<p>最后,要发展副业的话,我推荐两本书:萧秋水和剽悍一只猫合著的《知识变现》,以及安晓辉的《副业赚钱之道》。</p>
<h2 id="6-弃疗转行"><a href="#6-弃疗转行" class="headerlink" title="6. 弃疗转行"></a>6. 弃疗转行</h2><p>最后一条路,那就是放弃治疗转做其他行业了,比如开个小饭馆,或开个咖啡馆。中国是全球最大的消费市场,随着迈入中产阶级的人越来越多,存在很多赚钱的机会。消费升级、婴幼儿的吃穿、教育等,到处都是机会。</p>
<p>我还有朋友从程序猿转行做保险推销员,其实,现在也是越来越多人开始注重购买保险,主要还是为家人和自己购买医疗险,尤其是为孩子,不少人从孩子出生就给宝宝购买各种保险了。</p>
<p>也有朋友转做股票操盘手。从去年开始,更多资金已经从房地产向股市转移,政策上也在大力扶持股市。</p>
<p>还记得当年那个卖猪肉的北大学子吗?被称为「北大屠夫」,人家身价早已过亿了,他和同是北大的师兄陈生一起创立的「壹号土猪」,估值已经超过 40 亿元,年营业额达 18 亿。还有一个中央民族大学的刘浩明,卖煎饼果子月入 13 万。还有「松哥油焖大虾」,其高管团队 80% 来自华为,包括创始人徐松也是从华为出来的。</p>
<p>希望你能从这些案例中得到启发。</p>
<hr>
<p>扫描以下二维码即可关注公众号(公众号名称:Keegan小钢)</p>
<img src="/post/career/20200201/qrcode_keegan.jpg">
</div>
<footer class="post-footer">
<div class="post-eof"></div>
</footer>
</div>
</article>
<article class="post post-type-normal" itemscope itemtype="http://schema.org/Article">
<div class="post-block">
<link itemprop="mainEntityOfPage" href="https://keeganlee.me/post/default/20200106/">
<span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
<meta itemprop="name" content="Keegan小钢">
<meta itemprop="description" content="分享钢哥人生路上的点点滴滴">
<meta itemprop="image" content="/images/avatar.gif">
</span>
<span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
<meta itemprop="name" content="Keegan小钢">
</span>
<header class="post-header">
<h1 class="post-title" itemprop="name headline">
<a href="/post/default/20200106/" class="post-title-link" itemprop="url">2020年第一篇,聊聊钱从哪里来?</a>
</h1>
<div class="post-meta">
<span class="post-meta-item">
<span class="post-meta-item-icon">
<i class="fa fa-calendar-o"></i>
</span>
<span class="post-meta-item-text">发表于</span>
<time title="创建时间:2020-01-06 16:58:26 / 修改时间:21:06:31" itemprop="dateCreated datePublished" datetime="2020-01-06T16:58:26+08:00">2020-01-06</time>
</span>
<span class="post-meta-item">
<span class="post-meta-item-icon">
<i class="fa fa-folder-o"></i>
</span>
<span class="post-meta-item-text">分类于</span>
<span itemprop="about" itemscope itemtype="http://schema.org/Thing"><a href="/categories/default/" itemprop="url" rel="index"><span itemprop="name">default</span></a></span>
</span>
<br>
</div>
</header>
<div class="post-body" itemprop="articleBody">
<p>原创文章,转载请注明:转载自<a href="http://keeganlee.me/">Keegan小钢</a><br>并标明原文链接:<a href="http://keeganlee.me/post/default/20200106"><strong>http://keeganlee.me/post/default/20200106</strong></a><br>微信公众号:名称:Keegan小钢;微信号:keeganlee_me<br>写于2020-01-06</p>
<hr>
<h2 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h2><p>每年我都会观看罗胖(罗振宇)的跨年演讲<strong>《时间的朋友》</strong>,今年也不例外。看完演讲后,第二天就在京东买了首发的三本新书:<strong>《变量2》《钱从哪里来》《中国优势》</strong>。这几天,抽空先读完了香帅老师的《钱从哪里来》,提高了一些认知,打算再结合自己的一些观察和思考,聊聊一些观点。</p>
<p>钱从哪里来?这应该是我们每个普通人都关心的问题。香帅老师的书主要是通过大量的数据、案例和调研,做了汇总和整理,最终梳理出一份 2020 年适合普通人的财富解决方案,一个财富逻辑的“罗盘”。书的内容主要从<strong>职业方向、城市选择、资产配置</strong>这些大方向的决策上给我们提供了指引,而我接下来也将从这几个维度去展开,聊聊我的一些思考。</p>
<h2 id="职业方向"><a href="#职业方向" class="headerlink" title="职业方向"></a>职业方向</h2><p>我们都知道,2019 年的经济形势不太好,拖欠工资、裁员、倒闭的公司比比皆是。其中,除了小创业公司之外,也包括一些经营了多年的独角兽企业,比如经营了 7 年的团贷网,还有经营了 11 年之久的尚品网,都在 2019 年死亡了。还有熊猫直播、麦子金服、乐蜂网等,都在死亡名单中。裁员的公司就更多了,就说年底爆出的华为裁 7000 人,其中大部分是 35 岁以上员工。话说,今年我也将要迈进 35 岁大门了。</p>
<p>2019 年,猪肉上涨、物价上涨、房价上涨,唯独工资没涨,不少人还因为被裁反而降薪了。毕业几年的害怕被裁,毕业十几年的也害怕被裁。2020年,在职业方向上该如何选择,才不会有被裁的风险或能减低被裁的风险呢?我觉得可以同时发展两条路,<strong>主业</strong>和<strong>副业</strong>。</p>
<p>首先,不管是主业还是副业,从大的方向来说,都应该选择<strong>低危职业</strong>。这里所说的低危职业,主要是指难以被<strong>人工智能</strong>取代的职业,包括职业理疗师、小学教师、软件工程师、保姆、美容师等。没错,保姆也属于低危职业,而且保姆收入一般还不低。能被人工智能取代的职业则属于<strong>高危职业</strong>,比如电话销售员、收银员、出纳员、服务员、股票交易员等。</p>
<p>难以被人工智能取代的技能主要有三类:社交智慧、创造力、感知和操作能力。</p>
<ul>
<li><strong>社交智慧</strong>:包括社交洞察力、谈判能力、同情心等社交和情感能力</li>
<li><strong>创造力</strong>:包括原创力和艺术审美能力</li>
<li><strong>感知和操作能力</strong>:主要指手指灵敏度、协调操作能力和应付复杂工作环境的能力</li>
</ul>
<p>因此,我们要选择发展的主业和副业,都应该要具备这三类技能中至少一类。</p>
<p>接着,选定大方向之后,还要进一步规划好自己的职业发展路径,不能安逸、不能停止进步,否则,不管是初出茅庐的新人还是具有多年经验的老人,只要是平庸之辈,就难以立足。优胜劣汰虽然残酷,但却是事实。就说程序猿们,如果过了 35 岁,依然还只是基层写代码的,那公司不裁你还裁谁呢。我自己平时招聘开发人员,年龄过大的都直接不考虑的。</p>
<p>最后,需要注意,副业只是辅助,切记不要因为发展副业而荒废了主业。理想情况是,副业能为主业助力,能带动主业的提升。不过,也有些人的副业发展迅速,当副业收入超越主业之后,可能会将副业升级为主业。另外,副业一开始是很难赚到钱的,发展副业需要坚持。</p>
<p>关于如何发展副业,我推荐一本书,安晓辉的《副业赚钱之道》,年底刚出版的新书,我看过了,挺不错,尤其适合技术人员。</p>
<h2 id="城市选择"><a href="#城市选择" class="headerlink" title="城市选择"></a>城市选择</h2><p>除了职业,选择在哪座城市打拼和生活,也会决定我们不同的人生方向。北上广深这样的一线大城市,薪资高、机会多、资源多,不管是工作还是创业,都是大部分人的首选之地。</p>
<p>但这些地方的房价高、消费高、加班多、压力大,因此,近些年也不断有人逃离这些一线城市,而去往二线城市,甚至漂往远方出国。不过,根据京东近期发布的<strong>《2019基于京东大数据的中国人口迁移和城镇化发展研究报告》</strong>显示,相当一部分人只是从一个一线城市去往另一个一线城市,上海、广州、深圳人口迁入来源最多的城市均是北京。另外,杭州、成都、重庆、长沙等二线城市人口净流入强劲,而哈尔滨、大连、沈阳等城市人口流出却非常严重。净流入强劲的城市具有收入增速快、产业升级加速、人才政策力度大等特征。因此,杭州、成都、重庆、长沙等这些强二线城市也被称为了<strong>新一线</strong>。</p>
<p>对于刚毕业或工作几年但还没有家室的人来说,选择一个城市更多考虑的还是机会和财富增长的速度。但对于有家室有小孩的人来说,要考虑的因素就更多了,比如户口问题、小孩读书问题等。对于逃离大城市的人,有各种各样的理由,比如空气质量太差、房价太高、996 太变态、离家太远、小孩上不起学等等。</p>
<p>选择哪个城市无所谓对错,关键在于是否适合自己。不说别人,就说我自己。我 2009 年毕业后就长期在广州,在广州上大学、工作、成家,本来觉得应该会在广州定居了。2017 年下旬开始计划进军区块链,但发现,在广州,区块链方面的机会其实并不多,找了几次,没找到适合自己的机会。相比之下,深圳的机会则多得多。刚好,2018 年年初,有朋友给我引荐了一个深圳的机会,做去中心化交易所,正是适合我的机会,于是接了下来,年后就举家搬到深圳来了。这两年在深圳兜兜转转,虽然过得有些艰难,但发现深圳这边的机会明显比广州多很多,而且,资源也多,这两年结识了不少优质的人脉资源。至于房价高的问题,以后有钱就买,没钱就继续租房呗。另外,我也不想当房奴,所以我不会为了买房把全部身家都填进去。至于孩子教育问题,深圳那么多学校,不是都需要有户口有学区房才能上的,如果为了一个破旧的学区房花几百上千万,我还不如送小孩去读国际学校,甚至送出国,比如送去新加坡,新加坡的幼儿教育比国内好太多了。</p>
<p>其实,核心在于,我有我的梦想、目标,而目前留在深圳是有助于我去实现我的追求的,所以我不会因为各种困难而选择逃离。</p>
<h2 id="资产配置"><a href="#资产配置" class="headerlink" title="资产配置"></a>资产配置</h2><p>说到资产,第一个要聊的就是房地产。2019 年的房地产其实产生了分化,我就直接举两个案例。第一个案例,深圳市南山区深圳湾翡翠海岸一套 89 平方米的房子从 1650 万元的高位下跌至 270 万元成交。第二个案例,也是在深圳的,百花片区国城花园,43.5 平方米的 1 居室总价 1000 万元,单价达到 23 万元/平方米,而 103 平方米的 3 居室总价 1500 万元,单价为 14.6 万元/平方米,比 1 居室的单价还低了将近 10 万。</p>
<p>一个是靠海的海景房,一个是在市区的学区房,我们就只思考一个问题:哪个价值大?注意,我说的是「<strong>价值</strong>」,而不是「<strong>价格</strong>」。如果想不通这个问题,就无法理解上面的结果。</p>
<p>这也明显意味着房地产普涨的时代已经结束了,以后买房要看真实价值。</p>
<p>房地产之后再来聊聊资本市场,包括股票、债券、数字资产等。香帅老师是看多 2020 年中国的资本市场的,我也同样看多。</p>
<p>另外,我还看好区块链以及一些数字资产。2019 年,我因为玩合约,亏空了手上所有的币。2020 年,我将会再配置一些数字资产,如比特币、ATOM,但不会再玩合约了,只会囤现货。</p>
<h2 id="总结"><a href="#总结" class="headerlink" title="总结"></a>总结</h2><p>2020 年,我要打造多个收入渠道,除了继续提高主业收入,再发展副业应对未知的风险,以及屯点优质的数字资产等待升值。</p>
<hr>
<p>扫描以下二维码即可关注公众号(公众号名称:Keegan小钢)</p>
<img src="/post/default/20200106/qrcode_keegan.jpg">
</div>
<footer class="post-footer">
<div class="post-eof"></div>
</footer>
</div>
</article>
<article class="post post-type-normal" itemscope itemtype="http://schema.org/Article">
<div class="post-block">
<link itemprop="mainEntityOfPage" href="https://keeganlee.me/post/matching/20191204/">
<span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
<meta itemprop="name" content="Keegan小钢">
<meta itemprop="description" content="分享钢哥人生路上的点点滴滴">
<meta itemprop="image" content="/images/avatar.gif">
</span>
<span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
<meta itemprop="name" content="Keegan小钢">
</span>
<header class="post-header">
<h1 class="post-title" itemprop="name headline">
<a href="/post/matching/20191204/" class="post-title-link" itemprop="url">撮合引擎开发:完结篇</a>
</h1>
<div class="post-meta">
<span class="post-meta-item">
<span class="post-meta-item-icon">
<i class="fa fa-calendar-o"></i>
</span>
<span class="post-meta-item-text">发表于</span>
<time title="创建时间:2019-12-04 12:23:09" itemprop="dateCreated datePublished" datetime="2019-12-04T12:23:09+08:00">2019-12-04</time>
</span>
<span class="post-meta-item">
<span class="post-meta-item-icon">
<i class="fa fa-calendar-check-o"></i>
</span>
<span class="post-meta-item-text">更新于</span>
<time title="修改时间:2019-12-16 09:52:21" itemprop="dateModified" datetime="2019-12-16T09:52:21+08:00">2019-12-16</time>
</span>
<span class="post-meta-item">
<span class="post-meta-item-icon">
<i class="fa fa-folder-o"></i>
</span>
<span class="post-meta-item-text">分类于</span>
<span itemprop="about" itemscope itemtype="http://schema.org/Thing"><a href="/categories/matching/" itemprop="url" rel="index"><span itemprop="name">matching</span></a></span>
</span>
<br>
</div>
</header>
<div class="post-body" itemprop="articleBody">
<p>原创文章,转载请注明:转载自<a href="http://keeganlee.me/">Keegan小钢</a><br>并标明原文链接:<a href="http://keeganlee.me/post/matching/20191204"><strong>http://keeganlee.me/post/matching/20191204</strong></a><br>微信公众号:名称:Keegan小钢;微信号:keeganlee_me<br>写于2019-12-04</p>
<hr>
<p><a href="http://keeganlee.me/post/matching/20191117">撮合引擎开发:开篇</a><br><a href="http://keeganlee.me/post/matching/20191118">撮合引擎开发:MVP版本</a><br><a href="http://keeganlee.me/post/matching/20191119">撮合引擎开发:数据结构设计</a><br><a href="http://keeganlee.me/post/matching/20191121">撮合引擎开发:对接黑箱</a><br><a href="http://keeganlee.me/post/matching/20191127">撮合引擎开发:解密黑箱流程</a><br><a href="http://keeganlee.me/post/matching/20191130">撮合引擎开发:流程的代码实现</a><br><a href="http://keeganlee.me/post/matching/20191202">撮合引擎开发:缓存和MQ</a><br><a href="http://keeganlee.me/post/matching/20191203">撮合引擎开发:日志输出</a><br><a href="http://keeganlee.me/post/matching/20191204">撮合引擎开发:完结篇</a></p>
<hr>
<p>本小节是该系列文章的最后一篇了,将讲解剩下的一些东西,包括交易委托账本中订单队列的实现逻辑、更多订单类型的实现逻辑。另外,不少朋友在问,完结后所有代码是否会开源放上 Github?我只能说,长期大概率会开源,但短期内还没打算开源。</p>
<h2 id="订单队列"><a href="#订单队列" class="headerlink" title="订单队列"></a>订单队列</h2><p>交易委托账本其实就是由两个订单队列组成的,一个买单队列,一个卖单队列。任何对交易委托账本的查询和操作,实际上都是查询和操作这两个队列。订单队列的设计也直接影响了撮合的性能,前面文章讲数据结构设计时也有简单聊了订单队列的设计,我们主要是用二维链接结合 Map 来保存所有订单的,依赖的是 <strong>container/list</strong> 包。</p>
<p>订单队列的结构体如下:</p>
<figure class="highlight go"><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="keyword">type</span> orderQueue <span class="keyword">struct</span> {</span><br><span class="line"> sortBy enum.SortDirection</span><br><span class="line"> parentList *list.List</span><br><span class="line"> elementMap <span class="keyword">map</span>[<span class="keyword">string</span>]*list.Element</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<p><strong>sortBy</strong> 指定价格排序的方向,买单队列是降序的,而卖单队列则是升序的。<strong>parentList</strong> 保存整个二维链表的所有订单,第一维以价格排序,第二维以时间排序。<strong>elementMap</strong> 则是 Key 为价格、Value 为第二维订单链表的键值对。</p>
<p>初始化函数就比较简单了,对几个字段赋值而已,代码如下:</p>
<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">func</span> <span class="params">(q *orderQueue)</span> <span class="title">init</span><span class="params">(sortBy enum.SortDirection)</span></span> {</span><br><span class="line"> q.sortBy = sortBy</span><br><span class="line"> q.parentList = list.New()</span><br><span class="line"> q.elementMap = <span class="built_in">make</span>(<span class="keyword">map</span>[<span class="keyword">string</span>]*list.Element)</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<p>除了初始化函数,还提供了另外五个函数:</p>
<ul>
<li><strong>addOrder(order)</strong>:添加订单</li>
<li><strong>getHeadOrder()</strong>:读取头部订单</li>
<li><strong>popHeadOrder()</strong>:读取并删除头部订单</li>
<li><strong>removeOrder(order)</strong>:移除订单</li>
<li><strong>getDepthPrice(depth)</strong>:读取深度价格</li>
</ul>
<p>以上五个函数就只有第一个函数会比较复杂,为了让处理流程更容易理解,我就不贴代码了,画一个完整的流程图给大家看看:</p>
<img src="/post/matching/20191204/orderQueue-addOrder.png">
<p>这个流程确实有一点复杂,可以多看几遍好好消化,最好自己动手将其转为代码实现。</p>
<p>其他几个函数就简单了,关于最后一个函数需要补充说明一下。读取深度价格是为了方便处理 market-opponent、market-top5、market-top10 等类型的订单时判断上限价格。请看该函数的代码以理解该函数的逻辑和用法:</p>
<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">func</span> <span class="params">(q *orderQueue)</span> <span class="title">getDepthPrice</span><span class="params">(depth <span class="keyword">int</span>)</span> <span class="params">(<span class="keyword">string</span>, <span class="keyword">int</span>)</span></span> {</span><br><span class="line"> <span class="keyword">if</span> q.parentList.Len() == <span class="number">0</span> {</span><br><span class="line"> <span class="keyword">return</span> <span class="string">""</span>, <span class="number">0</span></span><br><span class="line"> }</span><br><span class="line"> p := q.parentList.Front()</span><br><span class="line"> i := <span class="number">1</span></span><br><span class="line"> <span class="keyword">for</span> ; i < depth; i++ {</span><br><span class="line"> t := p.Next()</span><br><span class="line"> <span class="keyword">if</span> t != <span class="literal">nil</span> {</span><br><span class="line"> p = t</span><br><span class="line"> } <span class="keyword">else</span> {</span><br><span class="line"> <span class="keyword">break</span>;</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> o := p.Value.(*list.List).Front().Value.(*Order)</span><br><span class="line"> <span class="keyword">return</span> o.Price.String(), i</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<h2 id="多种订单类型"><a href="#多种订单类型" class="headerlink" title="多种订单类型"></a>多种订单类型</h2><p>我们引擎总共支持了六种订单类型,之前的文章有简单介绍过,但没有深入讲解这几种不同类型的具体业务逻辑应该是怎样的,因此,在此将这部分内容补充上。</p>
<h3 id="1-limit"><a href="#1-limit" class="headerlink" title="1. limit"></a>1. limit</h3><p>普通限价是最简单的,前文也已经展示过代码实现,为了加深理解,我再给大家画一张图:</p>
<img src="/post/matching/20191204/limit.png">
<p>处理逻辑就是:</p>
<ol>
<li>判断新订单是买单还是卖单。</li>
<li>如果是买单,那从 OrderBook 中读取出头部卖单,即卖单队列中的头部订单;如果是卖单,那从 OrderBook 中读取出头部买单,即买单队列中的头部订单。</li>
<li>新订单为买单时,如果头部订单为空,或者新订单小于头部订单,即无法成交,那就把新订单添加到买单队列中,处理结束;新订单为卖单时,如果头部订单为空,或者新订单大于头部订单,即无法成交,那就把新订单添加到卖单队列中,处理结束。</li>
<li>否则,符合匹配条件,新订单和头部订单进行撮合成交。</li>
<li>撮合完成后,如果新订单剩余数量为零则结束,如果还大于零,则回到第2步继续取下一个头部订单,如此循环。</li>
</ol>
<h3 id="2-limit-ioc"><a href="#2-limit-ioc" class="headerlink" title="2. limit-ioc"></a>2. limit-ioc</h3><p>IOC 限价与普通限价不同的地方只有一个,如果新订单和头部订单不匹配时,普通限价单会被添加到订单队列中,而 IOC 限价则是作撤单处理,请看下图:</p>
<img src="/post/matching/20191204/limit-ioc.png">
<h3 id="3-market"><a href="#3-market" class="headerlink" title="3. market"></a>3. market</h3><p>默认市价单的逻辑也比较简单,它不需要判断价格,只要头部订单不为空,就直接和头部订单匹配成交,其处理逻辑如下图:</p>
<img src="/post/matching/20191204/market.png">
<h3 id="4-market-top5-market-top10"><a href="#4-market-top5-market-top10" class="headerlink" title="4. market-top5/market-top10"></a>4. market-top5/market-top10</h3><p>最优五档/十档市价单与默认市价单的逻辑也是类似的,不同点在于:默认市价的成交价格没有上限或下限,但最优五档/十档市价则存在价格上限或下限,超过上下限的委托单不会成交。画图太累,还是直接贴代码吧,以下是处理买单的:</p>
<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">dealBuyMarketTop</span><span class="params">(order *Order, book *orderBook, lastTradePrice *decimal.Decimal, depth <span class="keyword">int</span>)</span></span> {</span><br><span class="line"> priceStr, _ := book.getSellDepthPrice(depth)</span><br><span class="line"> <span class="keyword">if</span> priceStr == <span class="string">""</span> {</span><br><span class="line"> cancelOrder(order)</span><br><span class="line"> <span class="keyword">return</span></span><br><span class="line"> }</span><br><span class="line"> limitPrice, _ := decimal.NewFromString(priceStr)</span><br><span class="line">LOOP:</span><br><span class="line"> headOrder := book.getHeadSellOrder()</span><br><span class="line"> <span class="keyword">if</span> headOrder != <span class="literal">nil</span> && limitPrice.GreaterThanOrEqual(headOrder.Price) {</span><br><span class="line"> matchTrade(headOrder, order, book, lastTradePrice)</span><br><span class="line"> <span class="keyword">if</span> order.Amount.IsPositive() {</span><br><span class="line"> <span class="keyword">goto</span> LOOP</span><br><span class="line"> }</span><br><span class="line"> } <span class="keyword">else</span> {</span><br><span class="line"> cancelOrder(order)</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<h3 id="5-market-opponent"><a href="#5-market-opponent" class="headerlink" title="5. market-opponent"></a>5. market-opponent</h3><p>最后一种类型,对手方最优价,该类型只与对手方一档的价位成交,但与最优五档/十档还有一点不一样:最优五档/十档未成交的部分是作撤单处理的,而对手方最优价最后未成交的部分则是转为限价单。请看代码:</p>
<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">dealBuyMarketOpponent</span><span class="params">(order *Order, book *orderBook, lastTradePrice *decimal.Decimal)</span></span> {</span><br><span class="line"> priceStr, _ := book.getSellDepthPrice(<span class="number">1</span>)</span><br><span class="line"> <span class="keyword">if</span> priceStr == <span class="string">""</span> {</span><br><span class="line"> cancelOrder(order)</span><br><span class="line"> <span class="keyword">return</span></span><br><span class="line"> }</span><br><span class="line"> limitPrice, _ := decimal.NewFromString(priceStr)</span><br><span class="line">LOOP:</span><br><span class="line"> headOrder := book.getHeadSellOrder()</span><br><span class="line"> <span class="keyword">if</span> headOrder != <span class="literal">nil</span> && limitPrice.GreaterThanOrEqual(headOrder.Price) {</span><br><span class="line"> matchTrade(headOrder, order, book, lastTradePrice)</span><br><span class="line"> <span class="keyword">if</span> order.Amount.IsPositive() {</span><br><span class="line"> <span class="keyword">goto</span> LOOP</span><br><span class="line"> }</span><br><span class="line"> } <span class="keyword">else</span> {</span><br><span class="line"> order.Price = limitPrice</span><br><span class="line"> order.Type = enum.TypeLimit</span><br><span class="line"> book.addBuyOrder(order)</span><br><span class="line"> cache.UpdateOrder(order.ToMap())</span><br><span class="line"> log.Info(<span class="string">"engine %s, a order has added to the orderbook: %s"</span>, order.Symbol, order.ToJson())</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<h2 id="完结"><a href="#完结" class="headerlink" title="完结"></a>完结</h2><p>至此,整个系列就此完结。不过,我的撮合程序依然会继续迭代升级,另外,也将开始开发其他组件,将会和当前这个撮合引擎结合来用。欢迎关注后续动态。</p>
<hr>
<p>扫描以下二维码即可关注公众号(公众号名称:Keegan小钢)</p>
<img src="/post/matching/20191204/qrcode_keegan.jpg">
</div>
<footer class="post-footer">
<div class="post-eof"></div>
</footer>
</div>
</article>
<article class="post post-type-normal" itemscope itemtype="http://schema.org/Article">
<div class="post-block">
<link itemprop="mainEntityOfPage" href="https://keeganlee.me/post/matching/20191203/">
<span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
<meta itemprop="name" content="Keegan小钢">
<meta itemprop="description" content="分享钢哥人生路上的点点滴滴">
<meta itemprop="image" content="/images/avatar.gif">
</span>
<span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
<meta itemprop="name" content="Keegan小钢">
</span>
<header class="post-header">
<h1 class="post-title" itemprop="name headline">
<a href="/post/matching/20191203/" class="post-title-link" itemprop="url">撮合引擎开发:日志输出</a>
</h1>
<div class="post-meta">
<span class="post-meta-item">
<span class="post-meta-item-icon">
<i class="fa fa-calendar-o"></i>
</span>
<span class="post-meta-item-text">发表于</span>
<time title="创建时间:2019-12-03 10:32:34" itemprop="dateCreated datePublished" datetime="2019-12-03T10:32:34+08:00">2019-12-03</time>
</span>
<span class="post-meta-item">
<span class="post-meta-item-icon">
<i class="fa fa-calendar-check-o"></i>
</span>