-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.html
1595 lines (703 loc) · 67.9 KB
/
index.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<!doctype html>
<html class="theme-next pisces use-motion">
<head>
<meta charset="UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1"/>
<meta http-equiv="Cache-Control" content="no-transform" />
<meta http-equiv="Cache-Control" content="no-siteapp" />
<link href="/vendors/fancybox/source/jquery.fancybox.css?v=2.1.5" rel="stylesheet" type="text/css" />
<link href="//fonts.googleapis.com/css?family=Lato:300,300italic,400,400italic,700,700italic&subset=latin,latin-ext" rel="stylesheet" type="text/css">
<link href="/vendors/font-awesome/css/font-awesome.min.css?v=4.4.0" rel="stylesheet" type="text/css" />
<link href="/css/main.css?v=5.0.1" rel="stylesheet" type="text/css" />
<meta name="keywords" content="Hexo, NexT" />
<link rel="shortcut icon" type="image/x-icon" href="/favicon.ico?v=5.0.1" />
<meta property="og:type" content="website">
<meta property="og:title" content="Kelly's blog">
<meta property="og:url" content="http://pangcy.github.io/index.html">
<meta property="og:site_name" content="Kelly's blog">
<meta name="twitter:card" content="summary">
<meta name="twitter:title" content="Kelly's blog">
<script type="text/javascript" id="hexo.configuration">
var NexT = window.NexT || {};
var CONFIG = {
scheme: 'Pisces',
sidebar: {"position":"left","display":"post"},
fancybox: true,
motion: true,
duoshuo: {
userId: 0,
author: '博主'
}
};
</script>
<link rel="canonical" href="http://pangcy.github.io/"/>
<title> Kelly's blog </title>
</head>
<body itemscope itemtype="http://schema.org/WebPage" lang="zh-Hans">
<div class="container one-collumn sidebar-position-left
page-home
">
<div class="headband"></div>
<header id="header" class="header" itemscope itemtype="http://schema.org/WPHeader">
<div class="header-inner"><div class="site-meta ">
<div class="custom-logo-site-title">
<a href="/" class="brand" rel="start">
<span class="logo-line-before"><i></i></span>
<span class="site-title">Kelly's blog</span>
<span class="logo-line-after"><i></i></span>
</a>
</div>
<p class="site-subtitle"></p>
</div>
<div class="site-nav-toggle">
<button>
<span class="btn-bar"></span>
<span class="btn-bar"></span>
<span class="btn-bar"></span>
</button>
</div>
<nav class="site-nav">
<ul id="menu" class="menu">
<li class="menu-item menu-item-home">
<a href="/home" rel="section">
<i class="menu-item-icon fa fa-fw fa-home"></i> <br />
首页
</a>
</li>
<li class="menu-item menu-item-categories">
<a href="/categories" rel="section">
<i class="menu-item-icon fa fa-fw fa-th"></i> <br />
分类
</a>
</li>
<li class="menu-item menu-item-archives">
<a href="/archives" rel="section">
<i class="menu-item-icon fa fa-fw fa-archive"></i> <br />
归档
</a>
</li>
<li class="menu-item menu-item-tags">
<a href="/tags" rel="section">
<i class="menu-item-icon fa fa-fw fa-tags"></i> <br />
标签
</a>
</li>
</ul>
</nav>
</div>
</header>
<main id="main" class="main">
<div class="main-inner">
<div class="content-wrap">
<div id="content" class="content">
<section id="posts" class="posts-expand">
<article class="post post-type-normal " itemscope itemtype="http://schema.org/Article">
<header class="post-header">
<h1 class="post-title" itemprop="name headline">
<a class="post-title-link" href="/2016/09/15/tcp/" itemprop="url">
tcp协议
</a>
</h1>
<div class="post-meta">
<span class="post-time">
<span class="post-meta-item-icon">
<i class="fa fa-calendar-o"></i>
</span>
<span class="post-meta-item-text">发表于</span>
<time itemprop="dateCreated" datetime="2016-09-15T16:50:00+08:00" content="2016-09-15">
2016-09-15
</time>
</span>
<span class="post-category" >
|
<span class="post-meta-item-icon">
<i class="fa fa-folder-o"></i>
</span>
<span class="post-meta-item-text">分类于</span>
<span itemprop="about" itemscope itemtype="https://schema.org/Thing">
<a href="/categories/技术/" itemprop="url" rel="index">
<span itemprop="name">技术</span>
</a>
</span>
</span>
</div>
</header>
<div class="post-body" itemprop="articleBody">
<p>TCP协议:传输控制协议(Transmission Control Protocol)是一种面向连接的、可靠的、基于字节流的传输层通信协议。TCP协议在网络OSI七层模型的第四次(传输层)。<br>TCP连接包括三个状态:连接创建、数据传送和连接终止。TCP用三次握手(three-way handshake)过程创建一个连接。四次挥手关闭一个连接。</p>
<h3 id="tcp头部格式"><a href="#tcp头部格式" class="headerlink" title="tcp头部格式"></a>tcp头部格式</h3><p><img src="/images/p1.png" alt="TCP header"></p>
<ul>
<li>source port 源端口</li>
<li>destination port 目标端口</li>
<li>Sequence Number是包的序号,用来解决网络包乱序。</li>
<li>Acknowledgement Number(ACK)确认号—— 用来解决确认是否收到。</li>
<li>window 滑动窗口</li>
<li>TCP flag 有SYN, FIN, ACK, PSH, RST, URG这几种状态,SYN表示建立连接,FIN表示关闭连接,ACK表示响应,PSH表示接收端不将该数据进行队列处理,RST表示连接重置,URG:紧急指针(urgent pointer)有效。</li>
</ul>
<h3 id="建立连接三次握手"><a href="#建立连接三次握手" class="headerlink" title="建立连接三次握手"></a>建立连接三次握手</h3><p><img src="/images/p2.png" alt="three way handshake"></p>
<ul>
<li>Client将标志位SYN置为1,随机产生一个值seq=x,并将该数据包发送给Server,Client进入SYN_SENT状态,等待Server确认。</li>
<li>Server收到数据包后由标志位SYN=1知道Client请求建立连接,Server将标志位SYN和ACK都置为1,ack=x+1,随机产生一个值seq=y,并将该数据包发送给Client以确认连接请求,Server进入SYN_RCVD状态。</li>
<li>Client收到确认后,检查ack是否为x+1,ACK是否为1,如果正确则将标志位ACK置为1,ack=y+1,并将该数据包发送给Server,Server检查ack是否为y+1,ACK是否为1,如果正确则连接建立成功,Client和Server进入ESTABLISHED状态,完成三次握手,随后Client与Server之间可以开始传输数据了。</li>
</ul>
<h3 id="终止连接四次挥手"><a href="#终止连接四次挥手" class="headerlink" title="终止连接四次挥手"></a>终止连接四次挥手</h3><p><img src="/images/p3.png" alt="three way handshake"></p>
<ul>
<li>Client将标志位FIN置为1,随机产生一个值seq=u,并将该数据包发送给Server,用来关闭Client到Server的数据传送,Client进入FIN_WAIT_1状态。</li>
<li>Server收到数据包后,设置标志位ACK=1,ack=u+1,随机产生一个值seq=v,并将该数据包发送给Client,Server进入CLOSE_WAIT状态。</li>
<li>Server将标志位FIN、ACK置为1,随机产生一个值seq=w,ack=u+1,并将该数据包发送给Client,用来关闭Server到Client的数据传送,Server进入LAST_ACK状态。</li>
<li>Client收到数据包后,Client进入TIME_WAIT状态,发送数据包ack=w+1,Server确认收到的ack正确后进入CLOSED状态,完成四次挥手。<br>如果Server没有收到ack,会要求Client重发一次,如果server收到后就会Closed。如果client等待2MSL(两倍报文最大生成时间)后还是没有收到server的要求重发请求,那个client认为server已经收到了ack报文,所以client就会关闭自己的连接。</li>
</ul>
<h3 id="TCP状态图"><a href="#TCP状态图" class="headerlink" title="TCP状态图"></a>TCP状态图</h3><p><img src="/images/p3.gif" alt="TCP status"></p>
<ul>
<li>CLOSED :初始状态,表示TCP连接是“关闭着的”或“未打开的”。</li>
<li>LISTEN :表示服务器端的某个SOCKET处于监听状态,可以接受客户端的连接。</li>
<li>SYN_SENT :表示建立连接是,客户端已经发生SYN报文。</li>
<li>SYN_RCVD :表示接收到了SYN报文。</li>
<li>ESTABLISHED :表示TCP连接已经成功建立。</li>
<li>FIN_WAIT_1 :想主动关闭连接,向对方发送了FIN报文,等待返回ACK报文。</li>
<li>FIN_WAIT_2 :主动关闭连接的一方收到对方返回的ACK包后,等待对方发送FIN包。</li>
<li>TIME_WAIT :表示收到了对方的FIN报文,并发送出了ACK报文。 TIME_WAIT状态下的TCP连接会等待2*MSL,然后即可回到CLOSED 可用状态了。如果FIN_WAIT_1状态下,收到了对方同时带FIN标志和ACK标志的报文时,可以直接进入到TIME_WAIT状态,而无须经过FIN_WAIT_2状态。</li>
<li>CLOSING :这种状态在实际情况中应该很少见,正常情况下,当一方发送FIN报文后,按理来说是应该先收到(或同时收到)对方的ACK报文,再收到对方的FIN报文。但是CLOSING 状态表示一方发送FIN报文后,并没有收到对方的ACK报文,反而却也收到了对方的FIN报文。当双方几乎在同时close的话,就出现了双方同时发送FIN报文的情况,这是就会出现CLOSING 状态,表示双方都正在关闭SOCKET连接。</li>
<li>CLOSE_WAIT :第四次挥手发送ACK报文后会变为CLOSE_WAIT,如果Server没有收到ack,会要求Client重发一次,如果server收到后就会Closed。如果client等待2MSL(两倍报文最大生成时间)后还是没有收到server的要求重发请求,那个client认为server已经收到了ack报文,所以client就会关闭自己的连接。</li>
<li>LAST_ACK :当被动关闭的一方在发送FIN报文后,等待对方的ACK报文的时候,就处于LAST_ACK 状态。当收到对方的ACK报文后,也就可以进入到CLOSED 可用状态了。</li>
</ul>
</div>
<div>
</div>
<div>
</div>
<footer class="post-footer">
<div class="post-eof"></div>
</footer>
</article>
<article class="post post-type-normal " itemscope itemtype="http://schema.org/Article">
<header class="post-header">
<h1 class="post-title" itemprop="name headline">
<a class="post-title-link" href="/2016/09/14/fullcg/" itemprop="url">
触发full gc的几种情况
</a>
</h1>
<div class="post-meta">
<span class="post-time">
<span class="post-meta-item-icon">
<i class="fa fa-calendar-o"></i>
</span>
<span class="post-meta-item-text">发表于</span>
<time itemprop="dateCreated" datetime="2016-09-14T15:55:00+08:00" content="2016-09-14">
2016-09-14
</time>
</span>
<span class="post-category" >
|
<span class="post-meta-item-icon">
<i class="fa fa-folder-o"></i>
</span>
<span class="post-meta-item-text">分类于</span>
<span itemprop="about" itemscope itemtype="https://schema.org/Thing">
<a href="/categories/技术/" itemprop="url" rel="index">
<span itemprop="name">技术</span>
</a>
</span>
</span>
</div>
</header>
<div class="post-body" itemprop="articleBody">
<h3 id="老年代空间不足"><a href="#老年代空间不足" class="headerlink" title="老年代空间不足"></a>老年代空间不足</h3><p>当新生代对象经过若干次(默认15次,可以通过XX:MaxTenuringThreshold参数来配置)后依旧没有被回收,此对象会进入老年代,或者new一个大对象,或者是一个很大的数组,新生代没有足够的空间,这时对象也会进入老年代,在这些对象进入老年代的时候,假设老年代没有足够的连续的空间,那么就会触发full GC 。如果FULL GC 之后空间还是不足,那么就会报错java.lang.OutOfMemoryError: Java heap space。<br>为了防止老年代内存碎片问题,CMS垃圾收集器提供了一个可配置的参数,-XX:+UseCMSCompactAtFullCollection,用于在Full GC之后进行碎片整理,因为内存整理的过程无法并发的,所以停顿时间就会变长。XX:CMSFullGCsBeforeCompaction,这个参数用于设置在执行多少次不压缩的Full GC后,跟着来一次带压缩的full gc。</p>
<h3 id="perm-gen空间不足"><a href="#perm-gen空间不足" class="headerlink" title="perm gen空间不足"></a>perm gen空间不足</h3><p>perm gen通常称为方法区,主要存放的是class的信息,常量池,静态变量。如果项目中的class太多,或者反射生成太多的class话,就会触发full gc,如果full gc之后还是没有被回收,那么就会报错,java.lang.OutOfMemoryError: PermGen space ,解决这个错误可以调大方法区的大小,PermSize, MaxPermSize<br>如果项目中老年代配置的是CMS收集器,那么该收集器会在回收老年代的时候去回收perm gen。</p>
<h3 id="minor-GC之后进入老年代的平均大小大于老年剩余空间"><a href="#minor-GC之后进入老年代的平均大小大于老年剩余空间" class="headerlink" title="minor GC之后进入老年代的平均大小大于老年剩余空间"></a>minor GC之后进入老年代的平均大小大于老年剩余空间</h3><p>jvm会在minor GC时判断,如果之前几次minor GC 进入老年代的平均大小,如果平均值大于老年代剩余的空间,那么会直接触发full gc。如果新生代用的Parallel Scavenge收集器,它会在计算出平均值大于老年代后,去回收老年代。</p>
</div>
<div>
</div>
<div>
</div>
<footer class="post-footer">
<div class="post-eof"></div>
</footer>
</article>
<article class="post post-type-normal " itemscope itemtype="http://schema.org/Article">
<header class="post-header">
<h1 class="post-title" itemprop="name headline">
<a class="post-title-link" href="/2016/09/12/proxy/" itemprop="url">
代理模式
</a>
</h1>
<div class="post-meta">
<span class="post-time">
<span class="post-meta-item-icon">
<i class="fa fa-calendar-o"></i>
</span>
<span class="post-meta-item-text">发表于</span>
<time itemprop="dateCreated" datetime="2016-09-12T21:02:00+08:00" content="2016-09-12">
2016-09-12
</time>
</span>
<span class="post-category" >
|
<span class="post-meta-item-icon">
<i class="fa fa-folder-o"></i>
</span>
<span class="post-meta-item-text">分类于</span>
<span itemprop="about" itemscope itemtype="https://schema.org/Thing">
<a href="/categories/技术/" itemprop="url" rel="index">
<span itemprop="name">技术</span>
</a>
</span>
</span>
</div>
</header>
<div class="post-body" itemprop="articleBody">
<p>代理模式通常分为静态代理和动态代理,动态代理里面又有jdk的代理和cglib的代理。<br>代理类和委托类需要有共同的接口,代理类主要负责在执行委托类方法前后做一些处理。代理类不要实现业务逻辑,而是调用委托类的相关方法。业务类只需要关注业务逻辑本身,保证了业务类的重用性。如果接口增加一个方法,除了所有实现类需要实现这个方法外,所有代理类也需要实现此方法。</p>
<h3 id="静态代理"><a href="#静态代理" class="headerlink" title="静态代理"></a>静态代理</h3><p>静态代理由程序员创建代理类或特定工具自动生成源代码再对其编译。在程序运行前代理类的.class文件就已经存在了。</p>
<p>首先定义一个接口<br><figure class="highlight java"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">interface</span> <span class="title">Subject</span> </span>{</div><div class="line"></div><div class="line"> <span class="function"><span class="keyword">void</span> <span class="title">doSomething</span><span class="params">()</span></span>;</div><div class="line"></div><div class="line">}</div></pre></td></tr></table></figure></p>
<p>委托类实现接口方法<br><figure class="highlight java"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">RealSubject</span> <span class="keyword">implements</span> <span class="title">Subject</span> </span>{</div><div class="line"></div><div class="line"> <span class="meta">@Override</span></div><div class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">doSomething</span><span class="params">()</span> </span>{</div><div class="line"></div><div class="line"> System.out.println(<span class="string">"dosomething"</span>);</div><div class="line"></div><div class="line"> }</div><div class="line"></div><div class="line">}</div></pre></td></tr></table></figure></p>
<p>代理类也实现该接口<br><figure class="highlight java"><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="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">ProxySubject</span> <span class="keyword">implements</span> <span class="title">Subject</span> </span>{</div><div class="line"></div><div class="line"> <span class="keyword">private</span> Subject rs;</div><div class="line"></div><div class="line"> <span class="function"><span class="keyword">public</span> <span class="title">ProxySubject</span><span class="params">(Subject rs)</span></span>{</div><div class="line"> <span class="keyword">this</span>.rs = rs;</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="meta">@Override</span></div><div class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">doSomething</span><span class="params">()</span> </span>{</div><div class="line"> System.out.println(<span class="string">"before dosomething...."</span>);</div><div class="line"> rs.doSomething();</div><div class="line"> System.out.println(<span class="string">"after dosomething..."</span>);</div><div class="line"></div><div class="line"> }</div><div class="line">}</div></pre></td></tr></table></figure></p>
<p>客户端调用<br><figure class="highlight java"><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="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">TestProxy</span> </span>{</div><div class="line"></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">(String[] args)</span> </span>{</div><div class="line"> Subject s= <span class="keyword">new</span> RealSubject();</div><div class="line"> ProxySubject ps = <span class="keyword">new</span> ProxySubject(s);</div><div class="line"> ps.doSomething();</div><div class="line"> }</div></pre></td></tr></table></figure></p>
<h3 id="动态代理"><a href="#动态代理" class="headerlink" title="动态代理"></a>动态代理</h3><p>动态代理类的源码是在程序运行期间由JVM根据反射等机制动态的生成,所以不存在代理类的.class文件。代理类和委托类的关系是在程序运行时确定的。</p>
<ul>
<li><h4 id="jdk动态代理"><a href="#jdk动态代理" class="headerlink" title="jdk动态代理"></a>jdk动态代理</h4><p>只能对实现了接口的类生产代理,不能针对类。</p>
<figure class="highlight java"><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></pre></td><td class="code"><pre><div class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">JdkDynamicProxy</span> <span class="keyword">implements</span> <span class="title">InvocationHandler</span> </span>{</div><div class="line"></div><div class="line"> <span class="keyword">private</span> Object target;</div><div class="line"></div><div class="line"> <span class="function"><span class="keyword">public</span> Object <span class="title">getProxy</span><span class="params">(Object target)</span> </span>{</div><div class="line"> <span class="keyword">this</span>.target = target;</div><div class="line"> <span class="keyword">return</span> Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), <span class="keyword">this</span>);</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="meta">@Override</span></div><div class="line"> <span class="function"><span class="keyword">public</span> Object <span class="title">invoke</span><span class="params">(Object proxy, Method method, Object[] args)</span> <span class="keyword">throws</span> Throwable </span>{</div><div class="line"> System.out.println(<span class="string">"before do..."</span>);</div><div class="line"> Object object = method.invoke(target, args);</div><div class="line"> System.out.println(<span class="string">"after do..."</span>);</div><div class="line"> <span class="keyword">return</span> object;</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="comment">//测试。。</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">(String[] args)</span> </span>{</div><div class="line"> JdkDynamicProxy jp = <span class="keyword">new</span> JdkDynamicProxy();</div><div class="line"> Subject obj = (Subject) jp.getProxy(<span class="keyword">new</span> RealSubject());</div><div class="line"> obj.doSomething();</div><div class="line"> }</div><div class="line"></div><div class="line">}</div></pre></td></tr></table></figure>
</li>
<li><h4 id="cglib动态代理"><a href="#cglib动态代理" class="headerlink" title="cglib动态代理"></a>cglib动态代理</h4><p>cglib能够代理类和接口,它的原理是针对委托类,通过继承生成一个子类,再覆盖方法进行处理。所以不能代理final修饰的类。</p>
<figure class="highlight java"><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></pre></td><td class="code"><pre><div class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">CglibProxy</span> <span class="keyword">implements</span> <span class="title">MethodInterceptor</span> </span>{</div><div class="line"></div><div class="line"> <span class="keyword">private</span> Object target;</div><div class="line"></div><div class="line"> <span class="function"><span class="keyword">public</span> Object <span class="title">getCglibProxy</span><span class="params">(Object target)</span> </span>{</div><div class="line"> <span class="keyword">this</span>.target = target;</div><div class="line"> Enhancer eh = <span class="keyword">new</span> Enhancer();</div><div class="line"> eh.setSuperclass(target.getClass());</div><div class="line"> eh.setCallback(<span class="keyword">this</span>);</div><div class="line"> <span class="keyword">return</span> eh.create();</div><div class="line"> }</div><div class="line"></div><div class="line"></div><div class="line"> <span class="meta">@Override</span></div><div class="line"> <span class="function"><span class="keyword">public</span> Object <span class="title">intercept</span><span class="params">(Object object, Method method, Object[] args, MethodProxy proxy)</span> <span class="keyword">throws</span> Throwable </span>{</div><div class="line"> System.out.println(<span class="string">"begin...."</span>);</div><div class="line"> Object result = proxy.invoke(target,args);</div><div class="line"> System.out.println(<span class="string">"after...."</span>);</div><div class="line"> <span class="keyword">return</span> result;</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="comment">//测试。。</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">(String[] args)</span> </span>{</div><div class="line"> CglibProxy cp = <span class="keyword">new</span> CglibProxy();</div><div class="line"> Subject obj = (Subject) cp.getCglibProxy(<span class="keyword">new</span> RealSubject());</div><div class="line"> obj.doSomething();</div><div class="line"> }</div><div class="line">}</div></pre></td></tr></table></figure>
</li>
</ul>
</div>
<div>
</div>
<div>
</div>
<footer class="post-footer">
<div class="post-eof"></div>
</footer>
</article>
<article class="post post-type-normal " itemscope itemtype="http://schema.org/Article">
<header class="post-header">
<h1 class="post-title" itemprop="name headline">
<a class="post-title-link" href="/2016/09/11/redis/" itemprop="url">
redis笔记
</a>
</h1>
<div class="post-meta">
<span class="post-time">
<span class="post-meta-item-icon">
<i class="fa fa-calendar-o"></i>
</span>
<span class="post-meta-item-text">发表于</span>
<time itemprop="dateCreated" datetime="2016-09-11T21:02:00+08:00" content="2016-09-11">
2016-09-11
</time>
</span>
<span class="post-category" >
|
<span class="post-meta-item-icon">
<i class="fa fa-folder-o"></i>
</span>
<span class="post-meta-item-text">分类于</span>
<span itemprop="about" itemscope itemtype="https://schema.org/Thing">
<a href="/categories/技术/" itemprop="url" rel="index">
<span itemprop="name">技术</span>
</a>
</span>
</span>
</div>
</header>
<div class="post-body" itemprop="articleBody">
<p>Redis是一个开源(BSD许可),内存存储的数据结构服务器,可用作数据库,高速缓存和消息队列代理。它支持字符串、哈希表、列表、集合、有序集合,位图,hyperloglogs等数据类型。内置复制、Lua脚本、LRU收回、事务以及不同级别磁盘持久化功能,同时通过Redis Sentinel提供高可用,通过Redis Cluster提供自动分区。</p>
<h3 id="redis与Memcached的区别:"><a href="#redis与Memcached的区别:" class="headerlink" title="redis与Memcached的区别:"></a>redis与Memcached的区别:</h3><ul>
<li>redis不仅仅支持k-v类型的数据,同时还提供list,set,zset,hash等数据结构的存储。</li>
<li>redis支持数据的备份,即master-slave模式的数据备份。</li>
<li>redis支持数据的持久化,可以将内存中的数据保持在磁盘中,重启的时候可以再次加载进行使用。</li>
<li>redis是单线程的,而memcached是多线程的。100k以上的数据中,Memcached性能要高于Redis。</li>
</ul>
<p>redis相比Memcached,拥有更多的数据结构和并支持更丰富的数据操作,通常在Memcached里, 你需要将数据拿到客户端来进行类似的修改再set回去。这大大增加了网络IO的次数和数据体积。在redis中,这些复杂的操作通常和一般的GET-SET一样高效。所以,如果你需要缓存能够支持更复杂的结构和操作,那么redis会是不错的选择。</p>
<h3 id="redis5种数据类型简介"><a href="#redis5种数据类型简介" class="headerlink" title="redis5种数据类型简介"></a>redis5种数据类型简介</h3><ul>
<li>String<br>常用的操作就是get,set ,mget,mset,incr,decr。还可以对字符串进行一些操作,例如获取其长度,append内容,获取中间的一段值等等。是最常用的字符类型,用来做K-V存储,也可以进行计数操作。</li>
<li>List<br>常用命令lpush,rpush,lpop,rpop,lrange,BLPOP,BRPOP,BRPOPLPUSH,LTRIM。它的内部是一个双向链表<br>可以用来实现消息队列、或者粉丝列表等场景。</li>
<li>Set<br>常用命令sadd,srem,spop,sdiff,smembers,sunion。它内部就是一个value为null的hashmap。<br>set适合需要存储一个列表但是同时又不能重复的情况,还可以用set快速判断某个值是否在其中,还可以求一些交集,并集,差集等。例如在两个好友的set中,求出共同好友。</li>
<li>Sorted Set<br>常用命令zadd,zrange,zrem,zcard,他是一个有序的set。内部使用了hashmap和跳跃表。<br>通常用来做排行榜,根据一个值进行排序的列表。</li>
<li>hash<br>常用命令hget,hset,hgetal,hmget,hmset。可以把一个对象的每个属性和值存在hash中,每次可以只修改一个字段。不用像memcached那样必须把整个对象拿出来,修改之后再set进去,需要序列号和反序列化。</li>
</ul>
<h3 id="redis高级功能"><a href="#redis高级功能" class="headerlink" title="redis高级功能"></a>redis高级功能</h3><ul>
<li>Pub/Sub(发布订阅)<br>可以根据一个key进行消息发布和订阅。当一个key值上进行了消息发布后,所有订阅它的客户端都会收到相应的消息。</li>
<li>Transaction<br>并不是严格的ACID的事务。redis还提供了一个Watch功能,你可以对一个key进行Watch,然后再执行Transactions,在这过程中,如果这个Watched的值进行了修改,那么这个Transactions会发现并拒绝执行。</li>
</ul>
</div>
<div>
</div>
<div>
</div>
<footer class="post-footer">
<div class="post-eof"></div>
</footer>
</article>
<article class="post post-type-normal " itemscope itemtype="http://schema.org/Article">
<header class="post-header">
<h1 class="post-title" itemprop="name headline">
<a class="post-title-link" href="/2016/09/09/mysql-index/" itemprop="url">
mysql索引学习笔记
</a>
</h1>
<div class="post-meta">
<span class="post-time">
<span class="post-meta-item-icon">
<i class="fa fa-calendar-o"></i>
</span>
<span class="post-meta-item-text">发表于</span>
<time itemprop="dateCreated" datetime="2016-09-09T00:00:00+08:00" content="2016-09-09">
2016-09-09
</time>
</span>
<span class="post-category" >
|
<span class="post-meta-item-icon">
<i class="fa fa-folder-o"></i>
</span>
<span class="post-meta-item-text">分类于</span>
<span itemprop="about" itemscope itemtype="https://schema.org/Thing">
<a href="/categories/技术/" itemprop="url" rel="index">
<span itemprop="name">技术</span>
</a>
</span>
</span>
</div>
</header>
<div class="post-body" itemprop="articleBody">
<p>MySQL官方对索引的定义为:索引(Index)是帮助MySQL高效获取数据的数据结构。简单通俗的比喻一下,索引就好比一本书的目录,能够快速的定位到你想查找的位置上去。</p>
<h3 id="索引的数据结构"><a href="#索引的数据结构" class="headerlink" title="索引的数据结构"></a>索引的数据结构</h3><p>mysql的索引采用了一种叫做B+TREE的数据结构。它是一个N叉数树,一种多路搜索树。B+TREE是B-TREE的一个变种。B+TREE的具体内同就不介绍了。</p>
<p>索引又分为聚簇索引和非聚簇索引(对InnoDB而言)</p>
<ul>
<li>聚簇索引:在该索引实现方式中B+Tree的叶子节点上的data就是数据本身,每个表只能拥有有一个聚簇索引。<br><img src="/images/pic2.jpeg" alt="聚簇索引"></li>
<li>非聚簇索引(二级索引):非聚簇索引就是指B+Tree的叶子节点上存储的是相应记录的主键值。<br><img src="/images/pic3.jpeg" alt="聚簇索引"></li>
</ul>
<h3 id="索引的使用"><a href="#索引的使用" class="headerlink" title="索引的使用"></a>索引的使用</h3><p>mysql 的索引又分为单列索引和复合索引。<br>复合索引建立时应该遵循<code>最左前缀原则</code>。<br>建立一张employee表,字段如下所示<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><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">CREATE</span> <span class="keyword">TABLE</span> <span class="string">`employees`</span> (</div><div class="line"> <span class="string">`emp_no`</span> <span class="built_in">int</span>(<span class="number">11</span>) <span class="keyword">NOT</span> <span class="literal">NULL</span>,</div><div class="line"> <span class="string">`birth_date`</span> <span class="built_in">date</span> <span class="keyword">NOT</span> <span class="literal">NULL</span>,</div><div class="line"> <span class="string">`first_name`</span> <span class="built_in">varchar</span>(<span class="number">14</span>) <span class="keyword">NOT</span> <span class="literal">NULL</span>,</div><div class="line"> <span class="string">`last_name`</span> <span class="built_in">varchar</span>(<span class="number">16</span>) <span class="keyword">NOT</span> <span class="literal">NULL</span>,</div><div class="line"> <span class="string">`gender`</span> enum(<span class="string">'M'</span>,<span class="string">'F'</span>) <span class="keyword">NOT</span> <span class="literal">NULL</span>,</div><div class="line"> <span class="string">`hire_date`</span> <span class="built_in">date</span> <span class="keyword">NOT</span> <span class="literal">NULL</span>,</div><div class="line"> PRIMARY <span class="keyword">KEY</span> (<span class="string">`emp_no`</span>),</div><div class="line"> <span class="keyword">KEY</span> <span class="string">`firstname_lastname_birth_date`</span> (<span class="string">`first_name`</span>,<span class="string">`last_name`</span>,<span class="string">`birth_date`</span>)</div><div class="line">) <span class="keyword">ENGINE</span>=<span class="keyword">InnoDB</span> <span class="keyword">DEFAULT</span> <span class="keyword">CHARSET</span>=latin1;</div></pre></td></tr></table></figure></p>
<p>并且为表建立一个主键emp_no 和一个复合索引,字段有first_name,last_name,birth_date。</p>
<figure class="highlight sql"><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="keyword">select</span> * <span class="keyword">from</span> employees <span class="keyword">where</span> first_name=<span class="string">'Georgi'</span> <span class="keyword">and</span> last_name=<span class="string">'Facello'</span></div><div class="line"><span class="keyword">and</span> birth_date=<span class="string">'1953-09-02'</span>;</div></pre></td></tr></table></figure>
<p>这条sql语句用到了上面复合索引,并且这个三个字段位置可以任意,都会用到这个索引。其实按照最左匹配原则where条件顺序应该是要按照索引里面字段的顺序,现在可以顺序随便,因为mysql内部做了优化。</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> employees <span class="keyword">where</span> last_name=<span class="string">'Facello'</span><span class="keyword">and</span> birth_date=<span class="string">'1953-09-02'</span>;</div></pre></td></tr></table></figure>
<p>上面这条sql没有用到索引,因为复合索引的第一个字段first_name没有出现在where条件中,不符合最左前缀原则。</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> employees <span class="keyword">where</span> last_name=<span class="string">'Facello'</span><span class="keyword">and</span> first_name=<span class="string">'Georgi'</span>;</div></pre></td></tr></table></figure>
<p>虽然where条件只有两个,但是first_name,last_name这两个字段是该索引的前面两个字段,所有符合最左前缀原则,用到了两个字段的索引。<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> employees <span class="keyword">where</span> birth_date=<span class="string">'1953-09-02'</span> <span class="keyword">and</span> first_name=<span class="string">'Georgi'</span>;</div></pre></td></tr></table></figure></p>
<p>虽然这条语句也用到了索引,但是只用到first_name这个字段,因为第二个字段没有在where条件中,mysql按照顺序,发现没有第二个字段,索引只能在第一个字段中过滤的数据里面扫描birth_date这个字段的数据。</p>
<p>从上面的例子可以看出如果要走索引(first_name,last_name,birth_date),那么where条件必须满足下面三种情况中的一个,字段顺序无所谓。</p>
<ul>
<li>first_name,last_name,birth_date</li>
<li>first_name,last_name</li>
<li>first_name<br>通过上面的例子应该理解了mysql的最左前缀原则了。</li>
</ul>
<p><strong>范围查询(>/</like/between)索引情况</strong><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><div class="line">4</div><div class="line">5</div><div class="line">6</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">explain</span> <span class="keyword">select</span> * <span class="keyword">from</span> employees <span class="keyword">where</span> first_name <span class="keyword">like</span><span class="string">'Georg%'</span> <span class="keyword">and</span> last_name=<span class="string">'Facello'</span>;</div><div class="line">+<span class="comment">----+-------------+-----------+------------+-------+-------------------------------+-------------------------------+---------+------+------+----------+-----------------------+</span></div><div class="line">| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |</div><div class="line">+<span class="comment">----+-------------+-----------+------------+-------+-------------------------------+-------------------------------+---------+------+------+----------+-----------------------+</span></div><div class="line">| 1 | SIMPLE | employees | NULL | range | firstname_lastname_birth_date | firstname_lastname_birth_date | 34 | NULL | 975 | 10.00 | Using index condition |</div><div class="line">+<span class="comment">----+-------------+-----------+------------+-------+-------------------------------+-------------------------------+---------+------+------+----------+-----------------------+</span></div></pre></td></tr></table></figure></p>
<p>在复合索引中上面sql虽然用到了索引,但是last_name这个字段没有根据索引来查询,如果通配符%不出现在开头,则可以用到索引,但是后面的条件是不会走索引的。</p>
<p>在两个独立的索引中,下面两条sql语句如下<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><div class="line">4</div><div class="line">5</div><div class="line">6</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">explain</span> <span class="keyword">select</span> * <span class="keyword">from</span> employees <span class="keyword">where</span> emp_no><span class="number">499991</span> <span class="keyword">and</span> first_name =<span class="string">'Georgi'</span>;</div><div class="line">+<span class="comment">----+-------------+-----------+------------+-------+---------------------------------------+---------+---------+------+------+----------+-------------+</span></div><div class="line">| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |</div><div class="line">+<span class="comment">----+-------------+-----------+------------+-------+---------------------------------------+---------+---------+------+------+----------+-------------+</span></div><div class="line">| 1 | SIMPLE | employees | NULL | range | PRIMARY,firstname_lastname_birth_date | PRIMARY | 4 | NULL | 8 | 0.62 | Using where |</div><div class="line">+<span class="comment">----+-------------+-----------+------------+-------+---------------------------------------+---------+---------+------+------+----------+-------------+</span></div></pre></td></tr></table></figure></p>
<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><div class="line">4</div><div class="line">5</div><div class="line">6</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">explain</span> <span class="keyword">select</span> * <span class="keyword">from</span> employees <span class="keyword">where</span> emp_no><span class="number">199991</span> <span class="keyword">and</span> first_name =<span class="string">'Georgi'</span>;</div><div class="line">+<span class="comment">----+-------------+-----------+------------+------+---------------------------------------+-------------------------------+---------+-------+------+----------+-----------------------+</span></div><div class="line">| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |</div><div class="line">+<span class="comment">----+-------------+-----------+------------+------+---------------------------------------+-------------------------------+---------+-------+------+----------+-----------------------+</span></div><div class="line">| 1 | SIMPLE | employees | NULL | ref | PRIMARY,firstname_lastname_birth_date | firstname_lastname_birth_date | 16 | const | 253 | 50.00 | Using index condition |</div><div class="line">+<span class="comment">----+-------------+-----------+------------+------+---------------------------------------+-------------------------------+---------+-------+------+----------+-----------------------+</span></div></pre></td></tr></table></figure>
<p>条件列一样,只是条件的范围不一样,走的索引就不同。所以mysql会根据索引的效率进行优化,选择最快的索引来执行。索引不存在说范围查询后面的条件不会走索引这种说法。</p>
</div>
<div>
</div>
<div>
</div>
<footer class="post-footer">
<div class="post-eof"></div>
</footer>
</article>
<article class="post post-type-normal " itemscope itemtype="http://schema.org/Article">
<header class="post-header">
<h1 class="post-title" itemprop="name headline">
<a class="post-title-link" href="/2016/08/22/talk-about-hashMap/" itemprop="url">
说一说Java的HashMap
</a>
</h1>
<div class="post-meta">
<span class="post-time">
<span class="post-meta-item-icon">
<i class="fa fa-calendar-o"></i>
</span>
<span class="post-meta-item-text">发表于</span>
<time itemprop="dateCreated" datetime="2016-08-22T00:00:00+08:00" content="2016-08-22">
2016-08-22
</time>
</span>
<span class="post-category" >
|
<span class="post-meta-item-icon">
<i class="fa fa-folder-o"></i>
</span>
<span class="post-meta-item-text">分类于</span>
<span itemprop="about" itemscope itemtype="https://schema.org/Thing">
<a href="/categories/技术/" itemprop="url" rel="index">
<span itemprop="name">技术</span>
</a>
</span>
</span>
</div>
</header>
<div class="post-body" itemprop="articleBody">
</div>
<div>
</div>
<div>
</div>
<footer class="post-footer">
<div class="post-eof"></div>
</footer>
</article>