-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsearch.xml
3754 lines (3588 loc) · 459 KB
/
search.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
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
<?xml version="1.0" encoding="utf-8"?>
<search>
<entry>
<title>30-years-old</title>
<url>/2020/02/28/30-years-old/</url>
<content><![CDATA[<p><img src="http://imgs.yrzdm.com/imgs/20200228/zblPctz24xrE.png?imageslim" alt="mark"></p>
<p>如果生活是大海,那么其中的每天就像海浪,有的震撼,有的普通。</p>
<p>每年的反省都会发现很多让自己后悔不已的事情,往事并不如烟。</p>
<a id="more"></a>
<ol>
<li><p>相信命</p>
<p>信命不是极致的悲观、灰暗和迷信,而是理性又成熟深刻的价值观,知道山外有山,才能更加云淡风轻,每个人的起跑线不一样,个体的差异不因意志转移而改变,尊重客观事实才能更好的活自己。</p>
</li>
<li><p>信息差</p>
<p>都说现在互联网时代了,没有什么信息查和信息壁垒,其实信息差永远存在。这一点如果认识的更早一些就好了。天下所有靠培训教育来盈利的都是靠的信息差。</p>
</li>
<li><p>不要把所有的鸡蛋都放在一个篮子里</p>
<p>不要等到拥有几十万再去理财,把收入分成几份,消费,应急,储蓄,年轻的时候不要折腾股票和其他投资,在你认知不能驾驭你所有用的时候,这些拥有都将成为失去,老实把钱存起来,钱多一些,你的自信会更多一些,思维会越来越广。</p>
</li>
<li><p>降低自我预期的阈值</p>
<p>没有人能随便成功,降低预期能让自己好过不少,至少失败的时候能舒服一些,学会接受失败面对现实。</p>
</li>
<li><p>家庭合伙制是婚宴的本质</p>
<p>性格好的女人比漂亮、有才、有钱之类更加优势明显。</p>
</li>
<li><p>不要和老板做朋友</p>
<p>如果和老板称兄道弟,表面越好,后面撕逼就更严重。开始很美丽,结束没道理。</p>
</li>
<li><p>少买或者不买付费知识课程</p>
<p>90%的课程本质上都是垃圾,对你没有任何好处,所有的方法论和成功方式都不适合你,基本连可应用的场景都没有,知识付费本质上是贩卖焦虑,收智商税。省下这些时间读几本经典的书并总结。</p>
</li>
<li><p>买保险</p>
<p>保险是你人生变故后的最后一根救命稻草。</p>
</li>
<li><p>学习一项特长</p>
<p>趁早刻意练习,特长能够让你保持足够的竞争力和优势。</p>
</li>
<li><p>及时止损</p>
<p>错了就是错了,失败了就是失败了,及时抽离。</p>
</li>
<li><p>锻炼身体</p>
<p>这世界是你的,但最终是哪些身体好的。</p>
</li>
<li><p>享受孤独,学会独立思考</p>
<p>孤独并不可耻,每个人都是孤独的,只有自己了解自己。</p>
</li>
<li><p>创业</p>
<p>多去折腾,选择别人而不是被别人选择。</p>
</li>
<li><p>自信坚持</p>
<p>自信能让你获得更多的资源和快感。</p>
</li>
</ol>
]]></content>
<categories>
<category>docs</category>
<category>python</category>
<category>index</category>
</categories>
<tags>
<tag>Python</tag>
</tags>
</entry>
<entry>
<title>50-python-interview-questions-and-answers</title>
<url>/2020/06/16/50-python-interview-questions-and-answers/</url>
<content><![CDATA[<p>50 Python Interviwe Questions and Answers<br><img src="http://imgs.yrzdm.com/imgs/20200618/LE9hjRVnfL6W.png?imageslim" alt="mark"></p>
<blockquote>
<p>This post was written by Cameron Wilson, and was originally published at <a href='https://www.educative.io/blog' target="_blank" rel="noopener">Educative.io</a> 中文翻译由Roy在<a href='https://cx4.github.io'>cx4</a>首发,如需转载请注明出处。</p>
</blockquote>
<a id="more"></a>
<p>这篇文章涵盖有关Python编程语言的50个面试问题。 </p>
<h3 id="基础部分"><a href="#基础部分" class="headerlink" title="基础部分"></a>基础部分</h3><ul>
<li><a href="#1">list和tuple的区别是什么?</a></li>
<li><a href="#2">怎样转换list为tuple?</a></li>
<li><a href="#3">array和list的区别是什么?</a></li>
<li><a href="#4">Python是怎样进行内存管理的?</a></li>
<li><a href="#5">如何在Python中实现多线程?</a></li>
<li><a href="#6">什么是monkey patching?</a></li>
<li><a href="#7">什么是lambda函数,举例说明什么时候用匿名函数更好,什么时候不行?</a></li>
<li><a href="#8">什么是pickling和unpickling?</a></li>
<li><a href="#9">与嵌套列表相比Numpy数组有什么优势?</a></li>
<li><a href="#10">举例说明Python的继承。</a></li>
<li><a href="#11">python中的多态是什么?</a></li>
<li><a href="#12">举例说明range()和xrange()的区别。</a></li>
<li><a href="#13">举例说明Flask和Django的区别。</a></li>
<li><a href="#14">什么是PYTHONATH?</a></li>
<li><a href="#15">什么是PEP8?</a></li>
<li><a href="#16">什么是Python装饰器?</a></li>
<li><a href="#17">什么是init?</a></li>
<li><a href="#18">什么是三元运算符?</a></li>
<li><a href="#19">什么是全局变量和局部变量?</a></li>
<li><a href="#20">什么是@property?</a></li>
<li><a href="#21">try/except在python中是怎样使用的?</a></li>
<li><a href="#22">举例说明Python2和Python3的区别。</a></li>
<li><a href="#23">什么是join方法?</a></li>
<li><a href="#24">什么是字典理解?</a></li>
<li><a href="#25">怎样做一次深度copy?</a></li>
<li><a href="#26">怎样检查一个键是否在字典中?</a></li>
<li><a href="#27">如何在Python中实现记忆优化?</a></li>
<li><a href="#28">在Python中如何实现字典排序?</a></li>
<li><a href="#29">什么时候使用any()和all(),如何使用?</a></li>
<li><a href="#30">什么是python的文档字符串?</a></li>
<li><a href="#31">写一个python的函数并举例说明它是怎样运行的。</a></li>
<li><a href="#32">举例说明迭代器和生成器在Python中的区别。</a></li>
<li><a href="#33">Python中的defaultdict是什么?</a></li>
<li><a href="#34">什么是python的库?</a></li>
<li><a herf="#35">怎样转换一个list为array?</a><h2 id="代码部分"><a href="#代码部分" class="headerlink" title="代码部分"></a>代码部分</h2></li>
<li><a herf="#36">反转字符串</a></li>
<li><a herf="#37">检查一个字符串是否在另外一个字符串中</a></li>
<li><a herf="#38">在Python中实施广度优先搜索(BFS)</a></li>
<li><a herf="#39">在Python中实现深度优先搜索(DFS)</a></li>
<li><a herf="#40">实现通配符</a></li>
<li><a herf="#41">在Python中实施合并排序</a></li>
<li><a herf="#42">在Python中实现Dijkstra算法</a></li>
<li><a herf="#43">合并两个排序列表</a></li>
<li><a herf="#44">寻找两个和为‘K’的数字</a></li>
<li><a herf="#45">找到列表中第一个非重复整数</a></li>
<li><a herf="#46">查找链接列表的中间值</a></li>
<li><a herf="#47">颠倒队列中的前“k”个元素</a></li>
<li><a herf="#48">查找二叉搜索树(BST)的高度</a></li>
<li><a herf="#49">将最大堆转换为最小堆</a></li>
<li><a herf="#50">检测链表中的循环</a></li>
</ul>
<h3 id="1-list和tuple的区别"><a href="#1-list和tuple的区别" class="headerlink" title="1. list和tuple的区别"></a>1. <a name="1">list和tuple的区别</a></h3><table>
<thead>
<tr>
<th><strong>List</strong></th>
<th><strong>Tuple</strong></th>
</tr>
</thead>
<tbody><tr>
<td>列表由可变对象组成。 (创建后可以更改的对象)</td>
<td>元组由不可变的对象组成。 (创建后无法更改的对象)</td>
</tr>
<tr>
<td>列表占用很大的内存。</td>
<td>元组占用的内存很小。</td>
</tr>
<tr>
<td>列表存储在两个内存块中(一个是固定大小的,另一个是可变大小的,用于存储数据)</td>
<td>元组存储在单个内存块中。</td>
</tr>
<tr>
<td>创建列表的速度较慢,因为需要访问两个内存块。</td>
<td>创建元组比创建列表快。</td>
</tr>
<tr>
<td>列表中的元素可以删除或替换。</td>
<td>元组中的元素无法删除或替换。</td>
</tr>
<tr>
<td>列表中的数据存储在[]括号中。例如[1,2,3]</td>
<td>元组的数据存储在()括号中。例如(1,2,3)</td>
</tr>
</tbody></table>
<blockquote>
<p>只要用户知道在元组中插入了什么,就应该使用元组。假设一所大学将其学生的信息存储在一个数据结构中;为了使此信息保持不变,应将其存储在元组中。由于列表为用户提供了更方便的可访问性,因此在需要存储类似类型的对象时应使用它们。例如,如果杂货店需要将所有乳制品存储在一个字段中,则应使用一个列表。</p>
</blockquote>
<h3 id="2-您如何将列表转换为元组?"><a href="#2-您如何将列表转换为元组?" class="headerlink" title="2. 您如何将列表转换为元组?"></a>2. <a name="2">您如何将列表转换为元组?</a></h3><figure class="highlight stylus"><table><tr><td class="code"><pre><code class="hljs stylus"><span class="hljs-selector-tag">a</span> = [<span class="hljs-number">50</span>,<span class="hljs-string">"hello"</span>,<span class="hljs-string">"Ok"</span>]<br><span class="hljs-selector-tag">b</span> = (<span class="hljs-selector-tag">a</span>[<span class="hljs-number">0</span>],<span class="hljs-selector-tag">a</span>[<span class="hljs-number">1</span>],<span class="hljs-selector-tag">a</span>[<span class="hljs-number">2</span>])<br></code></pre></td></tr></table></figure>
<h3 id="3-数组和列表的区别是什么?"><a href="#3-数组和列表的区别是什么?" class="headerlink" title="3. 数组和列表的区别是什么?"></a>3. <a name="3">数组和列表的区别是什么?</a></h3><table>
<thead>
<tr>
<th>List</th>
<th>Array</th>
</tr>
</thead>
<tbody><tr>
<td>Python列表非常灵活,可以保存任意数据。</td>
<td>Python数组只是C数组的一个薄包装。</td>
</tr>
<tr>
<td>列表是Python语法的一部分,因此不需要首先声明它们。</td>
<td>首先需要从其他库(即numpy)中导入或声明数组。</td>
</tr>
<tr>
<td>列表还可以以省时的方式快速调整大小。这是因为Python在初始化时会初始化列表中的一些额外元素。</td>
<td>数组无法调整大小。相反,需要将一个数组的值复制到另一个更大的数组中。</td>
</tr>
<tr>
<td>列表可以保存异构数据。</td>
<td>数组只能存储同质数据。它们的值具有统一的数据类型。</td>
</tr>
<tr>
<td>数学函数不能直接应用于列表。相反,必须将它们分别应用于每个元素。</td>
<td>数组是专门为算术计算而优化的。</td>
</tr>
<tr>
<td>由于为列表分配了一些额外的元素,因此可以消耗更多的内存,从而可以更快地附加项目。</td>
<td>由于数组保持其首次初始化时的大小,因此它们是紧凑的。</td>
</tr>
</tbody></table>
<h3 id="4-如何在Python中管理内存?"><a href="#4-如何在Python中管理内存?" class="headerlink" title="4. 如何在Python中管理内存?"></a>4. <a name="4">如何在Python中管理内存?</a></h3><ol>
<li>python中的内存管理由Python专用堆空间管理。所有Python对象和数据结构都位于私有堆中。程序员无权访问此私有堆。 python解释器代替了它。</li>
<li>Python对象的堆空间分配是由Python的内存管理器完成的。核心API允许访问一些工具,以便程序员进行编码。</li>
<li>Python还具有一个内置的垃圾收集器,该垃圾收集器回收所有未使用的内存,并使其可用于堆空间。<h3 id="5-如何在Python中实现多线程?"><a href="#5-如何在Python中实现多线程?" class="headerlink" title="5. 如何在Python中实现多线程?"></a>5. <a name="5">如何在Python中实现多线程?</a></h3></li>
<li>Python有一个多线程程序包,但是如果您想使用多线程来加快代码速度,那么使用它通常不是一个好主意。</li>
<li>Python具有称为全局解释器锁(GIL)的构造。 GIL确保您的“线程”只能在任何一次执行。线程获取GIL,做一些工作,然后将GIL传递到下一个线程。</li>
<li>这发生得非常快,因此在人眼看来,您的线程似乎是并行执行的,但实际上它们只是使用相同的CPU内核轮流执行。</li>
<li>所有这些GIL传递都会增加执行开销。这意味着,如果您想使代码运行更快,那么使用线程包通常不是一个好主意。<h3 id="6-什么是猴子修补?"><a href="#6-什么是猴子修补?" class="headerlink" title="6. 什么是猴子修补?"></a>6. <a name="6">什么是猴子修补?</a></h3>在Python中,术语“monkey patch”仅指运行时对类或模块的动态修改。<h3 id="7-什么是lambda函数?举例说明什么时候有用,什么时候没用。"><a href="#7-什么是lambda函数?举例说明什么时候有用,什么时候没用。" class="headerlink" title="7. 什么是lambda函数?举例说明什么时候有用,什么时候没用。"></a>7. <a name="7">什么是lambda函数?举例说明什么时候有用,什么时候没用。</a></h3>Lambda函数是一个小的匿名函数,它返回一个对象。<br>lambda返回的对象通常被分配给变量或用作其他较大函数的一部分。<br>lambda函数不是用于创建函数的常规def关键字,而是使用lambda关键字定义。<br>lambda的结构如下所示:<br><img src="http://imgs.yrzdm.com/imgs/20200618/TUW0HpzWB2ub.png?imageslim" alt="mark"><h4 id="使用lambda的目的:"><a href="#使用lambda的目的:" class="headerlink" title="使用lambda的目的:"></a>使用lambda的目的:</h4></li>
</ol>
<ul>
<li>Lambda比完整功能更具可读性,因为它可以内联编写。因此,当函数表达式较小时,最好使用lambda。</li>
<li>lambda函数的优点在于它们返回函数对象。</li>
<li>当与要求函数对象作为参数的map或filter等函数一起使用时,这使它们很有用。</li>
<li>当表达式超过一行时,Lambda无效。<h3 id="8-什么是pickling和unpickling"><a href="#8-什么是pickling和unpickling" class="headerlink" title="8. 什么是pickling和unpickling?"></a>8. <a name="8">什么是pickling和unpickling?</a></h3>Pickle模块接受任何Python对象并将其转换为字符串表示形式,然后使用转储函数将其转储到文件中,此过程称为pickling。<br>从存储的字符串表示形式检索原始Python对象的过程称为unpickling。<h3 id="9-与(嵌套)Python列表相比,NumPy数组有什么优势?"><a href="#9-与(嵌套)Python列表相比,NumPy数组有什么优势?" class="headerlink" title="9. 与(嵌套)Python列表相比,NumPy数组有什么优势?"></a>9. <a name="9">与(嵌套)Python列表相比,NumPy数组有什么优势?</a></h3></li>
</ul>
<ol>
<li>Python的列表是有效的通用容器。<br>它们支持(相当)高效的插入,删除,附加和连接,并且Python的列表表达式使它们易于构造和操作。</li>
<li>它们有一定的局限性:它们不支持“向量化”操作,例如逐元素加法和乘法,并且它们可以包含不同类型的对象这一事实意味着Python必须存储每个元素的类型信息,并且在操作时必须执行类型调度代码在每个元素上。</li>
<li>NumPy不仅效率更高,也更加方便。您可以免费获得许多矢量和矩阵运算,避免不必要的工作。</li>
<li>NumPy数组更快,您可以使用NumPy,FFT,卷积,快速搜索,基本统计信息,线性代数,直方图等内置大量内容。<h3 id="10-举例说明Python中的继承"><a href="#10-举例说明Python中的继承" class="headerlink" title="10. 举例说明Python中的继承"></a>10. <a name="10">举例说明Python中的继承</a></h3>继承允许一个类获取另一类的所有成员(例如属性和方法)。<br>继承提供了代码可重用性,使创建和维护应用程序变得更加容易。<br>我们从中继承的类称为超类,而继承的类称为派生/子类。</li>
<li>单一继承:派生类获取超类的单个成员。</li>
<li>多级继承:从超类A继承的派生类A1,和从B类继承的B2</li>
<li>层次继承:从一个超类可以继承任意数量的子类。</li>
<li>多重继承:派生类继承自多个超类。<h3 id="11-Python中的多态是什么?"><a href="#11-Python中的多态是什么?" class="headerlink" title="11. Python中的多态是什么?"></a>11. <a name="11">Python中的多态是什么?</a></h3>多态是指采取多种形式的能力。<br>因此,例如,如果父类具有一个名为ABC的方法,那么子类也可以具有一个具有相同名称和参数的ABC方法。<br>Python允许多态。</li>
</ol>
<h3 id="12-解释range()和xrange()之间的区别"><a href="#12-解释range()和xrange()之间的区别" class="headerlink" title="12. 解释range()和xrange()之间的区别"></a>12. <a name="12">解释range()和xrange()之间的区别</a></h3><p>在大多数情况下,xrange和range在功能方面完全相同。<br>它们都提供了一种生成整数列表供您使用的方法。<br>唯一的区别是range返回一个Python列表对象,而xrange返回一个xrange对象。<br>这意味着xrange实际上不会像range那样在运行时生成静态列表。<br>它通过一种称为yield的特殊技术根据需要创建值。<br>该技术与一种称为生成器的对象一起使用。</p>
<h3 id="13-解释Flask和Django之间的区别"><a href="#13-解释Flask和Django之间的区别" class="headerlink" title="13. 解释Flask和Django之间的区别"></a>13. <a name="13">解释Flask和Django之间的区别</a></h3><p><strong>Django</strong>是一个Python网络框架,提供了一个开放源代码的高级框架,“鼓励快速开发和简洁实用的设计”。<br>快速,安全且可扩展。Django提供了强大的社区支持和详细的文档。</br><br>该框架是一个包容性软件包,在您创建应用程序时,您将在其中获得管理面板,数据库界面和目录结构。<br>此外,它包括许多功能,因此您不必添加单独的库和依赖项。<br>它提供的一些功能包括用户身份验证,模板引擎,路由,数据库模式迁移等等。</br><br>Django框架非常灵活,您可以在其中与大型公司的MVP一起使用。<br>从某些角度来看,使用Django的一些最大的公司是Instagram,Dropbox,Pinterest和Spotify。</br></p>
<hr>
<p><strong>Flask</strong>被认为是一个微框架,是一个简约的Web框架。<br>它电量较低,这意味着它缺少Django等全栈框架提供的许多功能,例如网络模板引擎,帐户授权和身份验证。</br><br>Flask极简且轻巧,这意味着您可以在编写代码时添加所需的扩展和库,而不会被框架自动提供。<br>Flask背后的理念是,它仅提供构建应用程序所需的组件,因此您具有灵活性和控制力。<br>换句话说,它是不受限制的。<br>它提供的一些功能包括:一个内置int开发服务器,Restful请求分派,Http请求处理等等。</p>
<h3 id="14-什么是PYTHONPATH?"><a href="#14-什么是PYTHONPATH?" class="headerlink" title="14. 什么是PYTHONPATH?"></a>14. <a name="14">什么是PYTHONPATH?</a></h3><p>它是环境变量,在导入模块时使用。<br>每当导入模块时,都会查找PYTHONPATH以检查各个目录中是否存在导入的模块。<br>解释器使用它来确定要加载哪个模块。</p>
<h3 id="15-什么是PEP8?"><a href="#15-什么是PEP8?" class="headerlink" title="15. 什么是PEP8?"></a>15. <a name="15">什么是PEP8?</a></h3><p>PEP代表Python增强提案。<br>这是一组规则,用于指定如何格式化Python代码以实现最大的可读性。</p>
<h3 id="16-什么是Python装饰器?"><a href="#16-什么是Python装饰器?" class="headerlink" title="16. 什么是Python装饰器?"></a>16. <a name="16">什么是Python装饰器?</a></h3><p>装饰器是Python中的一种设计模式,允许用户在不修改其结构的情况下向现有对象添加新功能。<br>装饰器通常在要装饰的函数定义之前调用。</p>
<h3 id="17-什么是初始化init"><a href="#17-什么是初始化init" class="headerlink" title="17. 什么是初始化init"></a>17. <a name="17">什么是初始化init</a></h3><p>_init__是Python中的方法或构造函数。<br>创建类的新对象/实例时,将自动调用此方法以分配内存。<br>所有类都具有<strong>init</strong>方法。</p>
<h3 id="18-什么是三元运算符?"><a href="#18-什么是三元运算符?" class="headerlink" title="18. 什么是三元运算符?"></a>18. <a name="18">什么是三元运算符?</a></h3><p>三元运算符是用Python编写条件语句的一种方式。<br>顾名思义,此Python运算符由三个操作数组成。</p>
<blockquote>
<p>注意:三元运算符可以看作是if-else语句的简化的单行版本,用于测试条件。 </p>
</blockquote>
<h4 id="语法:"><a href="#语法:" class="headerlink" title="语法:"></a>语法:</h4><p>三元表达式包含三个操作式:</p>
<ol>
<li>条件语句:一个布尔表达式,其值为true或false</li>
<li><strong>true_val</strong>:如果表达式的计算结果为true,则将分配一个值。</li>
<li><strong>false_val</strong>: 如果表达式的结果为false,则分配一个值。<figure class="highlight ini"><table><tr><td class="code"><pre><code class="hljs ini"><span class="hljs-attr">var</span> = <span class="hljs-literal">true</span>_val if condition else <span class="hljs-literal">false</span>_val<br></code></pre></td></tr></table></figure>
</li>
</ol>
<h3 id="19-Python中的全局变量和局部变量是什么?"><a href="#19-Python中的全局变量和局部变量是什么?" class="headerlink" title="19. Python中的全局变量和局部变量是什么?"></a>19. <a name="19">Python中的全局变量和局部变量是什么?</a></h3><h4 id="全局变量"><a href="#全局变量" class="headerlink" title="全局变量"></a>全局变量</h4><p>在函数外部或全局空间中声明的变量称为全局变量。<br>程序中的任何函数都可以访问这些变量。</p>
<h4 id="局部变量"><a href="#局部变量" class="headerlink" title="局部变量"></a>局部变量</h4><p>在函数内部声明的任何变量都称为局部变量。<br>此变量存在于局部空间而不是全局空间中。</p>
<h3 id="20-Python中的-property是什么?"><a href="#20-Python中的-property是什么?" class="headerlink" title="20. Python中的@property是什么?"></a>20. <a name="20">Python中的@property是什么?</a></h3><p>@property是一个装饰器。<br>在Python中,装饰器使用户能够以相同的方式使用该类(而不管对其属性或方法所做的更改)。<br>@property装饰器允许像属性一样访问函数。</p>
<h3 id="21-在Python中如何使用try-except?"><a href="#21-在Python中如何使用try-except?" class="headerlink" title="21. 在Python中如何使用try/except?"></a>21. <a name="21">在Python中如何使用try/except?</a></h3><p>异常是程序执行时发生的错误。<br>发生错误时,程序将停止并生成异常,捕捉异常然后对其进行处理,以防止程序崩溃。</br><br>程序生成的异常在try块中捕获,并在except块中处理。</p>
<h3 id="22-解释Python-2和Python-3之间的区别"><a href="#22-解释Python-2和Python-3之间的区别" class="headerlink" title="22. 解释Python 2和Python 3之间的区别"></a>22. <a name="22">解释Python 2和Python 3之间的区别</a></h3><table>
<thead>
<tr>
<th>Python2</th>
<th>Python3</th>
</tr>
</thead>
<tbody><tr>
<td>字符串编码</br>Python 2将它们存储为ASCII。</br>Unicode是ASCII的超集,因此可以编码更多字符,包括外来字符。</td>
<td>字符串编码</br>Python 3默认将字符串存储为Unicode。</td>
</tr>
<tr>
<td>Python 2除法将floor函数应用于十进制输出并返回整数。</br>因此,将5除以2将返回floor(2.5)= 2。</td>
<td>Python 3中的除法返回期望的输出,即使它是十进制的。</td>
</tr>
<tr>
<td>Python 2打印不需要括号。</td>
<td>Python3需要在要打印的内容周围加上括号。</td>
</tr>
<tr>
<td>许多较旧的库是专门为Python 2构建的,并不“向上兼容”。</td>
<td>一些较新的库是专门为Python 3构建的,不适用于Python 2。</td>
</tr>
</tbody></table>
<h3 id="23-python中的join方法是什么?"><a href="#23-python中的join方法是什么?" class="headerlink" title="23. python中的join方法是什么?"></a>23. <a name="23">python中的join方法是什么?</a></h3><p>Python中的<strong>join</strong>方法采用可迭代数据结构的元素,并使用特定的字符串连接器值将它们连接在一起。 </p>
<h4 id="join是如何工作的?"><a href="#join是如何工作的?" class="headerlink" title="join是如何工作的?"></a>join是如何工作的?</h4><p>Python中的join方法是一个字符串方法,它通过使用特定的字符串作为连接器来连接字符串可迭代结构的元素,该结构还包含字符串或字符(数组,列表等)。<br><img src="http://imgs.yrzdm.com/imgs/20200618/r9WYoIj9YMNi.png?imageslim" alt="mark"></p>
<h3 id="24-什么是字典?"><a href="#24-什么是字典?" class="headerlink" title="24. 什么是字典?"></a>24. <a name="24">什么是字典?</a></h3><p>字典表达式是在Python中创建字典的一种方法。<br>它通过合并以列表或数组形式的两组数据来创建字典。<br>两个列表/数组之一的数据将作为字典的键,而第二个列表/数组的数据将作为值。<br>每个键充当每个值的唯一标识符,因此两个列表/数组的大小应相同。</p>
<figure class="highlight q"><table><tr><td class="code"><pre><code class="hljs q">NewDictionary = {<span class="hljs-built_in">key</span>:<span class="hljs-built_in">value</span> for (<span class="hljs-built_in">key</span>,<span class="hljs-built_in">value</span>) in iterable}<br></code></pre></td></tr></table></figure>
<h3 id="25-您将如何在Python中进行深层复制?"><a href="#25-您将如何在Python中进行深层复制?" class="headerlink" title="25. 您将如何在Python中进行深层复制?"></a>25. <a name="25">您将如何在Python中进行深层复制?</a></h3><p>深拷贝是指克隆对象。<br>当使用=运算符时,我们不克隆对象;<br>相反,我们将变量引用到相同的对象(也称为浅表副本)。</br><br>这意味着更改一个变量的值会影响另一个变量的值,因为它们引用(或指向)同一对象。<br>浅表副本与深表副本之间的区别仅适用于包含其他对象的对象,例如列表和类的实例。</p>
<h4 id="方法"><a href="#方法" class="headerlink" title="方法"></a>方法</h4><p>此函数将要克隆的对象作为唯一参数,并返回克隆。</p>
<h4 id="语法"><a href="#语法" class="headerlink" title="语法"></a>语法</h4><p>此函数将要克隆的对象作为唯一参数,并返回克隆。</p>
<figure class="highlight dockerfile"><table><tr><td class="code"><pre><code class="hljs dockerfile">a = <span class="hljs-keyword">copy</span>.<span class="bash">deepcopy(b)</span><br></code></pre></td></tr></table></figure>
<p><img src="http://imgs.yrzdm.com/imgs/20200618/Uu3AGRXfl04X.png?imageslim" alt="mark"></p>
<figure class="highlight angelscript"><table><tr><td class="code"><pre><code class="hljs angelscript"><span class="hljs-keyword">import</span> copy<br>x = [<span class="hljs-number">1</span>,<span class="hljs-number">2</span>,<span class="hljs-number">3</span>]<br>y = x<br>x[<span class="hljs-number">0</span>] = <span class="hljs-number">5</span><br>x[<span class="hljs-number">1</span>] = <span class="hljs-number">15</span><br>print(<span class="hljs-string">"shallow copy:"</span>,y)<br>a = [<span class="hljs-number">10</span>,<span class="hljs-number">20</span>,<span class="hljs-number">30</span>]<br>b = copy.deepcopy(a)<br>a[<span class="hljs-number">1</span>] = <span class="hljs-number">70</span><br>print(<span class="hljs-string">"deep copy:"</span>,b)<br>Output:<br>shallow copy:[<span class="hljs-number">5</span>,<span class="hljs-number">15</span>,<span class="hljs-number">3</span>]<br>deep copy:[<span class="hljs-number">10</span>,<span class="hljs-number">20</span>,<span class="hljs-number">30</span>]<br></code></pre></td></tr></table></figure>
<h3 id="26-如何检查Python字典中是否存在键?"><a href="#26-如何检查Python字典中是否存在键?" class="headerlink" title="26. 如何检查Python字典中是否存在键?"></a>26. <a name="26">如何检查Python字典中是否存在键?</a></h3><p>一种安全的做法是在提取该键的值之前检查该键是否在字典中存在。<br>为此,Python提供了两个内置函数:<br><code>has_key()</code><br>如果字典中有给定的键,则<code>has_key</code>方法返回<code>true</code>;否则,返回<code>true</code>。<br>否则,它返回<code>false</code>。<br><code>if-in</code>表达式<br>此方法使用<code>if-in</code>语句检查字典中是否存在给定键。</p>
<figure class="highlight routeros"><table><tr><td class="code"><pre><code class="hljs routeros">Fruits = [<span class="hljs-string">'a'</span>:<span class="hljs-string">"apple"</span>,<span class="hljs-string">'b'</span>:<span class="hljs-string">"banana"</span>,<span class="hljs-string">'c'</span>:<span class="hljs-string">"carrot"</span>]<br>key_to_lookup = <span class="hljs-string">'a'</span><br><span class="hljs-keyword">if</span> key_to_lookup <span class="hljs-keyword">in</span> Fruits:<br> <span class="hljs-builtin-name">print</span>(<span class="hljs-string">"exists"</span>)<br><span class="hljs-keyword">else</span>:<br> <span class="hljs-builtin-name">print</span>(<span class="hljs-string">"does not exists"</span>)<br></code></pre></td></tr></table></figure>
<h3 id="27-您将如何在Python中实现记忆化?"><a href="#27-您将如何在Python中实现记忆化?" class="headerlink" title="27. 您将如何在Python中实现记忆化?"></a>27. <a name="27">您将如何在Python中实现记忆化?</a></h3><h4 id="对于计算量比较大的代码:"><a href="#对于计算量比较大的代码:" class="headerlink" title="对于计算量比较大的代码:"></a>对于计算量比较大的代码:</h4><figure class="highlight maxima"><table><tr><td class="code"><pre><code class="hljs maxima">#Fibonacci Numbers<br>def <span class="hljs-built_in">fib</span>(<span class="hljs-built_in">num</span>):<br> <span class="hljs-keyword">if</span> <span class="hljs-built_in">num</span> == <span class="hljs-number">0</span>:<br> <span class="hljs-built_in">return</span> <span class="hljs-number">0</span><br> elif <span class="hljs-built_in">num</span> == <span class="hljs-number">1</span>:<br> <span class="hljs-built_in">return</span> <span class="hljs-number">1</span><br> <span class="hljs-built_in">return</span> <span class="hljs-built_in">fib</span>(<span class="hljs-built_in">num</span> - <span class="hljs-number">1</span>) + <span class="hljs-built_in">fib</span>(n-<span class="hljs-number">1</span>)<br></code></pre></td></tr></table></figure>
<p>记忆化可以通过Python装饰器实现<br>这是完整的实现。</p>
<figure class="highlight sql"><table><tr><td class="code"><pre><code class="hljs sql">import timeit<br><br>def memoize_fib(func):<br> <span class="hljs-keyword">cache</span> = {}<br> <span class="hljs-keyword">def</span> <span class="hljs-keyword">inner</span>(arg):<br> <span class="hljs-keyword">if</span> arg <span class="hljs-keyword">not</span> <span class="hljs-keyword">in</span> <span class="hljs-keyword">cache</span>: <br> <span class="hljs-keyword">cache</span>[arg] = func(arg)<br> <span class="hljs-keyword">return</span> <span class="hljs-keyword">cache</span>[arg]<br> <span class="hljs-keyword">return</span> <span class="hljs-keyword">inner</span><br><br><br><span class="hljs-keyword">def</span> fib(<span class="hljs-keyword">num</span>):<br> <span class="hljs-keyword">if</span> <span class="hljs-keyword">num</span> == <span class="hljs-number">0</span>:<br> <span class="hljs-keyword">return</span> <span class="hljs-number">0</span><br> elif <span class="hljs-keyword">num</span> == <span class="hljs-number">1</span>:<br> <span class="hljs-keyword">return</span> <span class="hljs-number">1</span><br> <span class="hljs-keyword">else</span>:<br> <span class="hljs-keyword">return</span> fib(<span class="hljs-keyword">num</span><span class="hljs-number">-1</span>) + fib(<span class="hljs-keyword">num</span><span class="hljs-number">-2</span>)<br><br>fib = memoize_fib(fib)<br><br><br>print(timeit.timeit(<span class="hljs-string">'fib(30)'</span>, globals=globals(), <span class="hljs-built_in">number</span>=<span class="hljs-number">1</span>))<br>print(timeit.timeit(<span class="hljs-string">'fib(30)'</span>, globals=globals(), <span class="hljs-built_in">number</span>=<span class="hljs-number">1</span>))<br>print(timeit.timeit(<span class="hljs-string">'fib(30)'</span>, globals=globals(), <span class="hljs-built_in">number</span>=<span class="hljs-number">1</span>))<br></code></pre></td></tr></table></figure>
<h3 id="28-您将如何在Python中对字典进行排序?"><a href="#28-您将如何在Python中对字典进行排序?" class="headerlink" title="28. 您将如何在Python中对字典进行排序?"></a>28. <a name="28">您将如何在Python中对字典进行排序?</a></h3><p>我们可以通过键或值对这种类型的数据进行排序,这可以通过使用sorted()函数来完成。<br>首先,我们需要知道如何从字典中检索数据以传递给该函数。 </p>
<p>有两种从字典中获取数据的基本方法: </p>
<ul>
<li>Dictionary.keys():仅以任意顺序返回键。</li>
<li>Dictionary.values():返回值列表。</li>
<li>Dictionary.items():返回所有数据作为键值对列表。<h4 id="Sorted()语法"><a href="#Sorted()语法" class="headerlink" title="Sorted()语法"></a>Sorted()语法</h4>此方法采用一个强制性参数和两个可选参数: </li>
</ul>
<p><strong>数据(必填)</strong>:要排序的数据。<br>我们将使用上述方法之一传递我们检索到的数据。<br><strong>键(可选)</strong>:我们要根据其对列表进行排序的功能(或条件)。<br>例如,条件可以是根据字符串的长度或任何其他任意函数对字符串进行排序。<br>此功能应用于列表的每个元素,并对结果数据进行排序。<br>将其保留为空将根据其原始值对列表进行排序。<br><strong>反向(可选)</strong>:将第三个参数设置为true将按降序对列表进行排序。<br>保留此空的升序排列。<br><code>keys()</code> </p>
<figure class="highlight perl"><table><tr><td class="code"><pre><code class="hljs perl">dict = {}<br>dict[<span class="hljs-string">'1'</span>] = <span class="hljs-string">'apple'</span><br>dict[<span class="hljs-string">'3'</span>] = <span class="hljs-string">'orange'</span><br>dict[<span class="hljs-string">'2'</span>] = <span class="hljs-string">'pango'</span><br><br>lst = dict.keys()<br><br><span class="hljs-comment"># Sorted by key</span><br><span class="hljs-keyword">print</span>(<span class="hljs-string">"Sorted by key: "</span>, sorted(lst))<br><span class="hljs-string">``</span><span class="hljs-string">` <br>`</span><span class="hljs-keyword">values</span>()<span class="hljs-string">`</span><br></code></pre></td></tr></table></figure>
<p>dict = {}<br>dict[‘1’] = ‘apple’<br>dict[‘3’] = ‘orange’<br>dict[‘2’] = ‘pango’</p>
<p>lst = dict.values()</p>
<p>#Sorted by value<br>print(“Sorted by value: “, sorted(lst))</p>
<figure class="highlight arcade"><table><tr><td class="code"><pre><code class="hljs arcade"><span class="hljs-string">`items()`</span><br></code></pre></td></tr></table></figure>
<p>dict = {}<br>dict[‘1’] = ‘apple’<br>dict[‘3’] = ‘orange’<br>dict[‘2’] = ‘strawberry’</p>
<p>lst = dict.items()</p>
<h1 id="Sorted-by-key"><a href="#Sorted-by-key" class="headerlink" title="Sorted by key"></a>Sorted by key</h1><p>print(“Sorted by key: “, sorted(lst, key = lambda x : x[0]))</p>
<p>#Sorted by value<br>print(“Sorted by value: “, sorted(lst, key = lambda x : x[1]))</p>
<figure class="highlight autohotkey"><table><tr><td class="code"><pre><code class="hljs autohotkey"><br>### <span class="hljs-number">29</span>. <a name=<span class="hljs-string">"29"</span>>您将如何以及何时使用any()和all()?</a><br>#### 什么是`any()`?<br>`any()`是一个函数,它接受一个可迭代的函数(例如列表,元组,集合等),并且如果任何元素的值为真,则返回`True`,但如果所有元素的值为`False`,则返回`False`。 <br>可以通过以下方式将`iterable`传递给`any()``,以检查是否有任何元素为`True`:<br></code></pre></td></tr></table></figure>
<p>one_truth = [True, False, False]<br>three_lies = [0, ‘’, None]<br>print(any(one_truth))<br>print(any(three_lies))</p>
<figure class="highlight autohotkey"><table><tr><td class="code"><pre><code class="hljs autohotkey">#### 什么是`all()`?<br>`all()`是另一个Python函数,该函数具有一个可迭代的函数,如果所有元素的评估结果均为`True`,则返回`True`,否则返回`False`。 <br>与`any()`类似,`all()`接受列表,元组,集合或任何可迭代的对象,如下所示:<br></code></pre></td></tr></table></figure>
<p>all_true = [True, 1, ‘a’, object()]<br>one_true = [True, False, False, 0]<br>all_false = [None, ‘’, False, 0]<br>print(all(all_true))<br>print(all(one_true))<br>print(all(all_false))</p>
<figure class="highlight markdown"><table><tr><td class="code"><pre><code class="hljs markdown"><span class="hljs-section">### 30. <a name="30">什么是Python文档字符串?</a></span><br>Python文档字符串提供了一种将文档与以下内容相关联的合适方法: <br><span class="hljs-bullet">- </span>Python模块<br><span class="hljs-bullet">- </span>Python函数<br><span class="hljs-bullet">- </span>Python类 <br>这是书面代码的指定文件。<br>与常规代码注释不同,篡改应描述函数的功能,而不是功能的作用。 <br>可以使用以下命令访问文档字符串 <br><span class="hljs-code">`__doc__`</span>对象的方法 <br><span class="hljs-code">`help`</span>函数<br></code></pre></td></tr></table></figure>
<p>def Examplefunc(str): #function that outputs the str parameter<br> print(“The value is”, str)<br> #no return statement needed in this function</p>
<p>def Multiply(x,y): #function that computes the product of x and y<br> return x*y #returning the product of x and y</p>
<p>#Calling the functions<br>Examplefunc(9) #9 passed as the parameter)<br>answer = Multiply(4,2) #4 and 2 passed as the parameters<br>print(“The product of x and y is:”,answer)</p>
<figure class="highlight gherkin"><table><tr><td class="code"><pre><code class="hljs gherkin"><span class="hljs-comment">### 32. <a name="32">解释Python中生成器和迭代器之间的区别。</a></span><br>Python中的迭代器充当对象的持有者,以便可以对其进行迭代;<br>生成器有助于创建自定义迭代器。 <br><br>除了明显的语法差异外,还有一些值得注意的差异:<br>|<span class="hljs-string"> Generator </span>|<span class="hljs-string"> Iterator </span>|<br>|<span class="hljs-string"> --- </span>|<span class="hljs-string"> --- </span>|<br>|<span class="hljs-string"> 使用函数实现 </span>|<span class="hljs-string"> 使用类实现 </span>|<br>|<span class="hljs-string"> 使用`yield`关键字 </span>|<span class="hljs-string"> 不使用`yield`关键字 </span>|<br>|<span class="hljs-string"> 代码简洁 </span>|<span class="hljs-string"> 代码不简洁 </span>|<br>|<span class="hljs-string"> 存储yield语句之前的所有局部变量。 </span>|<span class="hljs-string"> 没有使用局部变量 </span>|<br><span class="hljs-comment">#### 迭代器的实现</span><br></code></pre></td></tr></table></figure>
<h1 id="Function-to-generate-all-the-non-negative-numbers"><a href="#Function-to-generate-all-the-non-negative-numbers" class="headerlink" title="Function to generate all the non-negative numbers"></a>Function to generate all the non-negative numbers</h1><h1 id="up-to-the-given-non-negative-number"><a href="#up-to-the-given-non-negative-number" class="headerlink" title="up to the given non-negative number."></a>up to the given non-negative number.</h1><p>class UpTo:<br> # giving the parameter a default value of 0<br> def <strong>init</strong>(self, max = 0):<br> self.max = max<br> def <strong>iter</strong>(self):<br> self.n = 0<br> return self<br> def <strong>next</strong>(self):<br> # The next method will throw an<br> # exception when the termination condition is reached.<br> if self.n > self.max:<br> raise StopIteration<br> else:<br> result = self.n<br> self.n += 1<br> return result<br>for number in UpTo(5):<br> print(number)</p>
<figure class="highlight clean"><table><tr><td class="code"><pre><code class="hljs clean">#### 生成器的实现<br></code></pre></td></tr></table></figure>
<h1 id="Function-to-generate-all-the-non-negative-numbers-1"><a href="#Function-to-generate-all-the-non-negative-numbers-1" class="headerlink" title="Function to generate all the non-negative numbers"></a>Function to generate all the non-negative numbers</h1><h1 id="up-to-the-given-non-negative-number-1"><a href="#up-to-the-given-non-negative-number-1" class="headerlink" title="up to the given non-negative number"></a>up to the given non-negative number</h1><p>def upto(n):<br> for i in range(n+1):<br> # The yield statement is what makes a function<br> # a generator<br> yield i<br>for number in upto(5):<br> print(number)</p>
<figure class="highlight autohotkey"><table><tr><td class="code"><pre><code class="hljs autohotkey">### <span class="hljs-number">33</span>. <a name=<span class="hljs-string">"33"</span>>Python中的defaultdict是什么?</a><br>Python字典dict包含单词和含义以及任何数据类型的键值对。<br>`defaultdict`是内置`dict`类的另一个细分。 <br>`defaultdict`可以通过给出其声明来创建,该声明可以具有三个值。<br>列出,设置或诠释。<br>根据指定的数据类型,将创建字典,并且当添加或访问`defaultdict`中不存在的任何键时,将为其分配默认值,而不是给出`KeyError`。 <br>举例: <br>下面的第一个代码段显示了一个简单的字典,以及如何访问dict中不存在的键时如何产生错误。<br></code></pre></td></tr></table></figure>
<p>dict_demo = dict()<br>print(dict_demo[3])</p>
<figure class="highlight autohotkey"><table><tr><td class="code"><pre><code class="hljs autohotkey">现在,让我们介绍一个`defaultdict`,看看会发生什么。<br></code></pre></td></tr></table></figure>
<p>from collections import defaultdict<br>defaultdict_demo = defaultdict(int)<br>print(defaultdict_demo[3])<br>Output: 0</p>
<figure class="highlight clean"><table><tr><td class="code"><pre><code class="hljs clean">在这种情况下,我们将`int`作为数据类型传递给`defaultdict`。<br>因此,将为`defaultdict_demo`中不存在的任何键分配一个值<span class="hljs-number">0</span>,除非为其定义了值。<br>>注意:您也可以将set或list作为参数<br><br>### <span class="hljs-number">34.</span> <a name=<span class="hljs-string">"34"</span>>什么是Python模块?</a><br>Python模块是一个Python文件,其中包含要在应用程序中使用的一组函数和变量。<br>变量可以是任何类型(数组,字典,对象等) <br>模块可以是: <br>- 内建<br>- 用户自定义<br>#### Python模块的好处<br>在Python中创建和使用模块有两个主要好处: <br>##### 结构化代码<br>- 通过将代码分组到一个Python文件中,逻辑上将代码组织起来,这使开发更加容易且不易出错。<br>代码更易于理解和使用。 <br>##### 可重用性<br>- 单个模块中定义的功能可以被应用程序的其他部分轻松地重用。<br>这样就无需重新创建重复的代码。<br>### <span class="hljs-number">35.</span> <a nama=<span class="hljs-string">"35"</span>>如何将列表转换为数组</a><br></code></pre></td></tr></table></figure>
<p>import numpy as np<br>my_list = [2,4,6,8,10]<br>my_array = np.array(my_list)<br>print(my_array)<br>print(type(my_array))<br>[2 4 6 8 10]</p>
<figure class="highlight autohotkey"><table><tr><td class="code"><pre><code class="hljs autohotkey">===<br><br>### <span class="hljs-number">36</span>. <a name=<span class="hljs-string">"36"</span>>反转Python中的字符串</a><br>`stringname[strlength::-<span class="hljs-number">1</span>]` <br>`stringname[::-<span class="hljs-number">1</span>]`<br>### <span class="hljs-number">37</span>. <a name=<span class="hljs-string">"37"</span>>检查Python字符串是否包含另一个字符串</a><br>有两种检查方法。<br>对于本文,我们将研究`find`方法。 <br>`find`方法检查字符串是否包含子字符串。<br>如果是这样,则该方法返回字符串中子字符串的起始索引;否则,返回<span class="hljs-number">0</span>。<br>否则,返回-<span class="hljs-number">1</span>。<br></code></pre></td></tr></table></figure>
<p>string.find(substring)<br>a_string=”Python Programming”<br>substring1=”Programming”<br>substring2=”Language”<br>print(“Check if “+a_string+” contains “+substring1+”:”)<br>print(a_string.find(substring1))<br>print(“Check if “+a_string+” contains “+substring2+”:”)<br>print(a_string.find(substring2))</p>
<figure class="highlight markdown"><table><tr><td class="code"><pre><code class="hljs markdown">检查字符串是否包含另一个字符串的其他两种值得注意的方法是在操作符中使用<span class="hljs-code">`in`</span>或使用<span class="hljs-code">`count`</span>方法。<br><span class="hljs-section">### 38. <a name="38">在Python中实施广度优先搜索(BFS)</a></span><br>考虑以下代码中实现的图:<br><br></code></pre></td></tr></table></figure>
<p>graph = {<br> ‘A’ : [‘B’,’C’],<br> ‘B’ : [‘D’, ‘E’],<br> ‘C’ : [‘F’],<br> ‘D’ : [],<br> ‘E’ : [‘F’],<br> ‘F’ : []<br>}</p>
<p>visited = [] # List to keep track of visited nodes.<br>queue = [] #Initialize a queue</p>
<p>def bfs(visited, graph, node):<br> visited.append(node)<br> queue.append(node)</p>
<p> while queue:<br> s = queue.pop(0)<br> print (s, end = “ “) </p>
<pre><code>for neighbour in graph[s]:
if neighbour not in visited:
visited.append(neighbour)
queue.append(neighbour)</code></pre><h1 id="Driver-Code"><a href="#Driver-Code" class="headerlink" title="Driver Code"></a>Driver Code</h1><p>bfs(visited, graph, ‘A’)<br>Output: A B C D E</p>
<figure class="highlight markdown"><table><tr><td class="code"><pre><code class="hljs markdown"><span class="hljs-bullet">- </span>第3-10行:图示的图表使用邻接表表示。 <br>在Python中执行此操作的一种简单方法是使用字典数据结构,其中每个顶点都有其相邻节点的存储列表。<br><span class="hljs-bullet">- </span>第12行:受访者是用于跟踪受访节点的列表。<br><span class="hljs-bullet">- </span>第13行:queue是一个列表,用于跟踪队列中当前的节点。<br><span class="hljs-bullet">- </span>第29行:bfs函数的参数是访问列表,字典形式的图形和起始节点A。<br><span class="hljs-bullet">- </span>第15-26行:bfs遵循上述算法:<br>它检查起始节点并将其附加到访问列表和队列中。<br>然后,当队列包含元素时,它将继续从队列中取出节点,如果未访问该节点的邻居,则将该节点的邻居添加到队列中,并将其标记为已访问。<br>这一直持续到队列为空。<br><span class="hljs-section">##### 时间复杂度</span><br>由于访问了所有的节点和顶点,因此图上BFS的时间复杂度为O(V + E);<br>其中V是顶点数,E是边数。<br><span class="hljs-section">### 39. <a name="39">在Python中实施深度优先搜索(DFS)</a></span><br>考虑下面的代码,该代码在以下代码中实现:<br><br></code></pre></td></tr></table></figure>
<h1 id="Using-a-Python-dictionary-to-act-as-an-adjacency-list"><a href="#Using-a-Python-dictionary-to-act-as-an-adjacency-list" class="headerlink" title="Using a Python dictionary to act as an adjacency list"></a>Using a Python dictionary to act as an adjacency list</h1><p>graph = {<br> ‘A’ : [‘B’,’C’],<br> ‘B’ : [‘D’, ‘E’],<br> ‘C’ : [‘F’],<br> ‘D’ : [],<br> ‘E’ : [‘F’],<br> ‘F’ : []<br>}<br>visited = set() # Set to keep track of visited nodes.<br>def dfs(visited, graph, node):<br> if node not in visited:<br> print (node)<br> visited.add(node)<br> for neighbour in graph[node]:<br> dfs(visited, graph, neighbour)</p>
<h1 id="Driver-Code-1"><a href="#Driver-Code-1" class="headerlink" title="Driver Code"></a>Driver Code</h1><p>dfs(visited, graph, ‘A’)<br>Output: A B D E F C</p>
<figure class="highlight markdown"><table><tr><td class="code"><pre><code class="hljs markdown"><span class="hljs-bullet">- </span>第2-9行:使用邻接表表示图示的图形-在Python中执行此操作的一种简单方法是使用字典数据结构。<br>每个顶点都有一个存储其相邻节点的列表。<br><span class="hljs-bullet">- </span>第11行:受访者集,用于跟踪受访节点。<br><span class="hljs-bullet">- </span>第21行:调用dfs函数并将其传递给被访问的集合,字典形式的图形以及作为起始节点的A。<br><span class="hljs-bullet">- </span>第13-18行:dfs遵循上述算法:<br><span class="hljs-bullet">1. </span>它首先检查当前节点是否未访问-如果是,则将其附加到已访问集合中。<br><span class="hljs-bullet">2. </span>然后,对于当前节点的每个邻居,再次调用dfs函数。<br><span class="hljs-bullet">3. </span>当访问所有节点时,将调用基本情况。<br>然后函数返回。<br><span class="hljs-section">##### 时间复杂度</span><br>由于访问了所有节点和顶点,因此图上DFS的平均时间复杂度为O(V + E),其中V是顶点数,E是边数。<br>对于树上的DFS,时间复杂度为O(V),其中V是节点数。<br><span class="hljs-section">### 40. <a name="40">在Python中实现通配符</a></span><br>在Python中,您可以使用regex(正则表达式)库实现通配符。 <br>dot <span class="hljs-code">`.`</span>字符代替问号<span class="hljs-code">`?`</span>符号。<br>因此,要搜索与颜色模式匹配的所有单词,代码将如下所示。<br></code></pre></td></tr></table></figure>
<h1 id="Regular-expression-library"><a href="#Regular-expression-library" class="headerlink" title="Regular expression library"></a>Regular expression library</h1><p>import re</p>
<h1 id="Add-or-remove-the-words-in-this-list-to-vary-the-results"><a href="#Add-or-remove-the-words-in-this-list-to-vary-the-results" class="headerlink" title="Add or remove the words in this list to vary the results"></a>Add or remove the words in this list to vary the results</h1><p>wordlist = [“color”, “colour”, “work”, “working”,<br> “fox”, “worker”, “working”]</p>
<p>for word in wordlist:<br> # The . symbol is used in place of ? symbol<br> if re.search(‘col.r’, word) :<br> print (word)<br>Output:color</p>
<figure class="highlight clean"><table><tr><td class="code"><pre><code class="hljs clean">### <span class="hljs-number">41.</span> <a name=<span class="hljs-string">"41"</span>>在Python中实施合并排序</a><br></code></pre></td></tr></table></figure>
<p>def mergeSort(myList):<br> if len(myList) > 1:<br> mid = len(myList) // 2<br> left = myList[:mid]<br> right = myList[mid:]</p>
<pre><code># Recursive call on each half
mergeSort(left)
mergeSort(right)
# Two iterators for traversing the two halves
i = 0
j = 0
# Iterator for the main list
k = 0
while i < len(left) and j < len(right):
if left[i] < right[j]:
# The value from the left half has been used
myList[k] = left[i]
# Move the iterator forward
i += 1
else:
myList[k] = right[j]
j += 1
# Move to the next slot
k += 1
# For all the remaining values
while i < len(left):
myList[k] = left[i]
i += 1
k += 1
while j < len(right):
myList[k]=right[j]
j += 1
k += 1</code></pre><p>myList = [54,26,93,17,77,31,44,55,20]<br>mergeSort(myList)<br>print(myList)<br>Output: [17, 20, 26, 31, 44, 54, 55, 77, 93]</p>
<figure class="highlight clean"><table><tr><td class="code"><pre><code class="hljs clean">##### 说明<br>这是用于实现合并排序的递归方法。<br>通过此方法获得排序数组所需的步骤可以在下面找到:<br><span class="hljs-number">1.</span> 在每个递归调用中,该列表分为左右两部分,直到获得两个相邻元素为止。<br><span class="hljs-number">2.</span> 现在开始排序过程。<br>i和j迭代器遍历每个调用中的两个部分。<br>k迭代器遍历整个列表并在此过程中进行更改。<br><span class="hljs-number">3.</span> 如果i处的值小于j处的值,则将left [i]分配给myList [k]插槽,并递增i。<br>如果不是,则选择right [j]。<br><span class="hljs-number">4.</span> 这样,通过k分配的值将全部排序。<br><span class="hljs-number">5.</span> 在此循环结束时,可能没有完全遍历一半。<br>它的值仅分配给列表中的其余插槽。<br>##### 时间复杂度<br>该算法在O(n.logn)中起作用。<br>这是因为列表在log(n)个调用中被拆分,并且合并过程在每个调用中花费线性时间。<br>### <span class="hljs-number">42.</span> <a name=<span class="hljs-string">"42"</span>>在Python中实现Dijkstra的算法</a><br>##### 基本算法<br><span class="hljs-number">1.</span> 从每个未访问的顶点中,选择距离最小的顶点并进行访问。<br><span class="hljs-number">2.</span> 更新已访问顶点的每个相邻顶点的距离,该顶点的当前距离大于其总和以及它们之间边缘的权重。<br><span class="hljs-number">3.</span> 重复步骤<span class="hljs-number">1</span>和<span class="hljs-number">2</span>,直到访问了所有顶点。<br></code></pre></td></tr></table></figure>
<p>import sys</p>
<h1 id="Function-to-find-out-which-of-the-unvisited-node"><a href="#Function-to-find-out-which-of-the-unvisited-node" class="headerlink" title="Function to find out which of the unvisited node"></a>Function to find out which of the unvisited node</h1><h1 id="needs-to-be-visited-next"><a href="#needs-to-be-visited-next" class="headerlink" title="needs to be visited next"></a>needs to be visited next</h1><p>def to_be_visited():<br> global visited_and_distance<br> v = -10</p>
<h1 id="Choosing-the-vertex-with-the-minimum-distance"><a href="#Choosing-the-vertex-with-the-minimum-distance" class="headerlink" title="Choosing the vertex with the minimum distance"></a>Choosing the vertex with the minimum distance</h1><p> for index in range(number_of_vertices):<br> if visited_and_distance[index][0] == 0 <br> and (v < 0 or visited_and_distance[index][1] <= <br> visited_and_distance[v][1]):<br> v = index<br> return v</p>
<h1 id="Creating-the-graph-as-an-adjacency-matrix"><a href="#Creating-the-graph-as-an-adjacency-matrix" class="headerlink" title="Creating the graph as an adjacency matrix"></a>Creating the graph as an adjacency matrix</h1><p>vertices = [[0, 1, 1, 0],<br> [0, 0, 1, 0],<br> [0, 0, 0, 1],<br> [0, 0, 0, 0]]<br>edges = [[0, 3, 4, 0],<br> [0, 0, 0.5, 0],<br> [0, 0, 0, 1],<br> [0, 0, 0, 0]]</p>
<p>number_of_vertices = len(vertices[0])</p>
<h1 id="The-first-element-of-the-lists-inside-visited-and-distance"><a href="#The-first-element-of-the-lists-inside-visited-and-distance" class="headerlink" title="The first element of the lists inside visited_and_distance"></a>The first element of the lists inside visited_and_distance</h1><h1 id="denotes-if-the-vertex-has-been-visited"><a href="#denotes-if-the-vertex-has-been-visited" class="headerlink" title="denotes if the vertex has been visited."></a>denotes if the vertex has been visited.</h1><h1 id="The-second-element-of-the-lists-inside-the-visited-and-distance"><a href="#The-second-element-of-the-lists-inside-the-visited-and-distance" class="headerlink" title="The second element of the lists inside the visited_and_distance"></a>The second element of the lists inside the visited_and_distance</h1><h1 id="denotes-the-distance-from-the-source"><a href="#denotes-the-distance-from-the-source" class="headerlink" title="denotes the distance from the source."></a>denotes the distance from the source.</h1><p>visited_and_distance = [[0, 0]]<br>for i in range(number_of_vertices-1):<br> visited_and_distance.append([0, sys.maxsize])</p>
<p>for vertex in range(number_of_vertices):</p>
<h1 id="Finding-the-next-vertex-to-be-visited"><a href="#Finding-the-next-vertex-to-be-visited" class="headerlink" title="Finding the next vertex to be visited."></a>Finding the next vertex to be visited.</h1><p> to_visit = to_be_visited()<br> for neighbor_index in range(number_of_vertices):<br> # Calculating the new distance for all unvisited neighbours<br> # of the chosen vertex.<br> if vertices[to_visit][neighbor_index] == 1 and <br> visited_and_distance[neighbor_index][0] == 0:<br> new_distance = visited_and_distance[to_visit][1] <br> + edges[to_visit][neighbor_index]<br> # Updating the distance of the neighbor if its current distance<br> # is greater than the distance that has just been calculated<br> if visited_and_distance[neighbor_index][1] > new_distance:<br> visited_and_distance[neighbor_index][1] = new_distance<br> # Visiting the vertex found earlier<br> visited_and_distance[to_visit][0] = 1</p>
<p>i = 0 </p>
<h1 id="Printing-out-the-shortest-distance-from-the-source-to-each-vertex"><a href="#Printing-out-the-shortest-distance-from-the-source-to-each-vertex" class="headerlink" title="Printing out the shortest distance from the source to each vertex"></a>Printing out the shortest distance from the source to each vertex</h1><p>for distance in visited_and_distance:<br> print(“The shortest distance of “,chr(ord(‘a’) + i),<br> “ from the source vertex a is:”,distance[1])<br> i = i + 1</p>
<p>Output:<br>The shortest distance of a from the source vertex a is: 0<br>The shortest distance of b from the source vertex a is: 3<br>The shortest distance of c from the source vertex a is: 3.5<br>The shortest distance of d from the source vertex a is: 4.5</p>
<figure class="highlight clean"><table><tr><td class="code"><pre><code class="hljs clean">### <span class="hljs-number">43.</span> <a name=<span class="hljs-string">"43"</span>>合并两个排序列表</a><br></code></pre></td></tr></table></figure>
<h1 id="Merge-list1-and-list2-and-return-resulted-list"><a href="#Merge-list1-and-list2-and-return-resulted-list" class="headerlink" title="Merge list1 and list2 and return resulted list"></a>Merge list1 and list2 and return resulted list</h1><p>def merge_lists(lst1, lst2):<br> index_arr1 = 0<br> index_arr2 = 0<br> index_result = 0<br> result = []</p>
<pre><code>for i in range(len(lst1)+len(lst2)):
result.append(i)
# Traverse Both lists and insert smaller value from arr1 or arr2
# into result list and then increment that lists index.
# If a list is completely traversed, while other one is left then just
# copy all the remaining elements into result list
while (index_arr1 < len(lst1)) and (index_arr2 < len(lst2)):
if (lst1[index_arr1] < lst2[index_arr2]):
result[index_result] = lst1[index_arr1]
index_result += 1
index_arr1 += 1
else:
result[index_result] = lst2[index_arr2]
index_result += 1
index_arr2 += 1
while (index_arr1 < len(lst1)):
result[index_result] = lst1[index_arr1]
index_result += 1
index_arr1 += 1
while (index_arr2 < len(lst2)):
result[index_result] = lst2[index_arr2]
index_result += 1
index_arr2 += 1
return result</code></pre><p>print(merge_lists([4, 5, 6], [-2, -1, 0, 7]))<br>Output: [-2, -1, 0, 4, 5, 6, 7]</p>
<figure class="highlight clean"><table><tr><td class="code"><pre><code class="hljs clean">上面的解决方案是解决此问题的更直观的方法。<br><span class="hljs-number">1.</span> 首先创建一个新的空列表。<br>该列表将按排序顺序填充两个列表的所有元素,然后返回。<br><span class="hljs-number">2.</span> 然后将三个变量初始化为零以存储每个列表的当前索引。<br><span class="hljs-number">3.</span> 然后在每个列表的当前索引处比较两个给定列表的元素,将较小的列表追加到新列表,然后将该列表的索引增加<span class="hljs-number">1</span>。<br><span class="hljs-number">4.</span> 重复直到到达其中一个列表的末尾,然后将另一个列表追加到合并列表中。<br>##### 时间复杂度<br>此算法的时间复杂度为O(n + m)O(n + m),其中nn和mm是列表的长度。<br>这是因为两个列表都至少迭代了一次。<br>请注意,也可以通过就地合并解决此问题。<br>### <span class="hljs-number">44.</span> <a name=<span class="hljs-string">"44"</span>>查找两个加起来为“ k”的数字</a><br></code></pre></td></tr></table></figure>
<p>def binarySearch(a, item, curr):<br> first = 0<br> last = len(a) - 1<br> found = False<br> index = -1<br> while first <= last and not found:<br> mid = (first + last) // 2<br> if a[mid] == item:<br> index = mid<br> found = True<br> else:<br> if item < a[mid]:<br> last = mid - 1<br> else:<br> first = mid + 1<br> if found:<br> return index<br> else:<br> return -1</p>
<p>def findSum(lst, k):<br> lst.sort()<br> for j in range(len(lst)):<br> # find the difference in list through binary search<br> # return the only if we find an index<br> index = binarySearch(lst, k -lst[j], j)<br> if index is not -1 and index is not j:<br> return [lst[j], k -lst[j]]</p>
<p>print(findSum([1, 5, 3], 2))<br>print(findSum([1, 2, 3, 4], 5))<br>Output:<br>None<br>[1,4]</p>
<figure class="highlight autohotkey"><table><tr><td class="code"><pre><code class="hljs autohotkey">您可以通过首先对列表进行排序来解决此问题。<br>然后,对于列表中的每个元素,使用二进制搜索来查找该元素与预期总和之间的差异。<br>换句话说,如果预期总和为`k`,而排序列表的第一个元素为`a0` <br>我们将进行二进制搜索`a0` <br>重复搜索直到找到一个。<br>您可以根据需要以递归或迭代的方式实现`binarySearch()`函数。<br>##### 时间复杂度<br>由于大多数基于比较的最佳排序函数均采用O(nlogn),因此我们假设Python .sort()函数采用相同的排序方式。<br>此外,由于二进制搜索要花费O(logn)时间来查找单个元素,因此对所有n个元素进行二进制搜索都将花费O(nlogn)时间。<br><br><br>### <span class="hljs-number">45</span>. <a name=<span class="hljs-string">"45"</span>>查找列表中的第一个非重复整数</a><br>在这里,您可以使用Python字典来记录重复次数。<br></code></pre></td></tr></table></figure>
<p>[9,2,3,2,6,6]<br>def findFirstUnique(lst):<br> counts = {} # Creating a dictionary<br> # Initializing dictionary with pairs like (lst[i],(count,order))<br> counts = counts.fromkeys(lst, (0,len(lst)))<br> order = 0<br> for ele in lst:<br> # counts[ele][0] += 1 # Incrementing for every repitition<br> # counts[ele][1] = order<br> counts[ele] = (counts[ele][0]+1 , order)<br> order += 1 # increment order<br> answer = None<br> answer_key = None<br> # filter non-repeating with least order<br> for ele in lst:<br> if (counts[ele][0] is 1) and (answer is None):<br> answer = counts[ele]<br> answer_key = ele<br> elif answer is None:<br> continue<br> elif (counts[ele][0] is 1) and (counts[ele][1] < answer[1]):<br> answer = counts[ele]<br> answer_key = ele<br> return answer_key<br>print(findFirstUnique([1, 1, 1, 2]))<br>Output: 2</p>
<figure class="highlight clean"><table><tr><td class="code"><pre><code class="hljs clean">counts字典中的键是给定列表的元素,值是每个元素出现在列表中的次数。<br>我们返回在第<span class="hljs-number">23</span>行的列表中最多出现一次的元素。我们需要保持元组值中每个键的更新顺序。<br>##### 时间复杂度<br>由于该列表仅被迭代两次,并且使用线性时间复杂度来初始化计数字典,因此该解决方案的时间复杂度是线性的,即O(n)。<br><br>### <span class="hljs-number">46.</span> <a name=<span class="hljs-string">"46"</span>>查找链接列表的中间值</a><br>在这里,您可以使用两个可以同时工作的指针。<br>这样想:<br>- 快速指针一次移动两步,直到列表结尾<br>- 慢速指针一次移动一步<br>- 当快速指针到达末尾时,慢速指针将在中间<br>使用此算法,由于长度和遍历直到中间的遍历的计算是并行进行的,因此可以使过程更快。 <br>##### 时间复杂度<br>您以两倍的速度遍历链表,因此它肯定更快。<br>但是,瓶颈复杂度仍然是O(n)。<br>### <span class="hljs-number">47.</span> <a name=<span class="hljs-string">"47"</span>>反转队列的第一个“ k”元素</a><br>##### 说明<br>检查输入是否无效,即队列是否为空,`k`是否大于队列,以及在队列`k`是否为负 <br>如果输入有效,则从创建堆栈开始。 <br>可用的堆栈功能有:<br>- 构造函数:myStack()<br>- 推送元素:push(int)将元素添加到堆栈中。<br>- 弹出元素:pop()从堆栈中删除或弹出顶部元素。<br>- 检查是否为空:如果堆栈为空,则isEmpty()返回true,否则返回false。<br>- 返回:back()返回在末尾添加的元素,而不将其从堆栈中删除。<br>- 返回front:front()返回顶部元素(已在开头添加),而不将其从堆栈中删除。 <br>我们的函数`reverseK(queue,k)`将queue作为输入参数。<br>`k`表示我们要反转的元素数。 <br>可用的队列功能是:<br>- 构造函数:myQueue(size)size应该是一个整数,指定队列的大小。<br>- 入队:enqueue(int)<br>- 出队:dequeue()<br>- 检查是否为空:isEmpty()<br>- 检查尺寸:size()<br>现在,继续进行实际的逻辑,从队列的前面使前`k`个元素出队,并使用第<span class="hljs-number">8</span>行中的`stack.push(queue.dequeue())`将它们推入我们先前创建的堆栈中。 <br>将所有`k`个值都压入堆栈后,开始弹出它们并将它们按顺序排入队列的后面。<br>我们将在第<span class="hljs-number">12</span>行中使用`queue.enqueue(stack.pop())`进行此操作。在此步骤的最后,我们将得到一个空堆栈,并将`k`个反向元素添加到队列的后面。 <br>现在我们需要将这些反向元素移到队列的最前面。<br>为此,我们在第<span class="hljs-number">16</span>行中使用了`queue.enqueue(queue.dequeue())`。每个元素都首先从背面出队。<br>### <span class="hljs-number">48.</span> <a name=<span class="hljs-string">"48"</span>>查找二叉搜索树(BST)的高度</a><br>在这里,您可以使用递归来找到左侧和右侧子树的高度。<br>##### 说明<br>在这里,如果给定节点为None,则返回<span class="hljs-number">-1</span>。<br>然后,我们在左右子树上调用findHeight()函数,并返回具有更大值加<span class="hljs-number">1</span>的子树。如果给定节点为None,则不返回<span class="hljs-number">0</span>,因为叶节点的高度为<span class="hljs-number">0</span>。 <br>时间复杂度 <br>代码的时间复杂度为O(n)O(n),因为必须遍历整个树的所有节点。<br>### <span class="hljs-number">49.</span> <a name=<span class="hljs-string">"49"</span>>将最大堆转换为最小堆</a><br></code></pre></td></tr></table></figure>
<p>def minHeapify(heap, index):<br> left = index * 2 + 1<br> right = (index * 2) + 2<br> smallest = index<br> # check if left child exists and is less than smallest<br> if len(heap) > left and heap[smallest] > heap[left]:<br> smallest = left<br> # check if right child exists and is less than smallest<br> if len(heap) > right and heap[smallest] > heap[right]:<br> smallest = right<br> # check if current index is not the smallest<br> if smallest != index:<br> # swap current index value with smallest<br> tmp = heap[smallest]<br> heap[smallest] = heap[index]<br> heap[index] = tmp<br> # minHeapify the new node<br> minHeapify(heap, smallest)<br> return heap</p>
<p>def convertMax(maxHeap):<br> # iterate from middle to first element<br> # middle to first indices contain all parent nodes<br> for i in range((len(maxHeap))//2, -1, -1):<br> # call minHeapify on all parent nodes<br> maxHeap = minHeapify(maxHeap, i)<br> return maxHeap</p>
<p>maxHeap = [9, 4, 7, 1, -2, 6, 5]<br>print(convertMax(maxHeap))<br>Output: [-2, 1, 5, 9, 4, 6, 7]</p>
<p>```<br>说明<br>请记住,我们可以将给定的<code>maxHeap</code>视为元素的常规列表,并对其进行重新排序,以使其准确表示最小堆。<br>我们在此解决方案中正是这样做的。<br><code>convertMax()</code>函数通过在每个父节点上调用<code>minHeapify()</code>函数来从最低父节点还原所有节点上的堆属性。<br>时间复杂度<br><code>minHeapify()</code>函数被调用堆中一半的节点。<br><code>minHeapify()</code>函数花费<code>O(log(n))</code>时间,并被调用</p>
<h3 id="50-检测链表中的循环"><a href="#50-检测链表中的循环" class="headerlink" title="50. 检测链表中的循环"></a>50. <a name="50">检测链表中的循环</a></h3><p>说明<br>遍历整个链表,并将每个访问的节点添加到visit_nodes集合中。<br>在每个节点上,我们检查它是否已被访问。<br>原则上,如果重新访问节点,则存在一个循环! </p>
<h5 id="时间复杂度"><a href="#时间复杂度" class="headerlink" title="时间复杂度"></a>时间复杂度</h5><p>我们对列表进行一次迭代。<br>平均而言,集合中的查找需要O(1)时间。<br>因此,该算法的平均运行时间为O(n)。<br>但是,在最坏的情况下,查找可能会增加到O(n),这将导致算法在</p>
]]></content>
<categories>
<category>docs</category>
<category>python</category>
<category>index</category>
</categories>
<tags>
<tag>Python</tag>
</tags>
</entry>
<entry>
<title>FastApi</title>
<url>/2020/01/20/FastApi/</url>
<content><![CDATA[<p><img src="http://imgs.yrzdm.com/imgs/20200120/ULXjnIOWfCPh.jpg?imageslim" alt="mark"><br>FastAPI framework, high performance, easy to learn, fast to code, ready for production</p>
<a id="more"></a>
<p>Documentation: <a class="link" href="https://fastapi.tiangolo.com" target="_blank" rel="noopener">https://fastapi.tiangolo.com<i class="fas fa-external-link-alt"></i></a></p>
<p>如果应对一个非常简单的需求,比如编写一个接口,总不能直接Django,但也不能写的很糙。如果用Flask,虽然可以用很短的代码写出一个能用的项目,但是需要很多地方需要处理。</p>
<p>如果使用FastApi就会简单很多:</p>
<figure class="highlight properties"><table><tr><td class="code"><pre><code class="hljs properties"><span class="hljs-attr">from</span> <span class="hljs-string">fastapi import FastAPI</span><br><span class="hljs-attr">from</span> <span class="hljs-string">pydantic import BaseModel</span><br><span class="hljs-attr">app</span> = <span class="hljs-string">FastAPI()</span><br><span class="hljs-attr">class</span> <span class="hljs-string">People(BaseModel):</span><br> <span class="hljs-attr">name</span>:<span class="hljs-string">str</span><br> <span class="hljs-attr">age</span>:<span class="hljs-string">int</span><br> <span class="hljs-attr">address</span>:<span class="hljs-string">str</span><br> <span class="hljs-attr">salary</span>:<span class="hljs-string">float</span><br><br><span class="hljs-attr">@app.post('/insert')</span><br><span class="hljs-attr">def</span> <span class="hljs-string">insert(people:People):</span><br> <span class="hljs-attr">age_after_10_years</span> = <span class="hljs-string">people.age + 10</span><br> <span class="hljs-attr">msg</span> = <span class="hljs-string">"人名:{people.name},十年后的年龄为:{age_after_10_years}'</span><br> <span class="hljs-attr">return</span> <span class="hljs-string">{'success:'True,'msg':msg}</span><br></code></pre></td></tr></table></figure>
<p>启动服务后,如果传入错误的值,返回值将会非常友好的告诉你哪里出错了。对类型的检查全部由FastAPI自己完成,非常pythonic。<br>使用fastAPI 需要使用uvicorn来运行FastAPI</p>
<figure class="highlight sql"><table><tr><td class="code"><pre><code class="hljs sql">pip <span class="hljs-keyword">install</span> uvicorn<br>uvicorn <span class="hljs-keyword">main</span>:app <span class="hljs-comment">--reload</span><br></code></pre></td></tr></table></figure>
<p>main: 代码文件名 main.py</br><br>app: 初始化FastAPI的对象名</br><br>–reload 代码修改后立即生效,不需要重启</p>
<h3 id="GET-方法定义"><a href="#GET-方法定义" class="headerlink" title="GET 方法定义"></a>GET 方法定义</h3><figure class="highlight ruby"><table><tr><td class="code"><pre><code class="hljs ruby">@app.get(<span class="hljs-string">'/quert/{uid}'</span>)<br><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">query</span><span class="hljs-params">(uid)</span></span>:<br> msg = <span class="hljs-string">'您查询的uid为:{uid}'</span><br> <span class="hljs-keyword">return</span> {<span class="hljs-string">'success'</span><span class="hljs-symbol">:True</span>,<span class="hljs-string">'msg'</span><span class="hljs-symbol">:msg</span>}<br></code></pre></td></tr></table></figure>
<p>直接请求该地址:<br><a class="link" href="http://127.0.0.1:8000/query/789" target="_blank" rel="noopener">http://127.0.0.1:8000/query/789<i class="fas fa-external-link-alt"></i></a><br>如果限定uid的类型,只需要在函数定义时候指定类型</p>
<figure class="highlight ruby"><table><tr><td class="code"><pre><code class="hljs ruby"><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">quert</span><span class="hljs-params">(<span class="hljs-symbol">uid:</span>int)</span></span><span class="hljs-symbol">:</span><br></code></pre></td></tr></table></figure>
<p>除了这些之外,FastAPI还能帮我们快速的生成接口文档。<br><a class="link" href="http://127.0.0.1:8000/docs" target="_blank" rel="noopener">http://127.0.0.1:8000/docs<i class="fas fa-external-link-alt"></i></a><br><img src="https://fastapi.tiangolo.com/img/index/index-03-swagger-02.png" alt=""></p>
]]></content>
<categories>
<category>docs</category>
<category>python</category>
<category>index</category>
</categories>
<tags>
<tag>Python</tag>
</tags>
</entry>
<entry>
<title>热水器改造项目</title>
<url>/2020/01/14/Friendly-Arm/</url>
<content><![CDATA[<p>生活上有一个不便之处是关于热水器的使用,说到这里,务必劝解各位,🤐买房一定不要买☠️万科☠️。</p>
<a id="more"></a>
<p>因为热水器🚿是配套赠送的,暂时没有更换的需求,热水器是力诺瑞特电热和太阳能混合的,保证了天气不好的时候可以使用电加热,但是电加热非常不方便,尤其在这个被物联网时代惯坏了时代。在外没法看到热水器的温度显示。<br>想着实现如下功能:</p>
<ul>
<li><input disabled="" type="checkbox"> 远程观看热水器水温</li>
<li><input disabled="" type="checkbox"> 远程(手机)可点击热水器的加热按钮</li>
<li><input disabled="" type="checkbox"> 在家时候使用天猫精灵进行开启和关闭加热</li>
</ul>
<ol>
<li><p><strong>硬件准备</strong></p>
<p>手里有树莓派、esp32、esp8266和好多开发板,综合考虑使用一块友善之臂的开发板,但是友善之臂开发板的固件非常的不友善,看了一下采用了H3的soc,对比了一下国内有好几家有类似的方案,orangePi,BananaPi,发现香蕉派的M2和友善之臂M1 Plus有着惊人的相似之处,连引脚定义都是相同的,但是香蕉派的固件明显的要友善一些,单从固件大小上就能看出,友善之臂没有打包很多的驱动在内。</p>
<blockquote>
<p>尝试将BananaPi的固件刷入友善之臂,竟然完美兼容。😂</p>
</blockquote>
<p>要实现温度的读取,如果从热水器内部下手,担心丢失保修,只能从外部下手,使用大的摄像头担心浪费,买了一个esp32-cam模块来拍摄温度显示,然后写个图像的ocr识别来曲线救国。</p>
</li>
</ol>
<ul>
<li>加热按钮考虑使用舵机来实现模拟人工的按键</li>
</ul>
<ol start="2">
<li><p>数据中心使用Domoticz</p>
<p>树莓派安装Domoticz非常方便</p>
<figure class="highlight vim"><table><tr><td class="code"><pre><code class="hljs vim">sudo curl -L install.domoticz.<span class="hljs-keyword">cn</span> | sudo bash<br>sudo apt-<span class="hljs-built_in">get</span> <span class="hljs-keyword">update</span><br></code></pre></td></tr></table></figure>
<p>运行以上命令后就会进入domoticz的配置界面。</p>
</li>
<li><p>流程图</p>
<figure class="highlight plain"><table><tr><td class="code"><pre><code class="hljs sequence">participant 客户端 as A<br>participant esp32CAM as B<br>participant 数据中心 as C<br>Note over A:用户账号、密码<br>A->C: 访问数据中心<br>Note over C:验证账号、密码<br>C-->>A:热水器温度状态<br>A->C:发送指令<br>C-->>B:发送指令<br>B->B:自交互<br></code></pre></td></tr></table></figure>
<p>未完待续…</p>
</li>
</ol>
<p>尤其是济南华艺黄运林这个老板经营的地产项目,绝对是坑,项目要配套没有配套在济南开发的这些项目都是合作开发,狗血的是作为万科济南负责人竟然自己注册了个华艺地产,万科和华艺合作。</p>
]]></content>
<categories>
<category>docs</category>
<category>python</category>
<category>index</category>
</categories>
<tags>
<tag>Python</tag>
</tags>
</entry>
<entry>
<title>Matplotlib常见问题</title>
<url>/2020/01/10/Matplotlib/</url>
<content><![CDATA[<p><a href="https://imgchr.com/i/lfzqat" target="_blank" rel="noopener"><img src="https://s2.ax1x.com/2020/01/10/lfzqat.md.jpg" alt="lfzqat.md.jpg"></a><br>最近接了不少学生作业大多数都是预测和数据分析以及分类器相关,所用图表展示用到Matplotlib,经常会涉及到一些问题,对出现的问题进行整理,避免重复踩坑。</p>
<a id="more"></a>
<ol>
<li><strong>中文显示乱码问题</strong><br>图表展示,图例等标识都需要用到中文,如果MATPLOTLIB缺少中文字体的调用,图表显示的时候会出现乱码。</li>
</ol>
<figure class="highlight xl"><table><tr><td class="code"><pre><code class="hljs xl"><span class="hljs-keyword">import</span> numpy <span class="hljs-keyword">as</span> np<br><span class="hljs-keyword">import</span> matplotlib<br><span class="hljs-keyword">import</span> matplotlib.pyplot <span class="hljs-keyword">as</span> plt<br>from matplotlib.figure <span class="hljs-keyword">import</span> Figure<br><br># 正常显示画图时出现的中文和负号<br>from pylab <span class="hljs-keyword">import</span> mpl<br>mpl.rcParams[<span class="hljs-string">'font.sans-serif'</span>]=[<span class="hljs-string">'SimHei'</span>]<br>mpl.rcParams[<span class="hljs-string">'axes.unicode_minus'</span>]=False<br></code></pre></td></tr></table></figure>
<ol start="2">
<li><strong>tight_layout()</strong><br>Matplotlib v1.1 引入一个新的命令tight_layout(),用来调整子图参数,使之填充图像区域,解决Axes轴标签、标题、刻度超出图形区域的问题。</li>
</ol>
<figure class="highlight routeros"><table><tr><td class="code"><pre><code class="hljs routeros">def show(self):<br> self.figure.tight_layout()<br> FigureCanvasAgg.draw(self)<br> <span class="hljs-keyword">if</span><span class="hljs-built_in"> PORT </span>is None:<br> return<br><br> <span class="hljs-keyword">if</span> matplotlib.__version__ < <span class="hljs-string">'1.2'</span>:<br> buffer = self.tostring_rgb(0, 0)<br> <span class="hljs-keyword">else</span>:<br> buffer = self.tostring_rgb()<br><br> <span class="hljs-keyword">if</span> len(<span class="hljs-builtin-name">set</span>(buffer)) <= 1:<br> # <span class="hljs-keyword">do</span> <span class="hljs-keyword">not</span> plot empty<br> return<br><br> render = self.get_renderer()<br> width = int(render.width)<br><br> plot_index = index <span class="hljs-keyword">if</span> os.getenv(<span class="hljs-string">"PYCHARM_MATPLOTLIB_INTERACTIVE"</span>, <span class="hljs-literal">False</span>) <span class="hljs-keyword">else</span> -1<br> try:<br> sock = socket.socket()<br> sock.connect((HOST, PORT))<br> sock.send(struct.pack(<span class="hljs-string">'>i'</span>, width))<br> sock.send(struct.pack(<span class="hljs-string">'>i'</span>, plot_index))<br> sock.send(struct.pack(<span class="hljs-string">'>i'</span>, len(buffer)))<br> sock.send(buffer)<br> except OSError as _:<br> # <span class="hljs-literal">nothing</span> bad. It just means, that our<span class="hljs-built_in"> tool </span>window doesn<span class="hljs-string">'t run yet<br> pass</span><br></code></pre></td></tr></table></figure>
<p>当axes列表为空的时候,tight_layout()将会报错,此时需要将plt.show()替换为plt.savefig(‘file.png’,bbox_inches=’tight’)</p>
]]></content>
<categories>
<category>docs</category>
<category>python</category>
<category>index</category>
</categories>
<tags>
<tag>Python</tag>
<tag>MatPlotlib</tag>
</tags>
</entry>
<entry>
<title>及时行乐</title>
<url>/2018/08/03/about/</url>
<content><![CDATA[<p>及时行乐(Enjoy Pleasure in Good Time.)<br><img src="https://i.loli.net/2018/08/03/5b63cc6e20cd8.png" alt="epgt"></p>
<blockquote>
<p>人生苦短,何不及时行乐</br><br>释义:抓紧时机,不失时机,寻欢作乐。</br></p>
</blockquote>
<a id="more"></a>
<p>出处:《新刊大宋宣和遗事》:“人生如白驹过隙,倘不及时行乐,则老大徒伤悲也。”</br><br>例句:短歌行(曹操)对酒当歌,人生几何? 譬如朝露,去日苦多。 慨当以慷,忧思难忘。 何以解忧?唯有杜康。</p>
<p>So, there you have it… enjoy!</p>
]]></content>
<categories>
<category>docs</category>
<category>index</category>
</categories>
<tags>
<tag>collect</tag>
</tags>
</entry>
<entry>
<title>android-command</title>
<url>/2017/03/01/android-command/</url>
<content><![CDATA[<p><img src="http://imgs.yrzdm.com/imgs/20200229/bizqoIV7W31a.png?imageslim" alt="mark"><br>每个拥有android手机的人必须要会几条ADB Commands. 掌握一下命令行通过中间人的方式,你的同事的手机如果root过或者在公共场合,可以随意查看他们手机中的资料。所以对于android手机root就等于开放。</p>
<a id="more"></a>
<p>ADB = Android Debug Bridge</p>
<p>ADB命令有很多,整理一下几条比较常用的如下:</p>
<p>1.查看版本</p>
<figure class="highlight routeros"><table><tr><td class="code"><pre><code class="hljs routeros"><span class="hljs-variable">$abd</span> version<br>Andorid <span class="hljs-builtin-name">Debug</span><span class="hljs-built_in"> Bridge </span>version 1.0.36<br>Revision 8F855A3D9B35-android<br></code></pre></td></tr></table></figure>
<p>2.查看连接设备</p>
<figure class="highlight gams"><table><tr><td class="code"><pre><code class="hljs gams"><span class="hljs-meta"><span class="hljs-meta-keyword">$adb</span> devices</span><br>of devices attached<br><span class="hljs-number">02</span>ae0c1021089daf device<br></code></pre></td></tr></table></figure>
<p>```</p>
<p>3.安装</p>
<figure class="highlight cmake"><table><tr><td class="code"><pre><code class="hljs cmake">adb <span class="hljs-keyword">install</span><br></code></pre></td></tr></table></figure>
<p>保留数据和缓存文件,重新安装apk:</p>
<p><code>adb install -r</code><br>安装apk到sd卡:</p>
<figure class="highlight cmake"><table><tr><td class="code"><pre><code class="hljs cmake">adb <span class="hljs-keyword">install</span> -s<br></code></pre></td></tr></table></figure>
<p>4.卸载</p>
<figure class="highlight css"><table><tr><td class="code"><pre><code class="hljs css"><span class="hljs-selector-tag">adb</span> <span class="hljs-selector-tag">uninstall</span> <br>\\<span class="hljs-selector-tag">eg</span>:<span class="hljs-selector-tag">adb</span> <span class="hljs-selector-tag">uninstall</span> <span class="hljs-selector-tag">com</span><span class="hljs-selector-class">.stormzhang</span><span class="hljs-selector-class">.demo</span><br></code></pre></td></tr></table></figure>
<p>卸载app但保留数据和缓存文件</p>
<figure class="highlight ebnf"><table><tr><td class="code"><pre><code class="hljs ebnf"><span class="hljs-attribute">adb uninstall -k</span><br></code></pre></td></tr></table></figure>
<p>5.启动/停止Server</p>
<p>启动Server</p>
<figure class="highlight pgsql"><table><tr><td class="code"><pre><code class="hljs pgsql">adb <span class="hljs-keyword">start</span>-<span class="hljs-keyword">server</span><br></code></pre></td></tr></table></figure>
<p>停止Server</p>
<figure class="highlight sql"><table><tr><td class="code"><pre><code class="hljs sql">adb <span class="hljs-keyword">kill</span>-<span class="hljs-keyword">server</span><br></code></pre></td></tr></table></figure>
<p>6.包管理</p>
<p>列出手机装的所有app的包名</p>
<figure class="highlight dockerfile"><table><tr><td class="code"><pre><code class="hljs dockerfile">adb <span class="hljs-keyword">shell</span><span class="bash"> pm list packages</span><br></code></pre></td></tr></table></figure>
<p>列出系统应用的所有包名</p>
<figure class="highlight dockerfile"><table><tr><td class="code"><pre><code class="hljs dockerfile">adb <span class="hljs-keyword">shell</span><span class="bash"> pm list packages -s</span><br></code></pre></td></tr></table></figure>
<p>列出第三方应用:</p>
<figure class="highlight dockerfile"><table><tr><td class="code"><pre><code class="hljs dockerfile">adb <span class="hljs-keyword">shell</span><span class="bash"> pm list packages -3</span><br></code></pre></td></tr></table></figure>
<p>使用grep来过滤</p>
<figure class="highlight vim"><table><tr><td class="code"><pre><code class="hljs vim">adb <span class="hljs-keyword">shell</span> pm <span class="hljs-keyword">list</span> packages | <span class="hljs-keyword">grep</span> qq<br></code></pre></td></tr></table></figure>
<p>7.清除应用数据及缓存</p>
<figure class="highlight dockerfile"><table><tr><td class="code"><pre><code class="hljs dockerfile">adb <span class="hljs-keyword">shell</span><span class="bash"> pm clear</span><br></code></pre></td></tr></table></figure>
<p>8.启动应用</p>
<figure class="highlight dockerfile"><table><tr><td class="code"><pre><code class="hljs dockerfile">adb <span class="hljs-keyword">shell</span><span class="bash"> am start -n /.ui.SplashActivity</span><br></code></pre></td></tr></table></figure>
<p>9.强制停止应用</p>
<figure class="highlight vim"><table><tr><td class="code"><pre><code class="hljs vim">adb <span class="hljs-keyword">shell</span> <span class="hljs-keyword">am</span> force-<span class="hljs-keyword">stop</span><br></code></pre></td></tr></table></figure>
<p>10.查看日志</p>
<figure class="highlight ebnf"><table><tr><td class="code"><pre><code class="hljs ebnf"><span class="hljs-attribute">adb logcat</span><br></code></pre></td></tr></table></figure>
<p>11.重启</p>
<figure class="highlight ebnf"><table><tr><td class="code"><pre><code class="hljs ebnf"><span class="hljs-attribute">adb reboot</span><br></code></pre></td></tr></table></figure>
<p>12.获取序列号</p>
<figure class="highlight gams"><table><tr><td class="code"><pre><code class="hljs gams"><span class="hljs-meta"><span class="hljs-meta-keyword">$adb</span> get-serialno</span><br></code></pre></td></tr></table></figure>
<p>13.获取MAC地址</p>
<figure class="highlight stata"><table><tr><td class="code"><pre><code class="hljs stata"><span class="hljs-variable">$adb</span> <span class="hljs-keyword">shell</span> <span class="hljs-keyword">cat</span> /sys/<span class="hljs-keyword">class</span>/<span class="hljs-keyword">net</span>/wlan0/address<br></code></pre></td></tr></table></figure>
<p>14.查看设备型号</p>
<figure class="highlight css"><table><tr><td class="code"><pre><code class="hljs css"><span class="hljs-selector-tag">adb</span> <span class="hljs-selector-tag">shell</span> <span class="hljs-selector-tag">getprop</span> <span class="hljs-selector-tag">ro</span><span class="hljs-selector-class">.product</span><span class="hljs-selector-class">.model</span><br></code></pre></td></tr></table></figure>
<p>15.查看Android系统版本</p>
<figure class="highlight stata"><table><tr><td class="code"><pre><code class="hljs stata"><span class="hljs-variable">$adb</span> <span class="hljs-keyword">shell</span> getprop ro.build.<span class="hljs-keyword">version</span>.release<br></code></pre></td></tr></table></figure>
<p>16.查看屏幕分辨率</p>
<figure class="highlight dockerfile"><table><tr><td class="code"><pre><code class="hljs dockerfile">$adb <span class="hljs-keyword">shell</span><span class="bash"> wm size</span><br></code></pre></td></tr></table></figure>
<p>17.检查设备是否已经ROOT</p>
<figure class="highlight dockerfile"><table><tr><td class="code"><pre><code class="hljs dockerfile">adb <span class="hljs-keyword">shell</span><span class="bash"><br>su</span><br></code></pre></td></tr></table></figure>
<p>18.开启关闭wifi(需ROOT权限)</p>
<figure class="highlight dockerfile"><table><tr><td class="code"><pre><code class="hljs dockerfile">adb root<br>adb <span class="hljs-keyword">shell</span><span class="bash"> svc wifi <span class="hljs-built_in">enable</span>/<span class="hljs-built_in">disable</span></span><br></code></pre></td></tr></table></figure>
<p>19.音量控制</p>
<figure class="highlight angelscript"><table><tr><td class="code"><pre><code class="hljs angelscript">adb shell input keyevent <span class="hljs-number">24</span>/<span class="hljs-number">25</span>、<span class="hljs-number">164</span><br></code></pre></td></tr></table></figure>
<p>24增加音量,25降低音量 164 静音</p>
<p>20.文件管理</p>
<p>复制电脑里的文件到设备</p>
<figure class="highlight xml"><table><tr><td class="code"><pre><code class="hljs xml">adb push <span class="hljs-tag"><<span class="hljs-name">电脑文件路径</span>></span> <span class="hljs-tag"><<span class="hljs-name">设备里的目录</span>></span><br></code></pre></td></tr></table></figure>
<p>复制设备文件到电脑</p>
<figure class="highlight jboss-cli"><table><tr><td class="code"><pre><code class="hljs jboss-cli">adb pull <span class="hljs-string">/sdcard/sr.mp4</span> ~<span class="hljs-string">/tmp</span><br></code></pre></td></tr></table></figure>]]></content>
<categories>
<category>docs</category>
<category>Android</category>
<category>index</category>
</categories>
<tags>
<tag>Android</tag>
<tag>Shell</tag>
</tags>
</entry>
<entry>
<title>LineageOS 16.0 (Android 9) for Raspberry Pi 3</title>
<url>/2020/04/17/android-for-raspberry/</url>
<content><![CDATA[<p><img src="http://imgs.yrzdm.com/imgs/20200421/vFL0yUXfrnzq.png?imageslim" alt="mark"><br>最近有个需求是需要一个安卓设备,最好是android7 以上系统,总不能豪横的买一个,手里有个Raspberry3B+🚫🍓</br><br>百度了一下,有几个分享的都是使用Android Things来移植的,Google了一下发现了一个LineageOS 和 emteria.OS可以再3上面运行,那我的3B+肯定也能跑。</p>
<a id="more"></a>
<p><strong>About Emteria.OS</strong></p>
<blockquote>
<p>Emteria.OS is a full build of Android available for Raspberry Pi. While you can get it for free and use it as an individual, it’s aimed more towards industry. Embedded Android devices are big business, and marrying the mobile OS with the Pi opens up a whole new world of Android in both maker projects and consumer products.</p>
</blockquote>
<p>Emteria.OS 是一个面向工业化使用的android系统,也有面向个人的版本,都是需要收费。<br>相关介绍和安装文档: </p>
<p>📃<a class="link" href="https://magpi.raspberrypi.org/articles/android-raspberry-pi" target="_blank" rel="noopener">Emteria.OS<i class="fas fa-external-link-alt"></i></a></p>
<p>官网:🌐 <a class="link" href="https://emteria.com/" target="_blank" rel="noopener">Emteria.OS<i class="fas fa-external-link-alt"></i></a></p>
<p><strong>About LineageOS</strong></p>
<blockquote>
<p>LineageOS 16.0 for Raspberry Pi 3 Model B and Model B+. It is unofficial and unsupported by the LineageOS team. It’s for advanced users only.</p>
</blockquote>
<p>LineageOS 是基于LineageOS 16.0官方版本有个人修改来的,官方并不提供支持。</p>
<p>安装说明文档: 📃 <a class="link" href="https://konstakang.com/devices/rpi3/LineageOS16.0/" target="_blank" rel="noopener">LineageOS<i class="fas fa-external-link-alt"></i></a></p>
<p><img src="http://imgs.yrzdm.com/imgs/20200421/hEUz4NxkYe7t.png?imageslim" alt="Raspberry3B+"></p>
<h3 id="可以正常使用的功能和驱动部分"><a href="#可以正常使用的功能和驱动部分" class="headerlink" title="可以正常使用的功能和驱动部分"></a>可以正常使用的功能和驱动部分</h3><ul>
<li>Audio (HDMI, 3.5mm jack, USB microphones, bluetooth speakers/headsets, etc)</li>
<li>Bluetooth</li>
<li>Camera (using official Pi camera modules & UVC USB webcams)</li>
<li>GPIO</li>
<li>GPS (using external USB modules e.g. U-Blox 7)</li>
<li>Ethernet</li>
<li>Hardware accelerated graphics (VC4)</li>
<li>HDMI display</li>
<li>I2C</li>
<li>IR remotes (using external GPIO IR modules e.g. TSOP4838)</li>
<li>RTC (using external GPIO I2C modules e.g. DS3231)</li>
<li>Serial console (using external GPIO serial console adapters e.g. PL2303)</li>
<li>SPI</li>
<li>Touchscreen/multi-touch (using official 7” display with SwiftShafer software renderer)</li>
<li>USB (mouse, keyboard, storage, etc)</li>
<li>Wifi</li>
<li>Wifi tethering<h3 id="不可以正常使用的功能"><a href="#不可以正常使用的功能" class="headerlink" title="不可以正常使用的功能"></a>不可以正常使用的功能</h3></li>
<li>Hardware video decoding & encoding</li>
</ul>
<h2 id="烧录ROM过程"><a href="#烧录ROM过程" class="headerlink" title="烧录ROM过程"></a>烧录ROM过程</h2><p>使用balenaEtcher 将固件烧录到TF卡中。<br> 🔥<a class="link" href="https://www.balena.io/etcher/" target="_blank" rel="noopener">balenaEtcher<i class="fas fa-external-link-alt"></i></a></p>
<h2 id="如何安装apk"><a href="#如何安装apk" class="headerlink" title="如何安装apk"></a>如何安装apk</h2><p>如果需要安装apk,需要安装 <a class="link" href="https://opengapps.org/?arch=arm&api=9.0&variant=pico" target="_blank" rel="noopener">opengapps<i class="fas fa-external-link-alt"></i></a></p>
]]></content>
<categories>
<category>docs</category>
<category>Raspberry</category>
<category>Android</category>
<category>index</category>
</categories>
<tags>
<tag>Raspberry</tag>
</tags>
</entry>
<entry>
<title>awake</title>
<url>/2021/05/25/awake/</url>
<content><![CDATA[<blockquote>
<p>he needs to wake up to reality.</p>
</blockquote>
<p>上个周六的晚上,孩子跟我们一起睡,一直枕着我的肚子或者腿,晚上一直在做梦,要么是哈哈大笑,要么是再说看的动画片或者白天玩的游戏。</p>
<p>但是今晚突然哭了起来,说爸爸没有钱,奶奶也没有钱,他们都没有钱给我买好好了,然后边说边嚎啕大哭。</p>
<p>我想了一下,确实,我想了整整一宿,我想我要记录下我当时的感受,每当懒散不振的时候,自己来看看。</p>
]]></content>
<categories>
<category>docs</category>
<category>python</category>
<category>index</category>
</categories>
<tags>
<tag>Life</tag>
</tags>
</entry>
<entry>
<title>bigbang</title>
<url>/2016/10/26/bigbang/</url>
<content><![CDATA[<p><img src="http://imgs.yrzdm.com/imgs/20200229/e1LUuD5jbrUO.png?imageslim" alt="mark"></p>
<h4 id="关于Big-Bang"><a href="#关于Big-Bang" class="headerlink" title="关于Big Bang!"></a>关于Big Bang!</h4><p>前几天看老罗的新品发布会 M1 M1L(据说谐音是满意和满意了)<br>发现新的Smartisan OS 3.0系统里面的Big Bang功能有点像前几天研究的分词。</p>
<a id="more"></a>
<p>今天晚上在T1上也受到了OTA的升级推送,体验了一下新版的3.0系统,发现Big Bang 功能的触摸体验不是很好,额 有点偏离主题了。</p>
<p>今天我们来做一下用python实现Big Bang的功能。<br>这里需要用到一个开源的Module,jieba(结巴),可以使用pip进行安装<br><code>pip install jieba</code></p>
<p>使用方法:</p>
<figure class="highlight plain"><figcaption><span>-*- coding:utf-8 -*-</span></figcaption><table><tr><td class="code"><pre><code class="hljs #!">import jieba<br>seg_list = jieba.cut(“我来到山东大学”, cut_all = True)<br>print “Full Mode:”, ‘ ‘.join(seg_list)<br></code></pre></td></tr></table></figure>
<p>#Full Mode: 我 来到 山东 山东大学 东大 大学</p>
<p>#感觉这个分词模式可以用到搜索引擎的优化,得到用户可能搜索的意图<br>seg_list = jieba.cut(“周末可以去帮吱吱搬家”)<br>print “Default Mode:”, ‘ ‘.join(seg_list)</p>
<p>#Default Mode: 周末 可以 去 帮 吱吱 搬家<br>↑这个结果完全和Big Bang的爆炸效果完全一样</p>
]]></content>
<categories>
<category>docs</category>
<category>python</category>
<category>index</category>
</categories>
<tags>
<tag>Python</tag>
<tag>Jieba</tag>
</tags>
</entry>
<entry>
<title>beautifulsoup-useage</title>
<url>/2016/09/08/beautifulsoup-useage/</url>
<content><![CDATA[<p><img src="http://imgs.yrzdm.com/imgs/20200229/2P84vXFo0Fzh.png?imageslim" alt="mark"></p>
<p>之前混合使用bs4、re、lxml 这三个Modules进行解析html的方式虽然可以解决问题但是明显的影响了响应速度,突然发现BS4可以使用CSS Selector方式类似与Xpath的解析。</p>
<a id="more"></a>
<p><img src="http://imgs.yrzdm.com/imgs/20200229/kNugfSMSXFNJ.png?imageslim" alt="mark"></p>
<p>通过Chrome或者FF 得到tag的CSS Selector 路径使用select可以直接进行使用,明显的代码少了很多行,而且执行速度大大提升。</p>
]]></content>
<categories>
<category>docs</category>
<category>python</category>
<category>index</category>
</categories>
<tags>
<tag>Python</tag>
<tag>BeautifulSoup</tag>
</tags>
</entry>
<entry>
<title>常见Ai公开数据集收集</title>
<url>/2021/06/24/ai-dataset-collection/</url>
<content><![CDATA[<p>开始机器学习入门,经常需要找一些数据集进行训练练习,整理一下。</p>
<p><strong>KITTI数据集</strong></p>
<p><code>Kitti</code>数据集是由<a class="link" href="http://www.kit.edu" target="_blank" rel="noopener">德国卡尔斯鲁厄理工学院<i class="fas fa-external-link-alt"></i></a>和丰田技术研究院联合创办,是自动驾驶场景下的计算机视觉算法评测数据集。该数据集用于评测立体图像(stereo),光流(optical flow),视觉测距(visual odometry),3D物体检测(object detection)和3D跟踪(tracking)等计算机视觉技术在车载环境下的性能。</p>
<p>KITTI包含市区、乡村和高速公路等场景采集的真实图像数据,每张图像中最多达15辆车和30个行人,还有各种程度的遮挡与截断。整个数据集由389对立体图像和光流图,39.2 km视觉测距序列以及超过200k 3D标注物体的图像组成 ,以10Hz的频率采样及同步。总体上看,原始数据集被分类为‘Road’, ‘City’, ‘Residential’, ‘Campus’ 和‘Person’。对于3D物体检测,label细分为car, van, truck, pedestrian, pedestrian(sitting), cyclist, tram以及misc组成。<br>数据集大小:312MB~440GB不等</p>
]]></content>
<categories>
<category>docs</category>
<category>python</category>
<category>index</category>
</categories>
<tags>
<tag>Python</tag>
</tags>
</entry>
<entry>
<title>2019书单计划</title>
<url>/2019/04/24/booklist/</url>
<content><![CDATA[<p><img src="https://i.loli.net/2019/04/24/5cc0164d939fc.jpg" alt="Book-list-2019"></br></p>
<p>转眼间2019已经过去快一半的时间了,想到年初立的flag 虽然在做却没有及时的总结和复盘。<br>今天把今年需要读的书单发出来,以提醒自己。</p>
<a id="more"></a>
<p><img src="https://www.easyicon.net/api/resizeApi.php?id=1217509&size=24" alt=""><br>月亮与六便士</p>
<p><img src="https://www.easyicon.net/api/resizeApi.php?id=1230961&size=24" alt=""><br>刻意练习</p>
<p><img src="https://www.easyicon.net/api/resizeApi.php?id=1230961&size=24" alt=""><br>动物农场</p>
<p><img src="https://www.easyicon.net/api/resizeApi.php?id=1230961&size=24" alt=""><br>时间管理</p>
<p><img src="https://www.easyicon.net/api/resizeApi.php?id=1230961&size=24" alt=""><br>微习惯</p>
<p><img src="https://www.easyicon.net/api/resizeApi.php?id=1230961&size=24" alt=""><br>微精通</p>
<p><img src="https://www.easyicon.net/api/resizeApi.php?id=1230961&size=24" alt=""><br>极简工作法</p>
<h3 id="技术类"><a href="#技术类" class="headerlink" title="技术类"></a>技术类</h3><p><img src="https://www.easyicon.net/api/resizeApi.php?id=1227798&size=24" alt=""><br>精通Scrapy网络爬虫</p>
<p><img src="https://www.easyicon.net/api/resizeApi.php?id=1227798&size=24" alt=""><br>精通Python爬虫框架Scrapy</p>
<p><img src="https://www.easyicon.net/api/resizeApi.php?id=1227798&size=24" alt=""><br>编程珠玑</p>
<p><img src="https://www.easyicon.net/api/resizeApi.php?id=1227798&size=24" alt=""><br>编写可维护的JavaScript</p>
<p><img src="https://www.easyicon.net/api/resizeApi.php?id=1227798&size=24" alt=""><br>Python编程无师自通</p>
<p><img src="https://www.easyicon.net/api/resizeApi.php?id=1227798&size=24" alt=""><br>MicroPython for the Internet of Things</p>
<p><img src="https://www.easyicon.net/api/resizeApi.php?id=1227798&size=24" alt=""><br>图解HTTP</p>
<h3 id="其他"><a href="#其他" class="headerlink" title="其他"></a>其他</h3><p><img src="https://www.easyicon.net/api/resizeApi.php?id=1146989&size=32" alt=""><br>极客物理学</p>
<h3 id="理财类"><a href="#理财类" class="headerlink" title="理财类"></a>理财类</h3><p><img src="https://www.easyicon.net/api/resizeApi.php?id=1220091&size=24" alt=""><br>穷查理宝典</p>
<h3 id="语言类"><a href="#语言类" class="headerlink" title="语言类"></a>语言类</h3><p><img src="https://www.easyicon.net/api/resizeApi.php?id=554753&size=32" alt=""><br>1368个单词就够了</p>
<p><strong>另外还有eslpod 和englipod的音频 反复练习读听写</strong></br></p>
<h2 id="todo-list"><a href="#todo-list" class="headerlink" title="todo list"></a>todo list</h2><ul>
<li><input disabled="" type="checkbox"> 精通Scrapy网络爬虫 <img src="https://img.shields.io/badge/read-80-yellow.svg" alt=""></br></li>
<li><input checked="" disabled="" type="checkbox"> 圣斗士星矢 <img src="http://progressed.io/bar/91" alt=""></br></li>
<li><input checked="" disabled="" type="checkbox"> 万历十五年 <img src="http://progressed.io/bar/100" alt=""></br></li>
<li><input checked="" disabled="" type="checkbox"> 动物农场(中文) <img src="http://progressed.io/bar/100" alt=""></br></li>
<li><input checked="" disabled="" type="checkbox"> 日语五十音图详解 <img src="http://progressed.io/bar/100" alt=""></br></li>
</ul>
]]></content>
<categories>
<category>ebook</category>
<category>index</category>
</categories>
<tags>
<tag>ebook,kindle,collect</tag>
</tags>
</entry>
<entry>
<title>decryption-javascript</title>
<url>/2021/02/25/decryption-javascript/</url>
<content><![CDATA[]]></content>
<categories>
<category>docs</category>
<category>python</category>
<category>index</category>
</categories>
<tags>
<tag>Python</tag>
</tags>
</entry>
<entry>
<title>csp-nonce 守护inline Script</title>
<url>/2020/10/26/csp-nonce/</url>
<content><![CDATA[<p>在<a href="https://cx4.github.io/2020/10/22/csp-xss/">XSS终结者</a>一文中,讲述了CSP基础语法组成与使用方式。最终我们利用CSP提供的域名白名单机制,有效地将异常的外联脚本拦在门外。然而在线上环境千千万万,虽然我们限制了外联脚本,但是内联脚本却钻了空。</p>
<a id="more"></a>
<h3 id="CSP-unsafe-inline"><a href="#CSP-unsafe-inline" class="headerlink" title="CSP unsafe-inline"></a>CSP unsafe-inline</h3><p>CSP的默认策略是不允许inline脚本执行,所以当我们没有必要进行脚本inline时,CSP域名白名单的机制足以防范注入脚本的问题。然而在实际项目中,我们还是会因为一些场景需要将部分脚本进行inline。于是需要在CSP的规则中增加<code>script-src‘unsafe-inline’</code>配置允许inline资源执行。但也带来了新的隐患。</p>
<p>允许inline资源执行,也意味着当恶意代码通过inline的方式注入到页面中执行时,页面将变得不再安全。如富文本中被插入一段script代码(没被转义),或者是通过浏览器插件的方式进行代码注入等方式。</p>
<p><code>Content-Security-Policy: script-src 'unsafe-inline'</code></p>
<h3 id="CSP-nonce"><a href="#CSP-nonce" class="headerlink" title="CSP nonce"></a>CSP nonce</h3><p>为了避免上述问题,我们可以使用<code>nonce</code>方式加强的CSP策略,nonce方式是至每次页面访问都产生一个唯一id,通过给内联脚本增加一个nonce属性,并且使其属性值(id)与返回的CSP nonce-{id}对应。只有当两者一致时,对应的内敛脚本才被允许执行。于是,即使网页被注入异常的脚本,因为攻击者不知道当时的nonce的随机id值,所以注入的脚本不会被执行。从而让网页变得更加安全。</p>
<figure class="highlight html"><table><tr><td class="code"><pre><code class="hljs html">Content-Security-Policy:script-src 'nonce-5fAiFfSghuhdf'<br><span class="hljs-tag"><<span class="hljs-name">script</span> <span class="hljs-attr">nonce</span>=<span class="hljs-string">"5fAiFfSghuhdf"</span>></span><span class="actionscript"><br> <span class="hljs-comment">//.....</span><br></span><span class="hljs-tag"></<span class="hljs-name">script</span>></span><br></code></pre></td></tr></table></figure>
<p>那么,当我们通过动态生成脚本并进行插入时,nonce也会将我们正常的代码拦截在外。所以在这种场景下,我们需要配套使用CSP提供的<code>strict-dynamic</code>,<code>strict-dynamic</code>模式允许让被信任的脚本插入并放行正常的脚本执行。</p>
<p><code>Content-Security-Policy:script-src 'nonce-5fAiFfSghuhdf' 'strict-dynamic'</code></p>
<h3 id="Nonce的部署方式"><a href="#Nonce的部署方式" class="headerlink" title="Nonce的部署方式"></a>Nonce的部署方式</h3><h5 id="前端"><a href="#前端" class="headerlink" title="前端"></a>前端</h5><h5 id="script标签增加nonce属性"><a href="#script标签增加nonce属性" class="headerlink" title="script标签增加nonce属性"></a>script标签增加nonce属性</h5><p>我们可以通过构建的方式为页面中script标签添加nonce属性,并增加一个占位符,如</p>
<figure class="highlight html"><table><tr><td class="code"><pre><code class="hljs html"><span class="hljs-tag"><<span class="hljs-name">script</span> <span class="hljs-attr">nonce</span>=<span class="hljs-string">"NONCE_TOKEN"</span>></span><span class="actionscript"><br> <span class="hljs-comment">//....</span><br></span><span class="hljs-tag"></<span class="hljs-name">script</span>></span><br></code></pre></td></tr></table></figure>
<h5 id="后端"><a href="#后端" class="headerlink" title="后端"></a>后端</h5><h5 id="生产唯一id,在CSP返回头中添加nonce-id-并将id替换html上的nonce占位符"><a href="#生产唯一id,在CSP返回头中添加nonce-id-并将id替换html上的nonce占位符" class="headerlink" title="生产唯一id,在CSP返回头中添加nonce-{id}并将id替换html上的nonce占位符"></a>生产唯一id,在CSP返回头中添加nonce-{id}并将id替换html上的nonce占位符</h5><p>方式一: 服务端处理</p>
<ul>
<li>当也买你在服务端渲染时,html作为模板在服务端进行处理后输出,我们可以在后端胜场威一id</li>
<li>通过模板变量将id注入到html中实现替换NONCE_TOKEN占位符</li>
<li>于此同时,将CSP返回头进行对应设置</li>
</ul>
<p>方式二: Nginx处理</p>
<ul>
<li>Nginx中可以使用内置变量的<code>$request_id</code> 作为唯一id,而当nginx版本不支持时,则可以借助lua去生产一个uuid</li>
<li>接着通过Nginx的sub_filter NONCE_TOKEN ‘id’ 将页面中的NONCE_TOKEN占位符替换为id,或者使用lua进行替换</li>
<li>最后使用<code>add_header Content-Security-Policy "script-src 'nonce-{id}'"...</code> 添加对应的CSP返回头</li>
</ul>
<p>当然,为了避免攻击者提前注入一段脚本,并在script标签上同样添加了<code>nonce="NONCE_TOKEN"</code>后端的“误”替换,导致这段提前注入的脚本进行执行。我们需要保密好项目的占位符,取一个特殊的占位符,并行动起来吧。</p>
]]></content>
<categories>
<category>docs</category>
<category>python</category>
<category>index</category>
</categories>
<tags>
<tag>Python</tag>
</tags>
</entry>
<entry>
<title>domain-name-servers</title>
<url>/2017/05/16/domain-name-servers/</url>
<content><![CDATA[<p><img src="http://imgs.yrzdm.com/imgs/20200229/QvrbvunLMzT1.jpg?imageslim" alt="mark"></p>
<h4 id="dns在平时上网中扮演重要角色,如果不注意dns的话,可能会导致网速慢,弹窗广告,网址打不开,打开的不是自己想要的网站,劫持,抢中抢等一系列问题。针对dns的问题,今天我们来总结一下,看看哪家dns服务器最好用。"><a href="#dns在平时上网中扮演重要角色,如果不注意dns的话,可能会导致网速慢,弹窗广告,网址打不开,打开的不是自己想要的网站,劫持,抢中抢等一系列问题。针对dns的问题,今天我们来总结一下,看看哪家dns服务器最好用。" class="headerlink" title="dns在平时上网中扮演重要角色,如果不注意dns的话,可能会导致网速慢,弹窗广告,网址打不开,打开的不是自己想要的网站,劫持,抢中抢等一系列问题。针对dns的问题,今天我们来总结一下,看看哪家dns服务器最好用。"></a>dns在平时上网中扮演重要角色,如果不注意dns的话,可能会导致网速慢,弹窗广告,网址打不开,打开的不是自己想要的网站,劫持,抢中抢等一系列问题。针对dns的问题,今天我们来总结一下,看看哪家dns服务器最好用。</h4><a id="more"></a>
<p>以下常见问题可通过修改dns解决。<br>1.电脑只能上QQ,不能访问网页。<br>2.iphone手机访问appstore非常慢。<br>3.打开某网站速度非常慢。</p>
<p><strong>DNSPod DNS+:★★★★★(推荐)</strong><br>DNSPod的 Public DNS+是目前国内第一家支持ECS的公共DNS,是DNSPod推出的公共域名解析服务,可以为全网用户提供域名的公共递归解析服务!<br>DNS 服务器 IP 地址:<br>首选:119.29.29.29<br>备选:182.254.116.116<br>作者点评:测试数据显示Public DNS+国内数据均比114DNS好,强力推荐!</p>
<p><strong>114DNS:★★★★★</strong><br>国内用户量巨大的DNS,访问速度快,各省都有节点,同时满足电信、联通、移动各运营商用户,可以有效预防劫持。<br>DNS 服务器 IP 地址:<br>首选:114.114.114.114<br>备选:114.114.114.115<br>作者点评:虽然测试结果比不上Public DNS+理想,但是也是非常不错的DNS!</p>
<p><strong>阿里 AliDNS:★★★★</strong><br>阿里公共DNS是阿里巴巴集团推出的DNS递归解析系统,目标是成为国内互联网基础设施的组成部分,面向互联网用户提供“快速”、“稳定”、“智能”的免费DNS递归解析服务。<br>DNS 服务器 IP 地址:<br>首选:223.5.5.5<br>备选:223.6.6.6<br>作者点评:排名第三的DNS也不是吹的,只是节点貌似有点少。</p>
<p><strong>DNS派:★★★★</strong><br>DNS派是聚流科技旗下的DNS服务平台,为个人用户、网站主、企业提供各种有关DNS业务的服务,包括个人上网的域名解析服务、网站授权解析服务、企业域名解析服务等。<br>DNS 服务器 IP 地址:<br>首选(电信/移动/铁通):101.226.4.6<br>备选(电信/移动/铁通):218.30.118.6<br>首选(联通):123.125.81.6<br>备选(联通):140.207.198.6<br>作者点评:360出品!测试结果还不错!</p>
<p><strong>百度 BaiduDNS:★★★</strong><br>百度DNS旗下云解析服务,依托百度一流基础设施和强大技术实力,为用户提供免费的、超越竞品的服务体验。没有套餐区分,安全,稳定,高效<br>DNS 服务器 IP 地址:<br>首选:180.76.76.76<br>作者点评:暂时不知道百度有多少节点。不过应该也不少吧。</p>
<p><strong>CNNIC SDNS:★★★</strong><br>SDNS是由中国互联网络信息中心(CNNIC)正式推出的免费的公共云解析服务(SecureDNS,简称SDNS)。该服务可为广大网民提供安全、智能、高速的上网接入解析服务。<br>DNS 服务器 IP 地址:<br>首选:1.2.4.8<br>备选:210.2.4.8<br>作者点评:作为国家出品的DNS,有待测试……(你敢用吗?反正我不敢)</p>
<p><strong>OpenDNS:★(不推荐)</strong><br>OpenDNS是一个免费的域名解析服务提供商(DNS)。创建于2006年,长期以来致力于为广大个人用户以及商务企业用户和公共领域提供免费的域名解析服务。<br>DNS 服务器 IP 地址:<br>首选:208.67.222.222<br>备选:208.67.220.220<br>作者点评:国内节点少!貌似就几个,不推荐使用!</p>
<p><strong>Google DNS:★(强烈不推荐)</strong><br>谷歌公共域名解析服务(Google Public DNS)是由谷歌公司于2009年发布的一项新的DNS服务。主要为了替代ISPs或其他公司提供的DNS服务。<br>DNS 服务器 IP 地址:<br>首选:8.8.8.8<br>备选:8.8.4.4<br>作者点评:机房在国外,国内无节点!你如果用了谷歌DNS你的信息有可能会免费出国转一圈才回来!强烈不推荐使用!只适合国外用户使用!</p>
]]></content>
<categories>
<category>docs</category>
<category>collections</category>
<category>index</category>
</categories>
<tags>
<tag>DNS</tag>
</tags>
</entry>
<entry>
<title>XSS终结者Content-Security-Policy</title>
<url>/2020/10/22/csp-xss/</url>
<content><![CDATA[<p>CSP全称为Content Security Policy,即内容安全策略。主要以白名单的形式配置可信任的内容来源,在网页中,能够使白名单中的内容正常执行(JS,CSS,image等),而非白名单的内容无法正常执行,从而<code>减少跨站脚本攻击(XSS)</code>,当然也能够<code>减少运营商劫持的内容注入攻击</code>。</p>
<a id="more"></a>
<p>example:</p>
<meta http-equiv="Content-Security-Policy" content="script-src 'self'">
<p>不支持CSP的浏览器将会自动忽略CSP的信息,不会有什么影响。</p>
<p>浏览器兼容性查询<a class="link" href="http://caniuse.com/#feat=contentsecuritypolicy" target="_blank" rel="noopener">caniuse<i class="fas fa-external-link-alt"></i></a></p>
<h3 id="CSP-语法组成"><a href="#CSP-语法组成" class="headerlink" title="CSP 语法组成"></a>CSP 语法组成</h3><h4 id="策略类型"><a href="#策略类型" class="headerlink" title="策略类型"></a>策略类型</h4><p>csp有两种策略类型:</p>
<ul>
<li><p>Conten-Security-Policy</p>
</li>
<li><p>Content-Security-Policy-Report-Only</p>
<p>这两种策略类型的主要区别也i可以从命名上看出,第一种对不安全的资源会进行阻止,第二种只会进行数据上报,不会有实际的阻止。</p>
<p>当定义多个策略的时候,浏览器会优先采用最先定义的。</p>
</li>
</ul>
<h3 id="指令集合"><a href="#指令集合" class="headerlink" title="指令集合"></a>指令集合</h3><p>CSP的指令是指组成内容来源白名单的关键,上面两种策略类型含有以下</p>
<h4 id="指令示例及说明"><a href="#指令示例及说明" class="headerlink" title="指令示例及说明"></a>指令示例及说明</h4><table>
<thead>
<tr>
<th>指令</th>
<th>取值示例</th>
<th>说明</th>
</tr>
</thead>
<tbody><tr>
<td>default-src</td>
<td>‘self’ cdn.example.com</td>
<td>定义针对所有类型(js/image/css/web font/ajax/iframe/多媒体等)资源的默认加载策略,某类型资源如果没有单独定义策略,就使用默认。</td>
</tr>
<tr>
<td>script-src</td>
<td>‘self’ js.example.com</td>
<td>定义针对JavaScript的加载策略</td>
</tr>
<tr>
<td>object-src</td>
<td>‘self’</td>
<td>针对,, 等标签的加载策略</td>
</tr>
<tr>
<td>style-src</td>
<td>‘self’ css.example.com</td>
<td>定义针对样式的加载策略</td>
</tr>
<tr>
<td>img-src</td>
<td>‘self’ image.example.com</td>
<td>定义针对图片的加载策略</td>
</tr>
<tr>
<td>media-src</td>
<td>‘media.example.com’</td>
<td>针对或者引入的html多媒体等标签的加载策略</td>
</tr>
<tr>
<td>frame-src</td>
<td>‘self’</td>
<td>针对iframe的加载策略</td>
</tr>
<tr>
<td>connect-src</td>
<td>‘self’</td>
<td>针对Ajax、WebSocket等请求的加载策略。不允许的情况下,浏览器会模拟一个状态为400的响应</td>
</tr>
<tr>
<td>font-src</td>
<td>font.qq.com</td>
<td>针对Web Font的加载策略</td>
</tr>
<tr>
<td>sandbox</td>
<td>allow-forms allow-scripts</td>
<td>对请求的资源启用sandbox</td>
</tr>
<tr>
<td>report-uri</td>
<td>/some-report-uri</td>
<td>告诉浏览器如果请求的资源不被策略允许时,往哪个地址提交日志信息。不阻止任何内容,可以改用Content-Security-Policy-Report-Only头</td>
</tr>
<tr>
<td>base-uri</td>
<td>‘self’</td>
<td>限制当前页面的url(CSP2)</td>
</tr>
<tr>
<td>child-src</td>
<td>‘self’</td>