-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathatom.xml
947 lines (735 loc) · 162 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
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
<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
<title>XueCat</title>
<subtitle>用代码创造世界</subtitle>
<link href="/atom.xml" rel="self"/>
<link href="https://xuecat.github.io/"/>
<updated>2021-08-05T14:09:44.362Z</updated>
<id>https://xuecat.github.io/</id>
<author>
<name>XueCat</name>
</author>
<generator uri="http://hexo.io/">Hexo</generator>
<entry>
<title>go(258)</title>
<link href="https://xuecat.github.io/2021/06/05/258/"/>
<id>https://xuecat.github.io/2021/06/05/258/</id>
<published>2021-06-05T14:06:38.000Z</published>
<updated>2021-08-05T14:09:44.362Z</updated>
<content type="html"><![CDATA[<h3 id="go"><a href="#go" class="headerlink" title="go"></a>go</h3><h4 id="包"><a href="#包" class="headerlink" title="包"></a>包</h4><p> 包名最好是小写;导入多个包时,最好按照字母顺序排列方便易读。</p>
<p> 如果包名不是以 . 或 / 开头,如 “fmt” 或者 “container/list”,则 Go 会在全局文件进行查找;如果包名以 ./ 开头,则 Go 会在相对目录中查找;如果包名以 / 开头(在 Windows 下也可以这样使用),则会在系统的绝对路径中查找。<br> <figure class="highlight xl"><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></pre></td><td class="code"><pre><div class="line"><span class="keyword">import</span> <span class="string">"fmt"</span></div><div class="line"><span class="keyword">import</span> <span class="string">"os"</span></div><div class="line"></div><div class="line"><span class="keyword">import</span> <span class="string">"fmt"</span>; <span class="keyword">import</span> <span class="string">"os"</span></div><div class="line"></div><div class="line"><span class="keyword">import</span> (</div><div class="line"> <span class="string">"fmt"</span></div><div class="line"> <span class="string">"os"</span></div><div class="line"> )</div><div class="line"></div><div class="line"><span class="keyword">import</span> (<span class="string">"fmt"</span>; <span class="string">"os"</span>)</div></pre></td></tr></table></figure></p>
]]></content>
<summary type="html">
<h3 id="go"><a href="#go" class="headerlink" title="go"></a>go</h3><h4 id="包"><a href="#包" class="headerlink" title="包"></a>包</h4><p> 包名最好是小
</summary>
<category term="语言" scheme="https://xuecat.github.io/categories/%E8%AF%AD%E8%A8%80/"/>
<category term="Golang" scheme="https://xuecat.github.io/tags/Golang/"/>
</entry>
<entry>
<title>zookeeper(257)</title>
<link href="https://xuecat.github.io/2021/05/05/257/"/>
<id>https://xuecat.github.io/2021/05/05/257/</id>
<published>2021-05-05T14:00:06.000Z</published>
<updated>2021-08-05T14:06:18.974Z</updated>
<content type="html"><![CDATA[<h3 id="Zookeeper"><a href="#Zookeeper" class="headerlink" title="Zookeeper"></a>Zookeeper</h3><p>提供了文件系统和通知机制</p>
<h4 id="文件系统"><a href="#文件系统" class="headerlink" title="文件系统"></a>文件系统</h4><p>目录就是znode,能自由删除、增加znode,并可以存储数据。<br><strong>PERSISTENT-持久化目录节点</strong>:客户端与zookeeper断开连接后,该节点依旧存在<br><strong>PERSISTENT_SEQUENTIAL-持久化顺序编号目录节点</strong>:客户端与zookeeper断开连接后,该节点依旧存在,只是Zookeeper给该节点名称进行顺序编号<br><strong>EPHEMERAL-临时目录节点</strong>:客户端与zookeeper断开连接后,该节点被删除<br><strong>EPHEMERAL_SEQUENTIAL-临时顺序编号目录节点</strong>:客户端与zookeeper断开连接后,该节点被删除,只是Zookeeper给该节点名称进行顺序编号 </p>
<p>客户端注册监听它关心的目录节点,当目录节点发生变化(数据改变、被删除、子目录节点增加删除)时,zookeeper会通知客户端</p>
<h4 id="配置管理"><a href="#配置管理" class="headerlink" title="配置管理"></a>配置管理</h4><p>保存在 Zookeeper 的某个目录节点中,然后所有相关应用程序对这个目录节点进行监听,一旦配置信息发生变化,每个应用程序就会收到 Zookeeper 的通知,然后从 Zookeeper 获取新的配置信息应用到系统中就好</p>
<h4 id="分布式锁"><a href="#分布式锁" class="headerlink" title="分布式锁"></a>分布式锁</h4>]]></content>
<summary type="html">
<h3 id="Zookeeper"><a href="#Zookeeper" class="headerlink" title="Zookeeper"></a>Zookeeper</h3><p>提供了文件系统和通知机制</p>
<h4 id="文件系统"><a href="#文
</summary>
<category term="第三方库" scheme="https://xuecat.github.io/categories/%E7%AC%AC%E4%B8%89%E6%96%B9%E5%BA%93/"/>
<category term="Zookeeper" scheme="https://xuecat.github.io/tags/Zookeeper/"/>
</entry>
<entry>
<title>mysql(255)</title>
<link href="https://xuecat.github.io/2021/04/15/255/"/>
<id>https://xuecat.github.io/2021/04/15/255/</id>
<published>2021-04-15T11:27:38.000Z</published>
<updated>2021-08-05T13:47:20.919Z</updated>
<content type="html"><![CDATA[<p>索引类型:</p>
<pre><code>普通索引:最基本的索引,没有任何限制
唯一索引:与"普通索引"类似,不同的就是:索引列的值必须唯一,但允许有空值。
主键索引:它 是一种特殊的唯一索引,不允许有空值。
全文索引:仅可用于 MyISAM 表,针对较大的数据,生成全文索引很耗时好空间。
组合索引:为了更多的提高mysql效率可建立组合索引,遵循”最左前缀“原则。
</code></pre><p>索引结构: B-tree索引 哈希索引 全文索引</p>
<p>不要使用索引情况:</p>
<pre><code>区分度不是很大的字段
频繁更新的字段
字符串类型的字段 或者 文本类型的字段
不在where列中出现的索引
</code></pre><p>索引失效:</p>
<pre><code>* 查询列中有函数计算
* 查询列中有模糊查询,"%cloum","%cloum%",可以使用"cloum%" 代替。实在用这个索引,新增一列(使用`LOCATE` `POSITION`函数也可以加索引),存储该字段的反转。比如原字段是abcd,取反存储为dcba,查询%bcd改成查dcb%
* 如果查询条件中有or, 索引会失效,除非所有条件都加上索引
* 使用不等于(!= 或者 <>)
* is null 或者 is not null
* 字符串不加引号,会导致索引失效
* 没有最左原则
</code></pre><p>索引和锁:</p>
<pre><code>加锁的过程要分有索引和无索引两种情况,比如下面这条语句
update user set age=11 where id = 1
id 是这张表的主键,是有索引的情况,那么 MySQL 直接就在索引数中找到了这行数据,然后干净利落的加上行锁就可以了。
而下面这条语句
update user set age=11 where age=10
表中并没有为 age 字段设置索引,所以, MySQL 无法直接定位到这行数据。那怎么办呢,当然也不是加表锁了。MySQL 会为这张表中所有行加行锁,没错,是所有行。但是呢,在加上行锁后,MySQL 会进行一遍过滤,发现不满足的行就释放锁,最终只留下符合条件的行。虽然最终只为符合条件的行加了锁,但是这一锁一释放的过程对性能也是影响极大的。
</code></pre><h3 id="聚集索引和普通索引"><a href="#聚集索引和普通索引" class="headerlink" title="聚集索引和普通索引"></a>聚集索引和普通索引</h3><p>对于mysql来说<code>聚集索引</code>就是<code>主键索引</code>,<code>聚集索引</code>的叶子节点存储记录,<code>普通索引</code>的叶子节点存储存储主键值</p>
<h4 id="回表"><a href="#回表" class="headerlink" title="回表"></a>回表</h4><p>聚集索引<code>PRIMARY KEY</code> 叶子节点存储行记录<br>普通索引 <code>INDEX index_name (column_list)</code>和<code>unique</code></p>
<p><img src="/picture/ta.png" alt=""></p>
<figure class="highlight sql"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">select</span> * <span class="keyword">from</span> t <span class="keyword">where</span> <span class="keyword">name</span>=<span class="string">'lisi'</span>;</div></pre></td></tr></table></figure>
<p>这个语句需要扫码俩遍索引树:</p>
<ol>
<li>先通过普通索引定位到主键值</li>
<li>在通过聚集索引定位到行记录</li>
</ol>
<p>这就是所谓的回表查询,先定位主键值,再定位行记录。</p>
<h3 id="索引覆盖"><a href="#索引覆盖" class="headerlink" title="索引覆盖"></a>索引覆盖</h3><p>explain的输出结果Extra字段为Using index时,能够触发索引覆盖<br><figure class="highlight sql"><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"><span class="keyword">select</span> <span class="keyword">id</span>,<span class="keyword">name</span> <span class="keyword">from</span> <span class="keyword">user</span> <span class="keyword">where</span> <span class="keyword">name</span>=<span class="string">'shenjian'</span>; //通过name的索引树直接能找到id和name所需的数据,无需回表</div><div class="line"></div><div class="line"><span class="keyword">select</span> <span class="keyword">id</span>,<span class="keyword">name</span>,sex <span class="keyword">from</span> <span class="keyword">user</span> <span class="keyword">where</span> <span class="keyword">name</span>=<span class="string">'shenjian'</span>;//通过name的索引子节点找到id,但是sex自动需要回表才能查询,所以没有索引覆盖</div></pre></td></tr></table></figure></p>
<ol>
<li><code>select cout(name) from user;</code>如果这个是索引就会索引覆盖</li>
<li>用联合索引可以避免回表</li>
</ol>
<ol>
<li><p><code>最左前缀</code> </p>
<p><code>explain</code> type为all表示全文扫描。type为ref,表示使用非唯一索引扫描或唯一索引扫描</p>
</li>
</ol>
<ul>
<li>只有复合索引才会有所谓的左和右之分</li>
<li>查询从索引的最左前列开始并且不跳过索引中的列,通俗易懂的来说就是:带头大哥不能死、中间兄弟不能断</li>
</ul>
<p><img src="/picture/255.png" alt=""></p>
<ol>
<li><p><code>TRIGGER</code>触发器</p>
<p> DELIMITER $$<br> CREATE<br> TRIGGER <code>jony_keer</code>.<code>ins_account</code> AFTER INSERT<br> ON <code>jony_keer</code>.<code>t_account</code><br> FOR EACH ROW BEGIN<br> INSERT INTO <code>t_user</code>(<code>userid</code>,<code>cellphone</code>,<code>account_psd</code>) VALUES (new.<code>account_id</code>,new.<code>cellphone</code>,new.<code>account_psd</code>);<br> END$$<br> DELIMITER ;</p>
<p> mysql解释器根据‘;’来结束读取命令执行命令,在多个‘;’号时,解释器不知到在哪一句结束读取命令执行命令,而delimiter的作用是,将sql结束读取命令并执行命令的标志,替换成delimiter后的标志(在本文是‘//’),这样只有当‘//’出现之后,mysql解释器才会执行这段语句。</p>
</li>
<li><p>存储过程和函数</p>
<p> 主要区别就是函数必须有返回值(return),并且函数的参数只有IN类型而存储过程有IN、OUT、INOUT这三种类型。</p>
</li>
<li><p><strong><em>MySQL 事务都是指在 InnoDB 引擎下,MyISAM 引擎是不支持事务的</em></strong></p>
<p> 事务具有: 原子性 一致性 隔离性 持久性, 随便一个<code>update</code>都能是个事务</p>
<p> <code>select @@tx_isolation;</code>来查当前数据的隔离级别</p>
<ol>
<li>读未提交(read uncommitted)</li>
<li>读提交(read committed)</li>
<li>可重复读(repeatable read)</li>
<li><p>串行化(serializable)</p>
<p>一. 读未提交是不加锁的,连<code>脏读(数据可能回滚)</code>都无法解决。</p>
<p>二. 读提交就是事务只能读到其他事务调用 commit 命令之后的数据,能解决<code>脏读</code>,不能解决<code>可重复读(事务中修改条件数据)</code>,<code>幻读(事务中加减条件数据)</code>。</p>
<p>三. 可重复读(mysql默认读)是指,事务不会读到其他事务对已有数据的修改,及时其他事务已提交,也就是说,事务开始时读到的已有数据是什么,在事务提交前的任意时刻,这些数据的值都是一样的。 解决了<code>可重复读</code>,实际也解决了<code>幻读</code>。</p>
<p>解决方法是:</p>
</li>
<li>版本快照解决<code>可重复读</code>,事务开始的读叫<code>当前读</code>,事务中用<code>快照读</code>。</li>
<li><p>间隙锁解决<code>幻读</code>,通过索引锁范围,保证添加删除新的会等待</p>
<p>四. 串行化是4种事务隔离级别中隔离效果最好的,解决了脏读、可重复读、幻读的问题,但是效果最差,它将事务的执行变为顺序执行,与其他三个隔离级别相比,它就相当于单线程,后一个事务的执行必须等待前一个事务结束</p>
</li>
</ol>
</li>
</ol>
<p><strong>结语:</strong> 通常,对于绝大多数的应用程序来说,可以优先考虑将数据库系统的隔离级别设置为读已提交(Read Committed),这能够在避免脏读的同时保证较好的并发性能。尽管这种事务隔离级别会导致不可重复读、幻读和第二类丢失更新等并发问题,但较为科学的做法是在可能出现这类问题的个别场合中,由应用程序主动采用悲观锁或乐观锁来进行事务控制。</p>
<h3 id="分布式事务"><a href="#分布式事务" class="headerlink" title="分布式事务"></a>分布式事务</h3><h4 id="两段提交"><a href="#两段提交" class="headerlink" title="两段提交"></a>两段提交</h4><p>协调者先询问参与者事务是否执行成功,参与者向协调者返回成功。协调者再发送通知让参与者提交事务;否则,协调者发送通知让参与者回滚事务。<br>假如在第一阶段有一个参与者返回失败,那么协调者就会向所有参与者发送回滚事务的请求,即分布式事务执行失败。</p>
<h4 id="补偿事务"><a href="#补偿事务" class="headerlink" title="补偿事务"></a>补偿事务</h4><p>针对每个操作,都要注册一个与其对应的确认和补偿(撤销)操作。例如:</p>
<p> 1.首先在 Try 阶段,要先调用远程接口把 Smith 和 Bob 的钱给冻结起来。<br> 2.在 Confirm 阶段,执行远程调用的转账的操作,转账成功进行解冻。<br> 3.如果第2步执行成功,那么转账成功,如果第二步执行失败,则调用远程冻结接口对应的解冻方法 (Cancel)。</p>
<h4 id="本地消息表"><a href="#本地消息表" class="headerlink" title="本地消息表"></a>本地消息表</h4><p>本地写业务数据后,记录本地消息队列再发到kafka,转发成功再删除本地消息队列。另一方读取kafka消息队列并处理</p>
<h4 id="MQ事务消息"><a href="#MQ事务消息" class="headerlink" title="MQ事务消息"></a>MQ事务消息</h4>]]></content>
<summary type="html">
<p>索引类型:</p>
<pre><code>普通索引:最基本的索引,没有任何限制
唯一索引:与&quot;普通索引&quot;类似,不同的就是:索引列的值必须唯一,但允许有空值。
主键索引:它 是一种特殊的唯一索引,不允许有空值。
全文索引:仅可用于 MyISAM 表
</summary>
<category term="数据库" scheme="https://xuecat.github.io/categories/%E6%95%B0%E6%8D%AE%E5%BA%93/"/>
<category term="学习看书笔记" scheme="https://xuecat.github.io/tags/%E5%AD%A6%E4%B9%A0%E7%9C%8B%E4%B9%A6%E7%AC%94%E8%AE%B0/"/>
<category term="Mysql" scheme="https://xuecat.github.io/tags/Mysql/"/>
</entry>
<entry>
<title>kafka/依赖注入(256)</title>
<link href="https://xuecat.github.io/2021/03/29/256/"/>
<id>https://xuecat.github.io/2021/03/29/256/</id>
<published>2021-03-29T13:08:52.000Z</published>
<updated>2021-08-05T13:13:35.702Z</updated>
<content type="html"><![CDATA[<ol>
<li><p><code>kafka</code></p>
<p> <img src="/picture/2551.png" alt=""></p>
<p> 对于一个group而言,消费者的数量不应该多余分区的数量,因为在一个group中,每个分区至多只能绑定到一个消费者上,即一个消费者可以消费多个分区,一个分区只能给一个消费者消费</p>
<p> 因此,若一个group中的消费者数量大于分区数量的话,多余的消费者将不会收到任何消息</p>
</li>
<li><p>依赖注入</p>
<p> Scoped方式是每个请求时创建一个新的实例,但Transient是每个请求中调用每个服务都会创建一个新的实例,在一次请求中,如果在Singleton中还使用Scoped的话,Scoped和Singleton的意义是一样的(比如我这次请求的时候正常Scoped产生的值是1,我在其它服务中使用的值都将是1,但是在Singleton中保存的值还是0,这样就会产生歧义),但如果Singleton中使用Transient的话只针对当前服务中是唯一的,调用其它服务的时候Transient还是会创建新的实例,因此在其它服务中就不会有其它问题(简单来讲就是默认我在Singleton中调用Transient时我就默认产生的值就为0,反正我每次请求都会产生新的值,无所谓是0还是1,还是2了),虽然没有报错但我们还是要避免这样使用。</p>
</li>
<li><p>浮点数无损定点化</p>
</li>
</ol>
]]></content>
<summary type="html">
<ol>
<li><p><code>kafka</code></p>
<p> <img src="/picture/2551.png" alt=""></p>
<p> 对于一个group而言,消费者的数量不应该多余分区的数量,因为在一个group中,每个分区至多只能绑定到一个消费
</summary>
<category term="杂项" scheme="https://xuecat.github.io/categories/%E6%9D%82%E9%A1%B9/"/>
<category term="kafka" scheme="https://xuecat.github.io/tags/kafka/"/>
<category term=".NET Core" scheme="https://xuecat.github.io/tags/NET-Core/"/>
</entry>
<entry>
<title>jenkins配置(254)</title>
<link href="https://xuecat.github.io/2020/11/02/254/"/>
<id>https://xuecat.github.io/2020/11/02/254/</id>
<published>2020-11-02T14:30:42.000Z</published>
<updated>2021-08-05T13:09:18.391Z</updated>
<content type="html"><![CDATA[<figure class="highlight stata"><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><div class="line">35</div><div class="line">36</div><div class="line">37</div><div class="line">38</div><div class="line">39</div><div class="line">40</div><div class="line">41</div><div class="line">42</div><div class="line">43</div><div class="line">44</div><div class="line">45</div><div class="line">46</div><div class="line">47</div><div class="line">48</div><div class="line">49</div><div class="line">50</div><div class="line">51</div><div class="line">52</div></pre></td><td class="code"><pre><div class="line">name=ingestdbsvr</div><div class="line"><span class="keyword">version</span>=1.8.5</div><div class="line">time=$(date +%Y%<span class="keyword">m</span>%<span class="keyword">d</span>%<span class="keyword">H</span>)</div><div class="line">images=<span class="variable">${name}</span>:<span class="variable">${version}</span>.<span class="variable">${time}</span>.<span class="variable">${BUILD_NUMBER}</span></div><div class="line">tarname=<span class="variable">${images}</span>.tar</div><div class="line">pushurl=172.16.128.170:5000/<span class="variable">${images}</span></div><div class="line">date +%<span class="keyword">H</span>:%<span class="keyword">M</span>:%<span class="built_in">S</span></div><div class="line">dotnet build -c Release IngestDB.sln</div><div class="line"><span class="keyword">cd</span> IngestDB </div><div class="line">dotnet publish -c Release -o ../publish</div><div class="line"><span class="keyword">cd</span> ..</div><div class="line">cp BinU/netcoreapp2.1/IngestDB.dll -r publish/</div><div class="line">cp BinU/netcoreapp2.1/IngestDBCore.dll -r publish/</div><div class="line"></div><div class="line">cp BinU/netcoreapp2.1/<span class="keyword">Plugin</span>/IngestMatrixPlugin.dll -r publish/<span class="keyword">Plugin</span>/</div><div class="line">cp BinU/netcoreapp2.1/<span class="keyword">Plugin</span>/IngestDeviceInterfacePlugin.dll -r publish/<span class="keyword">Plugin</span>/</div><div class="line">cp BinU/netcoreapp2.1/<span class="keyword">Plugin</span>/IngestGlobalInterfacePlugin.dll -r publish/<span class="keyword">Plugin</span>/</div><div class="line">cp BinU/netcoreapp2.1/<span class="keyword">Plugin</span>/IngestTaskInterfacePlugin.dll -r publish/<span class="keyword">Plugin</span>/</div><div class="line">cp BinU/netcoreapp2.1/<span class="keyword">Plugin</span>/IngestTaskPlugin.dll -r publish/<span class="keyword">Plugin</span>/</div><div class="line">cp BinU/netcoreapp2.1/<span class="keyword">Plugin</span>/IngestDevicePlugin.dll -r publish/<span class="keyword">Plugin</span>/</div><div class="line">cp BinU/netcoreapp2.1/<span class="keyword">Plugin</span>/MSVNotifyPlugin.dll -r publish/<span class="keyword">Plugin</span>/</div><div class="line">cp BinU/netcoreapp2.1/<span class="keyword">Plugin</span>/IngestGlobalPlugin.dll -r publish/<span class="keyword">Plugin</span>/</div><div class="line">cp BinU/netcoreapp2.1/<span class="keyword">Plugin</span>/KafKaNotifyPlugin.dll -r publish/<span class="keyword">Plugin</span>/</div><div class="line">cp BinU/netcoreapp2.1/<span class="keyword">Plugin</span>/UdpNotifyPlugin.dll -r publish/<span class="keyword">Plugin</span>/</div><div class="line"></div><div class="line">#docker images | grep 'ingestdbsvr' | awk '{<span class="keyword">print</span> <span class="variable">$3}</span>' | xargs docker rmi</div><div class="line">chmod -Rf 777 publish</div><div class="line">docker build -t <span class="variable">$images</span> .</div><div class="line">docker tag <span class="variable">$images</span> <span class="variable">$pushurl</span></div><div class="line">docker push <span class="variable">$pushurl</span></div><div class="line"></div><div class="line">time=$(date +%Y%<span class="keyword">m</span>%<span class="keyword">d</span>%<span class="keyword">H</span>)</div><div class="line">appname=ingestdbsvr</div><div class="line"><span class="keyword">version</span>=1.8.5.<span class="variable">${time}</span>.<span class="variable">${BUILD_NUMBER}</span></div><div class="line">images=<span class="variable">${appname}</span>:<span class="variable">${version}</span></div><div class="line">Oldtag=`docker images|grep <span class="variable">${appname}</span>|awk '{<span class="keyword">print</span> <span class="variable">$2}</span>'|<span class="keyword">sort</span> -r|awk 'NR==1{<span class="keyword">print</span>}'`</div><div class="line">container=`docker ps -a|grep <span class="variable">${appname}</span>|awk '{<span class="keyword">print</span> <span class="variable">$1}</span>'|<span class="keyword">sort</span> -r|awk 'NR==1{<span class="keyword">print</span>}'`</div><div class="line">echo <span class="variable">${appname}</span>-<span class="variable">${Oldtag}</span></div><div class="line">echo <span class="variable">${appname}</span>-<span class="variable">${version}</span></div><div class="line">echo <span class="variable">${appname}</span>:<span class="variable">${container}</span></div><div class="line">docker stop <span class="variable">${container}</span></div><div class="line">docker <span class="keyword">rm</span> -f <span class="variable">${container}</span></div><div class="line"><span class="keyword">mkdir</span> /sobeyhive/<span class="keyword">app</span>/<span class="variable">${appname}</span>-<span class="variable">${version}</span></div><div class="line">cp -rp /sobeyhive/<span class="keyword">app</span>/<span class="variable">${appname}</span>-notchange/<span class="keyword">run</span>.<span class="keyword">sh</span> /sobeyhive/<span class="keyword">app</span>/<span class="variable">${appname}</span>-<span class="variable">${version}</span>/</div><div class="line"><span class="keyword">rm</span> -fr /sobeyhive/<span class="keyword">app</span>/<span class="variable">${appname}</span>-<span class="variable">${Oldtag}</span> </div><div class="line"><span class="keyword">cd</span> /RunScript/ </div><div class="line"><span class="keyword">sh</span> ingestdbsvrsrg.<span class="keyword">sh</span> <span class="variable">${version}</span></div><div class="line"><span class="keyword">sleep</span> 5</div><div class="line"></div><div class="line">scp -r /other/sobeyhive/<span class="keyword">app</span>/ingestmsgsvr-1.6.0/ingestmsgsvr<span class="comment">/* [email protected]:/other/jenkins/workspace/IngestMsgSvr-Integration-SRG1.8.5/publish/ </span></div><div class="line"> </div><div class="line">sleep 1</div></pre></td></tr></table></figure>
]]></content>
<summary type="html">
<figure class="highlight stata"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</di
</summary>
<category term="配置" scheme="https://xuecat.github.io/categories/%E9%85%8D%E7%BD%AE/"/>
<category term="工具" scheme="https://xuecat.github.io/tags/%E5%B7%A5%E5%85%B7/"/>
<category term="杂项" scheme="https://xuecat.github.io/tags/%E6%9D%82%E9%A1%B9/"/>
</entry>
<entry>
<title>c#语法糖253</title>
<link href="https://xuecat.github.io/2020/10/22/253/"/>
<id>https://xuecat.github.io/2020/10/22/253/</id>
<published>2020-10-22T14:13:33.000Z</published>
<updated>2020-11-03T15:27:26.820Z</updated>
<content type="html"><![CDATA[<p><a href="https://help.semmle.com/wiki/display/CSHARP/Abstract+class+only+declares+common+constants" target="_blank" rel="external">原文章地址</a></p>
<h2 id=""><a href="#" class="headerlink" title=""></a><img src="/picture/253_11.jpg" alt=""></h2><ol>
<li><code>abstract</code>类最好用来声明公共<code>const</code>变量</li>
</ol>
<figure class="highlight cs"><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></pre></td><td class="code"><pre><div class="line"><span class="keyword">class</span> <span class="title">Bad</span></div><div class="line">{</div><div class="line"> <span class="keyword">abstract</span> <span class="keyword">class</span> <span class="title">MathConstants</span></div><div class="line"> {</div><div class="line"> <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">readonly</span> <span class="keyword">double</span> Pi = <span class="number">3.14</span>;</div><div class="line"> }</div><div class="line"> </div><div class="line"> <span class="keyword">class</span> <span class="title">Circle</span> : <span class="title">MathConstants</span></div><div class="line"> {</div><div class="line"> <span class="keyword">private</span> <span class="keyword">double</span> radius;</div><div class="line"> </div><div class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">double</span> <span class="title">Area</span>(<span class="params"></span>) </span>=> Math.Pow(radius, <span class="number">2</span>) * Pi;</div><div class="line"> }</div><div class="line">}</div></pre></td></tr></table></figure>
<ol>
<li><code>ReadOnlyCollection</code>替换<code>Array</code>的<code>readonly</code></li>
</ol>
<figure class="highlight cs"><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></pre></td><td class="code"><pre><div class="line"><span class="comment">//错误</span></div><div class="line"><span class="keyword">class</span> <span class="title">Bad</span></div><div class="line">{</div><div class="line"> <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">readonly</span> <span class="keyword">string</span>[] Foo = { <span class="string">"hello"</span>, <span class="string">"world"</span> };</div><div class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">Main</span>(<span class="params"><span class="keyword">string</span>[] args</span>)</span></div><div class="line"> {</div><div class="line"> Foo[<span class="number">0</span>] = <span class="string">"goodbye"</span>;</div><div class="line"> }</div><div class="line">}</div><div class="line"></div><div class="line"><span class="comment">//对的</span></div><div class="line"><span class="keyword">class</span> <span class="title">Good</span></div><div class="line">{</div><div class="line"> <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">readonly</span> ReadOnlyCollection<<span class="keyword">string</span>> Foo</div><div class="line"> = <span class="keyword">new</span> ReadOnlyCollection<<span class="keyword">string</span>>(<span class="keyword">new</span> <span class="keyword">string</span>[] { <span class="string">"hello"</span>, <span class="string">"world"</span> });</div><div class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">Main</span>(<span class="params"><span class="keyword">string</span>[] args</span>)</span></div><div class="line"> {</div><div class="line"> </div><div class="line"> }</div><div class="line">}</div></pre></td></tr></table></figure>
<ol>
<li><code>Assembly</code>的代码</li>
</ol>
<figure class="highlight cs"><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></pre></td><td class="code"><pre><div class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title">AssemblyPathInjectionHandler</span> : <span class="title">IHttpHandler</span> {</div><div class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">ProcessRequest</span>(<span class="params">HttpContext ctx</span>) </span>{</div><div class="line"> <span class="keyword">string</span> configType = ctx.Request.QueryString[<span class="string">"configType"</span>];</div><div class="line"> </div><div class="line"> <span class="keyword">if</span> (configType.equals(<span class="string">"configType1"</span>) || configType.equals(<span class="string">"configType2"</span>)) {</div><div class="line"> <span class="comment">// GOOD: Loaded assembly is one of the two known safe options</span></div><div class="line"> <span class="keyword">var</span> safeAssembly = Assembly.LoadFile(<span class="string">@"C:\SafeLibraries\"</span> + configType + <span class="string">".dll"</span>);</div><div class="line"> </div><div class="line"> <span class="comment">// Code execution is limited to one of two known and vetted assemblies</span></div><div class="line"> MethodInfo m = safeAssembly.GetType(<span class="string">"Config"</span>).GetMethod(<span class="string">"GetCustomPath"</span>);</div><div class="line"> Object customPath = m.Invoke(<span class="literal">null</span>, <span class="literal">null</span>);</div><div class="line"> <span class="comment">// ...</span></div><div class="line"> }</div><div class="line"> }</div><div class="line">}</div></pre></td></tr></table></figure>
<ol>
<li><p>Cyclomatic Complexity(圈复杂度)</p>
</li>
<li><p><code>dynamic</code> 弱语言的东西类似js的结构体,和模板搭配很好用</p>
</li>
<li><p><code>Obsolete</code></p>
<figure class="highlight scheme"><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">[<span class="name">Obsolete</span>(<span class="string">"该方法已被弃用,请使用NewMethod代替"</span>)]</div><div class="line">static void OldMethod()</div></pre></td></tr></table></figure>
</li>
<li><p><code>abstract</code>属性可以通过继承覆盖<br>···<br>public abstract class Shape<br>{<br> private string name;</p>
<p> public Shape(string s)<br> {</p>
<pre><code>// calling the set accessor of the Id property.
Id = s;
</code></pre><p> }<br> public string Id<br> {</p>
<pre><code>get
{
return name;
}
set
{
name = value;
}
</code></pre><p> }</p>
<p> // Area is a read-only property - only a get accessor is needed:<br> public abstract double Area<br> {</p>
<pre><code>get;
</code></pre><p> }</p>
<p> public override string ToString()<br> {</p>
<pre><code>return $"{Id} Area = {Area:F2}";
</code></pre><p> }<br>}<br>public class Square : Shape<br>{<br> private int side;</p>
<p> public Square(int side, string id)</p>
<pre><code>: base(id)
</code></pre><p> {</p>
<pre><code>this.side = side;
</code></pre><p> }</p>
<p> public override double Area<br> {</p>
<pre><code>get
{
// Given the side, return the area of a square:
return side * side;
}
</code></pre><p> }<br>}</p>
</li>
</ol>
<p>···</p>
<ol>
<li><p><code>is</code>的规则</p>
<figure class="highlight cs"><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></pre></td><td class="code"><pre><div class="line"><span class="keyword">interface</span> <span class="title">Animal</span> { }</div><div class="line"><span class="keyword">class</span> <span class="title">Cat</span> : <span class="title">Animal</span> { }</div><div class="line"><span class="keyword">class</span> <span class="title">Dog</span> : <span class="title">Animal</span> { }</div><div class="line"><span class="function"><span class="keyword">static</span> <span class="keyword">void</span> <span class="title">Main</span>(<span class="params"><span class="keyword">string</span>[] args</span>)</span></div><div class="line">{</div><div class="line"> List<Animal> animals = <span class="keyword">new</span> List<Animal> { <span class="keyword">new</span> Cat(), <span class="keyword">new</span> Dog() };</div><div class="line"> <span class="keyword">foreach</span> (Animal a <span class="keyword">in</span> animals)</div><div class="line"> {</div><div class="line"> <span class="keyword">if</span> (a <span class="keyword">is</span> Cat)</div><div class="line"> Console.WriteLine(<span class="string">"Miaow!"</span>);</div><div class="line"> <span class="keyword">if</span> (a <span class="keyword">is</span> Dog)</div><div class="line"> Console.WriteLine(<span class="string">"Woof!"</span>);</div><div class="line"> <span class="keyword">if</span> (a <span class="keyword">is</span> Animal)</div><div class="line"> Console.WriteLine(<span class="string">"Animal!"</span>);</div><div class="line"> }</div><div class="line"></div><div class="line"> Console.ReadLine();</div><div class="line"> Console.ReadKey();</div><div class="line">}<span class="comment">// Miaow Animal Woof Animal</span></div></pre></td></tr></table></figure>
</li>
<li><p>引用用类型,值类型比较</p>
</li>
</ol>
<p>引用类型:<br><code>ReferenceEquals(null, x)</code>比较是否是指向同一内存<br>虚函数<code>Equals</code></p>
<p>值类型:<br><code>==</code>运算符比较</p>
<ol>
<li>双重检查<code>lock</code></li>
</ol>
]]></content>
<summary type="html">
<p><a href="https://help.semmle.com/wiki/display/CSHARP/Abstract+class+only+declares+common+constants" target="_blank" rel="external">原文章地址<
</summary>
<category term="C#" scheme="https://xuecat.github.io/categories/C/"/>
<category term="学习看书笔记" scheme="https://xuecat.github.io/tags/%E5%AD%A6%E4%B9%A0%E7%9C%8B%E4%B9%A6%E7%AC%94%E8%AE%B0/"/>
</entry>
<entry>
<title>EF Core Linq(252)</title>
<link href="https://xuecat.github.io/2020/03/29/252/"/>
<id>https://xuecat.github.io/2020/03/29/252/</id>
<published>2020-03-29T02:42:32.000Z</published>
<updated>2020-05-06T14:35:00.749Z</updated>
<content type="html"><![CDATA[<p>EF默认情况下对数据的访问都是启用模型跟踪</p>
<p>使用AsNoTracking方法查询返回无变动跟踪的Province的DbSet,由于是无变动跟踪,所以对返回的Province集中数据的任何修改,在SaveChanges()时,都不会提交到数据库中</p>
<ul>
<li>无跟踪查询而已,也就是说查询出来的对象不能直接做修改。所以,我们在做数据集合查询显示,而又不需要对集合修改并更新到数据库的时候,一定不要忘记加上AsNoTracking。</li>
</ul>
<figure class="highlight lasso"><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">using (<span class="built_in">var</span> context = <span class="literal">new</span> MyDbContext())</div><div class="line">{</div><div class="line"> <span class="built_in">var</span> <span class="built_in">data</span> = context.Orders</div><div class="line"> .Include(c => c.OrderLines)</div><div class="line"> .<span class="keyword">Select</span>(c => <span class="literal">new</span> { OrderObj = c, Lines = c.OrderLines})</div><div class="line"> .AsNoTracking()<span class="comment">//除非去掉这句不然不会更新</span></div><div class="line"> .FirstOrDefault();</div><div class="line"> </div><div class="line"> <span class="built_in">data</span>.OrderObj.Number = <span class="string">"#ABC123"</span>;</div><div class="line"> </div><div class="line"> context.SaveChanges();</div><div class="line">}</div></pre></td></tr></table></figure>
<ul>
<li>如果查询过程做了select映射就不需要加AsNoTracking。如:db.Students.Where(t=>t.Name.Contains(“张三”)).select(t=>new (t.Name,t.Age)).ToList();</li>
</ul>
<figure class="highlight php"><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></pre></td><td class="code"><pre><div class="line"><span class="comment">//导出部分属性列,提高效率</span></div><div class="line">.AsNoTracking()</div><div class="line"> .Select(item =></div><div class="line"> <span class="keyword">new</span> ProductViewModel</div><div class="line"> {</div><div class="line"> Product = item,</div><div class="line"></div><div class="line"> NoOfProducts = item.Comments.Count</div><div class="line"></div><div class="line"> }).ToListAsync());</div><div class="line"></div><div class="line"></div><div class="line"><span class="comment">//同理</span></div><div class="line"> <span class="keyword">var</span> <span class="keyword">list</span> = context.Bloggers</div><div class="line"> .<span class="keyword">Include</span>(x => x.Posts)</div><div class="line"> .ToList();</div></pre></td></tr></table></figure>
<figure class="highlight pony"><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></pre></td><td class="code"><pre><div class="line"><span class="comment">//更新单列</span></div><div class="line"><span class="comment">//这个方法需要注意一点,就是禁止多个跟踪。假如前面用track方式`where`选出了一些对象,由于这些对象被跟踪了,再用这个方法`attach`添加跟踪就会异常。除非用同一个对象更新</span></div><div class="line">using (<span class="type">TestDBContext</span> testDBContext = <span class="function"><span class="keyword">new</span> <span class="title">TestDBContext</span>())</span></div><div class="line">{</div><div class="line"> <span class="title">Person</span> <span class="title">person</span> = <span class="title">new</span> <span class="title">Person</span>() { <span class="title">Code</span> = "<span class="title">A</span>" ,<span class="title">Name</span>="<span class="title">Tom</span>"};<span class="comment">//列Code是Key,声明Key属性列Code的值,及要修改的列Name的值</span></div><div class="line"></div><div class="line"> <span class="title">testDBContext</span>.<span class="title">Attach</span>(person);<span class="comment">//告诉EF Core开始跟踪person实体的更改,因为调用DbContext.Attach方法后,EF Core会将person实体的State值(可以通过testDBContext.Entry(person).State查看到)更改回EntityState.Unchanged,所以这里testDBContext.Attach(person)一定要放在下面一行testDBContext.Entry(person).</span></div><div class="line"> </div><div class="line"> <span class="title">Property</span>(p => p.<span class="type">Name</span>).<span class="title">IsModified</span> = <span class="title">true</span>的前面,否者后面的<span class="title">testDBContext</span>.<span class="title">SaveChanges</span>方法调用后,数据库不会被更新</div><div class="line"> <span class="title">testDBContext</span>.<span class="title">Entry</span>(person).<span class="title">Property</span>(p => p.<span class="type">Name</span>).<span class="title">IsModified</span> = <span class="title">true</span>;<span class="comment">//告诉EF Core实体person的Name属性已经更改。将testDBContext.Entry(person).Property(p => p.Name).IsModified设置为true后,也会将person实体的State值(可以通过testDBContext.Entry(person).State查看到)更改为EntityState.Modified,这样就保证了下面SaveChanges的时候会将person实体的Name属性值Update到数据库中。</span></div><div class="line"> <span class="title">testDBContext</span>.<span class="title">SaveChanges</span>();</div><div class="line">}</div><div class="line"></div><div class="line"><span class="title">context</span>.<span class="title">Attach</span>(person);</div><div class="line"><span class="title">context</span>.<span class="title">Entry</span>(person).<span class="title">Property</span>("<span class="type">Name</span>").<span class="title">IsModified</span> = <span class="title">true</span>;</div><div class="line"><span class="title">context</span>.<span class="title">SaveChanges</span>();</div><div class="line"></div><div class="line"><span class="comment">//更新还有个mysql坑,那就是int主键默认是0。因为主键ID默认是不赋值的,只给其他项目赋值了 id是int类型,int类型如果不允许为空那么会被默认为0,所以插入第二条数据时,数据库中已经有了主键为0的数据</span></div><div class="line"></div><div class="line"><span class="comment">//modelBuilder.Entity<Person>(entity =></span></div><div class="line"><span class="comment">//{</span></div><div class="line"><span class="comment">// entity.Property(e => e.Id).ValueGeneratedOnAdd();//这句会用到的</span></div><div class="line"><span class="comment">// entity.HasKey(e => e.Code);//声明列Code是实体的Key属性</span></div><div class="line"><span class="comment">//});</span></div></pre></td></tr></table></figure>
<h3 id="自定义标量函数"><a href="#自定义标量函数" class="headerlink" title="自定义标量函数"></a>自定义标量函数</h3><p> Entity Framework Core 有一个重要特性就是自定义标量函数。<br> 自定义标量函数可以将数据库中的标量函数映射到类中的方法,并且在使用 LINQ 查询时会用到</p>
<p> 我看例子他们还可以映射数据的函数<code>Average</code> <code>Max</code> <code>Min</code>等<br> ···</p>
<p> [DbFunction(FUNCTIONnAME=”sdf”,Schema=”dd”)]<br> public static string my()<br> {}</p>
<p> //调用<br> public int GetNextValId(string value)<br> {<br> return Context.DbpTask.Select(x => IngestTaskDBContext.next_val(value)).FirstOrDefault();<br> }<br> ···</p>
<h3 id="显式编译查询"><a href="#显式编译查询" class="headerlink" title="显式编译查询"></a>显式编译查询</h3><p>一般的<code>NoTracking()</code>查询,此时要经过编译翻译阶段最终返回实际结果,比如在Web网站上这样的请求很频繁,此时将严重影响响应速度导致页面加载数据过慢。</p>
<figure class="highlight dart"><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="keyword">static</span> <span class="keyword">async</span> Task<Blog> GetBlogAsync(EFCoreDbContext context, <span class="built_in">int</span> id)</div><div class="line">{</div><div class="line"> Func<EFCoreDbContext, <span class="built_in">int</span>, Task<Blog>> blog = EF.CompileAsyncQuery((EFCoreDbContext context, <span class="built_in">int</span> Id) =></div><div class="line"> context.Blogs.Include(c => c.Posts)</div><div class="line"> .Where(c => c.Id == Id)</div><div class="line"> .FirstOrDefault());</div><div class="line"> <span class="keyword">return</span> <span class="keyword">await</span> blog(context, id);</div><div class="line">}</div><div class="line"><span class="comment">//提前把查询编译好,再直接返回查询结果的方式</span></div></pre></td></tr></table></figure>
<h3 id="延时加载技术"><a href="#延时加载技术" class="headerlink" title="延时加载技术"></a>延时加载技术</h3><p>用的时候才会加载</p>
]]></content>
<summary type="html">
<p>EF默认情况下对数据的访问都是启用模型跟踪</p>
<p>使用AsNoTracking方法查询返回无变动跟踪的Province的DbSet,由于是无变动跟踪,所以对返回的Province集中数据的任何修改,在SaveChanges()时,都不会提交到数据库中</p>
<ul
</summary>
<category term="服务器" scheme="https://xuecat.github.io/categories/%E6%9C%8D%E5%8A%A1%E5%99%A8/"/>
<category term="Mysql" scheme="https://xuecat.github.io/tags/Mysql/"/>
<category term="Asp.Net" scheme="https://xuecat.github.io/tags/Asp-Net/"/>
</entry>
<entry>
<title>Orleans新记录(251)</title>
<link href="https://xuecat.github.io/2020/02/02/251/"/>
<id>https://xuecat.github.io/2020/02/02/251/</id>
<published>2020-02-02T04:31:32.000Z</published>
<updated>2020-07-22T15:55:16.113Z</updated>
<content type="html"><![CDATA[<p><strong><em>Grain Identity</em></strong></p>
<ul>
<li>获取key有多样的(继承多样:<code>IGrainWithIntegerKey</code>)</li>
</ul>
<p><strong><em>Timers and Reminders</em></strong></p>
<ul>
<li><p><strong><em>Observers</em></strong></p>
</li>
<li>服务端<code>ObserverSubscriptionManager<></code> <code>IGrainObserver</code>保持订阅列表,调相应接口来进行通知对应订阅</li>
<li>客户端<code>CreateObjectReference</code> <code>Subscribe</code>向服务器订阅</li>
</ul>
<p><strong><em>Reentrancy</em></strong></p>
<ul>
<li>grain类用<code>[Reentrant]</code>能完全异步,外部调它的方法顺序全是乱的。</li>
<li><code>[AlwaysInterleave]</code>单个方法异步</li>
<li>如果没有异步要注意方法里面出现<code>GetGrain</code>导致的<code>grain</code>之间互相调用会死锁</li>
<li>服务端可以写个属性来进行动态异步交错(感觉没啥用呢)</li>
</ul>
<p><strong><em>RequestContext</em></strong></p>
<ul>
<li>客户端<code>RequestContext.Set</code>,服务端<code>RequestContext.Get</code>它将与Orleans请求一起流向接收谷物;<br>应用程序元数据不会随响应一起流回<br>应用场景:请求从客户端到服务器跟踪流程用</li>
</ul>
<p><strong><em>JournaledGrain</em></strong><br>这个很有用,<code>event</code>和<code>state</code>绑定,通过事件更新状态,注意读写状态</p>
<p><strong><em>外部的任务和grain</em></strong><br>1) await,Task.Factory.StartNew,Task.ContinuewWith,Task.WhenAny,Task.WhenAll,Task.Delay都遵循当前的任务计划。这意味着以默认方式使用它们,无需传递不同的TaskScheduler,它们会在grain上下文中执行。</p>
<p>2)Task.Factory.FromAsync的Task.Run和endMethod委托,都不遵循当前的任务调度程序。它们都使用TaskScheduler.Default调度程序,即.NET线程池任务调度程序。</p>
<p><strong><em>拦截器</em></strong><br>1) 客户端调用<code>grain</code>用呼出,可以向<code>RequestContext</code>添加认证的东西<br>2} 服务端<code>grain</code>配置呼入,检查每个调用请求</p>
<p><strong><em>GrainServices</em></strong><br>GrainService是一种特殊的grain;它没有身份标识,并且在每个silo中运行,从silo的启动到关闭。</p>
<ul>
<li>如果可能,使GrainService可重入,以获得更好的性能</li>
<li>GrainService无法写入Orleans流,因为它不能在grain任务调度程序中工作</li>
</ul>
<p>有点像数据服务的代理,其他grain注入这个来访问数据啥的</p>
<p><strong><em>无状态grain</em></strong></p>
<ul>
<li>对无状态工作器grain的请求总是在本地执行,身份标识是 0或Guid.Empty</li>
</ul>
<p><strong><em>事务</em></strong><br>需要配合存储使用</p>
<p><strong><em>启动任务</em></strong><br>在许多情况下,一旦silo可用,就需要自动执行某些任务。启动任务提供此功能。</p>
<p>一些用例包括但不限于:</p>
<ul>
<li>启动后台计时器,以执行周期性的”家务”式的任务</li>
<li>使用从外部的后备存储下载的数据,预加载一些缓存的grain</li>
</ul>
]]></content>
<summary type="html">
<p><strong><em>Grain Identity</em></strong></p>
<ul>
<li>获取key有多样的(继承多样:<code>IGrainWithIntegerKey</code>)</li>
</ul>
<p><strong><em>Timers
</summary>
<category term="C#" scheme="https://xuecat.github.io/categories/C/"/>
<category term="分布式" scheme="https://xuecat.github.io/tags/%E5%88%86%E5%B8%83%E5%BC%8F/"/>
<category term="Orleans" scheme="https://xuecat.github.io/tags/Orleans/"/>
</entry>
<entry>
<title>for(;;)和while(true)(250)</title>
<link href="https://xuecat.github.io/2019/12/11/250/"/>
<id>https://xuecat.github.io/2019/12/11/250/</id>
<published>2019-12-11T15:39:46.000Z</published>
<updated>2019-12-11T15:46:02.681Z</updated>
<content type="html"><![CDATA[<p>比较结果<br><figure class="highlight subunit"><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></pre></td><td class="code"><pre><div class="line">while(1)</div><div class="line"></div><div class="line">mov eax,1</div><div class="line"><span class="keyword">test </span>eax,eax</div><div class="line">je foo<span class="string">+23</span>h</div><div class="line">jmp foo<span class="string">+18</span>h</div><div class="line"></div><div class="line"></div><div class="line">for(;;)</div><div class="line"></div><div class="line">jmp foo<span class="string">+23</span>h</div></pre></td></tr></table></figure></p>
<p>总结:for (;;):1.指令少2.不占用寄存器3.没有判断跳转,并不是不能跳出</p>
]]></content>
<summary type="html">
<p>比较结果<br><figure class="highlight subunit"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class
</summary>
<category term="语言" scheme="https://xuecat.github.io/categories/%E8%AF%AD%E8%A8%80/"/>
<category term="c++" scheme="https://xuecat.github.io/tags/c/"/>
</entry>
<entry>
<title>服务器记录(249)</title>
<link href="https://xuecat.github.io/2019/10/28/249/"/>
<id>https://xuecat.github.io/2019/10/28/249/</id>
<published>2019-10-28T15:22:06.000Z</published>
<updated>2021-07-29T13:06:30.636Z</updated>
<content type="html"><![CDATA[<p> 最近优化了些服务器做下记录</p>
<ol>
<li>httpclient的使用<blockquote>
<p>httpclient不能立即关闭,会占用资源,并发量一大就耗尽。所以.net core 会使用如下:</p>
</blockquote>
</li>
</ol>
<figure class="highlight typescript"><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><div class="line">35</div><div class="line">36</div><div class="line">37</div><div class="line">38</div><div class="line">39</div><div class="line">40</div><div class="line">41</div><div class="line">42</div><div class="line">43</div><div class="line">44</div><div class="line">45</div><div class="line">46</div><div class="line">47</div><div class="line">48</div><div class="line">49</div><div class="line">50</div><div class="line">51</div><div class="line">52</div><div class="line">53</div><div class="line">54</div><div class="line">55</div><div class="line">56</div><div class="line">57</div><div class="line">58</div><div class="line">59</div><div class="line">60</div><div class="line">61</div><div class="line">62</div><div class="line">63</div><div class="line">64</div><div class="line">65</div><div class="line">66</div><div class="line">67</div><div class="line">68</div><div class="line">69</div><div class="line">70</div><div class="line">71</div><div class="line">72</div><div class="line">73</div><div class="line">74</div><div class="line">75</div><div class="line">76</div><div class="line">77</div><div class="line">78</div><div class="line">79</div><div class="line">80</div><div class="line">81</div><div class="line">82</div><div class="line">83</div><div class="line">84</div><div class="line">85</div><div class="line">86</div><div class="line">87</div><div class="line">88</div><div class="line">89</div><div class="line">90</div><div class="line">91</div><div class="line">92</div><div class="line">93</div><div class="line">94</div><div class="line">95</div><div class="line">96</div><div class="line">97</div><div class="line">98</div><div class="line">99</div><div class="line">100</div><div class="line">101</div><div class="line">102</div><div class="line">103</div><div class="line">104</div><div class="line">105</div><div class="line">106</div><div class="line">107</div><div class="line">108</div><div class="line">109</div><div class="line">110</div><div class="line">111</div><div class="line">112</div><div class="line">113</div><div class="line">114</div><div class="line">115</div><div class="line">116</div><div class="line">117</div><div class="line">118</div><div class="line">119</div><div class="line">120</div><div class="line">121</div><div class="line">122</div><div class="line">123</div><div class="line">124</div><div class="line">125</div><div class="line">126</div><div class="line">127</div><div class="line">128</div><div class="line">129</div><div class="line">130</div><div class="line">131</div><div class="line">132</div><div class="line">133</div><div class="line">134</div><div class="line">135</div><div class="line">136</div><div class="line">137</div><div class="line">138</div><div class="line">139</div><div class="line">140</div><div class="line">141</div><div class="line">142</div><div class="line">143</div><div class="line">144</div><div class="line">145</div><div class="line">146</div><div class="line">147</div><div class="line">148</div><div class="line">149</div><div class="line">150</div><div class="line">151</div><div class="line">152</div><div class="line">153</div><div class="line">154</div><div class="line">155</div><div class="line">156</div><div class="line">157</div><div class="line">158</div><div class="line">159</div><div class="line">160</div><div class="line">161</div><div class="line">162</div><div class="line">163</div><div class="line">164</div><div class="line">165</div><div class="line">166</div><div class="line">167</div><div class="line">168</div><div class="line">169</div><div class="line">170</div><div class="line">171</div><div class="line">172</div><div class="line">173</div><div class="line">174</div><div class="line">175</div><div class="line">176</div><div class="line">177</div><div class="line">178</div><div class="line">179</div><div class="line">180</div><div class="line">181</div><div class="line">182</div><div class="line">183</div><div class="line">184</div><div class="line">185</div><div class="line">186</div><div class="line">187</div><div class="line">188</div><div class="line">189</div><div class="line">190</div><div class="line">191</div><div class="line">192</div><div class="line">193</div><div class="line">194</div><div class="line">195</div><div class="line">196</div><div class="line">197</div><div class="line">198</div><div class="line">199</div><div class="line">200</div><div class="line">201</div><div class="line">202</div><div class="line">203</div><div class="line">204</div><div class="line">205</div><div class="line">206</div><div class="line">207</div><div class="line">208</div><div class="line">209</div><div class="line">210</div><div class="line">211</div><div class="line">212</div><div class="line">213</div><div class="line">214</div><div class="line">215</div><div class="line">216</div><div class="line">217</div><div class="line">218</div><div class="line">219</div><div class="line">220</div><div class="line">221</div><div class="line">222</div><div class="line">223</div><div class="line">224</div><div class="line">225</div><div class="line">226</div><div class="line">227</div><div class="line">228</div><div class="line">229</div><div class="line">230</div><div class="line">231</div><div class="line">232</div><div class="line">233</div><div class="line">234</div><div class="line">235</div><div class="line">236</div><div class="line">237</div><div class="line">238</div><div class="line">239</div><div class="line">240</div><div class="line">241</div><div class="line">242</div><div class="line">243</div><div class="line">244</div><div class="line">245</div><div class="line">246</div><div class="line">247</div><div class="line">248</div><div class="line">249</div><div class="line">250</div><div class="line">251</div><div class="line">252</div><div class="line">253</div><div class="line">254</div><div class="line">255</div><div class="line">256</div><div class="line">257</div><div class="line">258</div><div class="line">259</div><div class="line">260</div><div class="line">261</div><div class="line">262</div><div class="line">263</div><div class="line">264</div><div class="line">265</div><div class="line">266</div><div class="line">267</div><div class="line">268</div><div class="line">269</div><div class="line">270</div><div class="line">271</div><div class="line">272</div><div class="line">273</div><div class="line">274</div><div class="line">275</div><div class="line">276</div><div class="line">277</div><div class="line">278</div><div class="line">279</div><div class="line">280</div><div class="line">281</div><div class="line">282</div><div class="line">283</div><div class="line">284</div><div class="line">285</div><div class="line">286</div><div class="line">287</div><div class="line">288</div><div class="line">289</div><div class="line">290</div><div class="line">291</div><div class="line">292</div><div class="line">293</div><div class="line">294</div><div class="line">295</div><div class="line">296</div><div class="line">297</div><div class="line">298</div><div class="line">299</div><div class="line">300</div><div class="line">301</div><div class="line">302</div><div class="line">303</div><div class="line">304</div><div class="line">305</div><div class="line">306</div><div class="line">307</div><div class="line">308</div><div class="line">309</div><div class="line">310</div><div class="line">311</div><div class="line">312</div><div class="line">313</div><div class="line">314</div><div class="line">315</div><div class="line">316</div><div class="line">317</div><div class="line">318</div><div class="line">319</div><div class="line">320</div><div class="line">321</div><div class="line">322</div><div class="line">323</div><div class="line">324</div><div class="line">325</div><div class="line">326</div><div class="line">327</div><div class="line">328</div><div class="line">329</div><div class="line">330</div><div class="line">331</div><div class="line">332</div><div class="line">333</div><div class="line">334</div><div class="line">335</div><div class="line">336</div><div class="line">337</div><div class="line">338</div><div class="line">339</div><div class="line">340</div><div class="line">341</div><div class="line">342</div><div class="line">343</div><div class="line">344</div><div class="line">345</div><div class="line">346</div><div class="line">347</div><div class="line">348</div><div class="line">349</div><div class="line">350</div><div class="line">351</div><div class="line">352</div><div class="line">353</div><div class="line">354</div><div class="line">355</div><div class="line">356</div><div class="line">357</div><div class="line">358</div><div class="line">359</div><div class="line">360</div><div class="line">361</div><div class="line">362</div><div class="line">363</div><div class="line">364</div><div class="line">365</div><div class="line">366</div><div class="line">367</div><div class="line">368</div><div class="line">369</div><div class="line">370</div><div class="line">371</div><div class="line">372</div><div class="line">373</div><div class="line">374</div><div class="line">375</div><div class="line">376</div><div class="line">377</div><div class="line">378</div><div class="line">379</div><div class="line">380</div><div class="line">381</div><div class="line">382</div><div class="line">383</div><div class="line">384</div><div class="line">385</div><div class="line">386</div><div class="line">387</div><div class="line">388</div><div class="line">389</div><div class="line">390</div><div class="line">391</div><div class="line">392</div><div class="line">393</div><div class="line">394</div><div class="line">395</div><div class="line">396</div><div class="line">397</div><div class="line">398</div><div class="line">399</div><div class="line">400</div><div class="line">401</div><div class="line">402</div><div class="line">403</div><div class="line">404</div><div class="line">405</div><div class="line">406</div><div class="line">407</div><div class="line">408</div><div class="line">409</div><div class="line">410</div><div class="line">411</div><div class="line">412</div><div class="line">413</div><div class="line">414</div><div class="line">415</div><div class="line">416</div><div class="line">417</div><div class="line">418</div><div class="line">419</div><div class="line">420</div><div class="line">421</div><div class="line">422</div><div class="line">423</div><div class="line">424</div><div class="line">425</div><div class="line">426</div><div class="line">427</div><div class="line">428</div><div class="line">429</div><div class="line">430</div><div class="line">431</div><div class="line">432</div><div class="line">433</div><div class="line">434</div><div class="line">435</div><div class="line">436</div><div class="line">437</div><div class="line">438</div><div class="line">439</div><div class="line">440</div><div class="line">441</div><div class="line">442</div><div class="line">443</div><div class="line">444</div><div class="line">445</div><div class="line">446</div><div class="line">447</div><div class="line">448</div><div class="line">449</div><div class="line">450</div><div class="line">451</div><div class="line">452</div><div class="line">453</div><div class="line">454</div><div class="line">455</div><div class="line">456</div><div class="line">457</div><div class="line">458</div><div class="line">459</div><div class="line">460</div><div class="line">461</div><div class="line">462</div><div class="line">463</div><div class="line">464</div><div class="line">465</div><div class="line">466</div><div class="line">467</div><div class="line">468</div><div class="line">469</div><div class="line">470</div><div class="line">471</div><div class="line">472</div><div class="line">473</div><div class="line">474</div><div class="line">475</div><div class="line">476</div><div class="line">477</div><div class="line">478</div><div class="line">479</div><div class="line">480</div><div class="line">481</div><div class="line">482</div><div class="line">483</div><div class="line">484</div><div class="line">485</div><div class="line">486</div><div class="line">487</div><div class="line">488</div><div class="line">489</div><div class="line">490</div><div class="line">491</div><div class="line">492</div><div class="line">493</div><div class="line">494</div><div class="line">495</div><div class="line">496</div><div class="line">497</div><div class="line">498</div><div class="line">499</div><div class="line">500</div><div class="line">501</div><div class="line">502</div><div class="line">503</div><div class="line">504</div><div class="line">505</div><div class="line">506</div><div class="line">507</div><div class="line">508</div><div class="line">509</div><div class="line">510</div><div class="line">511</div><div class="line">512</div><div class="line">513</div><div class="line">514</div><div class="line">515</div><div class="line">516</div><div class="line">517</div><div class="line">518</div><div class="line">519</div><div class="line">520</div><div class="line">521</div><div class="line">522</div><div class="line">523</div><div class="line">524</div><div class="line">525</div><div class="line">526</div><div class="line">527</div><div class="line">528</div><div class="line">529</div><div class="line">530</div><div class="line">531</div><div class="line">532</div><div class="line">533</div><div class="line">534</div><div class="line">535</div><div class="line">536</div><div class="line">537</div><div class="line">538</div><div class="line">539</div><div class="line">540</div><div class="line">541</div><div class="line">542</div><div class="line">543</div><div class="line">544</div><div class="line">545</div><div class="line">546</div><div class="line">547</div><div class="line">548</div><div class="line">549</div><div class="line">550</div><div class="line">551</div><div class="line">552</div><div class="line">553</div><div class="line">554</div><div class="line">555</div><div class="line">556</div><div class="line">557</div><div class="line">558</div><div class="line">559</div><div class="line">560</div><div class="line">561</div><div class="line">562</div><div class="line">563</div><div class="line">564</div><div class="line">565</div><div class="line">566</div><div class="line">567</div><div class="line">568</div><div class="line">569</div><div class="line">570</div><div class="line">571</div><div class="line">572</div><div class="line">573</div><div class="line">574</div><div class="line">575</div><div class="line">576</div><div class="line">577</div><div class="line">578</div><div class="line">579</div><div class="line">580</div><div class="line">581</div><div class="line">582</div><div class="line">583</div><div class="line">584</div><div class="line">585</div><div class="line">586</div><div class="line">587</div><div class="line">588</div><div class="line">589</div><div class="line">590</div><div class="line">591</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">public</span> <span class="keyword">class</span> RestClient : IDisposable</div><div class="line"> {</div><div class="line"> <span class="keyword">private</span> readonly ILogger Logger = LoggerManager.GetLogger(<span class="string">"ApiClient"</span>);</div><div class="line"></div><div class="line"> <span class="keyword">private</span> HttpClient _httpClient = <span class="literal">null</span>;</div><div class="line"> <span class="keyword">const</span> <span class="built_in">string</span> TASKAPI20 = <span class="string">"api/v2/task"</span>;</div><div class="line"> <span class="keyword">const</span> <span class="built_in">string</span> TASKAPI30 = <span class="string">"api/v3/task"</span>;</div><div class="line"> <span class="keyword">const</span> <span class="built_in">string</span> MATRIXAPI20 = <span class="string">"api/v2/matrix"</span>;</div><div class="line"> <span class="keyword">const</span> <span class="built_in">string</span> USERAPI20 = <span class="string">"api/v2/user"</span>;</div><div class="line"> <span class="keyword">const</span> <span class="built_in">string</span> DEVICEAPI30 = <span class="string">"api/v3/device"</span>;</div><div class="line"> <span class="keyword">const</span> <span class="built_in">string</span> DEVICEAPI20 = <span class="string">"api/v2/device"</span>;</div><div class="line"></div><div class="line"> <span class="keyword">private</span> <span class="built_in">string</span> IngestDbUrl { <span class="keyword">get</span>; <span class="keyword">set</span>; }</div><div class="line"> <span class="keyword">private</span> <span class="built_in">string</span> CmServerUrl { <span class="keyword">get</span>; <span class="keyword">set</span>; }</div><div class="line"></div><div class="line"> <span class="keyword">private</span> bool _disposed;</div><div class="line"> <span class="keyword">public</span> RestClient(HttpClient httpClient, <span class="built_in">string</span> ingesturl, <span class="built_in">string</span> cmurl)</div><div class="line"> {</div><div class="line"> _disposed = <span class="literal">false</span>;</div><div class="line"> _httpClient = httpClient != <span class="literal">null</span>? httpClient : <span class="keyword">new</span> HttpClient();</div><div class="line"> _httpClient.DefaultRequestHeaders.Connection.Clear();</div><div class="line"> _httpClient.DefaultRequestHeaders.ConnectionClose = <span class="literal">false</span>;</div><div class="line"> _httpClient.Timeout = TimeSpan.FromSeconds(<span class="number">15</span>);</div><div class="line"> _httpClient.DefaultRequestHeaders.Accept.Add(<span class="keyword">new</span> MediaTypeWithQualityHeaderValue(<span class="string">"application/json"</span>));</div><div class="line"> _httpClient.DefaultRequestHeaders.Add(<span class="string">"sobeyhive-http-system"</span>, <span class="string">"INGESTSERVER"</span>);</div><div class="line"> _httpClient.DefaultRequestHeaders.Add(<span class="string">"sobeyhive-http-site"</span>, <span class="string">"S1"</span>);</div><div class="line"> _httpClient.DefaultRequestHeaders.Add(<span class="string">"sobeyhive-http-tool"</span>, <span class="string">"INGESTSERVER"</span>);</div><div class="line"> IngestDbUrl = ingesturl;</div><div class="line"> CmServerUrl = cmurl;</div><div class="line"> </div><div class="line"> }</div><div class="line"> <span class="keyword">public</span> <span class="built_in">void</span> Dispose()</div><div class="line"> {</div><div class="line"> Dispose(<span class="literal">true</span>);</div><div class="line"> GC.SuppressFinalize(<span class="keyword">this</span>);</div><div class="line"> }</div><div class="line"></div><div class="line"> ~RestClient()</div><div class="line"> {</div><div class="line"> <span class="comment">//必须为false</span></div><div class="line"> Dispose(<span class="literal">false</span>);</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="keyword">protected</span> virtual <span class="built_in">void</span> Dispose(bool disposing)</div><div class="line"> {</div><div class="line"> <span class="keyword">if</span> (_disposed) <span class="keyword">return</span>;</div><div class="line"> <span class="keyword">if</span> (disposing)</div><div class="line"> {</div><div class="line"></div><div class="line"> }</div><div class="line"> <span class="keyword">if</span> (_httpClient != <span class="literal">null</span>)</div><div class="line"> {</div><div class="line"> _httpClient.Dispose();</div><div class="line"> _httpClient = <span class="literal">null</span>;</div><div class="line"> }</div><div class="line"> _disposed = <span class="literal">true</span>;</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="keyword">public</span> Dictionary<<span class="built_in">string</span>, <span class="built_in">string</span>> GetTokenHeader(<span class="built_in">string</span> usertoken)</div><div class="line"> {</div><div class="line"> <span class="keyword">return</span> <span class="keyword">new</span> Dictionary<<span class="built_in">string</span>, <span class="built_in">string</span>>() { </div><div class="line"> {<span class="string">"sobeyhive-http-token"</span>, usertoken }</div><div class="line"> };</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="keyword">public</span> Dictionary<<span class="built_in">string</span>, <span class="built_in">string</span>> GetCodeHeader(<span class="built_in">string</span> usertoken)</div><div class="line"> {</div><div class="line"> <span class="keyword">return</span> <span class="keyword">new</span> Dictionary<<span class="built_in">string</span>, <span class="built_in">string</span>>() {</div><div class="line"> {<span class="string">"sobeyhive-http-secret"</span>, RSAHelper.RSAstr()},</div><div class="line"> {<span class="string">"current-user-code"</span>, usertoken }</div><div class="line"> };</div><div class="line"> }</div><div class="line"> <span class="keyword">public</span> Dictionary<<span class="built_in">string</span>, <span class="built_in">string</span>> GetIngestHeader()</div><div class="line"> {</div><div class="line"> <span class="keyword">return</span> <span class="keyword">new</span> Dictionary<<span class="built_in">string</span>, <span class="built_in">string</span>>() {</div><div class="line"> {<span class="string">"sobeyhive-ingest-signature"</span>, Base64SQL.ToBase64String($<span class="string">"ingest_server;{DateTime.Now}"</span>)},</div><div class="line"> };</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="keyword">public</span> async Task<TResponse> PostAsync<TResponse>(<span class="built_in">string</span> url, object body, <span class="built_in">string</span> method = <span class="string">"POST"</span>, NameValueCollection queryString = <span class="literal">null</span>, int timeout = <span class="number">60</span>)</div><div class="line"> where TResponse : <span class="keyword">class</span>, <span class="keyword">new</span>()</div><div class="line"> {</div><div class="line"> TResponse response = <span class="literal">null</span>;</div><div class="line"> <span class="keyword">try</span></div><div class="line"> {</div><div class="line"> <span class="built_in">string</span> json = JsonHelper.ToJson(body);</div><div class="line"> HttpClient client = _httpClient;</div><div class="line"> <span class="keyword">if</span> (queryString == <span class="literal">null</span>)</div><div class="line"> {</div><div class="line"> queryString = <span class="keyword">new</span> NameValueCollection();</div><div class="line"> }</div><div class="line"> <span class="keyword">if</span> (<span class="built_in">String</span>.IsNullOrEmpty(method))</div><div class="line"> {</div><div class="line"> method = <span class="string">"POST"</span>;</div><div class="line"> }</div><div class="line"> url = CreateUrl(url, queryString);</div><div class="line"> <span class="comment">//Logger.Debug("请求:{0} {1}", method, url);</span></div><div class="line"> byte[] strData = Encoding.UTF8.GetBytes(json);</div><div class="line"> MemoryStream ms = <span class="keyword">new</span> MemoryStream(strData);</div><div class="line"> using (StreamContent sc = <span class="keyword">new</span> StreamContent(ms))</div><div class="line"> {</div><div class="line"> sc.Headers.ContentType = <span class="keyword">new</span> MediaTypeWithQualityHeaderValue(<span class="string">"application/json"</span>);</div><div class="line"></div><div class="line"> <span class="comment">//foreach (var item in _httpClient.DefaultRequestHeaders)</span></div><div class="line"> <span class="comment">//{</span></div><div class="line"> <span class="comment">// Logger.Error("header : " + item.Key + ":" + item.Value.FirstOrDefault());</span></div><div class="line"> <span class="comment">// foreach(var test in item.Value)</span></div><div class="line"> <span class="comment">// {</span></div><div class="line"> <span class="comment">// Logger.Error("test : " + test);</span></div><div class="line"> <span class="comment">// }</span></div><div class="line"> <span class="comment">//}</span></div><div class="line"></div><div class="line"> <span class="keyword">var</span> res = await client.PostAsync(url, sc).ConfigureAwait(<span class="literal">true</span>);</div><div class="line"> byte[] rData = await res.Content.ReadAsByteArrayAsync().ConfigureAwait(<span class="literal">true</span>);</div><div class="line"> <span class="built_in">string</span> rJson = Encoding.UTF8.GetString(rData);</div><div class="line"> Logger.Info(<span class="string">"url body response:\r\n{0} {1} {2}"</span>, url, json, rJson);</div><div class="line"> response = JsonHelper.ToObject<TResponse>(rJson);</div><div class="line"> <span class="keyword">return</span> response;</div><div class="line"> }</div><div class="line"> </div><div class="line"> }</div><div class="line"> <span class="keyword">catch</span> (System.Exception e)</div><div class="line"> {</div><div class="line"> TResponse r = <span class="keyword">new</span> TResponse();</div><div class="line"> Logger.Error(<span class="string">"请求异常:\r\n{0} {1}"</span>, e.ToString(), url);</div><div class="line"> <span class="keyword">throw</span>;</div><div class="line"> }</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="keyword">public</span> async Task<<span class="built_in">string</span>> PostAsync(<span class="built_in">string</span> url, <span class="built_in">string</span> body, <span class="built_in">string</span> method = <span class="string">"POST"</span>, NameValueCollection queryString = <span class="literal">null</span>, int timeout = <span class="number">60</span>)</div><div class="line"> {</div><div class="line"> <span class="built_in">string</span> response = <span class="literal">null</span>;</div><div class="line"> <span class="keyword">try</span></div><div class="line"> {</div><div class="line"> <span class="built_in">string</span> json = body;</div><div class="line"> HttpClient client = _httpClient;</div><div class="line"> <span class="keyword">if</span> (queryString == <span class="literal">null</span>)</div><div class="line"> {</div><div class="line"> queryString = <span class="keyword">new</span> NameValueCollection();</div><div class="line"> }</div><div class="line"> <span class="keyword">if</span> (<span class="built_in">String</span>.IsNullOrEmpty(method))</div><div class="line"> {</div><div class="line"> method = <span class="string">"POST"</span>;</div><div class="line"> }</div><div class="line"> url = CreateUrl(url, queryString);</div><div class="line"> <span class="comment">//Logger.Debug("请求:{0} {1}", method, url);</span></div><div class="line"> byte[] strData = Encoding.UTF8.GetBytes(json);</div><div class="line"> MemoryStream ms = <span class="keyword">new</span> MemoryStream(strData);</div><div class="line"> using (StreamContent sc = <span class="keyword">new</span> StreamContent(ms))</div><div class="line"> {</div><div class="line"> sc.Headers.ContentType = <span class="keyword">new</span> MediaTypeWithQualityHeaderValue(<span class="string">"application/json"</span>);</div><div class="line"> <span class="keyword">var</span> res = await client.PostAsync(url, sc).ConfigureAwait(<span class="literal">true</span>);</div><div class="line"> <span class="keyword">if</span> (res.Content == <span class="literal">null</span> || res.Content.Headers.ContentLength == <span class="number">0</span>)</div><div class="line"> {</div><div class="line"> response = <span class="string">""</span>;</div><div class="line"> }</div><div class="line"> <span class="keyword">else</span></div><div class="line"> {</div><div class="line"> byte[] rData = await res.Content.ReadAsByteArrayAsync().ConfigureAwait(<span class="literal">true</span>);</div><div class="line"> <span class="built_in">string</span> rJson = Encoding.UTF8.GetString(rData);</div><div class="line"> <span class="comment">//Logger.Debug("应答:\r\n{0}", rJson);</span></div><div class="line"> response = rJson;</div><div class="line"> }</div><div class="line"> }</div><div class="line"> </div><div class="line"> }</div><div class="line"> <span class="keyword">catch</span> (System.Exception e)</div><div class="line"> {</div><div class="line"> response = <span class="string">"ERROR"</span>;</div><div class="line"> Logger.Error(<span class="string">"请求异常:\r\n{0} {1}"</span>, e.ToString(), url);</div><div class="line"> }</div><div class="line"> <span class="keyword">return</span> response;</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="keyword">public</span> async Task<TResponse> PutAsync<TResponse>(<span class="built_in">string</span> url, object body, Dictionary<<span class="built_in">string</span>, <span class="built_in">string</span>> header, NameValueCollection queryString = <span class="literal">null</span>)</div><div class="line"> {</div><div class="line"> TResponse response = <span class="keyword">default</span>(TResponse);</div><div class="line"> <span class="keyword">try</span></div><div class="line"> {</div><div class="line"> <span class="built_in">string</span> json = JsonHelper.ToJson(body);</div><div class="line"> HttpClient client = _httpClient;</div><div class="line"> <span class="keyword">if</span> (queryString == <span class="literal">null</span>)</div><div class="line"> {</div><div class="line"> queryString = <span class="keyword">new</span> NameValueCollection();</div><div class="line"> }</div><div class="line"></div><div class="line"> url = CreateUrl(url, queryString);</div><div class="line"> <span class="comment">//Logger.Debug("请求:{0} {1}", method, url);</span></div><div class="line"> byte[] strData = Encoding.UTF8.GetBytes(json);</div><div class="line"> MemoryStream ms = <span class="keyword">new</span> MemoryStream(strData);</div><div class="line"> using (StreamContent sc = <span class="keyword">new</span> StreamContent(ms))</div><div class="line"> {</div><div class="line"> sc.Headers.ContentType = <span class="keyword">new</span> MediaTypeWithQualityHeaderValue(<span class="string">"application/json"</span>);</div><div class="line"> <span class="keyword">if</span> (header != <span class="literal">null</span>)</div><div class="line"> {</div><div class="line"> foreach (<span class="keyword">var</span> item <span class="keyword">in</span> header)</div><div class="line"> {</div><div class="line"> sc.Headers.Add(item.Key, item.Value);</div><div class="line"> }</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="keyword">var</span> res = await client.PutAsync(url, sc).ConfigureAwait(<span class="literal">true</span>);</div><div class="line"> byte[] rData = await res.Content.ReadAsByteArrayAsync().ConfigureAwait(<span class="literal">true</span>);</div><div class="line"> <span class="built_in">string</span> rJson = Encoding.UTF8.GetString(rData);</div><div class="line"> <span class="comment">//Logger.Debug("应答:\r\n{0}", rJson);</span></div><div class="line"> response = JsonHelper.ToObject<TResponse>(rJson);</div><div class="line"> <span class="keyword">return</span> response;</div><div class="line"> }</div><div class="line"></div><div class="line"> }</div><div class="line"> <span class="keyword">catch</span> (System.Exception e)</div><div class="line"> {</div><div class="line"> Logger.Error(<span class="string">"请求异常:\r\n{0} {1}"</span>, e.ToString(), url);</div><div class="line"> <span class="keyword">throw</span>;</div><div class="line"> }</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="keyword">public</span> async Task<TResponse> DeleteAsync<TResponse>(<span class="built_in">string</span> url, Dictionary<<span class="built_in">string</span>, <span class="built_in">string</span>> header, NameValueCollection queryString = <span class="literal">null</span>)</div><div class="line"> where TResponse : <span class="keyword">class</span>, <span class="keyword">new</span>()</div><div class="line"> {</div><div class="line"> TResponse response = <span class="keyword">default</span>(TResponse);</div><div class="line"> <span class="keyword">try</span></div><div class="line"> {</div><div class="line"> HttpClient client = _httpClient;</div><div class="line"> <span class="keyword">if</span> (queryString == <span class="literal">null</span>)</div><div class="line"> {</div><div class="line"> queryString = <span class="keyword">new</span> NameValueCollection();</div><div class="line"> }</div><div class="line"></div><div class="line"> url = CreateUrl(url, queryString);</div><div class="line"> <span class="comment">//Logger.Debug("请求:{0} {1}", method, url);</span></div><div class="line"></div><div class="line"> using (<span class="keyword">var</span> requestMessage = <span class="keyword">new</span> HttpRequestMessage(HttpMethod.Delete, url))</div><div class="line"> {</div><div class="line"> <span class="keyword">if</span> (header != <span class="literal">null</span>)</div><div class="line"> {</div><div class="line"> foreach (<span class="keyword">var</span> item <span class="keyword">in</span> header)</div><div class="line"> {</div><div class="line"> requestMessage.Headers.Add(item.Key, item.Value);</div><div class="line"> }</div><div class="line"> }</div><div class="line"> <span class="keyword">var</span> backinfo = await client.SendAsync(requestMessage).ConfigureAwait(<span class="literal">true</span>);</div><div class="line"> <span class="keyword">var</span> rJson = await backinfo.Content.ReadAsStringAsync().ConfigureAwait(<span class="literal">true</span>);</div><div class="line"> Logger.Info(<span class="string">"url response:\r\n{0} {1}"</span>, url, rJson);</div><div class="line"> response = JsonHelper.ToObject<TResponse>(rJson);</div><div class="line"> }</div><div class="line"></div><div class="line"> }</div><div class="line"> <span class="keyword">catch</span> (System.Exception e)</div><div class="line"> {</div><div class="line"> TResponse r = <span class="keyword">new</span> TResponse();</div><div class="line"> Logger.Error(<span class="string">"请求异常:\r\n{0}"</span>, e.ToString(), url);</div><div class="line"> <span class="keyword">return</span> r;</div><div class="line"> }</div><div class="line"> <span class="keyword">return</span> response;</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="keyword">public</span> async Task<TResponse> GetAsync<TResponse>(<span class="built_in">string</span> url, NameValueCollection queryString, Dictionary<<span class="built_in">string</span>, <span class="built_in">string</span>> header)</div><div class="line"> where TResponse : <span class="keyword">class</span>, <span class="keyword">new</span>()</div><div class="line"> {</div><div class="line"> TResponse response = <span class="literal">null</span>;</div><div class="line"> <span class="keyword">try</span></div><div class="line"> {</div><div class="line"> HttpClient client = _httpClient;</div><div class="line"> <span class="keyword">if</span> (queryString != <span class="literal">null</span>)</div><div class="line"> {</div><div class="line"> url = CreateUrl(url, queryString);</div><div class="line"> }</div><div class="line"> </div><div class="line"> <span class="comment">//Logger.Debug("请求:{0} {1}", "GET", url);</span></div><div class="line"> using (<span class="keyword">var</span> requestMessage = <span class="keyword">new</span> HttpRequestMessage(HttpMethod.Get, url))</div><div class="line"> {</div><div class="line"> <span class="keyword">if</span> (header != <span class="literal">null</span>)</div><div class="line"> {</div><div class="line"> foreach (<span class="keyword">var</span> item <span class="keyword">in</span> header)</div><div class="line"> {</div><div class="line"> requestMessage.Headers.Add(item.Key, item.Value);</div><div class="line"> }</div><div class="line"> }</div><div class="line"> <span class="keyword">var</span> backinfo = await client.SendAsync(requestMessage).ConfigureAwait(<span class="literal">true</span>);</div><div class="line"> <span class="keyword">var</span> rJson = await backinfo.Content.ReadAsStringAsync().ConfigureAwait(<span class="literal">true</span>);</div><div class="line"> Logger.Info(<span class="string">"url response:\r\n{0} {1}"</span>, url, rJson);</div><div class="line"> response = JsonHelper.ToObject<TResponse>(rJson);</div><div class="line"> }</div><div class="line"> </div><div class="line"> }</div><div class="line"> <span class="keyword">catch</span> (System.Exception e)</div><div class="line"> {</div><div class="line"> TResponse r = <span class="keyword">new</span> TResponse();</div><div class="line"> Logger.Error(<span class="string">"请求异常:\r\n{0} {1}"</span>, e.ToString(), url);</div><div class="line"> <span class="keyword">return</span> r;</div><div class="line"> }</div><div class="line"> <span class="keyword">return</span> response;</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="comment">//public async Task<TResponse> GetAsync<TResponse>(string url, NameValueCollection queryString)</span></div><div class="line"> <span class="comment">// where TResponse : class, new()</span></div><div class="line"> <span class="comment">//{</span></div><div class="line"> <span class="comment">// TResponse response = null;</span></div><div class="line"> <span class="comment">// try</span></div><div class="line"> <span class="comment">// {</span></div><div class="line"> <span class="comment">// HttpClient client = _httpClient;</span></div><div class="line"> <span class="comment">// if (queryString != null)</span></div><div class="line"> <span class="comment">// {</span></div><div class="line"> <span class="comment">// url = CreateUrl(url, queryString);</span></div><div class="line"> <span class="comment">// }</span></div><div class="line"> <span class="comment">// </span></div><div class="line"> <span class="comment">// //Logger.Debug("请求:{0} {1}", "GET", url);</span></div><div class="line"> <span class="comment">// byte[] rData = await client.GetByteArrayAsync(url).ConfigureAwait(true);</span></div><div class="line"> <span class="comment">// string rJson = Encoding.UTF8.GetString(rData);</span></div><div class="line"> <span class="comment">// Logger.Info("url response:\r\n{0} {1}", url, rJson);</span></div><div class="line"> <span class="comment">// response = JsonHelper.ToObject<TResponse>(rJson);</span></div><div class="line"> <span class="comment">// }</span></div><div class="line"> <span class="comment">// catch (System.Exception )</span></div><div class="line"> <span class="comment">// {</span></div><div class="line"> <span class="comment">// TResponse r = new TResponse();</span></div><div class="line"> <span class="comment">// //Logger.Error("请求异常:\r\n{0}", e.ToString());</span></div><div class="line"> <span class="comment">// return r;</span></div><div class="line"> <span class="comment">// }</span></div><div class="line"> <span class="comment">// return response;</span></div><div class="line"> <span class="comment">//}</span></div><div class="line"> <span class="keyword">public</span> async Task<TResponse> PostAsync<TResponse>(<span class="built_in">string</span> url, object body, Dictionary<<span class="built_in">string</span>, <span class="built_in">string</span>> header, <span class="built_in">string</span> method = <span class="literal">null</span>, NameValueCollection queryString = <span class="literal">null</span>)</div><div class="line"> {</div><div class="line"> TResponse response = <span class="keyword">default</span>(TResponse);</div><div class="line"> <span class="keyword">try</span></div><div class="line"> {</div><div class="line"> <span class="built_in">string</span> json = JsonHelper.ToJson(body);</div><div class="line"> HttpClient client = _httpClient;</div><div class="line"> <span class="keyword">if</span> (queryString == <span class="literal">null</span>)</div><div class="line"> {</div><div class="line"> queryString = <span class="keyword">new</span> NameValueCollection();</div><div class="line"> }</div><div class="line"></div><div class="line"> url = CreateUrl(url, queryString);</div><div class="line"> <span class="keyword">if</span> (<span class="built_in">String</span>.IsNullOrEmpty(method))</div><div class="line"> {</div><div class="line"> method = <span class="string">"POST"</span>;</div><div class="line"> }</div><div class="line"> <span class="comment">//Logger.Debug("请求:{0} {1}", method, url);</span></div><div class="line"> byte[] strData = Encoding.UTF8.GetBytes(json);</div><div class="line"> MemoryStream ms = <span class="keyword">new</span> MemoryStream(strData);</div><div class="line"> using (StreamContent sc = <span class="keyword">new</span> StreamContent(ms))</div><div class="line"> {</div><div class="line"> sc.Headers.ContentType = <span class="keyword">new</span> MediaTypeWithQualityHeaderValue(<span class="string">"application/json"</span>);</div><div class="line"> <span class="keyword">if</span> (header != <span class="literal">null</span>)</div><div class="line"> {</div><div class="line"> foreach (<span class="keyword">var</span> item <span class="keyword">in</span> header)</div><div class="line"> {</div><div class="line"> sc.Headers.Add(item.Key, item.Value);</div><div class="line"> }</div><div class="line"> }</div><div class="line"> </div><div class="line"> <span class="keyword">var</span> res = await client.PostAsync(url, sc).ConfigureAwait(<span class="literal">true</span>);</div><div class="line"> byte[] rData = await res.Content.ReadAsByteArrayAsync().ConfigureAwait(<span class="literal">true</span>);</div><div class="line"> <span class="built_in">string</span> rJson = Encoding.UTF8.GetString(rData);</div><div class="line"> <span class="comment">//Logger.Debug("应答:\r\n{0}", rJson);</span></div><div class="line"> response = JsonHelper.ToObject<TResponse>(rJson);</div><div class="line"> <span class="keyword">return</span> response;</div><div class="line"> }</div><div class="line"> </div><div class="line"> }</div><div class="line"> <span class="keyword">catch</span> (System.Exception )</div><div class="line"> {</div><div class="line"> <span class="comment">//Logger.Error("请求异常:\r\n{0}", e.ToString());</span></div><div class="line"> <span class="keyword">throw</span>;</div><div class="line"> }</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="comment">//public async Task<string> PostAsync(string url, object body, string method, NameValueCollection queryString)</span></div><div class="line"> <span class="comment">//{</span></div><div class="line"> <span class="comment">// string response = null;</span></div><div class="line"> <span class="comment">// try</span></div><div class="line"> <span class="comment">// {</span></div><div class="line"> <span class="comment">// string json = JsonHelper.ToJson(body);</span></div><div class="line"> <span class="comment">// HttpClient client = _httpClient;</span></div><div class="line"> <span class="comment">// if (queryString == null)</span></div><div class="line"> <span class="comment">// {</span></div><div class="line"> <span class="comment">// queryString = new NameValueCollection();</span></div><div class="line"> <span class="comment">// }</span></div><div class="line"></div><div class="line"> <span class="comment">// url = CreateUrl(url, queryString);</span></div><div class="line"> <span class="comment">// if (String.IsNullOrEmpty(method))</span></div><div class="line"> <span class="comment">// {</span></div><div class="line"> <span class="comment">// method = "POST";</span></div><div class="line"> <span class="comment">// }</span></div><div class="line"> <span class="comment">// //Logger.Debug("请求:{0} {1}", method, url);</span></div><div class="line"> <span class="comment">// byte[] strData = Encoding.UTF8.GetBytes(json);</span></div><div class="line"> <span class="comment">// MemoryStream ms = new MemoryStream(strData);</span></div><div class="line"> <span class="comment">// using (StreamContent sc = new StreamContent(ms))</span></div><div class="line"> <span class="comment">// {</span></div><div class="line"> <span class="comment">// sc.Headers.ContentType = new MediaTypeWithQualityHeaderValue("application/json");</span></div><div class="line"> <span class="comment">// var res = await client.PostAsync(url, sc).ConfigureAwait(true);</span></div><div class="line"> <span class="comment">// byte[] rData = await res.Content.ReadAsByteArrayAsync().ConfigureAwait(true);</span></div><div class="line"> <span class="comment">// string rJson = Encoding.UTF8.GetString(rData);</span></div><div class="line"> <span class="comment">// //Logger.Debug("应答:\r\n{0}", rJson);</span></div><div class="line"> <span class="comment">// response = rJson;</span></div><div class="line"> <span class="comment">// return response;</span></div><div class="line"> <span class="comment">// }</span></div><div class="line"> </div><div class="line"> <span class="comment">// }</span></div><div class="line"> <span class="comment">// catch (System.Exception )</span></div><div class="line"> <span class="comment">// {</span></div><div class="line"> <span class="comment">// //Logger.Error("请求异常:\r\n{0}", e.ToString());</span></div><div class="line"> <span class="comment">// throw;</span></div><div class="line"> <span class="comment">// }</span></div><div class="line"> <span class="comment">//}</span></div><div class="line"></div><div class="line"> <span class="keyword">public</span> async Task<TResult> PostWithTokenAsync<TResult>(<span class="built_in">string</span> url, object body, <span class="built_in">string</span> token, <span class="built_in">string</span> userId = <span class="literal">null</span>, <span class="built_in">string</span> method = <span class="string">"Post"</span>)</div><div class="line"> {</div><div class="line"> <span class="comment">//Stopwatch sw = new Stopwatch();</span></div><div class="line"> <span class="comment">//sw.Start();</span></div><div class="line"></div><div class="line"> <span class="built_in">string</span> apiUrl = $<span class="string">"{url}"</span>;</div><div class="line"> HttpMethod hm = <span class="keyword">new</span> HttpMethod(method);</div><div class="line"></div><div class="line"> using (<span class="keyword">var</span> request = <span class="keyword">new</span> HttpRequestMessage(hm, apiUrl))</div><div class="line"> {</div><div class="line"> <span class="keyword">if</span> (!<span class="built_in">String</span>.IsNullOrEmpty(token))</div><div class="line"> {</div><div class="line"> request.Headers.Authorization = <span class="keyword">new</span> AuthenticationHeaderValue(<span class="string">"Bearer"</span>, token);</div><div class="line"></div><div class="line"> }</div><div class="line"> <span class="keyword">if</span> (!<span class="built_in">String</span>.IsNullOrEmpty(userId))</div><div class="line"> {</div><div class="line"> request.Headers.Add(<span class="string">"User"</span>, userId);</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="built_in">string</span> json = <span class="string">""</span>;</div><div class="line"> <span class="keyword">if</span> (body != <span class="literal">null</span>)</div><div class="line"> {</div><div class="line"> json = Newtonsoft.Json.JsonConvert.SerializeObject(body);</div><div class="line"> }</div><div class="line"> request.Content = <span class="keyword">new</span> StringContent(json);</div><div class="line"> request.Content.Headers.ContentType = <span class="keyword">new</span> MediaTypeWithQualityHeaderValue(<span class="string">"application/json"</span>);</div><div class="line"></div><div class="line"> <span class="keyword">var</span> response = await _httpClient.SendAsync(request, HttpCompletionOption.ResponseContentRead).ConfigureAwait(<span class="literal">true</span>);</div><div class="line"> <span class="keyword">if</span> (response.StatusCode == System.Net.HttpStatusCode.Unauthorized ||</div><div class="line"> response.StatusCode == System.Net.HttpStatusCode.Forbidden)</div><div class="line"> {</div><div class="line"> <span class="keyword">throw</span> <span class="keyword">new</span> UnauthorizedAccessException(<span class="string">"验证失败"</span>);</div><div class="line"> }</div><div class="line"> <span class="keyword">try</span></div><div class="line"> {</div><div class="line"> response.EnsureSuccessStatusCode();</div><div class="line"> <span class="built_in">string</span> str = await response.Content.ReadAsStringAsync().ConfigureAwait(<span class="literal">true</span>);</div><div class="line"></div><div class="line"> <span class="comment">//sw.Stop();</span></div><div class="line"> <span class="comment">//if (sw.ElapsedMilliseconds >= 1000)</span></div><div class="line"> <span class="comment">//{</span></div><div class="line"> <span class="comment">//slowLogger.Warn("请求时间超过一秒:POST {0} {1}", apiUrl, sw.ElapsedMilliseconds);</span></div><div class="line"> <span class="comment">//}</span></div><div class="line"></div><div class="line"> <span class="keyword">return</span> Newtonsoft.Json.JsonConvert.DeserializeObject<TResult>(str);</div><div class="line"> }</div><div class="line"> <span class="keyword">catch</span> (Exception )</div><div class="line"> {</div><div class="line"> <span class="comment">//logger.Error("Post 失败:{0}\r\n{1}", url, e.ToString());</span></div><div class="line"> <span class="built_in">string</span> str = await response.Content.ReadAsStringAsync().ConfigureAwait(<span class="literal">true</span>);</div><div class="line"> <span class="comment">//logger.Error(str);</span></div><div class="line"> <span class="keyword">throw</span>;</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="keyword">public</span> async Task<TResult> SubmitFormAsync<TResult>(<span class="built_in">string</span> url, Dictionary<<span class="built_in">string</span>, <span class="built_in">string</span>> formData, <span class="built_in">string</span> method = <span class="string">"Post"</span>)</div><div class="line"> {</div><div class="line"> HttpMethod hm = <span class="keyword">new</span> HttpMethod(method);</div><div class="line"> using (<span class="keyword">var</span> request = <span class="keyword">new</span> HttpRequestMessage(hm, url))</div><div class="line"> {</div><div class="line"> request.Content = <span class="keyword">new</span> FormUrlEncodedContent(formData);</div><div class="line"> <span class="keyword">var</span> response = await _httpClient.SendAsync(request, HttpCompletionOption.ResponseContentRead).ConfigureAwait(<span class="literal">true</span>);</div><div class="line"> <span class="keyword">if</span> (response.StatusCode == System.Net.HttpStatusCode.Unauthorized ||</div><div class="line"> response.StatusCode == System.Net.HttpStatusCode.Forbidden)</div><div class="line"> {</div><div class="line"> <span class="keyword">throw</span> <span class="keyword">new</span> UnauthorizedAccessException(<span class="string">"验证失败"</span>);</div><div class="line"> }</div><div class="line"> response.EnsureSuccessStatusCode();</div><div class="line"> <span class="built_in">string</span> str = await response.Content.ReadAsStringAsync().ConfigureAwait(<span class="literal">true</span>);</div><div class="line"> <span class="keyword">return</span> Newtonsoft.Json.JsonConvert.DeserializeObject<TResult>(str);</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="keyword">public</span> <span class="keyword">static</span> <span class="built_in">string</span> CreateUrl(<span class="built_in">string</span> url, NameValueCollection qs)</div><div class="line"> {</div><div class="line"> <span class="keyword">if</span> (qs != <span class="literal">null</span> && qs.Count > <span class="number">0</span>)</div><div class="line"> {</div><div class="line"> StringBuilder sb = <span class="keyword">new</span> StringBuilder();</div><div class="line"> List<<span class="built_in">string</span>> kl = qs.AllKeys.ToList();</div><div class="line"> foreach (<span class="built_in">string</span> k <span class="keyword">in</span> kl)</div><div class="line"> {</div><div class="line"> <span class="keyword">if</span> (sb.Length > <span class="number">0</span>)</div><div class="line"> {</div><div class="line"> sb.Append(<span class="string">"&"</span>);</div><div class="line"> }</div><div class="line"> sb.Append(k).Append(<span class="string">"="</span>);</div><div class="line"> <span class="keyword">if</span> (!<span class="built_in">String</span>.IsNullOrEmpty(qs[k]))</div><div class="line"> {</div><div class="line"></div><div class="line"> sb.Append(System.Net.WebUtility.UrlEncode(qs[k]));</div><div class="line"> }</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="keyword">if</span> (url != <span class="literal">null</span>)</div><div class="line"> {</div><div class="line"> <span class="keyword">if</span> (url.Contains(<span class="string">"?"</span>))</div><div class="line"> {</div><div class="line"> url = url + <span class="string">"&"</span> + sb.ToString();</div><div class="line"> }</div><div class="line"> <span class="keyword">else</span></div><div class="line"> {</div><div class="line"> url = url + <span class="string">"?"</span> + sb.ToString();</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="keyword">return</span> url;</div><div class="line"></div><div class="line"> }</div><div class="line"></div><div class="line"> #region Global</div><div class="line"> <span class="keyword">public</span> async Task<List<UserLoginInfo>> GetAllUserLoginInfosAsync()</div><div class="line"> {</div><div class="line"> <span class="keyword">var</span> back = await AutoRetry.RunAsync<ResponseMessage<List<UserLoginInfo>>>(() =></div><div class="line"> {</div><div class="line"> <span class="keyword">return</span> GetAsync<ResponseMessage<List<UserLoginInfo>>>(</div><div class="line"> $<span class="string">"{IngestDbUrl}/{USERAPI20}/userlogininfo/all"</span>, <span class="literal">null</span>, GetIngestHeader()</div><div class="line"> );</div><div class="line"> }).ConfigureAwait(<span class="literal">true</span>);</div><div class="line"></div><div class="line"> <span class="keyword">if</span> (back != <span class="literal">null</span>)</div><div class="line"> {</div><div class="line"> <span class="keyword">return</span> back.Ext;</div><div class="line"> }</div><div class="line"> <span class="keyword">return</span> <span class="literal">null</span>;</div><div class="line"> }</div><div class="line"> #endregion</div><div class="line"></div><div class="line"> #region Task</div><div class="line"></div><div class="line"> <span class="keyword">public</span> async Task<TaskSource> GetTaskSourceByTaskIdAsync(int taskid)</div><div class="line"> {</div><div class="line"> <span class="keyword">var</span> back = await AutoRetry.RunAsync<ResponseMessage<TaskSource>>(() =></div><div class="line"> {</div><div class="line"> <span class="keyword">return</span> GetAsync<ResponseMessage<TaskSource>>(</div><div class="line"> $<span class="string">"{IngestDbUrl}/{TASKAPI20}/tasksource/{taskid}"</span>,</div><div class="line"> <span class="literal">null</span>, GetIngestHeader());</div><div class="line"> }).ConfigureAwait(<span class="literal">true</span>);</div><div class="line"></div><div class="line"> <span class="keyword">if</span> (back != <span class="literal">null</span>)</div><div class="line"> {</div><div class="line"> <span class="keyword">return</span> back.Ext;</div><div class="line"> }</div><div class="line"> <span class="keyword">return</span> TaskSource.emUnknowTask;</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="keyword">public</span> async Task<DispatchTask> GetTaskDBAsync(int taskid)</div><div class="line"> {</div><div class="line"> <span class="keyword">var</span> back = await GetAsync<ResponseMessage<DispatchTask>>(</div><div class="line"> $<span class="string">"{IngestDbUrl}/{TASKAPI30}/db/{taskid}"</span>, <span class="literal">null</span>, GetIngestHeader()</div><div class="line"> ).ConfigureAwait(<span class="literal">true</span>);</div><div class="line"></div><div class="line"> <span class="keyword">if</span> (back != <span class="literal">null</span>)</div><div class="line"> {</div><div class="line"> <span class="keyword">return</span> back.Ext;</div><div class="line"> }</div><div class="line"> <span class="keyword">return</span> <span class="literal">null</span>;</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="keyword">public</span> async Task<TaskContent> ReScheduleTaskChannelAsync(int oldtaskid)</div><div class="line"> {</div><div class="line"> <span class="keyword">var</span> back = await AutoRetry.RunAsync<ResponseMessage<TaskContent>>(() =></div><div class="line"> {</div><div class="line"></div><div class="line"> <span class="keyword">return</span> PutAsync<ResponseMessage<TaskContent>>(</div><div class="line"> $<span class="string">"{IngestDbUrl}/{TASKAPI30}/reschedule/channel/{oldtaskid}"</span>, <span class="literal">null</span>,</div><div class="line"> GetIngestHeader());</div><div class="line"> }).ConfigureAwait(<span class="literal">true</span>);</div><div class="line"></div><div class="line"> <span class="keyword">if</span> (back != <span class="literal">null</span> && back.IsSuccess())</div><div class="line"> {</div><div class="line"> <span class="keyword">return</span> back.Ext;</div><div class="line"> }</div><div class="line"> <span class="keyword">return</span> <span class="literal">null</span>;</div><div class="line"> }</div><div class="line"> #endregion</div><div class="line"> </div><div class="line"> }</div></pre></td></tr></table></figure>
<ol>
<li><p>在异步方法中,不要使用 Thread.Sleep;在同步方法中,不要使用Task.Delay ,否则可能出现线程死锁,结果难出来。</p>
</li>
<li><p>吞吐量(TPS)、QPS(每秒查询率)、并发数、响应时间(RT)<br>当时为了增加qps,把所有webapi接口都改成异步请求</p>
</li>
</ol>
]]></content>
<summary type="html">
<p> 最近优化了些服务器做下记录</p>
<ol>
<li>httpclient的使用<blockquote>
<p>httpclient不能立即关闭,会占用资源,并发量一大就耗尽。所以.net core 会使用如下:</p>
</blockquote>
</li>
</ol
</summary>
<category term="服务器" scheme="https://xuecat.github.io/categories/%E6%9C%8D%E5%8A%A1%E5%99%A8/"/>
<category term="分布式" scheme="https://xuecat.github.io/tags/%E5%88%86%E5%B8%83%E5%BC%8F/"/>
</entry>
<entry>
<title>单元测试白盒(248)</title>
<link href="https://xuecat.github.io/2019/05/19/248/"/>
<id>https://xuecat.github.io/2019/05/19/248/</id>
<published>2019-05-19T07:31:39.000Z</published>
<updated>2019-09-04T15:49:31.737Z</updated>
<content type="html"><![CDATA[<p><em>昨天下雨了!好像!</em><br><blockquote><p>外面风雨琳琅,漫山遍野都是今天。</p>
</blockquote></p>
<h2 id="测试项目"><a href="#测试项目" class="headerlink" title="测试项目"></a>测试项目</h2><p> vs支持的白盒测试项目的编写。一般用来测试接口的</p>
<ul>
<li>测试项目引用必须引用到实体项目</li>
<li>测试项目链接必须连接到实体项目中间文件: ../test/Debug/test.obj.</li>
<li>包含头文件 <code>#include "../test/test.h"</code></li>
</ul>
<hr>
<p> c#的要简单点,直接引用项目,然后调用就可以了。<br> 唯一的问题在于dot net core的测试项目的创建。mstest,nunit,xunit这三个项目,好像社区用xunit来创建多些,还能跨平台。</p>
<hr>
<p> <code>Assert.Equal</code>几乎都是用这个。</p>
<p><strong>然后看同步的测试项目:</strong></p>
]]></content>
<summary type="html">
<p><em>昨天下雨了!好像!</em><br><blockquote><p>外面风雨琳琅,漫山遍野都是今天。</p>
</blockquote></p>
<h2 id="测试项目"><a href="#测试项目" class="headerlink" title="测试项目"
</summary>
<category term="测试" scheme="https://xuecat.github.io/categories/%E6%B5%8B%E8%AF%95/"/>
<category term="编译器和VC" scheme="https://xuecat.github.io/tags/%E7%BC%96%E8%AF%91%E5%99%A8%E5%92%8CVC/"/>
<category term="学习看书笔记" scheme="https://xuecat.github.io/tags/%E5%AD%A6%E4%B9%A0%E7%9C%8B%E4%B9%A6%E7%AC%94%E8%AE%B0/"/>
</entry>
<entry>
<title>资源问题(247)</title>
<link href="https://xuecat.github.io/2018/11/26/247/"/>
<id>https://xuecat.github.io/2018/11/26/247/</id>
<published>2018-11-26T13:58:52.000Z</published>
<updated>2018-11-26T14:13:05.162Z</updated>
<content type="html"><![CDATA[<p> 今天说给收录写个新功能来着,搞半天老是资源错误,”试图执行的操作不受支持”。气死人了。<br> 最后想起在DoDataExchange下个断点,一个一个的找资源控件问题,</p>
]]></content>
<summary type="html">
<p> 今天说给收录写个新功能来着,搞半天老是资源错误,”试图执行的操作不受支持”。气死人了。<br> 最后想起在DoDataExchange下个断点,一个一个的找资源控件问题,</p>
</summary>
<category term="Windows" scheme="https://xuecat.github.io/categories/Windows/"/>
<category term="mfc" scheme="https://xuecat.github.io/tags/mfc/"/>
</entry>
<entry>
<title>高性能mysql(246)</title>
<link href="https://xuecat.github.io/2018/10/22/246/"/>
<id>https://xuecat.github.io/2018/10/22/246/</id>
<published>2018-10-22T15:52:18.000Z</published>
<updated>2019-09-04T16:13:52.090Z</updated>
<content type="html"><![CDATA[<p><strong>schema</strong></p>
<ul>
<li><p>尽量避免<code>NULL</code>, 可为<code>NULL</code>的列使得索引 索引统计和值比较都更为复杂,可为<code>NULL</code>的列会使用更多空间</p>
</li>
<li><p>整数类型, INT(11),并不会限制值的合法范围,只是规定MYSQL显示字符的个数;<code>DECIMAL</code>是浮点型</p>
</li>
<li><p>字符类型,<code>VARCHAR</code>存储变长字符串,比定长<code>CHAR</code>(md5等这种来存储)更省空间.会额外多1到2个字节来存储长度</p>
</li>
</ul>
]]></content>
<summary type="html">
<p><strong>schema</strong></p>
<ul>
<li><p>尽量避免<code>NULL</code>, 可为<code>NULL</code>的列使得索引 索引统计和值比较都更为复杂,可为<code>NULL</code>的列会使用更多空间</p>
<
</summary>
<category term="数据库" scheme="https://xuecat.github.io/categories/%E6%95%B0%E6%8D%AE%E5%BA%93/"/>
<category term="Mysql" scheme="https://xuecat.github.io/tags/Mysql/"/>
</entry>
<entry>
<title>mysql(245)</title>
<link href="https://xuecat.github.io/2018/09/23/245/"/>
<id>https://xuecat.github.io/2018/09/23/245/</id>
<published>2018-09-22T17:39:53.000Z</published>
<updated>2018-09-22T17:46:44.403Z</updated>
<content type="html"><![CDATA[<ul>
<li><p>约束</p>
<ul>
<li>非空约束(not null)</li>
<li>唯一性约束(unique)</li>
<li>主键约束(primary key) PK</li>
<li>外键约束(foreign key) FK</li>
<li>检查约束(目前MySQL不支持、Oracle支持)</li>
</ul>
</li>
<li><p>非空约束</p>
<ul>
<li><code>name varchar(32) not null</code></li>
</ul>
</li>
<li><p>唯一约束 (表之间插入相同值会报错)</p>
<ul>
<li><code>email varchar(128) unique</code></li>
<li><code>email varchar(128), unique(name,email)</code></li>
<li><code>constraint t_user_email_unique unique(email)</code>给约束表起名,方便以后删除</li>
</ul>
</li>
<li><p>主键约束</p>
<ul>
<li><code>id int(10) primary key</code> 单一列级</li>
<li><code>constraint t_user_id_pk primary key(id)</code> 单一表级</li>
<li><code>primary key(id,name)</code> 符合表级</li>
<li>主键自增 <figure class="highlight cs"><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="function">reate table <span class="title">t_user</span>(<span class="params"></span></span></div><div class="line"> id <span class="keyword">int</span>(<span class="number">10</span>) primary key auto_increment,</div><div class="line"> name <span class="title">varchar</span>(<span class="params"><span class="number">32</span></span>) not <span class="literal">null</span></div><div class="line"> );</div><div class="line"></div><div class="line"><span class="function">insert <span class="keyword">into</span> <span class="title">t_user</span>(<span class="params">name</span>) <span class="title">values</span>(<span class="params"><span class="string">'jay'</span></span>)</span>;</div><div class="line"><span class="keyword">select</span> * <span class="keyword">from</span> t_user</div></pre></td></tr></table></figure>
</li>
</ul>
</li>
<li><p>外键约束</p>
</li>
</ul>
<ul>
<li><code>FOREIGN KEY (Id_P) REFERENCES Persons(Id_P)</code></li>
</ul>
<h4 id="索引"><a href="#索引" class="headerlink" title="索引"></a>索引</h4><p><code>字段建立索引可以大大提升查询速度</code></p>
<ul>
<li><p>普通索引</p>
<ul>
<li><code>CREATE INDEX indexName ON mytable(username(length))</code></li>
<li><code>CREATE TABLE mytable( ID INT NOT NULL, username VARCHAR(16) NOT NULL, INDEX [indexName] (username(length)) )</code></li>
</ul>
</li>
<li><p>唯一索引<br> 它必须唯一,但允许有空值</p>
<ul>
<li><code>CREATE UNIQUE INDEX indexName ON mytable(username(length))</code></li>
<li><code>CREATE TABLE mytable( ID INT NOT NULL, username VARCHAR(16) NOT NULL, UNIQUE [indexName] (username(length)) )</code></li>
</ul>
</li>
<li><p>主键索引<br> 唯一且不允许空</p>
<ul>
<li><code>CREATE TABLE mytable( ID INT NOT NULL, username VARCHAR(16) NOT NULL, PRIMARY KEY(ID) );</code></li>
</ul>
</li>
<li><p>组合索引</p>
<ul>
<li><code>ALTER TABLE mytable ADD INDEX name_city_age (name(10),city,age);</code></li>
</ul>
</li>
</ul>
<h3 id="字符串"><a href="#字符串" class="headerlink" title="字符串"></a>字符串</h3><p>varchar最好在1024以内,虽然它能支持到6553;其它用blob和text来代替</p>
]]></content>
<summary type="html">
<ul>
<li><p>约束</p>
<ul>
<li>非空约束(not null)</li>
<li>唯一性约束(unique)</li>
<li>主键约束(primary key) PK</li>
<li>外键约束(foreign key) FK</li>
<li>检查约束(
</summary>
<category term="数据库" scheme="https://xuecat.github.io/categories/%E6%95%B0%E6%8D%AE%E5%BA%93/"/>
<category term="Mysql" scheme="https://xuecat.github.io/tags/Mysql/"/>
</entry>
<entry>
<title>Xsum问题(243)</title>
<link href="https://xuecat.github.io/2018/09/04/243/"/>
<id>https://xuecat.github.io/2018/09/04/243/</id>
<published>2018-09-04T14:40:16.000Z</published>
<updated>2018-09-25T15:38:00.270Z</updated>
<content type="html"><![CDATA[<h3 id="xsum问题"><a href="#xsum问题" class="headerlink" title="xsum问题"></a>xsum问题</h3><ul>
<li><p>2sum</p>
<ul>
<li><p>map结构时间复杂度O(n)<br>map把那些离target有差距的都存起来,等target-nums[i]有对应值时,就表示达到了</p>
<figure class="highlight cpp"><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></pre></td><td class="code"><pre><div class="line"><span class="built_in">vector</span><<span class="keyword">int</span>> twoSum(<span class="built_in">vector</span><<span class="keyword">int</span>>& nums, <span class="keyword">int</span> target) {</div><div class="line"> <span class="built_in">vector</span><<span class="keyword">int</span>> res;</div><div class="line"> <span class="keyword">int</span> len = nums.size();</div><div class="line"> <span class="keyword">if</span> ( len < <span class="number">2</span>) </div><div class="line"> <span class="keyword">return</span> res;</div><div class="line"></div><div class="line"> <span class="built_in">map</span><<span class="keyword">int</span>, <span class="keyword">int</span>> mp;</div><div class="line"></div><div class="line"> <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i < len ; i++){</div><div class="line"> <span class="keyword">if</span> (mp[target - nums[i]] != <span class="number">0</span>){</div><div class="line"> res.push_back(mp[target - nums[i]] - <span class="number">1</span>);<span class="comment">//减去加的那个1</span></div><div class="line"> res.push_back(i);</div><div class="line"> }</div><div class="line"> <span class="keyword">else</span>{</div><div class="line"> mp[nums[i]] = i + <span class="number">1</span>;<span class="comment">//故意加了1是为了防止为0,这样好判断这个键-值是否存在</span></div><div class="line"> }</div><div class="line"> }</div><div class="line"> <span class="comment">//sort(res.begin(), res.end());</span></div><div class="line"> <span class="keyword">return</span> res;</div><div class="line">}</div></pre></td></tr></table></figure>
</li>
<li><p>先对数据进行排序,如果用STL的sort快排,时间复杂度为O(nlogn),然后设置两个指针,一个初始化为数组的头,一个初始化在数组的尾,然后两边向中间扫描,如果当前两个指针指向的数的和正好是target,那么就保存当前数对 (防止重复就跳过相同值)<br>这个方法找多个就很麻烦了</p>
<figure class="highlight cpp"><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><div class="line">35</div><div class="line">36</div><div class="line">37</div><div class="line">38</div><div class="line">39</div><div class="line">40</div><div class="line">41</div><div class="line">42</div><div class="line">43</div><div class="line">44</div><div class="line">45</div><div class="line">46</div></pre></td><td class="code"><pre><div class="line"><span class="built_in">vector</span><<span class="keyword">int</span>> twoSum(<span class="built_in">vector</span><<span class="keyword">int</span>>& nums, <span class="keyword">int</span> target) {</div><div class="line"> <span class="built_in">vector</span><<span class="keyword">int</span>> res;</div><div class="line"> <span class="keyword">int</span> len = nums.size();</div><div class="line"> <span class="keyword">if</span> (len < <span class="number">2</span>)</div><div class="line"> <span class="keyword">return</span> res;</div><div class="line"> <span class="built_in">vector</span><<span class="keyword">int</span>> numsTmp = nums;</div><div class="line"> sort(nums.begin(), nums.end()); <span class="comment">//使得有序</span></div><div class="line"></div><div class="line"> <span class="comment">//收尾指针法</span></div><div class="line"> <span class="keyword">int</span> sta = <span class="number">0</span>;</div><div class="line"> <span class="keyword">int</span> end = len - <span class="number">1</span>;</div><div class="line"></div><div class="line"> <span class="keyword">while</span> (sta < end)</div><div class="line"> {</div><div class="line"> <span class="keyword">if</span> (nums[sta] + nums[end] == target)</div><div class="line"> {</div><div class="line"> <span class="keyword">bool</span> f1 = <span class="literal">false</span>;</div><div class="line"> <span class="keyword">bool</span> f2 = <span class="literal">false</span>;</div><div class="line"> <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i < len; i++)<span class="comment">//排序队列找到了,还要去原来队列找到对应的值序列号</span></div><div class="line"> {</div><div class="line"> <span class="keyword">if</span> (f1 && f2)</div><div class="line"> <span class="keyword">break</span>;</div><div class="line"> <span class="keyword">if</span> (!f1 && numsTmp[i] == nums[sta]) <span class="comment">// nums[sta] 可能等于 nums[end]</span></div><div class="line"> {</div><div class="line"> res.push_back(i);</div><div class="line"> f1 = <span class="literal">true</span>;</div><div class="line"> }</div><div class="line"> <span class="keyword">else</span> <span class="keyword">if</span> (!f2 && numsTmp[i] == nums[end]) <span class="comment">// 这里是else if 不是if</span></div><div class="line"> {</div><div class="line"> res.push_back(i);</div><div class="line"> f2 = <span class="literal">true</span>;</div><div class="line"> }</div><div class="line"> }</div><div class="line"> <span class="keyword">break</span>;</div><div class="line"> }</div><div class="line"> <span class="keyword">else</span> <span class="keyword">if</span> (nums[sta] + nums[end] < target)<span class="comment">//单方面递增或递减</span></div><div class="line"> {</div><div class="line"> sta++;</div><div class="line"> }</div><div class="line"> <span class="keyword">else</span>{</div><div class="line"> end--;</div><div class="line"> }</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="keyword">return</span> res;</div><div class="line">}</div></pre></td></tr></table></figure>
</li>
</ul>
</li>
<li><p>3sum</p>
<ul>
<li>依次对数组中得每一个元素num[i]找和为target-num[i]的连个数,这样问题又回到了2Sum上</li>
</ul>
</li>
<li><p>4sum</p>
<ul>
<li><figure class="highlight maxima"><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><div class="line">35</div><div class="line">36</div><div class="line">37</div><div class="line">38</div><div class="line">39</div><div class="line">40</div><div class="line">41</div><div class="line">42</div><div class="line">43</div><div class="line">44</div><div class="line">45</div><div class="line">46</div><div class="line">47</div><div class="line">48</div><div class="line">49</div><div class="line">50</div><div class="line">51</div><div class="line">52</div></pre></td><td class="code"><pre><div class="line"> <span class="built_in">vector</span><<span class="built_in">vector</span><int> > fourSum(<span class="built_in">vector</span><int> &<span class="built_in">num</span>, int target) {</div><div class="line"> <span class="built_in">vector</span><<span class="built_in">vector</span><int> > ret;</div><div class="line"></div><div class="line"> <span class="keyword">if</span> (<span class="built_in">num</span>.size() == <span class="number">0</span>) <span class="built_in">return</span> ret;</div><div class="line"></div><div class="line"> <span class="built_in">sort</span>(<span class="built_in">num</span>.begin(), <span class="built_in">num</span>.end());</div><div class="line"></div><div class="line"> <span class="keyword">for</span> (size_t a = <span class="number">0</span>; a < <span class="built_in">num</span>.size(); ++a)</div><div class="line"> {</div><div class="line"> <span class="keyword">if</span> (a != <span class="number">0</span> && <span class="built_in">num</span>[a] == <span class="built_in">num</span>[a-<span class="number">1</span>])</div><div class="line"> continue;</div><div class="line"> </div><div class="line"> <span class="keyword">for</span> (size_t b = a + <span class="number">1</span>; b < <span class="built_in">num</span>.size(); ++b)</div><div class="line"> {</div><div class="line"> <span class="keyword">if</span> (b != a + <span class="number">1</span> && <span class="built_in">num</span>[b] == <span class="built_in">num</span>[b-<span class="number">1</span>])</div><div class="line"> continue;</div><div class="line"> </div><div class="line"> size_t c = b + <span class="number">1</span>;</div><div class="line"> size_t d = <span class="built_in">num</span>.size() - <span class="number">1</span>;</div><div class="line"> </div><div class="line"> <span class="keyword">while</span> (c < d)</div><div class="line"> {</div><div class="line"> const int <span class="built_in">sum</span> = <span class="built_in">num</span>[a] + <span class="built_in">num</span>[b] + <span class="built_in">num</span>[c] + <span class="built_in">num</span>[d];</div><div class="line"> </div><div class="line"> <span class="keyword">if</span> (<span class="built_in">sum</span> > target)</div><div class="line"> --d;</div><div class="line"> <span class="keyword">else</span> <span class="keyword">if</span> (<span class="built_in">sum</span> < target)</div><div class="line"> ++c;</div><div class="line"> <span class="keyword">else</span> <span class="keyword">if</span> (c != b + <span class="number">1</span> && <span class="built_in">num</span>[c] == <span class="built_in">num</span>[c-<span class="number">1</span>])</div><div class="line"> ++c;</div><div class="line"> <span class="keyword">else</span> <span class="keyword">if</span> (d != <span class="built_in">num</span>.size() - <span class="number">1</span> && <span class="built_in">num</span>[d] == <span class="built_in">num</span>[d+<span class="number">1</span>])</div><div class="line"> --d;</div><div class="line"> <span class="keyword">else</span></div><div class="line"> {</div><div class="line"> <span class="built_in">vector</span><int> result;</div><div class="line"> </div><div class="line"> result.push_back(<span class="built_in">num</span>[a]);</div><div class="line"> result.push_back(<span class="built_in">num</span>[b]);</div><div class="line"> result.push_back(<span class="built_in">num</span>[c]);</div><div class="line"> result.push_back(<span class="built_in">num</span>[d]);</div><div class="line"> </div><div class="line"> ret.push_back(result);</div><div class="line"> </div><div class="line"> ++c;</div><div class="line"> --d;</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="built_in">return</span> ret;</div><div class="line">}</div></pre></td></tr></table></figure></li>
</ul>
</li>
</ul>
]]></content>
<summary type="html">
<h3 id="xsum问题"><a href="#xsum问题" class="headerlink" title="xsum问题"></a>xsum问题</h3><ul>
<li><p>2sum</p>
<ul>
<li><p>map结构时间复杂度O(n)<br>map把那些
</summary>
<category term="语言" scheme="https://xuecat.github.io/categories/%E8%AF%AD%E8%A8%80/"/>
<category term="c++" scheme="https://xuecat.github.io/tags/c/"/>
<category term="stl" scheme="https://xuecat.github.io/tags/stl/"/>
<category term="算法" scheme="https://xuecat.github.io/tags/%E7%AE%97%E6%B3%95/"/>
</entry>
<entry>
<title>permutation(242)</title>
<link href="https://xuecat.github.io/2018/08/19/242/"/>
<id>https://xuecat.github.io/2018/08/19/242/</id>
<published>2018-08-19T09:32:02.000Z</published>
<updated>2018-08-19T10:22:13.521Z</updated>
<content type="html"><![CDATA[<p>排列算法<code>stl</code>里面的<code>next_permutation</code>和<code>prev_permutation</code></p>
<h4 id="next-permutation"><a href="#next-permutation" class="headerlink" title="next_permutation"></a><code>next_permutation</code></h4><ol>
<li>从尾部开始往前寻找两个相邻的元素,第1个元素i,第2个元素j(从前往后数的),且i<j</li>
<li>在[j,end)中寻找一个最小的k使其满足A[i]<A[k],将i与k交换</li>
<li>[j,last)范围的元素置逆(颠倒排列)</li>
</ol>
<blockquote>
<p>1,3,2-> 2,1,3过程<br>i是1,j是3. k是3;互换后是3,1,2; 由于j是3,逆序就是2,1,3了</p>
</blockquote>
<h4 id="prev-permutation"><a href="#prev-permutation" class="headerlink" title="prev_permutation"></a><code>prev_permutation</code></h4><ol>
<li>从尾部开始往前寻找两个相邻的元素,第1个元素i,第2个元素j(从前往后数的),且i>j</li>
<li>从最尾端开始往前寻找第一个小于i的元素,令它为k, 讲i和k对调</li>
<li>j之后颠倒</li>
</ol>
]]></content>
<summary type="html">
<p>排列算法<code>stl</code>里面的<code>next_permutation</code>和<code>prev_permutation</code></p>
<h4 id="next-permutation"><a href="#next-permutati
</summary>
<category term="语言" scheme="https://xuecat.github.io/categories/%E8%AF%AD%E8%A8%80/"/>
<category term="c++" scheme="https://xuecat.github.io/tags/c/"/>
<category term="stl" scheme="https://xuecat.github.io/tags/stl/"/>
<category term="算法" scheme="https://xuecat.github.io/tags/%E7%AE%97%E6%B3%95/"/>
</entry>
<entry>
<title>c++的currying(241)</title>
<link href="https://xuecat.github.io/2018/08/09/241/"/>
<id>https://xuecat.github.io/2018/08/09/241/</id>
<published>2018-08-08T16:06:25.000Z</published>
<updated>2018-08-08T16:07:17.114Z</updated>
<content type="html">< -> <span class="keyword">auto</span> {<span class="comment">//草这就是c++的lamda,和js c#的完全不同啊,我这个笨蛋第一时间居然没反应过来</span></div><div class="line"> <span class="keyword">return</span> f(args..., rest...);</div><div class="line"> };</div><div class="line">}</div><div class="line"></div><div class="line"><span class="function"><span class="keyword">void</span> <span class="title">demo</span><span class="params">(<span class="keyword">int</span> a, <span class="keyword">int</span> & b, <span class="keyword">int</span> c, <span class="keyword">int</span> & d)</span> </span>{</div><div class="line"> b = b + <span class="number">1</span>;</div><div class="line"> d = d + <span class="number">1</span>;</div><div class="line">}</div><div class="line"></div><div class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">()</span> </span>{</div><div class="line"> <span class="keyword">int</span> a = <span class="number">11</span>, b = <span class="number">111</span>, c = <span class="number">1111</span>, d = <span class="number">11111</span>;</div><div class="line"> <span class="built_in">std</span>::<span class="built_in">cout</span> << <span class="string">"a: "</span> << a << <span class="string">" b: "</span> << b << <span class="string">" c: "</span> << c << <span class="string">" d: "</span> << d << <span class="built_in">std</span>::<span class="built_in">endl</span>;</div><div class="line"></div><div class="line"> partial(demo, a, <span class="built_in">std</span>::ref(b))(c, <span class="built_in">std</span>::ref(d));</div><div class="line"></div><div class="line"> <span class="built_in">std</span>::<span class="built_in">cout</span> << <span class="string">"a: "</span> << a << <span class="string">" b: "</span> << b << <span class="string">" c: "</span> << c << <span class="string">" d: "</span> << d << <span class="built_in">std</span>::<span class="built_in">endl</span>;</div><div class="line"></div><div class="line"> <span class="keyword">return</span> <span class="number">0</span>;</div><div class="line">}</div></pre></td></tr></table></figure>]]></content>
<summary type="html">
<figure class="highlight c++"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div>
</summary>
<category term="语言" scheme="https://xuecat.github.io/categories/%E8%AF%AD%E8%A8%80/"/>
<category term="c++" scheme="https://xuecat.github.io/tags/c/"/>
<category term="stl" scheme="https://xuecat.github.io/tags/stl/"/>
</entry>
<entry>
<title>stl排序(240)</title>
<link href="https://xuecat.github.io/2018/07/28/240/"/>
<id>https://xuecat.github.io/2018/07/28/240/</id>
<published>2018-07-28T08:09:45.000Z</published>
<updated>2018-07-28T09:16:01.303Z</updated>
<content type="html"><![CDATA[<blockquote class="blockquote-center">以前有笔记,但忘了放哪了,再做一次吧</blockquote>
<p><img src="/picture/240.jpg" alt=""></p>
<ul>
<li>stable_sort</li>
<li>partial_sort</li>
<li>nth_element</li>
<li>partition和stable_partition</li>
</ul>
<figure class="highlight c++"><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"><span class="function"><span class="keyword">bool</span> <span class="title">func</span><span class="params">(<span class="keyword">const</span> w& l, <span class="keyword">const</span> w& r)</span> </span>{...}</div><div class="line"></div><div class="line"><span class="function"><span class="keyword">bool</span> <span class="title">ifunc</span><span class="params">(<span class="keyword">const</span> w& c)</span> </span>{...}</div></pre></td></tr></table></figure>
<h4 id="partial-sort"><a href="#partial-sort" class="headerlink" title="partial_sort"></a>partial_sort</h4><pre><code>只排一部分:`partial_sort(w.begin(),w.beging()+20,w.end(),func)`只对前20个元素排
</code></pre><h4 id="nth-element"><a href="#nth-element" class="headerlink" title="nth_element"></a>nth_element</h4><pre><code>只分界:`nth_element(w.begin(),w.beging()+20,w.end(),func)`
将最后的20个元素放前面,但它不会像前面那个函数,这个函数不会排序,只是单纯放前面
</code></pre><h4 id="partition"><a href="#partition" class="headerlink" title="partition"></a>partition</h4><pre><code>前面俩个只会比较元素,当判断元素属性时呢
`partition(w.begin(), w.end(), ifunc)`功能类似`partial_sort`但比较函数不同
</code></pre>]]></content>
<summary type="html">
<blockquote class="blockquote-center">以前有笔记,但忘了放哪了,再做一次吧</blockquote>
<p><img src="/picture/240.jpg" alt=""></p>
<ul>
<li>stable_sort</li>
</summary>
<category term="语言" scheme="https://xuecat.github.io/categories/%E8%AF%AD%E8%A8%80/"/>
<category term="c++" scheme="https://xuecat.github.io/tags/c/"/>
<category term="stl" scheme="https://xuecat.github.io/tags/stl/"/>
</entry>
<entry>
<title>mysql检索(239)</title>
<link href="https://xuecat.github.io/2018/07/13/239/"/>
<id>https://xuecat.github.io/2018/07/13/239/</id>
<published>2018-07-12T16:49:11.000Z</published>
<updated>2018-07-12T16:53:29.982Z</updated>
<content type="html"><![CDATA[<figure class="highlight stylus"><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">Å, å,这是丹麦的</div><div class="line">Ä ä,这是德语的</div><div class="line">A <span class="selector-tag">a</span> 这是英文得</div></pre></td></tr></table></figure>
<p>mysql里校对包含字符时有这些<code>like</code> <code>instr</code> <code>locate</code>,<br>但它们时建立在一个校对规则之上的,<br><code>_unicode_ci</code>不区分大小写<br><code>_general_ci</code>不区分大小写<br><code>*_cs</code>区分大小写<br><code>*_bin</code>用二进制存储</p>
<p>utf8_general_ci 校对速度快,但准确度稍差<br>utf8_unicode_ci 准确度高,但校对速度稍慢(所以最近那个sql问题我该改成这个)</p>
<p>utf8mb4字符集可以保存表情符号.</p>
<p>最后直接限定字符检索才成功,不明白为何改<code>_bin</code>也不成功。唉!<br><figure class="highlight sql"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">SELECT</span> * <span class="keyword">FROM</span> dbp_log_object <span class="keyword">as</span> a <span class="keyword">WHERE</span> <span class="keyword">locate</span>(<span class="string">'Ä'</span> <span class="keyword">collate</span> utf8_bin, a.objectname)><span class="number">0</span></div></pre></td></tr></table></figure></p>
]]></content>
<summary type="html">
<figure class="highlight stylus"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</d
</summary>
<category term="数据库" scheme="https://xuecat.github.io/categories/%E6%95%B0%E6%8D%AE%E5%BA%93/"/>
<category term="函数和结构" scheme="https://xuecat.github.io/tags/%E5%87%BD%E6%95%B0%E5%92%8C%E7%BB%93%E6%9E%84/"/>
</entry>
<entry>
<title>orleans(238)</title>
<link href="https://xuecat.github.io/2018/07/06/238/"/>
<id>https://xuecat.github.io/2018/07/06/238/</id>
<published>2018-07-06T13:00:29.000Z</published>
<updated>2018-07-10T16:00:54.412Z</updated>
<content type="html"><![CDATA[<p>这个亚马逊云素材同步代码是我至今最大坡度的代码<br>第一次有种想早点下班好回去恶补知识的感觉,可惜又不得不加班完成任务。</p>
<ol>
<li>silo 代表一个服务,可以是主节点也可以是副节点</li>
<li><p>grain 可以看作是一个单例进程,队列只有一个,会排队修改数据。相同类型的只要key不同,它们就互相独立</p>
</li>
<li><p>客户端一开始就会连接一个服务即silo.(GrainClient.Initialize)</p>
</li>
<li><p>StreamProvider订阅,无论是隐式还是显式,都要用this.stream.OnNextAsync(data)去分发<br>显式还是隐式都是一个grain,初始化注册订阅后才能使用</p>
</li>
</ol>
<ol>
<li><p>Orleans.Immutable 这个是由于和grain的方法调用传参是一次深拷贝<br>grain之间通信,silo之间通信也是深拷贝。<br>为了避免,所以用这个来控制,避免深拷贝。</p>
</li>
<li><p>Orleans永远不会在执行Task的中途创造另一个Task,所以要求程序代码在执行Task的中途,不要开辟多线程.不然会报错或者会破坏单线程机制.如果真的有需要创造额外的task.</p>
</li>
<li><p><code>StatelessWorker</code>的<code>grain</code>,状态无关类型;可以在集群的多个silo里,每一个silo都创造一个相同标识的Grain。 针对此类grain的请求,都只在第一个接受到请求的silo里执行。 Orleans会在所有此类grain忙的时候,自动增加一个</p>
</li>
</ol>
]]></content>
<summary type="html">
<p>这个亚马逊云素材同步代码是我至今最大坡度的代码<br>第一次有种想早点下班好回去恶补知识的感觉,可惜又不得不加班完成任务。</p>
<ol>
<li>silo 代表一个服务,可以是主节点也可以是副节点</li>
<li><p>grain 可以看作是一个单例进程,队列只有一个
</summary>
<category term="C#" scheme="https://xuecat.github.io/categories/C/"/>
<category term="分布式" scheme="https://xuecat.github.io/tags/%E5%88%86%E5%B8%83%E5%BC%8F/"/>
</entry>
</feed>