forked from vzardlloo/vzardlloo.github.io
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.html
1305 lines (722 loc) · 53.5 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 lang="en">
<head>
<meta charset="utf-8" />
<meta name="description" content="认真生活,快乐工作" />
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1" />
<title>
vzard's blog
</title>
<meta name="generator" content="hexo-theme-yilia-plus">
<link rel="shortcut icon" href="/favicon.ico" />
<link rel="stylesheet" href="/css/main.css">
<script src="/js/pace.min.js"></script>
<script>
var _hmt = _hmt || [];
(function() {
var hm = document.createElement("script");
hm.src = "https://hm.baidu.com/hm.js?e6f2823e25c76ed531befabd4471f6fb";
var s = document.getElementsByTagName("script")[0];
s.parentNode.insertBefore(hm, s);
})();
</script>
<link rel="alternate" href="/atom.xml" title="vzard's blog" type="application/atom+xml">
</head>
</html>
<body>
<div id="app">
<main class="content">
<section class="cover">
<a class="forkMe" href="https://github.com/vzardlloo"
target="_blank"><img width="149" height="149" src="/images/forkme.png"
class="attachment-full size-full" alt="Fork me on GitHub" data-recalc-dims="1"></a>
<div class="cover-frame">
<div class="bg-box">
<img src="/images/cover6.jpg" alt="image frame" />
</div>
<div class="cover-inner text-center text-white">
<h1><a href="/">vzard's blog</a></h1>
<div id="subtitle-box">
<span id="subtitle"></span>
</div>
<div>
</div>
</div>
</div>
<div class="cover-learn-more">
<a href="javascript:void(0)" class="anchor"><i class="ri-arrow-down-line"></i></a>
</div>
</section>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/lib/typed.min.js"></script>
<div id="main">
<section class="outer">
<article class="articles">
<article id="post-XPath线索追踪技术" class="article article-type-post" itemscope
itemprop="blogPost" data-scroll-reveal>
<div class="article-inner">
<header class="article-header">
<h2 itemprop="name">
<a class="article-title" href="/2020/03/05/XPath%E7%BA%BF%E7%B4%A2%E8%BF%BD%E8%B8%AA%E6%8A%80%E6%9C%AF/"
>XPath线索追踪技术</a
>
</h2>
</header>
<div class="article-meta">
<a href="/2020/03/05/XPath%E7%BA%BF%E7%B4%A2%E8%BF%BD%E8%B8%AA%E6%8A%80%E6%9C%AF/" class="article-date">
<time datetime="2020-03-05T14:33:23.000Z" itemprop="datePublished">2020-03-05</time>
</a>
<div class="article-category">
<a class="article-category-link" href="/categories/%E8%AE%A1%E7%AE%97%E5%B9%BF%E5%91%8A/">计算广告</a>
</div>
</div>
<div class="article-entry" itemprop="articleBody">
<h3><span id="什么是xpath">什么是XPath</span></h3><p> XPath全称XML路径语言(XML Path Language),它是一种用来确定XML文档中某部分位置的计算机语言。XPath基于XML的树状结构,提供在数据结构树中找寻节点的能力。举例来说:<br> 我们有网页A,他的页面代码为:<br><img src="https://tva1.sinaimg.cn/large/00831rSTly1gclqy3wbaej30wc0lsabl.jpg" alt="code.jpg"></p>
<p>它对应的domtree为<br><img src="https://tva1.sinaimg.cn/large/00831rSTly1gclqxj0iixj30t60gi0tf.jpg" alt="domtree.jpg"><br> 每个网页的页面结构都可以解析为一颗domtree,每个页面元素都是这棵树的一个节点,那如何唯一的表示每一个节点呢?很自然的由于每个节点到根节点的路径都是不同的,所以可以用节点到根路径的路径来表示,比如meta元素可以用/html/head/meta来表示,这样的话有个问题,比如最右和皮皮搞笑这个两个元素都可以表示成/html/head/h1,这样岂不是乱了套,所以对于这样的情况可以用/html/head/h1[0],/html/head/h1[1]来表示,至于谁是h1[0]谁是h1[1]取决于具体实现。这样用路径表达式唯一标识一个页面元素的方法就叫做XPath。<br> <strong>总结:XPath是我们用来唯一标识页面元素的一种方法和工具。</strong></p>
<h3><span id="为什么要做xpath线索追踪">为什么要做XPath线索追踪</span></h3><p> 为什么要做XPath线索追踪?这其实可以分解为两个问题:1、为什么要做线索追踪 2、为什么要选择XPath做线索追踪。<br> 首先是问题一,为什么要做线索追踪?这个答案很简单,因为我们要做oCPX,需要根据转化情况(像提交的表单、咨询工具等),系统自动优化转化效果。它的第一步就是转化数据收集,目前我们只对于App下载类有转化数据的收集,而对于网页线索类特别是对第三方网页的线索收集是一片空白,如果无法收集到这些信息,那么对于这些类型广告的oCPX将无从做起,所以我们有必要对于这些类型的广告做线索追踪。这是做XPath线索追踪的必要性。<br> 其次是问题二,为什么选择选择XPath做线索追踪。对于线索追踪目前主要有:js布码、api回传、XPath,这三种做法。其中js布码和api回传都需要平台方面和广告主侧投入较大的技术支持,而XPath只需要平台侧提供对应功能,投放时广告主可以自主选择线索绑定,不需要投入技术支持,较为方便和易于推广。另外因为业内有已经有应用的比较好的先例,可以省去一些调研选型的时间,还有完整的产品形态可以参考,对于最终可以达到的效果也有个预期。这是做XPath线索追踪的充分性。<br> <strong>总结:通过问题一,二的讨论,我们知道我们有充分且必要的理由做XPath线索追踪这件事。</strong></p>
<h3><span id="xpath线索追踪技术实现">XPath线索追踪技术实现</span></h3><ol>
<li><p><strong>服务端domtree和截图技术选型</strong><br>通过调研可供我们选择的有三种方案:1、基于PhantomJS的方案,2、基于ChromeDP的方案,3、基于Puppeteer的方案。<br>经过尝试调研后总结他们的优缺点对比如下:</p>
<table>
<thead>
<tr>
<th align="center"></th>
<th align="center">优点</th>
<th align="center">缺点</th>
</tr>
</thead>
<tbody><tr>
<td align="center">phantomjs</td>
<td align="center">有过使用经验,学习成本低,二进制文件部署简单</td>
<td align="center">已经停止维护,web引擎实现不一定和现在主流一致</td>
</tr>
<tr>
<td align="center">chromedp</td>
<td align="center">go语言实现,底层使用Chrome(我们服务端主要语言是go)</td>
<td align="center">性能不稳定,社区不活跃,资料不多</td>
</tr>
<tr>
<td align="center">puppeteer</td>
<td align="center">Chrome官方推荐,社区活跃</td>
<td align="center">需要在服务器搭建对应环境,同时有一些学习成本</td>
</tr>
</tbody></table>
<p><strong>经过实际的尝试我们最终选择使用Puppeter作为服务端domtree解析和服务端截图的工具。</strong></p>
</li>
<li><p><strong>页面domtree json和页面截图匹配</strong><br>domtree json是一串描述元素位置信息和其XPath表达式的json,它通过服务器模拟访问页面,然后遍历页面的domtree生成,例如: </p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">{</span><br><span class="line"> <span class="string">"height"</span>: <span class="number">200</span>,</span><br><span class="line"> <span class="string">"left"</span>: <span class="number">400</span>,</span><br><span class="line"> <span class="string">"top"</span>: <span class="number">500</span>,</span><br><span class="line"> <span class="string">"width"</span>: <span class="number">300</span>,</span><br><span class="line"> <span class="string">"xpath"</span>: <span class="string">"/html/body/div[1]"</span></span><br><span class="line"> }</span><br></pre></td></tr></table></figure>
</li>
</ol>
<p>的含义是: xpath表达式为/html/body/div[1]的元素,它的左上角距离视窗左上角右偏400像素, 下偏500像素,同时该元素高200像素,宽300像素。根据这些信息我们可以在截图的对应区域进行框选,如果在截图上框选到的这块区域刚好是路径表达式/html/body/div[1]表示的区域,那么这个元素即匹配成功。</p>
<p><img src="https://tva1.sinaimg.cn/large/00831rSTly1gclqum5elgj30dw0dwt94.jpg" alt="rect.png"></p>
<p>下面主要介绍两种较难匹配的元素的解决: <strong>一、固定浮动元素 二、重叠元素</strong> </p>
<ol>
<li><p><strong>固定浮动元素的匹配</strong><br>固定浮动元素指的是网页上一些不随着页面滑动而移动的元素,它们与页面其他元素的相对位置是不固定的,比如一些悬浮球,底部栏之类的元素,这类元素的位置完全取决于你的设备型号,一个悬浮球在小屏幕设备上可能位于屏幕中部,换成大屏幕后它可能就位于屏幕靠下的位置了,而且在服务端截图的时候,对于一些需要滑动的页面截得是展开的长图。所以此时如果模拟移动设备去访问页面解析domtree的话,浮动元素的domtree json必然与截图无法匹配。对于这个问题摸索出的解决方案为: 放弃chrome模拟移动设备的方法,手动设置ua,然后截图之后,在解析domtree之前,获取页面高度,然后设置模拟访问的页面视图打开高度为页面高度,对应不同动态的设置视图高度,由于这样的视图高度和页面高度一致,所以在这样的视图下打开的页面不存在滑动的情况,所以完美解决浮动元素的问题。</p>
</li>
<li><p><strong>重叠元素的匹配</strong><br>domtree json只表示了元素之间二维的位置关系,但是对于三维上的重叠等情况没有描述,所以当一个位置出现两个元素,到底应该框选谁变成了问题。这个问题解决最容易想到的就是给domtree json加上三维信息的描述,并且元素确实有z-index这个属性表示层级关系,但是实际中发现z-index属性有许多的坑,不是很靠谱,比如父标签 position属性为relative,标签无position属性,标签含有浮动(float)属性等都会导致z-index失效(根本原因是css属性间作用不正交),同时发现巨量引擎也并没有使用z-index属性来进行匹配。后来我们观察了一些页面,发现其实大部分页面都存在着小元素在在大元素上层的规律,于是我们决定按照元素面积来做层级的判断,即面积小的元素默认在面积大的上层,这样还意外的解决了一些有蒙层的弹窗元素导致整个页面被蒙层遮盖无法选择的问题,并且在测试一些页面后在使用上已经达到类似工具的同等的水平。同时我们好奇是否同行也是使用同样的手法来解决这个问题,于是我们制作了一个特殊的页面,一个600<em>400的元素在上层,两个600</em>200的元素在下层,上下层边缘轮廓完全重合,这样按照面积小的元素默认在上的实现方式会导致实际在上层的大元素无法选中,我们拿着这个页面去类型工具尝试,发现果然上层的大元素无法选中,这说明了大家用的手法都是一致的!<br>至此,我们的XPath工具已经达到业内类似工具的使用水平,然后在此基础上对一些业内工具支持不太好的地方进行了优化,主要是:</p>
<ol>
<li><p>对重定向页面的支持,技术选项使用puppeteer自动解决</p>
</li>
<li><p>对于懒加载页面的优化,截图解析之前服务器模拟对页面进行滑动,使得页面完全加载 </p>
<p><em>最终元素选择效果:</em><br><img src="https://tva1.sinaimg.cn/large/00831rSTly1gclqwsm2lgj30la0v2k3t.jpg" alt="effect.png"></p>
</li>
</ol>
<p><strong>END: 更完整详细技术及产品实现细节在:<a href="https://download.csdn.net/download/qq_33446401/12233649" target="_blank" rel="noopener">内部分享PPT</a></strong></p>
</li>
</ol>
<!-- reward -->
</div>
<!-- copyright -->
<footer class="article-footer">
<ul class="article-tag-list" itemprop="keywords"><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/%E7%BA%BF%E7%B4%A2%E8%BF%BD%E8%B8%AA/" rel="tag">线索追踪</a></li></ul>
</footer>
</div>
</article>
<article id="post-cron表达式小记" class="article article-type-post" itemscope
itemprop="blogPost" data-scroll-reveal>
<div class="article-inner">
<header class="article-header">
<h2 itemprop="name">
<a class="article-title" href="/2019/04/08/cron%E8%A1%A8%E8%BE%BE%E5%BC%8F%E5%B0%8F%E8%AE%B0/"
>cron表达式小记</a
>
</h2>
</header>
<div class="article-meta">
<a href="/2019/04/08/cron%E8%A1%A8%E8%BE%BE%E5%BC%8F%E5%B0%8F%E8%AE%B0/" class="article-date">
<time datetime="2019-04-08T06:58:43.000Z" itemprop="datePublished">2019-04-08</time>
</a>
</div>
<div class="article-entry" itemprop="articleBody">
<h3 id="简介"><a href="#简介" class="headerlink" title="简介"></a>简介</h3><p> Cron表达式的作用是用来配置定时任务,它是一个字符串,由七个元素或者说叫域组成的,元素之间用空格来分割。</p>
<p> 组成Cron表达式的七个元素及其可能出现的值分别是:</p>
<table>
<thead>
<tr>
<th>元素</th>
<th>Seconds</th>
<th>Minutes</th>
<th>Hours</th>
<th>Day-of-Month</th>
<th>Month</th>
<th>Day-of-Week</th>
<th>Year(可选)</th>
</tr>
</thead>
<tbody>
<tr>
<td>值</td>
<td>[, - * /],[0-59]</td>
<td>[, - * /],[0-59]</td>
<td>[, - * /],[0-23]</td>
<td>[, - * / ? L W C],[1-31]</td>
<td>[, - * /],[1-12],[JAN-DEC]</td>
<td>[, - * / ? L C #],[1-7],[SUN-SAT]</td>
<td>[, - * /],[1970-2099]</td>
</tr>
</tbody>
</table>
<p>[^注]: Day-of-week: 1表示星期日,以此类推</p>
<p>特殊符号意义:</p>
<ol>
<li><p>* :匹配该域的任意值,假如在Minutes域使用 *,即表示每分钟都会触发事件。</p>
</li>
<li><p>?:只可以用于Day-of-Month和Day-of-Week两个域,它实际上就是为了解决星期和天之间的冲突而产生的,因为”星期”并不在” 年月日”这种时间记法体系里面,如果设置成每个月一号同时设置每个星期一执行任务的话,任务便会不知道该哪天执行。具体用法是当Day-of-Month和Day-of-Week中其中有一个有值的话另一个就应该设置成”?”。</p>
</li>
<li><p>-: 表示范围,例如在Minutes域使用5-20,表示从5分到20分钟每分钟触发一次 。</p>
</li>
<li><p>/: 表示起始时间开始触发,然后每隔固定时间触发一次,例如在Minutes域使用5/20,则意味着5分钟触发一次,而25,45等分别触发一次。</p>
</li>
<li><p>,: 表示列出枚举值值。例如:在Minutes域使用5,20,则意味着在5和20分每分钟触发一次。</p>
</li>
<li><p>L: 表示最后,只能出现在DayofWeek和DayofMonth域,如果在DayofWeek域使用5L,意味着在最后的一个星期四触发。</p>
</li>
<li><p>W:表示有效工作日(周一到周五),只能出现在DayofMonth域,系统将在离指定日期的最近的有效工作日触发事件。例如:在 DayofMonth使用5W,如果5日是星期六,则将在最近的工作日:星期五,即4日触发。如果5日是星期天,则在6日(周一)触发;如果5日在星期一到星期五中的一天,则就在5日触发。另外一点,W的最近寻找不会跨过月份</p>
</li>
<li><p>LW:这两个字符可以连用,表示在某个月最后一个工作日,即最后一个星期五。</p>
</li>
<li><p># :用于确定每个月第几个星期几,只能出现在DayofMonth域。例如在4#2,表示某月的第二个星期三。</p>
</li>
</ol>
<h3 id="举例"><a href="#举例" class="headerlink" title="举例"></a>举例</h3> <figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><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">*/5 * * * * ? 每隔5秒执行一次:</div><div class="line">0 */1 * * * ? 每隔1分钟执行一次:</div><div class="line">0 15 10 * * ? * 每天10点15分触发</div><div class="line">0 15 10 * * ? 2017 2017年每天10点15分触发</div><div class="line">0 * 14 * * ? 每天下午的 2点到2点59分每分触发</div><div class="line">0 0/5 14 * * ? 每天下午的 2点到2点59分(整点开始,每隔5分触发)</div><div class="line">0 0/5 14,18 * * ? 每天下午的 2点到2点59分、18点到18点59分(整点开始,每隔5分触发)</div><div class="line">0 0-5 14 * * ? 每天下午的 2点到2点05分每分触发</div><div class="line">0 15 10 ? * 6L 每月最后一周的星期五的10点15分触发</div><div class="line">0 15 10 ? * 6#3 每月的第三周的星期五开始触发</div></pre></td></tr></table></figure>
<!-- reward -->
</div>
<!-- copyright -->
<footer class="article-footer">
<ul class="article-tag-list" itemprop="keywords"><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/%E6%9D%82%E8%AE%B0/" rel="tag">杂记</a></li></ul>
</footer>
</div>
</article>
<article id="post-计算广告核心问题总结" class="article article-type-post" itemscope
itemprop="blogPost" data-scroll-reveal>
<div class="article-inner">
<header class="article-header">
<h2 itemprop="name">
<a class="article-title" href="/2019/03/28/%E8%AE%A1%E7%AE%97%E5%B9%BF%E5%91%8A%E6%A0%B8%E5%BF%83%E9%97%AE%E9%A2%98%E6%80%BB%E7%BB%93/"
>计算广告核心问题总结</a
>
</h2>
</header>
<div class="article-meta">
<a href="/2019/03/28/%E8%AE%A1%E7%AE%97%E5%B9%BF%E5%91%8A%E6%A0%B8%E5%BF%83%E9%97%AE%E9%A2%98%E6%80%BB%E7%BB%93/" class="article-date">
<time datetime="2019-03-28T09:56:58.000Z" itemprop="datePublished">2019-03-28</time>
</a>
</div>
<div class="article-entry" itemprop="articleBody">
<p>计算广告的核心问题(目标):<br>$$<br>max \sum^T_{i=1}(r_i-q_i)<br>$$<br> 就是这个最优化问题。上面的<code>i</code>代表从第<code>1</code>次到第<code>T</code>次之间的广告展示,<code>r</code>代表收入,<code>q</code>代表成本,<code>(r-q)</code> 代表这次广告活动的利润,最终目标是广告活动的总利润最大化。</p>
<p>同时由上面的可以导出投入产出比公式:<br>$$<br>ROI=max({\sum_ir_i}/{\sum_iq_i})<br>$$<br>点击率:<br>$$<br>CTR=广告点击数/广告展现数<br>$$<br>到达率:<br>$$<br>到达率=落地页成功打开次数/点击次数<br>$$<br>转化率:<br>$$<br>CVR=转化次数/到达次数<br>$$<br>描述网站盈利能力的参数:<br>$$<br>eCPM=r(a,u,c)=\mu(a,u,c)*v(a,u,c)<br>$$<br>$\mu$表示点击率, $v$代表点击价值,前者是在媒体上发生的行为,后者是在广告主网站上发生的行为。</p>
<p>$eCPM$一般指的是估计的千次展示收益。</p>
<p>$CPM$结算:按照千次展示结算。— 大多数互联网品牌广告特别是视频广告使用</p>
<p>$CPC$结算:按点击结算。— 在效果类广告市场中广泛使用</p>
<p>$$CSP/CPA/ROI$$结算:按照销售订单数,转化行为数或者投入产出比结算 — 用的不太多</p>
<p>$$CPT$$结算:按时间段结算。 — 针对大品牌广告主的广告活动</p>
<!-- reward -->
</div>
<!-- copyright -->
<footer class="article-footer">
<ul class="article-tag-list" itemprop="keywords"><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/%E8%AE%A1%E7%AE%97%E5%B9%BF%E5%91%8A/" rel="tag">计算广告</a></li></ul>
</footer>
</div>
</article>
<article id="post-实现一个简单的http服务器" class="article article-type-post" itemscope
itemprop="blogPost" data-scroll-reveal>
<div class="article-inner">
<header class="article-header">
<h2 itemprop="name">
<a class="article-title" href="/2018/02/10/%E5%AE%9E%E7%8E%B0%E4%B8%80%E4%B8%AA%E7%AE%80%E5%8D%95%E7%9A%84http%E6%9C%8D%E5%8A%A1%E5%99%A8/"
>实现一个简单的http服务器</a
>
</h2>
</header>
<div class="article-meta">
<a href="/2018/02/10/%E5%AE%9E%E7%8E%B0%E4%B8%80%E4%B8%AA%E7%AE%80%E5%8D%95%E7%9A%84http%E6%9C%8D%E5%8A%A1%E5%99%A8/" class="article-date">
<time datetime="2018-02-10T12:38:49.000Z" itemprop="datePublished">2018-02-10</time>
</a>
<div class="article-category">
<a class="article-category-link" href="/categories/%E7%BD%91%E7%BB%9C/">网络</a>
</div>
</div>
<div class="article-entry" itemprop="articleBody">
<p><img src="https://raw.githubusercontent.com/vzardlloo/imageHub/master/avatar.jpg" alt=""><br>这篇文章主要写一下如何实现一个简单的http服务器,并且借由这个问题讨论一下别的相关问题。首先实现一个http服务器是一件很难的事吗?这个问题不好回答,如果是一个demo级的http服务器,答案是:很简单,可以说是JAVA刚入门水平就可以做到的。如果是一个可供实际生产的、性能优良,架构优雅的服务器,答案是:很不容易,对大部分的人来说可能很难。不过不管是demo还是成熟的生产用的http服务器,他们核心的部分应该都是相似的,下面我们来分析一下服务器的工作过程:</p>
<p>首先何谓“服务”?服务就是按照客户的要求来完成客户的需求。服务器更具体的表现形式是按照客户的的请求来执行某种操作,返回指定数据,这里的数据和请求更具体的表现形式通常是<em>字符串</em>。也就是说<em>客户端发给服务器一个包含客户端需求的字符串,服务端通过解析客户端发来的字符串,获取客户端的需求,然后完成需求</em>。那么问题来了,服务端如何解析客户端发来的字符串呢?他们之间可是素不相识的,每个客户端按何种组织方式来发送自己的需求对服务器来说完全是不可预期的。于是这就需要一个统一的规范来统一客户端的请求和服务端的返回,以及一些别的行为规范,于是http协议合情合理的出现了。现在事情就变成<em>客户端发给服务器一个满足http协议的、包含客户端需求的字符串,服务端根据http协议来解析客户端发来的字符串获取客户端的需求,然后完成需求,返回符合http协议的字符串给客户端</em>。再然后这里的“发送”,“返回”又具体是什么呢?它们就是客户端和服务器之间通过socket连接执行的一些IO操作。这样分析之后我们大概知道整个的工作流程:<em>客户端建立一个连接到服务端,执行IO操作,把满足http协议的字符串发送给服务器,服务器根据http协议来解析客户端发来的字符串的含义,然后执行对应操作,最后把作为返回结果的、满足http协议的字符串执行IO操作发送给客户端。</em> </p>
<p>通过上面简单的分析我们大概知道http服务器具体干了啥(实际比较复杂)以及我们需要哪些基础前置知识:</p>
<ul>
<li>http协议(编程语言无关,核心):参见<a href="https://www.rfc-editor.org/rfc/rfc2616.txt" target="_blank" rel="external">RFC2616</a></li>
<li>IO操作(编程语言有关):各大编程语言的IO模块</li>
<li>字符串操作:这就是各大公司考算法题的原因吧(望天==)</li>
</ul>
<p>后续当然还有:</p>
<ul>
<li>多线程并发优化处理</li>
<li>设计模式</li>
<li>……</li>
</ul>
<p>下面是我用JAVA实现一个HTTP服务器,我这个服务器不是简单的小demo(demo只需两个JAVA 类即可搞定==),当然也不是可以生产用的(你可以把它写成可以生成用的),先导知识为Java NIO编程和Java 多线程编程,代码太长不贴,放在github。<em>代码地址:<a href="https://github.com/vzardlloo/crab" target="_blank" rel="external">Crab</a></em><br>项目截图:<br><img src="https://camo.githubusercontent.com/b5a6153196f06168813f24483056cbc054eb2944/687474703a2f2f6f6f336171336163382e626b742e636c6f7564646e2e636f6d2f637261622e706e67" alt=""></p>
<p>项目的目的是什么呢?最重要的目的是希望可以写出规范化的、工程化的代码以及项目,特别是与入门者来说常常只写一些玩具式的demo,或者盲目的去看一下大型项目的源码,我觉得这样对自己水平的提升帮助有限,事实上我认为对一个人提升最大的是从最开始就接触某个项目或领域,从它萌芽的时候开始参与,一步步由项目和问题驱动着来学习,在遇到问题的时候可以想办法来解决它,想不出来可以去别的项目看看别人是如何解决的,这样既提高了自己的水平,也对别的项目有了更深的理解,知道别人为何这样做,而不是去记忆别人是怎么做的。这里引出的一个问题是:当我们在阅读源码时我认为至少要带着这样几个问题:1.这个东西是干什么的,解决了什么问题。2。这里作者这里为什么要这样做,他的目的是什么,他想干什么。3.我现在想要做的东西需要它吗?需要到什么程度(会用?会魔改?)?以项目驱动学习,把从书上,别人源码里的技巧立马用到自己的项目里,才可以让知识真的化为己用。</p>
<h5 id="题外话当我们学习时我们通常实际上在学习什么"><a href="#题外话:当我们学习时我们通常实际上在学习什么?" class="headerlink" title="题外话:当我们学习时我们通常实际上在学习什么?"></a>题外话:当我们学习时我们通常实际上在学习什么?</h5><p>我的观点是我们在学习时通常实际上更多的在学习各种规范,比如JavaWeb其实通常就是Java语言规范+各种框架的使用规范+网络协议规范,因为计算机科学以及很多工程科学实际是一个人造的体系,支撑这个体系的就是各种规范,修补和发展这个体系也是依赖于各种规范,由于规范可以人造,因此规范可以说是学不完的,因为会不停的有新的规范出来,所以说学无止境。说起学无止境好像每门科学都是学无止境的,我认为科学大致可以分成两种,一直是研究的是基于一种人造的体系,一直是基于自然的体系(当然人造的最后也是基于自然的)。前者的学无止境是由于人类创造的无止境,不断地会有新的问题和规范被创造出来,后者的学无止境更多的是由于大自然的无止境,大到宇宙星辰,小到原子夸克,浩瀚无边地大自然的规范就在那里等待人们去发现。</p>
<!-- reward -->
</div>
<!-- copyright -->
<footer class="article-footer">
<ul class="article-tag-list" itemprop="keywords"><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/http-java/" rel="tag">http java</a></li></ul>
</footer>
</div>
</article>
<article id="post-由三次握手想到的" class="article article-type-post" itemscope
itemprop="blogPost" data-scroll-reveal>
<div class="article-inner">
<header class="article-header">
<h2 itemprop="name">
<a class="article-title" href="/2017/12/01/%E7%94%B1%E4%B8%89%E6%AC%A1%E6%8F%A1%E6%89%8B%E6%83%B3%E5%88%B0%E7%9A%84/"
>由三次握手想到的...</a
>
</h2>
</header>
<div class="article-meta">
<a href="/2017/12/01/%E7%94%B1%E4%B8%89%E6%AC%A1%E6%8F%A1%E6%89%8B%E6%83%B3%E5%88%B0%E7%9A%84/" class="article-date">
<time datetime="2017-12-01T14:44:31.000Z" itemprop="datePublished">2017-12-01</time>
</a>
<div class="article-category">
<a class="article-category-link" href="/categories/%E7%BD%91%E7%BB%9C/">网络</a>
</div>
</div>
<div class="article-entry" itemprop="articleBody">
<p><img src="http://oo3aq3ac8.bkt.clouddn.com/tcp.png" alt="tcp.png"><br>上面是一个tcp链接的过程,也就是俗称的三次握手,图上把每次握手做了什么也表示的比较清楚,不过这种表述的方式比较僵硬,没有自然而然的说明三次握手中“三次”的充分性和必要性。在建立可靠通信的准备过程中,客户端和服务端都要确认这样四件事:1、自己拥有发送信息的能力,2、自己拥有接受信息的能力,3、对方拥有发送信息的能力,4、对方拥有接受信息的能力。</p>
<ul>
<li>在第一次握手时(也就是客户端发送信息给服务端,服务端接受到信息那一刻),这个时候服务端明确了这样两件事,即对方(客户端)具有发送信息的能力,自己具有接受信息的能力。</li>
<li>在第二次握手的时候(也就是服务端返回信息给客户端,客户端接受到信息那一刻),这个时候客户端可以明确这样四件事:由于自己之前发出的信息有了反馈,可以推断出自己之前的信息发送成功,即自己拥有发送信息的能力,对方接受到信息并给出反馈,说明对方具有接受信息和发送信息的能力,自己接受到反馈说明自己拥有接受信息的能力。</li>
<li>在第三次握手的时候(服务端发送确认信息给服务端,服务端接受到信息那一刻),服务端可以明确这样两件事:由于自己发送的信息有了反馈可以推断出自己拥有发送信息的能力,对方具有接受信息的能力。</li>
</ul>
<p>这样通过三次握手双方都恰好完成了自己在建立可靠通信需要明确的四件事,所以可以进行可靠通信。那么可以做一下推广,三点,四点,乃至N点建立可靠通信需要握几次手呢?先看一下三点,三点就是在两点的基础上再加一点,那么对于第三点来说,对方(点一,点二)的接受和发送信息的能力均已经得到了验证,所以他只需验证自己的接受和发送信息的能力即可,那么验证自己的发送信息和接受信息的能力需要握几次手呢?答案是三次,因为接受信息的能力需要一次握手来验证,发送信息的能力需要两次握手来验证(先发送,等待反馈,接受到反馈说明具有接受发送信息的能力)。所以对于四点也是这样,只要通过三次握手确认自己的发送信息和接受信息的能力,就可以加入已有的三点可靠通信网络,推广一下就是N点可靠通信网络的建立需要[3*(n-1)]次握手,当N=2时,就是3次握手。</p>
<!-- reward -->
</div>
<!-- copyright -->
<footer class="article-footer">
<ul class="article-tag-list" itemprop="keywords"><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/%E7%BD%91%E7%BB%9C/" rel="tag">网络</a></li></ul>
</footer>
</div>
</article>
<article id="post-Js原型链解读" class="article article-type-post" itemscope
itemprop="blogPost" data-scroll-reveal>
<div class="article-inner">
<header class="article-header">
<h2 itemprop="name">
<a class="article-title" href="/2017/11/06/Js%E5%8E%9F%E5%9E%8B%E9%93%BE%E8%A7%A3%E8%AF%BB/"
>Js原型链解读</a
>
</h2>
</header>
<div class="article-meta">
<a href="/2017/11/06/Js%E5%8E%9F%E5%9E%8B%E9%93%BE%E8%A7%A3%E8%AF%BB/" class="article-date">
<time datetime="2017-11-06T13:41:43.000Z" itemprop="datePublished">2017-11-06</time>
</a>
<div class="article-category">
<a class="article-category-link" href="/categories/%E5%89%8D%E7%AB%AF/">前端</a>
</div>
</div>
<div class="article-entry" itemprop="articleBody">
<h3 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h3><p>在JavaScript中没”子类”和“父类”的概念,进一步地也没有“类”和“实例”的的区分。它靠一种看上去十分古怪的”原型链“(prototype chain)模式来实现继承。学过JAVA等编程语言的人可能会认为这是对Java等语言的继承实现方式的一种拙劣并且失败的模仿,然而事实并非如此,原型链模式和我们常见的Class模式分别是两种编程范式prototype_base和class_base的实现,前者在动态语言中似乎十分常见,而后者主要在静态语言领域流行。下面是维基百科关于prototype_base模式的介绍:</p>
<blockquote>
<p>Prototype-based programming is a style of object-oriented programming in which behaviour reuse (known as inheritance) is performed via a process of reusing existing objects via delegation that serve as prototypes. This model can also be known as prototypal, prototype-oriented, classless, or instance-based programming. Delegation is the language feature that supports prototype-based programming.<br>Prototype object oriented programming uses generalized objects, which can then be cloned and extended. Using fruit as an example, a “fruit” object would represent the properties and functionality of fruit in general. A “banana” object would be cloned from the “fruit” object, and would also be extended to include general properties specific to bananas. Each individual “banana” object would be cloned from the generic “banana” object. Compare to the class-based paradigm, where a “fruit” class (not object) would be extended by a “banana” class</p>
</blockquote>
<p><a href="https://en.wikipedia.org/wiki/Prototype-based_programming" target="_blank" rel="noopener">维基原文</a><br>
<a class="article-more-link" href="/2017/11/06/Js%E5%8E%9F%E5%9E%8B%E9%93%BE%E8%A7%A3%E8%AF%BB/">阅读更多...</a>
<!-- reward -->
</div>
<!-- copyright -->
<footer class="article-footer">
<ul class="article-tag-list" itemprop="keywords"><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/%E5%89%8D%E7%AB%AF/" rel="tag">前端</a></li></ul>
</footer>
</div>
</article>
<article id="post-统计知识(1)" class="article article-type-post" itemscope
itemprop="blogPost" data-scroll-reveal>
<div class="article-inner">
<header class="article-header">
<h2 itemprop="name">
<a class="article-title" href="/2017/10/16/%E7%BB%9F%E8%AE%A1%E7%9F%A5%E8%AF%86%EF%BC%881%EF%BC%89/"
>统计知识(1)</a
>
</h2>
</header>
<div class="article-meta">
<a href="/2017/10/16/%E7%BB%9F%E8%AE%A1%E7%9F%A5%E8%AF%86%EF%BC%881%EF%BC%89/" class="article-date">
<time datetime="2017-10-16T08:44:17.000Z" itemprop="datePublished">2017-10-16</time>
</a>
<div class="article-category">
<a class="article-category-link" href="/categories/%E7%BB%9F%E8%AE%A1/">统计</a>
</div>
</div>
<div class="article-entry" itemprop="articleBody">
<h2 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h2><p>最近为了参加一个数据分析比赛,在复习统计这块的知识。首先什么是统计呢?我采用北京大学出版社出版的《应用经济统计学》中的定义:统计学是一门对群体现象数量特征进行计量描述和分析推论的科学。从定义可以看出统计学主要干两件事一个是对群体现象特征进行计量描述,第二个是对群体数量进行分析得出推论。那我们一件一件事来,先来讲一下统计学干的第一件事:对群体现象特征进行计量描述。本文主要理一下脉络,对于细节不过多纠结(主要是Markdown打公式太麻烦……)<br>
<a class="article-more-link" href="/2017/10/16/%E7%BB%9F%E8%AE%A1%E7%9F%A5%E8%AF%86%EF%BC%881%EF%BC%89/">阅读更多...</a>
<!-- reward -->
</div>
<!-- copyright -->
<footer class="article-footer">
<ul class="article-tag-list" itemprop="keywords"><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/%E7%BB%9F%E8%AE%A1/" rel="tag">统计</a></li></ul>
</footer>
</div>
</article>
<article id="post-同步Github上的fork" class="article article-type-post" itemscope
itemprop="blogPost" data-scroll-reveal>
<div class="article-inner">
<header class="article-header">
<h2 itemprop="name">
<a class="article-title" href="/2017/10/13/%E5%90%8C%E6%AD%A5Github%E4%B8%8A%E7%9A%84fork/"
>同步Github上的fork</a
>
</h2>
</header>
<div class="article-meta">
<a href="/2017/10/13/%E5%90%8C%E6%AD%A5Github%E4%B8%8A%E7%9A%84fork/" class="article-date">
<time datetime="2017-10-13T07:08:51.000Z" itemprop="datePublished">2017-10-13</time>
</a>
<div class="article-category">
<a class="article-category-link" href="/categories/Github/">Github</a>
</div>
</div>
<div class="article-entry" itemprop="articleBody">
<p>我们有时候会在Github上fork一个我们感兴趣的项目到自己的仓库,等一段时间过后这个项目已经更新了,但是自己仓库里还停留在刚fork时的状态,那么我们如何把自己fork到仓库的项目同步到作者的进度呢?这篇博客主要就是讲一下这个问题。<br>这个问题我有两种解决的办法:<br>一种是在Github上操作,把自己仓库的项目设成<code>base</code>,把作者的的项目设成<code>head</code>,然后给自己提pr,最后在pull下来就行了。这种方法的缺点就是要开网页点来点去,如果你正在沉迷在命令行里无法自拔可能不太喜欢这种方法。<br>
<a class="article-more-link" href="/2017/10/13/%E5%90%8C%E6%AD%A5Github%E4%B8%8A%E7%9A%84fork/">阅读更多...</a>
<!-- reward -->
</div>
<!-- copyright -->
<footer class="article-footer">
<ul class="article-tag-list" itemprop="keywords"><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/Github/" rel="tag">Github</a></li></ul>
</footer>
</div>
</article>
<article id="post-Http协议杂谈" class="article article-type-post" itemscope
itemprop="blogPost" data-scroll-reveal>
<div class="article-inner">
<header class="article-header">
<h2 itemprop="name">
<a class="article-title" href="/2017/09/19/Http%E5%8D%8F%E8%AE%AE%E6%9D%82%E8%B0%88/"
>Http协议杂谈</a
>
</h2>
</header>
<div class="article-meta">
<a href="/2017/09/19/Http%E5%8D%8F%E8%AE%AE%E6%9D%82%E8%B0%88/" class="article-date">
<time datetime="2017-09-19T08:42:49.000Z" itemprop="datePublished">2017-09-19</time>
</a>
<div class="article-category">
<a class="article-category-link" href="/categories/JAVA/">JAVA</a>
</div>
</div>
<div class="article-entry" itemprop="articleBody">
<h4 id="HTTP的特性"><a href="#HTTP的特性" class="headerlink" title="HTTP的特性"></a>HTTP的特性</h4><ul>
<li>HTTP构建于TCP/IP协议之上,默认端口号是80</li>
<li>HTTP是无连接无状态的</li>
</ul>
<h4 id="HTTP报文"><a href="#HTTP报文" class="headerlink" title="HTTP报文"></a>HTTP报文</h4><p>Http协议是以ASCII码传输,建立在TCP/IP协议之上的应用层规范。规范把HTTP请求分为三个部分:状态行、请求头、消息主题。类似于下面这样:<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><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">GET /en-US/docs/Web/HTTP/Headers/Content-Disposition HTTP/1.1</div><div class="line">Host: developer.mozilla.org</div><div class="line">Connection: keep-alive</div><div class="line">Cache-Control: max-age=0</div><div class="line">Upgrade-Insecure-Requests: 1</div><div class="line">User-Agent: Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.113 Mobile Safari/537.36</div><div class="line">Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8</div><div class="line">Referer: https://hit-alibaba.github.io/interview/basic/network/HTTP.html</div><div class="line">Accept-Encoding: gzip, deflate, br</div><div class="line">Accept-Language: zh-CN,zh;q=0.8</div><div class="line">Cookie: csrftoken=0QVKqjybZR4MatNi0vCP03XIDrEWODO9; dwf_section_edit=True; dwf_sg_task_completion=False; _ga=GA1.2.817713072.1498834189; _gid=GA1.2.1652928103.1505806097</div><div class="line">If-None-Match: "76da2643e0174c564b0a898793e76edda496498f"</div></pre></td></tr></table></figure></p>
<a class="article-more-link" href="/2017/09/19/Http%E5%8D%8F%E8%AE%AE%E6%9D%82%E8%B0%88/">阅读更多...</a>
<!-- reward -->
</div>
<!-- copyright -->
<footer class="article-footer">
<ul class="article-tag-list" itemprop="keywords"><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/JAVA/" rel="tag">JAVA</a></li></ul>
</footer>
</div>
</article>
<article id="post-JAVA虚拟机的类加载机制" class="article article-type-post" itemscope
itemprop="blogPost" data-scroll-reveal>
<div class="article-inner">
<header class="article-header">
<h2 itemprop="name">
<a class="article-title" href="/2017/09/19/JAVA%E8%99%9A%E6%8B%9F%E6%9C%BA%E7%9A%84%E7%B1%BB%E5%8A%A0%E8%BD%BD%E6%9C%BA%E5%88%B6/"
>JAVA虚拟机的类加载机制</a
>
</h2>
</header>
<div class="article-meta">
<a href="/2017/09/19/JAVA%E8%99%9A%E6%8B%9F%E6%9C%BA%E7%9A%84%E7%B1%BB%E5%8A%A0%E8%BD%BD%E6%9C%BA%E5%88%B6/" class="article-date">
<time datetime="2017-09-19T02:27:43.000Z" itemprop="datePublished">2017-09-19</time>
</a>
<div class="article-category">
<a class="article-category-link" href="/categories/JAVA/">JAVA</a>
</div>
</div>
<div class="article-entry" itemprop="articleBody">
<h4 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h4><p>这篇博客讲一下JAVA虚拟机的类加载机制,一个类从被加载到虚拟机内存开始,到卸载处内存为止,它的整个生命周期包括:</p>
<ol>
<li>加载</li>
<li>验证</li>
<li>准备</li>
<li>解析</li>
<li>初始化</li>
<li>使用</li>
<li>卸载</li>
</ol>
<p>其中1,2,3,5,7这五个步骤的顺序是固定的,而解析却不一定,它可以在初始化之后再开始,这是为了支持JAVA语言的运行时绑定。下面开始逐一介绍每个步骤。<br>
<a class="article-more-link" href="/2017/09/19/JAVA%E8%99%9A%E6%8B%9F%E6%9C%BA%E7%9A%84%E7%B1%BB%E5%8A%A0%E8%BD%BD%E6%9C%BA%E5%88%B6/">阅读更多...</a>
<!-- reward -->
</div>
<!-- copyright -->
<footer class="article-footer">
<ul class="article-tag-list" itemprop="keywords"><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/JAVA/" rel="tag">JAVA</a></li></ul>
</footer>
</div>
</article>
</article>
<nav class="page-nav">
<span class="page-number current">1</span><a class="page-number" href="/page/2/">2</a><a class="page-number" href="/page/3/">3</a><a class="page-number" href="/page/4/">4</a><a class="extend next" rel="next" href="/page/2/">下一页</a>
</nav>
</section>
</div>
<footer class="footer">
<div class="outer">
<ul class="list-inline">
<li>
©
2017-2020
vzardlloo
</li>
<li>
Powered by
<a href="https://hexo.io" target="_blank">Hexo</a> Theme <a href="https://github.com/Shen-Yu/hexo-theme-ayer" target="_blank">Ayer</a>
</li>
</ul>
<ul class="list-inline">
<li>
<span>
<i>PV:<span id="busuanzi_value_page_pv"></span></i>