├── source ├── CNAME ├── reading │ └── index.md ├── view.png ├── header.jpg ├── favicon.ico ├── wechat.jpeg ├── project │ ├── index.md │ └── index │ │ ├── php-server.jpg │ │ ├── smart-car-freescale.png │ │ ├── electron-component-3d.png │ │ ├── 6WaPq-7Kfi1wLVo5ZE2P1d0y.jpg │ │ ├── CVyYJnKtigzaHiRQOKmtfMZE.jpg │ │ ├── W44BkT8TENzNCoih07mEyLN-.jpg │ │ └── 7742c67c-388c-4965-8a76-fcbf63b9a4fc.jpg ├── about │ ├── index │ │ ├── 1b8RAFgTPJ65AAY7vARIDYLa.jpg │ │ ├── 9fPXD11M-qsaym50SNAkwFl_.png │ │ ├── O_tDRRtwdgwUJGleCTb-fJvl.jpg │ │ ├── UtjFTjHOIYx92yaA6wsdh0GD.png │ │ ├── fQm_6CQKLTPRYXQ_vPInMijE.jpg │ │ ├── oIvyC4BVfC358zcqI3_8kQua.png │ │ ├── 6e6ade44-bc83-4a25-8b36-b41c5a0186a0.jpg │ │ ├── 7f5c2e7f-2dc8-46eb-9867-ca1c3fbd5fda.jpg │ │ ├── 7fbbc22c-3a0f-466b-87bb-d8d27367c419.gif │ │ ├── 8aded4ae-807e-41fa-913d-5f28726a447d.png │ │ ├── 98857854-705b-4306-a360-a32f78d87390.png │ │ └── ffd01abc-1dc8-41b9-b6c4-004f779dddf3.png │ └── index.md ├── _posts │ ├── 2016 │ │ ├── 10 │ │ │ └── im-thread │ │ │ │ └── fd1WM_W61si6GKLhz1QKjx0v.jpg │ │ └── 05 │ │ │ └── mysql-index │ │ │ ├── 09D4DC9D97CBE8A634D244232710688E.png │ │ │ ├── 0C246BB99D16D11FDF529437864AB7CE.png │ │ │ ├── 1592A1D1B6F59FDEC422FF5FC1C97CC0.png │ │ │ ├── 249AA6DD62821BDAC73892DEA1F61C4B.png │ │ │ ├── 3A4B107A96CE4C008B15D740D19CAF98.png │ │ │ ├── 48E546C2BE936C4A7CA2BB19FE4AA6DE.png │ │ │ ├── 53542FB1F6F6B898BEE53F4AE356564A.png │ │ │ ├── 63B428EC932670CB74B3A1B6249407AA.png │ │ │ ├── 6D0B18886D8A8FB14E512CEEE869B07B.png │ │ │ ├── 843424197A8FFFCD2894AC9B2F13302F.png │ │ │ ├── A561801D4FD4EAFB9FB7FB538ED8081F.png │ │ │ ├── A9F238357681376D30DF3C6F524156FB.png │ │ │ ├── C6D5AF9F2923AFB70753E9B9556FE42A.png │ │ │ ├── D13A43EAC5F0ECEE1FE1DA0AA06F69B4.png │ │ │ └── 7d6b1a54-61dd-4ecb-9b84-b064ec95775a.png │ ├── 2017 │ │ ├── 11 │ │ │ ├── qconf │ │ │ │ ├── 0cc54ae6-e55b-11e7-80c1-9a214cf093ae.jpg │ │ │ │ ├── 1a2c6f9e-e55a-11e7-80c1-9a214cf093ae.png │ │ │ │ ├── 2d146c96-e55b-11e7-80c1-9a214cf093ae.png │ │ │ │ ├── 31cbf598-e55a-11e7-80c1-9a214cf093ae.png │ │ │ │ ├── 5aade6d8-e55a-11e7-80c1-9a214cf093ae.png │ │ │ │ ├── 8bb7c9c6-c0e9-40d5-96c8-81b40613e9bc.jpg │ │ │ │ ├── b809d666-e55a-11e7-80c1-9a214cf093ae.jpg │ │ │ │ ├── d29ccf16-e559-11e7-80c1-9a214cf093ae.png │ │ │ │ └── d7fec4ae-e55a-11e7-80c1-9a214cf093ae.jpg │ │ │ └── synchronised-asynchronized-coroutine │ │ │ │ ├── 88bb24ee-b443-407d-ad14-fdae5a7113d6.png │ │ │ │ └── a89c6e5b-facd-47a1-a26b-c8fb747e9650.jpg │ │ ├── 12 │ │ │ ├── elk │ │ │ │ ├── 17b1a5c7-2897-46f2-becd-3f03f926bc0f.png │ │ │ │ ├── 4b4a7b8a-c26e-48b2-af45-27655e06f397.png │ │ │ │ ├── b19f74ae-2be3-4aef-b390-246acbf3050f.png │ │ │ │ ├── b488220c-e24a-4eaf-8ee9-81cc6ae9484c.png │ │ │ │ ├── c0625948-b690-48ad-a178-63fc08b0cefb.png │ │ │ │ ├── c2f50522-4a60-47b5-80b3-69f194745e19.png │ │ │ │ └── de986f14-1b7a-46f0-bf81-e477dda1e157.png │ │ │ ├── elk-advanced │ │ │ │ ├── 0f9b0271-108b-47d4-acc2-6fde4e4f9ff7.png │ │ │ │ ├── 3f97da38-e7e5-11e7-80c1-9a214cf093ae.png │ │ │ │ ├── 575f23bd-f21a-4b53-a7f3-5581f9c25c01.png │ │ │ │ ├── 993155ac-718b-4e4b-9d36-d9d73357b162.png │ │ │ │ ├── b27378ac-e7e8-11e7-80c1-9a214cf093ae.png │ │ │ │ ├── c618f544-7093-4530-9bda-b63ab58832ea.png │ │ │ │ ├── d82824ed-15eb-47c5-9ec6-925f2d3f7758.png │ │ │ │ └── f2c9321a-e7e4-11e7-80c1-9a214cf093ae.png │ │ │ ├── elk-install │ │ │ │ ├── 0da3b439-5174-4aff-b9dc-f275ebbd9e1f.png │ │ │ │ └── a1ff2131-8dd8-4ad1-8ba3-c2d2ebeffc91.png │ │ │ ├── 2017-ziroom-king-1 │ │ │ │ ├── 03a07a80-8bc3-46d1-bcab-17e2a057d951.png │ │ │ │ ├── 25fc16ed-ebdd-4094-84a4-150ad9a31b1f.png │ │ │ │ ├── a1cb7d2c-7fb6-4dbd-a363-3cd9e300743d.png │ │ │ │ ├── d0955aea-2787-4e6b-adea-8fe1f61236de.png │ │ │ │ ├── d4724b85-8491-451a-8b3c-d6c06842ec69.png │ │ │ │ └── f9829b13-af2e-4c7b-b214-40bc78223c18.png │ │ │ ├── 2017-ziroom-king-2 │ │ │ │ ├── 53afcc7a-ff51-4191-aab0-5c9cc6850566.png │ │ │ │ └── b2f137ff-b91b-4036-b7d8-fc86f82fb980.png │ │ │ ├── 2017-ziroom-king-3 │ │ │ │ ├── 18359c82-3ff9-48c7-825e-77fe17419621.png │ │ │ │ ├── 366c6f00-35a1-46c6-ba98-76e3c7b3bae4.png │ │ │ │ └── 9f4a2cb2-ab32-4b28-b054-b479c04270e5.png │ │ │ ├── 2017-ziroom-king-4 │ │ │ │ └── 3d9cf2e7-dfe6-4b6e-8526-991296c3ea51.png │ │ │ ├── 2017-ziroom-king-5 │ │ │ │ ├── 40beff35-47fc-4427-8805-e183233b598b.png │ │ │ │ ├── 45552677-bcd6-4d45-b627-a398f0cfe04d.png │ │ │ │ ├── 7eeefcb6-6b96-4719-9819-c96b31309449.png │ │ │ │ ├── b7724f85-3855-410c-9cc7-1cfcee5d29e4.png │ │ │ │ └── c5f725fc-f801-4e93-9f32-5adb8a76e1a0.png │ │ │ ├── 2017-ziroom-king-4.md │ │ │ └── elk.md │ │ ├── 01 │ │ │ ├── robots │ │ │ │ ├── 5PCU9neptZdG3aY5veYsls0v.png │ │ │ │ ├── FozbmxH8U0MTs0N-teFaCtWa.jpg │ │ │ │ ├── n9DQpbXNbazisDMy_bouP7HN.png │ │ │ │ └── xWjjcJzJrrhkjH6lWy7aZib_.png │ │ │ └── robots.md │ │ ├── 02 │ │ │ └── reward │ │ │ │ ├── Dd5AQhhljSVuOdmUAngQ0Zka.png │ │ │ │ ├── JXPHry2Rdd_PuvEwsaZrFJTq.png │ │ │ │ └── p4GlWAFMrXts5zPMnA88Zsm_.png │ │ ├── 09 │ │ │ ├── lua │ │ │ │ ├── 84414e900ee77fc8fd1baf9fc9c7a7d7.png │ │ │ │ ├── fe33e61ca081f36909b9f2d16b5c9d4b.png │ │ │ │ ├── c391629e-be21-4038-ab25-b47fe368daeb.jpg │ │ │ │ └── fc34646b-5eaf-45ba-b89a-0d8fc3f1b71d.png │ │ │ ├── lua-in-redis │ │ │ │ ├── 3916d13312c22d84d29d3860b59544a9.png │ │ │ │ └── ae7223b50754e37b7cd89cfe24fc13dd.png │ │ │ ├── lua-in-nginx │ │ │ │ └── 63113174-45d7-4a27-8472-d037675c2cbd.jpg │ │ │ ├── supervisor │ │ │ │ ├── 9d28cc24-a0d8-11e7-abc4-cec278b6b50a.png │ │ │ │ └── d42decd3-2342-4e8f-a34f-48b47fc6e557.png │ │ │ └── supervisor.md │ │ ├── 03 │ │ │ ├── install-hexo │ │ │ │ ├── es8bUSE01LiIgQtbSESyEWxW.png │ │ │ │ └── 11b9814d-885a-4aca-9b56-94c3ad908f3f.png │ │ │ ├── linux-core-caricature │ │ │ │ ├── 0E9D69D32086CA20007062B59842DE24.png │ │ │ │ ├── 14227E17ECB4AD1852B67CAD4DA48F42.png │ │ │ │ ├── 3C27118DE046AD57EF68F273C0D97CEB.png │ │ │ │ ├── 4AD005B03A39A0F49C0161914325B9C5.png │ │ │ │ ├── 5BD8ACFD12B2952124B8C9A70546A190.png │ │ │ │ ├── 62707DD3CCEB3B0765227E742A32F72F.png │ │ │ │ ├── 6ADA68452C7E8F3014CD8D7D68BF3DCD.png │ │ │ │ ├── 7367932F64D0D54E31AF624CF830E0CF.png │ │ │ │ ├── A60AFE2B528D380E7C11D921C5D416D2.png │ │ │ │ ├── A91A34A3B08128E2A06C66E8856585B0.png │ │ │ │ ├── A92E721F6E3331ECFF02BF6A2E25F43D.png │ │ │ │ ├── B3FBAEAC24E48666A4442ADEB950BE21.png │ │ │ │ ├── C8277CBC07F312F62D0EF9DA9AF01F19.png │ │ │ │ ├── CDA46D0971D6354391ECC3A88E711EA0.png │ │ │ │ └── DBE8511ECE02DC8ADF849F5062B83433.png │ │ │ └── linux-core-caricature.md │ │ ├── 07 │ │ │ ├── b- │ │ │ │ ├── 059c4183-9028-4abe-89c6-c12d9393d36e.jpg │ │ │ │ ├── 05afc638-3c1a-4020-98bd-78fa0ba6826d.jpg │ │ │ │ ├── 070ad465-7638-4f4c-8c4d-ef3e7ceff2a6.jpg │ │ │ │ ├── 0986b67c-7e37-4411-b057-9dbbf20930bb.jpg │ │ │ │ ├── 0fde9df2-c850-47d8-949d-398b8f3e831f.jpg │ │ │ │ ├── 112d602b-917a-4a11-a227-f3355bcc5d95.jpg │ │ │ │ ├── 12e9c3d2-280c-41ff-b5fd-67d79d884f3a.jpg │ │ │ │ ├── 14f6e592-ee53-42d7-b06b-050c595b2826.jpg │ │ │ │ ├── 180daa1d-b025-423a-89f5-0c5cd94af1e9.jpg │ │ │ │ ├── 19301a61-5d3f-422f-b66e-4853fd5c7caf.jpg │ │ │ │ ├── 1c9bb154-d47b-49ad-a33b-51a74021eb15.jpg │ │ │ │ ├── 1f161fac-1327-4649-a31e-33bc5efd693a.jpg │ │ │ │ ├── 20763cbb-12b3-4e9a-a00b-1759e1356231.jpg │ │ │ │ ├── 2ad346da-5243-492e-b30d-560a744c622e.jpg │ │ │ │ ├── 2c252095-aafa-4f84-8d76-d4c0285d209f.jpg │ │ │ │ ├── 2cd5bcec-3f3f-4ae7-959e-071d07ec1c3b.jpg │ │ │ │ ├── 397c217f-b0bf-4a11-84b4-34b82d2c6642.jpg │ │ │ │ ├── 3adf96f5-9791-44ff-b423-26cb34741be1.jpg │ │ │ │ ├── 42085b9b-c60f-4d6b-bce4-056bb60f9b82.jpg │ │ │ │ ├── 44f988cf-7a51-4863-88f0-766e99fb9f4e.jpg │ │ │ │ ├── 454f21ea-4f34-4556-9641-cee74178b34a.jpg │ │ │ │ ├── 4b90f113-fa96-4189-8804-73e8b1ff682e.jpg │ │ │ │ ├── 520badf6-ab99-4bbb-8c8a-5962900b4a51.jpg │ │ │ │ ├── 53719e92-49f8-450b-9ffc-f2cfbb96295a.jpg │ │ │ │ ├── 5ec15194-a2fa-4431-83ba-53b3ba63be8f.jpg │ │ │ │ ├── 5f468cb8-857c-4d67-8772-d86ee9d9340d.jpg │ │ │ │ ├── 60f11fd4-1c37-44a9-8d1c-f1a194559e37.jpg │ │ │ │ ├── 6137cf60-4db5-4e63-ba41-cea1dfe1de61.jpg │ │ │ │ ├── 6368f5b1-d08e-488c-b23e-a9cf783ea481.jpg │ │ │ │ ├── 6421f60a-6bd4-4c11-bd00-e6864b6c2f7c.jpg │ │ │ │ ├── 6b29f560-e192-4558-a399-5e125ca893e0.jpg │ │ │ │ ├── 76ee8b6f-b653-416b-bb44-99101a6fc40f.jpg │ │ │ │ ├── 78e65b5a-c9c1-4e19-841b-a06879f70032.jpg │ │ │ │ ├── 82d68b72-0dd0-4371-a8e7-a66dcf80a0e0.jpg │ │ │ │ ├── 842c3607-8a20-405f-8a16-12b26ab75b8d.jpg │ │ │ │ ├── 8438d6ce-bd67-4d4e-9dd4-06493d0ef144.jpg │ │ │ │ ├── 84af8a44-4f88-450b-9286-eec57e8ac003.jpg │ │ │ │ ├── 855e1037-3a90-49bb-8310-d9e3911962cf.jpg │ │ │ │ ├── 86fe22ab-fd0b-4ca0-a846-b5dc701c6581.jpg │ │ │ │ ├── 87a0a1d6-fa9e-4a1f-9e9a-6c07ec5c5509.jpg │ │ │ │ ├── 9628d43f-4569-4716-a1e4-ce23931b96f7.jpg │ │ │ │ ├── 9ad3c9a8-a874-4a25-a51d-25c8bb440b6c.jpg │ │ │ │ ├── 9b9ee0cb-50a2-418d-bcaf-4e30707bd886.jpg │ │ │ │ ├── 9ea9ea0e-d6a6-42ae-aace-5a1661ff9cc4.jpg │ │ │ │ ├── a2c81ffd-01f9-4c73-8b03-2aa46d8edf6f.jpg │ │ │ │ ├── a73a2881-7837-4b23-9c39-b6044dc0e26c.jpg │ │ │ │ ├── a9c34b2b-a73c-4611-a05a-a67a0b3e63c5.jpg │ │ │ │ ├── b98ea743-190d-449b-9253-b5e036d6d5ee.jpg │ │ │ │ ├── ba56f5d6-e9e7-41bf-a9d7-3045cbb1f114.jpg │ │ │ │ ├── bc424688-fa4c-4afd-91a9-67a0be2a08ad.png │ │ │ │ ├── bca1c1cc-587d-4b6c-be28-9f92650ad1e5.jpg │ │ │ │ ├── bf42c5e0-2a17-4e30-8e3d-8689f5130652.jpg │ │ │ │ ├── c2045edc-f98d-43b1-a21e-d0dbecf39c4b.jpg │ │ │ │ ├── c5a8411b-2233-47b7-9695-c99bf231fcdd.jpg │ │ │ │ ├── d1c0b5a6-f9c2-4a84-9a0f-dc643fbaf0ef.jpg │ │ │ │ ├── d2135b8d-3cf3-4a54-93af-695145ffa485.jpg │ │ │ │ ├── d242bb97-31cc-41a9-9820-39947f1291b4.jpg │ │ │ │ ├── d2ae3188-0d70-4e2e-b1b5-6df2971185cf.jpg │ │ │ │ ├── d36da4d2-723c-4860-a1ae-06ec45c8bbae.jpg │ │ │ │ ├── d710d2fe-ecee-458f-b478-65b32bedc7d4.jpg │ │ │ │ ├── e63df136-c6f7-4cc9-a1f9-c73ddc635e2e.jpg │ │ │ │ ├── e656282b-2e69-4c66-8351-9b4c9eaff541.jpg │ │ │ │ ├── e8fd2614-0fc7-432a-b9fd-00ed5f24f3a3.jpg │ │ │ │ ├── ef0015d5-7c1f-4af4-a254-a899753a4126.jpg │ │ │ │ ├── f2725bec-63b0-11e7-907b-a6006ad3dba0.jpg │ │ │ │ └── fb9a98ce-0b30-485b-af53-3b6c780aa299.jpg │ │ │ └── charles │ │ │ │ ├── 0a6e7c09-6361-4e9f-9bc4-778bb7656bc4.png │ │ │ │ ├── 0dc3e6f6-250e-4172-af30-83b91cfddf76.png │ │ │ │ ├── 0fa6ff3f-c1f8-4179-b458-b21cc63e02c2.png │ │ │ │ ├── 1bfe09f1-69a9-4b43-a39c-3d26e067d27a.png │ │ │ │ ├── 1fb741c8-4170-47fa-ad0f-1929ae7857fd.png │ │ │ │ ├── 255707e0-725c-4e8e-932a-34b870031e40.png │ │ │ │ ├── 25753d81-3257-43b7-8f35-89436d888974.png │ │ │ │ ├── 28fe758a-e2c2-48ab-8132-f26f438e79e0.png │ │ │ │ ├── 41bdb338-fcba-4d56-ac55-207aed5560b4.png │ │ │ │ ├── 4ccdcd7b-0b54-43df-bf09-4887edf7800e.png │ │ │ │ ├── 4e97e097-b884-4db0-b07f-292a78a77544.png │ │ │ │ ├── 647b22ba-8441-45db-8386-1c64b6ca520e.png │ │ │ │ ├── 73350a4e-816d-4f91-91d5-2a6d1104c722.png │ │ │ │ ├── 7af98999-1276-478b-a443-b92b8986b788.png │ │ │ │ ├── b037c6ae-8a8a-45fd-9a1f-b3628db8b8d6.png │ │ │ │ ├── b0875e59-e049-4b62-93f7-02311d0d47e7.png │ │ │ │ ├── bfd83ef1-1e78-4bbb-aa0d-50e4591ca04e.jpg │ │ │ │ ├── c8e71602-2bde-4b7a-850f-bde0b0a17084.png │ │ │ │ ├── d3193cee-783b-43c0-99c3-ac98ec52aaa6.png │ │ │ │ ├── d40b7bd9-3b1d-4901-816a-dd706909c48b.png │ │ │ │ ├── d97cf8fa-5e7f-4c3e-905f-ec0ed12038dd.png │ │ │ │ ├── dfa1e7c1-9072-4e33-836a-cdd62709af67.png │ │ │ │ ├── fab69a4a-17c1-4944-81c9-255ff33ff815.png │ │ │ │ └── fe7c1302-4101-4882-ae0f-a3d395bdb960.png │ │ ├── 08 │ │ │ ├── api-version │ │ │ │ └── 114d5a46452f82018a1f0aaee82fdfab.png │ │ │ ├── bitmap │ │ │ │ ├── 1605c694-bf55-4500-9531-9832df13b082.jpg │ │ │ │ ├── 1da4242d-018f-4cf4-82c3-e3421b4cf003.jpg │ │ │ │ ├── 1dbec168-cbf6-4b42-bb56-ca143f559d06.jpg │ │ │ │ ├── 24836d0b-efb2-450f-9307-d078722e2c72.jpg │ │ │ │ ├── 2ecb7934-8521-4b03-a13d-27a884d2cb18.jpg │ │ │ │ ├── 2f3a90c8-afe8-4d5c-995a-d064ac1f5336.png │ │ │ │ ├── 3933f7cb-934c-42e7-8fc7-989b3e021010.jpg │ │ │ │ ├── 3c423c70-2ed7-4cc4-a6fa-ce56bf285a5b.jpg │ │ │ │ ├── 45ef8692-b1d3-4b4b-a6ed-dbe105fb3f97.png │ │ │ │ ├── 57833b05-cf4c-4f30-8ff2-a5c5f3682139.jpg │ │ │ │ ├── 5ad4199b-e5d1-45f9-9657-98f2f2c34960.png │ │ │ │ ├── 63f0f0a2-22e4-49dd-bcec-47e43fc69787.jpg │ │ │ │ ├── 8be164ef-9f6a-4a56-8a5d-53b417c9310a.jpg │ │ │ │ ├── 92401d1b-02ac-446f-908e-3057fa9c7fd4.jpg │ │ │ │ ├── 97c98774-03b3-47ed-852c-71d1a546a65c.jpg │ │ │ │ ├── 98132f45-baeb-4317-823f-28994b6a1b53.jpg │ │ │ │ ├── a134be42-9acb-41c6-bc80-469b86de8ba0.png │ │ │ │ ├── a9997194-b4d8-4cf5-bb3e-33a68229729b.jpg │ │ │ │ ├── b94201a7-beaf-4613-beda-f7a3674f5228.jpg │ │ │ │ ├── b94d2ee6-08b8-46bb-bc14-648d25f3d1b0.jpg │ │ │ │ ├── bf0f2d59-b0de-4f96-b598-ffccb8677758.jpg │ │ │ │ ├── bf6bf8d3-3801-4fca-b229-8cc83ea5ba81.jpg │ │ │ │ ├── d14eff84-5eb1-4268-87ae-4776c66af4a5.jpg │ │ │ │ ├── d68e8fa2-433a-47dc-8aed-ff1b993cf082.png │ │ │ │ ├── de158ff0-a75a-4742-890f-7f8fa54e8429.jpg │ │ │ │ ├── e0e6f586-03ce-4d11-a390-34ff3c25400b.jpg │ │ │ │ ├── e72e268a-facd-4480-85be-c779db24ee74.jpg │ │ │ │ ├── e897a05e-90c5-442f-8700-b07650c5bb79.png │ │ │ │ ├── eda83296-8ff6-4558-975c-a73860cccc54.png │ │ │ │ ├── f0c74969-652b-4fa2-b980-fc4f5f99c61d.jpg │ │ │ │ ├── f4079a06-d308-4f25-ad37-46f2d1baf851.png │ │ │ │ ├── f9dc49b3-503c-427e-8256-7db81b39466f.jpg │ │ │ │ └── fc1939b6-a486-4998-9507-c3e5825bce9a.png │ │ │ ├── id-card │ │ │ │ └── 05f73384-a9ba-4a80-8433-563331dfd896.jpg │ │ │ ├── solr-search │ │ │ │ └── c4665602-82dc-4cc3-9eaf-c0ed12935d08.png │ │ │ ├── redis-pipelining │ │ │ │ └── abc8ae13-9f76-4cd0-902d-a4fbb9fedd4f.png │ │ │ ├── solr-install-push │ │ │ │ └── 43735106-acb6-4f42-a136-dd5ab347ef49.png │ │ │ ├── elasticsearch-search │ │ │ │ └── 9a3accb9-0da1-47e4-ad58-428370464af6.jpg │ │ │ ├── elasticsearch-advanced-search │ │ │ │ └── d758139c-86ce-4472-89e8-7eb385cf7991.jpg │ │ │ ├── redis-pipelining.md │ │ │ └── id-card.md │ │ ├── 04 │ │ │ ├── array-form-max-string │ │ │ │ ├── 65FD0FD202413415D266AC754A75AAF3.png │ │ │ │ └── 57f35c24-2eeb-4c68-bf28-0771b11cad34.png │ │ │ └── array-form-max-string.md │ │ └── 05 │ │ │ └── draw-by-prob.md │ ├── 2018 │ │ ├── 11 │ │ │ └── load-balance-round-robin │ │ │ │ └── 1e858872-6235-4131-98ba-433690eb32c1.jpg │ │ ├── 12 │ │ │ └── load-balance-smooth-weighted-round-robin │ │ │ │ └── fc16ba37-06b0-4193-9969-7541852dd46c.jpg │ │ ├── 02 │ │ │ └── linux-skill │ │ │ │ ├── 2a82ad6b-ab25-409f-858c-22312826ac06.jpg │ │ │ │ └── 7bb99049-49bd-427b-a338-3afff4268fb3.jpg │ │ ├── 03 │ │ │ ├── hexo-deploy │ │ │ │ ├── 082786eb-0903-4776-a345-e52d25de2e49.png │ │ │ │ ├── 12b62d2e-7e26-4a3c-a770-e0d16d5c2254.png │ │ │ │ ├── 3b8f20b3-f3b2-498d-afa4-d60391c47db5.png │ │ │ │ ├── 9ee84981-7d79-47f5-98f8-e7500eff6e67.png │ │ │ │ ├── bf3adf97-088b-47cd-b5ab-377a4f4acd44.png │ │ │ │ ├── cd4f6674-aba5-4cbc-87e6-18c0c230585b.png │ │ │ │ └── f2ec7449-ae8a-4f6a-8dfa-95d6abf4aaa6.png │ │ │ └── hexo-deploy.md │ │ ├── 06 │ │ │ ├── beijing-to-chengdu │ │ │ │ ├── 0149bcaf-f380-4ef3-b6e1-331b452d636a.jpg │ │ │ │ ├── 0f8ebfc5-3d54-489e-9dc3-ee74bd4d61d0.jpg │ │ │ │ ├── 234987d5-3dd2-4736-b32c-b843ff42505e.jpg │ │ │ │ ├── 30121dc4-7b67-11e8-adc0-fa7ae01bbebc.jpg │ │ │ │ ├── 4c7fd01e-91ce-48f5-a47b-5ee6500a5d5d.jpg │ │ │ │ ├── 53bc46b9-b1eb-4c3d-88ff-68b44bce5429.jpg │ │ │ │ ├── 59554de4-62c2-440b-af63-384ebcf79b24.jpg │ │ │ │ ├── 6054d4bf-b6fe-4dac-ab25-4f6653bc880f.jpg │ │ │ │ ├── 745d2ec3-6618-4fc0-9f30-4bee52496670.jpg │ │ │ │ ├── 8111a4fc-7b66-11e8-adc0-fa7ae01bbebc.jpg │ │ │ │ ├── 88d071da-7b6d-11e8-adc0-fa7ae01bbebc.jpg │ │ │ │ └── de39aeb3-5481-4181-a45c-b503ec16cd0a.jpg │ │ │ └── beijing-to-chengdu.md │ │ ├── 01 │ │ │ └── 2018-new-year-activity │ │ │ │ ├── 3a9dff7a-71f1-4d9d-a576-a3dcbaf65c9b.png │ │ │ │ ├── 9a15f5d1-0983-4155-80e4-ba55e5543672.png │ │ │ │ ├── 9cf63edb-315e-4951-9d7f-531953741e52.png │ │ │ │ ├── a3f34d9b-55cd-4931-8557-63f9b6767a79.jpg │ │ │ │ ├── b19eec7a-978b-4ddc-8c8b-13c643c27b48.png │ │ │ │ ├── de5070ca-fd29-493e-b433-28520a8aaa1a.png │ │ │ │ └── f405ee75-8e06-4f72-a8c5-60a155cc0ead.png │ │ ├── 08 │ │ │ └── process-php-basic-knowledge │ │ │ │ ├── 0f31694b-b96f-48f2-92f4-56552bded7f4.jpg │ │ │ │ ├── 80e3b1cf-51d8-4342-a08a-976b3a7b3c8c.png │ │ │ │ ├── c18f0a31-dade-49e0-90b3-308b7ce63ef6.jpg │ │ │ │ ├── dab56833-15dc-405e-b359-4a4fa0e305bc.jpg │ │ │ │ ├── f6eb7888-6de6-41a4-8d15-4d471825a24e.jpg │ │ │ │ └── f85ea400-6623-44ae-88c4-efc9ef1fa315.jpg │ │ └── 09 │ │ │ └── process-php-multiprocess-server │ │ │ ├── 22ed9e46-971c-4983-8bf5-65d321585d42.png │ │ │ ├── 34f35d33-57b2-41d7-b738-f0c1c712102f.png │ │ │ ├── 4c5ec8d3-e56e-4367-8856-beaf23ee7602.png │ │ │ ├── 8e65456f-8e08-4ae8-84f8-e6f2278410e4.png │ │ │ ├── ad804eb2-9300-4d34-ae63-3b820d81d4b1.png │ │ │ ├── db333298-5a10-4de3-b0b2-41088cafc77f.png │ │ │ ├── e0e86073-3093-4e5f-be20-b64510e61575.png │ │ │ └── fc458e5f-fccc-477f-9e18-eada5d856289.png │ ├── 2019 │ │ └── 02 │ │ │ └── multi-currency-price │ │ │ ├── 434ddc25-3b51-4753-b5d5-b765ac5ca30c.jpg │ │ │ ├── 4ff6ceb3-44c9-4edf-bfdb-23cf50b22c6f.png │ │ │ └── b5c63729-fd94-4f3b-b107-1b345d26c1c6.png │ ├── 2020 │ │ ├── 12 │ │ │ └── hexo-to-docker │ │ │ │ └── 704035c6-348e-439b-9048-d05a2a18ef1f.png │ │ ├── 05 │ │ │ ├── use-kafka │ │ │ │ ├── 1589251986346.png │ │ │ │ ├── 1589258896838.jpg │ │ │ │ ├── 1589258912991.jpg │ │ │ │ └── 1589262505081.png │ │ │ └── use-kafka.md │ │ └── 07 │ │ │ ├── openapi │ │ │ ├── 1a902abb-fb35-42e1-9f3a-c18e12074f11.png │ │ │ ├── 3321e082-1857-4c2b-8d19-a60334f9b4f5.png │ │ │ ├── 39befe95-381e-47ad-879d-e5433e778078.png │ │ │ ├── 48e89e9b-eede-4aec-b98f-ce50cc112c99.png │ │ │ ├── 4b6660db-0e0c-4c6d-9716-0e63820f45e1.png │ │ │ ├── 549e72de-cdbd-4b8d-a238-085f226d7555.jpg │ │ │ ├── 676dcc84-628d-493c-8ab6-c9f2ec3053df.png │ │ │ ├── 9655aec3-aa6c-4353-819e-a095a0fdd5bf.png │ │ │ ├── a4768e8e-f961-4270-ba9d-69d2a317d49b.png │ │ │ ├── ae062ec1-7f3c-4535-916b-c9cd08734a7d.jpg │ │ │ ├── ba4a385e-add6-40fe-aa30-40866f8e4f40.png │ │ │ ├── c6987388-682d-403f-8621-caa1fa6cd266.png │ │ │ ├── d0131310-b7f8-4deb-aa9e-fcc6b28a47a2.png │ │ │ ├── f227c462-b9b9-4846-aeae-23c579b05087.jpeg │ │ │ └── ffc6e25d-7044-467d-8b7c-910831249968.jpeg │ │ │ └── openapi.md │ ├── 2021 │ │ └── 12 │ │ │ ├── 2021-personal-summary │ │ │ ├── 10183cff-d8cc-4e5f-97cb-b897a256bd41.png │ │ │ └── a2d1e849-2e1f-42a3-a054-69005e91755b.jpg │ │ │ └── 2021-personal-summary.md │ ├── 2022 │ │ ├── 12 │ │ │ ├── user-profile-use-flink │ │ │ │ ├── 082D3F30-8845-4943-AC1E-6AF494885350.png │ │ │ │ ├── 4C7CA16C-53B3-455A-86B0-D0917B69C21E.png │ │ │ │ ├── 96A9AAFE-201F-48DF-8318-ED035B06269C.png │ │ │ │ ├── DD0DBEE8-32B8-4A78-B0A2-3907A710907A.png │ │ │ │ └── FAA84305-96B3-4934-8991-C5ACE2752C5A.png │ │ │ └── user-profile-use-flink.md │ │ └── 06 │ │ │ └── risk-rule │ │ │ ├── 07072d15-ffc0-434e-9417-cc04fd0ae979.png │ │ │ ├── 08e98b72-3fbd-4c58-a8a4-aa88af950499.png │ │ │ ├── 24476377-1566-4cfd-bcd6-3d8af562e57c.png │ │ │ ├── 2cf3e5c4-2a75-4f3b-a51e-f0a206a386e8.png │ │ │ ├── 5d6f4a50-a372-4280-bdef-df106aa1684b.png │ │ │ ├── 6c0c61f3-f53b-4a3e-bc40-caa4e868e981.png │ │ │ ├── 75345e28-87b4-4b77-8912-606821c5d08d.png │ │ │ ├── c3d8e074-443d-4b14-9533-ff45fd32a4c7.png │ │ │ ├── c54f0ab7-1a73-4c2e-998c-76d02148c8dc.png │ │ │ ├── ccd31bea-13f9-456e-b908-9d682e2bd5c3.png │ │ │ ├── cd83c013-eccc-42ce-8075-5fd7267edf3d.png │ │ │ └── d50d0ac4-e740-4ee5-a744-b8c9a593a8be.png │ ├── 2023 │ │ └── 01 │ │ │ ├── recommender-system │ │ │ ├── 19F578B4-4B33-4F28-AAE4-D4C71308A360.png │ │ │ ├── 41C31DFF-9546-413B-82A5-794DC47488B7.png │ │ │ ├── 5D1A9AD7-9EDF-4607-A2D2-8B73D9FEA7B5.png │ │ │ ├── 5FF361FE-B7B5-4A01-9DA5-CF9AEC5B7462.png │ │ │ ├── 74661B99-43E6-4532-9B93-AAB9469E5DD1.png │ │ │ ├── 7A956F05-52D9-4B2F-9466-62883F81958D.png │ │ │ ├── 97FD0BB9-EA8C-4BBD-BAAA-8721149084F3.png │ │ │ ├── B4417679-0FCA-4EA0-8E95-CAA95912C05E.png │ │ │ ├── BD317F5E-8689-4139-BE07-FC82C6EEA69A.png │ │ │ ├── D1C891D1-878A-4B95-97D7-BBA7AFAB3467.png │ │ │ ├── E2A4D0D2-EA74-4130-A8CE-4B7FBD9E9E40.png │ │ │ └── E7E33224-409F-44E4-8A39-EDA85F89435C.png │ │ │ └── recommender-system.md │ └── 2024 │ │ └── 04 │ │ └── design-rule-engine │ │ ├── 12805423-37FB-4225-91E3-EC6473BA720C.png │ │ ├── 30B59826-F443-4D9A-AC98-42F7E28127D5.png │ │ ├── 36E0B373-95A2-4E26-AFE2-ED9522CCB708.png │ │ ├── 6082eaf6-9534-4989-86d6-2422a3ab54b0.png │ │ ├── 65ebb70a-3e2d-4e20-a1f2-227fc08c0669.png │ │ ├── C0C5B489-90D1-4937-A8D8-55459E951ABC.png │ │ ├── C290970F-D33E-49DF-846B-577E62694709.png │ │ ├── E937E855-8B7C-4B4C-9761-0764D563BE42.png │ │ └── gengine.g4 ├── robots.txt ├── README.md ├── 404.html └── _data │ ├── project.json │ └── reading.json ├── ssl-override.yml ├── .gitmodules ├── .gitignore ├── dockerfiles └── nginx │ ├── conf.d │ ├── http │ │ ├── default.conf │ │ └── www.conf │ ├── common │ ├── https │ │ ├── cert.conf │ │ └── www.conf │ └── rewrite │ ├── Dockerfile │ ├── start.sh │ ├── ssl │ ├── init_ssl.sh │ └── refresh_cert.sh │ └── nginx.conf ├── docker.example.env ├── docker-compose.yml ├── hooks.json ├── package.json ├── _config.yml └── README.md /source/CNAME: -------------------------------------------------------------------------------- 1 | www.fanhaobai.com -------------------------------------------------------------------------------- /source/reading/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 读书 3 | layout: reading 4 | --- 5 | -------------------------------------------------------------------------------- /source/view.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/view.png -------------------------------------------------------------------------------- /source/header.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/header.jpg -------------------------------------------------------------------------------- /source/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/favicon.ico -------------------------------------------------------------------------------- /source/wechat.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/wechat.jpeg -------------------------------------------------------------------------------- /source/project/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 作品 3 | layout: project 4 | date: 2016-01-05 5 | --- 6 | -------------------------------------------------------------------------------- /ssl-override.yml: -------------------------------------------------------------------------------- 1 | version: 'prod' 2 | services: 3 | nginx: 4 | environment: 5 | - ENABLE_SSL=false -------------------------------------------------------------------------------- /source/project/index/php-server.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/project/index/php-server.jpg -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "themes/yilia"] 2 | path = themes/yilia 3 | url = https://github.com/howborn/hexo-theme-yilia.git 4 | -------------------------------------------------------------------------------- /source/project/index/smart-car-freescale.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/project/index/smart-car-freescale.png -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | .DS_Store 3 | .deploy_git 4 | 5 | package-lock.json 6 | db.json 7 | docker.env 8 | 9 | public 10 | node_modules -------------------------------------------------------------------------------- /source/about/index/1b8RAFgTPJ65AAY7vARIDYLa.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/about/index/1b8RAFgTPJ65AAY7vARIDYLa.jpg -------------------------------------------------------------------------------- /source/about/index/9fPXD11M-qsaym50SNAkwFl_.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/about/index/9fPXD11M-qsaym50SNAkwFl_.png -------------------------------------------------------------------------------- /source/about/index/O_tDRRtwdgwUJGleCTb-fJvl.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/about/index/O_tDRRtwdgwUJGleCTb-fJvl.jpg -------------------------------------------------------------------------------- /source/about/index/UtjFTjHOIYx92yaA6wsdh0GD.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/about/index/UtjFTjHOIYx92yaA6wsdh0GD.png -------------------------------------------------------------------------------- /source/about/index/fQm_6CQKLTPRYXQ_vPInMijE.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/about/index/fQm_6CQKLTPRYXQ_vPInMijE.jpg -------------------------------------------------------------------------------- /source/about/index/oIvyC4BVfC358zcqI3_8kQua.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/about/index/oIvyC4BVfC358zcqI3_8kQua.png -------------------------------------------------------------------------------- /source/project/index/electron-component-3d.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/project/index/electron-component-3d.png -------------------------------------------------------------------------------- /source/_posts/2020/05/use-kafka/1589251986346.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2020/05/use-kafka/1589251986346.png -------------------------------------------------------------------------------- /source/_posts/2020/05/use-kafka/1589258896838.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2020/05/use-kafka/1589258896838.jpg -------------------------------------------------------------------------------- /source/_posts/2020/05/use-kafka/1589258912991.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2020/05/use-kafka/1589258912991.jpg -------------------------------------------------------------------------------- /source/_posts/2020/05/use-kafka/1589262505081.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2020/05/use-kafka/1589262505081.png -------------------------------------------------------------------------------- /source/project/index/6WaPq-7Kfi1wLVo5ZE2P1d0y.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/project/index/6WaPq-7Kfi1wLVo5ZE2P1d0y.jpg -------------------------------------------------------------------------------- /source/project/index/CVyYJnKtigzaHiRQOKmtfMZE.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/project/index/CVyYJnKtigzaHiRQOKmtfMZE.jpg -------------------------------------------------------------------------------- /source/project/index/W44BkT8TENzNCoih07mEyLN-.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/project/index/W44BkT8TENzNCoih07mEyLN-.jpg -------------------------------------------------------------------------------- /source/_posts/2017/01/robots/5PCU9neptZdG3aY5veYsls0v.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/01/robots/5PCU9neptZdG3aY5veYsls0v.png -------------------------------------------------------------------------------- /source/_posts/2017/01/robots/FozbmxH8U0MTs0N-teFaCtWa.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/01/robots/FozbmxH8U0MTs0N-teFaCtWa.jpg -------------------------------------------------------------------------------- /source/_posts/2017/01/robots/n9DQpbXNbazisDMy_bouP7HN.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/01/robots/n9DQpbXNbazisDMy_bouP7HN.png -------------------------------------------------------------------------------- /source/_posts/2017/01/robots/xWjjcJzJrrhkjH6lWy7aZib_.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/01/robots/xWjjcJzJrrhkjH6lWy7aZib_.png -------------------------------------------------------------------------------- /source/_posts/2017/02/reward/Dd5AQhhljSVuOdmUAngQ0Zka.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/02/reward/Dd5AQhhljSVuOdmUAngQ0Zka.png -------------------------------------------------------------------------------- /source/_posts/2017/02/reward/JXPHry2Rdd_PuvEwsaZrFJTq.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/02/reward/JXPHry2Rdd_PuvEwsaZrFJTq.png -------------------------------------------------------------------------------- /source/_posts/2017/02/reward/p4GlWAFMrXts5zPMnA88Zsm_.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/02/reward/p4GlWAFMrXts5zPMnA88Zsm_.png -------------------------------------------------------------------------------- /source/_posts/2016/10/im-thread/fd1WM_W61si6GKLhz1QKjx0v.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2016/10/im-thread/fd1WM_W61si6GKLhz1QKjx0v.jpg -------------------------------------------------------------------------------- /source/about/index/6e6ade44-bc83-4a25-8b36-b41c5a0186a0.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/about/index/6e6ade44-bc83-4a25-8b36-b41c5a0186a0.jpg -------------------------------------------------------------------------------- /source/about/index/7f5c2e7f-2dc8-46eb-9867-ca1c3fbd5fda.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/about/index/7f5c2e7f-2dc8-46eb-9867-ca1c3fbd5fda.jpg -------------------------------------------------------------------------------- /source/about/index/7fbbc22c-3a0f-466b-87bb-d8d27367c419.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/about/index/7fbbc22c-3a0f-466b-87bb-d8d27367c419.gif -------------------------------------------------------------------------------- /source/about/index/8aded4ae-807e-41fa-913d-5f28726a447d.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/about/index/8aded4ae-807e-41fa-913d-5f28726a447d.png -------------------------------------------------------------------------------- /source/about/index/98857854-705b-4306-a360-a32f78d87390.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/about/index/98857854-705b-4306-a360-a32f78d87390.png -------------------------------------------------------------------------------- /source/about/index/ffd01abc-1dc8-41b9-b6c4-004f779dddf3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/about/index/ffd01abc-1dc8-41b9-b6c4-004f779dddf3.png -------------------------------------------------------------------------------- /source/_posts/2017/09/lua/84414e900ee77fc8fd1baf9fc9c7a7d7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/09/lua/84414e900ee77fc8fd1baf9fc9c7a7d7.png -------------------------------------------------------------------------------- /source/_posts/2017/09/lua/fe33e61ca081f36909b9f2d16b5c9d4b.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/09/lua/fe33e61ca081f36909b9f2d16b5c9d4b.png -------------------------------------------------------------------------------- /source/project/index/7742c67c-388c-4965-8a76-fcbf63b9a4fc.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/project/index/7742c67c-388c-4965-8a76-fcbf63b9a4fc.jpg -------------------------------------------------------------------------------- /source/_posts/2017/03/install-hexo/es8bUSE01LiIgQtbSESyEWxW.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/03/install-hexo/es8bUSE01LiIgQtbSESyEWxW.png -------------------------------------------------------------------------------- /source/_posts/2017/07/b-/059c4183-9028-4abe-89c6-c12d9393d36e.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/07/b-/059c4183-9028-4abe-89c6-c12d9393d36e.jpg -------------------------------------------------------------------------------- /source/_posts/2017/07/b-/05afc638-3c1a-4020-98bd-78fa0ba6826d.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/07/b-/05afc638-3c1a-4020-98bd-78fa0ba6826d.jpg -------------------------------------------------------------------------------- /source/_posts/2017/07/b-/070ad465-7638-4f4c-8c4d-ef3e7ceff2a6.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/07/b-/070ad465-7638-4f4c-8c4d-ef3e7ceff2a6.jpg -------------------------------------------------------------------------------- /source/_posts/2017/07/b-/0986b67c-7e37-4411-b057-9dbbf20930bb.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/07/b-/0986b67c-7e37-4411-b057-9dbbf20930bb.jpg -------------------------------------------------------------------------------- /source/_posts/2017/07/b-/0fde9df2-c850-47d8-949d-398b8f3e831f.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/07/b-/0fde9df2-c850-47d8-949d-398b8f3e831f.jpg -------------------------------------------------------------------------------- /source/_posts/2017/07/b-/112d602b-917a-4a11-a227-f3355bcc5d95.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/07/b-/112d602b-917a-4a11-a227-f3355bcc5d95.jpg -------------------------------------------------------------------------------- /source/_posts/2017/07/b-/12e9c3d2-280c-41ff-b5fd-67d79d884f3a.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/07/b-/12e9c3d2-280c-41ff-b5fd-67d79d884f3a.jpg -------------------------------------------------------------------------------- /source/_posts/2017/07/b-/14f6e592-ee53-42d7-b06b-050c595b2826.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/07/b-/14f6e592-ee53-42d7-b06b-050c595b2826.jpg -------------------------------------------------------------------------------- /source/_posts/2017/07/b-/180daa1d-b025-423a-89f5-0c5cd94af1e9.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/07/b-/180daa1d-b025-423a-89f5-0c5cd94af1e9.jpg -------------------------------------------------------------------------------- /source/_posts/2017/07/b-/19301a61-5d3f-422f-b66e-4853fd5c7caf.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/07/b-/19301a61-5d3f-422f-b66e-4853fd5c7caf.jpg -------------------------------------------------------------------------------- /source/_posts/2017/07/b-/1c9bb154-d47b-49ad-a33b-51a74021eb15.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/07/b-/1c9bb154-d47b-49ad-a33b-51a74021eb15.jpg -------------------------------------------------------------------------------- /source/_posts/2017/07/b-/1f161fac-1327-4649-a31e-33bc5efd693a.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/07/b-/1f161fac-1327-4649-a31e-33bc5efd693a.jpg -------------------------------------------------------------------------------- /source/_posts/2017/07/b-/20763cbb-12b3-4e9a-a00b-1759e1356231.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/07/b-/20763cbb-12b3-4e9a-a00b-1759e1356231.jpg -------------------------------------------------------------------------------- /source/_posts/2017/07/b-/2ad346da-5243-492e-b30d-560a744c622e.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/07/b-/2ad346da-5243-492e-b30d-560a744c622e.jpg -------------------------------------------------------------------------------- /source/_posts/2017/07/b-/2c252095-aafa-4f84-8d76-d4c0285d209f.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/07/b-/2c252095-aafa-4f84-8d76-d4c0285d209f.jpg -------------------------------------------------------------------------------- /source/_posts/2017/07/b-/2cd5bcec-3f3f-4ae7-959e-071d07ec1c3b.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/07/b-/2cd5bcec-3f3f-4ae7-959e-071d07ec1c3b.jpg -------------------------------------------------------------------------------- /source/_posts/2017/07/b-/397c217f-b0bf-4a11-84b4-34b82d2c6642.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/07/b-/397c217f-b0bf-4a11-84b4-34b82d2c6642.jpg -------------------------------------------------------------------------------- /source/_posts/2017/07/b-/3adf96f5-9791-44ff-b423-26cb34741be1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/07/b-/3adf96f5-9791-44ff-b423-26cb34741be1.jpg -------------------------------------------------------------------------------- /source/_posts/2017/07/b-/42085b9b-c60f-4d6b-bce4-056bb60f9b82.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/07/b-/42085b9b-c60f-4d6b-bce4-056bb60f9b82.jpg -------------------------------------------------------------------------------- /source/_posts/2017/07/b-/44f988cf-7a51-4863-88f0-766e99fb9f4e.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/07/b-/44f988cf-7a51-4863-88f0-766e99fb9f4e.jpg -------------------------------------------------------------------------------- /source/_posts/2017/07/b-/454f21ea-4f34-4556-9641-cee74178b34a.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/07/b-/454f21ea-4f34-4556-9641-cee74178b34a.jpg -------------------------------------------------------------------------------- /source/_posts/2017/07/b-/4b90f113-fa96-4189-8804-73e8b1ff682e.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/07/b-/4b90f113-fa96-4189-8804-73e8b1ff682e.jpg -------------------------------------------------------------------------------- /source/_posts/2017/07/b-/520badf6-ab99-4bbb-8c8a-5962900b4a51.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/07/b-/520badf6-ab99-4bbb-8c8a-5962900b4a51.jpg -------------------------------------------------------------------------------- /source/_posts/2017/07/b-/53719e92-49f8-450b-9ffc-f2cfbb96295a.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/07/b-/53719e92-49f8-450b-9ffc-f2cfbb96295a.jpg -------------------------------------------------------------------------------- /source/_posts/2017/07/b-/5ec15194-a2fa-4431-83ba-53b3ba63be8f.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/07/b-/5ec15194-a2fa-4431-83ba-53b3ba63be8f.jpg -------------------------------------------------------------------------------- /source/_posts/2017/07/b-/5f468cb8-857c-4d67-8772-d86ee9d9340d.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/07/b-/5f468cb8-857c-4d67-8772-d86ee9d9340d.jpg -------------------------------------------------------------------------------- /source/_posts/2017/07/b-/60f11fd4-1c37-44a9-8d1c-f1a194559e37.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/07/b-/60f11fd4-1c37-44a9-8d1c-f1a194559e37.jpg -------------------------------------------------------------------------------- /source/_posts/2017/07/b-/6137cf60-4db5-4e63-ba41-cea1dfe1de61.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/07/b-/6137cf60-4db5-4e63-ba41-cea1dfe1de61.jpg -------------------------------------------------------------------------------- /source/_posts/2017/07/b-/6368f5b1-d08e-488c-b23e-a9cf783ea481.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/07/b-/6368f5b1-d08e-488c-b23e-a9cf783ea481.jpg -------------------------------------------------------------------------------- /source/_posts/2017/07/b-/6421f60a-6bd4-4c11-bd00-e6864b6c2f7c.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/07/b-/6421f60a-6bd4-4c11-bd00-e6864b6c2f7c.jpg -------------------------------------------------------------------------------- /source/_posts/2017/07/b-/6b29f560-e192-4558-a399-5e125ca893e0.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/07/b-/6b29f560-e192-4558-a399-5e125ca893e0.jpg -------------------------------------------------------------------------------- /source/_posts/2017/07/b-/76ee8b6f-b653-416b-bb44-99101a6fc40f.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/07/b-/76ee8b6f-b653-416b-bb44-99101a6fc40f.jpg -------------------------------------------------------------------------------- /source/_posts/2017/07/b-/78e65b5a-c9c1-4e19-841b-a06879f70032.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/07/b-/78e65b5a-c9c1-4e19-841b-a06879f70032.jpg -------------------------------------------------------------------------------- /source/_posts/2017/07/b-/82d68b72-0dd0-4371-a8e7-a66dcf80a0e0.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/07/b-/82d68b72-0dd0-4371-a8e7-a66dcf80a0e0.jpg -------------------------------------------------------------------------------- /source/_posts/2017/07/b-/842c3607-8a20-405f-8a16-12b26ab75b8d.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/07/b-/842c3607-8a20-405f-8a16-12b26ab75b8d.jpg -------------------------------------------------------------------------------- /source/_posts/2017/07/b-/8438d6ce-bd67-4d4e-9dd4-06493d0ef144.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/07/b-/8438d6ce-bd67-4d4e-9dd4-06493d0ef144.jpg -------------------------------------------------------------------------------- /source/_posts/2017/07/b-/84af8a44-4f88-450b-9286-eec57e8ac003.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/07/b-/84af8a44-4f88-450b-9286-eec57e8ac003.jpg -------------------------------------------------------------------------------- /source/_posts/2017/07/b-/855e1037-3a90-49bb-8310-d9e3911962cf.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/07/b-/855e1037-3a90-49bb-8310-d9e3911962cf.jpg -------------------------------------------------------------------------------- /source/_posts/2017/07/b-/86fe22ab-fd0b-4ca0-a846-b5dc701c6581.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/07/b-/86fe22ab-fd0b-4ca0-a846-b5dc701c6581.jpg -------------------------------------------------------------------------------- /source/_posts/2017/07/b-/87a0a1d6-fa9e-4a1f-9e9a-6c07ec5c5509.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/07/b-/87a0a1d6-fa9e-4a1f-9e9a-6c07ec5c5509.jpg -------------------------------------------------------------------------------- /source/_posts/2017/07/b-/9628d43f-4569-4716-a1e4-ce23931b96f7.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/07/b-/9628d43f-4569-4716-a1e4-ce23931b96f7.jpg -------------------------------------------------------------------------------- /source/_posts/2017/07/b-/9ad3c9a8-a874-4a25-a51d-25c8bb440b6c.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/07/b-/9ad3c9a8-a874-4a25-a51d-25c8bb440b6c.jpg -------------------------------------------------------------------------------- /source/_posts/2017/07/b-/9b9ee0cb-50a2-418d-bcaf-4e30707bd886.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/07/b-/9b9ee0cb-50a2-418d-bcaf-4e30707bd886.jpg -------------------------------------------------------------------------------- /source/_posts/2017/07/b-/9ea9ea0e-d6a6-42ae-aace-5a1661ff9cc4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/07/b-/9ea9ea0e-d6a6-42ae-aace-5a1661ff9cc4.jpg -------------------------------------------------------------------------------- /source/_posts/2017/07/b-/a2c81ffd-01f9-4c73-8b03-2aa46d8edf6f.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/07/b-/a2c81ffd-01f9-4c73-8b03-2aa46d8edf6f.jpg -------------------------------------------------------------------------------- /source/_posts/2017/07/b-/a73a2881-7837-4b23-9c39-b6044dc0e26c.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/07/b-/a73a2881-7837-4b23-9c39-b6044dc0e26c.jpg -------------------------------------------------------------------------------- /source/_posts/2017/07/b-/a9c34b2b-a73c-4611-a05a-a67a0b3e63c5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/07/b-/a9c34b2b-a73c-4611-a05a-a67a0b3e63c5.jpg -------------------------------------------------------------------------------- /source/_posts/2017/07/b-/b98ea743-190d-449b-9253-b5e036d6d5ee.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/07/b-/b98ea743-190d-449b-9253-b5e036d6d5ee.jpg -------------------------------------------------------------------------------- /source/_posts/2017/07/b-/ba56f5d6-e9e7-41bf-a9d7-3045cbb1f114.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/07/b-/ba56f5d6-e9e7-41bf-a9d7-3045cbb1f114.jpg -------------------------------------------------------------------------------- /source/_posts/2017/07/b-/bc424688-fa4c-4afd-91a9-67a0be2a08ad.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/07/b-/bc424688-fa4c-4afd-91a9-67a0be2a08ad.png -------------------------------------------------------------------------------- /source/_posts/2017/07/b-/bca1c1cc-587d-4b6c-be28-9f92650ad1e5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/07/b-/bca1c1cc-587d-4b6c-be28-9f92650ad1e5.jpg -------------------------------------------------------------------------------- /source/_posts/2017/07/b-/bf42c5e0-2a17-4e30-8e3d-8689f5130652.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/07/b-/bf42c5e0-2a17-4e30-8e3d-8689f5130652.jpg -------------------------------------------------------------------------------- /source/_posts/2017/07/b-/c2045edc-f98d-43b1-a21e-d0dbecf39c4b.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/07/b-/c2045edc-f98d-43b1-a21e-d0dbecf39c4b.jpg -------------------------------------------------------------------------------- /source/_posts/2017/07/b-/c5a8411b-2233-47b7-9695-c99bf231fcdd.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/07/b-/c5a8411b-2233-47b7-9695-c99bf231fcdd.jpg -------------------------------------------------------------------------------- /source/_posts/2017/07/b-/d1c0b5a6-f9c2-4a84-9a0f-dc643fbaf0ef.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/07/b-/d1c0b5a6-f9c2-4a84-9a0f-dc643fbaf0ef.jpg -------------------------------------------------------------------------------- /source/_posts/2017/07/b-/d2135b8d-3cf3-4a54-93af-695145ffa485.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/07/b-/d2135b8d-3cf3-4a54-93af-695145ffa485.jpg -------------------------------------------------------------------------------- /source/_posts/2017/07/b-/d242bb97-31cc-41a9-9820-39947f1291b4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/07/b-/d242bb97-31cc-41a9-9820-39947f1291b4.jpg -------------------------------------------------------------------------------- /source/_posts/2017/07/b-/d2ae3188-0d70-4e2e-b1b5-6df2971185cf.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/07/b-/d2ae3188-0d70-4e2e-b1b5-6df2971185cf.jpg -------------------------------------------------------------------------------- /source/_posts/2017/07/b-/d36da4d2-723c-4860-a1ae-06ec45c8bbae.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/07/b-/d36da4d2-723c-4860-a1ae-06ec45c8bbae.jpg -------------------------------------------------------------------------------- /source/_posts/2017/07/b-/d710d2fe-ecee-458f-b478-65b32bedc7d4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/07/b-/d710d2fe-ecee-458f-b478-65b32bedc7d4.jpg -------------------------------------------------------------------------------- /source/_posts/2017/07/b-/e63df136-c6f7-4cc9-a1f9-c73ddc635e2e.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/07/b-/e63df136-c6f7-4cc9-a1f9-c73ddc635e2e.jpg -------------------------------------------------------------------------------- /source/_posts/2017/07/b-/e656282b-2e69-4c66-8351-9b4c9eaff541.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/07/b-/e656282b-2e69-4c66-8351-9b4c9eaff541.jpg -------------------------------------------------------------------------------- /source/_posts/2017/07/b-/e8fd2614-0fc7-432a-b9fd-00ed5f24f3a3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/07/b-/e8fd2614-0fc7-432a-b9fd-00ed5f24f3a3.jpg -------------------------------------------------------------------------------- /source/_posts/2017/07/b-/ef0015d5-7c1f-4af4-a254-a899753a4126.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/07/b-/ef0015d5-7c1f-4af4-a254-a899753a4126.jpg -------------------------------------------------------------------------------- /source/_posts/2017/07/b-/f2725bec-63b0-11e7-907b-a6006ad3dba0.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/07/b-/f2725bec-63b0-11e7-907b-a6006ad3dba0.jpg -------------------------------------------------------------------------------- /source/_posts/2017/07/b-/fb9a98ce-0b30-485b-af53-3b6c780aa299.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/07/b-/fb9a98ce-0b30-485b-af53-3b6c780aa299.jpg -------------------------------------------------------------------------------- /source/_posts/2017/09/lua/c391629e-be21-4038-ab25-b47fe368daeb.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/09/lua/c391629e-be21-4038-ab25-b47fe368daeb.jpg -------------------------------------------------------------------------------- /source/_posts/2017/09/lua/fc34646b-5eaf-45ba-b89a-0d8fc3f1b71d.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/09/lua/fc34646b-5eaf-45ba-b89a-0d8fc3f1b71d.png -------------------------------------------------------------------------------- /source/_posts/2017/12/elk/17b1a5c7-2897-46f2-becd-3f03f926bc0f.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/12/elk/17b1a5c7-2897-46f2-becd-3f03f926bc0f.png -------------------------------------------------------------------------------- /source/_posts/2017/12/elk/4b4a7b8a-c26e-48b2-af45-27655e06f397.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/12/elk/4b4a7b8a-c26e-48b2-af45-27655e06f397.png -------------------------------------------------------------------------------- /source/_posts/2017/12/elk/b19f74ae-2be3-4aef-b390-246acbf3050f.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/12/elk/b19f74ae-2be3-4aef-b390-246acbf3050f.png -------------------------------------------------------------------------------- /source/_posts/2017/12/elk/b488220c-e24a-4eaf-8ee9-81cc6ae9484c.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/12/elk/b488220c-e24a-4eaf-8ee9-81cc6ae9484c.png -------------------------------------------------------------------------------- /source/_posts/2017/12/elk/c0625948-b690-48ad-a178-63fc08b0cefb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/12/elk/c0625948-b690-48ad-a178-63fc08b0cefb.png -------------------------------------------------------------------------------- /source/_posts/2017/12/elk/c2f50522-4a60-47b5-80b3-69f194745e19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/12/elk/c2f50522-4a60-47b5-80b3-69f194745e19.png -------------------------------------------------------------------------------- /source/_posts/2017/12/elk/de986f14-1b7a-46f0-bf81-e477dda1e157.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/12/elk/de986f14-1b7a-46f0-bf81-e477dda1e157.png -------------------------------------------------------------------------------- /source/_posts/2016/05/mysql-index/09D4DC9D97CBE8A634D244232710688E.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2016/05/mysql-index/09D4DC9D97CBE8A634D244232710688E.png -------------------------------------------------------------------------------- /source/_posts/2016/05/mysql-index/0C246BB99D16D11FDF529437864AB7CE.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2016/05/mysql-index/0C246BB99D16D11FDF529437864AB7CE.png -------------------------------------------------------------------------------- /source/_posts/2016/05/mysql-index/1592A1D1B6F59FDEC422FF5FC1C97CC0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2016/05/mysql-index/1592A1D1B6F59FDEC422FF5FC1C97CC0.png -------------------------------------------------------------------------------- /source/_posts/2016/05/mysql-index/249AA6DD62821BDAC73892DEA1F61C4B.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2016/05/mysql-index/249AA6DD62821BDAC73892DEA1F61C4B.png -------------------------------------------------------------------------------- /source/_posts/2016/05/mysql-index/3A4B107A96CE4C008B15D740D19CAF98.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2016/05/mysql-index/3A4B107A96CE4C008B15D740D19CAF98.png -------------------------------------------------------------------------------- /source/_posts/2016/05/mysql-index/48E546C2BE936C4A7CA2BB19FE4AA6DE.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2016/05/mysql-index/48E546C2BE936C4A7CA2BB19FE4AA6DE.png -------------------------------------------------------------------------------- /source/_posts/2016/05/mysql-index/53542FB1F6F6B898BEE53F4AE356564A.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2016/05/mysql-index/53542FB1F6F6B898BEE53F4AE356564A.png -------------------------------------------------------------------------------- /source/_posts/2016/05/mysql-index/63B428EC932670CB74B3A1B6249407AA.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2016/05/mysql-index/63B428EC932670CB74B3A1B6249407AA.png -------------------------------------------------------------------------------- /source/_posts/2016/05/mysql-index/6D0B18886D8A8FB14E512CEEE869B07B.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2016/05/mysql-index/6D0B18886D8A8FB14E512CEEE869B07B.png -------------------------------------------------------------------------------- /source/_posts/2016/05/mysql-index/843424197A8FFFCD2894AC9B2F13302F.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2016/05/mysql-index/843424197A8FFFCD2894AC9B2F13302F.png -------------------------------------------------------------------------------- /source/_posts/2016/05/mysql-index/A561801D4FD4EAFB9FB7FB538ED8081F.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2016/05/mysql-index/A561801D4FD4EAFB9FB7FB538ED8081F.png -------------------------------------------------------------------------------- /source/_posts/2016/05/mysql-index/A9F238357681376D30DF3C6F524156FB.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2016/05/mysql-index/A9F238357681376D30DF3C6F524156FB.png -------------------------------------------------------------------------------- /source/_posts/2016/05/mysql-index/C6D5AF9F2923AFB70753E9B9556FE42A.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2016/05/mysql-index/C6D5AF9F2923AFB70753E9B9556FE42A.png -------------------------------------------------------------------------------- /source/_posts/2016/05/mysql-index/D13A43EAC5F0ECEE1FE1DA0AA06F69B4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2016/05/mysql-index/D13A43EAC5F0ECEE1FE1DA0AA06F69B4.png -------------------------------------------------------------------------------- /source/_posts/2017/07/charles/0a6e7c09-6361-4e9f-9bc4-778bb7656bc4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/07/charles/0a6e7c09-6361-4e9f-9bc4-778bb7656bc4.png -------------------------------------------------------------------------------- /source/_posts/2017/07/charles/0dc3e6f6-250e-4172-af30-83b91cfddf76.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/07/charles/0dc3e6f6-250e-4172-af30-83b91cfddf76.png -------------------------------------------------------------------------------- /source/_posts/2017/07/charles/0fa6ff3f-c1f8-4179-b458-b21cc63e02c2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/07/charles/0fa6ff3f-c1f8-4179-b458-b21cc63e02c2.png -------------------------------------------------------------------------------- /source/_posts/2017/07/charles/1bfe09f1-69a9-4b43-a39c-3d26e067d27a.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/07/charles/1bfe09f1-69a9-4b43-a39c-3d26e067d27a.png -------------------------------------------------------------------------------- /source/_posts/2017/07/charles/1fb741c8-4170-47fa-ad0f-1929ae7857fd.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/07/charles/1fb741c8-4170-47fa-ad0f-1929ae7857fd.png -------------------------------------------------------------------------------- /source/_posts/2017/07/charles/255707e0-725c-4e8e-932a-34b870031e40.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/07/charles/255707e0-725c-4e8e-932a-34b870031e40.png -------------------------------------------------------------------------------- /source/_posts/2017/07/charles/25753d81-3257-43b7-8f35-89436d888974.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/07/charles/25753d81-3257-43b7-8f35-89436d888974.png -------------------------------------------------------------------------------- /source/_posts/2017/07/charles/28fe758a-e2c2-48ab-8132-f26f438e79e0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/07/charles/28fe758a-e2c2-48ab-8132-f26f438e79e0.png -------------------------------------------------------------------------------- /source/_posts/2017/07/charles/41bdb338-fcba-4d56-ac55-207aed5560b4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/07/charles/41bdb338-fcba-4d56-ac55-207aed5560b4.png -------------------------------------------------------------------------------- /source/_posts/2017/07/charles/4ccdcd7b-0b54-43df-bf09-4887edf7800e.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/07/charles/4ccdcd7b-0b54-43df-bf09-4887edf7800e.png -------------------------------------------------------------------------------- /source/_posts/2017/07/charles/4e97e097-b884-4db0-b07f-292a78a77544.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/07/charles/4e97e097-b884-4db0-b07f-292a78a77544.png -------------------------------------------------------------------------------- /source/_posts/2017/07/charles/647b22ba-8441-45db-8386-1c64b6ca520e.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/07/charles/647b22ba-8441-45db-8386-1c64b6ca520e.png -------------------------------------------------------------------------------- /source/_posts/2017/07/charles/73350a4e-816d-4f91-91d5-2a6d1104c722.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/07/charles/73350a4e-816d-4f91-91d5-2a6d1104c722.png -------------------------------------------------------------------------------- /source/_posts/2017/07/charles/7af98999-1276-478b-a443-b92b8986b788.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/07/charles/7af98999-1276-478b-a443-b92b8986b788.png -------------------------------------------------------------------------------- /source/_posts/2017/07/charles/b037c6ae-8a8a-45fd-9a1f-b3628db8b8d6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/07/charles/b037c6ae-8a8a-45fd-9a1f-b3628db8b8d6.png -------------------------------------------------------------------------------- /source/_posts/2017/07/charles/b0875e59-e049-4b62-93f7-02311d0d47e7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/07/charles/b0875e59-e049-4b62-93f7-02311d0d47e7.png -------------------------------------------------------------------------------- /source/_posts/2017/07/charles/bfd83ef1-1e78-4bbb-aa0d-50e4591ca04e.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/07/charles/bfd83ef1-1e78-4bbb-aa0d-50e4591ca04e.jpg -------------------------------------------------------------------------------- /source/_posts/2017/07/charles/c8e71602-2bde-4b7a-850f-bde0b0a17084.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/07/charles/c8e71602-2bde-4b7a-850f-bde0b0a17084.png -------------------------------------------------------------------------------- /source/_posts/2017/07/charles/d3193cee-783b-43c0-99c3-ac98ec52aaa6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/07/charles/d3193cee-783b-43c0-99c3-ac98ec52aaa6.png -------------------------------------------------------------------------------- /source/_posts/2017/07/charles/d40b7bd9-3b1d-4901-816a-dd706909c48b.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/07/charles/d40b7bd9-3b1d-4901-816a-dd706909c48b.png -------------------------------------------------------------------------------- /source/_posts/2017/07/charles/d97cf8fa-5e7f-4c3e-905f-ec0ed12038dd.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/07/charles/d97cf8fa-5e7f-4c3e-905f-ec0ed12038dd.png -------------------------------------------------------------------------------- /source/_posts/2017/07/charles/dfa1e7c1-9072-4e33-836a-cdd62709af67.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/07/charles/dfa1e7c1-9072-4e33-836a-cdd62709af67.png -------------------------------------------------------------------------------- /source/_posts/2017/07/charles/fab69a4a-17c1-4944-81c9-255ff33ff815.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/07/charles/fab69a4a-17c1-4944-81c9-255ff33ff815.png -------------------------------------------------------------------------------- /source/_posts/2017/07/charles/fe7c1302-4101-4882-ae0f-a3d395bdb960.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/07/charles/fe7c1302-4101-4882-ae0f-a3d395bdb960.png -------------------------------------------------------------------------------- /source/_posts/2017/08/api-version/114d5a46452f82018a1f0aaee82fdfab.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/08/api-version/114d5a46452f82018a1f0aaee82fdfab.png -------------------------------------------------------------------------------- /source/_posts/2017/08/bitmap/1605c694-bf55-4500-9531-9832df13b082.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/08/bitmap/1605c694-bf55-4500-9531-9832df13b082.jpg -------------------------------------------------------------------------------- /source/_posts/2017/08/bitmap/1da4242d-018f-4cf4-82c3-e3421b4cf003.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/08/bitmap/1da4242d-018f-4cf4-82c3-e3421b4cf003.jpg -------------------------------------------------------------------------------- /source/_posts/2017/08/bitmap/1dbec168-cbf6-4b42-bb56-ca143f559d06.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/08/bitmap/1dbec168-cbf6-4b42-bb56-ca143f559d06.jpg -------------------------------------------------------------------------------- /source/_posts/2017/08/bitmap/24836d0b-efb2-450f-9307-d078722e2c72.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/08/bitmap/24836d0b-efb2-450f-9307-d078722e2c72.jpg -------------------------------------------------------------------------------- /source/_posts/2017/08/bitmap/2ecb7934-8521-4b03-a13d-27a884d2cb18.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/08/bitmap/2ecb7934-8521-4b03-a13d-27a884d2cb18.jpg -------------------------------------------------------------------------------- /source/_posts/2017/08/bitmap/2f3a90c8-afe8-4d5c-995a-d064ac1f5336.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/08/bitmap/2f3a90c8-afe8-4d5c-995a-d064ac1f5336.png -------------------------------------------------------------------------------- /source/_posts/2017/08/bitmap/3933f7cb-934c-42e7-8fc7-989b3e021010.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/08/bitmap/3933f7cb-934c-42e7-8fc7-989b3e021010.jpg -------------------------------------------------------------------------------- /source/_posts/2017/08/bitmap/3c423c70-2ed7-4cc4-a6fa-ce56bf285a5b.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/08/bitmap/3c423c70-2ed7-4cc4-a6fa-ce56bf285a5b.jpg -------------------------------------------------------------------------------- /source/_posts/2017/08/bitmap/45ef8692-b1d3-4b4b-a6ed-dbe105fb3f97.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/08/bitmap/45ef8692-b1d3-4b4b-a6ed-dbe105fb3f97.png -------------------------------------------------------------------------------- /source/_posts/2017/08/bitmap/57833b05-cf4c-4f30-8ff2-a5c5f3682139.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/08/bitmap/57833b05-cf4c-4f30-8ff2-a5c5f3682139.jpg -------------------------------------------------------------------------------- /source/_posts/2017/08/bitmap/5ad4199b-e5d1-45f9-9657-98f2f2c34960.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/08/bitmap/5ad4199b-e5d1-45f9-9657-98f2f2c34960.png -------------------------------------------------------------------------------- /source/_posts/2017/08/bitmap/63f0f0a2-22e4-49dd-bcec-47e43fc69787.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/08/bitmap/63f0f0a2-22e4-49dd-bcec-47e43fc69787.jpg -------------------------------------------------------------------------------- /source/_posts/2017/08/bitmap/8be164ef-9f6a-4a56-8a5d-53b417c9310a.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/08/bitmap/8be164ef-9f6a-4a56-8a5d-53b417c9310a.jpg -------------------------------------------------------------------------------- /source/_posts/2017/08/bitmap/92401d1b-02ac-446f-908e-3057fa9c7fd4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/08/bitmap/92401d1b-02ac-446f-908e-3057fa9c7fd4.jpg -------------------------------------------------------------------------------- /source/_posts/2017/08/bitmap/97c98774-03b3-47ed-852c-71d1a546a65c.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/08/bitmap/97c98774-03b3-47ed-852c-71d1a546a65c.jpg -------------------------------------------------------------------------------- /source/_posts/2017/08/bitmap/98132f45-baeb-4317-823f-28994b6a1b53.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/08/bitmap/98132f45-baeb-4317-823f-28994b6a1b53.jpg -------------------------------------------------------------------------------- /source/_posts/2017/08/bitmap/a134be42-9acb-41c6-bc80-469b86de8ba0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/08/bitmap/a134be42-9acb-41c6-bc80-469b86de8ba0.png -------------------------------------------------------------------------------- /source/_posts/2017/08/bitmap/a9997194-b4d8-4cf5-bb3e-33a68229729b.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/08/bitmap/a9997194-b4d8-4cf5-bb3e-33a68229729b.jpg -------------------------------------------------------------------------------- /source/_posts/2017/08/bitmap/b94201a7-beaf-4613-beda-f7a3674f5228.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/08/bitmap/b94201a7-beaf-4613-beda-f7a3674f5228.jpg -------------------------------------------------------------------------------- /source/_posts/2017/08/bitmap/b94d2ee6-08b8-46bb-bc14-648d25f3d1b0.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/08/bitmap/b94d2ee6-08b8-46bb-bc14-648d25f3d1b0.jpg -------------------------------------------------------------------------------- /source/_posts/2017/08/bitmap/bf0f2d59-b0de-4f96-b598-ffccb8677758.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/08/bitmap/bf0f2d59-b0de-4f96-b598-ffccb8677758.jpg -------------------------------------------------------------------------------- /source/_posts/2017/08/bitmap/bf6bf8d3-3801-4fca-b229-8cc83ea5ba81.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/08/bitmap/bf6bf8d3-3801-4fca-b229-8cc83ea5ba81.jpg -------------------------------------------------------------------------------- /source/_posts/2017/08/bitmap/d14eff84-5eb1-4268-87ae-4776c66af4a5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/08/bitmap/d14eff84-5eb1-4268-87ae-4776c66af4a5.jpg -------------------------------------------------------------------------------- /source/_posts/2017/08/bitmap/d68e8fa2-433a-47dc-8aed-ff1b993cf082.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/08/bitmap/d68e8fa2-433a-47dc-8aed-ff1b993cf082.png -------------------------------------------------------------------------------- /source/_posts/2017/08/bitmap/de158ff0-a75a-4742-890f-7f8fa54e8429.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/08/bitmap/de158ff0-a75a-4742-890f-7f8fa54e8429.jpg -------------------------------------------------------------------------------- /source/_posts/2017/08/bitmap/e0e6f586-03ce-4d11-a390-34ff3c25400b.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/08/bitmap/e0e6f586-03ce-4d11-a390-34ff3c25400b.jpg -------------------------------------------------------------------------------- /source/_posts/2017/08/bitmap/e72e268a-facd-4480-85be-c779db24ee74.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/08/bitmap/e72e268a-facd-4480-85be-c779db24ee74.jpg -------------------------------------------------------------------------------- /source/_posts/2017/08/bitmap/e897a05e-90c5-442f-8700-b07650c5bb79.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/08/bitmap/e897a05e-90c5-442f-8700-b07650c5bb79.png -------------------------------------------------------------------------------- /source/_posts/2017/08/bitmap/eda83296-8ff6-4558-975c-a73860cccc54.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/08/bitmap/eda83296-8ff6-4558-975c-a73860cccc54.png -------------------------------------------------------------------------------- /source/_posts/2017/08/bitmap/f0c74969-652b-4fa2-b980-fc4f5f99c61d.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/08/bitmap/f0c74969-652b-4fa2-b980-fc4f5f99c61d.jpg -------------------------------------------------------------------------------- /source/_posts/2017/08/bitmap/f4079a06-d308-4f25-ad37-46f2d1baf851.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/08/bitmap/f4079a06-d308-4f25-ad37-46f2d1baf851.png -------------------------------------------------------------------------------- /source/_posts/2017/08/bitmap/f9dc49b3-503c-427e-8256-7db81b39466f.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/08/bitmap/f9dc49b3-503c-427e-8256-7db81b39466f.jpg -------------------------------------------------------------------------------- /source/_posts/2017/08/bitmap/fc1939b6-a486-4998-9507-c3e5825bce9a.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/08/bitmap/fc1939b6-a486-4998-9507-c3e5825bce9a.png -------------------------------------------------------------------------------- /source/_posts/2017/08/id-card/05f73384-a9ba-4a80-8433-563331dfd896.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/08/id-card/05f73384-a9ba-4a80-8433-563331dfd896.jpg -------------------------------------------------------------------------------- /source/_posts/2017/11/qconf/0cc54ae6-e55b-11e7-80c1-9a214cf093ae.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/11/qconf/0cc54ae6-e55b-11e7-80c1-9a214cf093ae.jpg -------------------------------------------------------------------------------- /source/_posts/2017/11/qconf/1a2c6f9e-e55a-11e7-80c1-9a214cf093ae.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/11/qconf/1a2c6f9e-e55a-11e7-80c1-9a214cf093ae.png -------------------------------------------------------------------------------- /source/_posts/2017/11/qconf/2d146c96-e55b-11e7-80c1-9a214cf093ae.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/11/qconf/2d146c96-e55b-11e7-80c1-9a214cf093ae.png -------------------------------------------------------------------------------- /source/_posts/2017/11/qconf/31cbf598-e55a-11e7-80c1-9a214cf093ae.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/11/qconf/31cbf598-e55a-11e7-80c1-9a214cf093ae.png -------------------------------------------------------------------------------- /source/_posts/2017/11/qconf/5aade6d8-e55a-11e7-80c1-9a214cf093ae.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/11/qconf/5aade6d8-e55a-11e7-80c1-9a214cf093ae.png -------------------------------------------------------------------------------- /source/_posts/2017/11/qconf/8bb7c9c6-c0e9-40d5-96c8-81b40613e9bc.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/11/qconf/8bb7c9c6-c0e9-40d5-96c8-81b40613e9bc.jpg -------------------------------------------------------------------------------- /source/_posts/2017/11/qconf/b809d666-e55a-11e7-80c1-9a214cf093ae.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/11/qconf/b809d666-e55a-11e7-80c1-9a214cf093ae.jpg -------------------------------------------------------------------------------- /source/_posts/2017/11/qconf/d29ccf16-e559-11e7-80c1-9a214cf093ae.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/11/qconf/d29ccf16-e559-11e7-80c1-9a214cf093ae.png -------------------------------------------------------------------------------- /source/_posts/2017/11/qconf/d7fec4ae-e55a-11e7-80c1-9a214cf093ae.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/11/qconf/d7fec4ae-e55a-11e7-80c1-9a214cf093ae.jpg -------------------------------------------------------------------------------- /source/_posts/2020/07/openapi/1a902abb-fb35-42e1-9f3a-c18e12074f11.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2020/07/openapi/1a902abb-fb35-42e1-9f3a-c18e12074f11.png -------------------------------------------------------------------------------- /source/_posts/2020/07/openapi/3321e082-1857-4c2b-8d19-a60334f9b4f5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2020/07/openapi/3321e082-1857-4c2b-8d19-a60334f9b4f5.png -------------------------------------------------------------------------------- /source/_posts/2020/07/openapi/39befe95-381e-47ad-879d-e5433e778078.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2020/07/openapi/39befe95-381e-47ad-879d-e5433e778078.png -------------------------------------------------------------------------------- /source/_posts/2020/07/openapi/48e89e9b-eede-4aec-b98f-ce50cc112c99.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2020/07/openapi/48e89e9b-eede-4aec-b98f-ce50cc112c99.png -------------------------------------------------------------------------------- /source/_posts/2020/07/openapi/4b6660db-0e0c-4c6d-9716-0e63820f45e1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2020/07/openapi/4b6660db-0e0c-4c6d-9716-0e63820f45e1.png -------------------------------------------------------------------------------- /source/_posts/2020/07/openapi/549e72de-cdbd-4b8d-a238-085f226d7555.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2020/07/openapi/549e72de-cdbd-4b8d-a238-085f226d7555.jpg -------------------------------------------------------------------------------- /source/_posts/2020/07/openapi/676dcc84-628d-493c-8ab6-c9f2ec3053df.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2020/07/openapi/676dcc84-628d-493c-8ab6-c9f2ec3053df.png -------------------------------------------------------------------------------- /source/_posts/2020/07/openapi/9655aec3-aa6c-4353-819e-a095a0fdd5bf.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2020/07/openapi/9655aec3-aa6c-4353-819e-a095a0fdd5bf.png -------------------------------------------------------------------------------- /source/_posts/2020/07/openapi/a4768e8e-f961-4270-ba9d-69d2a317d49b.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2020/07/openapi/a4768e8e-f961-4270-ba9d-69d2a317d49b.png -------------------------------------------------------------------------------- /source/_posts/2020/07/openapi/ae062ec1-7f3c-4535-916b-c9cd08734a7d.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2020/07/openapi/ae062ec1-7f3c-4535-916b-c9cd08734a7d.jpg -------------------------------------------------------------------------------- /source/_posts/2020/07/openapi/ba4a385e-add6-40fe-aa30-40866f8e4f40.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2020/07/openapi/ba4a385e-add6-40fe-aa30-40866f8e4f40.png -------------------------------------------------------------------------------- /source/_posts/2020/07/openapi/c6987388-682d-403f-8621-caa1fa6cd266.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2020/07/openapi/c6987388-682d-403f-8621-caa1fa6cd266.png -------------------------------------------------------------------------------- /source/_posts/2020/07/openapi/d0131310-b7f8-4deb-aa9e-fcc6b28a47a2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2020/07/openapi/d0131310-b7f8-4deb-aa9e-fcc6b28a47a2.png -------------------------------------------------------------------------------- /source/robots.txt: -------------------------------------------------------------------------------- 1 | # robots.txt for www.fanhaobai.com 2019.04.26 2 | User-agent: * 3 | Disallow: /404.html 4 | Disallow: /categories 5 | Sitemap: http://www.fanhaobai.com/sitemap.xml 6 | -------------------------------------------------------------------------------- /dockerfiles/nginx/conf.d/http/default.conf: -------------------------------------------------------------------------------- 1 | server { 2 | listen 80 default_server; 3 | server_name _; 4 | #引流到www.fanhaobai.com 5 | return 302 https://www.fanhaobai.com; 6 | } -------------------------------------------------------------------------------- /source/_posts/2017/09/lua-in-redis/3916d13312c22d84d29d3860b59544a9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/09/lua-in-redis/3916d13312c22d84d29d3860b59544a9.png -------------------------------------------------------------------------------- /source/_posts/2017/09/lua-in-redis/ae7223b50754e37b7cd89cfe24fc13dd.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/09/lua-in-redis/ae7223b50754e37b7cd89cfe24fc13dd.png -------------------------------------------------------------------------------- /source/_posts/2020/07/openapi/f227c462-b9b9-4846-aeae-23c579b05087.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2020/07/openapi/f227c462-b9b9-4846-aeae-23c579b05087.jpeg -------------------------------------------------------------------------------- /source/_posts/2020/07/openapi/ffc6e25d-7044-467d-8b7c-910831249968.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2020/07/openapi/ffc6e25d-7044-467d-8b7c-910831249968.jpeg -------------------------------------------------------------------------------- /source/_posts/2022/06/risk-rule/07072d15-ffc0-434e-9417-cc04fd0ae979.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2022/06/risk-rule/07072d15-ffc0-434e-9417-cc04fd0ae979.png -------------------------------------------------------------------------------- /source/_posts/2022/06/risk-rule/08e98b72-3fbd-4c58-a8a4-aa88af950499.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2022/06/risk-rule/08e98b72-3fbd-4c58-a8a4-aa88af950499.png -------------------------------------------------------------------------------- /source/_posts/2022/06/risk-rule/24476377-1566-4cfd-bcd6-3d8af562e57c.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2022/06/risk-rule/24476377-1566-4cfd-bcd6-3d8af562e57c.png -------------------------------------------------------------------------------- /source/_posts/2022/06/risk-rule/2cf3e5c4-2a75-4f3b-a51e-f0a206a386e8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2022/06/risk-rule/2cf3e5c4-2a75-4f3b-a51e-f0a206a386e8.png -------------------------------------------------------------------------------- /source/_posts/2022/06/risk-rule/5d6f4a50-a372-4280-bdef-df106aa1684b.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2022/06/risk-rule/5d6f4a50-a372-4280-bdef-df106aa1684b.png -------------------------------------------------------------------------------- /source/_posts/2022/06/risk-rule/6c0c61f3-f53b-4a3e-bc40-caa4e868e981.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2022/06/risk-rule/6c0c61f3-f53b-4a3e-bc40-caa4e868e981.png -------------------------------------------------------------------------------- /source/_posts/2022/06/risk-rule/75345e28-87b4-4b77-8912-606821c5d08d.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2022/06/risk-rule/75345e28-87b4-4b77-8912-606821c5d08d.png -------------------------------------------------------------------------------- /source/_posts/2022/06/risk-rule/c3d8e074-443d-4b14-9533-ff45fd32a4c7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2022/06/risk-rule/c3d8e074-443d-4b14-9533-ff45fd32a4c7.png -------------------------------------------------------------------------------- /source/_posts/2022/06/risk-rule/c54f0ab7-1a73-4c2e-998c-76d02148c8dc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2022/06/risk-rule/c54f0ab7-1a73-4c2e-998c-76d02148c8dc.png -------------------------------------------------------------------------------- /source/_posts/2022/06/risk-rule/ccd31bea-13f9-456e-b908-9d682e2bd5c3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2022/06/risk-rule/ccd31bea-13f9-456e-b908-9d682e2bd5c3.png -------------------------------------------------------------------------------- /source/_posts/2022/06/risk-rule/cd83c013-eccc-42ce-8075-5fd7267edf3d.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2022/06/risk-rule/cd83c013-eccc-42ce-8075-5fd7267edf3d.png -------------------------------------------------------------------------------- /source/_posts/2022/06/risk-rule/d50d0ac4-e740-4ee5-a744-b8c9a593a8be.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2022/06/risk-rule/d50d0ac4-e740-4ee5-a744-b8c9a593a8be.png -------------------------------------------------------------------------------- /source/_posts/2016/05/mysql-index/7d6b1a54-61dd-4ecb-9b84-b064ec95775a.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2016/05/mysql-index/7d6b1a54-61dd-4ecb-9b84-b064ec95775a.png -------------------------------------------------------------------------------- /source/_posts/2017/03/install-hexo/11b9814d-885a-4aca-9b56-94c3ad908f3f.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/03/install-hexo/11b9814d-885a-4aca-9b56-94c3ad908f3f.png -------------------------------------------------------------------------------- /source/_posts/2017/08/solr-search/c4665602-82dc-4cc3-9eaf-c0ed12935d08.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/08/solr-search/c4665602-82dc-4cc3-9eaf-c0ed12935d08.png -------------------------------------------------------------------------------- /source/_posts/2017/09/lua-in-nginx/63113174-45d7-4a27-8472-d037675c2cbd.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/09/lua-in-nginx/63113174-45d7-4a27-8472-d037675c2cbd.jpg -------------------------------------------------------------------------------- /source/_posts/2017/09/supervisor/9d28cc24-a0d8-11e7-abc4-cec278b6b50a.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/09/supervisor/9d28cc24-a0d8-11e7-abc4-cec278b6b50a.png -------------------------------------------------------------------------------- /source/_posts/2017/09/supervisor/d42decd3-2342-4e8f-a34f-48b47fc6e557.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/09/supervisor/d42decd3-2342-4e8f-a34f-48b47fc6e557.png -------------------------------------------------------------------------------- /source/_posts/2017/12/elk-advanced/0f9b0271-108b-47d4-acc2-6fde4e4f9ff7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/12/elk-advanced/0f9b0271-108b-47d4-acc2-6fde4e4f9ff7.png -------------------------------------------------------------------------------- /source/_posts/2017/12/elk-advanced/3f97da38-e7e5-11e7-80c1-9a214cf093ae.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/12/elk-advanced/3f97da38-e7e5-11e7-80c1-9a214cf093ae.png -------------------------------------------------------------------------------- /source/_posts/2017/12/elk-advanced/575f23bd-f21a-4b53-a7f3-5581f9c25c01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/12/elk-advanced/575f23bd-f21a-4b53-a7f3-5581f9c25c01.png -------------------------------------------------------------------------------- /source/_posts/2017/12/elk-advanced/993155ac-718b-4e4b-9d36-d9d73357b162.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/12/elk-advanced/993155ac-718b-4e4b-9d36-d9d73357b162.png -------------------------------------------------------------------------------- /source/_posts/2017/12/elk-advanced/b27378ac-e7e8-11e7-80c1-9a214cf093ae.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/12/elk-advanced/b27378ac-e7e8-11e7-80c1-9a214cf093ae.png -------------------------------------------------------------------------------- /source/_posts/2017/12/elk-advanced/c618f544-7093-4530-9bda-b63ab58832ea.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/12/elk-advanced/c618f544-7093-4530-9bda-b63ab58832ea.png -------------------------------------------------------------------------------- /source/_posts/2017/12/elk-advanced/d82824ed-15eb-47c5-9ec6-925f2d3f7758.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/12/elk-advanced/d82824ed-15eb-47c5-9ec6-925f2d3f7758.png -------------------------------------------------------------------------------- /source/_posts/2017/12/elk-advanced/f2c9321a-e7e4-11e7-80c1-9a214cf093ae.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/12/elk-advanced/f2c9321a-e7e4-11e7-80c1-9a214cf093ae.png -------------------------------------------------------------------------------- /source/_posts/2017/12/elk-install/0da3b439-5174-4aff-b9dc-f275ebbd9e1f.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/12/elk-install/0da3b439-5174-4aff-b9dc-f275ebbd9e1f.png -------------------------------------------------------------------------------- /source/_posts/2017/12/elk-install/a1ff2131-8dd8-4ad1-8ba3-c2d2ebeffc91.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/12/elk-install/a1ff2131-8dd8-4ad1-8ba3-c2d2ebeffc91.png -------------------------------------------------------------------------------- /source/_posts/2018/02/linux-skill/2a82ad6b-ab25-409f-858c-22312826ac06.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2018/02/linux-skill/2a82ad6b-ab25-409f-858c-22312826ac06.jpg -------------------------------------------------------------------------------- /source/_posts/2018/02/linux-skill/7bb99049-49bd-427b-a338-3afff4268fb3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2018/02/linux-skill/7bb99049-49bd-427b-a338-3afff4268fb3.jpg -------------------------------------------------------------------------------- /source/_posts/2018/03/hexo-deploy/082786eb-0903-4776-a345-e52d25de2e49.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2018/03/hexo-deploy/082786eb-0903-4776-a345-e52d25de2e49.png -------------------------------------------------------------------------------- /source/_posts/2018/03/hexo-deploy/12b62d2e-7e26-4a3c-a770-e0d16d5c2254.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2018/03/hexo-deploy/12b62d2e-7e26-4a3c-a770-e0d16d5c2254.png -------------------------------------------------------------------------------- /source/_posts/2018/03/hexo-deploy/3b8f20b3-f3b2-498d-afa4-d60391c47db5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2018/03/hexo-deploy/3b8f20b3-f3b2-498d-afa4-d60391c47db5.png -------------------------------------------------------------------------------- /source/_posts/2018/03/hexo-deploy/9ee84981-7d79-47f5-98f8-e7500eff6e67.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2018/03/hexo-deploy/9ee84981-7d79-47f5-98f8-e7500eff6e67.png -------------------------------------------------------------------------------- /source/_posts/2018/03/hexo-deploy/bf3adf97-088b-47cd-b5ab-377a4f4acd44.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2018/03/hexo-deploy/bf3adf97-088b-47cd-b5ab-377a4f4acd44.png -------------------------------------------------------------------------------- /source/_posts/2018/03/hexo-deploy/cd4f6674-aba5-4cbc-87e6-18c0c230585b.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2018/03/hexo-deploy/cd4f6674-aba5-4cbc-87e6-18c0c230585b.png -------------------------------------------------------------------------------- /source/_posts/2018/03/hexo-deploy/f2ec7449-ae8a-4f6a-8dfa-95d6abf4aaa6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2018/03/hexo-deploy/f2ec7449-ae8a-4f6a-8dfa-95d6abf4aaa6.png -------------------------------------------------------------------------------- /source/_posts/2020/12/hexo-to-docker/704035c6-348e-439b-9048-d05a2a18ef1f.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2020/12/hexo-to-docker/704035c6-348e-439b-9048-d05a2a18ef1f.png -------------------------------------------------------------------------------- /source/_posts/2017/03/linux-core-caricature/0E9D69D32086CA20007062B59842DE24.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/03/linux-core-caricature/0E9D69D32086CA20007062B59842DE24.png -------------------------------------------------------------------------------- /source/_posts/2017/03/linux-core-caricature/14227E17ECB4AD1852B67CAD4DA48F42.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/03/linux-core-caricature/14227E17ECB4AD1852B67CAD4DA48F42.png -------------------------------------------------------------------------------- /source/_posts/2017/03/linux-core-caricature/3C27118DE046AD57EF68F273C0D97CEB.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/03/linux-core-caricature/3C27118DE046AD57EF68F273C0D97CEB.png -------------------------------------------------------------------------------- /source/_posts/2017/03/linux-core-caricature/4AD005B03A39A0F49C0161914325B9C5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/03/linux-core-caricature/4AD005B03A39A0F49C0161914325B9C5.png -------------------------------------------------------------------------------- /source/_posts/2017/03/linux-core-caricature/5BD8ACFD12B2952124B8C9A70546A190.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/03/linux-core-caricature/5BD8ACFD12B2952124B8C9A70546A190.png -------------------------------------------------------------------------------- /source/_posts/2017/03/linux-core-caricature/62707DD3CCEB3B0765227E742A32F72F.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/03/linux-core-caricature/62707DD3CCEB3B0765227E742A32F72F.png -------------------------------------------------------------------------------- /source/_posts/2017/03/linux-core-caricature/6ADA68452C7E8F3014CD8D7D68BF3DCD.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/03/linux-core-caricature/6ADA68452C7E8F3014CD8D7D68BF3DCD.png -------------------------------------------------------------------------------- /source/_posts/2017/03/linux-core-caricature/7367932F64D0D54E31AF624CF830E0CF.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/03/linux-core-caricature/7367932F64D0D54E31AF624CF830E0CF.png -------------------------------------------------------------------------------- /source/_posts/2017/03/linux-core-caricature/A60AFE2B528D380E7C11D921C5D416D2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/03/linux-core-caricature/A60AFE2B528D380E7C11D921C5D416D2.png -------------------------------------------------------------------------------- /source/_posts/2017/03/linux-core-caricature/A91A34A3B08128E2A06C66E8856585B0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/03/linux-core-caricature/A91A34A3B08128E2A06C66E8856585B0.png -------------------------------------------------------------------------------- /source/_posts/2017/03/linux-core-caricature/A92E721F6E3331ECFF02BF6A2E25F43D.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/03/linux-core-caricature/A92E721F6E3331ECFF02BF6A2E25F43D.png -------------------------------------------------------------------------------- /source/_posts/2017/03/linux-core-caricature/B3FBAEAC24E48666A4442ADEB950BE21.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/03/linux-core-caricature/B3FBAEAC24E48666A4442ADEB950BE21.png -------------------------------------------------------------------------------- /source/_posts/2017/03/linux-core-caricature/C8277CBC07F312F62D0EF9DA9AF01F19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/03/linux-core-caricature/C8277CBC07F312F62D0EF9DA9AF01F19.png -------------------------------------------------------------------------------- /source/_posts/2017/03/linux-core-caricature/CDA46D0971D6354391ECC3A88E711EA0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/03/linux-core-caricature/CDA46D0971D6354391ECC3A88E711EA0.png -------------------------------------------------------------------------------- /source/_posts/2017/03/linux-core-caricature/DBE8511ECE02DC8ADF849F5062B83433.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/03/linux-core-caricature/DBE8511ECE02DC8ADF849F5062B83433.png -------------------------------------------------------------------------------- /source/_posts/2017/04/array-form-max-string/65FD0FD202413415D266AC754A75AAF3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/04/array-form-max-string/65FD0FD202413415D266AC754A75AAF3.png -------------------------------------------------------------------------------- /source/_posts/2017/08/redis-pipelining/abc8ae13-9f76-4cd0-902d-a4fbb9fedd4f.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/08/redis-pipelining/abc8ae13-9f76-4cd0-902d-a4fbb9fedd4f.png -------------------------------------------------------------------------------- /source/_posts/2017/08/solr-install-push/43735106-acb6-4f42-a136-dd5ab347ef49.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/08/solr-install-push/43735106-acb6-4f42-a136-dd5ab347ef49.png -------------------------------------------------------------------------------- /source/_posts/2017/12/2017-ziroom-king-1/03a07a80-8bc3-46d1-bcab-17e2a057d951.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/12/2017-ziroom-king-1/03a07a80-8bc3-46d1-bcab-17e2a057d951.png -------------------------------------------------------------------------------- /source/_posts/2017/12/2017-ziroom-king-1/25fc16ed-ebdd-4094-84a4-150ad9a31b1f.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/12/2017-ziroom-king-1/25fc16ed-ebdd-4094-84a4-150ad9a31b1f.png -------------------------------------------------------------------------------- /source/_posts/2017/12/2017-ziroom-king-1/a1cb7d2c-7fb6-4dbd-a363-3cd9e300743d.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/12/2017-ziroom-king-1/a1cb7d2c-7fb6-4dbd-a363-3cd9e300743d.png -------------------------------------------------------------------------------- /source/_posts/2017/12/2017-ziroom-king-1/d0955aea-2787-4e6b-adea-8fe1f61236de.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/12/2017-ziroom-king-1/d0955aea-2787-4e6b-adea-8fe1f61236de.png -------------------------------------------------------------------------------- /source/_posts/2017/12/2017-ziroom-king-1/d4724b85-8491-451a-8b3c-d6c06842ec69.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/12/2017-ziroom-king-1/d4724b85-8491-451a-8b3c-d6c06842ec69.png -------------------------------------------------------------------------------- /source/_posts/2017/12/2017-ziroom-king-1/f9829b13-af2e-4c7b-b214-40bc78223c18.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/12/2017-ziroom-king-1/f9829b13-af2e-4c7b-b214-40bc78223c18.png -------------------------------------------------------------------------------- /source/_posts/2017/12/2017-ziroom-king-2/53afcc7a-ff51-4191-aab0-5c9cc6850566.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/12/2017-ziroom-king-2/53afcc7a-ff51-4191-aab0-5c9cc6850566.png -------------------------------------------------------------------------------- /source/_posts/2017/12/2017-ziroom-king-2/b2f137ff-b91b-4036-b7d8-fc86f82fb980.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/12/2017-ziroom-king-2/b2f137ff-b91b-4036-b7d8-fc86f82fb980.png -------------------------------------------------------------------------------- /source/_posts/2017/12/2017-ziroom-king-3/18359c82-3ff9-48c7-825e-77fe17419621.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/12/2017-ziroom-king-3/18359c82-3ff9-48c7-825e-77fe17419621.png -------------------------------------------------------------------------------- /source/_posts/2017/12/2017-ziroom-king-3/366c6f00-35a1-46c6-ba98-76e3c7b3bae4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/12/2017-ziroom-king-3/366c6f00-35a1-46c6-ba98-76e3c7b3bae4.png -------------------------------------------------------------------------------- /source/_posts/2017/12/2017-ziroom-king-3/9f4a2cb2-ab32-4b28-b054-b479c04270e5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/12/2017-ziroom-king-3/9f4a2cb2-ab32-4b28-b054-b479c04270e5.png -------------------------------------------------------------------------------- /source/_posts/2017/12/2017-ziroom-king-4/3d9cf2e7-dfe6-4b6e-8526-991296c3ea51.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/12/2017-ziroom-king-4/3d9cf2e7-dfe6-4b6e-8526-991296c3ea51.png -------------------------------------------------------------------------------- /source/_posts/2017/12/2017-ziroom-king-5/40beff35-47fc-4427-8805-e183233b598b.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/12/2017-ziroom-king-5/40beff35-47fc-4427-8805-e183233b598b.png -------------------------------------------------------------------------------- /source/_posts/2017/12/2017-ziroom-king-5/45552677-bcd6-4d45-b627-a398f0cfe04d.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/12/2017-ziroom-king-5/45552677-bcd6-4d45-b627-a398f0cfe04d.png -------------------------------------------------------------------------------- /source/_posts/2017/12/2017-ziroom-king-5/7eeefcb6-6b96-4719-9819-c96b31309449.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/12/2017-ziroom-king-5/7eeefcb6-6b96-4719-9819-c96b31309449.png -------------------------------------------------------------------------------- /source/_posts/2017/12/2017-ziroom-king-5/b7724f85-3855-410c-9cc7-1cfcee5d29e4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/12/2017-ziroom-king-5/b7724f85-3855-410c-9cc7-1cfcee5d29e4.png -------------------------------------------------------------------------------- /source/_posts/2017/12/2017-ziroom-king-5/c5f725fc-f801-4e93-9f32-5adb8a76e1a0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/12/2017-ziroom-king-5/c5f725fc-f801-4e93-9f32-5adb8a76e1a0.png -------------------------------------------------------------------------------- /source/_posts/2018/06/beijing-to-chengdu/0149bcaf-f380-4ef3-b6e1-331b452d636a.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2018/06/beijing-to-chengdu/0149bcaf-f380-4ef3-b6e1-331b452d636a.jpg -------------------------------------------------------------------------------- /source/_posts/2018/06/beijing-to-chengdu/0f8ebfc5-3d54-489e-9dc3-ee74bd4d61d0.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2018/06/beijing-to-chengdu/0f8ebfc5-3d54-489e-9dc3-ee74bd4d61d0.jpg -------------------------------------------------------------------------------- /source/_posts/2018/06/beijing-to-chengdu/234987d5-3dd2-4736-b32c-b843ff42505e.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2018/06/beijing-to-chengdu/234987d5-3dd2-4736-b32c-b843ff42505e.jpg -------------------------------------------------------------------------------- /source/_posts/2018/06/beijing-to-chengdu/30121dc4-7b67-11e8-adc0-fa7ae01bbebc.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2018/06/beijing-to-chengdu/30121dc4-7b67-11e8-adc0-fa7ae01bbebc.jpg -------------------------------------------------------------------------------- /source/_posts/2018/06/beijing-to-chengdu/4c7fd01e-91ce-48f5-a47b-5ee6500a5d5d.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2018/06/beijing-to-chengdu/4c7fd01e-91ce-48f5-a47b-5ee6500a5d5d.jpg -------------------------------------------------------------------------------- /source/_posts/2018/06/beijing-to-chengdu/53bc46b9-b1eb-4c3d-88ff-68b44bce5429.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2018/06/beijing-to-chengdu/53bc46b9-b1eb-4c3d-88ff-68b44bce5429.jpg -------------------------------------------------------------------------------- /source/_posts/2018/06/beijing-to-chengdu/59554de4-62c2-440b-af63-384ebcf79b24.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2018/06/beijing-to-chengdu/59554de4-62c2-440b-af63-384ebcf79b24.jpg -------------------------------------------------------------------------------- /source/_posts/2018/06/beijing-to-chengdu/6054d4bf-b6fe-4dac-ab25-4f6653bc880f.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2018/06/beijing-to-chengdu/6054d4bf-b6fe-4dac-ab25-4f6653bc880f.jpg -------------------------------------------------------------------------------- /source/_posts/2018/06/beijing-to-chengdu/745d2ec3-6618-4fc0-9f30-4bee52496670.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2018/06/beijing-to-chengdu/745d2ec3-6618-4fc0-9f30-4bee52496670.jpg -------------------------------------------------------------------------------- /source/_posts/2018/06/beijing-to-chengdu/8111a4fc-7b66-11e8-adc0-fa7ae01bbebc.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2018/06/beijing-to-chengdu/8111a4fc-7b66-11e8-adc0-fa7ae01bbebc.jpg -------------------------------------------------------------------------------- /source/_posts/2018/06/beijing-to-chengdu/88d071da-7b6d-11e8-adc0-fa7ae01bbebc.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2018/06/beijing-to-chengdu/88d071da-7b6d-11e8-adc0-fa7ae01bbebc.jpg -------------------------------------------------------------------------------- /source/_posts/2018/06/beijing-to-chengdu/de39aeb3-5481-4181-a45c-b503ec16cd0a.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2018/06/beijing-to-chengdu/de39aeb3-5481-4181-a45c-b503ec16cd0a.jpg -------------------------------------------------------------------------------- /source/_posts/2023/01/recommender-system/19F578B4-4B33-4F28-AAE4-D4C71308A360.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2023/01/recommender-system/19F578B4-4B33-4F28-AAE4-D4C71308A360.png -------------------------------------------------------------------------------- /source/_posts/2023/01/recommender-system/41C31DFF-9546-413B-82A5-794DC47488B7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2023/01/recommender-system/41C31DFF-9546-413B-82A5-794DC47488B7.png -------------------------------------------------------------------------------- /source/_posts/2023/01/recommender-system/5D1A9AD7-9EDF-4607-A2D2-8B73D9FEA7B5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2023/01/recommender-system/5D1A9AD7-9EDF-4607-A2D2-8B73D9FEA7B5.png -------------------------------------------------------------------------------- /source/_posts/2023/01/recommender-system/5FF361FE-B7B5-4A01-9DA5-CF9AEC5B7462.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2023/01/recommender-system/5FF361FE-B7B5-4A01-9DA5-CF9AEC5B7462.png -------------------------------------------------------------------------------- /source/_posts/2023/01/recommender-system/74661B99-43E6-4532-9B93-AAB9469E5DD1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2023/01/recommender-system/74661B99-43E6-4532-9B93-AAB9469E5DD1.png -------------------------------------------------------------------------------- /source/_posts/2023/01/recommender-system/7A956F05-52D9-4B2F-9466-62883F81958D.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2023/01/recommender-system/7A956F05-52D9-4B2F-9466-62883F81958D.png -------------------------------------------------------------------------------- /source/_posts/2023/01/recommender-system/97FD0BB9-EA8C-4BBD-BAAA-8721149084F3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2023/01/recommender-system/97FD0BB9-EA8C-4BBD-BAAA-8721149084F3.png -------------------------------------------------------------------------------- /source/_posts/2023/01/recommender-system/B4417679-0FCA-4EA0-8E95-CAA95912C05E.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2023/01/recommender-system/B4417679-0FCA-4EA0-8E95-CAA95912C05E.png -------------------------------------------------------------------------------- /source/_posts/2023/01/recommender-system/BD317F5E-8689-4139-BE07-FC82C6EEA69A.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2023/01/recommender-system/BD317F5E-8689-4139-BE07-FC82C6EEA69A.png -------------------------------------------------------------------------------- /source/_posts/2023/01/recommender-system/D1C891D1-878A-4B95-97D7-BBA7AFAB3467.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2023/01/recommender-system/D1C891D1-878A-4B95-97D7-BBA7AFAB3467.png -------------------------------------------------------------------------------- /source/_posts/2023/01/recommender-system/E2A4D0D2-EA74-4130-A8CE-4B7FBD9E9E40.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2023/01/recommender-system/E2A4D0D2-EA74-4130-A8CE-4B7FBD9E9E40.png -------------------------------------------------------------------------------- /source/_posts/2023/01/recommender-system/E7E33224-409F-44E4-8A39-EDA85F89435C.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2023/01/recommender-system/E7E33224-409F-44E4-8A39-EDA85F89435C.png -------------------------------------------------------------------------------- /source/_posts/2024/04/design-rule-engine/12805423-37FB-4225-91E3-EC6473BA720C.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2024/04/design-rule-engine/12805423-37FB-4225-91E3-EC6473BA720C.png -------------------------------------------------------------------------------- /source/_posts/2024/04/design-rule-engine/30B59826-F443-4D9A-AC98-42F7E28127D5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2024/04/design-rule-engine/30B59826-F443-4D9A-AC98-42F7E28127D5.png -------------------------------------------------------------------------------- /source/_posts/2024/04/design-rule-engine/36E0B373-95A2-4E26-AFE2-ED9522CCB708.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2024/04/design-rule-engine/36E0B373-95A2-4E26-AFE2-ED9522CCB708.png -------------------------------------------------------------------------------- /source/_posts/2024/04/design-rule-engine/6082eaf6-9534-4989-86d6-2422a3ab54b0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2024/04/design-rule-engine/6082eaf6-9534-4989-86d6-2422a3ab54b0.png -------------------------------------------------------------------------------- /source/_posts/2024/04/design-rule-engine/65ebb70a-3e2d-4e20-a1f2-227fc08c0669.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2024/04/design-rule-engine/65ebb70a-3e2d-4e20-a1f2-227fc08c0669.png -------------------------------------------------------------------------------- /source/_posts/2024/04/design-rule-engine/C0C5B489-90D1-4937-A8D8-55459E951ABC.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2024/04/design-rule-engine/C0C5B489-90D1-4937-A8D8-55459E951ABC.png -------------------------------------------------------------------------------- /source/_posts/2024/04/design-rule-engine/C290970F-D33E-49DF-846B-577E62694709.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2024/04/design-rule-engine/C290970F-D33E-49DF-846B-577E62694709.png -------------------------------------------------------------------------------- /source/_posts/2024/04/design-rule-engine/E937E855-8B7C-4B4C-9761-0764D563BE42.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2024/04/design-rule-engine/E937E855-8B7C-4B4C-9761-0764D563BE42.png -------------------------------------------------------------------------------- /source/_posts/2017/04/array-form-max-string/57f35c24-2eeb-4c68-bf28-0771b11cad34.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/04/array-form-max-string/57f35c24-2eeb-4c68-bf28-0771b11cad34.png -------------------------------------------------------------------------------- /source/_posts/2017/08/elasticsearch-search/9a3accb9-0da1-47e4-ad58-428370464af6.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/08/elasticsearch-search/9a3accb9-0da1-47e4-ad58-428370464af6.jpg -------------------------------------------------------------------------------- /source/_posts/2018/01/2018-new-year-activity/3a9dff7a-71f1-4d9d-a576-a3dcbaf65c9b.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2018/01/2018-new-year-activity/3a9dff7a-71f1-4d9d-a576-a3dcbaf65c9b.png -------------------------------------------------------------------------------- /source/_posts/2018/01/2018-new-year-activity/9a15f5d1-0983-4155-80e4-ba55e5543672.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2018/01/2018-new-year-activity/9a15f5d1-0983-4155-80e4-ba55e5543672.png -------------------------------------------------------------------------------- /source/_posts/2018/01/2018-new-year-activity/9cf63edb-315e-4951-9d7f-531953741e52.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2018/01/2018-new-year-activity/9cf63edb-315e-4951-9d7f-531953741e52.png -------------------------------------------------------------------------------- /source/_posts/2018/01/2018-new-year-activity/a3f34d9b-55cd-4931-8557-63f9b6767a79.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2018/01/2018-new-year-activity/a3f34d9b-55cd-4931-8557-63f9b6767a79.jpg -------------------------------------------------------------------------------- /source/_posts/2018/01/2018-new-year-activity/b19eec7a-978b-4ddc-8c8b-13c643c27b48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2018/01/2018-new-year-activity/b19eec7a-978b-4ddc-8c8b-13c643c27b48.png -------------------------------------------------------------------------------- /source/_posts/2018/01/2018-new-year-activity/de5070ca-fd29-493e-b433-28520a8aaa1a.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2018/01/2018-new-year-activity/de5070ca-fd29-493e-b433-28520a8aaa1a.png -------------------------------------------------------------------------------- /source/_posts/2018/01/2018-new-year-activity/f405ee75-8e06-4f72-a8c5-60a155cc0ead.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2018/01/2018-new-year-activity/f405ee75-8e06-4f72-a8c5-60a155cc0ead.png -------------------------------------------------------------------------------- /source/_posts/2019/02/multi-currency-price/434ddc25-3b51-4753-b5d5-b765ac5ca30c.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2019/02/multi-currency-price/434ddc25-3b51-4753-b5d5-b765ac5ca30c.jpg -------------------------------------------------------------------------------- /source/_posts/2019/02/multi-currency-price/4ff6ceb3-44c9-4edf-bfdb-23cf50b22c6f.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2019/02/multi-currency-price/4ff6ceb3-44c9-4edf-bfdb-23cf50b22c6f.png -------------------------------------------------------------------------------- /source/_posts/2019/02/multi-currency-price/b5c63729-fd94-4f3b-b107-1b345d26c1c6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2019/02/multi-currency-price/b5c63729-fd94-4f3b-b107-1b345d26c1c6.png -------------------------------------------------------------------------------- /source/_posts/2021/12/2021-personal-summary/10183cff-d8cc-4e5f-97cb-b897a256bd41.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2021/12/2021-personal-summary/10183cff-d8cc-4e5f-97cb-b897a256bd41.png -------------------------------------------------------------------------------- /source/_posts/2021/12/2021-personal-summary/a2d1e849-2e1f-42a3-a054-69005e91755b.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2021/12/2021-personal-summary/a2d1e849-2e1f-42a3-a054-69005e91755b.jpg -------------------------------------------------------------------------------- /source/_posts/2022/12/user-profile-use-flink/082D3F30-8845-4943-AC1E-6AF494885350.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2022/12/user-profile-use-flink/082D3F30-8845-4943-AC1E-6AF494885350.png -------------------------------------------------------------------------------- /source/_posts/2022/12/user-profile-use-flink/4C7CA16C-53B3-455A-86B0-D0917B69C21E.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2022/12/user-profile-use-flink/4C7CA16C-53B3-455A-86B0-D0917B69C21E.png -------------------------------------------------------------------------------- /source/_posts/2022/12/user-profile-use-flink/96A9AAFE-201F-48DF-8318-ED035B06269C.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2022/12/user-profile-use-flink/96A9AAFE-201F-48DF-8318-ED035B06269C.png -------------------------------------------------------------------------------- /source/_posts/2022/12/user-profile-use-flink/DD0DBEE8-32B8-4A78-B0A2-3907A710907A.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2022/12/user-profile-use-flink/DD0DBEE8-32B8-4A78-B0A2-3907A710907A.png -------------------------------------------------------------------------------- /source/_posts/2022/12/user-profile-use-flink/FAA84305-96B3-4934-8991-C5ACE2752C5A.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2022/12/user-profile-use-flink/FAA84305-96B3-4934-8991-C5ACE2752C5A.png -------------------------------------------------------------------------------- /source/_posts/2018/11/load-balance-round-robin/1e858872-6235-4131-98ba-433690eb32c1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2018/11/load-balance-round-robin/1e858872-6235-4131-98ba-433690eb32c1.jpg -------------------------------------------------------------------------------- /source/_posts/2018/08/process-php-basic-knowledge/0f31694b-b96f-48f2-92f4-56552bded7f4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2018/08/process-php-basic-knowledge/0f31694b-b96f-48f2-92f4-56552bded7f4.jpg -------------------------------------------------------------------------------- /source/_posts/2018/08/process-php-basic-knowledge/80e3b1cf-51d8-4342-a08a-976b3a7b3c8c.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2018/08/process-php-basic-knowledge/80e3b1cf-51d8-4342-a08a-976b3a7b3c8c.png -------------------------------------------------------------------------------- /source/_posts/2018/08/process-php-basic-knowledge/c18f0a31-dade-49e0-90b3-308b7ce63ef6.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2018/08/process-php-basic-knowledge/c18f0a31-dade-49e0-90b3-308b7ce63ef6.jpg -------------------------------------------------------------------------------- /source/_posts/2018/08/process-php-basic-knowledge/dab56833-15dc-405e-b359-4a4fa0e305bc.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2018/08/process-php-basic-knowledge/dab56833-15dc-405e-b359-4a4fa0e305bc.jpg -------------------------------------------------------------------------------- /source/_posts/2018/08/process-php-basic-knowledge/f6eb7888-6de6-41a4-8d15-4d471825a24e.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2018/08/process-php-basic-knowledge/f6eb7888-6de6-41a4-8d15-4d471825a24e.jpg -------------------------------------------------------------------------------- /source/_posts/2018/08/process-php-basic-knowledge/f85ea400-6623-44ae-88c4-efc9ef1fa315.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2018/08/process-php-basic-knowledge/f85ea400-6623-44ae-88c4-efc9ef1fa315.jpg -------------------------------------------------------------------------------- /source/_posts/2017/08/elasticsearch-advanced-search/d758139c-86ce-4472-89e8-7eb385cf7991.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/08/elasticsearch-advanced-search/d758139c-86ce-4472-89e8-7eb385cf7991.jpg -------------------------------------------------------------------------------- /source/_posts/2018/09/process-php-multiprocess-server/22ed9e46-971c-4983-8bf5-65d321585d42.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2018/09/process-php-multiprocess-server/22ed9e46-971c-4983-8bf5-65d321585d42.png -------------------------------------------------------------------------------- /source/_posts/2018/09/process-php-multiprocess-server/34f35d33-57b2-41d7-b738-f0c1c712102f.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2018/09/process-php-multiprocess-server/34f35d33-57b2-41d7-b738-f0c1c712102f.png -------------------------------------------------------------------------------- /source/_posts/2018/09/process-php-multiprocess-server/4c5ec8d3-e56e-4367-8856-beaf23ee7602.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2018/09/process-php-multiprocess-server/4c5ec8d3-e56e-4367-8856-beaf23ee7602.png -------------------------------------------------------------------------------- /source/_posts/2018/09/process-php-multiprocess-server/8e65456f-8e08-4ae8-84f8-e6f2278410e4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2018/09/process-php-multiprocess-server/8e65456f-8e08-4ae8-84f8-e6f2278410e4.png -------------------------------------------------------------------------------- /source/_posts/2018/09/process-php-multiprocess-server/ad804eb2-9300-4d34-ae63-3b820d81d4b1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2018/09/process-php-multiprocess-server/ad804eb2-9300-4d34-ae63-3b820d81d4b1.png -------------------------------------------------------------------------------- /source/_posts/2018/09/process-php-multiprocess-server/db333298-5a10-4de3-b0b2-41088cafc77f.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2018/09/process-php-multiprocess-server/db333298-5a10-4de3-b0b2-41088cafc77f.png -------------------------------------------------------------------------------- /source/_posts/2018/09/process-php-multiprocess-server/e0e86073-3093-4e5f-be20-b64510e61575.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2018/09/process-php-multiprocess-server/e0e86073-3093-4e5f-be20-b64510e61575.png -------------------------------------------------------------------------------- /source/_posts/2018/09/process-php-multiprocess-server/fc458e5f-fccc-477f-9e18-eada5d856289.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2018/09/process-php-multiprocess-server/fc458e5f-fccc-477f-9e18-eada5d856289.png -------------------------------------------------------------------------------- /source/_posts/2017/11/synchronised-asynchronized-coroutine/88bb24ee-b443-407d-ad14-fdae5a7113d6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/11/synchronised-asynchronized-coroutine/88bb24ee-b443-407d-ad14-fdae5a7113d6.png -------------------------------------------------------------------------------- /source/_posts/2017/11/synchronised-asynchronized-coroutine/a89c6e5b-facd-47a1-a26b-c8fb747e9650.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2017/11/synchronised-asynchronized-coroutine/a89c6e5b-facd-47a1-a26b-c8fb747e9650.jpg -------------------------------------------------------------------------------- /docker.example.env: -------------------------------------------------------------------------------- 1 | # 是否启用HTTPS证书 2 | ENABLE_SSL=false 3 | # 支持HTTPS协议的域名 4 | SSL_DOMAINS=fanhaobai.com,www.fanhaobai.com,img.fanhaobai.com,img0.fanhaobai.com,img1.fanhaobai.com,img2.fanhaobai.com,img3.fanhaobai.com,img4.fanhaobai.com,img5.fanhaobai.com -------------------------------------------------------------------------------- /source/_posts/2018/12/load-balance-smooth-weighted-round-robin/fc16ba37-06b0-4193-9969-7541852dd46c.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howborn/blog/HEAD/source/_posts/2018/12/load-balance-smooth-weighted-round-robin/fc16ba37-06b0-4193-9969-7541852dd46c.jpg -------------------------------------------------------------------------------- /dockerfiles/nginx/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM nginx:1.24.0 2 | 3 | RUN sed -i s@/deb.debian.org/@/mirrors.aliyun.com/@g /etc/apt/sources.list 4 | RUN apt-get update && apt-get install -y cron wget python 5 | 6 | ADD nginx.conf /etc/nginx/nginx.conf 7 | 8 | ADD *.sh / 9 | RUN chmod 777 /*.sh 10 | 11 | ADD ssl/* /var/www/ssl/ 12 | RUN chmod +x /var/www/ssl/*.sh 13 | RUN chmod 777 -R /var/log/nginx -------------------------------------------------------------------------------- /dockerfiles/nginx/conf.d/common: -------------------------------------------------------------------------------- 1 | if ($http_user_agent ~ "DNSPod") { 2 | return 200; 3 | } 4 | 5 | #https证书申请使用,不再往下匹配 6 | location ^~ /.well-known/acme-challenge/ { 7 | alias /var/www/ssl/challenges/; 8 | try_files $uri = 404; 9 | } 10 | 11 | #网站地图地址 12 | location ~ /sitemap|map\.(html|xml)$ { 13 | expires off; 14 | } 15 | 16 | 17 | #防止图片盗链,1天的过期时间 18 | location ~ .*\.(jpg|jpeg|gif|png|bmp|swf|fla|flv|mp3|ico|js|css)$ { 19 | access_log off; 20 | expires 1d; 21 | } -------------------------------------------------------------------------------- /dockerfiles/nginx/start.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | dir="/var/www/ssl" 4 | mkdir -p $dir/challenges 5 | 6 | # 是否启用HTTPS 7 | if [ "$ENABLE_SSL" = "false" ]; then 8 | 9 | # 修改nginx配置, 不启用HTTPS 10 | sed -i '/https/d' /etc/nginx/nginx.conf 11 | else 12 | 13 | # 每2个月更新一次, 并重启nginx容器 14 | ssl_cron="0 0 1 */1 * $dir/refresh_cert.sh && nginx -s reload 2>> /var/log/acme_tiny.log" 15 | crontab -l | { cat; echo "$ssl_cron"; } | crontab - 16 | fi 17 | 18 | # 前台启动 19 | nginx -g "daemon off;" -------------------------------------------------------------------------------- /dockerfiles/nginx/conf.d/http/www.conf: -------------------------------------------------------------------------------- 1 | server { 2 | listen 80; 3 | server_name fanhaobai.com www.fanhaobai.com img.fanhaobai.com img0.fanhaobai.com img1.fanhaobai.com img2.fanhaobai.com img3.fanhaobai.com img4.fanhaobai.com img5.fanhaobai.com; 4 | root /var/www/blog/public; 5 | 6 | include conf.d/common; 7 | #重定向到https 8 | if ($request_uri !~ '(sitemap|map\.html|xml|\.well-known)|(robots\.txt)') { 9 | return 301 https://www.fanhaobai.com$request_uri; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /source/README.md: -------------------------------------------------------------------------------- 1 | # [后端搬运工]() 2 | 3 | [![](https://img.shields.io/github/issues/fan-haobai/blog.svg)](https://github.com/fan-haobai/blog/issues) [![](https://img.shields.io/github/forks/fan-haobai/blog.svg)](https://github.com/fan-haobai/blog/network) [![](https://img.shields.io/github/stars/fan-haobai/blog.svg)](https://github.com/fan-haobai/blog/stargazers) 4 | 5 | ![预览图](https://github.com/howborn/blog/blob/master/source/view.png) 6 | 7 | ## 关注公众号获取文章推送 8 | 9 | ![公众号](https://github.com/howborn/blog/blob/master/source/wechat.jpeg) -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: 'prod' 2 | services: 3 | nginx: 4 | restart: always 5 | build: ./dockerfiles/nginx 6 | ports: 7 | - "80:80" 8 | - "443:443" 9 | volumes: 10 | - "/var/www/blog:/var/www/blog" 11 | - "/var/www/ssl/certs:/var/www/ssl/certs" 12 | - "./dockerfiles/nginx/conf.d:/etc/nginx/conf.d" 13 | command: /bin/bash /start.sh 14 | env_file: 15 | - docker.env 16 | extra_hosts: 17 | - "raw.githubusercontent.com:199.232.96.133" 18 | container_name: "nginx" -------------------------------------------------------------------------------- /dockerfiles/nginx/conf.d/https/cert.conf: -------------------------------------------------------------------------------- 1 | ssl_prefer_server_ciphers on; 2 | 3 | ssl_certificate /var/www/ssl/certs/chained.pem; 4 | ssl_certificate_key /var/www/ssl/certs/domain.key; 5 | ssl_dhparam /var/www/ssl/certs/dhparams.pem; 6 | 7 | ssl_session_timeout 5m; 8 | ssl_protocols TLSv1 TLSv1.1 TLSv1.2; 9 | ssl_ciphers ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA; 10 | ssl_session_cache shared:SSL:50m; 11 | -------------------------------------------------------------------------------- /dockerfiles/nginx/ssl/init_ssl.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo "### Stoping nginx ..." 4 | docker-compose down 5 | 6 | echo "### Starting nginx ..." 7 | docker-compose -f docker-compose.yml -f ssl-override.yml up --force-recreate --build -d 8 | 9 | # 是否启动完成 10 | until [ "`docker inspect -f {{.State.Running}} nginx`"=="true" ]; do 11 | echo "### Wait nginx docker start ..." 12 | sleep 0.1; 13 | done; 14 | 15 | echo "### Gen nginx ssl ..." 16 | docker exec nginx /bin/bash /var/www/ssl/refresh_cert.sh 17 | 18 | echo "### Restart nginx ..." 19 | docker exec nginx nginx -s reload -------------------------------------------------------------------------------- /source/404.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 404 - 樊浩柏's blog 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 |

404错误,页面消失啦!

14 | 15 | 16 | -------------------------------------------------------------------------------- /source/about/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 关于 3 | layout: about 4 | date: 2016-02-10 5 | --- 6 | [本站所有文章,仅代表个人思想,与其他任何个人或组织无关!](#) 7 | 8 | ## 个人介绍 9 | 10 | 作者是一个乐于折腾的人,目前专注于互联网后端系统设计及性能优化。是一名电子 DIY、斯诺克、F1 爱好者。 11 | 12 | ### 技术公众号 13 | 14 | ![公众号](//www.fanhaobai.com/wechat.jpeg) 15 | 16 | ### 学习方法 17 | 18 | 喜欢写博客、逛博客、常 Google、研读开源项目、欣赏一些优秀的架构,空余时间会读一些书丰富自己。 19 | 20 |
21 | 每天至少读一篇博客;
22 | 每周至少看一个项目;
23 | 每月至少写一篇博客;
24 | 每季度至少读一本书;
25 | 每年至少会一门新技能;
26 | 
27 | 28 | ## 版权说明 29 | 30 | 主站 Blog 托管于 [Github](https://github.com/fan-haobai/blog),所有文章的 [Markdown 源文件](https://github.com/fan-haobai/blog/tree/master/_posts) 均可以直接查看或下载,除非单独说明外,个人转载本站的原创内容,请遵循 [CC BY-NC-SA 3.0](http://creativecommons.org/licenses/by-nc-sa/3.0/deed.zh) 的创作共享协议。 31 | -------------------------------------------------------------------------------- /dockerfiles/nginx/conf.d/https/www.conf: -------------------------------------------------------------------------------- 1 | server { 2 | listen 443; 3 | ssl on; 4 | server_name fanhaobai.com www.fanhaobai.com img.fanhaobai.com img0.fanhaobai.com img1.fanhaobai.com img2.fanhaobai.com img3.fanhaobai.com img4.fanhaobai.com img5.fanhaobai.com; 5 | root /var/www/blog/public; 6 | 7 | #fanhaobai.com重定向到www.fanhaobai.com 8 | if ($host ~ ^fanhaobai.com$) { 9 | return 301 https://www.fanhaobai.com$request_uri; 10 | } 11 | 12 | #404特殊页面日志排除 13 | location ~ /404.html { 14 | if ($request_uri ~* '/(file/upload)|jianshu|hangqing|qinghua|script|lib|pifa|(apple\-touch)|(wp\-login))' { 15 | access_log off; 16 | } 17 | } 18 | 19 | include conf.d/common; 20 | include conf.d/rewrite; 21 | } -------------------------------------------------------------------------------- /hooks.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "id": "webhook-deploy-hexo", 4 | "execute-command": "/restart.sh", 5 | "command-working-directory": "/", 6 | "include-command-output-in-response": true, 7 | "trigger-rule": 8 | { 9 | "and": 10 | [ 11 | { 12 | "match": 13 | { 14 | "type": "payload-hash-sha1", 15 | "secret": "88E7fe7aDf58d8a42108F0b7c2065d55dF3204D7", 16 | "parameter": 17 | { 18 | "source": "header", 19 | "name": "X-Hub-Signature" 20 | } 21 | } 22 | }, 23 | { 24 | "match": 25 | { 26 | "type": "value", 27 | "value": "refs/heads/master", 28 | "parameter": 29 | { 30 | "source": "payload", 31 | "name": "ref" 32 | } 33 | } 34 | } 35 | ] 36 | } 37 | } 38 | ] -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "fhb-blog", 3 | "version": "1.0.0", 4 | "private": true, 5 | "scripts": { 6 | "build": "hexo generate", 7 | "clean": "hexo clean", 8 | "deploy": "hexo deploy", 9 | "server": "hexo server" 10 | }, 11 | "hexo": { 12 | "version": "5.4.2" 13 | }, 14 | "dependencies": { 15 | "hexo": "^5.4.2", 16 | "hexo-deployer-git": "^3.0.0", 17 | "hexo-generator-archive": "^1.0.0", 18 | "hexo-generator-baidu-sitemap": "^0.1.2", 19 | "hexo-generator-category": "^1.0.0", 20 | "hexo-generator-feed": "^1.2.0", 21 | "hexo-generator-index": "^2.0.0", 22 | "hexo-generator-json-content": "^3.0.1", 23 | "hexo-generator-json-feed": "^1.0.0", 24 | "hexo-generator-sitemap": "^1.1.2", 25 | "hexo-generator-tag": "^1.0.0", 26 | "hexo-helper-qrcode": "^1.0.1", 27 | "hexo-renderer-ejs": "^1.0.0", 28 | "hexo-renderer-marked": "^3.0.0", 29 | "hexo-renderer-stylus": "^2.0.0", 30 | "hexo-server": "^2.0.0" 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /dockerfiles/nginx/ssl/refresh_cert.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | dir='/var/www/ssl' 4 | certs_dir="$dir/certs" 5 | 6 | mkdir -p $certs_dir 7 | cd $certs_dir 8 | 9 | if [ -z "$SSL_DOMAINS" ]; then 10 | echo "### Domains is empty" 11 | exit 1 12 | fi 13 | 14 | echo "### Starting ssl ..." 15 | 16 | openssl genrsa 4096 > account.key 17 | openssl genrsa 4096 > domain.key 18 | 19 | domains=`echo "DNS:$SSL_DOMAINS" | sed 's/,/&DNS:/g'` 20 | echo "### Gen domain key, domains: $domains ..." 21 | openssl req -new -sha256 -key domain.key -subj "/" -reqexts SAN -config \ 22 | <(cat /etc/ssl/openssl.cnf <(printf "[SAN]\nsubjectAltName=$domains")) > domain.csr 23 | 24 | echo "### Download acme_tiny script ..." 25 | wget https://raw.githubusercontent.com/diafygi/acme-tiny/master/acme_tiny.py -O acme_tiny.py 26 | 27 | echo "### Gen chained cert ..." 28 | python acme_tiny.py --account-key account.key --csr domain.csr --acme-dir $dir/challenges/ > signed.crt || exit 29 | openssl dhparam -out dhparams.pem 2048 30 | wget -O - https://letsencrypt.org/certs/lets-encrypt-x3-cross-signed.pem > intermediate.pem 31 | cat signed.crt intermediate.pem > chained.pem 32 | 33 | echo "### End ssl ..." -------------------------------------------------------------------------------- /source/_data/project.json: -------------------------------------------------------------------------------- 1 | { 2 | "define": { 3 | "diy": "DIY", 4 | "coder": "Coder" 5 | }, 6 | "contents": { 7 | "diy": [ 8 | { 9 | "title": "飞思卡尔智能车", 10 | "cover": "//www.fanhaobai.com/project/index/CVyYJnKtigzaHiRQOKmtfMZE.jpg", 11 | "review": "", 12 | "link": "https://github.com/howborn/smart-car-freescale" 13 | }, 14 | { 15 | "title": "点阵打字机", 16 | "cover": "//www.fanhaobai.com/project/index/W44BkT8TENzNCoih07mEyLN-.jpg", 17 | "review": "", 18 | "link": "https://github.com/howborn/dot-matrix-printer" 19 | }, 20 | { 21 | "title": "四旋翼", 22 | "cover": "//www.fanhaobai.com/project/index/6WaPq-7Kfi1wLVo5ZE2P1d0y.jpg", 23 | "review": "", 24 | "link": "https://github.com/howborn/quadrotor-uav" 25 | }, 26 | { 27 | "title": "电子元器件3D模型", 28 | "cover": "//www.fanhaobai.com/project/index/electron-component-3d.png", 29 | "review": "", 30 | "link": "https://github.com/howborn/electron-component-3d" 31 | } 32 | ], 33 | "coder": [ 34 | { 35 | "title": "php-server", 36 | "cover": "//www.fanhaobai.com/project/index/php-server.jpg", 37 | "review": "", 38 | "link": "https://github.com/howborn/php-server" 39 | }, 40 | { 41 | "title": "smart-car-freescale", 42 | "cover": "//www.fanhaobai.com/project/index/smart-car-freescale.png", 43 | "review": "", 44 | "link": "https://github.com/howborn/smart-car-freescale" 45 | } 46 | ] 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /dockerfiles/nginx/conf.d/rewrite: -------------------------------------------------------------------------------- 1 | rewrite ^/2022/01/2021-personal-summary(.*) /2021/12/2021-personal-summary$1 permanent; 2 | rewrite ^/2021/01/2021-personal-summary(.*) /2021/12/2021-personal-summary$1 permanent; 3 | rewrite ^/2017/08/solr-insatll(.*) /2017/08/solr-install$1 permanent; 4 | rewrite ^/2017/11/elk(.*) /2017/12/elk$1 permanent; 5 | rewrite ^/post/upgrade-gcc-4.8(.*) /2016/12/upgrade-gcc$1 permanent; 6 | rewrite ^/post/linux-version(.*) /2016/07/linux-version$1 permanent; 7 | rewrite ^/post/nodejs-install(.*) /2016/12/nodejs-install$1 permanent; 8 | rewrite ^/post/docker-install(.*) /2017/01/docker-install$1 permanent; 9 | rewrite ^/post/firekylin(.*) /2016/12/firekylin$1 permanent; 10 | rewrite ^/post/mongo-docker-install(.*) /2017/01/mongo-docker-install$1 permanent; 11 | rewrite ^/post/iptables(.*) /2017/02/iptables$1 permanent; 12 | rewrite ^/post/ajax-cookie(.*) /2016/12/ajax-cookie$1 permanent; 13 | rewrite ^/post/recover-file(.*) /2016/05/recover-file$1 permanent; 14 | rewrite ^/post/redis-install(.*) /2016/08/redis-install$1 permanent; 15 | rewrite ^/post/robots(.*) /2017/01/robots$1 permanent; 16 | rewrite ^/post/update-sitemap(.*) /2017/01/update-sitemap$1 permanent; 17 | rewrite ^/post/ssh-safely-use(.*) /2016/08/ssh-safely-use$1 permanent; 18 | rewrite ^/post/nginx-error-log(.*) /2017/01/nginx-error-log$1 permanent; 19 | rewrite ^/post/win10-vm-network(.*) /2016/02/win10-vm-network$1 permanent; 20 | rewrite ^/post/lock-ip(.*) /2017/02/lock-ip$1 permanent; 21 | rewrite ^/post/reward(.*) /2017/02/reward$1 permanent; 22 | rewrite ^/post/letsencrypt(.*) /2016/12/lets-encrypt$1 permanent; 23 | rewrite ^/post/linux-tool-website(.*) /2017/02/linux-tool-website$1 permanent; 24 | rewrite ^/rss /atom.xml last; 25 | rewrite ^/map /sitemap.xml last; -------------------------------------------------------------------------------- /dockerfiles/nginx/nginx.conf: -------------------------------------------------------------------------------- 1 | worker_processes 4; 2 | error_log /var/log/nginx/error.log; 3 | 4 | events { 5 | use epoll; 6 | worker_connections 2048; 7 | } 8 | 9 | http { 10 | include mime.types; 11 | default_type application/octet-stream; 12 | #日志格式 13 | log_format main '$remote_addr - $remote_user [$time_local] "$request" ' 14 | '$status $body_bytes_sent "$http_referer" ' 15 | '"$http_user_agent" "$http_x_forwarded_for" "$request_body"'; 16 | access_log /var/log/nginx/$server_name.access.log main; 17 | 18 | index index.html index.php; 19 | #错误页面 20 | error_page 403 404 500 502 503 504 /404.html; 21 | #关闭错误页面的nginx版本号 22 | server_tokens off; 23 | sendfile on; 24 | #tcp_nopush on; 25 | keepalive_timeout 65; 26 | client_max_body_size 10m; 27 | fastcgi_temp_file_write_size 128k; 28 | fastcgi_intercept_errors on; 29 | charset utf-8; 30 | #开启gzip 31 | gzip on; 32 | gzip_min_length 1k; 33 | gzip_buffers 16 64k; 34 | gzip_http_version 1.1; 35 | gzip_comp_level 6; 36 | gzip_types text/plain application/x-javascript text/css application/xml application/json text/javascript application/x-httpd-php image/jpeg image/gif image/png; 37 | gzip_vary on; 38 | 39 | #proxy设置 40 | proxy_connect_timeout 2s; 41 | proxy_read_timeout 2s; 42 | proxy_redirect off; 43 | proxy_set_header X-Real-IP $remote_addr; 44 | proxy_set_header X-Forwarded-For $remote_addr; 45 | proxy_temp_path /var/www/temp; 46 | proxy_cache_path /var/www/cache levels=1:2 keys_zone=cache_one:50m inactive=2h max_size=10g; 47 | 48 | #限流 49 | limit_req_zone $binary_remote_addr zone=one:10m rate=10r/s; 50 | 51 | include conf.d/https/*.conf; 52 | include conf.d/http/*.conf; 53 | } 54 | -------------------------------------------------------------------------------- /source/_data/reading.json: -------------------------------------------------------------------------------- 1 | { 2 | "define": { 3 | "readed": "已读", 4 | "reading": "在读", 5 | "wanted": "想读" 6 | }, 7 | "contents": { 8 | "readed": [ 9 | { 10 | "title": "Head First设计模式", 11 | "cover": "//img3.doubanio.com/lpic/s2414323.jpg", 12 | "time": "2016", 13 | "doubanLink": "https://book.douban.com/subject/2243615/" 14 | }, 15 | { 16 | "title": "大型网站技术架构", 17 | "cover": "//img3.doubanio.com/lpic/s27250675.jpg", 18 | "time": "2017", 19 | "doubanLink": "https://book.douban.com/subject/25723064/" 20 | }, 21 | { 22 | "title": "打造facebook", 23 | "cover": "//img3.doubanio.com/lpic/s24581301.jpg", 24 | "time": "2017", 25 | "doubanLink": "https://book.douban.com/subject/20471120/" 26 | }, 27 | { 28 | "title": "富爸爸穷爸爸", 29 | "cover": "//img3.doubanio.com/lpic/s27274192.jpg", 30 | "time": "2018", 31 | "doubanLink": "https://book.douban.com/subject/25816940/" 32 | } 33 | ], 34 | "reading": [ 35 | { 36 | "title": "底层逻辑", 37 | "cover": "//img3.doubanio.com/lpic/s34012502.jpg", 38 | "doubanLink": "https://book.douban.com/subject/30155731/" 39 | }, 40 | { 41 | "title": "算法之美", 42 | "cover": "//img3.doubanio.com/lpic/s29762735.jpg", 43 | "doubanLink": "https://book.douban.com/subject/30155731/" 44 | } 45 | ], 46 | "wanted": [ 47 | { 48 | "title": "高扩展性网站的50条原则", 49 | "cover": "//img3.doubanio.com/lpic/s9126724.jpg", 50 | "doubanLink": "https://book.douban.com/subject/10756899/" 51 | }, 52 | { 53 | "title": "代码整洁之道", 54 | "cover": "//img3.doubanio.com/lpic/s6268784.jpg", 55 | "doubanLink": "https://book.douban.com/subject/5442024/" 56 | } 57 | ] 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /source/_posts/2022/12/user-profile-use-flink.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Flink在用户画像上的应用 3 | date: 2022-12-23 19:00:00 4 | tags: 5 | - 架构 6 | --- 7 | 8 | 将 Flink 应用于用户画像的场景,既能轻松应对大量的计算量,也能提供实时的计算结果,还能避免开发同学用编程的方式开发数据清洗任务。 9 | ![风控抽象过程](//www.fanhaobai.com/2022/12/user-profile-use-flink/FAA84305-96B3-4934-8991-C5ACE2752C5A.png) 10 | 11 | ## 关键词 12 | 13 | * 大数据计算 14 | * SQL 15 | 16 | ## 痛点 17 | 18 | 解决计算海量数据计算量大、延迟高的性能问题,如用户画像需要计算大量业务和事件数据的场景。 19 | ![海量数据](//www.fanhaobai.com/2022/12/user-profile-use-flink/082D3F30-8845-4943-AC1E-6AF494885350.png) 20 | 21 | ## 商业价值 22 | ### 数据即价值 23 | 24 | 对平台积累的大量数据进行挖掘分析,创造出潜在的商业价值。 25 | 26 | ## 概述 27 | ### 什么是 Flink 28 | 29 | Flink 是一个分布式计算引擎,可以用来做批处理,即处理历史数据;也可以用来做流处理,即实时地处理数据流,并实时地产生数据的结果。 30 | ![Flink处理数据流程](//www.fanhaobai.com/2022/12/user-profile-use-flink/DD0DBEE8-32B8-4A78-B0A2-3907A710907A.png) 31 | 32 | Flink 特点: 33 | 34 | * 性能突出:计算量大-百亿级、延迟低-秒级 35 | * 支持 SQL 作业:只需要写 SQL 逻辑,简单上手快 36 | * 有状态支持容错:即发生了失败,也不会丢失、多计算或者少计算 37 | 38 | Flink 支持丰富的数据源,能满足大部分的业务场景需求。数据输入源支持 MySQL、Mongo 等数据库,也支持 Kafka 等事件消息中心;数据输出源支持 MySQL、Mongo、Redis 等数据库,也支持 Hbase、Hive 等数据仓库。 39 | 40 | ### 当前行业现状 41 | 42 | Flink 已成为了大数据计算引擎的首选,国内各大厂都有相应的落地实践案例,技术比较成熟。各云厂商也都提供了相应的云计算产品: 43 | 44 | * 腾讯云:[Oceanus](https://cloud.tencent.com/product/oceanus) 45 | * 阿里云:[Flink](https://www.aliyun.com/product/bigdata/sc) 46 | 47 | ## 解决方案介绍 48 | ### Flink 怎样接入 49 | 50 | ![Flink怎样接入](//www.fanhaobai.com/2022/12/user-profile-use-flink/FAA84305-96B3-4934-8991-C5ACE2752C5A.png) 51 | 52 | Flink 数据输入端接入 MySQL 数据库和 Kafka 消息中心,能同时对业务数据和业务事件 2 种数据类型进行处理。 53 | Flink 计算输出结果一般存储在 Hive、Hbase 等大数据数仓。 因此,接入已有系统数据源并不需要做任何改造。 54 | 55 | ### SQL 作业使用 56 | 57 | 数据的计算逻辑任务,一般都会选择 SQL 作业的类型。 58 | 对开发者友好,只需要用 SQL 表达出对应逻辑即可。 59 | 60 | ![SQL作业](//www.fanhaobai.com/2022/12/user-profile-use-flink/4C7CA16C-53B3-455A-86B0-D0917B69C21E.png) 61 | 62 | ## 我们的机会 63 | ### 业务场景 64 | 65 | #### 用户画像 66 | 67 | ![架构](//www.fanhaobai.com/2022/12/user-profile-use-flink/96A9AAFE-201F-48DF-8318-ED035B06269C.png) 68 | 69 | 如图所示,交易数据、处方数据、用户基础数据、用户行为数据作为数据源,经过大数据 Flink 计算清洗、结构化、预处理后,产出疾病特征、基本属性、行为特征画像数据。 70 | 71 | 借助于 Flink,这一切只需要编写 SQL 即可,数据的处理、分布式调度我们都不需要关心。 72 | 73 | 74 | -------------------------------------------------------------------------------- /source/_posts/2017/12/2017-ziroom-king-4.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 王者编程大赛之四 — 约瑟夫环 3 | date: 2017-12-06 13:12:00 4 | tags: 5 | - 算法 6 | - 数据结构 7 | categories: 8 | - 算法 9 | --- 10 | 11 | 每年夏季自如都会组织夏季夏令营活动,给来京参加夏令营的小朋友准备好多礼物,今年也是如此。 12 | 13 | ![](//www.fanhaobai.com/2017/12/2017-ziroom-king-4/3d9cf2e7-dfe6-4b6e-8526-991296c3ea51.png) 14 | 15 | 组委会准备了一些小游戏来获得这些礼物,其中有一个游戏是这样的:组委会让小朋友围成一个圈。然后随机制定一个数 e,让编号为 0 的小朋友开始报数。每次喊道 e-1 的小朋友直接出列,淘达出局。从本次喊道 e-1 的下一个小朋友开始,继续从 0 报数...e-1 淘汰出局...一直这样进行...最后进行到最后一个小朋友,这位可以拿到"熊帅"亲笔签名的"木木"毛绒玩具。(注:小朋友的编号是从 0 到 n-1 ) 16 | 17 | 示例: 18 | 输入:n=1314 e=520 19 | 输出:796 20 | 输入:n=88888 e=1018 21 | 输出:69148 22 | 23 | ## 解题思路 24 | 25 | 该题是一个 [约瑟夫环](https://zh.wikipedia.org/wiki/%E7%BA%A6%E7%91%9F%E5%A4%AB%E6%96%AF%E9%97%AE%E9%A2%98) 问题(猴子选大王),这里运用数学知识找出递推关系式。 26 | 27 | 假设,总共有 n 个人,数到 k(n >= k)的人被杀掉,幸存者的位置为 $p_n$(为了便于理解,编号从 1 开始)。 28 | 29 | 易知,初始位置为 k 的人会被第一个杀掉。此时,经过重新排序之后,问题变成了 n-1 个人的情形。幸存者的位置为 $p_{n-1}$。如果能够找到从 $p_{n}$ 到 $p_{n-1}$ 的递推关系,那么问题就解决了。 30 | 31 | ![](//www.fanhaobai.com/2017/12/2017-ziroom-king-4/3d9cf2e7-dfe6-4b6e-8526-991296c3ea51.png) 32 | 33 | 重新编号后,上一轮相对这一轮每个人位置关系映射为: 34 | 35 | 1 -> n-k+1 36 | 2 -> n-k+2 37 | ... 38 | k-1 -> n-1 39 | k+1 -> 1 40 | ... 41 | $p_n$ -> $p_{n-1}$ 42 | ... 43 | n-1 -> n-k+1 44 | n -> n-k 45 | 46 | 这样,我们就得到一个递推关系式:[$p_n = (p_{n-1} + k)$ % $n$](#),初始条件 $p_1 = 1$(1 个人时幸存者为自己),当然该提递推公式同样适用于 n < k 的情况。 47 | 48 | ## [编码实现](https://github.com/fan-haobai/2017-ziroom-king/blob/master/src/6.php) 49 | 50 | 约瑟夫环递推实现: 51 | 52 | ```PHP 53 | function josephus($n, $e) 54 | { 55 | $idx = 0; 56 | for ($i = 2; $i <= $n; $i ++) { 57 | $idx = ($idx + $e) % $i; 58 | } 59 | return $idx; 60 | } 61 | ``` 62 | 63 | 接收标准输入处理并输出结果: 64 | 65 | ```PHP 66 | $input = str_replace(' ', '&', $input); 67 | parse_str($input, $arr); 68 | echo josephus($arr['n'], $arr['e']), PHP_EOL; 69 | ``` 70 | 71 | ## 总结 72 | 73 | 由于本题只是需要求出最终的幸存者编号,所以可以直接使用递推公式求解,算法时间复杂度为 $O(n)$。若需要模拟整个游戏过程,则需要使用 [链表](http://blog.csdn.net/sxhelijian/article/details/9052891) 模拟实现。 74 | 75 | 相关文章 [»](#) 76 | 77 | * [王者编程大赛之一](https://www.fanhaobai.com/2017/12/2017-ziroom-king-1.html) (2017-12-05) 78 | * [王者编程大赛之二 — 蓄水池](https://www.fanhaobai.com/2017/12/2017-ziroom-king-2.html) (2017-12-05) 79 | * [王者编程大赛之三 — 01背包](https://www.fanhaobai.com/2017/12/2017-ziroom-king-3.html) (2017-12-05) 80 | * [王者编程大赛之五 — 最短路径](https://www.fanhaobai.com/2017/12/2017-ziroom-king-5.html) (2017-12-06) -------------------------------------------------------------------------------- /_config.yml: -------------------------------------------------------------------------------- 1 | # Hexo Configuration 2 | ## Docs: https://hexo.io/docs/configuration.html 3 | ## Source: https://github.com/hexojs/hexo/ 4 | 5 | # Site 6 | title: 后端搬运工 7 | subtitle: 公众号:后端搬运工 8 | subtitle_url: '/about/#技术公众号' 9 | description: 目前专注于后端研发,关注分布式系统性能优化。 10 | keywords: "架构,后端,Go,开发者,编程,代码,开源,Coder,Geek" 11 | author: 12 | language: zh-CN 13 | 14 | # URLh 15 | ## If your site is put in a subdirectory, set url as 'http://yoursite.com/child' and root as '/child/' 16 | url: https://www.fanhaobai.com 17 | root: / 18 | permalink: :title.html 19 | permalink_defaults: 20 | lang: en 21 | pretty_urls: 22 | trailing_index: true 23 | trailing_html: true 24 | 25 | # Directory 26 | source_dir: source 27 | public_dir: public 28 | tag_dir: tags 29 | archive_dir: archives 30 | category_dir: categories 31 | code_dir: downloads/code 32 | i18n_dir: :lang 33 | skip_render: 34 | - "**/*.(png)|(jpg)|(jpeg)|(ico)" 35 | - "**/*.txt" 36 | - "404.html" 37 | - "*.md" 38 | - "CNAME" 39 | 40 | # Writing 41 | new_post_name: :title.md 42 | default_layout: post 43 | titlecase: false 44 | filename_case: 0 45 | render_drafts: false 46 | post_asset_folder: true 47 | relative_link: true 48 | future: true 49 | highlight: 50 | enable: true 51 | line_number: false 52 | auto_detect: false 53 | tab_replace: 54 | 55 | # Home page setting 56 | # path: Root path for your blogs index page. (default = '') 57 | # per_page: Posts displayed per page. (0 = disable pagination) 58 | # order_by: Posts order. (Order by date descending by default) 59 | index_generator: 60 | path: '' 61 | per_page: 10 62 | order_by: -date 63 | 64 | # Date / Time format 65 | ## Hexo uses Moment.js to parse and display date 66 | ## You can customize the date format as defined in 67 | ## http://momentjs.com/docs/#/displaying/format/ 68 | date_format: YYYY-MM-DD 69 | time_format: HH:mm:ss 70 | 71 | # Pagination 72 | ## Set per_page to 0 to disable pagination 73 | per_page: 10 74 | pagination_dir: page 75 | 76 | # Extensions 77 | ## Plugins: https://hexo.io/plugins/ 78 | ## Themes: https://hexo.io/themes/ 79 | theme: yilia 80 | 81 | sitemap: 82 | path: sitemap.xml 83 | 84 | feed: 85 | type: atom 86 | path: atom.xml 87 | limit: 100 88 | 89 | jsonContent: 90 | meta: false 91 | pages: false 92 | posts: 93 | title: true 94 | date: true 95 | path: true 96 | text: false 97 | raw: false 98 | content: false 99 | slug: false 100 | updated: false 101 | comments: false 102 | link: false 103 | permalink: false 104 | excerpt: false 105 | categories: false 106 | tags: true 107 | 108 | deploy: 109 | type: git 110 | repo: git@github.com:howborn/howborn.github.io.git 111 | # example, https://github.com/hexojs/hexojs.github.io 112 | branch: master -------------------------------------------------------------------------------- /source/_posts/2023/01/recommender-system.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 千人千面个性化推荐系统 3 | date: 2023-01-02 14:00:00 4 | tags: 5 | - 架构 6 | --- 7 | 8 | 千人千面是指系统基于用户的兴趣,通过复杂算法来推荐个性化的内容,不再是千篇一律,达到用户所见即所需的效果,能显著提高成交转化率,更能提升用户体验。 9 | 10 | ![推荐系统](//www.fanhaobai.com/2023/01/recommender-system/19F578B4-4B33-4F28-AAE4-D4C71308A360.png) 11 | 12 | ## 关键词 13 | 14 | * 千人千面 15 | * 个性化推荐 16 | * 内容系统 17 | * 算法 18 | 19 | ## 发展历程 20 | 21 | 目前我们日常使用互联网应用几乎都应用了个性化推荐技术,但是它的推广应用却不是一蹴而就的。 22 | 23 | * 第一阶段 24 | 2012年今日头条上线,第一个利用推荐系统进行流量分发的内容APP 25 | 26 | * 第二阶段 27 | 2015年淘宝双11全面开启“千人千面”时代 28 | 29 | * 现在 30 | 知乎、抖音、美团等各大应用都在使用推荐系统进行个性化内容推荐 31 | 32 | ## 商业价值 33 | ### 提升用户体验 34 | 35 | 所见即所需,不再需要用户从成千上万的内容中去挑选自己感兴趣的。 36 | 37 | ### 提高成交转化率 38 | 39 | 精准推广,用户成交冲动更强。 40 | 41 | ## 解决方案介绍 42 | ### 应用场景举例 43 | #### 搜索列表 44 | 45 | * 淘宝搜索商品 46 | 关键字搜索,并根据相似度排序来推荐相似的商品。 47 | 48 | ![淘宝搜索商品](//www.fanhaobai.com/2023/01/recommender-system/5D1A9AD7-9EDF-4607-A2D2-8B73D9FEA7B5.png) 49 | 50 | * 美团外卖搜索 51 | 关键字搜索,并根据商家距离、评分、配送速度等因素来综合排序推荐。 52 | 53 | ![美团外卖](//www.fanhaobai.com/2023/01/recommender-system/7A956F05-52D9-4B2F-9466-62883F81958D.png) 54 | 55 | * 信息流 56 | 知乎首页信息流,推荐有浏览、赞同、评价的同类内容,以及关注的人的内容,曾发表过的文章有相同主题的内容。 57 | 58 | ![知乎](//www.fanhaobai.com/2023/01/recommender-system/D1C891D1-878A-4B95-97D7-BBA7AFAB3467.png) 59 | 60 | * 猜你喜欢 61 | 推荐用户购买过、浏览过商品的同类商品,还可以推荐对相同商品有相同行为的这类用户的购买和浏览商品。 62 | 63 | ![猜你喜欢](//www.fanhaobai.com/2023/01/recommender-system/74661B99-43E6-4532-9B93-AAB9469E5DD1.png) 64 | 65 | ### 技术路线 66 | 67 | 因为推荐系统整个的技术难度较大,一般都是算法专业且有经验的团队来做。实践中可以分3个阶段来做:千人几面——千人百面——千人千面 68 | 69 | * 萌芽:千人几面 70 | 基于规则匹配推荐。制定一些简单的业务规则,如根据用户自己对内容产生的浏览次数(看了又看)、购买次数(买了还买),收藏次数来做简单的推荐;或者根据性别年龄分类来做推荐,18岁的女生都喜欢什么,中年大叔又都喜欢什么。 71 | 72 | ![千人几面](//www.fanhaobai.com/2023/01/recommender-system/E2A4D0D2-EA74-4130-A8CE-4B7FBD9E9E40.png) 73 | 74 | * 起步:千人百面 75 | 基于内容的推荐。如果只是推荐用户已经产生行为的内容,那这些内容也只会是单一的,对用户吸引性不强。那么我们可以基于用户产生行为的这些内容做相似推荐,如推荐相同分类、品牌、标签的内容。 76 | 77 | ![千人百面](//www.fanhaobai.com/2023/01/recommender-system/5FF361FE-B7B5-4A01-9DA5-CF9AEC5B7462.png) 78 | 79 | * 绽芒:千人千面,比你自己更懂你 80 | 基于协同过滤的推荐。基于内容的推荐已经能基本满足用户的推荐需求,却不能做到真正的千人千面,因为都是基于用户自己的行为数据来做推荐。 81 | 82 | ![千人千面](//www.fanhaobai.com/2023/01/recommender-system/41C31DFF-9546-413B-82A5-794DC47488B7.png) 83 | 84 | 协同过滤不单单只根据自己的喜好,而且还引入了相同行为的人的喜好来进行推荐,即我喜欢的内容,他也喜欢,那么他喜欢的其他内容我可能也很喜欢。以人类人这样推荐更加充分,而且可以深入挖掘用户潜在的兴趣。 85 | 86 | **那怎么计算内容相似度呢?** 87 | 首先提取出内容的特征,又通计算得出了用户喜欢的特征,那么可以通过余弦相似度计算出内容间的相似度,做为个性化推荐的依据。余弦相似度是指通过计算两个向量的夹角余弦值来评估他们的相似度,夹角越小,两个向量越相似;夹角越大,两个向量越不同。 88 | 89 | ![内容相似度](//www.fanhaobai.com/2023/01/recommender-system/BD317F5E-8689-4139-BE07-FC82C6EEA69A.png) 90 | 91 | ## 我们的机会 92 | ### 业务场景 93 | 94 | * 药房与药品列表 95 | 能直接猜出用户所需的药品,而不是简单配一些常见药。 96 | 97 | ![药房与药品列表](//www.fanhaobai.com/2023/01/recommender-system/B4417679-0FCA-4EA0-8E95-CAA95912C05E.png) 98 | 99 | * 医生列表 100 | 对于一个肝病患者展示这些,患者也只能再去搜医生的名字或者科室才能找到医生。 101 | 102 | ![医生列表](//www.fanhaobai.com/2023/01/recommender-system/E7E33224-409F-44E4-8A39-EDA85F89435C.png) 103 | 104 | * 学术文章信息流 105 | 医生很忙,不能推些他不感兴趣的学术内容打扰他。 106 | 107 | ![学术文章信息流](//www.fanhaobai.com/2023/01/recommender-system/97FD0BB9-EA8C-4BBD-BAAA-8721149084F3.png) 108 | -------------------------------------------------------------------------------- /source/_posts/2017/08/redis-pipelining.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 使用Redis管道提升性能 3 | date: 2017-08-31 14:10:35 4 | tags: 5 | - Redis 6 | categories: 7 | - DB 8 | - Redis 9 | --- 10 | 11 | Redis 的 [管道](https://redis.io/topics/pipelining) (pipelining)是用来打包多条无关命令批量执行,以减少多个命令分别执行带来的网络交互时间。在一些批量操作数据的场景,使用管道可以显著提升 Redis 的读写性能。 12 | 13 | ![预览图](http://www.fanhaobai.com/2017/08/redis-pipelining/abc8ae13-9f76-4cd0-902d-a4fbb9fedd4f.png) 14 | 15 | ## 原理演示 16 | 17 | Redis 的管道实质就是命令打包批量执行,多次网络交互减少到单次。使用管道和不使用管道时的交互过程如下: 18 | 19 | ![原理图](http://www.fanhaobai.com/2017/08/redis-pipelining/abc8ae13-9f76-4cd0-902d-a4fbb9fedd4f.png) 20 | 21 | 我们使用 nc 命令来直观感受下 Redis 管道的使用过程: 22 | 23 | ```Shell 24 | # 安装nc命令 25 | $ yum install nc 26 | # nc打包多个命令 27 | $ (printf "PING\r\nPING\r\nPING\r\n") | nc localhost 6379 28 | # 响应 29 | +PONG 30 | +PONG 31 | +PONG 32 | ``` 33 | 34 | 因此,只要通过管道进行命令打包后,Redis 就可以批量返回命令的执行结果了。 35 | 36 | ## 管道的应用 37 | 38 | 首先,构造示例需要的 Hash 用户数据: 39 | 40 | ```PHP 41 | $keyPrex = 'user:hash:u:'; 42 | for ($i=1; $i<=10000; $i++) { 43 | $redis->hMset($keyPrex.$i, [ 44 | 'name' => name(), //name()函数生成随机姓名 45 | 'age' => rand(21, 30), 46 | 'sex' => rand(0, 1), 47 | 'is_new' => rand(0, 1) 48 | ]); 49 | } 50 | ``` 51 | 52 | 然后,查看导入 Redis 中的数据: 53 | 54 | ```Redis 55 | 127.0.0.1:6379> keys user:hash:u:* 56 | 9997) "user:hash:u:3013" 57 | 9998) "user:hash:u:8971" 58 | 9999) "user:hash:u:4761" 59 | 10000) "user:hash:u:1828" 60 | 61 | 127.0.0.1:6379> HGETALL user:hash:u:1828 62 | 1) "name" 63 | 2) "ggrg" 64 | 3) "age" 65 | 4) "23" 66 | 5) "sex" 67 | 6) "0" 68 | 7) "is_new" 69 | 8) "1" 70 | ``` 71 | 72 | ### 需求 73 | 74 | 在某个社交活动中,通过一系列筛选逻辑后取得种子用户 uid,然后用这些 uid 去 Hash 获取用户的信息。这种情况下你会怎么来处理呢? 75 | 76 | ### 不使用管道 77 | 78 | 一般情况下,在数据量较小时,我们会直接使用 HGETALL 命令遍历地获取用户数据。 79 | 80 | ```PHP 81 | $start = nowTime(); 82 | foreach (range(1, 1000) as $id) { 83 | $user[] = $redis->hgetAll($keyPrex.$id); 84 | } 85 | echo '时间:', nowTime() - $start, 'ms', PHP_EOL; 86 | 87 | 时间:39ms 88 | ``` 89 | 90 | 执行所用时间:[39ms](#) 91 | 92 | 93 | ### 使用管道 94 | 95 | 因为通过 uid 批量获取用户数据,各个命令并没有依赖关系,所以可以使用 Redis 的管道来优化查询。 96 | 97 | ```PHP 98 | $start = nowTime(); 99 | $redis->multi(Redis::PIPELINE); 100 | foreach (range(1, 1000) as $id) { 101 | //返回资源id相同的socket资源,并未执行命令 102 | $redis->hgetAll($keyPrex.$id); 103 | } 104 | $user = $redis->exec(); 105 | echo '时间:', nowTime() - $start, 'ms', PHP_EOL; 106 | 107 | 时间:6ms 108 | ``` 109 | 110 | 使用管道后,执行时间显著地减少为:[6ms](#)。使用 tcpdump 抓取打包后的命令如下: 111 | 112 | ```Tcp 113 | 10:45:03.029049 IP localhost.58176 > localhost.6379: Flags [P.], seq 2255478840:2255479211, ack 3144685411, win 342, options [nop,nop,TS val 17640474 ecr 17640474], length 371 114 | E..../@.@.o..........@...o.8.p.c...V....... 115 | ,.*2 116 | $7 117 | HGETALL 118 | $13 119 | user:hash:u:1 120 | *2 121 | $7 122 | HGETALL 123 | $13 124 | user:hash:u:2 125 | *2 126 | $7 127 | ... ... 128 | ``` 129 | 130 | ## 适用场景 131 | 132 | 在批量操作(查询和写入)数据时,我们应尽量避免多次跟 Redis 的网络交互。这时,可以使用管道实现,也可以 Redis 内嵌 Lua 脚本实现。**需要注意的是**: 133 | * [管道只适用于无因果关联的多命令操作](#),否则就需要借助 Lua 脚本实现批量操作; 134 | * 在实际应用中,Redis 往往不可能是单机部署,如果想要在集群中使用管道,可以部署为一主多从架构,此时所有节点的数据都一致,随机选取节点使用管道即可; 135 | 136 | ## 总结 137 | 138 | 在批量获取数据时,尽管使用 Redis 的管道性能会显著提升,但是使用管道时 Redis 会缓存之前命令的结果,最后一并输出给终端,因此所打包的命令不宜太多,否则内存使用会很严重。 139 | -------------------------------------------------------------------------------- /source/_posts/2017/12/elk.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: ELK集中式日志平台之一 — 平台架构 3 | date: 2017-12-16 13:14:00 4 | tags: 5 | - 系统设计 6 | - 日志 7 | categories: 8 | - 系统设计 9 | --- 10 | 11 | 随着微服务化的推广,我们的应用都会采取分布式方式部署,这就会导致应用日志比较分散,应用监控和排查问题都比较困难,同时效率还低下,集中式日志平台就是为了解决这个问题。 12 | 13 | ![](//www.fanhaobai.com/2017/12/elk/c0625948-b690-48ad-a178-63fc08b0cefb.png) 14 | 15 | ## 背景 16 | 17 | 很早前,我们的应用都已经接入了 [CAT](https://github.com/dianping/cat),能够在线实时查看应用访问量、异常的调用情况等应用性能指标,同时也打通了各平台的调用链路,基本满足应用的性能监控要求。 18 | 19 | ![](//www.fanhaobai.com/2017/12/elk/b488220c-e24a-4eaf-8ee9-81cc6ae9484c.png) 20 | 21 | 由于我们应用业务日志并没有推送到 CAT,所以当线上出现问题时,传统方式查看业务日志,排查问题比较困难,搭建业务日志集中平台迫在眉睫。经过调研,我们选择了 [Elastic](https://www.elastic.co) 提供的 ELK 日志解决方案,查看 [在线演示](http://demo.elastic.co/app/kibana#/dashboard/b7be4700-6837-11e7-bd1c-eb5e5ad48f8b)。 22 | 23 | 原因主要有两点: 24 | 25 | * ELK 提供的功能满足我们的使用要求,并有较高的扩展性; 26 | * ELK 为一套开源项目,较低的维护成本; 27 | 28 | ## 相关概念 29 | 30 | ELK 指的是一套解决方案,是 [Elasticsearch](https://www.elastic.co/cn/products/elasticsearch)、[Logstash](https://www.elastic.co/cn/products/logstash) 和 [Kibana](https://www.elastic.co/cn/products/kibana) 三种软件产品的首字母缩写,[Beats](https://www.elastic.co/cn/products/beats) 是 ELK 协议栈的新成员。 31 | 32 | * E:代表 Elasticsearch,负责日志的存储和检索; 33 | * L:代表 Logstash,负责日志的收集、过滤和格式化; 34 | * K:代表 Kibana,负责日志数据的可视化; 35 | * Beats:是一类轻量级数据采集器; 36 | 37 | 其中,目前 Beats 家族根据功能划分,主要包括 4 种: 38 | 39 | * Filebeat:负责收集文件数据; 40 | * Packetbeat:负责收集网络流量数据; 41 | * Metricbeat:负责收集系统级的 CPU 使用率、内存、文件系统、磁盘 IO 和网络 IO 统计数据; 42 | * Winlogbeat:负责收集 Windows 事件日志数据; 43 | 44 | ![](//www.fanhaobai.com/2017/12/elk/de986f14-1b7a-46f0-bf81-e477dda1e157.png) 45 | 46 | 在该日志平台系统中,就使用了 Filebeat 作为日志文件收集工具,Filebeat 可以很方便地收集 Nginx、Mysql、Redis、Syslog 等应用的日志文件。 47 | 48 | ## 日志平台架构 49 | 50 | ELK 集中式日志平台,总体上来说,部署在应用服务器上的数据采集器,近实时收集日志数据推送到日志过滤节点的 Logstash,然后 Logstash 再推送格式化的日志数据到 Elasticsearch 存储,Kibana 通过 Elasticsearch 集中检索日志并可视化。 51 | 52 | 当然,ELK 集中日志平台也是经过一次次演变,才变成最终的样子。 53 | 54 | ### ES + Logstash + Kibana 55 | 56 | ![](//www.fanhaobai.com/2017/12/elk/b19f74ae-2be3-4aef-b390-246acbf3050f.png) 57 | 58 | 最开始的架构中,由 Logstash 承担数据采集器和过滤功能,并部署在应用服务器。由于 Logstash 对大量日志进行过滤操作,会消耗应用系统的部分性能,带来不合理的资源分配问题;另一方面,过滤日志的配置,分布在每台应用服务器,不便于集中式配置管理。 59 | 60 | ### 引入Logstash-forwarder 61 | 62 | ![](//www.fanhaobai.com/2017/12/elk/c2f50522-4a60-47b5-80b3-69f194745e19.png) 63 | 64 | 使用该架构,引入 Logstash-forwarder 作为数据采集,Logstash 和应用服务器分离,应用服务器只做数据采集,数据过滤统一在日志平台服务器,解决了之前存在的问题。但是 Logstash-forwarder 和 Logstash 间通信必须由 SSL 加密传输,部署麻烦且系统性能并没有显著提升;另一方面,Logstash-forwarder 的定位并不是数据采集插件,系统不易扩展。 65 | 66 | ### 引入Beats 67 | 68 | ![](//www.fanhaobai.com/2017/12/elk/c0625948-b690-48ad-a178-63fc08b0cefb.png) 69 | 70 | 该架构,基于 Logstash-forwarder 架构,将 Logstash-forwarder 替换为 Beats。由于 Beats 的系统性能开销更小,所以应用服务器性能开销可以忽略不计;另一方面,Beats 可以作为数据采集插件形式工作,可以按需启用 Beats 下不同功能的插件,更灵活,扩展性更强。例如,应用服务器只启用 Filebeat,则只收集日志文件数据,如果某天需要收集系统性能数据时,再启用 Metricbeat 即可,并不需要太多的修改和配置。 71 | 72 | 这种 ELK+Beats 的架构,已经满足大部分应用场景了,但当业务系统庞大,日志数据量较大、较实时时,业务系统就和日志系统耦合在一起了。 73 | 74 | ### 引入队列 75 | 76 | ![](//www.fanhaobai.com/2017/12/elk/17b1a5c7-2897-46f2-becd-3f03f926bc0f.png) 77 | 78 | 该架构,引入消息队列,均衡了网络传输,从而降低了网络闭塞,尤其是丢失数据的可能性;另一方面,这样可以系统解耦,具有更好的灵活性和扩展性。 79 | 80 | ## 总结 81 | 82 | 比较成熟的 ELK+Beats 架构,因其扩展性很强,是集中式日志平台的首选方案。在实际部署时,是否引入消息队列,根据业务系统量来确定,早期也可以不引入消息队列,简单部署,后续需要扩展再接入消息队列。 83 | 84 | 相关文章 [»](#) 85 | 86 | * [ELK集中式日志平台之二 — 部署](https://www.fanhaobai.com/2017/12/elk-install.html) (2017-12-21) 87 | * [ELK集中式日志平台之三 — 进阶](https://www.fanhaobai.com/2017/12/elk-advanced.html) (2017-12-22) 88 | -------------------------------------------------------------------------------- /source/_posts/2017/03/linux-core-caricature.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 漫画欣赏:Linux内核到底长啥样? 3 | date: 2017-03-25 4 | tags: 5 | - Linux 6 | categories: 7 | - Linux 8 | --- 9 | 10 | > 原文:https://linux.cn/article-8290-1.html 11 | 12 | 今天,我来为大家解读一幅来自 TurnOff.us 的漫画 “[InSide The Linux Kernel](http://turnoff.us/geek/inside-the-linux-kernel/)” 。 [TurnOff.us](http://turnoff.us/)是一个极客漫画网站,作者Daniel Stori 画了一些非常有趣的关于编程语言、Web、云计算、Linux 相关的漫画。今天解读的便是其中的一篇。 13 | 14 | 在开始,我们先来看看这幅漫画的全貌! 15 | 16 | ![](//www.fanhaobai.com/2017/03/linux-core-caricature/5BD8ACFD12B2952124B8C9A70546A190.png) 17 | 18 | 这幅漫画是以一个房子的侧方刨面图来绘画的。使用这样的一个房子来代表 Linux 内核。 19 | 20 | ## 地基 ## 21 | 22 | 作为一个房子,最重要的莫过于其地基,在这个图片里,我们也从最下面的地基开始看起: 23 | 24 | ![](//www.fanhaobai.com/2017/03/linux-core-caricature/3C27118DE046AD57EF68F273C0D97CEB.png) 25 | 26 | 地基(底层)由一排排的文件柜组成,井然有序,文件柜里放置着“文件”——电脑中的文件。左上角,有一只胸前挂着 421 号牌的小企鹅,它表示着 PID(进程 IDProcess ID) 为 421 的进程,它正在查看文件柜中的文件,这代表系统中正有一个进程在访问文件系统。在右下角有一只小狗,它是看门狗 watchdog ,这代表对文件系统的监控。 27 | 28 | ## 一层(地面层)## 29 | 30 | ![](//www.fanhaobai.com/2017/03/linux-core-caricature/B3FBAEAC24E48666A4442ADEB950BE21.png) 31 | 32 | 看完了地基,接下来我们来看地基上面的一层,都有哪些东西。 33 | 34 | ![](//www.fanhaobai.com/2017/03/linux-core-caricature/7367932F64D0D54E31AF624CF830E0CF.png) 35 | 36 | 在这一层,最引人瞩目的莫过于中间的一块垫子,众多小企鹅在围着着桌子坐着。这个垫子的区域代表进程表。 37 | 38 | 左上角有一个小企鹅,站着,仿佛在说些什么这显然是一位家长式的人物,不过看起来周围坐的那些小企鹅不是很听话——你看有好多走神、自顾自聊天的——“喂喂,说你呢,哇塞娃(171),转过身来”。它代表着 Linux 内核中的初始化(init)进程,也就是我们常说的 PID 为 1 的进程。桌子上坐的小企鹅都在等待状态 wait 中,等待工作任务。 39 | 40 | ![](//www.fanhaobai.com/2017/03/linux-core-caricature/A60AFE2B528D380E7C11D921C5D416D2.png) 41 | 42 | 瞧瞧,垫子(进程表)旁边也有一只小狗,它会监控小企鹅的状态(监控进程),当小企鹅们不听话时,它就会汪汪地叫喊起来。 43 | 44 | ![](//www.fanhaobai.com/2017/03/linux-core-caricature/CDA46D0971D6354391ECC3A88E711EA0.png) 45 | 46 | 在这层的左侧,有一只号牌为 1341 的小企鹅,守在门口,门上写着 80,说明这个 PID 为 1341 的小企鹅负责接待 80 端口,也就是我们常说的 HTTP (网站)的端口。小企鹅头上有一片羽毛,这片羽毛大有来历,它是著名的 HTTP 服务器 Apache 的 Logo。喏,就是这只: 47 | 48 | ![](//www.fanhaobai.com/2017/03/linux-core-caricature/A92E721F6E3331ECFF02BF6A2E25F43D.png) 49 | 50 | 向右看,我们可以看到这里仍有一扇门,门上写着 21,但是,看起来这扇门似乎年久失修,上面的门牌号都歪了,门口也没人守着。看起来这个 21 端口的 FTP 协议有点老旧了,目前用的人也比以前少了,以至于这里都没人接待了。 51 | 52 | ![](//www.fanhaobai.com/2017/03/linux-core-caricature/C8277CBC07F312F62D0EF9DA9AF01F19.png) 53 | 54 | 而在最右侧的一个门牌号 22 的们的待遇就大为不同,居然有一只带着墨镜的小企鹅在守着,看起来好酷啊,它是黑衣人叔叔吗?为什么要这么酷的一个企鹅呢,因为 22 端口是 SSH 端口,是一个非常重要的远程连接端口,通常通过这个端口进行远程管理,所以对这个端口进来的人要仔细审查。 55 | 56 | ![](//www.fanhaobai.com/2017/03/linux-core-caricature/4AD005B03A39A0F49C0161914325B9C5.png) 57 | 58 | 它的身上写着 52,说明它是第 52 个小企鹅。 59 | 60 | ![](//www.fanhaobai.com/2017/03/linux-core-caricature/DBE8511ECE02DC8ADF849F5062B83433.png) 61 | 62 | 在图片的左上角,有一个向下台阶。这个台阶是底层(地基)的文件系统中的,进程们可以通过这个台阶,到文件系统中去读取文件,进行操作。 63 | 64 | ![](//www.fanhaobai.com/2017/03/linux-core-caricature/0E9D69D32086CA20007062B59842DE24.png) 65 | 66 | 在这一层中,有一个身上写着 217 的小企鹅,他正满头大汗地看着自己的手表。这只小企鹅就是定时任务(Crontab),他会时刻关注时间,查看是否要去做某个工作。 67 | 68 | ![](//www.fanhaobai.com/2017/03/linux-core-caricature/6ADA68452C7E8F3014CD8D7D68BF3DCD.png) 69 | 70 | 在图片的中部,有两个小企鹅扛着管道(PipeLine)在行走,一只小企鹅可以把自己手上的东西通过这个管道,传递给后面的小企鹅。不过怎么看起来前面这种(男?)企鹅累得满头大汗,而后面那只(女?)企鹅似乎游刃有余——喂喂,前面那个,裤子快掉了~ 71 | 72 | ![](//www.fanhaobai.com/2017/03/linux-core-caricature/14227E17ECB4AD1852B67CAD4DA48F42.png) 73 | 74 | 在这一层还有另外的一个小企鹅,它手上拿着一杯红酒,身上写着 411,看起来有点不胜酒力。它就是红酒(Wine)小企鹅,它可以干(执行)一些来自 Windows 的任务。 75 | 76 | ## 跃层 ## 77 | 78 | 在一层之上,还有一个跃层,这里有很多不同的屏幕,每个屏幕上写着 TTY(这就是对外的终端)。比如说最左边 tty4 上输入了“fre”——这是想输入“freshmeat...”么 :d ;它旁边的 tty2 和 tty3 就正常多了,看起来是比较正常的命令;tty7 显示的图形界面嗳,对,图形界面(X Window)一般就在 7 号终端;tty5 和 tty6 是空的,这表示这两个终端没人用。等等,tty1 呢? 79 | 80 | ![](//www.fanhaobai.com/2017/03/linux-core-caricature/62707DD3CCEB3B0765227E742A32F72F.png) 81 | 82 | tty(终端)是对外沟通的渠道之一,但是,不是每一个进程都需要 tty,某些进程可以直接通过其他途径(比如端口)来和外部进行通信,对外提供服务的,所以,这一层不是完整的一层,只是个跃层。 83 | 84 | 好了,我们有落下什么吗? 85 | 86 | ![](//www.fanhaobai.com/2017/03/linux-core-caricature/A91A34A3B08128E2A06C66E8856585B0.png) 87 | 88 | 这小丑是谁啊? 89 | 90 | 啊哈,我也不知道,或许是病毒?你说呢? 91 | -------------------------------------------------------------------------------- /source/_posts/2024/04/design-rule-engine/gengine.g4: -------------------------------------------------------------------------------- 1 | grammar gengine; 2 | 3 | primary: ruleEntity+; 4 | // 规则定义 5 | ruleEntity: RULE ruleName ruleDescription? salience? BEGIN ruleContent END; 6 | ruleName : stringLiteral; 7 | ruleDescription : stringLiteral; 8 | salience : SALIENCE integer; 9 | // 规则体 10 | ruleContent : statements; 11 | statements: statement* returnStmt?; 12 | 13 | // 基本语句 14 | statement : ifStmt | functionCall | assignment | forStmt | breakStmt; 15 | 16 | expression : mathExpression 17 | | expression comparisonOperator expression 18 | | expression logicalOperator expression 19 | | notOperator ? expressionAtom 20 | | notOperator ? LR_BRACKET expression RR_BRACKET 21 | ; 22 | 23 | mathExpression : mathExpression mathMdOperator mathExpression 24 | | mathExpression mathPmOperator mathExpression 25 | | expressionAtom 26 | | LR_BRACKET mathExpression RR_BRACKET 27 | ; 28 | 29 | expressionAtom 30 | : functionCall 31 | | constant 32 | | variable 33 | ; 34 | assignment : variable assignOperator (mathExpression| expression); 35 | returnStmt : RETURN expression?; 36 | ifStmt : IF expression LR_BRACE statements RR_BRACE elseIfStmt* elseStmt?; 37 | elseIfStmt : ELSE IF expression LR_BRACE statements RR_BRACE; 38 | elseStmt : ELSE LR_BRACE statements RR_BRACE; 39 | forStmt : FOR assignment SEMICOLON expression SEMICOLON assignment LR_BRACE statements RR_BRACE; 40 | breakStmt: BREAK; 41 | 42 | constant 43 | : booleanLiteral 44 | | integer 45 | | stringLiteral 46 | ; 47 | functionArgs 48 | : (constant | variable | functionCall | expression) (','(constant | variable | functionCall | expression))* 49 | ; 50 | integer : MINUS? INT; 51 | stringLiteral: DQUOTA_STRING; 52 | booleanLiteral : TRUE | FALSE; 53 | functionCall : SIMPLENAME LR_BRACKET functionArgs? RR_BRACKET; 54 | variable : SIMPLENAME | DOTTEDNAME; 55 | mathPmOperator : PLUS | MINUS; 56 | mathMdOperator : MUL | DIV; 57 | comparisonOperator : GT | LT | GTE | LTE | EQUALS | NOTEQUALS; 58 | logicalOperator : AND | OR; 59 | assignOperator: SET; 60 | notOperator: NOT; 61 | 62 | // 关键字 63 | NIL : 'nil'; 64 | RULE : 'rule'; 65 | AND : '&&'; 66 | OR : '||'; 67 | 68 | IF : 'if'; 69 | ELSE : 'else'; 70 | RETURN : 'return'; 71 | FOR : 'for'; 72 | BREAK : 'break'; 73 | 74 | TRUE : 'true'; 75 | FALSE : 'false'; 76 | SALIENCE : 'salience'; 77 | BEGIN : 'begin'; 78 | END : 'end'; 79 | 80 | SIMPLENAME : ('a'..'z' |'A'..'Z'| '_')+ ( ('0'..'9') | ('a'..'z' |'A'..'Z') | '_' )*; 81 | 82 | INT : '0'..'9' +; 83 | PLUS : '+'; 84 | MINUS : '-'; 85 | DIV : '/'; 86 | MUL : '*'; 87 | 88 | EQUALS : '=='; 89 | GT : '>'; 90 | LT : '<'; 91 | GTE : '>='; 92 | LTE : '<='; 93 | NOTEQUALS : '!='; 94 | NOT : '!'; 95 | SET : '='; 96 | 97 | SEMICOLON : ';'; 98 | LR_BRACE : '{'; 99 | RR_BRACE : '}'; 100 | LR_BRACKET : '('; 101 | RR_BRACKET : ')'; 102 | DOT : '.'; 103 | DQUOTA_STRING : '"' ( '\\'. | '""' | ~('"'| '\\') )* '"'; 104 | DOTTEDNAME : SIMPLENAME DOT SIMPLENAME; 105 | 106 | // 过滤token 107 | SL_COMMENT: '//' .*? '\n' -> skip; 108 | WS : [ \t\n\r]+ -> skip; -------------------------------------------------------------------------------- /source/_posts/2018/03/hexo-deploy.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 我的博客发布上线方案 — Hexo 3 | date: 2018-03-03 16:14:00 4 | tags: 5 | - 系统设计 6 | - 工具 7 | categories: 8 | - 系统设计 9 | --- 10 | 11 | 之前一直在使用 [Hexo](https://www.fanhaobai.com/2017/03/install-hexo.html#官方推荐) 推荐的发布方案,缺点是本地依赖 Hexo 环境,无法随时随地地更新博客。为了摆脱 Hexo 环境约束进而高效写作,有了下述的发布方案。 12 | 13 | ![预览图](//www.fanhaobai.com/2018/03/hexo-deploy/082786eb-0903-4776-a345-e52d25de2e49.png) 14 | 15 | 本文的发布方案中,Git 仓库只是托管 md 文件,通过 Webhook 通知服务器拉取 md 文件,然后执行构建静态文件操作,完成一个发布过程。 16 | 17 | 我的写作环境为 [Typora](https://www.typora.io/)(Win10),博客发布在阿里云的 [ECS](https://www.fanhaobai.com)(CentOS)上,文章托管在 [GitHub](https://github.com/fan-haobai/blog)。 18 | 19 | ## 需求升级 20 | 21 | 随着时间成本的增高,只能利用碎片时间来进行写作。因此,我的写作场景变成了这样: 22 | 23 | * 习惯使用 MarkDown 写原稿,有 MarkDown 编辑器就行; 24 | * 写作场地不限定,有电脑就行; 25 | * 写作时间不确定,有灵感就写; 26 | 27 | ## 新的问题 28 | 29 | 之前(包括 Hexo 推荐)的发布方案,都是先本地编写 MarkDown 源文件,然后本地构建静态文件,最后同步静态文件到服务器。发布流程图如下: 30 | 31 | ![原来的发布流程](//www.fanhaobai.com/2018/03/hexo-deploy/f2ec7449-ae8a-4f6a-8dfa-95d6abf4aaa6.png) 32 | 33 | 显而易见,若继续使用之前的发布方案,那么每当更换写作场地时都需要安装 Hexo 环境,写作场地和时间都受到限制,不满足需求。 34 | 35 | ## 新的方案 36 | 37 | 问题主要是,本地受制于构建静态文件时需要的 Hexo 环境,那么是否可以将构建静态文件操作放到服务器端? 38 | 39 | ### 发布流程 40 | 41 | 首先,看下新方案的发布流程图: 42 | 43 | ![我的发布流程](//www.fanhaobai.com/2018/03/hexo-deploy/bf3adf97-088b-47cd-b5ab-377a4f4acd44.png) 44 | 45 | 如流程图所示,整个发布系统共涉及到 3 个环境,分别为本地(写作)、Git 仓库(托管 md 源文件)、服务器(Web 服务)环境。在服务器环境构建静态文件,因此只需要在服务器端安装 Hexo 环境。 46 | 47 | 一个完整的发布流程包含 3 个部分: 48 | 49 | * 流程 ① :[写作流程](#写作流程); 50 | * 流程 ② :[发布流程](#发布流程); 51 | * 流程 ③ :[构建流程](#构建流程); 52 | 53 | #### 写作流程 54 | 55 | 采用按分支开发策略,当写作完成后,只需要 push 修改到对应分支即可。只要有 MarkDown 编辑器,以及任何文本编辑器,甚至 [马克飞象](https://maxiang.io/) 都可以随时随地写作。 56 | 57 | ![写作流程](//www.fanhaobai.com/2018/03/hexo-deploy/cd4f6674-aba5-4cbc-87e6-18c0c230585b.png) 58 | 59 | 当然,你可能说还需要 Git 环境呀?好吧,如果你是一名合格的 Coder,竟然没有 Git,你知道该干嘛了!再说没有 Git 环境,还可以通过 [GitHub](https://github.com) 来完成写作。 60 | 61 | #### 发布流程 62 | 63 | 采用 master 发布策略,当需要发布时,需要将对应开发分支 merge 到 master 分支,然后 `push master` 分支,即可实现发布。 64 | 65 | ![发布流程](//www.fanhaobai.com/2018/03/hexo-deploy/12b62d2e-7e26-4a3c-a770-e0d16d5c2254.png) 66 | 67 | #### 构建流程 68 | 69 | 这里使用到 Webhook 机制,触发代码更新并部署操作。 70 | 71 | 当流程 ① 和 ② 结束后,Git 仓库都会向服务器发起一次 HTTP 请求,记录如下: 72 | 73 | ![Webhook请求](//www.fanhaobai.com/2018/03/hexo-deploy/9ee84981-7d79-47f5-98f8-e7500eff6e67.png) 74 | 75 | 当收到构建请求后,执行构建操作。构建流程图如下: 76 | 77 | ![构建流程图](//www.fanhaobai.com/2018/03/hexo-deploy/3b8f20b3-f3b2-498d-afa4-d60391c47db5.png) 78 | 79 | 首先检查当前变更分支,只有为 master 分支时,执行 pull 操作拉取 md 文件更新,然后再执行 `hexo g` 完成静态文件的构建。 80 | 81 | ### Webhook脚本 82 | 83 | 这里直接使用 [webhook-cli](https://github.com/sigoden/webhook) 工具,只需简单配置即可使用。 84 | 85 | 新增 `hook.json` 配置文件,内容如下: 86 | 87 | ```bash 88 | [ 89 | { 90 | "id": "webhook-deploy-hexo", 91 | "execute-command": "/build_hexo.sh", 92 | "include-command-output-in-response": true, 93 | "trigger-rule": 94 | { 95 | "and": 96 | [ 97 | { 98 | "match": 99 | { 100 | "type": "payload-hash-sha1", 101 | "secret": "88E7fe7aDf58d8a42108F0b7c2065d55dF3204D7", 102 | "parameter": 103 | { 104 | "source": "header", 105 | "name": "X-Hub-Signature" 106 | } 107 | } 108 | }, 109 | { 110 | "match": 111 | { 112 | "type": "value", 113 | "value": "refs/heads/master", 114 | "parameter": 115 | { 116 | "source": "payload", 117 | "name": "ref" 118 | } 119 | } 120 | } 121 | ] 122 | } 123 | } 124 | ] 125 | ``` 126 | 127 | 其中,`execute-command` 为部署脚本路径,`secret` 为 webhook 参数加密密钥。 128 | 129 | 部署脚本 `execute-command` 的内容如下: 130 | 131 | ```Bash 132 | #!/bin/bash 133 | 134 | cd /var/www/blog 135 | 136 | # 更新代码 137 | git pull 138 | 139 | # 生成静态资源 140 | npm install --force 141 | # hexo clean 142 | hexo g 143 | ``` 144 | 145 | ## 总结 146 | 147 | 新发布方案与之前方案的区别是:前者只需本地编写 md 文件,博客服务器构建静态文件;后者本地编写 md 文件后,需要本地构建静态文件,然后博客服务器只同步静态文件。 148 | 149 | 当然,有很多办法可以解决当前问题,比如可以使用 [持续集成](https://formulahendry.github.io/2016/12/04/hexo-ci/)。本文只是提供一个发布思路,在项目的生产环境中,我们也很容易应用上这种发布思路,开发出自己的发布系统。 150 | 151 | 相关文章 [»](#) 152 | 153 | * [启用Hexo开源博客系统](https://www.fanhaobai.com/2017/03/install-hexo.html)(2017-03-01) -------------------------------------------------------------------------------- /source/_posts/2018/06/beijing-to-chengdu.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 从北京回到成都的这3个月 3 | date: 2018-06-27 20:00:00 4 | tags: 5 | - 杂谈 6 | categories: 7 | - 杂谈 8 | --- 9 | 10 | 今年 3 月从 [自如](http://www.ziroom.com) 离职,然后就回成都并加入了 [聚美](http://www.jumei.com),我的北漂记忆也就定格在了自如。回来 3 个月,为了这个伟大的决定,一直想写篇文章,今天刚刚好,这篇文章将叙述自己回成都后经历的事和见闻,有想来成都发展的小伙伴可以以此为参考。 11 | 12 | ![成都](//www.fanhaobai.com/2018/06/beijing-to-chengdu/234987d5-3dd2-4736-b32c-b843ff42505e.jpg) 13 | 14 | ## 公司 15 | 16 | 说到成都,很多人(包括小马哥)都会扔出一句“少不入川,老不出川”。他们认为,成都生活安逸,适合养老,年轻人容易失去斗志,但是我并不认同,小马哥后面也改变看法了,因为 N 逼的天美工作室。 17 | 18 | 现在的成都,有很多互联网公司入驻,虽说条件比不上北上深,但是在工作和生活平衡点上,是可以安居乐业的;政府也在大力培育“独角兽”企业,未来就业前景也是可期的。至于待遇方面,普遍比北上深低 20~30% 左右,还是那句话:如果你真牛逼,也没有什么是不可能的。 19 | 20 | ![成都公司](//www.fanhaobai.com/2018/06/beijing-to-chengdu/6054d4bf-b6fe-4dac-ab25-4f6653bc880f.jpg) 21 | 22 | 现在来说说聚美。目前我主要负责商品中心和库存中心系统,这两个系统作为核心的基础服务,日调用量最高且系统可靠性要求高。 23 | 24 | ![聚美](//www.fanhaobai.com/2018/06/beijing-to-chengdu/745d2ec3-6618-4fc0-9f30-4bee52496670.jpg) 25 | 26 | * 从 [行业](#) 上来看: 27 | 28 | 聚美曾经辉煌过,所以大家对其一直有很高的期待,现在聚美正在崛起的路上。个人觉得公司的成功跟行业有很大关系,“风口上的猪”嘛,之前聚美正处风口上,现在自如正处于这个位置,这是我留恋自如的原因。 29 | 30 | * 从 [技术](#) 上来看,PHP 维度: 31 | 32 | 聚美 PHP 的生态是我见过做的最好的,这里也是 PHP 在国内大规模成熟应用的实例。毕竟作为电商,经历过业务顶峰,沉淀下来的,这是我来聚美的目的。 33 | 34 | 服务 Worker、连接池、RPC、服务调度、旁路、配置中心、消息中心、任务中心等解决方案,尽管目前我还未吃透这些设计,但是旁路的设计就能给我很赞的感觉。当然,这些都需要一个强大的架构团队来支持。一个互联网公司,只有有了一个好的技术生态,才能更好更快地响应业务需求。 35 | 36 | ## 购房 37 | 38 | 为了承载你的梦想,首先得有个家。而 2018 的楼市,可谓惨不忍睹。全民炒房,全国房价飞涨,多个城市先后出台了摇号政策,才将这一轮炒房热 Hold 住。整个过程,最受伤的就是刚需。 39 | 40 | ![楼盘售罄](//www.fanhaobai.com/2018/06/beijing-to-chengdu/4c7fd01e-91ce-48f5-a47b-5ee6500a5d5d.jpg) 41 | 42 | 成都楼市,在限购限价的政策下,均价控制在 1.5W 左右,当然现在买房,不光得有钱,还得先摇号。攻略如下: 43 | 44 | 1. 先确认自己是否有购房资格,主要是户口社保,[资格查询工具](http://tool.ixiangzhu.net/limit/index); 45 | 2. 通过 [房协网](https://www.cdfangxie.com) 、成都摇号助手(小程序)获取最新预售房源,并网上登记报名; 46 | 3. 去往登记的售楼部提交纸质资格资料,等待资格审核通过; 47 | 4. 等待摇号结果; 48 | 5. 摇中后,准备好首付款(首付 3 成),进行按序选房,并办理购房手续; 49 | 50 | 整个过程,只可意会,不可言传,只有经历了才知道是多么的惊悚。 51 | 52 | * 惊悚场景1: 53 | 54 | 摇中就像中彩票一样,大部分的摇中概率为 1%。且自己买什么楼盘可选性不大,因为摇中什么才能买什么。 55 | 56 | * 惊悚场景2: 57 | 58 | 原本以为摇中就好,可没有想到,按序选房是多么的恐怖。因为在仅仅只有一大排房号的数字面前,需要 2 分钟从剩余的房源中选定自己看中的房号,就跟去菜市场买白菜一样。当然,这就需要提前做好功课,比如实地踩点,按优先顺序排出多个中意房号。一切都准备好了,但是你运气不太好,摇中的号靠后就不太可能选上中意的房源。 59 | 60 | 就摇号买房来说,终于不用拼爹了,而是拼运气。在 5.15 新政之后,这种情况得到改善,但是大学生落户的人就失去了购房资格(所在区社保需满 1 年)。我只是运气刚刚好,赶上新政之前的末班车,摇的号还比较靠前。总之一句话,如果是刚需,就尽快下手,占个坑,因为政策会让你琢磨不透。 61 | 62 | ## 未来之城 63 | 64 | 成都未来的发展,就看这座未来之城——四川天府新区。至于为什么要花大量人力物力打造这座新城?简单的答案是: 65 | 66 | 1. 成都层面:中心城区“摊拼式”发展,导致中心城区越来越拥挤堵塞,亟需向外疏导人流; 67 | 2. 四川层面:需要打造四川经济新的增长极,促进经济高速发展; 68 | 69 | 接下来就介绍一下这个国家级新区。 70 | 71 | ### 规划 72 | 73 | 四川天府新区规划与 2010 年,2014 年正式成为国家级新区。天府新区建成后,将与成都中心城区形成“双核共兴”的局面。如下为天府新区产业规划图: 74 | 75 | ![新区规划](//www.fanhaobai.com/2018/06/beijing-to-chengdu/53bc46b9-b1eb-4c3d-88ff-68b44bce5429.jpg) 76 | 77 | 我在网上看过一句话,说高新区是民营资本的聚集地,而天府新区是国家队资本的聚集地。我觉得应该说,国家队只是起先导引流作用。 78 | 79 | ### 地铁 80 | 81 | 规划这么美的天府新区,交通自然不能拖了后退。从成都地铁规划图中,可以看到新区地铁覆盖率较高,出行较方便。到 2020 年,开通的地铁有 1、5、6、15、18 号线。 82 | 83 | ![新区地铁](//www.fanhaobai.com/2018/06/beijing-to-chengdu/0f8ebfc5-3d54-489e-9dc3-ee74bd4d61d0.jpg) 84 | 85 | ### 代表建筑和景观 86 | 87 | #### 兴隆湖 88 | 89 | 习大大说,“绿水青山,就是金山银山”。由于优越的地理位置,决定了天府新区一诞生就是一座“公园城市”。兴隆湖作为天府新区的发展起步区,很好地响应了公园城市理念。 90 | 91 | ![兴隆湖](//www.fanhaobai.com/2018/06/beijing-to-chengdu/0149bcaf-f380-4ef3-b6e1-331b452d636a.jpg) 92 | 93 | #### 一带一路大厦 94 | 95 | 曾用名为“熊猫大厦”的 676 米超高地标建筑,正式命名为“一带一路大厦”,这也让人们一直铭记住天府新区是“一带一路”战略的一个重要环节。待“一带一路大厦”旁依附的超高建筑群建成后,成都的天际线将进一步提高,也使得成都的天空具有较强的层次感。 96 | 97 | ![一带一路大厦](//www.fanhaobai.com/2018/06/beijing-to-chengdu/8111a4fc-7b66-11e8-adc0-fa7ae01bbebc.jpg) 98 | 99 | #### 独角兽岛 100 | 101 | 独角兽岛当然是独角兽企业(10 亿美元以上创业公司)的聚集地,建设独角兽岛,体现了成都大力培育独角兽企业的决心。独角兽岛先后分两期建成,一期于 2019 年建成,二期 2019 年开建并于 2022 年建成。 102 | 103 | ![独角兽岛](//www.fanhaobai.com/2018/06/beijing-to-chengdu/88d071da-7b6d-11e8-adc0-fa7ae01bbebc.jpg) 104 | 105 | #### 天府国际机场 106 | 107 | 天府国际机场造型为“太阳神鸟”,位于高新东区简阳芦葭镇,定位为国家级国际航空枢纽。预计到 2020 年建成使用,届时成都即迈入双机场时代,成为中国大陆地区第三个拥有双国际机场的城市。 108 | 109 | ![天府机场](//www.fanhaobai.com/2018/06/beijing-to-chengdu/30121dc4-7b67-11e8-adc0-fa7ae01bbebc.jpg) 110 | 111 | #### 西博城 112 | 113 | 中国西部博览城简称西博城,是我国中西部最大的国际会展中心。由于西博城有着铝制的金属外表,使其看起来很有科技感。 114 | 115 | ![西博城](//www.fanhaobai.com/2018/06/beijing-to-chengdu/de39aeb3-5481-4181-a45c-b503ec16cd0a.jpg) 116 | 117 | 如今 4 年过去了,有的规划已初步建成,有的还在如火如荼的建设中,建设者正在一一将规划图变成一座座楼宇,呈现在人们面前。 118 | 119 | ## 总结 120 | 121 | 虽然成都不比北上广深,却是一个可以承载我梦想的地方。在这里,我可以安居乐业,重要的是能守护心中的她。 122 | -------------------------------------------------------------------------------- /source/_posts/2021/12/2021-personal-summary.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 2021年终总结 3 | date: 2021-12-31 21:00:00 4 | tags: 5 | - 成长 6 | --- 7 | 8 | > 关键词:不轴 9 | 10 | 这一年信息量还是挺大,做了很多项目,但是业务产出较少(有一些外部因素),职级也未能得到晋升。经过这一年的时间沉淀,不再自以为是,以更开放的心态接受身边事物的改变。 11 | 12 | ![预览图](//www.fanhaobai.com/2021/12/2021-personal-summary/10183cff-d8cc-4e5f-97cb-b897a256bd41.png) 13 | 14 | 15 | ## 业务 16 | 17 | ### 业务第一 18 | 19 | 不再以为技术最牛逼,更多考虑的是用户体验,跟产品撕逼的情况少了,愿意去提供更好的方案,更会站在产品的角度去懂得产品同学的想法。业务第一,产品第二,技术第三,技术赋能产品,产品驱动业务,一切都是为了业务。 20 | 21 | 最近有一个业务需求,需求前期阶段就同产品同学对接过几次,确定了可行方案。但是到了需求评审阶段,又进行了多次修改调整,需求评审时间跨度1周+,这就导致剩余给开发和测试的时间只有 1 周了。项目参与同学怨声载道,不满情绪较多。 22 | 这时我就陷入了两难境地,为了让项目参与同学解气也一起喷产品同学(你这需求能不能行了),还是试图让项目同学理解这种特殊情况(项目同学:理解个屁啊,开发时间这么短,谁能理解我啊,到时候上不了线又说技术同学不给力)? 23 | 我是项目技术 Owner,要解决这种僵局需要多做少说,解释就是掩饰,只能想办法解决需求变更的原因。先拉上产品同学从技术视角提供可行的解决方案,从用户视角优化流程体验,确定最终的产品核心流程链路,这些一期先上线不能再变动。 24 | 其他的统统放后续优化迭代,在一期上线之后再处理。 25 | 26 | ### 技术重构 27 | 28 | 这一年在上游产品输出一般的情况下,我们抽了大部分时间做了系统重构,填了很多坑(也又埋了一些坑),业务完成了收口,也为后续业务迭代打好基础。超过 85% 的业务已完成系统重构,2 个重构项目获得了标杆 OKR。 29 | 30 | **怎么选定重构项目?** 31 | 32 | 从实际出发,是业务或开发痛点的才去重构,不要为了重构而重构。 33 | * 历史包袱重且迭代频繁的核心业务功能 34 | * 迭代频繁可抽象通用化的功能 35 | * 迭代频繁可配置化的功能 36 | 37 | **怎么实施重构?** 38 | 39 | 不着急大步推进重构,拆分成不同的迭代周期,每期的任务是具体的,是可以完成,是进度可控的。另外找到合适的时间点去做重构,借力合适的业务需求去做重构,就会事半功倍。 40 | 41 | 合适的时间点去做重构,有这样一个例子: 42 | 由于历史原因,我们有个问诊系统,对接了百度、腾讯且各自为独立系统,算上我们自己的系统有 3 套类似功能的系统,在 APP 端也是不同的功能流程。这样用户体验不好,开发维护体验也不好。 43 | 之前我们团队一直在小步重构自己的这套系统(功能已兼容其他 2 套系统),而其他2套对接三方的系统重构优先级放的比较低。 44 | 直到有一天,业务团队说三方对接业务暂停了,借此时机我们快速推进了问诊系统重构,把 APP 端的功能统一为一个流程了。 45 | 46 | 重构过程中,我比较关注怎么为以后的开发提效: 47 | * 功能复用,减少重复开发 48 | * 配置化,不需要开发和发版 49 | 50 | **重构后有什么收获?** 51 | 52 | * 人员更熟悉业务了 53 | 之前由于人员流动,部分新同学进来,加上业务文档缺失,短期没人熟悉业务,导致问题频出。重构前,会先梳理出业务文档和技术方案,有了文档沉淀。重构后,团队参与重构的同学也熟悉业务了。 54 | 55 | * 历史包袱少了 56 | 历史代码逻辑本来就设计不合理,因为逻辑混乱再加上后续的迭代修改,没人看得懂也没人敢优化逻辑,就成了一堆祖传代码(屎山)。后续修改维护都需要花大量时间梳理逻辑找到需要修改的点,另任何修改都需要测试全面覆盖用例。 57 | 58 | * 系统更合理更可扩展了 59 | 举一个例子,诊室 IM 按钮的配置化改造后,后端可以直接配置下发。 60 | 61 | ```goland 62 | { 63 | "name": "@", // 按钮名称 64 | "menuType": 1, // 按钮类型 65 | "url": "", // 按钮跳转scheme 66 | "apiAddress": "", // 按钮点击触发接口 67 | "tag": null // 按钮角标 68 | } 69 | ``` 70 | 95% 情况的修改不需要 APP 发版。前几天,公司 CTO 觉得现在的按钮顺序不太合理,找到我想要调整一下,我当时心里窃喜,还好我们已经提前做了配置化改造,不然就要被喷了。 71 | 可以配置化后,很快就完成了按钮顺序调整。这件事也让我更体会到技术手段的重要性,之前 Native 开发按钮,也不是不可用,只是不够灵活,任何修改需要发版,关键时刻救不了火。 72 | 73 | 74 | ## 团队 75 | 76 | 每个人都是某块业务的 Owner,协作起来比较顺畅,执行力比较强(自我感觉)。 77 | 78 | ### 拥抱变化 79 | 80 | 公司经历了几次组织架构调整,团队人员有进有出,也以开放的心态拥抱这种变化,因为唯一不变的就是变化。 81 | 最近一次组织架构调整,原本团队 20 人左右(包括 Native),对 APP 终端的业务功能负责。这次调整,我把 Native 交给了一个比我更合适的同事。 82 | 其一,我后端出身,对 Native 技术不熟悉,属于外行管内行的情况,可能由于我这方面的短视,无法提供更有建设性的意见,对这些同学的发展不利;其二,在团队内也没有找到合适的同学来补位。 83 | 84 | 但是我还是挺感谢这一段时间经历,对我来说是一个跨界,接触到了之前没关注的领域,拓展了自己的技术视野,会全局考虑技术实现方案,对后续工作也是很有帮助。 85 | 比如之前后端在设计技术方案的时候不会考虑 Native 这边,出现过 1 个页面需要调用 20 多个接口的情况(Native 同学咋没原则,不知道拒绝),Native 代码里也充斥着大量的业务逻辑实现。对此后续在团队里面形成规定: 86 | * 接口要收敛 87 | * 业务逻辑收口到后端,前端只做展示和交互逻辑 88 | 89 | ### 充分信任 90 | 91 | 相信团队的每一个人,不再觉得只有自己能做。把一些事授权给团队成员去做,对他们才会有更多成长机会。 92 | * 充分信任。疑人不用,用人不疑 93 | * 授权指导。明确任务、时间、验收标准,以及如果是我大概会去怎么做 94 | * 监督。正向反馈,即时修偏 95 | * 拿结果。做得怎么样,问题复盘改进 96 | 97 | ### 寻找关键人 98 | 99 | 以点带面,良币驱逐劣币。抓好团队这些关键人,让他们经历更多事情的蹂躏快速成长起来,负责更多的事,担更多的责任,避免团队因我这个单点而导致的翻车。 100 | 101 | 102 | ## 个人 103 | 104 | ### 新的角色 105 | 106 | 加入了后端技术委员会,能为团队做更多的事,面对更有挑战的一些技术难题。 107 | 108 | 以下 2 个案例都是为了解决团队发版日必过凌晨的问题,团队发布效率低导致加班严重。 109 | 110 | **发布流水线** 111 | 112 | 微服务化之后,稍微大一点的项目发布都会有 10+ 的应用,之前全是人工手动到发布平台上一个一个应用点发布,效率低,且容易出现发布遗漏应用的情况。 113 | 另外如果是多个项目发布,那么就需要排队等待,后面发布的项目就遭殃了。 114 | 115 | 有段时间我深受其害,想办法解决这种情况。刚好质效部门有个同学有些想法,于是我俩来回拉扯了几次,确定了发布流水线大概功能:每个迭代需求系统自动生成发布清单, 116 | 多个迭代可以合并发布,支持一键部署完成代码合并和应用发布。这哥们也是给力,过了一段时间就做好上线了,当然我们部门也就成了第一个吃螃蟹的人。效果很明显,后续发布效率提高了很多。 117 | 118 | **预发布环境** 119 | 120 | 之前工程部门已经搞过一次,但是没有落地成功。一是方案不是很合理;二是需要对接的业务团队较多,协调困难;三是没有做到开箱即用(工程部只管搭好环境,预发环境的应用还需要业务团队自己部署)。 121 | 122 | 基于之前的教训,我先是设计出整体实施方案,并得到了技术委员会的通过,然后拉上各业务线技术负责人,告知背景并需要得到资源支持(1 个人就好,小部分应用需要做一点小改造), 最后我就拉上运维开始实施,搭建环境并批量部署应用。 123 | 预发环境搭建好之后,白天可以在预发环境(真实的数据一致的环境)测试验收,因为降低了发布风险所以可以提前发布生产了,后续发布到很晚的情况就更少了。 124 | 125 | ### 时间怎么分配 126 | 127 | 负责的业务更多了,大部分事情都会先到我这里。可一天时间就这么多(995 又咋样),怎么办?搬出我的时间四象限: 128 | 129 | ![预览图](//www.fanhaobai.com/2021/12/2021-personal-summary/a2d1e849-2e1f-42a3-a054-69005e91755b.jpg) 130 | 131 | 132 | ## 明年TODO 133 | 134 | * 能负责 1 个新产品落地,从 0 到 1 更需要系统设计,更有挑战,也更有成就感 135 | * 跟其他团队合作更多,认识更多的人,发现更多的团队问题 136 | * 个人职级晋升,负责更多的事,担更多的责任(背更多的锅) 137 | * 养成读书习惯,复制行业榜样的经验 138 | 139 | 职场即战场,很残酷很现实,需要实力和运气,如果当前的情况左右不了,就随它去吧,先丰富自己。 -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # [后端搬运工]() 2 | 3 | [![](https://img.shields.io/github/issues/fan-haobai/blog.svg)](https://github.com/fan-haobai/blog/issues) [![](https://img.shields.io/github/forks/fan-haobai/blog.svg)](https://github.com/fan-haobai/blog/network) [![](https://img.shields.io/github/stars/fan-haobai/blog.svg)](https://github.com/fan-haobai/blog/stargazers) 4 | 5 | ## 关注公众号获取文章推送 6 | 7 | ![公众号](https://github.com/howborn/blog/blob/master/source/wechat.jpeg) 8 | 9 | ## 项目代码 10 | 11 | 本项目采用 git submodule 方式管理源代码。 12 | 13 | * clone 命令 14 | 15 | ```bash 16 | git clone --recursive https://github.com/howborn/blog.git 17 | ``` 18 | 19 | * pull 命令 20 | 21 | ```bash 22 | git pull && git submodule foreach git pull origin master 23 | ``` 24 | 25 | * 安装 hexo 26 | 27 | ```bash 28 | npm install -g hexo-cli 29 | npm install hexo 30 | npm install hexo-deployer-git --save 31 | ``` 32 | 33 | * 发布文章 34 | 35 | ```bash 36 | # 本地预览 37 | hexo s 38 | # 发布到git仓库托管, 配置见_config.yml的deploy项 39 | hexo deploy -g 40 | ``` 41 | 42 | ## 部署环境 43 | 44 | 支持 docker 部署,请先安装 [docker-compose](https://docs.docker.com/compose/)。 45 | 46 | * 配置环境变量 47 | 48 | ```bash 49 | cp docker.example.env docker.env 50 | ``` 51 | 52 | > 其中,各环境变量意义见`docker.example.env`文件中的注释说明,可以根据实际情况修改各环境变量参数的值。 53 | 54 | * 支持HTTPS协议 55 | 56 | ```bash 57 | /bin/bash dockerfiles/nginx/ssl/init_ssl.sh 58 | ``` 59 | 60 | > 注意:如果无需支持HTTPS协议,则跳过此步骤,需要将环境变量`ENABLE_SSL`修改为`true`。 61 | 62 | * 启动容器 63 | 64 | ```bash 65 | docker-compose up --force-recreate --build -d 66 | ``` 67 | 68 | ## 文章内容 69 | 70 | 本站所有的文章 Markdown 文件,请移步 [这里](https://github.com/fan-haobai/blog/tree/master/source/_posts)。 71 | 72 | ### 杂谈 73 | 74 | * [2021年终总结]()(2022-01-12) 75 | * [从北京回到成都的这3个月](https://mp.weixin.qq.com/s/mTiNQg57SgFneAC46aaQig)(2018-06-27) 76 | 77 | ### 架构 78 | 79 | * [如何实现一个自定义规则引擎](https://mp.weixin.qq.com/s/MZSLrfdXFR_iiZWmNk2Mgg)(2024-04-23) 80 | * [基于准实时规则引擎的业务风控方案](https://mp.weixin.qq.com/s/ZW7bkd9JZudvK0YS5WmS9A)(2022-06-28) 81 | * [自如2018新年活动系统 — 抢红包](https://mp.weixin.qq.com/s/VG_Wcxte8avnXzn4bPXiGA)(2018-01-30) 82 | * [千人千面个性化推荐系统](https://mp.weixin.qq.com/s/FVs4Kfi_stQ9Yp_qgOv78g)(2023-01-02) 83 | * [Flink在用户画像上的应用](https://mp.weixin.qq.com/s/VYjwbQ3vrepLkOJoH0xoIA)(2022-12-23) 84 | * [使用Docker轻松部署Hexo博客系统](https://mp.weixin.qq.com/s/seUlg_CicwaEZE-BuJPaAQ)(2020-12-27) 85 | * [自建一个简易的OpenAPI网关](https://mp.weixin.qq.com/s/QF585V8k0xqmwNGx3uggfw)(2020-07-15) 86 | * [在分布式系统使用Kafka](https://mp.weixin.qq.com/s/2jiVvgCsBH4_AT1bj_6dUQ)(2020-05-12) 87 | * [商品价格的多币种方案](https://mp.weixin.qq.com/s/-4-ZhWhGUr9jGCyZwQVrkw)(2019-02-28) 88 | * [我的博客发布上线方案 — Hexo]()(2018-03-03) 89 | * [ELK集中式日志平台之三 — 进阶](https://mp.weixin.qq.com/s/hMLjVx9JF7EPAYd5B94O3Q)(2017-12-22) 90 | * [ELK集中式日志平台之二 — 部署](https://mp.weixin.qq.com/s/E3W48eVpRahLtFjsdb_xwA)(2017-12-21) 91 | * [ELK集中式日志平台之一 — 平台架构](https://mp.weixin.qq.com/s/A-QZm2JTGP2BMCnh6kpjBg)(2017-12-16) 92 | 93 | ### 算法 94 | 95 | * [负载均衡算法 — 平滑加权轮询](https://mp.weixin.qq.com/s/LmBra6oPihlqKXGtWv6yIQ)(2018-12-30) 96 | * [负载均衡算法 — 轮询](https://mp.weixin.qq.com/s/tAeI27-IA5CnbKwavUUkLQ)(2018-12-29) 97 | * [王者编程大赛之五 — 最短路径](https://mp.weixin.qq.com/s/BhyTTm3x2NnrFCpoyYA5Pw)(2017-12-06) 98 | * [王者编程大赛之四 — 约瑟夫环](https://mp.weixin.qq.com/s/yOhZ_kzxBTDr0uKAH5_g5g)(2017-12-06) 99 | * [王者编程大赛之三 — 01背包](https://mp.weixin.qq.com/s/xq2SRtXNls7Bii5OMiAapA)(2017-12-05) 100 | * [王者编程大赛之二 — 蓄水池](https://mp.weixin.qq.com/s/VYrStSwxMOer5Ivq3t9PFA)(2017-12-05) 101 | * [王者编程大赛之一](https://mp.weixin.qq.com/s/tuE_rEsWVwRh8bD9zPUFeg)(2017-12-05) 102 | * [什么是Bitmap算法?]()(2017-08-16) 103 | * [按照奖品概率分布抽奖的实现](https://mp.weixin.qq.com/s/W5ON6gJRiNFl1WHCPw-XMg)(2017-05-18) 104 | * [求非负元素数组所有元素能组合的最大字符串](https://mp.weixin.qq.com/s/Es0OVVga9GpuABHOSTCyCA)(2017-04-03) 105 | * [PHP生成随机红包算法]()(2017-02-13) 106 | * [什么是B-树?]()(2017-07-08) 107 | 108 | ### 语言 109 | 110 | * [用PHP玩转进程之二 — 多进程PHPServer](https://mp.weixin.qq.com/s/XrAV2BRUkx8o4tIaYWYdDA)(2018-09-02) 111 | * [用PHP玩转进程之一 — 基础](https://mp.weixin.qq.com/s/_WPrbGRG7Fuk1RYNSoK7Eg)(2018-08-28) 112 | * [使用Supervisor管理进程]()(2017-09-23) 113 | * [APP接口多版本处理]()(2017-08-19) 114 | * [Lua在Nginx的应用](https://mp.weixin.qq.com/s/dt_4FVcgRpMkwTSp7qy32w)(2017-09-09) 115 | * [Lua在Redis的应用](https://mp.weixin.qq.com/s/-U13YRZ3yLVQW4jzzxPMoQ)(2017-09-04) 116 | * [进入Lua的世界]()(2017-09-03) 117 | * [异步、并发、协程原理]()(2017-11-13) 118 | 119 | ### DB 120 | 121 | #### MySQL 122 | 123 | * [MySQL索引背后的数据结构及算法原理]()(2016-05-19) 124 | 125 | #### Redis 126 | 127 | * [Lua在Redis的应用](https://mp.weixin.qq.com/s/-U13YRZ3yLVQW4jzzxPMoQ)(2017-09-04) 128 | * [使用Redis管道提升性能](https://mp.weixin.qq.com/s/5Ak5ss0FnH-nhZ42m35hUg)(2017-08-31) 129 | 130 | #### 搜索 131 | 132 | * [Elasticsearch检索 — 聚合和LBS](https://mp.weixin.qq.com/s/JYmcsIZAsZM4UVhK7ni0sg)(2017-08-21) 133 | * [Elasticsearch检索实战]()(2017-08-09) 134 | * [Solr的使用 — 检索]()(2017-08-13) 135 | * [Solr的使用 — 部署和数据推送]()(2017-08-12) 136 | 137 | 138 | -------------------------------------------------------------------------------- /source/_posts/2017/08/id-card.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 身份证的编码规则 3 | date: 2017-08-20 11:39:31 4 | tags: 5 | - PHP 6 | categories: 7 | - 语言 8 | - PHP 9 | --- 10 | 11 | 在我国现行的身份证系统中共有 15 位和 18 位两种身份证号码,第一代身份证大多为 15 位号码,由于 15 位身份证只能为 1900.01.01 到 1999.12.31 出生的人编码(千年虫问题),所以后来逐步替换为 18 位的身份证号码。 12 | 13 | ![](//www.fanhaobai.com/2017/08/id-card/05f73384-a9ba-4a80-8433-563331dfd896.jpg) 14 | 15 | ## 编码规则 16 | 17 | ### 15位 18 | 19 | 15 位身份证编码规则为:[DDDDDD YYMMDD XXS](#) 20 | 21 | 各组成部分说明: 22 | 23 | | 部分名 | 描述 | 24 | | ------ | ----------------------------- | 25 | | DDDDDD | 6 位地区编码 | 26 | | YYMMDD | 出生年月。年份用 2 位表示 | 27 | | XXS | 顺序码。
其中 S 为性别识别码,奇数为男,偶数为女 | 28 | 29 | 例如某个 15 位 ID 为:513701930509101。 30 | 31 | ### 18位 32 | 33 | 18 位身份证较 15 位身份证,出生年月改变为 8 位,并引入了校验位。编码规则为:[DDDDDD YYYYMMDD XXX Y](#) 34 | 35 | 各组成部分说明: 36 | 37 | | 部分名 | 描述 | 38 | | -------- | --------------- | 39 | | DDDDDD | 6 位地区编码 | 40 | | YYYYMMDD | 出生年月。年份用 4 位表示 | 41 | | XXX | 顺序码。奇数为男,偶数为女 | 42 | | Y | 校验位。前 17 位值计算而得 | 43 | 44 | 校验位 Y 取值范围为 [1, 0, X, 9, 8, 7, 6, 5, 4, 3, 2],其采用加权方式校验,校验规则为:p = mod(∑(Ai×Wi), 11) 45 | 46 | 参数说明: 47 | * i 为身份证数字所在的位数,1-17; 48 | * Ai 为身份证第 i 位对应的数字值; 49 | * Wi 为加权因子,值为 [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2]; 50 | * p 表示获取 Y 范围值的第 p+1 个值作为校验值 Y; 51 | 52 | 例如某个 18 位 ID 位:513701199305091010,校验位后续计算得出。 53 | 54 | ## 格式校验 55 | 56 | 通过分析身份证的 [编码规则](#编码规则),我们就可以得出身份证的校验规则,这里使用正则表达式去进行匹配。 57 | 58 | ### 15位 59 | 60 | 15 位身份证`DDDDDD YYMMDD XXS`的每部分的正则匹配表达式为: 61 | 62 | | 部分名 | 正则表达式 | 63 | | ------ | ---------------------------------------- | 64 | | DDDDDD | [1-9]\d{5} | 65 | | YYMMDD | (\d{2})(0\[1-9\]|(1\[0-2\]))((\[0-2\]\[1-9\])|([1-2]0)|31) | 66 | | XXS | \d{3} | 67 | 68 | 由此可得 15 位身份证证正则匹配表达式为: 69 | 70 | ```Js 71 | '^[1-9]\d{5}\d{2}(0[1-9]|(1[0-2]))(([0-2][1-9])|([1-2]0)|31)\d{3}$' 72 | //可简化为: 73 | '^[1-9]\d{7}(0[1-9]|1[0-2])([0-2][1-9]|[1-2]0|31)\d{3}$' 74 | ``` 75 | 76 | PHP 中校验为: 77 | 78 | ```PHP 79 | const ID_15_PREG = '/^[1-9]\d{7}(0[1-9]|1[0-2])([0-2][1-9]|[1-2]0|31)\d{3}$/'; 80 | 81 | public static function validate($id) 82 | { 83 | if (!is_string($id) || empty($id)) { 84 | return false; 85 | } else if (strlen($id) == 15 && preg_match(static::ID_15_PREG, $id)) { 86 | return true; 87 | } 88 | return false; 89 | } 90 | ``` 91 | 92 | ### 18位 93 | 94 | 同理,18 位身份证`DDDDDD YYYYMMDD XXX Y`的每部分的正则匹配表达式为: 95 | 96 | | 部分名 | 正则表达式 | 97 | | -------- | ---------------------------------------- | 98 | | DDDDDD | [1-9]\d{5} | 99 | | YYYYMMDD | (\[1-9\]\d{3})(0\[1-9\]|(1\[0-2\]))((\[0-2\]\[1-9\])|([1-2]0)|31) | 100 | | XXX | \d{3} | 101 | | Y | \d | 102 | 103 | 由此可得 18 位身份证证正则匹配表达式为: 104 | 105 | ```Js 106 | '^[1-9]\d{5}([1-9]\d{3})((0[1-9]|(1[0-2]))(([0-2][1-9])|([1-2]0)|31)\d{3}\d|[Xx]$' 107 | //可简化为: 108 | '^[1-9]\d{5}[1-9]\d{3}(0[1-9]|1[0-2])([0-2][1-9]|[1-2]0|31)(\d{4}|\d{3}[Xx])$' 109 | ``` 110 | 111 | 根据校验位校验规则,实现 **校验位** 的编码: 112 | 113 | ```PHP 114 | public static function getCheckBit($id) 115 | { 116 | if (18 !== strlen($id)) { 117 | return false; 118 | } 119 | $yArr = ['1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2']; 120 | $wArr = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2]; 121 | $sum = 0; 122 | for ($i = strlen($id)-2; $i>=0; $i--) { 123 | $sum += $id[$i] * $wArr[$i]; 124 | } 125 | $key = $sum % 11; 126 | return $yArr[$key]; 127 | } 128 | ``` 129 | 130 | 所以,PHP 中校验逻辑为: 131 | 132 | ```PHP 133 | const ID_18_PREG = '/^[1-9]\d{5}[1-9]\d{3}(0[1-9]|1[0-2])([0-2][1-9]|[1-2]0|31)(\d{4}|\d{3}[Xx])$/'; 134 | 135 | public static function validate($id) 136 | { 137 | if (!is_string($id) || empty($id)) { 138 | return false; 139 | } else if (strlen($id) == 18 && preg_match(static::ID_18_PREG, $id) && strtoupper($id[17]) === self::getCheckBit($id)) { 140 | return true; 141 | } else if (strlen($id) == 15 && preg_match(static::ID_15_PREG, $id)) { 142 | return true; 143 | } 144 | return false; 145 | } 146 | ``` 147 | 148 | ## 15位转化为18位 149 | 150 | 在金融等某些特殊行业,需要将 15 位身份证号码格式化为 18 位。由于 15 位身份证颁发年份都是 19\*\* 年,所以在转化为 18 位时补充出生年份时直接添加 19 即可。 151 | 152 | 转化步骤: 153 | * 年份补全成 4 位,年份前直接添加 19; 154 | * 补全上步的新号码为 18 位,可以在原号码末尾直接追加 X; 155 | * 计算新号码的校验位并替换原校验位值; 156 | 157 | 15 位身份证转化为 18 位的代码如下: 158 | 159 | ```PHP 160 | public static function format18($id) 161 | { 162 | if (!static::validate($id)) { 163 | return ''; 164 | } else if (15 !== strlen($id)) { 165 | return $id; 166 | } 167 | $newId = substr($id, 0, 6) . '19' . substr($id, -9) . 'X'; 168 | $newId[17] = static::getCheckBit($newId); 169 | return $newId; 170 | } 171 | ``` 172 | 173 | 转化示例结果: 174 | 175 | ```PHP 176 | //15位---------------------18位 177 | '370725881105149' => '37072519881105149X' 178 | ``` 179 | 180 | -------------------------------------------------------------------------------- /source/_posts/2017/04/array-form-max-string.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 求非负数组元素组成的最大字符串 3 | date: 2017-04-03 13:43:56 4 | tags: 5 | - PHP 6 | - 算法 7 | categories: 8 | - 语言 9 | - PHP 10 | --- 11 | 12 | 问题叙述:将一个非负元素数组中的所有元素排列组合在一起,找出值最大的那个排列情况。例如 [0, 9, 523, 94, 10, 4],排列组合后值最大数为:9945234100。 13 | 14 | ![预览图](//www.fanhaobai.com/2017/04/array-form-max-string/57f35c24-2eeb-4c68-bf28-0771b11cad34.png) 15 | 16 | 本文废话较多,可以直接跳转到 [编码实现](#编码实现) 部分。 17 | 18 | ## 背景描述 ## 19 | 20 | 这是我遇到的一道笔试题。首次遇见我也是很懵,当时我的第一感觉就是排序,但是没有及时理清里面的规律,导致后面并没有解答出此题。 21 | 22 | ## 问题分析 ## 23 | 24 | ### 确定输入值 ### 25 | 26 | 该问题描述很简单,也给出了测试用例,需求很明白。但是还需要注意问题背后隐藏的一些问题。 27 | 28 | 可确定输入的情况大致为: 29 | 30 | * 数组元素都为非负数,但可能为 0; 31 | * 数组长度并没有确定,长度可能很大。这里假设操作不溢出; 32 | * 数组元素的位数不确定,用例只涉及到 2 位数,需要考虑多位数的情况。这里假设操作不溢出; 33 | 34 | ### 寻找规律 ### 35 | 36 | 面试时请教了一下面试官,面试官的思路: 37 | 38 | > 最简单办法就是枚举所有可能的排列组合情况,然后求排列组合后的最大值;再就是寻找组合的规律,满足什么条件的元素排列在前。 39 | 40 | 当然这只是面试官提供的一些解决思路,付诸于实践还需要探索。在复试前的一天晚上我再次翻出这个问题,并找到了一些思路。 41 | 42 | 就拿问题中的用例 [0, 9, 523, 94, 10, 4] 来说,需要找出的结果为:9,94,523,4,10,0(为了方便说明,用”,“分割了数组元素)。 43 | 44 | 先将复杂问题简单化处理,首先尝试使用 **排序算法** 来分析过程。分析 9 和 94 的排列,为什么 9 排列在 94 前?[那是因为这 2 个数存在 2 种排列情况,既_ 9_94_ 和_ 9_49_,很明显 _9_94_ 排列大于 _9_49_ 排列,所以需要将 9 排列在 94 前,反之则需要交换元素位置](#)。如果采用这样规则处理,是在 2 个元素之间进行枚举排列情况,且单次枚举情况限定在了 2 种,降低了问题的复杂程度并易于编码实现,后续可以直接使用排序方法来多次重复这种 2 个元素之间的单次枚举动作。 45 | 46 | 说明:符号“_”为占位符,表示该位置可能还存在其他元素,但不影响当前两个元素的前后排列顺序。后续出现该符号将不再说明。 47 | 48 | 总之,我认为该问题是排序问题的一个变种情况,同排序问题不同的是 **比较规则**。这里不是直接比较 2 个元素值大小,而是比较 2 个元素排列组合后值的大小。 49 | 50 | ## 实现思路 ## 51 | 52 | 经过上述分析,问题规律已经掌握清楚,这里整理出实现的思路。 53 | 54 | ### 整体思路 ### 55 | 56 | * 确定使用排序算法实现; 57 | * 与传统排序不同之处为元素之间的比较规则; 58 | 59 | ### 排序过程 ### 60 | 61 | 使用冒泡排序来说明上述用例的排序过程。 62 | 63 | ![](//www.fanhaobai.com/2017/04/array-form-max-string/65FD0FD202413415D266AC754A75AAF3.png) 64 | 65 | ### 比较规则 ### 66 | 67 | 本问题的排序比较规则可以描述为:假设参与比较的两个元素为 A、B(初始时 A 在 B 前,排序结果从左至右为由大到小),比较时如果排列 _A_B_ 小于排列 _B_A_,A 和 B 则交换位置,反之不交换。 68 | 69 | ## 编码实现 ## 70 | 71 | ### 比较规则 ### 72 | 73 | ```PHP 74 | /** 75 | * 比较规则 76 | * @param string $a 77 | * @param string $b 78 | * @return int 79 | */ 80 | function cmp($a, $b) { 81 | if ($a == $b) { 82 | return 0; 83 | } 84 | return $a . $b > $b . $a ? -1 : 1; 85 | } 86 | ``` 87 | 88 | ### 冒泡排序 ### 89 | 90 | ```PHP 91 | /** 92 | * 冒泡排序 93 | * @param array $Arr 待排序数组 94 | * @return array 95 | */ 96 | function bubble_sort(array $Arr) { 97 | $length = count($Arr); 98 | if ($length < 2) { 99 | return $Arr; 100 | } 101 | 102 | for ($i = 1, $change = true; $i <= $length && $change; $i++) { 103 | $change = false; 104 | for ($j = $length - 1; $j > $i - 1; $j--) { 105 | if (cmp($Arr[$j - 1], $Arr[$j]) > 0) { 106 | $temp = $Arr[$j - 1]; 107 | $Arr[$j - 1] = $Arr[$j]; 108 | $Arr[$j] = $temp; 109 | $change = true; 110 | } 111 | } 112 | } 113 | return $Arr; 114 | } 115 | 116 | /** 117 | * 寻找非零元素数组中所有元素排列组合后的最大值 118 | * @param array $Arr 待排序数组 119 | * @param string $method 排序方法 120 | * @return mixed 121 | */ 122 | function array_form_max_str(array $Arr, $method = 'bubble') { 123 | //参数校验 124 | if (!is_array($Arr)) return false; 125 | foreach ($Arr as $value) { 126 | if ($value < 0) return false; 127 | } 128 | //排序算法 129 | switch ($method) { 130 | case 'quick' : 131 | usort($Arr, "cmp"); //快速排序 132 | break; 133 | case 'bubble' : 134 | $Arr = bubble_sort($Arr); //冒泡排序 135 | break; 136 | default : break; 137 | } 138 | //拼接 139 | return implode('', $Arr); 140 | } 141 | ``` 142 | 143 | ### 快速排序 ### 144 | 145 | 由于 PHP 中 sort 排序函数采用快速排序算法,这里直接使用之。 146 | 147 | ```PHP 148 | /** 149 | * 寻找非零元素数组中所有元素排列组合后的最大值 150 | * @param array $Arr 待排序数组 151 | * @param string $method 排序方法 152 | * @return mixed 153 | */ 154 | function array_form_max_str(array $Arr, $method = 'quick') { 155 | //参数校验 156 | if (!is_array($Arr)) return false; 157 | foreach ($Arr as $value) { 158 | if ($value < 0) return false; 159 | } 160 | //排序算法 161 | switch ($method) { 162 | case 'quick' : //快速排序 163 | usort($Arr, "cmp"); 164 | break; 165 | case 'bubble' : 166 | $Arr = bubble_sort($Arr); //冒泡排序 167 | break; 168 | default : break; 169 | } 170 | //拼接 171 | return implode('', $Arr); 172 | } 173 | ``` 174 | 175 | ## 用例测试 ## 176 | 177 | 这里只对快速排序方法使用 2 组测试用例并列举如下。 178 | 179 | ### 测试代码 ### 180 | 181 | ```PHP 182 | $Arr = [20,913,223,91,20,3]; 183 | echo '数组为[', implode(',', $Arr), ']', PHP_EOL; 184 | echo '最大排列组合为:', array_form_max_str($Arr), PHP_EOL; 185 | ``` 186 | 187 | ### 测试结果 ### 188 | 189 | ```PHP 190 | //第1组用例 191 | 数组为[0,9,523,94,10,4] 192 | 最大排列组合为:9945234100 193 | 194 | //第2组用例 195 | 数组为[20,913,223,91,20,3] 196 | 最大排列组合为:9191332232020 197 | ``` 198 | 199 | ## 写在最后 ## 200 | 201 | 经过深入分析问题的本质,也使得我对与排序算法有了更深入的认识,更算是一个巩固。同时,正是由于我尝试着去解决这个问题,才使得我在后面的复试环节中面试官再次提出相同问题时,给出了一个满意的解决方案。 202 | 203 | 相关文章 [»](#) 204 | 205 | * [王者编程大赛之一](https://www.fanhaobai.com/2017/12/2017-ziroom-king-1.html#题3) (2017-12-05) -------------------------------------------------------------------------------- /source/_posts/2020/05/use-kafka.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 在分布式系统使用Kafka 3 | date: 2020-05-12 12:30:00 4 | tags: 5 | - 系统设计 6 | categories: 7 | - 语言 8 | - Go 9 | --- 10 | 11 | 在分布式系统中,常常使用消息系统进行系统解耦,并实现一些异步业务逻辑,保证系统最终数据一致性。这里主要介绍在实际中落地使用 Kafka 的一些事项。 12 | 13 | ![预览图](//www.fanhaobai.com/2020/05/use-kafka/1589262505081.png) 14 | 15 | ## 消息TOPIC 16 | 17 | 根据不同业务,拆分不同的 Topic。 18 | 19 | ## 消息结构 20 | 21 | ### 格式定义 22 | 23 | 推送至 Kafka 的消息统一使用 JSON 结构,数据如: 24 | 25 | ```Json 26 | { 27 | "type": "/StatusEvent", 28 | "data": "XXXXXXXXXX" 29 | } 30 | ``` 31 | 32 | 33 | 消息结构定义为: 34 | 35 | ```Go 36 | // 消息事件数据 37 | type PbEventMessage struct { 38 | // 事件数据类型:包/结构体名 39 | Type string 40 | // 事件数据 41 | Data []byte 42 | } 43 | ``` 44 | 45 | 其中,`Type` 为消息类型,`Type` 为消息事件的 PB 结构体名称;`Data` 为 PB 协议的事件数据,见下文。 46 | 47 | > 由于 PB 只序列化字段类型和顺序,因此同一个 PB 数据流在反序列化时,存在多个类型消息事件解释。而同一个 Topic 会存在多个类型消息事件,只通过 PB 并不能区分消息,因此引入 Type 用来区分不同类型消息。 48 | 49 | 50 | ### 事件数据 51 | 52 | 例如,当业务订单状态发生扭转时,会产生订单状态事件消息。 53 | 54 | ``` 55 | 订单状态 56 | message StatusEvent { 57 | // 订单transNo 58 | uint64 trans_no = 1; 59 | // 状态 60 | uint32 status = 2; 61 | // 扩展数据 62 | string ext = 3; 63 | } 64 | ``` 65 | 66 | 67 | ## 业务消费 68 | 69 | 通过消费 Kafka 消息,实现部分业务逻辑。在实现 Consume 时,需要注意以下几个事项: 70 | 71 | 1、原则上保持职责单一原则 72 | 73 | 即不同的业务逻辑要拆分到不同的 Consume 实现。 74 | 75 | ```Go 76 | // Consume PaySms 77 | // 支付短信提醒 78 | type PaySms struct { 79 | handler.Base 80 | } 81 | 82 | 83 | func (h PaySms) Handle(msg *cevent.PbEventMessagee) error { 84 | } 85 | ``` 86 | 87 | 88 | ```Go 89 | // Consume PayWx 90 | // 支付公众号消息通知 91 | type PayWx struct { 92 | handler.Base 93 | } 94 | 95 | 96 | func (h PayWx) Handle(msg *cevent.PbEventMessage) error { 97 | } 98 | ``` 99 | 100 | 2、只消费自己关注的 Type 类型消息 101 | 102 | ```Go 103 | // Consume PaySms 104 | type PaySms struct { 105 | handler.Base 106 | } 107 | 108 | 109 | func (h PaySms) Handle(msg *cevent.PbEventMessage) error { 110 | var ( 111 | event = new(StatusEvent) 112 | ) 113 | 114 | // 只消费自己关注的 Type 类型消息 115 | if !msg.Unmarshal(event, msg) { 116 | return nil 117 | } 118 | 119 | 120 | // 处理逻辑 121 | } 122 | 123 | 124 | // 事件数据消息 125 | type PbEventMessage struct { 126 | // 事件数据类型:包/结构体名 127 | Type string 128 | // 事件数据 129 | Data []byte 130 | } 131 | 132 | func (msg PbEventMessage) Unmarshal(event PbEvent) error { 133 | // 事件数据类型校验 134 | t := utils.FullTypeNameOf(event) 135 | if msg.Type != t { 136 | return errors.Errorf("type %s cannot be converted to %s", msg.Type, t) 137 | } 138 | 139 | // 数据解码 140 | err := event.XXX_Unmarshal(msg.Data) 141 | if nil != err { 142 | return err 143 | } 144 | 145 | return nil 146 | } 147 | ``` 148 | 149 | 3、消费异常重试机制 150 | 151 | 消息消费采用 [至少一次]() 的消费语义,即 先消费后保存读取偏移量。若消费失败,则不更新读取偏移量,会继续消费该失败消息。 152 | 153 | ```Go 154 | // 实现 ConsumerGroupHandler 接口 155 | type defaultConsumer struct { 156 | handler cevent.Handler 157 | } 158 | 159 | 160 | func (c *defaultConsumer) Setup(sarama.ConsumerGroupSession) error { 161 | return nil 162 | } 163 | 164 | func (c *defaultConsumer) Cleanup(sarama.ConsumerGroupSession) error { 165 | return nil 166 | } 167 | 168 | // ConsumeClaim must start a consumer loop of ConsumerGroupClaim's Messages(). 169 | func (c *defaultConsumer) ConsumeClaim(session sarama.ConsumerGroupSession, claim sarama.ConsumerGroupClaim) error { 170 | for msg := range claim.Messages() { 171 | c.logger.Debugf( 172 | "message topic[%q] timestamp[%v] partition[%d] offset[%d]", 173 | msg.Topic, msg.Timestamp, msg.Partition, msg.Offset, 174 | ) 175 | 176 | // 解析消息 177 | pbMsg := &cevent.PbEventMessage{} 178 | err := json.Unmarshal(msg.Value, pbMsg) 179 | if nil != err { 180 | return errors.Wrapf(err, "msg unmarshal failed") 181 | } 182 | 183 | // 消费逻辑,失败返回错误 184 | if err := c.handler(pbMsg); err != nil { 185 | c.logger.Info(fmt.Sprintf("event handle failed, data: %s, err: %s", msg.Value, err)) 186 | return errors.Wrapf(err, "event handle failed,data: %s", msg.Value) 187 | } 188 | 189 | 190 | 191 | // 成功,更新偏移量标记该消息已被消费过 192 | session.MarkMessage(msg, "") 193 | } 194 | 195 | return nil 196 | } 197 | ``` 198 | 199 | 由于 [至少一次]() 消费语义,会导致消息重复消费,因此消费逻辑需要做幂等处理。 200 | 201 | 202 | 4、不同业务逻辑的 Consume 应该使用不同的 Group 203 | 204 | 一是,为了减少不同业务逻辑失败时之间的相互影响;二是,同一个消息在同一个 Group 的 Consume,只会被消费一次,否则存在部分 Consume 丢失消息的情况。 205 | 206 | ```Go 207 | consume.Listen("order-pay-sms", message.PaySms{}.Handle) 208 | consume.Listen("order-pay-wx", message.PayWx{}.Handle) 209 | ``` 210 | 211 | ## 容错处理 212 | 213 | 为了保持最终数据一致性,消息在生产和消费时都做了重试机制。 214 | 215 | ### Producer 216 | 217 | 1、推送失败重试机制 218 | 219 | 投递消息使用同步应答模式,当消息推送失败时,这里才用 [最大努力尝试]() 策略保持数据最终一致性。 220 | 221 | ![推送失败重试机制](//www.fanhaobai.com/2020/05/use-kafka/1589251986346.png) 222 | 223 | ### Consumer 224 | 225 | 2、消费异常重试机制 226 | 227 | ![消费异常重试机制](//www.fanhaobai.com/2020/05/use-kafka/1589258896838.jpg) 228 | 229 | > 特别注意需要处理脏数据,防止因为错误数据导致消费阻塞。 230 | 231 | 3、只消费自己关注的 Type 类型消息 232 | 233 | ![关注只关注Type类型消息](//www.fanhaobai.com/2020/05/use-kafka/1589258912991.jpg) 234 | 235 | 具体实现,见 [业务消费](#业务消费) 部分。 236 | 237 | ## 总结 238 | 239 | 在分布式系统中引入消息系统,使得各系统可以只关注自己的业务逻辑,系统维护性更强,同时能极大的提高系统的稳定性。但是由于具有异步特性,存在一定的使用场景限制,对于实时响应的系统,还是建议直接使用 RPC 调用完成交互。 -------------------------------------------------------------------------------- /source/_posts/2017/01/robots.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Robots协议的那些事 3 | date: 2017-01-12 12:33:20 4 | tags: 5 | - 协议 6 | categories: 7 | - 协议 8 | --- 9 | 10 | 由于本站文章搜索引擎搜索机器人(以下简称:爬虫)爬取效果不是很理想,出现了导航链接大量被爬取,而文章链接爬取较少。所以准备对本站加入 SEO,其实也就是引入了 [Robots协议](http://baike.baidu.com/link?url=2cB03FvdeTNWMUFlQEQxT4E6FxQ7DGXQr7Q6tAt702pNePMjVODT4Sj1vxp9W5ehdG9QP6dUZBrsiIJNYphnkPz6M9D8nHmbo7sdLNEydcg7QVqgnu4LUIGKTg5v-3ii0JqcHLrvxcBzN1UNBBH3fWBWmVlh3Jh0kSpoybswT7_) 。Robots 协议(也称为爬虫协议、机器人协议等)的全称是「[网络爬虫排除标准](http://baike.baidu.com/link?url=qZmXuLBjgnHeD9Q-gV4Rg1QAZOF04_MbuFOQRLaA_jZqIBgqVkbtVA-8YAzHo3mFwtrL2l0vrfmgw97OlU2R36hMv0KGgRTFOnl2lonhJ7J4Uspy3WCTiGCtpGK65BCc)」(Robots Exclusion Protocol)。网站通过 Robots 协议告诉搜索引擎哪些页面可以抓取,哪些页面不能抓取,而 **robots.txt 文本文件** 就是 Robots 协议的表述。 11 | 12 | ![](//www.fanhaobai.com/2017/01/robots/n9DQpbXNbazisDMy_bouP7HN.png) 13 | 14 | Robots 协议代表了互联网领域的一种契约精神,互联网企业只有遵守这一规则,才能保证网站及用户的隐私数据不被侵犯,违背 Robots 协议将带来巨大安全隐忧。例如,[百度诉奇虎360违反“Robots协议”抓取、复制其网站内容侵权一案](http://tech.ifeng.com/internet/special/baidupk360/content-1/detail_2012_08/29/17183239_0.shtml)。 15 | 16 | # 爬取过程 17 | 18 | 互联网的网页都是通过超链接互相关联的,进而形成了网页的网状结构。所以爬虫的工作方法就如蜘蛛在网络上沿着超链接按照一定的爬取规则爬取网页。 19 | 20 | ![](//www.fanhaobai.com/2017/01/robots/FozbmxH8U0MTs0N-teFaCtWa.jpg) 21 | 22 | 基本流程大致为: 23 | 24 | 1) 喂给爬虫一堆 URL,称之为 **种子**(Seeds); 25 | 2) 爬虫爬取 Seeds,**分析** HTML 网页,抽取其中的 **超链接**; 26 | 3) 爬虫接着爬取这些 **新发现** 的超链接指向的 HTML 网页; 27 | 4) 对过程 2),3)**循环往复**; 28 | 29 | # 协议作用 30 | 31 | Robots协议 **主要功能** 为以下 4 项: 32 | 33 | 1) 网站通过该协议告诉搜索引擎哪些页面可以抓取,哪些页面不能; 34 | 2) 可以屏蔽一些网站中比较大的文件,如:图片,音乐,视频等,节省服务器带宽; 35 | 3) 可以屏蔽站点的一些死链接,方便搜索引擎抓取网站内容; 36 | 4) 设置网站地图导向,方便引导蜘蛛爬取页面; 37 | 38 | 可以想象,如果一个站点没有引入 Robots 协议,那么爬虫就会漫无目地爬取,爬取结果一般不尽人意。反之,将我们站点内容通过 Robots 协议表述出来并引入 Robots 协议,爬虫就会按照我们的意愿进行爬取。 39 | 40 | 41 | # 协议原则 42 | 43 | Robots 协议是国际互联网界通行的 **道德规范**,基于以下 ** 原则** 建立: 44 | 45 | 1) 搜索技术应服务于人类,同时尊重信息提供者的意愿,并维护其隐私权; 46 | 2) 网站有义务保护其使用者的个人信息和隐私不被侵犯; 47 | 48 | # 协议表述 49 | 50 | Robots 协议是通过 robots.txt 文件来进行表述的,[robots.txt文件规范见这里](http://www.robotstxt.org/robotstxt.html) 。robots.txt 文件是一个 **文本文件**,使用任何一个常见的文本编辑器都可以对它进行查看与编辑。当然,也可以使用 [Robots 文件生成工具](http://tool.chinaz.com/robots) 方便地生成我们所需要的 robots.txt 文件。 51 | 52 | 提示: robots.txt 文件应该放置在网站根目录下。 53 | 54 | ## 协议表述规范 55 | 56 | 对规范大致描述为: 57 | 58 | ```Ini 59 | User-agent: * # *代表所有的搜索引擎种类,是一个通配符,其他常用值:百度-Baiduspider,搜狗-sogou spider,谷歌-Googlebot 60 | Disallow: /admin/ # 禁止抓取admin目录下面的目录 61 | Disallow: /require/ # 禁止抓取require目录下面的目录 62 | Disallow: /static/ # 禁止抓取static目录下面的目录 63 | Disallow: /cgi-bin/*.htm # 禁止抓取/cgi-bin/目录下的所有以".htm"为后缀的URL(包含子目录)。 64 | Disallow: /*?* # 禁止抓取网站中所有包含问号 (?) 的网址 65 | Disallow: /.jpg$ # 禁止抓取网站中所有的.jpg格式的图片 66 | Disallow: /public/404.html # 禁止爬取public文件夹下面的404.htm文件。 67 | Allow: /home/  # 允许抓取home目录下面的目录 68 | Allow: /home # 允许抓取home的整个目录 69 | Allow: .htm$ # 允许抓取以".htm"为后缀的URL。 70 | Allow: .gif$ # 允许抓取gif格式图片 71 | Sitemap: http://你的网址/map.xml # 建议加入xml格式的文件,这个是谷歌标准格式 72 | Sitemap: http://你的网址/map.html # 建议加入html格式的文件,这个是百度标准格式 73 | ``` 74 | 75 | 一般情况下不需要指定 Allow 这项配置。 76 | 77 | ## 网站地图规范 78 | 79 | * **XML格式** 80 | 81 | 这里参照了百度站长的 [官方文档](http://zhanzhang.baidu.com/college/courseinfo?id=267&page=2#h2_article_title3),大致描述如下: 82 | 83 | ```PHP 84 | 85 | 86 | 87 | 88 | 89 | 90 | http://www.yoursite.com/yoursite.html 91 | 92 | 2009-12-14 93 | 94 | daily 95 | 96 | 0.8 97 | 98 | 99 | 100 | ``` 101 | 102 | * **HTML格式** 103 | 104 | 主体结构为完整的 HTML,将需要被爬的链接以``标签的形式加入到`body`中即可。 105 | 106 | ```HTML 107 | ... ... 108 | 109 | 110 | 111 | ... ... 112 | 113 | ... ... 114 | ``` 115 | 116 | ## 本站配置 117 | 118 | * ** 本站博客 ** 119 | 120 | 本站拒绝了雅虎爬虫的爬取,对其他的爬虫,theme、static 目录下的 2 个逻辑代码目录 api、module 和 4 个静态资源目录 font、css、img、js 做了限制爬取,对 static 目录下 upload 做了允许爬取处理,并配置了后缀为`.xml`和`.htm`文件的站点地图。 121 | 122 | ```Ini 123 | # robots.txt for fanhaobai.com 2017.01.12 124 | # yahoo disallow 125 | User-agent: Slurp 126 | Disallow: / 127 | # other allow 128 | User-agent: * 129 | Disallow: /admin 130 | Disallow: /theme/ 131 | Disallow: /static/api/ 132 | Disallow: /static/module/ 133 | Disallow: /static/font/ 134 | Disallow: /static/css/ 135 | Disallow: /static/img/ 136 | Disallow: /static/js/ 137 | Sitemap: http://www.fanhaobai.com/map.xml 138 | Sitemap: http://www.fanhaobai.com/map.html 139 | ``` 140 | 141 | 查看本站的 **网站地图**,[HTML格式](#) 和 [XML格式](https://www.fanhaobai.com/sitemap.xml) 。 142 | 143 | * ** 本站维基 ** 144 | 145 | ```Ini 146 | User-agent: * 147 | Disallow: / 148 | ``` 149 | 150 | # 提交文件 151 | 152 | 一般情况下,站点根目录下加入了 robots.txt 文件后,各种搜索引擎的爬虫就会自动爬取该文件。尽管如此,还是建议手动将 robots.txt 文件提交到搜索引擎,同时也能帮助检测 robots.txt 文件是否存在错误。 153 | 154 | 本站手动将 robots.txt 提交到谷歌和百度两个搜索引擎: 155 | 156 | 1) [谷歌测试工具](https://www.google.com/webmasters/tools/robots-testing-tool?hl=zh-CN) 157 | 158 | ![](//www.fanhaobai.com/2017/01/robots/5PCU9neptZdG3aY5veYsls0v.png) 159 | 160 | 2) [百度测试工具](http://zhanzhang.baidu.com/robots/index) 161 | 162 | ![](//www.fanhaobai.com/2017/01/robots/xWjjcJzJrrhkjH6lWy7aZib_.png) 163 | 164 | 按照对应提示操作即可,出现上图情况则表示 robots.txt 手动提交成功。 165 | 166 | # 总结 167 | 168 | Robots 协议只是爬虫抓取站点内容的一种规则,需要搜索引擎爬虫的配合才行,并不是每个搜索引擎爬虫都遵守的。但是,目前看来,绝大多数的搜索引擎爬虫都遵守 Robots 协议的规则。 169 | 170 | 值得注意的是,robots.txt 文件虽说是提供给爬虫使用,但是正如它的名称——网络爬虫排除标准,它具有消极的排爬虫抓取作用。所以百度官方建议,** [仅当网站包含不希望被搜索引擎收录的内容时,才需要使用 robots.txt 文件。如果您希望搜索引擎收录网站上所有内容,请勿建立robots.txt 文件](#) **。 171 | 172 | > 推荐一篇相关文章:http://lusongsong.com/reed/732.html。 173 | 174 | 相关文章 [»](#) 175 | 176 | * [如何向搜索引擎提交链接](https://www.fanhaobai.com/2017/01/push-links.html) (2017-01-17) -------------------------------------------------------------------------------- /source/_posts/2020/07/openapi.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 自建一个简易的OpenAPI网关 3 | date: 2020-07-15 19:30:00 4 | tags: 5 | - 系统设计 6 | categories: 7 | - 语言 8 | - Go 9 | --- 10 | 11 | 网关(API Gateway)是请求流量的唯一入口,可以适配各类渠道和业务,处理各种协议接入、路由与报文转换、同步异步调用等,来管理 API 接口和进行请求流量控制,在微服务架构中,网关尤为重要。 12 | 13 | ![预览图](//www.fanhaobai.com/2020/07/openapi/ffc6e25d-7044-467d-8b7c-910831249968.jpeg) 14 | 15 | ## 背景 16 | 17 | 当然,现在已有很多开源软件,如 [Kong](https://github.com/Kong/kong)、[Gravitee](https://gravitee.io/)、[Zuul](https://github.com/Netflix/zuul)。 18 | 19 | 这些开源网关固然功能齐全,但对于我们业务来说,有点太重了,我们有部分定制化需求,为此我们自建了一个轻量级的 OpenAPI 网关,主要供第三方渠道对接使用。 20 | 21 | ## 简介 22 | 23 | ### 功能特性 24 | 25 | #### 接口鉴权 26 | 27 | * 请求 5s 自动过期 28 | * 参数 md5 签名 29 | * 模块粒度的权限控制 30 | 31 | #### 接口版本控制 32 | 33 | * 支持转发到不同服务 34 | * 支持转发到同一个服务不同接口 35 | 36 | #### 事件回调 37 | 38 | * 事件订阅 39 | * 最大重试 3 次 40 | * 重试时间采用衰减策略(30s、60s、180s) 41 | 42 | ### 系统架构 43 | 44 | 从第三方请求 API 链路来说,第三方渠道通过 HTTP 协议请求 OpenAPI 网关,网关再将请求转发到对应的内部服务端口,这些端口层通过 gRPC 调用请求到服务层,处理完请求后依次返回。 45 | 46 | 从事件回调请求链路来说,服务层通过 HTTP 协议发起事件回调请求到 OpenAPI 网关,并立即返回成功。OpenAPI 网关异步完成第三方渠道事件回调请求。 47 | 48 | ![系统架构](//www.fanhaobai.com/2020/07/openapi/f227c462-b9b9-4846-aeae-23c579b05087.jpeg) 49 | 50 | ## 实现 51 | 52 | ### 网关配置 53 | 54 | 由于网关存在内部服务和第三方渠道配置,更为了实现配置的热更新,我们采用了 ETCD 存储配置,存储格式为 JSON。 55 | 56 | #### 配置分类 57 | 58 | 配置分为以下 3 类: 59 | 60 | * 第三方 AppId 配置 61 | * 内外 API 映射关系 62 | * 内部服务地址 63 | 64 | #### 配置结构 65 | 66 | a、第三方 AppId 配置 67 | 68 | ![AppId配置](//www.fanhaobai.com/2020/07/openapi/9655aec3-aa6c-4353-819e-a095a0fdd5bf.png) 69 | 70 | b、内部服务地址 71 | 72 | ![内部服务地址](//www.fanhaobai.com/2020/07/openapi/48e89e9b-eede-4aec-b98f-ce50cc112c99.png) 73 | 74 | c、内外 API 映射关系 75 | 76 | ![API映射关系](//www.fanhaobai.com/2020/07/openapi/676dcc84-628d-493c-8ab6-c9f2ec3053df.png) 77 | 78 | #### 配置更新 79 | 80 | 利用 ETCD 的 watch 监听,可以轻易实现配置的热更新。 81 | 82 | ![配置热更新](//www.fanhaobai.com/2020/07/openapi/549e72de-cdbd-4b8d-a238-085f226d7555.jpg) 83 | 84 | 当然也还是需要主动拉取配置的情况,如重启服务的时候。 85 | 86 | ![拉取热更新](//www.fanhaobai.com/2020/07/openapi/ae062ec1-7f3c-4535-916b-c9cd08734a7d.jpg) 87 | 88 | 89 | ### API 接口 90 | 91 | 第三方调用 API 接口的时序,大致如下: 92 | 93 | ![API调用时序](//www.fanhaobai.com/2020/07/openapi/a4768e8e-f961-4270-ba9d-69d2a317d49b.png) 94 | 95 | #### 参数格式 96 | 97 | 为了简化对接流程,我们统一了 API 接口的请求参数格式。请求方式支持 POST 或者 GET。 98 | 99 | ![API调用时序](//www.fanhaobai.com/2020/07/openapi/d0131310-b7f8-4deb-aa9e-fcc6b28a47a2.png) 100 | 101 | #### 接口签名 102 | 103 | 签名采用 md5 加密方式,算法可描述为: 104 | 105 | 1、将参数 p、m、a、t、v、ak、secret 的值按顺序拼接,得到字符串; 106 | 2、md5 第 1 步的字符串并截取前 16 位, 得到新字符串; 107 | 3、将第 2 步的字符串转化为小写,即为签名; 108 | 109 | PHP 版的请求,如下: 110 | 111 | ```PHP 112 | $appId = 'app id'; 113 | $appSecret = 'app secret'; 114 | $api = 'api method'; 115 | 116 | // 业务参数 117 | $businessParams = [ 118 | 'orderId' => '123123132', 119 | ]; 120 | 121 | $time = time(); 122 | $params = [ 123 | 'p' => json_encode($businessParams), 124 | 'm' => 'inquiry', 125 | 'a' => $api, 126 | 't' => $time, 127 | 'v' => 1, 128 | 'ak' => $appId, 129 | ]; 130 | 131 | $signStr = implode('', array_values($params)) . $appSecret; 132 | $sign = strtolower(substr(md5($signStr), 0, 16)); 133 | 134 | $params['s'] = $sign; 135 | ``` 136 | 137 | #### 接口版本控制 138 | 139 | 不同的接口版本,可以转发请求到不同的服务,或同一个服务的不同接口。 140 | 141 | ![接口版本控制](//www.fanhaobai.com/2020/07/openapi/c6987388-682d-403f-8621-caa1fa6cd266.png) 142 | 143 | 144 | ### 事件回调 145 | 146 | 通过事件回调机制,第三方可以订阅自己关注的事件。 147 | 148 | ![接口版本控制](//www.fanhaobai.com/2020/07/openapi/4b6660db-0e0c-4c6d-9716-0e63820f45e1.png) 149 | 150 | ## 对接接入 151 | 152 | ### 渠道接入 153 | 154 | 只需要配置第三方 AppId 信息,包括 secret、回调地址、模块权限。 155 | 156 | ![渠道AppId配置](//www.fanhaobai.com/2020/07/openapi/3321e082-1857-4c2b-8d19-a60334f9b4f5.png) 157 | 158 | 即,需要在 ETCD 执行如下操作: 159 | 160 | ```bash 161 | $ etcdctl set /openapi/app/baidu '{ 162 | "Id": "baidu", 163 | "Secret": "00cf2dcbf8fb6e73bc8de50a8c64880f", 164 | "Modules": { 165 | "inquiry": { 166 | "module": "inquiry", 167 | "CallBack": "http://www.baidu.com" 168 | } 169 | } 170 | }' 171 | 172 | ``` 173 | 174 | ### 服务接入 175 | 176 | a、配置内部服务地址 177 | 178 | ![配置内部服务地址](//www.fanhaobai.com/2020/07/openapi/1a902abb-fb35-42e1-9f3a-c18e12074f11.png) 179 | 180 | 即,需要在 ETCD 执行如下操作: 181 | 182 | ```bash 183 | $ etcdctl set /openapi/backend/form_openapi '{ 184 | "type": "form", 185 | "Url": "http://med-ih-openapi.app.svc.cluster.local" 186 | }' 187 | ``` 188 | 189 | b、配置内外 API 映射关系 190 | 191 | ![配置内部服务地址](//www.fanhaobai.com/2020/07/openapi/39befe95-381e-47ad-879d-e5433e778078.png) 192 | 193 | 同样,需要在 ETCD 执行如下操作: 194 | 195 | ```bash 196 | $ etcdctl set /openapi/api/inquiry/createMedicine.v2 '{ 197 | "Module": "inquiry", 198 | "Method": "createMedicine", 199 | "Backend": "form_openapi", 200 | "ApiParams": { 201 | "path": "inquiry/medicine-clinic/create" 202 | } 203 | }' 204 | ``` 205 | 206 | c、接入事件回调 207 | 208 | 接入服务也需要按照第三方接入方式,并申请 AppId。回调业务参数约定为: 209 | 210 | ![配置内部服务地址](//www.fanhaobai.com/2020/07/openapi/ba4a385e-add6-40fe-aa30-40866f8e4f40.png) 211 | 212 | Golang 版本的接入,如下: 213 | 214 | ```golang 215 | const ( 216 | AppId = "__inquiry" 217 | AppSecret = "xxxxxxxxxx" 218 | Version = "1" 219 | ) 220 | 221 | type CallbackReq struct { 222 | TargetAppId string //目标APP Id 223 | Module string //目标模块 224 | Event string //事件 225 | Params map[string]interface{} //参数 226 | } 227 | 228 | func generateData(req CallbackReq) map[string]string { 229 | params, _ := json.Marshal(req.Params) 230 | p := map[string]interface{}{ 231 | "ak": req.TargetAppId, 232 | "m": req.Module, 233 | "e": req.Event, 234 | "p": string(params), 235 | } 236 | 237 | pStr, _ := json.Marshal(p) 238 | postParams := map[string]string{ 239 | "p": string(pStr), 240 | "m": "callback", 241 | "a": "callback", 242 | "t": fmt.Sprintf("%d", time.Now().Unix()), 243 | "v": Version, 244 | "ak": AppId, 245 | } 246 | 247 | postParams["s"] = sign(getSignData(postParams) + AppSecret) 248 | 249 | return postParams 250 | } 251 | 252 | func getSignData(params map[string]string) string { 253 | return strings.Join([]string{params["p"], params["m"], params["a"], params["t"], params["v"], params["ak"]}, "") 254 | } 255 | 256 | func sign(str string) string { 257 | return strings.ToLower(utils.Md5(str)[0:16]) 258 | } 259 | ``` 260 | 261 | ## 未来规划 262 | 263 | * 后台支持配置 AppId 264 | * 事件回调失败请求支持手动重试 265 | * 请求限流 266 | -------------------------------------------------------------------------------- /source/_posts/2017/09/supervisor.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 使用Supervisor管理进程 3 | date: 2017-09-23 17:56:57 4 | tags: 5 | - 工具 6 | categories: 7 | - 工具 8 | --- 9 | 10 | [Supervisor](http://supervisord.org) 是一款使用 Python 开发的非常优秀的进程管理工具。它可以在类 UNIX 系统上让用户精确地监视与控制多组指定数量的服务进程。当监控的服务进程意外退出时,会尝试自动重启这些服务,以保持服务可用状态。 11 | 12 | ![](//www.fanhaobai.com/2017/09/supervisor/d42decd3-2342-4e8f-a34f-48b47fc6e557.png) 13 | 14 | ## 安装 15 | 16 | Supervisor [官方](http://www.supervisord.org/installing.html) 提供的安装方式较多,这里采用 pip 方式安装。 17 | 18 | ### 安装pip 19 | 20 | ```Shell 21 | $ yum install python-pip 22 | # 升级pip 23 | $ pip install --upgrade pip 24 | $ pip -V 25 | pip 9.0.1 26 | ``` 27 | 28 | ### 安装Supervisor 29 | 30 | 通过 pip 安装 Supervisor: 31 | 32 | ```Shell 33 | $ pip install supervisor 34 | Successfully installed supervisor-3.3.3 35 | ``` 36 | 37 | 安装 Supervisor 后,会出现 supervisorctl 和 supervisord 两个程序,其中 supervisorctl 为服务监控终端,而 supervisord 才是所有监控服务的大脑。查看 supervisord 是否安装成功: 38 | 39 | ```Shell 40 | $ supervisord -v 41 | 3.3.3 42 | ``` 43 | 44 | ### 开机启动 45 | 46 | 将 supervisord 配置成开机启动服务,下载官方 [init 脚本](https://github.com/Supervisor/initscripts/blob/master/redhat-init-mingalevme)。 47 | 48 | 修改关键路径配置: 49 | 50 | ```Shell 51 | PIDFILE=/var/run/supervisord.pid 52 | LOCKFILE=/var/lock/subsys/supervisord 53 | OPTIONS="-c /etc/supervisord.conf" 54 | ``` 55 | 56 | 移到该文件到`/etc/init.d`目录下,并重命名为 supervisor,添加可执行权限: 57 | 58 | ```Shell 59 | $ chmod 777 /etc/init.d/supervisor 60 | ``` 61 | 62 | 配置成开机启动服务: 63 | 64 | ```Shell 65 | $ chkconfig --add supervisor 66 | $ chkconfig supervisor on 67 | $ chkconfig --list | grep "supervisor" 68 | supervisor 0:off 1:off 2:on 3:on 4:on 5:on 6:off 69 | ``` 70 | 71 | ## 配置 72 | 73 | ### 生成配置文件 74 | 75 | Supervisord 安装后,需要使用如下命令生成配置文件。 76 | 77 | ```Shell 78 | $ mkdir /etc/supervisor 79 | $ echo_supervisord_conf > /etc/supervisor/supervisord.conf 80 | ``` 81 | 82 | ### 主配置部分 83 | 84 | `supervisord.conf`的主配置部分说明: 85 | 86 | ```Ini 87 | [unix_http_server] 88 | file=/tmp/supervisor.sock ; socket文件的路径 89 | ;chmod=0700 ; socket文件权限 90 | ;chown=nobody:nogroup ; socket文件用户和用户组 91 | ;username=user ; 连接时认证的用户名 92 | ;password=123 ; 连接时认证的密码 93 | 94 | [inet_http_server] ; 监听TCP 95 | port=127.0.0.1:9001 ; 监听ip和端口 96 | username=user ; 连接时认证的用户名 97 | password=123 ; 连接时认证的密码 98 | 99 | [supervisord] 100 | logfile=/var/log/supervisord.log ; log目录 101 | logfile_maxbytes=50MB ; log文件最大空间 102 | logfile_backups=10 ; log文件保持的数量 103 | loglevel=info ; log级别 104 | pidfile=/var/run/supervisord.pid 105 | nodaemon=false ; 是否非守护进程态运行 106 | minfds=1024 ; 系统空闲的最少文件描述符 107 | minprocs=200 ; 可用的最小进程描述符 108 | ;umask=022 ; 进程创建文件的掩码 109 | ;identifier=supervisor ; supervisord标识符 110 | ;directory=/tmp ; 启动前切换到的目录 111 | ;nocleanup=true ; 启动前是否清除子进程的日志文件 112 | ;childlogdir=/tmp ; AUTO模式,子进程日志路径 113 | ;environment=KEY="value" ; 设置环境变量 114 | 115 | [rpcinterface:supervisor] ; XML_RPC配置 116 | supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface 117 | 118 | [supervisorctl] 119 | serverurl=unix:///tmp/supervisor.sock ; 连接的socket路径 120 | ;username=chris ; 用户名 121 | ;password=123 ; 密码 122 | prompt=mysupervisor ; 输入用户名和密码时的提示符 123 | ;history_file=~/.sc_history ; 历史操作记录存储路径 124 | 125 | [include] ; 包含文件,将每个进程配置为一个文件并包含 126 | files = /etc/supervisor/*.ini ; 多个进程的配置文件 127 | ``` 128 | 129 | 这部分我们不需要做太多的配置修改,如果需要开启 WEB 终端监控,则需要配置并开启 inet_http_server 项。 130 | 131 | ### 进程配置部分 132 | 133 | Supervisor 需管理的进程服务配置,示例如下: 134 | 135 | ```Ini 136 | [program:work] ; 服务名,例如work 137 | command=php -r "sleep(10);exit(1);" ; 带有参数的可执行命令 138 | process_name=%(process_num)s ; 进程名,当numprocs>1时,需包含%(process_num)s 139 | numprocs=2 ; 启动进程的数目数 140 | ;directory=/tmp ; 运行前切换到该目录 141 | ;umask=022 ; 进程掩码 142 | ;priority=999 ; 子进程启动关闭优先级 143 | autostart=true ; 子进程是否被自动启动 144 | startsecs=1 ; 成功启动几秒后则认为成功启动 145 | ;startretries=3 ; 子进程启动失败后,最大尝试启动的次数 146 | autorestart=unexpected ; 子进程意外退出后自动重启的选项,false, unexpected, true。unexpected表示不在exitcodes列表时重启 147 | exitcodes=0,2 ; 期待的子程序退出码 148 | ;stopsignal=QUIT ; 进程停止信号,可以为TERM,HUP,INT,QUIT,KILL,USR1,or USR2等信号,默认为TERM 149 | ;stopwaitsecs=10 ; 发送停止信号后等待的最大时间 150 | ;stopasgroup=false ; 是否向子进程组发送停止信号 151 | ;killasgroup=false ; 是否向子进程组发送kill信号 152 | ;redirect_stderr=true ; 是否重定向日志到标准输出 153 | stdout_logfile=/data/logs/work.log ; 进程的stdout的日志路径 154 | ;stdout_logfile_maxbytes=1MB ; 日志文件最大大小 155 | ;stdout_logfile_backups=10 156 | ;stdout_capture_maxbytes=1MB 157 | ;stderr_logfile=/a/path ; stderr的日志路径 158 | ;stderr_logfile_maxbytes=1MB 159 | ;stderr_logfile_backups=10 160 | ;stderr_capture_maxbytes=1MB 161 | ;environment=A="1",B="2" ; 子进程的环境变量 162 | ;serverurl=AUTO ; 子进程的环境变量SUPERVISOR_SERVER_URL 163 | ``` 164 | 165 | > 通常将每个进程的配置信息配置成独立文件,并通过 include 模块包含,这样方便修改和管理配置文件。 166 | 167 | ## 启动 168 | 169 | 配置完成后,启动 supervisord 守护服务: 170 | 171 | ```Shell 172 | $ supervisord -c /etc/supervisor/supervisord.conf 173 | ``` 174 | 175 | 常用的命令参数说明: 176 | 177 | * -c:指定配置文件路径 178 | * -n:是否非守护态运行 179 | * -l:日志文件目录 180 | * -i:唯一标识 181 | 182 | 查看 supervisord 启动情况: 183 | 184 | ```Shell 185 | $ ps -ef | grep "supervisor" 186 | root 24901 1 0 Sep23 ? 00:00:30 /usr/bin/python /usr/bin/supervisord -c /etc/supervisor/supervisord.conf 187 | $ netstat -tunpl 188 | tcp 0 0 127.0.0.1:9001 0.0.0.0:* LISTEN 24901/python 189 | ``` 190 | 191 | ## 监控进程 192 | 193 | Supervisor 提供了多种监控服务的方式,包括 supervisorctl 命令行终端、Web 端、XML_RPC 接口多种方式。 194 | 195 | ### 命令终端 196 | 197 | 直接使用 supervisorctl 即可在命令行终端查看所有服务的情况,如下: 198 | 199 | ```Shell 200 | $ supervisorctl 201 | work:0 RUNNING pid 31313, uptime 0:00:07 202 | work:1 RUNNING pid 31318, uptime 0:00:06 203 | # -u 用户名 -p 密码 204 | ``` 205 | 206 | supervisorctl 常用命令列表如下; 207 | 208 | * [status](#):查看服务状态 209 | * [update](#):重新加载配置文件 210 | * [restart](#):重新启动服务 211 | * [stop](#):停止服务 212 | * [pid](#):查看某服务的 pid 213 | * [tail](#):输出最新的 log 信息 214 | * [shutdown](#):关闭 supervisord 服务 215 | 216 | ### Web 217 | 218 | 在配置中开启 inet_http_server 后,即可通过 Web 界面便捷地监控进程服务了。 219 | 220 | ![](//www.fanhaobai.com/2017/09/supervisor/9d28cc24-a0d8-11e7-abc4-cec278b6b50a.png) 221 | -------------------------------------------------------------------------------- /source/_posts/2017/05/draw-by-prob.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 按照奖品概率分布抽奖的实现 3 | date: 2017-05-18 12:20:23 4 | tags: 5 | - PHP 6 | - 算法 7 | categories: 8 | - 语言 9 | - PHP 10 | --- 11 | 12 | 需求:首先用户通过以一定方式(好友点赞等)开启抽奖资格,然后按照用户 100% 中奖概率进行抽奖,且系统的发放奖品需要按照各个奖品整体的期望中奖比例来进行分布,最后用户抽中奖品调用第三方发放接口发放奖品并记录保存,另有些奖品存在发放数量限制。 13 | 14 | ## 问题分析 15 | 16 | 整个抽奖过程是同步进行,由于前置了开启抽奖资格保护,会避免用户集中进行抽奖,故系统并发量并不会太高。突出的问题主要有以下几个: 17 | 18 | 1)由于同步调用第三方接口发放奖品,奖品可能发放失败; 19 | 2)有一些奖品存在数量限制,可能已经发放完; 20 | 3)系统要求用户 100% 抽中奖品; 21 | 4)系统要求各个奖品总的发放情况符合预期的比例分布; 22 | 23 | ## 解决方案 24 | 25 | 针对以上突出问题,给出针对的解决办法。 26 | 27 | * 问题1:采用带有次数限制的重试机制,降低奖品发放接口发放失败情况,同时捕获异常来应对接口返回异常信息。重试机制失败则自动重新进行一轮按概率抽奖,依次类推并做重发次数限制; 28 | * 问题2:奖品数量在奖品发放端进行限制。因为系统存在数量限制的奖品期望发放比例较低,每轮抽中这些奖品概率也较低,所以可以采用若奖品已发放完,则自动重新进行一轮按概率抽奖,依次类推并做重发次数限制; 29 | * 问题3:尽管有发放接口的重试机制和自动多轮按概率抽奖机制,也可能存在抽取奖品失败的情况,这里采用一种特定奖品作为兜底的办法,当然兜底奖品也有重试机制,使用户抽中概率接近 100%; 30 | * 问题4:因为重试机制失败或者抽取到已经发送完毕的奖品时,会自动重新进行下一轮抽奖,由于规则也是按照概率抽奖,所以不影响各个奖品总的比例分布情况; 31 | 32 | ## 编码 33 | 34 | ### 按概率抽奖 35 | 36 | 核心思想是采用随机函数 mt_rand() 来模拟用户抽奖。 37 | 38 | 奖品信息如下: 39 | ```PHP 40 | //所有奖品信息 41 | $allPrizes = [ 42 | 'jd' => ['name' => '京东券', 'probability' => 30], 43 | 'film' => ['name' => '电影票', 'probability' => 10], 44 | 'tb' => ['name' => '淘宝券', 'probability' => 60], 45 | ] 46 | ``` 47 | 48 | **方式一** 49 | 50 | 这是一个比较中规中矩的方式,*主要思想* 是:将所有奖品按照期望比例分布,一段一段小区间分布到 1~100 这个区间,然后随机一个 1~100 的随机数,如果这个随机数落在某段区间,则表示抽取对应区间的奖品。 51 | 52 | ``` 53 | 1 30 10 60 54 | 1|-----------|------|----------------------|100 55 | 京东券 电影票 淘宝券 56 | ``` 57 | 58 | 代码如下: 59 | ```PHP 60 | /** 61 | * 按照概率抽取一个奖品, 返回奖品 62 | * @param array $prizes 所有奖品的probability概率总和应该为100 63 | * @return mixed 64 | */ 65 | private function randPrize(array $prizes) 66 | { 67 | //总概率基数 68 | $totalProbability = array_sum(array_column(array_values($prizes), 'probability')); 69 | if (100 !== $totalProbability) { 70 | throw new Exception('invalid probability config'); 71 | } 72 | $rand = mt_rand(1, 100); 73 | $cursor = 0; 74 | $id = ''; 75 | while(list($key, $item) = each($prizes)) { 76 | if ($rand > $cursor && $rand <= $cursor + $item['probability']) { 77 | $id = $key; 78 | break; 79 | } 80 | $cursor += $item['probability']; 81 | } 82 | unset($prizes[$id]['probability']); 83 | 84 | return $prizes[$id] + ['id' => $id]; 85 | } 86 | ``` 87 | 88 | *方式二* 89 | 90 | 该方式如果直接看代码比较难理解。主要思想:按照给定顺序(按照奖品配置顺序),先后一个一个抽取奖品,直到抽中一个奖品为止, 抽中后续奖品的概率的前提是没有抽中当前奖品,多次抽取概率应该相乘。 91 | 92 | 例如: 93 | 94 | ``` 95 | 次数 奖品 概率 基数 中奖概率 未中奖概率 96 | 1 京东券 30 100 30/100 70/100 97 | 2 电影票 10 70 (70/100)*(10/70) (70/100)*(60/70) 98 | 3 淘宝券 60 60 (70/100)*(60/70)*(1) 1-(70/100)*(60/70)*(1) 99 | ``` 100 | 101 | ```PHP 102 | /** 103 | * 按照概率抽取一个奖品, 返回奖品, 104 | * @param array $prizes 参与抽奖的奖品信息, 所有奖品的probability概率总和应该为100 105 | * @return array 106 | */ 107 | private function randPrize(array $prizes) 108 | { 109 | //总概率基数 110 | $totalProbability = array_sum(array_column(array_values($prizes), 'probability')); 111 | if (100 !== $totalProbability) { 112 | throw new Exception('invalid probability config'); 113 | } 114 | //可以考虑按照概率倒序排序 115 | /*uasort($prizes, function(array $a, array $b) { 116 | if ($a['probability'] == $b['probability']) return 0; 117 | return $a['probability'] > $b['probability'] ? -1 : 1; 118 | });*/ 119 | //按照奖品顺序依次模拟抽中奖品 120 | $id = ''; 121 | foreach ($prizes as $key => $item) { 122 | $rand = mt_rand(1, $totalProbability); //本次抽奖的基数 123 | if ($rand <= $item['probability']) { //表示抽中 124 | $id = $key; 125 | break; 126 | } else { 127 | $totalProbability -= $item['probability']; //后续奖品基数减去抽过的概率, 因为抽中后一个奖品的前提是抽不中前一些奖品 128 | } 129 | } 130 | unset($prizes[$id]['probability']); 131 | return $prizes[$id] + ['id' => $id]; 132 | } 133 | ``` 134 | 135 | ### 抽中奖品 136 | 137 | 主要包含重试机制、自动重新一轮按照概率抽奖机制、兜底机制的实现。 138 | 139 | ```PHP 140 | /** 141 | * 抽奖 142 | * @param array $allPrizes 143 | * @return mixed 144 | */ 145 | public function draw($allPrizes) 146 | { 147 | $tryTimes = 0; 148 | $outPrize = []; 149 | $prize = []; 150 | 151 | //如果抽到有数量限制奖品且奖品也已经抽完或者抽取失败, 最多抽奖次数 152 | while ($tryTimes < 4) { 153 | $tryTimes++; 154 | //按照概率抽取 155 | $prize = $this->randPrize($allPrizes); 156 | //模拟发放奖品方法 157 | $outPrize = $this->getOnePrize($prize['id']); 158 | //抽中退出 159 | if (!empty($outPrize)) { 160 | break; 161 | } 162 | } 163 | 164 | echo '尝试按照概率抽取次数:' , $tryTimes, PHP_EOL; 165 | 166 | //多次抽奖都抽中已经抽完的奖品, 则用兜底奖品兜底 167 | $tryTimes = 0; 168 | while (!$outPrize && $tryTimes < 2) { 169 | $tryTimes++; 170 | $prize = $allPrizes['default'] + ['id' => 'default']; 171 | $outPrize = $this->getOnePrize('default'); 172 | } 173 | 174 | echo '兜底抽取次数:' , $tryTimes, PHP_EOL; 175 | 176 | if (!$outPrize) { 177 | //兜底失败, 可能是券达到上限, 或者接口down了 178 | return false; 179 | } else { 180 | //合并奖品信息 181 | $outPrize = $outPrize + $prize; 182 | } 183 | 184 | return $outPrize; 185 | } 186 | ``` 187 | 188 | ## 验证 189 | 190 | ### 概率分布 191 | 192 | *抽样方法* 193 | ```PHP 194 | public function sample($all, $times) 195 | { 196 | $out = []; 197 | $count = $times; 198 | if ($times > 1000000) return; 199 | while ($times) { 200 | $times--; 201 | $prize = $this->draw($all); 202 | if (!isset($out[$prize['id']])) { 203 | $out[$prize['id']] = 0; 204 | } 205 | $out[$prize['id']]++; 206 | } 207 | array_walk($out, function(&$value, $key) use ($count) { 208 | $value = ($value / $count * 100); 209 | }); 210 | 211 | ksort($out); 212 | return $out; 213 | } 214 | ``` 215 | *抽样结果* 216 | ```PHP 217 | //期望概率 218 | array(3) { 219 | ["film"] => int(10) 220 | ["jd"] => int(30) 221 | ["tb"] => int(60) 222 | } 223 | //抽样2000次 224 | array(3) { 225 | ["film"] => string(4) "9.8" 226 | ["jd"] => string(6) "31.35" 227 | ["tb"] => string(6) "58.85" 228 | } 229 | ``` 230 | 231 | ### 异常处理机制 232 | 233 | ```PHP 234 | 尝试按照概率抽取次数: 3 235 | 兜底抽取次数: 0 236 | 抽中奖品为:array(3) { 237 | ["name"] => string(20) "淘宝50元消费券" 238 | ["content"] => string(12) "WD84-3233-21" 239 | ["id"] => string(2) "tb" 240 | } 241 | ``` 242 | 243 | --------------------------------------------------------------------------------