From f60d82138a9872cac6c3dc63464139a27271f321 Mon Sep 17 00:00:00 2001 From: YC Date: Mon, 18 Sep 2023 10:06:36 +0800 Subject: [PATCH] auto deploy, remotes/origin/main-0-g2868b11 --- 404.html | 21 + android/index.html | 64 + archives/index.html | 204 ++ assets/css/0.styles.8a8cb31f.css | 1 + assets/img/search.83621669.svg | 1 + assets/js/1.a7be01c9.js | 6 + assets/js/10.b8b1c69f.js | 1 + assets/js/100.6c889d38.js | 1 + assets/js/101.60ad6dbe.js | 1 + assets/js/102.4127c84d.js | 1 + assets/js/103.3d9db5eb.js | 1 + assets/js/104.46c9c015.js | 1 + assets/js/105.47aefb8e.js | 1 + assets/js/106.11920c46.js | 1 + assets/js/107.0b61254d.js | 1 + assets/js/108.ec9dff6b.js | 1 + assets/js/109.f1deacf5.js | 1 + assets/js/11.5c4cc4bb.js | 1 + assets/js/110.d0192926.js | 1 + assets/js/111.606d2d81.js | 1 + assets/js/112.aa6de9dc.js | 1 + assets/js/113.8766cc3e.js | 1 + assets/js/114.46b84e3f.js | 1 + assets/js/115.17cb622d.js | 1 + assets/js/116.f3684c67.js | 1 + assets/js/117.c3b4267e.js | 1 + assets/js/118.4674f502.js | 1 + assets/js/119.5d33a787.js | 1 + assets/js/12.d7b1a59f.js | 1 + assets/js/120.ab526730.js | 1 + assets/js/121.d91fe832.js | 1 + assets/js/122.c8f1bccc.js | 1 + assets/js/123.d7a6cea8.js | 1 + assets/js/124.ed03c543.js | 1 + assets/js/125.51f4a6cc.js | 1 + assets/js/126.ea9e102c.js | 1 + assets/js/127.0d747633.js | 1 + assets/js/128.080e33e7.js | 1 + assets/js/129.da1e979c.js | 1 + assets/js/13.fc723977.js | 1 + assets/js/130.a6e9802c.js | 1 + assets/js/131.0f269eb9.js | 1 + assets/js/132.da58fe07.js | 1 + assets/js/133.4a51e59f.js | 1 + assets/js/134.dc9c8690.js | 1 + assets/js/135.dbd7a88c.js | 1 + assets/js/136.a4874667.js | 1 + assets/js/137.7205d03d.js | 1 + assets/js/138.2df4a0de.js | 1 + assets/js/139.380116d5.js | 1 + assets/js/14.285cce9e.js | 1 + assets/js/140.69abfa8c.js | 1 + assets/js/141.3ceb723f.js | 1 + assets/js/142.f960d1ce.js | 1 + assets/js/143.6b32cab5.js | 1 + assets/js/144.0f0e34e1.js | 1 + assets/js/145.77ccd494.js | 1 + assets/js/146.44102b53.js | 1 + assets/js/147.4c7d9048.js | 1 + assets/js/148.71d7c7b3.js | 1 + assets/js/149.6f0e763c.js | 1 + assets/js/15.d6e839a3.js | 1 + assets/js/150.70b791a5.js | 1 + assets/js/151.2fbf46c6.js | 1 + assets/js/152.4667a007.js | 1 + assets/js/153.d59db30c.js | 1 + assets/js/154.f826c41c.js | 1 + assets/js/155.2037fa4f.js | 1 + assets/js/156.118c9123.js | 1 + assets/js/157.9bff072a.js | 1 + assets/js/158.e0fbd9d4.js | 1 + assets/js/159.7adbcbd6.js | 1 + assets/js/16.42aaf4fa.js | 1 + assets/js/160.4b92934c.js | 1 + assets/js/161.1b4a1d0d.js | 1 + assets/js/162.f9dd8f5c.js | 1 + assets/js/17.5ab70506.js | 1 + assets/js/18.311ef653.js | 1 + assets/js/19.86c15ae6.js | 1 + assets/js/2.4938589e.js | 1 + assets/js/20.38b68893.js | 1 + assets/js/21.e59a9fa2.js | 1 + assets/js/22.ba3d4daa.js | 1 + assets/js/23.5330affd.js | 1 + assets/js/24.5a2a5e07.js | 1 + assets/js/25.49df835e.js | 1 + assets/js/26.49477071.js | 1 + assets/js/27.78c4bfb3.js | 1 + assets/js/28.3aed427f.js | 1 + assets/js/29.be2fe3f7.js | 1 + assets/js/3.c591ef2f.js | 9 + assets/js/30.65c53f6e.js | 1 + assets/js/31.0ea24d9d.js | 1 + assets/js/32.0181ccd5.js | 1 + assets/js/33.f7b2a77f.js | 1 + assets/js/34.4d583feb.js | 1 + assets/js/35.d32af94e.js | 1 + assets/js/36.523cc6b8.js | 1 + assets/js/37.a3d1a0f1.js | 1 + assets/js/38.d2f862be.js | 1 + assets/js/39.add3f26d.js | 1 + assets/js/4.63f828c8.js | 1 + assets/js/40.3c545622.js | 1 + assets/js/41.aac1c8b8.js | 1 + assets/js/42.9049242c.js | 1 + assets/js/43.95fe1066.js | 1 + assets/js/44.234e85a1.js | 1 + assets/js/45.766c2ddd.js | 1 + assets/js/46.baf712b6.js | 1 + assets/js/47.36f43ab8.js | 1 + assets/js/48.566091e4.js | 1 + assets/js/49.fdd49479.js | 1 + assets/js/5.b1b1df38.js | 1 + assets/js/50.ecf93ba1.js | 1 + assets/js/51.5ee9dbbb.js | 1 + assets/js/52.eec69599.js | 1 + assets/js/53.bf6b3f12.js | 1 + assets/js/54.dbc23ce8.js | 1 + assets/js/55.6b158b9e.js | 1 + assets/js/56.2872159b.js | 1 + assets/js/57.c84be887.js | 1 + assets/js/58.c5576bf5.js | 1 + assets/js/59.5186dd10.js | 1 + assets/js/6.d320717b.js | 1 + assets/js/60.965ec7df.js | 1 + assets/js/61.26bdabb3.js | 1 + assets/js/62.c48ad769.js | 1 + assets/js/63.07a9a7ed.js | 1 + assets/js/64.e0ad93a0.js | 1 + assets/js/65.bb2c89ab.js | 1 + assets/js/66.f21ab691.js | 1 + assets/js/67.ae34006f.js | 1 + assets/js/68.325d6318.js | 1 + assets/js/69.a00d1e3f.js | 1 + assets/js/70.c347c4c6.js | 1 + assets/js/71.c52e0f63.js | 1 + assets/js/72.9c3acff8.js | 1 + assets/js/73.c224c877.js | 1 + assets/js/74.677ebc29.js | 1 + assets/js/75.c11411fc.js | 1 + assets/js/76.60639833.js | 1 + assets/js/77.406dc39c.js | 1 + assets/js/78.76a0e76b.js | 1 + assets/js/79.93272048.js | 1 + assets/js/80.da400a7d.js | 1 + assets/js/81.75134db8.js | 1 + assets/js/82.52f4f6ca.js | 1 + assets/js/83.8c89e99f.js | 1 + assets/js/84.77fef493.js | 1 + assets/js/85.1cf2900b.js | 1 + assets/js/86.2def8f0a.js | 1 + assets/js/87.9fbbf8dc.js | 1 + assets/js/88.f0f85fcf.js | 1 + assets/js/89.3e155781.js | 1 + assets/js/9.fd10529f.js | 1 + assets/js/90.8821aeec.js | 1 + assets/js/91.d1fb6ddb.js | 1 + assets/js/92.84eb3950.js | 1 + assets/js/93.7c1db7dc.js | 1 + assets/js/94.c33623d6.js | 1 + assets/js/95.1f164633.js | 1 + assets/js/96.9f028032.js | 1 + assets/js/97.a25be736.js | 1 + assets/js/98.c63a5061.js | 1 + assets/js/99.3f671d22.js | 1 + assets/js/app.d4a66103.js | 16 + assets/js/vendors~docsearch.32565523.js | 3 + blog/index.html | 49 + categories/index.html | 209 ++ fe/index.html | 49 + iOS/index.html | 47 + index.html | 81 + java/index.html | 48 + logo.png | Bin 0 -> 88018 bytes mime/index.html | 50 + more/index.html | 60 + other/index.html | 124 + pages/0140a0/index.html | 118 + pages/02f88a/index.html | 58 + pages/03456e/index.html | 46 + pages/086701/index.html | 47 + pages/0c11ea/index.html | 46 + pages/0cdfba/index.html | 61 + pages/0d7cc1/index.html | 44 + pages/0fe5d6/index.html | 167 ++ pages/109caf/index.html | 45 + pages/10a997/index.html | 44 + pages/10e7db/index.html | 46 + pages/12d86f/index.html | 44 + pages/140cb3/index.html | 53 + pages/186356/index.html | 50 + pages/18abfe/index.html | 46 + pages/1bc90b/index.html | 47 + pages/1c262c/index.html | 47 + pages/21df4f/index.html | 95 + pages/22d48b/index.html | 53 + pages/233ea5/index.html | 46 + pages/29a4de/index.html | 108 + pages/2a8b7b/index.html | 43 + pages/2af3e9/index.html | 43 + pages/30ec1d/index.html | 49 + pages/37f363/index.html | 74 + pages/3869be/index.html | 46 + pages/39870b/index.html | 58 + pages/3adccf/index.html | 48 + pages/3aeda3/index.html | 63 + pages/3d30c9/index.html | 50 + pages/3dd4b2/index.html | 101 + pages/411579/index.html | 46 + pages/420ab6/index.html | 46 + pages/4595e1/index.html | 74 + pages/4db36a/index.html | 91 + pages/4f876a/index.html | 46 + pages/4f9b39/index.html | 43 + pages/514538/index.html | 60 + pages/548959/index.html | 61 + pages/55dc87/index.html | 47 + pages/59b0a9/index.html | 47 + pages/59f768/index.html | 43 + pages/5a96b7/index.html | 47 + pages/5d8ba8/index.html | 47 + pages/651b48/index.html | 43 + pages/6570ab/index.html | 63 + pages/669dfc/index.html | 47 + pages/6ab0a7/index.html | 48 + pages/6c1d02/index.html | 44 + pages/6cd2e1/index.html | 46 + pages/6ea216/index.html | 46 + pages/7071e6/index.html | 50 + pages/79c121/index.html | 45 + pages/79f386/index.html | 46 + pages/7c68cb/index.html | 46 + pages/7e542a/index.html | 44 + pages/7ee6cc/index.html | 52 + pages/82e5d7/index.html | 46 + pages/857c89/index.html | 46 + pages/86683c/index.html | 43 + pages/89d231/index.html | 51 + pages/8cb2e1/index.html | 46 + pages/8fbdb4/index.html | 44 + pages/907793/index.html | 46 + pages/935419/index.html | 46 + pages/977efe/index.html | 47 + pages/9b0a57/index.html | 46 + pages/9c451e/index.html | 66 + pages/9f55fd/index.html | 43 + pages/a0d7dc/index.html | 46 + pages/a96c0f/index.html | 126 + pages/aaf954/index.html | 112 + pages/b21fed/index.html | 46 + pages/b6bad0/index.html | 46 + pages/bd17b5/index.html | 48 + pages/bea5e2/index.html | 46 + pages/c3229c/index.html | 79 + pages/c38a8f/index.html | 46 + pages/c65eb4/index.html | 46 + pages/c76462/index.html | 46 + pages/c80e98/index.html | 46 + pages/c8fb65/index.html | 46 + pages/ca8e7a/index.html | 3278 +++++++++++++++++++++++ pages/cb9380/index.html | 54 + pages/cb9d0f/index.html | 47 + pages/cd0789/index.html | 46 + pages/ce4afc/index.html | 44 + pages/d2a447/index.html | 48 + pages/d2d3e5/index.html | 168 ++ pages/d3b34e/index.html | 67 + pages/d8c80d/index.html | 45 + pages/d8cbeb/index.html | 48 + pages/d9fade/index.html | 48 + pages/db8380/index.html | 194 ++ pages/dc1698/index.html | 58 + pages/dd1044/index.html | 44 + pages/df7642/index.html | 53 + pages/e4a24e/index.html | 51 + pages/e9db87/index.html | 1361 ++++++++++ pages/eae245/index.html | 46 + pages/ed7a6a/index.html | 47 + pages/f1d871/index.html | 43 + pages/f23ed2/index.html | 44 + pages/f7262c/index.html | 226 ++ pages/f85f1b/index.html | 63 + pages/f9b0df/index.html | 60 + pages/f9c14d/index.html | 48 + python/index.html | 55 + react/index.html | 50 + server/index.html | 58 + tags/index.html | 57 + tool/index.html | 63 + vue/index.html | 59 + web/index.html | 50 + 291 files changed, 12376 insertions(+) create mode 100644 404.html create mode 100644 android/index.html create mode 100644 archives/index.html create mode 100644 assets/css/0.styles.8a8cb31f.css create mode 100644 assets/img/search.83621669.svg create mode 100644 assets/js/1.a7be01c9.js create mode 100644 assets/js/10.b8b1c69f.js create mode 100644 assets/js/100.6c889d38.js create mode 100644 assets/js/101.60ad6dbe.js create mode 100644 assets/js/102.4127c84d.js create mode 100644 assets/js/103.3d9db5eb.js create mode 100644 assets/js/104.46c9c015.js create mode 100644 assets/js/105.47aefb8e.js create mode 100644 assets/js/106.11920c46.js create mode 100644 assets/js/107.0b61254d.js create mode 100644 assets/js/108.ec9dff6b.js create mode 100644 assets/js/109.f1deacf5.js create mode 100644 assets/js/11.5c4cc4bb.js create mode 100644 assets/js/110.d0192926.js create mode 100644 assets/js/111.606d2d81.js create mode 100644 assets/js/112.aa6de9dc.js create mode 100644 assets/js/113.8766cc3e.js create mode 100644 assets/js/114.46b84e3f.js create mode 100644 assets/js/115.17cb622d.js create mode 100644 assets/js/116.f3684c67.js create mode 100644 assets/js/117.c3b4267e.js create mode 100644 assets/js/118.4674f502.js create mode 100644 assets/js/119.5d33a787.js create mode 100644 assets/js/12.d7b1a59f.js create mode 100644 assets/js/120.ab526730.js create mode 100644 assets/js/121.d91fe832.js create mode 100644 assets/js/122.c8f1bccc.js create mode 100644 assets/js/123.d7a6cea8.js create mode 100644 assets/js/124.ed03c543.js create mode 100644 assets/js/125.51f4a6cc.js create mode 100644 assets/js/126.ea9e102c.js create mode 100644 assets/js/127.0d747633.js create mode 100644 assets/js/128.080e33e7.js create mode 100644 assets/js/129.da1e979c.js create mode 100644 assets/js/13.fc723977.js create mode 100644 assets/js/130.a6e9802c.js create mode 100644 assets/js/131.0f269eb9.js create mode 100644 assets/js/132.da58fe07.js create mode 100644 assets/js/133.4a51e59f.js create mode 100644 assets/js/134.dc9c8690.js create mode 100644 assets/js/135.dbd7a88c.js create mode 100644 assets/js/136.a4874667.js create mode 100644 assets/js/137.7205d03d.js create mode 100644 assets/js/138.2df4a0de.js create mode 100644 assets/js/139.380116d5.js create mode 100644 assets/js/14.285cce9e.js create mode 100644 assets/js/140.69abfa8c.js create mode 100644 assets/js/141.3ceb723f.js create mode 100644 assets/js/142.f960d1ce.js create mode 100644 assets/js/143.6b32cab5.js create mode 100644 assets/js/144.0f0e34e1.js create mode 100644 assets/js/145.77ccd494.js create mode 100644 assets/js/146.44102b53.js create mode 100644 assets/js/147.4c7d9048.js create mode 100644 assets/js/148.71d7c7b3.js create mode 100644 assets/js/149.6f0e763c.js create mode 100644 assets/js/15.d6e839a3.js create mode 100644 assets/js/150.70b791a5.js create mode 100644 assets/js/151.2fbf46c6.js create mode 100644 assets/js/152.4667a007.js create mode 100644 assets/js/153.d59db30c.js create mode 100644 assets/js/154.f826c41c.js create mode 100644 assets/js/155.2037fa4f.js create mode 100644 assets/js/156.118c9123.js create mode 100644 assets/js/157.9bff072a.js create mode 100644 assets/js/158.e0fbd9d4.js create mode 100644 assets/js/159.7adbcbd6.js create mode 100644 assets/js/16.42aaf4fa.js create mode 100644 assets/js/160.4b92934c.js create mode 100644 assets/js/161.1b4a1d0d.js create mode 100644 assets/js/162.f9dd8f5c.js create mode 100644 assets/js/17.5ab70506.js create mode 100644 assets/js/18.311ef653.js create mode 100644 assets/js/19.86c15ae6.js create mode 100644 assets/js/2.4938589e.js create mode 100644 assets/js/20.38b68893.js create mode 100644 assets/js/21.e59a9fa2.js create mode 100644 assets/js/22.ba3d4daa.js create mode 100644 assets/js/23.5330affd.js create mode 100644 assets/js/24.5a2a5e07.js create mode 100644 assets/js/25.49df835e.js create mode 100644 assets/js/26.49477071.js create mode 100644 assets/js/27.78c4bfb3.js create mode 100644 assets/js/28.3aed427f.js create mode 100644 assets/js/29.be2fe3f7.js create mode 100644 assets/js/3.c591ef2f.js create mode 100644 assets/js/30.65c53f6e.js create mode 100644 assets/js/31.0ea24d9d.js create mode 100644 assets/js/32.0181ccd5.js create mode 100644 assets/js/33.f7b2a77f.js create mode 100644 assets/js/34.4d583feb.js create mode 100644 assets/js/35.d32af94e.js create mode 100644 assets/js/36.523cc6b8.js create mode 100644 assets/js/37.a3d1a0f1.js create mode 100644 assets/js/38.d2f862be.js create mode 100644 assets/js/39.add3f26d.js create mode 100644 assets/js/4.63f828c8.js create mode 100644 assets/js/40.3c545622.js create mode 100644 assets/js/41.aac1c8b8.js create mode 100644 assets/js/42.9049242c.js create mode 100644 assets/js/43.95fe1066.js create mode 100644 assets/js/44.234e85a1.js create mode 100644 assets/js/45.766c2ddd.js create mode 100644 assets/js/46.baf712b6.js create mode 100644 assets/js/47.36f43ab8.js create mode 100644 assets/js/48.566091e4.js create mode 100644 assets/js/49.fdd49479.js create mode 100644 assets/js/5.b1b1df38.js create mode 100644 assets/js/50.ecf93ba1.js create mode 100644 assets/js/51.5ee9dbbb.js create mode 100644 assets/js/52.eec69599.js create mode 100644 assets/js/53.bf6b3f12.js create mode 100644 assets/js/54.dbc23ce8.js create mode 100644 assets/js/55.6b158b9e.js create mode 100644 assets/js/56.2872159b.js create mode 100644 assets/js/57.c84be887.js create mode 100644 assets/js/58.c5576bf5.js create mode 100644 assets/js/59.5186dd10.js create mode 100644 assets/js/6.d320717b.js create mode 100644 assets/js/60.965ec7df.js create mode 100644 assets/js/61.26bdabb3.js create mode 100644 assets/js/62.c48ad769.js create mode 100644 assets/js/63.07a9a7ed.js create mode 100644 assets/js/64.e0ad93a0.js create mode 100644 assets/js/65.bb2c89ab.js create mode 100644 assets/js/66.f21ab691.js create mode 100644 assets/js/67.ae34006f.js create mode 100644 assets/js/68.325d6318.js create mode 100644 assets/js/69.a00d1e3f.js create mode 100644 assets/js/70.c347c4c6.js create mode 100644 assets/js/71.c52e0f63.js create mode 100644 assets/js/72.9c3acff8.js create mode 100644 assets/js/73.c224c877.js create mode 100644 assets/js/74.677ebc29.js create mode 100644 assets/js/75.c11411fc.js create mode 100644 assets/js/76.60639833.js create mode 100644 assets/js/77.406dc39c.js create mode 100644 assets/js/78.76a0e76b.js create mode 100644 assets/js/79.93272048.js create mode 100644 assets/js/80.da400a7d.js create mode 100644 assets/js/81.75134db8.js create mode 100644 assets/js/82.52f4f6ca.js create mode 100644 assets/js/83.8c89e99f.js create mode 100644 assets/js/84.77fef493.js create mode 100644 assets/js/85.1cf2900b.js create mode 100644 assets/js/86.2def8f0a.js create mode 100644 assets/js/87.9fbbf8dc.js create mode 100644 assets/js/88.f0f85fcf.js create mode 100644 assets/js/89.3e155781.js create mode 100644 assets/js/9.fd10529f.js create mode 100644 assets/js/90.8821aeec.js create mode 100644 assets/js/91.d1fb6ddb.js create mode 100644 assets/js/92.84eb3950.js create mode 100644 assets/js/93.7c1db7dc.js create mode 100644 assets/js/94.c33623d6.js create mode 100644 assets/js/95.1f164633.js create mode 100644 assets/js/96.9f028032.js create mode 100644 assets/js/97.a25be736.js create mode 100644 assets/js/98.c63a5061.js create mode 100644 assets/js/99.3f671d22.js create mode 100644 assets/js/app.d4a66103.js create mode 100644 assets/js/vendors~docsearch.32565523.js create mode 100644 blog/index.html create mode 100644 categories/index.html create mode 100644 fe/index.html create mode 100644 iOS/index.html create mode 100644 index.html create mode 100644 java/index.html create mode 100644 logo.png create mode 100644 mime/index.html create mode 100644 more/index.html create mode 100644 other/index.html create mode 100644 pages/0140a0/index.html create mode 100644 pages/02f88a/index.html create mode 100644 pages/03456e/index.html create mode 100644 pages/086701/index.html create mode 100644 pages/0c11ea/index.html create mode 100644 pages/0cdfba/index.html create mode 100644 pages/0d7cc1/index.html create mode 100644 pages/0fe5d6/index.html create mode 100644 pages/109caf/index.html create mode 100644 pages/10a997/index.html create mode 100644 pages/10e7db/index.html create mode 100644 pages/12d86f/index.html create mode 100644 pages/140cb3/index.html create mode 100644 pages/186356/index.html create mode 100644 pages/18abfe/index.html create mode 100644 pages/1bc90b/index.html create mode 100644 pages/1c262c/index.html create mode 100644 pages/21df4f/index.html create mode 100644 pages/22d48b/index.html create mode 100644 pages/233ea5/index.html create mode 100644 pages/29a4de/index.html create mode 100644 pages/2a8b7b/index.html create mode 100644 pages/2af3e9/index.html create mode 100644 pages/30ec1d/index.html create mode 100644 pages/37f363/index.html create mode 100644 pages/3869be/index.html create mode 100644 pages/39870b/index.html create mode 100644 pages/3adccf/index.html create mode 100644 pages/3aeda3/index.html create mode 100644 pages/3d30c9/index.html create mode 100644 pages/3dd4b2/index.html create mode 100644 pages/411579/index.html create mode 100644 pages/420ab6/index.html create mode 100644 pages/4595e1/index.html create mode 100644 pages/4db36a/index.html create mode 100644 pages/4f876a/index.html create mode 100644 pages/4f9b39/index.html create mode 100644 pages/514538/index.html create mode 100644 pages/548959/index.html create mode 100644 pages/55dc87/index.html create mode 100644 pages/59b0a9/index.html create mode 100644 pages/59f768/index.html create mode 100644 pages/5a96b7/index.html create mode 100644 pages/5d8ba8/index.html create mode 100644 pages/651b48/index.html create mode 100644 pages/6570ab/index.html create mode 100644 pages/669dfc/index.html create mode 100644 pages/6ab0a7/index.html create mode 100644 pages/6c1d02/index.html create mode 100644 pages/6cd2e1/index.html create mode 100644 pages/6ea216/index.html create mode 100644 pages/7071e6/index.html create mode 100644 pages/79c121/index.html create mode 100644 pages/79f386/index.html create mode 100644 pages/7c68cb/index.html create mode 100644 pages/7e542a/index.html create mode 100644 pages/7ee6cc/index.html create mode 100644 pages/82e5d7/index.html create mode 100644 pages/857c89/index.html create mode 100644 pages/86683c/index.html create mode 100644 pages/89d231/index.html create mode 100644 pages/8cb2e1/index.html create mode 100644 pages/8fbdb4/index.html create mode 100644 pages/907793/index.html create mode 100644 pages/935419/index.html create mode 100644 pages/977efe/index.html create mode 100644 pages/9b0a57/index.html create mode 100644 pages/9c451e/index.html create mode 100644 pages/9f55fd/index.html create mode 100644 pages/a0d7dc/index.html create mode 100644 pages/a96c0f/index.html create mode 100644 pages/aaf954/index.html create mode 100644 pages/b21fed/index.html create mode 100644 pages/b6bad0/index.html create mode 100644 pages/bd17b5/index.html create mode 100644 pages/bea5e2/index.html create mode 100644 pages/c3229c/index.html create mode 100644 pages/c38a8f/index.html create mode 100644 pages/c65eb4/index.html create mode 100644 pages/c76462/index.html create mode 100644 pages/c80e98/index.html create mode 100644 pages/c8fb65/index.html create mode 100644 pages/ca8e7a/index.html create mode 100644 pages/cb9380/index.html create mode 100644 pages/cb9d0f/index.html create mode 100644 pages/cd0789/index.html create mode 100644 pages/ce4afc/index.html create mode 100644 pages/d2a447/index.html create mode 100644 pages/d2d3e5/index.html create mode 100644 pages/d3b34e/index.html create mode 100644 pages/d8c80d/index.html create mode 100644 pages/d8cbeb/index.html create mode 100644 pages/d9fade/index.html create mode 100644 pages/db8380/index.html create mode 100644 pages/dc1698/index.html create mode 100644 pages/dd1044/index.html create mode 100644 pages/df7642/index.html create mode 100644 pages/e4a24e/index.html create mode 100644 pages/e9db87/index.html create mode 100644 pages/eae245/index.html create mode 100644 pages/ed7a6a/index.html create mode 100644 pages/f1d871/index.html create mode 100644 pages/f23ed2/index.html create mode 100644 pages/f7262c/index.html create mode 100644 pages/f85f1b/index.html create mode 100644 pages/f9b0df/index.html create mode 100644 pages/f9c14d/index.html create mode 100644 python/index.html create mode 100644 react/index.html create mode 100644 server/index.html create mode 100644 tags/index.html create mode 100644 tool/index.html create mode 100644 vue/index.html create mode 100644 web/index.html diff --git a/404.html b/404.html new file mode 100644 index 0000000000..f276491060 --- /dev/null +++ b/404.html @@ -0,0 +1,21 @@ + + + + + + Jacky's blog + + + + + + + + + + + +
404
这是一个Four-Oh-Four.
返回首页
+ + + diff --git a/android/index.html b/android/index.html new file mode 100644 index 0000000000..1390b0bf22 --- /dev/null +++ b/android/index.html @@ -0,0 +1,64 @@ + + + + + + android | Jacky's blog + + + + + + + + + + + +
+ + + diff --git a/archives/index.html b/archives/index.html new file mode 100644 index 0000000000..0705e8aa35 --- /dev/null +++ b/archives/index.html @@ -0,0 +1,204 @@ + + + + + + 归档 | Jacky's blog + + + + + + + + + + + +
+ + + diff --git a/assets/css/0.styles.8a8cb31f.css b/assets/css/0.styles.8a8cb31f.css new file mode 100644 index 0000000000..988f15b993 --- /dev/null +++ b/assets/css/0.styles.8a8cb31f.css @@ -0,0 +1 @@ +@import url(//at.alicdn.com/t/font_1678482_4tbhmh589x.css);.medium-zoom-overlay{z-index:100}.medium-zoom-overlay~img{z-index:101}.code-copy{color:#aaa;fill:#aaa;font-size:14px;display:inline-block;cursor:pointer}div[class*=aside-code] aside .code-copy,div[class*=language-] pre .code-copy{position:absolute;z-index:1000;top:7px;right:35px;opacity:0;font-size:16px}div[class*=aside-code] aside:hover .code-copy,div[class*=language-] pre:hover .code-copy{opacity:1}.content pre,.content pre[class*=language-]{overflow-y:hidden}div[class*=language-] pre,div[class*=language-] pre[class*=language-]{position:static!important}div[class~=language-text]:before{content:"text"}div[class~=language-yml]:before{content:"yml"}div[class*=language-] pre{-webkit-user-select:text;-moz-user-select:text;user-select:text}p code{-webkit-user-select:all;-moz-user-select:all;user-select:all}@keyframes message-move-in{0%{opacity:0;transform:translateY(-100%)}to{opacity:1;transform:translateY(0)}}#message-container .message.move-in{animation:message-move-in .3s ease-in-out}@keyframes message-move-out{0%{opacity:1;transform:translateY(0)}to{opacity:0;transform:translateY(-100%)}}#message-container .message.move-out{animation:message-move-out .3s ease-in-out;animation-fill-mode:forwards}#message-container .message{background:#fff;margin:10px 0;padding:0 10px;height:40px;box-shadow:0 0 10px 0 #ccc;font-size:14px;border-radius:3px;display:flex;align-items:center;transition:height .2s ease-in-out,margin .2s ease-in-out}#message-container{position:fixed;left:0;top:100px;right:0;display:flex;flex-direction:column;align-items:center}#message-container .message .text{color:#333;padding:0 20px 0 5px}.theme-code-block[data-v-4f1e9d0c]{display:none}.theme-code-block__active[data-v-4f1e9d0c]{display:block}.theme-code-block>pre[data-v-4f1e9d0c]{background-color:orange}@media (max-width:419px){.theme-code-group div[class*=language-][data-v-4f1e9d0c]{margin:0}}.theme-mode-light[data-v-2f5f1757]{--bodyBg:#f4f4f4;--mainBg:#fff;--sidebarBg:hsla(0,0%,100%,0.8);--blurBg:hsla(0,0%,100%,0.9);--customBlockBg:#f1f1f1;--textColor:#00323c;--textLightenColor:#0085ad;--borderColor:rgba(0,0,0,0.12);--codeBg:#f6f6f6;--codeColor:#525252}.theme-mode-light code[class*=language-][data-v-2f5f1757],.theme-mode-light pre[class*=language-][data-v-2f5f1757]{color:#000;background:none;text-shadow:0 1px #fff;font-family:Consolas,Monaco,Andale Mono,Ubuntu Mono,monospace;font-size:1em;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;hyphens:none}.theme-mode-light code[class*=language-][data-v-2f5f1757]::-moz-selection,.theme-mode-light code[class*=language-][data-v-2f5f1757] ::-moz-selection,.theme-mode-light pre[class*=language-][data-v-2f5f1757]::-moz-selection,.theme-mode-light pre[class*=language-][data-v-2f5f1757] ::-moz-selection{text-shadow:none;background:#b3d4fc}.theme-mode-light code[class*=language-][data-v-2f5f1757]::selection,.theme-mode-light code[class*=language-][data-v-2f5f1757] ::selection,.theme-mode-light pre[class*=language-][data-v-2f5f1757]::selection,.theme-mode-light pre[class*=language-][data-v-2f5f1757] ::selection{text-shadow:none;background:#b3d4fc}@media print{.theme-mode-light code[class*=language-][data-v-2f5f1757],.theme-mode-light pre[class*=language-][data-v-2f5f1757]{text-shadow:none}}.theme-mode-light pre[class*=language-][data-v-2f5f1757]{padding:1em;margin:.5em 0;overflow:auto}.theme-mode-light :not(pre)>code[class*=language-][data-v-2f5f1757],.theme-mode-light pre[class*=language-][data-v-2f5f1757]{background:#f5f2f0}.theme-mode-light :not(pre)>code[class*=language-][data-v-2f5f1757]{padding:.1em;border-radius:.3em;white-space:normal}.theme-mode-light .token.cdata[data-v-2f5f1757],.theme-mode-light .token.comment[data-v-2f5f1757],.theme-mode-light .token.doctype[data-v-2f5f1757],.theme-mode-light .token.prolog[data-v-2f5f1757]{color:#708090}.theme-mode-light .token.punctuation[data-v-2f5f1757]{color:#999}.theme-mode-light .namespace[data-v-2f5f1757]{opacity:.7}.theme-mode-light .token.boolean[data-v-2f5f1757],.theme-mode-light .token.constant[data-v-2f5f1757],.theme-mode-light .token.deleted[data-v-2f5f1757],.theme-mode-light .token.number[data-v-2f5f1757],.theme-mode-light .token.property[data-v-2f5f1757],.theme-mode-light .token.symbol[data-v-2f5f1757],.theme-mode-light .token.tag[data-v-2f5f1757]{color:#905}.theme-mode-light .token.attr-name[data-v-2f5f1757],.theme-mode-light .token.builtin[data-v-2f5f1757],.theme-mode-light .token.char[data-v-2f5f1757],.theme-mode-light .token.inserted[data-v-2f5f1757],.theme-mode-light .token.selector[data-v-2f5f1757],.theme-mode-light .token.string[data-v-2f5f1757]{color:#690}.theme-mode-light .language-css .token.string[data-v-2f5f1757],.theme-mode-light .style .token.string[data-v-2f5f1757],.theme-mode-light .token.entity[data-v-2f5f1757],.theme-mode-light .token.operator[data-v-2f5f1757],.theme-mode-light .token.url[data-v-2f5f1757]{color:#9a6e3a;background:hsla(0,0%,100%,.5)}.theme-mode-light .token.atrule[data-v-2f5f1757],.theme-mode-light .token.attr-value[data-v-2f5f1757],.theme-mode-light .token.keyword[data-v-2f5f1757]{color:#07a}.theme-mode-light .token.class-name[data-v-2f5f1757],.theme-mode-light .token.function[data-v-2f5f1757]{color:#dd4a68}.theme-mode-light .token.important[data-v-2f5f1757],.theme-mode-light .token.regex[data-v-2f5f1757],.theme-mode-light .token.variable[data-v-2f5f1757]{color:#e90}.theme-mode-light .token.bold[data-v-2f5f1757],.theme-mode-light .token.important[data-v-2f5f1757]{font-weight:700}.theme-mode-light .token.italic[data-v-2f5f1757]{font-style:italic}.theme-mode-light .token.entity[data-v-2f5f1757]{cursor:help}.theme-mode-light div[class*=language-] .highlight-lines .highlighted[data-v-2f5f1757],.theme-mode-light div[class*=language-].line-numbers-mode .highlight-lines .highlighted[data-v-2f5f1757]:before{background-color:hsla(0,0%,78.4%,.4)}.theme-mode-dark[data-v-2f5f1757]{--bodyBg:#27272b;--mainBg:#1e1e22;--sidebarBg:rgba(30,30,34,0.8);--blurBg:rgba(30,30,34,0.8);--customBlockBg:#27272b;--textColor:#9b9baa;--textLightenColor:#0085ad;--borderColor:#30363d;--codeBg:#252526;--codeColor:#fff}.theme-mode-dark code[class*=language-][data-v-2f5f1757],.theme-mode-dark pre[class*=language-][data-v-2f5f1757]{color:#ccc;background:none;text-shadow:none;font-family:Consolas,Monaco,Andale Mono,Ubuntu Mono,monospace;font-size:1em;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;hyphens:none}.theme-mode-dark pre[class*=language-][data-v-2f5f1757]{padding:1em;margin:.5em 0;overflow:auto}.theme-mode-dark :not(pre)>code[class*=language-][data-v-2f5f1757],.theme-mode-dark pre[class*=language-][data-v-2f5f1757]{background:#2d2d2d}.theme-mode-dark :not(pre)>code[class*=language-][data-v-2f5f1757]{padding:.1em;border-radius:.3em;white-space:normal}.theme-mode-dark .token.block-comment[data-v-2f5f1757],.theme-mode-dark .token.cdata[data-v-2f5f1757],.theme-mode-dark .token.comment[data-v-2f5f1757],.theme-mode-dark .token.doctype[data-v-2f5f1757],.theme-mode-dark .token.prolog[data-v-2f5f1757]{color:#999}.theme-mode-dark .token.punctuation[data-v-2f5f1757]{color:#ccc}.theme-mode-dark .token.attr-name[data-v-2f5f1757],.theme-mode-dark .token.deleted[data-v-2f5f1757],.theme-mode-dark .token.namespace[data-v-2f5f1757],.theme-mode-dark .token.tag[data-v-2f5f1757]{color:#e2777a}.theme-mode-dark .token.function-name[data-v-2f5f1757]{color:#6196cc}.theme-mode-dark .token.boolean[data-v-2f5f1757],.theme-mode-dark .token.function[data-v-2f5f1757],.theme-mode-dark .token.number[data-v-2f5f1757]{color:#f08d49}.theme-mode-dark .token.class-name[data-v-2f5f1757],.theme-mode-dark .token.constant[data-v-2f5f1757],.theme-mode-dark .token.property[data-v-2f5f1757],.theme-mode-dark .token.symbol[data-v-2f5f1757]{color:#f8c555}.theme-mode-dark .token.atrule[data-v-2f5f1757],.theme-mode-dark .token.builtin[data-v-2f5f1757],.theme-mode-dark .token.important[data-v-2f5f1757],.theme-mode-dark .token.keyword[data-v-2f5f1757],.theme-mode-dark .token.selector[data-v-2f5f1757]{color:#cc99cd}.theme-mode-dark .token.attr-value[data-v-2f5f1757],.theme-mode-dark .token.char[data-v-2f5f1757],.theme-mode-dark .token.regex[data-v-2f5f1757],.theme-mode-dark .token.string[data-v-2f5f1757],.theme-mode-dark .token.variable[data-v-2f5f1757]{color:#7ec699}.theme-mode-dark .token.entity[data-v-2f5f1757],.theme-mode-dark .token.operator[data-v-2f5f1757],.theme-mode-dark .token.url[data-v-2f5f1757]{color:#67cdcc}.theme-mode-dark .language-css .token.string[data-v-2f5f1757],.theme-mode-dark .style .token.string[data-v-2f5f1757],.theme-mode-dark .token.entity[data-v-2f5f1757],.theme-mode-dark .token.operator[data-v-2f5f1757],.theme-mode-dark .token.url[data-v-2f5f1757]{background:none}.theme-mode-dark .token.bold[data-v-2f5f1757],.theme-mode-dark .token.important[data-v-2f5f1757]{font-weight:700}.theme-mode-dark .token.italic[data-v-2f5f1757]{font-style:italic}.theme-mode-dark .token.entity[data-v-2f5f1757]{cursor:help}.theme-mode-dark .token.inserted[data-v-2f5f1757]{color:green}.theme-mode-read[data-v-2f5f1757]{--bodyBg:#ececcc;--mainBg:#f5f5d5;--sidebarBg:rgba(245,245,213,0.8);--blurBg:rgba(245,245,213,0.9);--customBlockBg:#ececcc;--textColor:#704214;--textLightenColor:#963;--borderColor:rgba(0,0,0,0.15);--codeBg:#282c34;--codeColor:#fff}.theme-mode-read code[class*=language-][data-v-2f5f1757],.theme-mode-read pre[class*=language-][data-v-2f5f1757]{color:#ccc;background:none;text-shadow:none;font-family:Consolas,Monaco,Andale Mono,Ubuntu Mono,monospace;font-size:1em;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;hyphens:none}.theme-mode-read pre[class*=language-][data-v-2f5f1757]{padding:1em;margin:.5em 0;overflow:auto}.theme-mode-read :not(pre)>code[class*=language-][data-v-2f5f1757],.theme-mode-read pre[class*=language-][data-v-2f5f1757]{background:#2d2d2d}.theme-mode-read :not(pre)>code[class*=language-][data-v-2f5f1757]{padding:.1em;border-radius:.3em;white-space:normal}.theme-mode-read .token.block-comment[data-v-2f5f1757],.theme-mode-read .token.cdata[data-v-2f5f1757],.theme-mode-read .token.comment[data-v-2f5f1757],.theme-mode-read .token.doctype[data-v-2f5f1757],.theme-mode-read .token.prolog[data-v-2f5f1757]{color:#999}.theme-mode-read .token.punctuation[data-v-2f5f1757]{color:#ccc}.theme-mode-read .token.attr-name[data-v-2f5f1757],.theme-mode-read .token.deleted[data-v-2f5f1757],.theme-mode-read .token.namespace[data-v-2f5f1757],.theme-mode-read .token.tag[data-v-2f5f1757]{color:#e2777a}.theme-mode-read .token.function-name[data-v-2f5f1757]{color:#6196cc}.theme-mode-read .token.boolean[data-v-2f5f1757],.theme-mode-read .token.function[data-v-2f5f1757],.theme-mode-read .token.number[data-v-2f5f1757]{color:#f08d49}.theme-mode-read .token.class-name[data-v-2f5f1757],.theme-mode-read .token.constant[data-v-2f5f1757],.theme-mode-read .token.property[data-v-2f5f1757],.theme-mode-read .token.symbol[data-v-2f5f1757]{color:#f8c555}.theme-mode-read .token.atrule[data-v-2f5f1757],.theme-mode-read .token.builtin[data-v-2f5f1757],.theme-mode-read .token.important[data-v-2f5f1757],.theme-mode-read .token.keyword[data-v-2f5f1757],.theme-mode-read .token.selector[data-v-2f5f1757]{color:#cc99cd}.theme-mode-read .token.attr-value[data-v-2f5f1757],.theme-mode-read .token.char[data-v-2f5f1757],.theme-mode-read .token.regex[data-v-2f5f1757],.theme-mode-read .token.string[data-v-2f5f1757],.theme-mode-read .token.variable[data-v-2f5f1757]{color:#7ec699}.theme-mode-read .token.entity[data-v-2f5f1757],.theme-mode-read .token.operator[data-v-2f5f1757],.theme-mode-read .token.url[data-v-2f5f1757]{color:#67cdcc}.theme-mode-read .language-css .token.string[data-v-2f5f1757],.theme-mode-read .style .token.string[data-v-2f5f1757],.theme-mode-read .token.entity[data-v-2f5f1757],.theme-mode-read .token.operator[data-v-2f5f1757],.theme-mode-read .token.url[data-v-2f5f1757]{background:none}.theme-mode-read .token.bold[data-v-2f5f1757],.theme-mode-read .token.important[data-v-2f5f1757]{font-weight:700}.theme-mode-read .token.italic[data-v-2f5f1757]{font-style:italic}.theme-mode-read .token.entity[data-v-2f5f1757]{cursor:help}.theme-mode-read .token.inserted[data-v-2f5f1757]{color:green}.theme-style-line.theme-mode-light[data-v-2f5f1757]{--bodyBg:#fff}.theme-style-line.theme-mode-dark[data-v-2f5f1757]{--bodyBg:#1e1e22}.theme-style-line.theme-mode-read[data-v-2f5f1757]{--bodyBg:#f5f5d5}.theme-code-group[data-v-2f5f1757],.theme-code-group__nav[data-v-2f5f1757]{background-color:var(--codeBg);padding-bottom:22px;border-radius:6px;padding-left:10px;padding-top:10px}.theme-code-group__nav[data-v-2f5f1757]{margin-bottom:-35px}.theme-code-group__ul[data-v-2f5f1757]{margin:auto 0;padding-left:0;display:inline-flex;list-style:none}.theme-code-group__li[data-v-2f5f1757],.theme-code-group__nav-tab[data-v-2f5f1757]{border:0;padding:5px;cursor:pointer;background-color:transparent;font-size:.85em;line-height:1.4;color:var(--codeColor);font-weight:600;opacity:.85}.theme-code-group__nav-tab-active[data-v-2f5f1757]{border-bottom:1px solid #11a8cd;opacity:1}.pre-blank[data-v-2f5f1757]{color:#11a8cd}body .theme-vdoing-content code{color:var(--textLightenColor);padding:.25rem .5rem;margin:0;font-size:.9em;background-color:hsla(0,0%,39.2%,.08);border-radius:3px}body .theme-vdoing-content code .token.deleted{color:#ec5975}body .theme-vdoing-content code .token.inserted{color:#11a8cd}body .theme-vdoing-content pre,body .theme-vdoing-content pre[class*=language-]{line-height:1.4;padding:1.25rem 1.5rem;margin:.85rem 0;background-color:#282c34;border-radius:6px;overflow:auto}body .theme-vdoing-content pre[class*=language-] code,body .theme-vdoing-content pre code{color:var(--codeColor);padding:0;background-color:transparent;border-radius:0}div[class*=language-]{position:relative;background-color:var(--codeBg);border-radius:6px}div[class*=language-] .highlight-lines{-webkit-user-select:none;user-select:none;padding-top:1.3rem;position:absolute;top:0;left:0;width:100%;line-height:1.4}div[class*=language-] .highlight-lines .highlighted{background-color:rgba(0,0,0,.3)}div[class*=language-] pre,div[class*=language-] pre[class*=language-]{background:transparent;position:relative!important;z-index:1}div[class*=language-]:before{position:absolute;z-index:3;top:.8em;right:1em;font-size:.8rem;color:hsla(0,0%,58.8%,.7)}div[class*=language-]:not(.line-numbers-mode) .line-numbers-wrapper{display:none}div[class*=language-].line-numbers-mode .highlight-lines .highlighted{position:relative}div[class*=language-].line-numbers-mode .highlight-lines .highlighted:before{content:" ";position:absolute;z-index:3;left:0;top:0;display:block;width:2.5rem;height:100%;background-color:rgba(0,0,0,.3)}div[class*=language-].line-numbers-mode pre{padding-left:3.5rem;vertical-align:middle}div[class*=language-].line-numbers-mode .line-numbers-wrapper{position:absolute;top:0;width:2.5rem;text-align:center;color:hsla(0,0%,49.8%,.5);padding:1.25rem 0;line-height:1.4}div[class*=language-].line-numbers-mode .line-numbers-wrapper br{-webkit-user-select:none;user-select:none}div[class*=language-].line-numbers-mode .line-numbers-wrapper .line-number{position:relative;z-index:4;-webkit-user-select:none;user-select:none;font-size:.85em}div[class*=language-].line-numbers-mode:after{content:"";position:absolute;z-index:2;top:0;left:0;width:2.5rem;height:100%;border-radius:6px 0 0 6px;border-right:1px solid var(--borderColor);background-color:var(--codeBg)}div[class~=language-js]:before{content:"js"}div[class~=language-ts]:before{content:"ts"}div[class~=language-html]:before{content:"html"}div[class~=language-md]:before{content:"md"}div[class~=language-vue]:before{content:"vue"}div[class~=language-css]:before{content:"css"}div[class~=language-sass]:before{content:"sass"}div[class~=language-scss]:before{content:"scss"}div[class~=language-less]:before{content:"less"}div[class~=language-stylus]:before{content:"stylus"}div[class~=language-go]:before{content:"go"}div[class~=language-java]:before{content:"java"}div[class~=language-c]:before{content:"c"}div[class~=language-sh]:before{content:"sh"}div[class~=language-yaml]:before{content:"yaml"}div[class~=language-py]:before{content:"py"}div[class~=language-docker]:before{content:"docker"}div[class~=language-dockerfile]:before{content:"dockerfile"}div[class~=language-makefile]:before{content:"makefile"}div[class~=language-javascript]:before{content:"js"}div[class~=language-typescript]:before{content:"ts"}div[class~=language-markup]:before{content:"html"}div[class~=language-markdown]:before{content:"md"}div[class~=language-json]:before{content:"json"}div[class~=language-ruby]:before{content:"rb"}div[class~=language-python]:before{content:"py"}div[class~=language-bash]:before{content:"sh"}div[class~=language-php]:before{content:"php"}.custom-block .custom-block-title{font-weight:600;margin-bottom:.2rem}.custom-block p{margin:0}.custom-block.danger,.custom-block.note,.custom-block.tip,.custom-block.warning{padding:.5rem 1.5rem;border-left-width:.5rem;border-left-style:solid;margin:1rem 0}.custom-block.tip{background-color:#f3f5f7;border-color:#42b983;color:#215d42}.custom-block.warning{background-color:#fff7d0;border-color:#e7c000;color:#6b5900}.custom-block.warning .custom-block-title{color:#b29400}.custom-block.warning a{color:var(--textColor)}.custom-block.danger{background-color:#ffe6e6;border-color:#c00;color:#4d0000}.custom-block.danger .custom-block-title{color:#900}.custom-block.danger a{color:var(--textColor)}.custom-block.note{background-color:#e8f5fa;border-color:#157bae;color:#0d4a68}.custom-block.right{color:var(--textColor);font-size:.9rem;text-align:right}.custom-block.theorem{margin:1rem 0;padding:.8rem 1.5rem;border-radius:2px;background-color:var(--customBlockBg)}.custom-block.theorem .title{font-weight:700;margin:.5rem 0}.custom-block.details{display:block;position:relative;border-radius:2px;margin:1em 0;padding:1.6em;background-color:var(--customBlockBg)}.custom-block.details p{margin:.8rem 0}.custom-block.details h4{margin-top:0}.custom-block.details figure:last-child,.custom-block.details p:last-child{margin-bottom:0;padding-bottom:0}.custom-block.details summary{outline:none;cursor:pointer}.custom-block.details summary:hover{color:#11a8cd}.theme-mode-dark .custom-block.warning{background-color:rgba(255,247,208,.2);color:#e7c000}.theme-mode-dark .custom-block.warning .custom-block-title{color:#ffdc2f}.theme-mode-dark .custom-block.tip{background-color:rgba(243,245,247,.2);color:#42b983}.theme-mode-dark .custom-block.danger{background-color:rgba(255,230,230,.4);color:maroon}.theme-mode-dark .custom-block.danger a{color:#11a8cd}.theme-mode-dark .custom-block.note{background-color:rgba(243,245,247,.2);color:#157bae}.arrow{display:inline-block;width:0;height:0}.arrow.up{border-bottom:6px solid #ccc}.arrow.down,.arrow.up{border-left:4px solid transparent;border-right:4px solid transparent}.arrow.down{border-top:6px solid #ccc}.arrow.right{border-left:6px solid #ccc}.arrow.left,.arrow.right{border-top:4px solid transparent;border-bottom:4px solid transparent}.arrow.left{border-right:6px solid #ccc}.theme-vdoing-content:not(.custom){max-width:860px}.table-of-contents .badge{vertical-align:middle}.center-container{text-align:center}.center-container>h1,.center-container>h2,.center-container>h3,.center-container>h4,.center-container>h5,.center-container>h6{margin-top:-3.1rem;padding-top:4.6rem;margin-bottom:0}.center-container>h1 a.header-anchor,.center-container>h2 a.header-anchor,.center-container>h3 a.header-anchor,.center-container>h4 a.header-anchor,.center-container>h5 a.header-anchor,.center-container>h6 a.header-anchor{float:none;padding-right:0;margin-left:-.9rem}.cardListContainer{margin:.7rem 0}.cardListContainer>:not(.card-list){display:none}.cardListContainer .card-list{margin:-.35rem;display:flex;flex-wrap:wrap;align-items:flex-start}.cardListContainer .card-list .card-item{width:calc(33.33333% - .7rem);margin:.35rem;background:var(--bodyBg);border-radius:3px;color:var(--textColor);display:flex;box-shadow:1px 1px 2px 0 rgba(0,0,0,.06);transition:all .4s}.cardListContainer .card-list .card-item:hover{text-decoration:none;box-shadow:0 10px 20px -10px var(--randomColor,rgba(0,0,0,.15));transform:translateY(-3px) scale(1.01)}.cardListContainer .card-list .card-item:hover img{box-shadow:3px 2px 7px rgba(0,0,0,.15)}.cardListContainer .card-list .card-item:hover div p{text-shadow:3px 2px 5px rgba(0,0,0,.15)}.cardListContainer .card-list .card-item img{width:60px;height:60px;border-radius:50%;border:2px solid #fff;margin:1rem 0 1rem 1rem;box-shadow:3px 2px 5px rgba(0,0,0,.08);transition:all .4s}.cardListContainer .card-list .card-item div{flex:1;display:inline-block;float:right;padding:1rem 0}.cardListContainer .card-list .card-item div p{margin:0;padding:0 1rem;transition:text-shadow .4s;text-align:center}.cardListContainer .card-list .card-item div .name{margin:.2rem 0 .3rem}.cardListContainer .card-list .card-item div .desc{font-size:.8rem;line-height:1.1rem;opacity:.8;margin-bottom:.2rem}.cardListContainer .card-list .card-item.row-1{width:calc(100% - .7rem)}.cardListContainer .card-list .card-item.row-1 img{margin-left:2rem}.cardListContainer .card-list .card-item.row-2{width:calc(50% - .7rem)}.cardListContainer .card-list .card-item.row-2 img{margin-left:1.5rem}.cardListContainer .card-list .card-item.row-3{width:calc(33.33333% - .7rem)}.cardListContainer .card-list .card-item.row-4{width:calc(25% - .7rem)}.cardImgListContainer{margin:1rem 0}.cardImgListContainer>:not(.card-list){display:none}.cardImgListContainer .card-list{margin:-.5rem;display:flex;flex-wrap:wrap;align-items:flex-start}.cardImgListContainer .card-list .card-item{width:calc(33.33333% - 1rem);margin:.5rem;background:var(--mainBg);border:1px solid rgba(0,0,0,.1);box-sizing:border-box;border-radius:3px;overflow:hidden;color:var(--textColor);box-shadow:2px 2px 10px rgba(0,0,0,.04);display:flex;flex-direction:column;justify-content:flex-start;align-items:stretch;align-content:stretch;transition:all .4s}.cardImgListContainer .card-list .card-item:hover{box-shadow:1px 1px 20px rgba(0,0,0,.1);transform:translateY(-3px)}.cardImgListContainer .card-list .card-item .box-img{overflow:hidden;position:relative;background:#eee}.cardImgListContainer .card-list .card-item .box-img img{display:block;width:100%;height:100%;transition:all .3s}.cardImgListContainer .card-list .card-item a{color:var(--textColor);transition:color .3s}.cardImgListContainer .card-list .card-item a:hover{text-decoration:none}.cardImgListContainer .card-list .card-item .box-info{padding:.8rem 1rem}.cardImgListContainer .card-list .card-item .box-info p{margin:0}.cardImgListContainer .card-list .card-item .box-info .desc{margin-top:.3rem;opacity:.8;font-size:.9rem;line-height:1.1rem;overflow:hidden;white-space:normal;text-overflow:ellipsis;display:-webkit-box;-webkit-box-orient:vertical}.cardImgListContainer .card-list .card-item .box-footer{overflow:hidden;padding:.8rem 1rem;border-top:1px solid rgba(0,0,0,.1)}.cardImgListContainer .card-list .card-item .box-footer img{width:1.8rem;height:1.8rem;border-radius:50%;float:left}.cardImgListContainer .card-list .card-item .box-footer span{line-height:1.8rem;float:left;margin-left:.6rem;font-size:.8rem}.cardImgListContainer .card-list .card-item.row-1{width:calc(100% - 1rem)}.cardImgListContainer .card-list .card-item.row-2{width:calc(50% - 1rem)}.cardImgListContainer .card-list .card-item.row-3{width:calc(33.33333% - 1rem)}.cardImgListContainer .card-list .card-item.row-4{width:calc(25% - 1rem)}.theme-mode-dark .cardImgListContainer .card-list .card-item,.theme-mode-dark .cardImgListContainer .card-list .card-item .box-footer{border-color:var(--borderColor)}@media (max-width:900px){.cardListContainer .card-list .card-item.row-4{width:calc(33.33333% - .7rem)}.cardImgListContainer .card-list .card-item.row-4{width:calc(33.33333% - 1rem)}}@media (max-width:720px){.cardListContainer .card-list .card-item.row-3,.cardListContainer .card-list .card-item.row-4{width:calc(50% - .7rem)}.cardListContainer .card-list .card-item.row-3 img,.cardListContainer .card-list .card-item.row-4 img{margin-left:1.5rem}.cardImgListContainer .card-list .card-item.row-3,.cardImgListContainer .card-list .card-item.row-4{width:calc(50% - 1rem)}}@media (max-width:500px){.cardListContainer .card-list .card-item.row-1,.cardListContainer .card-list .card-item.row-2,.cardListContainer .card-list .card-item.row-3,.cardListContainer .card-list .card-item.row-4{width:calc(100% - .7rem)}.cardListContainer .card-list .card-item.row-1 img,.cardListContainer .card-list .card-item.row-2 img,.cardListContainer .card-list .card-item.row-3 img,.cardListContainer .card-list .card-item.row-4 img{margin-left:1.5rem}.cardImgListContainer .card-list .card-item.row-1,.cardImgListContainer .card-list .card-item.row-2,.cardImgListContainer .card-list .card-item.row-3,.cardImgListContainer .card-list .card-item.row-4{width:calc(100% - 1rem)}}body,html{padding:0;margin:0}body{font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,Fira Sans,Droid Sans,Helvetica Neue,sans-serif;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;-webkit-tap-highlight-color:transparent;font-size:16px;color:#2c3e50;background:var(--bodyBg)}a,button,input{outline:none;-webkit-tap-highlight-color:rgba(255,255,255,0);-webkit-focus-ring-color:transparent}@media (min-width:719px){::-webkit-scrollbar{width:6px;height:5px}::-webkit-scrollbar-track-piece{background-color:rgba(0,0,0,.15);-webkit-border-radius:3px}::-webkit-scrollbar-thumb:vertical{height:5px;background-color:rgba(0,0,0,.28);-webkit-border-radius:3px}::-webkit-scrollbar-thumb:horizontal{width:5px;background-color:rgba(0,0,0,.28);-webkit-border-radius:3px}}.card-box{border-radius:5px;background:var(--mainBg);box-shadow:0 0 4px 0 rgba(0,0,0,.1);transition:box-shadow .5s}.card-box:hover{box-shadow:0 1px 15px 0 rgba(0,0,0,.1)}@media (max-width:719px){.theme-style-line{margin-left:-1px;margin-right:-1px}}.theme-style-line .card-box{box-shadow:0 0;border:1px solid var(--borderColor)}.blur{-webkit-backdrop-filter:saturate(200%) blur(20px);backdrop-filter:saturate(200%) blur(20px)}.custom-page{min-height:calc(100vh - 3.6rem);padding-top:3.6rem;padding-bottom:.9rem}.custom-page .theme-vdoing-wrapper{margin:0 auto}body .search-box input{background-color:transparent;color:var(--textColor);border:1px solid var(--borderColor,#ccc)}@media (max-width:959px){body .search-box input{border-color:transparent}}.page{transition:padding .2s ease;padding-left:.8rem}.navbar{position:fixed;z-index:20;top:0;left:0;right:0;height:3.6rem;background-color:var(--blurBg);box-sizing:border-box;box-shadow:0 2px 5px rgba(0,0,0,.06)}.sidebar-mask{top:0;width:100vw;height:100vh}.sidebar-hover-trigger,.sidebar-mask{position:fixed;z-index:12;left:0;display:none}.sidebar-hover-trigger{top:8.1rem;bottom:0;width:24px}.sidebar{font-size:16px;background-color:var(--sidebarBg);width:18rem;position:fixed;z-index:13;margin:0;top:3.6rem;left:0;bottom:0;box-sizing:border-box;border-right:1px solid var(--borderColor);overflow-y:auto;transform:translateX(-100%);transition:transform .2s}@media (max-width:719px){.sidebar{background-color:var(--mainBg)}}.theme-vdoing-content:not(.custom){word-wrap:break-word}.theme-vdoing-content:not(.custom) a:hover{text-decoration:underline}.theme-vdoing-content:not(.custom) p.demo{padding:1rem 1.5rem;border:1px solid #ddd;border-radius:4px}.theme-vdoing-content:not(.custom) img{max-width:100%}.theme-vdoing-content.custom{padding:0;margin:0}.theme-vdoing-content.custom img{max-width:100%}a{font-weight:500;text-decoration:none}a,p a code{color:#11a8cd}p a code{font-weight:400}kbd{background:#eee;border:.15rem solid #ddd;border-bottom:.25rem solid #ddd;border-radius:.15rem;padding:0 .15em}blockquote{font-size:1rem;opacity:.75;border-left:.2rem solid hsla(0,0%,39.2%,.3);margin:1rem 0;padding:.25rem 0 .25rem 1rem}blockquote>p{margin:0}ol,ul{padding-left:1.2em}strong{font-weight:600}h1,h2,h3,h4,h5,h6{font-weight:600;line-height:1.25}.theme-vdoing-content:not(.custom)>h1,.theme-vdoing-content:not(.custom)>h2,.theme-vdoing-content:not(.custom)>h3,.theme-vdoing-content:not(.custom)>h4,.theme-vdoing-content:not(.custom)>h5,.theme-vdoing-content:not(.custom)>h6{margin-top:-3.1rem;padding-top:4.6rem;margin-bottom:0}.theme-vdoing-content:not(.custom)>h1:first-child,.theme-vdoing-content:not(.custom)>h2:first-child,.theme-vdoing-content:not(.custom)>h3:first-child,.theme-vdoing-content:not(.custom)>h4:first-child,.theme-vdoing-content:not(.custom)>h5:first-child,.theme-vdoing-content:not(.custom)>h6:first-child{margin-bottom:1rem}.theme-vdoing-content:not(.custom)>h1:first-child+.custom-block,.theme-vdoing-content:not(.custom)>h1:first-child+p,.theme-vdoing-content:not(.custom)>h1:first-child+pre,.theme-vdoing-content:not(.custom)>h2:first-child+.custom-block,.theme-vdoing-content:not(.custom)>h2:first-child+p,.theme-vdoing-content:not(.custom)>h2:first-child+pre,.theme-vdoing-content:not(.custom)>h3:first-child+.custom-block,.theme-vdoing-content:not(.custom)>h3:first-child+p,.theme-vdoing-content:not(.custom)>h3:first-child+pre,.theme-vdoing-content:not(.custom)>h4:first-child+.custom-block,.theme-vdoing-content:not(.custom)>h4:first-child+p,.theme-vdoing-content:not(.custom)>h4:first-child+pre,.theme-vdoing-content:not(.custom)>h5:first-child+.custom-block,.theme-vdoing-content:not(.custom)>h5:first-child+p,.theme-vdoing-content:not(.custom)>h5:first-child+pre,.theme-vdoing-content:not(.custom)>h6:first-child+.custom-block,.theme-vdoing-content:not(.custom)>h6:first-child+p,.theme-vdoing-content:not(.custom)>h6:first-child+pre{margin-top:2rem}h1:focus .header-anchor,h1:hover .header-anchor,h2:focus .header-anchor,h2:hover .header-anchor,h3:focus .header-anchor,h3:hover .header-anchor,h4:focus .header-anchor,h4:hover .header-anchor,h5:focus .header-anchor,h5:hover .header-anchor,h6:focus .header-anchor,h6:hover .header-anchor{opacity:1}.theme-vdoing-content:not(.custom)>.custom-block:first-child,.theme-vdoing-content:not(.custom)>p:first-child,.theme-vdoing-content:not(.custom)>pre:first-child{margin-top:2rem}h1{font-size:1.9rem}.theme-vdoing-content:not(.custom)>h1:first-child{display:none}h2{font-size:1.5rem;padding-bottom:.3rem;border-bottom:1px solid var(--borderColor)}h3{font-size:1.35rem}.page h4{font-size:1.25rem}.page h5{font-size:1.15rem}.page h6{font-size:1.05rem}a.header-anchor{font-size:.85em;float:left;margin-left:-.87em;padding-right:.23em;margin-top:.125em;opacity:0}a.header-anchor:focus,a.header-anchor:hover{text-decoration:none}.line-number,code,kbd{font-family:source-code-pro,Menlo,Monaco,Consolas,Courier New,monospace}ol,p,ul{line-height:1.7}hr{border:0;border-top:1px solid var(--borderColor)}table{border-collapse:collapse;margin:1rem 0;overflow-x:auto;width:100%;display:inline-table}@media (max-width:719px){table{display:block}}tr{border-top:1px solid var(--borderColor)}tr:nth-child(2n){background-color:hsla(0,0%,58.8%,.1)}td,th{border:1px solid var(--borderColor);padding:.6em 1em}@media (max-width:719px){td,th{padding:.3em .5em}}td a,th a{word-break:break-all}.theme-container{color:var(--textColor);min-height:100vh}.theme-container.sidebar-open .sidebar-mask{display:block}.theme-container.no-navbar .theme-vdoing-content:not(.custom)>h1,.theme-container.no-navbar h2,.theme-container.no-navbar h3,.theme-container.no-navbar h4,.theme-container.no-navbar h5,.theme-container.no-navbar h6{margin-top:1.5rem;padding-top:0}.theme-container.no-navbar .sidebar{top:0}@media (min-width:720px){.theme-container.no-sidebar .sidebar{display:none}.theme-container.no-sidebar .page{padding-left:0}}@media (max-width:959px){.sidebar{font-size:15px}}@media (max-width:719px){.sidebar{width:17.099999999999998rem}}@media (min-width:720px) and (max-width:959px){.sidebar{width:16.2rem}.theme-container.sidebar-open .page{padding-left:17rem!important}}@media (max-width:719px){.sidebar{top:0;height:100vh;padding-top:3.6rem;transform:translateX(-100%);transition:transform .2s ease}.page{padding-left:0}.theme-container.sidebar-open .sidebar{transform:translateX(0)}.theme-container.sidebar-open .sidebar-mask{display:block}.theme-container.no-navbar .sidebar{padding-top:0}}@media (max-width:419px){h1{font-size:1.9rem}.theme-vdoing-content div[class*=language-]{margin:.85rem -1.5rem;border-radius:0}}@media (min-width:720px){.theme-container .sidebar-hover-trigger{display:block}.theme-container .sidebar-hover-trigger:hover~.sidebar,.theme-container:not(.sidebar-open) .sidebar-hover-trigger~.sidebar:hover{transform:translateX(0);z-index:100}.theme-container.sidebar-open .sidebar-mask{display:none}.theme-container.sidebar-open .sidebar{transform:translateX(0)}.theme-container.sidebar-open .sidebar-button{left:18rem}.theme-container.sidebar-open .page{padding-left:18.8rem;padding-right:.8rem}.theme-container.sidebar-open .sidebar-hover-trigger{display:none}.theme-container.have-rightmenu .page{padding-right:250px}.theme-container.no-sidebar .page{padding-left:0!important}.theme-container.no-sidebar .sidebar-hover-trigger{display:none}.theme-container.hide-navbar .sidebar-hover-trigger{top:4.5rem}.theme-container.hide-navbar .sidebar{top:0}.theme-container.no-sidebar .sidebar-button{display:none}}@media print{.buttons,.navbar,.sidebar{display:none}.page{padding-top:0!important}}@media (min-width:720px) and (max-width:959px){.theme-container.sidebar-open:not(.on-sidebar) .sidebar-button{left:12.6rem}}.gt-container .gt-ico-tip:after{content:"。( Win + . ) 或 ( ⌃ + ⌘ + ␣ ) 打开表情";color:#999;font-size:.8rem}.gt-container .gt-meta{border-color:var(--borderColor)!important}.gt-container .gt-comments-null{color:var(--textColor);opacity:.5}.gt-container .gt-header-textarea{color:var(--textColor);background:hsla(0,0%,70.6%,.1)!important}.gt-container .gt-btn{border-color:#11a8cd!important;background-color:#11a8cd!important}.gt-container .gt-btn-preview{background-color:hsla(0,0%,100%,0)!important;color:#11a8cd!important}.gt-container a{color:#11a8cd!important}.gt-container .gt-svg svg{fill:#11a8cd!important}.gt-container .gt-comment-admin .gt-comment-content,.gt-container .gt-comment-content{background-color:hsla(0,0%,58.8%,.1)!important}.gt-container .gt-comment-admin .gt-comment-content:hover,.gt-container .gt-comment-content:hover{box-shadow:0 0 25px hsla(0,0%,58.8%,.5)!important}.gt-container .gt-comment-admin .gt-comment-content .gt-comment-body,.gt-container .gt-comment-content .gt-comment-body{color:var(--textColor)!important}.qq{position:relative}.qq:after{content:"可撩";background:#11a8cd;color:#fff;padding:0 5px;border-radius:10px;font-size:12px;position:absolute;top:-4px;right:-35px;transform:scale(.85)}body .vuepress-plugin-demo-block__wrapper,body .vuepress-plugin-demo-block__wrapper .vuepress-plugin-demo-block__display{border-color:hsla(0,0%,62.7%,.3)}body .vuepress-plugin-demo-block__wrapper .vuepress-plugin-demo-block__footer:hover .vuepress-plugin-demo-block__expand:before{border-top-color:#11a8cd!important;border-bottom-color:#11a8cd!important}body .vuepress-plugin-demo-block__wrapper .vuepress-plugin-demo-block__footer:hover svg{fill:#11a8cd!important}.suggestions{overflow:auto;max-height:calc(100vh - 6rem)}@media (max-width:719px){.suggestions{width:90vw;min-width:90vw!important;margin-right:-20px}}.suggestions .highlight{color:#11a8cd;font-weight:700}#nprogress{pointer-events:none}#nprogress .bar{background:#11a8cd;position:fixed;z-index:1031;top:0;left:0;width:100%;height:2px}#nprogress .peg{display:block;position:absolute;right:0;width:100px;height:100%;box-shadow:0 0 10px #11a8cd,0 0 5px #11a8cd;opacity:1;transform:rotate(3deg) translateY(-4px)}#nprogress .spinner{display:block;position:fixed;z-index:1031;top:15px;right:15px}#nprogress .spinner-icon{width:18px;height:18px;box-sizing:border-box;border-color:#11a8cd transparent transparent #11a8cd;border-style:solid;border-width:2px;border-radius:50%;animation:nprogress-spinner .4s linear infinite}.nprogress-custom-parent{overflow:hidden;position:relative}.nprogress-custom-parent #nprogress .bar,.nprogress-custom-parent #nprogress .spinner{position:absolute}@keyframes nprogress-spinner{0%{transform:rotate(0deg)}to{transform:rotate(1turn)}}.theme-mode-light[data-v-5fd4ef0c]{--bodyBg:#f4f4f4;--mainBg:#fff;--sidebarBg:hsla(0,0%,100%,0.8);--blurBg:hsla(0,0%,100%,0.9);--customBlockBg:#f1f1f1;--textColor:#00323c;--textLightenColor:#0085ad;--borderColor:rgba(0,0,0,0.12);--codeBg:#f6f6f6;--codeColor:#525252}.theme-mode-light code[class*=language-][data-v-5fd4ef0c],.theme-mode-light pre[class*=language-][data-v-5fd4ef0c]{color:#000;background:none;text-shadow:0 1px #fff;font-family:Consolas,Monaco,Andale Mono,Ubuntu Mono,monospace;font-size:1em;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;hyphens:none}.theme-mode-light code[class*=language-][data-v-5fd4ef0c]::-moz-selection,.theme-mode-light code[class*=language-][data-v-5fd4ef0c] ::-moz-selection,.theme-mode-light pre[class*=language-][data-v-5fd4ef0c]::-moz-selection,.theme-mode-light pre[class*=language-][data-v-5fd4ef0c] ::-moz-selection{text-shadow:none;background:#b3d4fc}.theme-mode-light code[class*=language-][data-v-5fd4ef0c]::selection,.theme-mode-light code[class*=language-][data-v-5fd4ef0c] ::selection,.theme-mode-light pre[class*=language-][data-v-5fd4ef0c]::selection,.theme-mode-light pre[class*=language-][data-v-5fd4ef0c] ::selection{text-shadow:none;background:#b3d4fc}@media print{.theme-mode-light code[class*=language-][data-v-5fd4ef0c],.theme-mode-light pre[class*=language-][data-v-5fd4ef0c]{text-shadow:none}}.theme-mode-light pre[class*=language-][data-v-5fd4ef0c]{padding:1em;margin:.5em 0;overflow:auto}.theme-mode-light :not(pre)>code[class*=language-][data-v-5fd4ef0c],.theme-mode-light pre[class*=language-][data-v-5fd4ef0c]{background:#f5f2f0}.theme-mode-light :not(pre)>code[class*=language-][data-v-5fd4ef0c]{padding:.1em;border-radius:.3em;white-space:normal}.theme-mode-light .token.cdata[data-v-5fd4ef0c],.theme-mode-light .token.comment[data-v-5fd4ef0c],.theme-mode-light .token.doctype[data-v-5fd4ef0c],.theme-mode-light .token.prolog[data-v-5fd4ef0c]{color:#708090}.theme-mode-light .token.punctuation[data-v-5fd4ef0c]{color:#999}.theme-mode-light .namespace[data-v-5fd4ef0c]{opacity:.7}.theme-mode-light .token.boolean[data-v-5fd4ef0c],.theme-mode-light .token.constant[data-v-5fd4ef0c],.theme-mode-light .token.deleted[data-v-5fd4ef0c],.theme-mode-light .token.number[data-v-5fd4ef0c],.theme-mode-light .token.property[data-v-5fd4ef0c],.theme-mode-light .token.symbol[data-v-5fd4ef0c],.theme-mode-light .token.tag[data-v-5fd4ef0c]{color:#905}.theme-mode-light .token.attr-name[data-v-5fd4ef0c],.theme-mode-light .token.builtin[data-v-5fd4ef0c],.theme-mode-light .token.char[data-v-5fd4ef0c],.theme-mode-light .token.inserted[data-v-5fd4ef0c],.theme-mode-light .token.selector[data-v-5fd4ef0c],.theme-mode-light .token.string[data-v-5fd4ef0c]{color:#690}.theme-mode-light .language-css .token.string[data-v-5fd4ef0c],.theme-mode-light .style .token.string[data-v-5fd4ef0c],.theme-mode-light .token.entity[data-v-5fd4ef0c],.theme-mode-light .token.operator[data-v-5fd4ef0c],.theme-mode-light .token.url[data-v-5fd4ef0c]{color:#9a6e3a;background:hsla(0,0%,100%,.5)}.theme-mode-light .token.atrule[data-v-5fd4ef0c],.theme-mode-light .token.attr-value[data-v-5fd4ef0c],.theme-mode-light .token.keyword[data-v-5fd4ef0c]{color:#07a}.theme-mode-light .token.class-name[data-v-5fd4ef0c],.theme-mode-light .token.function[data-v-5fd4ef0c]{color:#dd4a68}.theme-mode-light .token.important[data-v-5fd4ef0c],.theme-mode-light .token.regex[data-v-5fd4ef0c],.theme-mode-light .token.variable[data-v-5fd4ef0c]{color:#e90}.theme-mode-light .token.bold[data-v-5fd4ef0c],.theme-mode-light .token.important[data-v-5fd4ef0c]{font-weight:700}.theme-mode-light .token.italic[data-v-5fd4ef0c]{font-style:italic}.theme-mode-light .token.entity[data-v-5fd4ef0c]{cursor:help}.theme-mode-light div[class*=language-] .highlight-lines .highlighted[data-v-5fd4ef0c],.theme-mode-light div[class*=language-].line-numbers-mode .highlight-lines .highlighted[data-v-5fd4ef0c]:before{background-color:hsla(0,0%,78.4%,.4)}.theme-mode-dark[data-v-5fd4ef0c]{--bodyBg:#27272b;--mainBg:#1e1e22;--sidebarBg:rgba(30,30,34,0.8);--blurBg:rgba(30,30,34,0.8);--customBlockBg:#27272b;--textColor:#9b9baa;--textLightenColor:#0085ad;--borderColor:#30363d;--codeBg:#252526;--codeColor:#fff}.theme-mode-dark code[class*=language-][data-v-5fd4ef0c],.theme-mode-dark pre[class*=language-][data-v-5fd4ef0c]{color:#ccc;background:none;text-shadow:none;font-family:Consolas,Monaco,Andale Mono,Ubuntu Mono,monospace;font-size:1em;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;hyphens:none}.theme-mode-dark pre[class*=language-][data-v-5fd4ef0c]{padding:1em;margin:.5em 0;overflow:auto}.theme-mode-dark :not(pre)>code[class*=language-][data-v-5fd4ef0c],.theme-mode-dark pre[class*=language-][data-v-5fd4ef0c]{background:#2d2d2d}.theme-mode-dark :not(pre)>code[class*=language-][data-v-5fd4ef0c]{padding:.1em;border-radius:.3em;white-space:normal}.theme-mode-dark .token.block-comment[data-v-5fd4ef0c],.theme-mode-dark .token.cdata[data-v-5fd4ef0c],.theme-mode-dark .token.comment[data-v-5fd4ef0c],.theme-mode-dark .token.doctype[data-v-5fd4ef0c],.theme-mode-dark .token.prolog[data-v-5fd4ef0c]{color:#999}.theme-mode-dark .token.punctuation[data-v-5fd4ef0c]{color:#ccc}.theme-mode-dark .token.attr-name[data-v-5fd4ef0c],.theme-mode-dark .token.deleted[data-v-5fd4ef0c],.theme-mode-dark .token.namespace[data-v-5fd4ef0c],.theme-mode-dark .token.tag[data-v-5fd4ef0c]{color:#e2777a}.theme-mode-dark .token.function-name[data-v-5fd4ef0c]{color:#6196cc}.theme-mode-dark .token.boolean[data-v-5fd4ef0c],.theme-mode-dark .token.function[data-v-5fd4ef0c],.theme-mode-dark .token.number[data-v-5fd4ef0c]{color:#f08d49}.theme-mode-dark .token.class-name[data-v-5fd4ef0c],.theme-mode-dark .token.constant[data-v-5fd4ef0c],.theme-mode-dark .token.property[data-v-5fd4ef0c],.theme-mode-dark .token.symbol[data-v-5fd4ef0c]{color:#f8c555}.theme-mode-dark .token.atrule[data-v-5fd4ef0c],.theme-mode-dark .token.builtin[data-v-5fd4ef0c],.theme-mode-dark .token.important[data-v-5fd4ef0c],.theme-mode-dark .token.keyword[data-v-5fd4ef0c],.theme-mode-dark .token.selector[data-v-5fd4ef0c]{color:#cc99cd}.theme-mode-dark .token.attr-value[data-v-5fd4ef0c],.theme-mode-dark .token.char[data-v-5fd4ef0c],.theme-mode-dark .token.regex[data-v-5fd4ef0c],.theme-mode-dark .token.string[data-v-5fd4ef0c],.theme-mode-dark .token.variable[data-v-5fd4ef0c]{color:#7ec699}.theme-mode-dark .token.entity[data-v-5fd4ef0c],.theme-mode-dark .token.operator[data-v-5fd4ef0c],.theme-mode-dark .token.url[data-v-5fd4ef0c]{color:#67cdcc}.theme-mode-dark .language-css .token.string[data-v-5fd4ef0c],.theme-mode-dark .style .token.string[data-v-5fd4ef0c],.theme-mode-dark .token.entity[data-v-5fd4ef0c],.theme-mode-dark .token.operator[data-v-5fd4ef0c],.theme-mode-dark .token.url[data-v-5fd4ef0c]{background:none}.theme-mode-dark .token.bold[data-v-5fd4ef0c],.theme-mode-dark .token.important[data-v-5fd4ef0c]{font-weight:700}.theme-mode-dark .token.italic[data-v-5fd4ef0c]{font-style:italic}.theme-mode-dark .token.entity[data-v-5fd4ef0c]{cursor:help}.theme-mode-dark .token.inserted[data-v-5fd4ef0c]{color:green}.theme-mode-read[data-v-5fd4ef0c]{--bodyBg:#ececcc;--mainBg:#f5f5d5;--sidebarBg:rgba(245,245,213,0.8);--blurBg:rgba(245,245,213,0.9);--customBlockBg:#ececcc;--textColor:#704214;--textLightenColor:#963;--borderColor:rgba(0,0,0,0.15);--codeBg:#282c34;--codeColor:#fff}.theme-mode-read code[class*=language-][data-v-5fd4ef0c],.theme-mode-read pre[class*=language-][data-v-5fd4ef0c]{color:#ccc;background:none;text-shadow:none;font-family:Consolas,Monaco,Andale Mono,Ubuntu Mono,monospace;font-size:1em;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;hyphens:none}.theme-mode-read pre[class*=language-][data-v-5fd4ef0c]{padding:1em;margin:.5em 0;overflow:auto}.theme-mode-read :not(pre)>code[class*=language-][data-v-5fd4ef0c],.theme-mode-read pre[class*=language-][data-v-5fd4ef0c]{background:#2d2d2d}.theme-mode-read :not(pre)>code[class*=language-][data-v-5fd4ef0c]{padding:.1em;border-radius:.3em;white-space:normal}.theme-mode-read .token.block-comment[data-v-5fd4ef0c],.theme-mode-read .token.cdata[data-v-5fd4ef0c],.theme-mode-read .token.comment[data-v-5fd4ef0c],.theme-mode-read .token.doctype[data-v-5fd4ef0c],.theme-mode-read .token.prolog[data-v-5fd4ef0c]{color:#999}.theme-mode-read .token.punctuation[data-v-5fd4ef0c]{color:#ccc}.theme-mode-read .token.attr-name[data-v-5fd4ef0c],.theme-mode-read .token.deleted[data-v-5fd4ef0c],.theme-mode-read .token.namespace[data-v-5fd4ef0c],.theme-mode-read .token.tag[data-v-5fd4ef0c]{color:#e2777a}.theme-mode-read .token.function-name[data-v-5fd4ef0c]{color:#6196cc}.theme-mode-read .token.boolean[data-v-5fd4ef0c],.theme-mode-read .token.function[data-v-5fd4ef0c],.theme-mode-read .token.number[data-v-5fd4ef0c]{color:#f08d49}.theme-mode-read .token.class-name[data-v-5fd4ef0c],.theme-mode-read .token.constant[data-v-5fd4ef0c],.theme-mode-read .token.property[data-v-5fd4ef0c],.theme-mode-read .token.symbol[data-v-5fd4ef0c]{color:#f8c555}.theme-mode-read .token.atrule[data-v-5fd4ef0c],.theme-mode-read .token.builtin[data-v-5fd4ef0c],.theme-mode-read .token.important[data-v-5fd4ef0c],.theme-mode-read .token.keyword[data-v-5fd4ef0c],.theme-mode-read .token.selector[data-v-5fd4ef0c]{color:#cc99cd}.theme-mode-read .token.attr-value[data-v-5fd4ef0c],.theme-mode-read .token.char[data-v-5fd4ef0c],.theme-mode-read .token.regex[data-v-5fd4ef0c],.theme-mode-read .token.string[data-v-5fd4ef0c],.theme-mode-read .token.variable[data-v-5fd4ef0c]{color:#7ec699}.theme-mode-read .token.entity[data-v-5fd4ef0c],.theme-mode-read .token.operator[data-v-5fd4ef0c],.theme-mode-read .token.url[data-v-5fd4ef0c]{color:#67cdcc}.theme-mode-read .language-css .token.string[data-v-5fd4ef0c],.theme-mode-read .style .token.string[data-v-5fd4ef0c],.theme-mode-read .token.entity[data-v-5fd4ef0c],.theme-mode-read .token.operator[data-v-5fd4ef0c],.theme-mode-read .token.url[data-v-5fd4ef0c]{background:none}.theme-mode-read .token.bold[data-v-5fd4ef0c],.theme-mode-read .token.important[data-v-5fd4ef0c]{font-weight:700}.theme-mode-read .token.italic[data-v-5fd4ef0c]{font-style:italic}.theme-mode-read .token.entity[data-v-5fd4ef0c]{cursor:help}.theme-mode-read .token.inserted[data-v-5fd4ef0c]{color:green}.theme-style-line.theme-mode-light[data-v-5fd4ef0c]{--bodyBg:#fff}.theme-style-line.theme-mode-dark[data-v-5fd4ef0c]{--bodyBg:#1e1e22}.theme-style-line.theme-mode-read[data-v-5fd4ef0c]{--bodyBg:#f5f5d5}.go-to-top[data-v-5fd4ef0c]{cursor:pointer;position:fixed;bottom:2rem;right:2.5rem;width:2rem;color:#11a8cd;z-index:1}.go-to-top[data-v-5fd4ef0c]:hover{color:#45cef0}@media (max-width:959px){.go-to-top[data-v-5fd4ef0c]{display:none}}.fade-enter-active[data-v-5fd4ef0c],.fade-leave-active[data-v-5fd4ef0c]{transition:opacity .3s}.fade-enter[data-v-5fd4ef0c],.fade-leave-to[data-v-5fd4ef0c]{opacity:0}.icon.outbound{color:#aaa;display:inline-block;vertical-align:middle;position:relative;top:-1px}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border-width:0}.algolia-search-wrapper>span{vertical-align:middle}.algolia-search-wrapper .algolia-autocomplete{line-height:normal}.algolia-search-wrapper .algolia-autocomplete .ds-dropdown-menu{background-color:#fff;border:1px solid #999;border-radius:4px;font-size:16px;margin:6px 0 0;padding:4px;text-align:left}.algolia-search-wrapper .algolia-autocomplete .ds-dropdown-menu:before{border-color:#999}.algolia-search-wrapper .algolia-autocomplete .ds-dropdown-menu [class*=ds-dataset-]{border:none;padding:0}.algolia-search-wrapper .algolia-autocomplete .ds-dropdown-menu .ds-suggestions{margin-top:0}.algolia-search-wrapper .algolia-autocomplete .ds-dropdown-menu .ds-suggestion{border-bottom:1px solid var(--borderColor)}.algolia-search-wrapper .algolia-autocomplete .algolia-docsearch-suggestion--highlight{color:#2c815b}.algolia-search-wrapper .algolia-autocomplete .algolia-docsearch-suggestion{border-color:var(--borderColor);padding:0}.algolia-search-wrapper .algolia-autocomplete .algolia-docsearch-suggestion .algolia-docsearch-suggestion--category-header{padding:5px 10px;margin-top:0;background:#11a8cd;color:#fff;font-weight:600}.algolia-search-wrapper .algolia-autocomplete .algolia-docsearch-suggestion .algolia-docsearch-suggestion--category-header .algolia-docsearch-suggestion--highlight{background:hsla(0,0%,100%,.6)}.algolia-search-wrapper .algolia-autocomplete .algolia-docsearch-suggestion .algolia-docsearch-suggestion--wrapper{padding:0}.algolia-search-wrapper .algolia-autocomplete .algolia-docsearch-suggestion .algolia-docsearch-suggestion--title{font-weight:600;margin-bottom:0;color:var(--textColor)}.algolia-search-wrapper .algolia-autocomplete .algolia-docsearch-suggestion .algolia-docsearch-suggestion--subcategory-column{vertical-align:top;padding:5px 7px 5px 5px;border-color:var(--borderColor);background:#f1f3f5}.algolia-search-wrapper .algolia-autocomplete .algolia-docsearch-suggestion .algolia-docsearch-suggestion--subcategory-column:after{display:none}.algolia-search-wrapper .algolia-autocomplete .algolia-docsearch-suggestion .algolia-docsearch-suggestion--subcategory-column-text{color:#555}.algolia-search-wrapper .algolia-autocomplete .algolia-docsearch-footer{border-color:var(--borderColor)}.algolia-search-wrapper .algolia-autocomplete .ds-cursor .algolia-docsearch-suggestion--content{background-color:#e7edf3!important;color:var(--textColor)}@media (min-width:719px){.algolia-search-wrapper .algolia-autocomplete .algolia-docsearch-suggestion .algolia-docsearch-suggestion--subcategory-column{float:none;width:150px;min-width:150px;display:table-cell}.algolia-search-wrapper .algolia-autocomplete .algolia-docsearch-suggestion .algolia-docsearch-suggestion--content{float:none;display:table-cell;width:100%;vertical-align:top}.algolia-search-wrapper .algolia-autocomplete .algolia-docsearch-suggestion .ds-dropdown-menu{min-width:515px!important}}@media (max-width:719px){.algolia-search-wrapper .ds-dropdown-menu{min-width:calc(100vw - 4rem)!important;max-width:calc(100vw - 4rem)!important}.algolia-search-wrapper .algolia-docsearch-suggestion--wrapper{padding:5px 7px 5px 5px!important}.algolia-search-wrapper .algolia-docsearch-suggestion--subcategory-column{padding:0!important;background:#fff!important}.algolia-search-wrapper .algolia-docsearch-suggestion--subcategory-column-text:after{content:" > ";font-size:10px;line-height:14.4px;display:inline-block;width:5px;margin:-3px 3px 0;vertical-align:middle}}.main-wrapper{margin:1.5rem auto 0;max-width:1100px;padding:0 .9rem;box-sizing:border-box;position:relative;display:flex}.main-wrapper .main-left{flex:1}.main-wrapper .main-left .theme-vdoing-content.card-box{padding:1rem 1.5rem;margin-bottom:.9rem}.main-wrapper .main-left .home-content{padding:1rem 1.5rem 0}.main-wrapper .main-right>*{width:245px;box-sizing:border-box}@media (max-width:900px){.main-wrapper .main-right>*{width:235px}}.main-wrapper .main-right .card-box{margin:0 0 .8rem .8rem;padding-top:.95rem;padding-bottom:.95rem}@media (max-width:719px){.main-wrapper{margin:.9rem 0;padding:0;display:block}.main-wrapper .main-left{width:100%}.main-wrapper .main-left .post-list{margin-bottom:3rem}.main-wrapper .main-left .post-list .post{border-radius:0}.main-wrapper .main-left .pagination{margin-bottom:3rem}.main-wrapper .main-right .blogger-wrapper{display:none}.main-wrapper .main-right .card-box{margin:0 0 .9rem;border-radius:0;width:100%}.theme-style-line .main-wrapper .main-right .card-box{margin:-1px 0 0}}.post-list{margin-bottom:3rem}.post-list .post{position:relative;padding:1rem 1.5rem;margin-bottom:.8rem;transition:all .3s}.post-list .post:last-child{border-bottom:none}.post-list .post.post-leave-active{display:none}.post-list .post.post-enter{opacity:0;transform:translateX(-20px)}.post-list .post:before{position:absolute;top:-1px;right:0;font-size:2.5rem;color:#ff5722;opacity:.85}.post-list .post .title-wrapper a{color:var(--textColor)}.post-list .post .title-wrapper a:hover{color:#11a8cd}.post-list .post .title-wrapper h2{margin:.5rem 0;font-size:1.4rem;border:none}.post-list .post .title-wrapper h2 .title-tag{height:1.2rem;line-height:1.2rem;border:1px solid #ff5722;color:#ff5722;font-size:.8rem;padding:0 .35rem;border-radius:.2rem;margin-left:0;transform:translateY(-.15rem);display:inline-block}.post-list .post .title-wrapper h2 a{display:block}@media (max-width:719px){.post-list .post .title-wrapper h2 a{font-weight:400}}.post-list .post .title-wrapper .article-info>a,.post-list .post .title-wrapper .article-info>span{opacity:.7;font-size:.8rem;margin-right:1rem;cursor:pointer}.post-list .post .title-wrapper .article-info>a:before,.post-list .post .title-wrapper .article-info>span:before{margin-right:.3rem}.post-list .post .title-wrapper .article-info>a a,.post-list .post .title-wrapper .article-info>span a{margin:0}.post-list .post .title-wrapper .article-info>a a:not(:first-child):before,.post-list .post .title-wrapper .article-info>span a:not(:first-child):before{content:"/"}.post-list .post .title-wrapper .article-info .tags a:not(:first-child):before{content:"、"}.post-list .post .excerpt-wrapper{border-top:1px solid var(--borderColor);margin:.5rem 0;overflow:hidden}.post-list .post .excerpt-wrapper .excerpt{margin-bottom:.3rem;font-size:.92rem}.post-list .post .excerpt-wrapper .excerpt h1,.post-list .post .excerpt-wrapper .excerpt h2,.post-list .post .excerpt-wrapper .excerpt h3{display:none}.post-list .post .excerpt-wrapper .excerpt img{max-height:280px;max-width:100%!important;margin:0 auto}.post-list .post .excerpt-wrapper .readmore{float:right;margin-right:1rem;line-height:1rem}.post-list .post .excerpt-wrapper .readmore:before{float:right;font-size:.8rem;margin:.1rem 0 0 .2rem}.theme-style-line .post-list{border:1px solid var(--borderColor);border-bottom:none;border-radius:5px;overflow:hidden}.theme-style-line .post-list .post{margin-bottom:0;border:none;border-bottom:1px solid var(--borderColor);border-radius:0}.theme-mode-light[data-v-d5affa18]{--bodyBg:#f4f4f4;--mainBg:#fff;--sidebarBg:hsla(0,0%,100%,0.8);--blurBg:hsla(0,0%,100%,0.9);--customBlockBg:#f1f1f1;--textColor:#00323c;--textLightenColor:#0085ad;--borderColor:rgba(0,0,0,0.12);--codeBg:#f6f6f6;--codeColor:#525252}.theme-mode-light code[class*=language-][data-v-d5affa18],.theme-mode-light pre[class*=language-][data-v-d5affa18]{color:#000;background:none;text-shadow:0 1px #fff;font-family:Consolas,Monaco,Andale Mono,Ubuntu Mono,monospace;font-size:1em;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;hyphens:none}.theme-mode-light code[class*=language-][data-v-d5affa18]::-moz-selection,.theme-mode-light code[class*=language-][data-v-d5affa18] ::-moz-selection,.theme-mode-light pre[class*=language-][data-v-d5affa18]::-moz-selection,.theme-mode-light pre[class*=language-][data-v-d5affa18] ::-moz-selection{text-shadow:none;background:#b3d4fc}.theme-mode-light code[class*=language-][data-v-d5affa18]::selection,.theme-mode-light code[class*=language-][data-v-d5affa18] ::selection,.theme-mode-light pre[class*=language-][data-v-d5affa18]::selection,.theme-mode-light pre[class*=language-][data-v-d5affa18] ::selection{text-shadow:none;background:#b3d4fc}@media print{.theme-mode-light code[class*=language-][data-v-d5affa18],.theme-mode-light pre[class*=language-][data-v-d5affa18]{text-shadow:none}}.theme-mode-light pre[class*=language-][data-v-d5affa18]{padding:1em;margin:.5em 0;overflow:auto}.theme-mode-light :not(pre)>code[class*=language-][data-v-d5affa18],.theme-mode-light pre[class*=language-][data-v-d5affa18]{background:#f5f2f0}.theme-mode-light :not(pre)>code[class*=language-][data-v-d5affa18]{padding:.1em;border-radius:.3em;white-space:normal}.theme-mode-light .token.cdata[data-v-d5affa18],.theme-mode-light .token.comment[data-v-d5affa18],.theme-mode-light .token.doctype[data-v-d5affa18],.theme-mode-light .token.prolog[data-v-d5affa18]{color:#708090}.theme-mode-light .token.punctuation[data-v-d5affa18]{color:#999}.theme-mode-light .namespace[data-v-d5affa18]{opacity:.7}.theme-mode-light .token.boolean[data-v-d5affa18],.theme-mode-light .token.constant[data-v-d5affa18],.theme-mode-light .token.deleted[data-v-d5affa18],.theme-mode-light .token.number[data-v-d5affa18],.theme-mode-light .token.property[data-v-d5affa18],.theme-mode-light .token.symbol[data-v-d5affa18],.theme-mode-light .token.tag[data-v-d5affa18]{color:#905}.theme-mode-light .token.attr-name[data-v-d5affa18],.theme-mode-light .token.builtin[data-v-d5affa18],.theme-mode-light .token.char[data-v-d5affa18],.theme-mode-light .token.inserted[data-v-d5affa18],.theme-mode-light .token.selector[data-v-d5affa18],.theme-mode-light .token.string[data-v-d5affa18]{color:#690}.theme-mode-light .language-css .token.string[data-v-d5affa18],.theme-mode-light .style .token.string[data-v-d5affa18],.theme-mode-light .token.entity[data-v-d5affa18],.theme-mode-light .token.operator[data-v-d5affa18],.theme-mode-light .token.url[data-v-d5affa18]{color:#9a6e3a;background:hsla(0,0%,100%,.5)}.theme-mode-light .token.atrule[data-v-d5affa18],.theme-mode-light .token.attr-value[data-v-d5affa18],.theme-mode-light .token.keyword[data-v-d5affa18]{color:#07a}.theme-mode-light .token.class-name[data-v-d5affa18],.theme-mode-light .token.function[data-v-d5affa18]{color:#dd4a68}.theme-mode-light .token.important[data-v-d5affa18],.theme-mode-light .token.regex[data-v-d5affa18],.theme-mode-light .token.variable[data-v-d5affa18]{color:#e90}.theme-mode-light .token.bold[data-v-d5affa18],.theme-mode-light .token.important[data-v-d5affa18]{font-weight:700}.theme-mode-light .token.italic[data-v-d5affa18]{font-style:italic}.theme-mode-light .token.entity[data-v-d5affa18]{cursor:help}.theme-mode-light div[class*=language-] .highlight-lines .highlighted[data-v-d5affa18],.theme-mode-light div[class*=language-].line-numbers-mode .highlight-lines .highlighted[data-v-d5affa18]:before{background-color:hsla(0,0%,78.4%,.4)}.theme-mode-dark[data-v-d5affa18]{--bodyBg:#27272b;--mainBg:#1e1e22;--sidebarBg:rgba(30,30,34,0.8);--blurBg:rgba(30,30,34,0.8);--customBlockBg:#27272b;--textColor:#9b9baa;--textLightenColor:#0085ad;--borderColor:#30363d;--codeBg:#252526;--codeColor:#fff}.theme-mode-dark code[class*=language-][data-v-d5affa18],.theme-mode-dark pre[class*=language-][data-v-d5affa18]{color:#ccc;background:none;text-shadow:none;font-family:Consolas,Monaco,Andale Mono,Ubuntu Mono,monospace;font-size:1em;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;hyphens:none}.theme-mode-dark pre[class*=language-][data-v-d5affa18]{padding:1em;margin:.5em 0;overflow:auto}.theme-mode-dark :not(pre)>code[class*=language-][data-v-d5affa18],.theme-mode-dark pre[class*=language-][data-v-d5affa18]{background:#2d2d2d}.theme-mode-dark :not(pre)>code[class*=language-][data-v-d5affa18]{padding:.1em;border-radius:.3em;white-space:normal}.theme-mode-dark .token.block-comment[data-v-d5affa18],.theme-mode-dark .token.cdata[data-v-d5affa18],.theme-mode-dark .token.comment[data-v-d5affa18],.theme-mode-dark .token.doctype[data-v-d5affa18],.theme-mode-dark .token.prolog[data-v-d5affa18]{color:#999}.theme-mode-dark .token.punctuation[data-v-d5affa18]{color:#ccc}.theme-mode-dark .token.attr-name[data-v-d5affa18],.theme-mode-dark .token.deleted[data-v-d5affa18],.theme-mode-dark .token.namespace[data-v-d5affa18],.theme-mode-dark .token.tag[data-v-d5affa18]{color:#e2777a}.theme-mode-dark .token.function-name[data-v-d5affa18]{color:#6196cc}.theme-mode-dark .token.boolean[data-v-d5affa18],.theme-mode-dark .token.function[data-v-d5affa18],.theme-mode-dark .token.number[data-v-d5affa18]{color:#f08d49}.theme-mode-dark .token.class-name[data-v-d5affa18],.theme-mode-dark .token.constant[data-v-d5affa18],.theme-mode-dark .token.property[data-v-d5affa18],.theme-mode-dark .token.symbol[data-v-d5affa18]{color:#f8c555}.theme-mode-dark .token.atrule[data-v-d5affa18],.theme-mode-dark .token.builtin[data-v-d5affa18],.theme-mode-dark .token.important[data-v-d5affa18],.theme-mode-dark .token.keyword[data-v-d5affa18],.theme-mode-dark .token.selector[data-v-d5affa18]{color:#cc99cd}.theme-mode-dark .token.attr-value[data-v-d5affa18],.theme-mode-dark .token.char[data-v-d5affa18],.theme-mode-dark .token.regex[data-v-d5affa18],.theme-mode-dark .token.string[data-v-d5affa18],.theme-mode-dark .token.variable[data-v-d5affa18]{color:#7ec699}.theme-mode-dark .token.entity[data-v-d5affa18],.theme-mode-dark .token.operator[data-v-d5affa18],.theme-mode-dark .token.url[data-v-d5affa18]{color:#67cdcc}.theme-mode-dark .language-css .token.string[data-v-d5affa18],.theme-mode-dark .style .token.string[data-v-d5affa18],.theme-mode-dark .token.entity[data-v-d5affa18],.theme-mode-dark .token.operator[data-v-d5affa18],.theme-mode-dark .token.url[data-v-d5affa18]{background:none}.theme-mode-dark .token.bold[data-v-d5affa18],.theme-mode-dark .token.important[data-v-d5affa18]{font-weight:700}.theme-mode-dark .token.italic[data-v-d5affa18]{font-style:italic}.theme-mode-dark .token.entity[data-v-d5affa18]{cursor:help}.theme-mode-dark .token.inserted[data-v-d5affa18]{color:green}.theme-mode-read[data-v-d5affa18]{--bodyBg:#ececcc;--mainBg:#f5f5d5;--sidebarBg:rgba(245,245,213,0.8);--blurBg:rgba(245,245,213,0.9);--customBlockBg:#ececcc;--textColor:#704214;--textLightenColor:#963;--borderColor:rgba(0,0,0,0.15);--codeBg:#282c34;--codeColor:#fff}.theme-mode-read code[class*=language-][data-v-d5affa18],.theme-mode-read pre[class*=language-][data-v-d5affa18]{color:#ccc;background:none;text-shadow:none;font-family:Consolas,Monaco,Andale Mono,Ubuntu Mono,monospace;font-size:1em;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;hyphens:none}.theme-mode-read pre[class*=language-][data-v-d5affa18]{padding:1em;margin:.5em 0;overflow:auto}.theme-mode-read :not(pre)>code[class*=language-][data-v-d5affa18],.theme-mode-read pre[class*=language-][data-v-d5affa18]{background:#2d2d2d}.theme-mode-read :not(pre)>code[class*=language-][data-v-d5affa18]{padding:.1em;border-radius:.3em;white-space:normal}.theme-mode-read .token.block-comment[data-v-d5affa18],.theme-mode-read .token.cdata[data-v-d5affa18],.theme-mode-read .token.comment[data-v-d5affa18],.theme-mode-read .token.doctype[data-v-d5affa18],.theme-mode-read .token.prolog[data-v-d5affa18]{color:#999}.theme-mode-read .token.punctuation[data-v-d5affa18]{color:#ccc}.theme-mode-read .token.attr-name[data-v-d5affa18],.theme-mode-read .token.deleted[data-v-d5affa18],.theme-mode-read .token.namespace[data-v-d5affa18],.theme-mode-read .token.tag[data-v-d5affa18]{color:#e2777a}.theme-mode-read .token.function-name[data-v-d5affa18]{color:#6196cc}.theme-mode-read .token.boolean[data-v-d5affa18],.theme-mode-read .token.function[data-v-d5affa18],.theme-mode-read .token.number[data-v-d5affa18]{color:#f08d49}.theme-mode-read .token.class-name[data-v-d5affa18],.theme-mode-read .token.constant[data-v-d5affa18],.theme-mode-read .token.property[data-v-d5affa18],.theme-mode-read .token.symbol[data-v-d5affa18]{color:#f8c555}.theme-mode-read .token.atrule[data-v-d5affa18],.theme-mode-read .token.builtin[data-v-d5affa18],.theme-mode-read .token.important[data-v-d5affa18],.theme-mode-read .token.keyword[data-v-d5affa18],.theme-mode-read .token.selector[data-v-d5affa18]{color:#cc99cd}.theme-mode-read .token.attr-value[data-v-d5affa18],.theme-mode-read .token.char[data-v-d5affa18],.theme-mode-read .token.regex[data-v-d5affa18],.theme-mode-read .token.string[data-v-d5affa18],.theme-mode-read .token.variable[data-v-d5affa18]{color:#7ec699}.theme-mode-read .token.entity[data-v-d5affa18],.theme-mode-read .token.operator[data-v-d5affa18],.theme-mode-read .token.url[data-v-d5affa18]{color:#67cdcc}.theme-mode-read .language-css .token.string[data-v-d5affa18],.theme-mode-read .style .token.string[data-v-d5affa18],.theme-mode-read .token.entity[data-v-d5affa18],.theme-mode-read .token.operator[data-v-d5affa18],.theme-mode-read .token.url[data-v-d5affa18]{background:none}.theme-mode-read .token.bold[data-v-d5affa18],.theme-mode-read .token.important[data-v-d5affa18]{font-weight:700}.theme-mode-read .token.italic[data-v-d5affa18]{font-style:italic}.theme-mode-read .token.entity[data-v-d5affa18]{cursor:help}.theme-mode-read .token.inserted[data-v-d5affa18]{color:green}.theme-style-line.theme-mode-light[data-v-d5affa18]{--bodyBg:#fff}.theme-style-line.theme-mode-dark[data-v-d5affa18]{--bodyBg:#1e1e22}.theme-style-line.theme-mode-read[data-v-d5affa18]{--bodyBg:#f5f5d5}.badge[data-v-d5affa18]{display:inline-block;font-size:14px;height:18px;line-height:18px;border-radius:3px;padding:0 6px;color:#fff}.badge.green[data-v-d5affa18],.badge.tip[data-v-d5affa18],.badge[data-v-d5affa18]{background-color:#42b983}.badge.error[data-v-d5affa18]{background-color:#da5961}.badge.warn[data-v-d5affa18],.badge.warning[data-v-d5affa18],.badge.yellow[data-v-d5affa18]{background-color:#e7c000}.badge+.badge[data-v-d5affa18]{margin-left:5px}.theme-mode-light[data-v-439bb2a8]{--bodyBg:#f4f4f4;--mainBg:#fff;--sidebarBg:hsla(0,0%,100%,0.8);--blurBg:hsla(0,0%,100%,0.9);--customBlockBg:#f1f1f1;--textColor:#00323c;--textLightenColor:#0085ad;--borderColor:rgba(0,0,0,0.12);--codeBg:#f6f6f6;--codeColor:#525252}.theme-mode-light code[class*=language-][data-v-439bb2a8],.theme-mode-light pre[class*=language-][data-v-439bb2a8]{color:#000;background:none;text-shadow:0 1px #fff;font-family:Consolas,Monaco,Andale Mono,Ubuntu Mono,monospace;font-size:1em;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;hyphens:none}.theme-mode-light code[class*=language-][data-v-439bb2a8]::-moz-selection,.theme-mode-light code[class*=language-][data-v-439bb2a8] ::-moz-selection,.theme-mode-light pre[class*=language-][data-v-439bb2a8]::-moz-selection,.theme-mode-light pre[class*=language-][data-v-439bb2a8] ::-moz-selection{text-shadow:none;background:#b3d4fc}.theme-mode-light code[class*=language-][data-v-439bb2a8]::selection,.theme-mode-light code[class*=language-][data-v-439bb2a8] ::selection,.theme-mode-light pre[class*=language-][data-v-439bb2a8]::selection,.theme-mode-light pre[class*=language-][data-v-439bb2a8] ::selection{text-shadow:none;background:#b3d4fc}@media print{.theme-mode-light code[class*=language-][data-v-439bb2a8],.theme-mode-light pre[class*=language-][data-v-439bb2a8]{text-shadow:none}}.theme-mode-light pre[class*=language-][data-v-439bb2a8]{padding:1em;margin:.5em 0;overflow:auto}.theme-mode-light :not(pre)>code[class*=language-][data-v-439bb2a8],.theme-mode-light pre[class*=language-][data-v-439bb2a8]{background:#f5f2f0}.theme-mode-light :not(pre)>code[class*=language-][data-v-439bb2a8]{padding:.1em;border-radius:.3em;white-space:normal}.theme-mode-light .token.cdata[data-v-439bb2a8],.theme-mode-light .token.comment[data-v-439bb2a8],.theme-mode-light .token.doctype[data-v-439bb2a8],.theme-mode-light .token.prolog[data-v-439bb2a8]{color:#708090}.theme-mode-light .token.punctuation[data-v-439bb2a8]{color:#999}.theme-mode-light .namespace[data-v-439bb2a8]{opacity:.7}.theme-mode-light .token.boolean[data-v-439bb2a8],.theme-mode-light .token.constant[data-v-439bb2a8],.theme-mode-light .token.deleted[data-v-439bb2a8],.theme-mode-light .token.number[data-v-439bb2a8],.theme-mode-light .token.property[data-v-439bb2a8],.theme-mode-light .token.symbol[data-v-439bb2a8],.theme-mode-light .token.tag[data-v-439bb2a8]{color:#905}.theme-mode-light .token.attr-name[data-v-439bb2a8],.theme-mode-light .token.builtin[data-v-439bb2a8],.theme-mode-light .token.char[data-v-439bb2a8],.theme-mode-light .token.inserted[data-v-439bb2a8],.theme-mode-light .token.selector[data-v-439bb2a8],.theme-mode-light .token.string[data-v-439bb2a8]{color:#690}.theme-mode-light .language-css .token.string[data-v-439bb2a8],.theme-mode-light .style .token.string[data-v-439bb2a8],.theme-mode-light .token.entity[data-v-439bb2a8],.theme-mode-light .token.operator[data-v-439bb2a8],.theme-mode-light .token.url[data-v-439bb2a8]{color:#9a6e3a;background:hsla(0,0%,100%,.5)}.theme-mode-light .token.atrule[data-v-439bb2a8],.theme-mode-light .token.attr-value[data-v-439bb2a8],.theme-mode-light .token.keyword[data-v-439bb2a8]{color:#07a}.theme-mode-light .token.class-name[data-v-439bb2a8],.theme-mode-light .token.function[data-v-439bb2a8]{color:#dd4a68}.theme-mode-light .token.important[data-v-439bb2a8],.theme-mode-light .token.regex[data-v-439bb2a8],.theme-mode-light .token.variable[data-v-439bb2a8]{color:#e90}.theme-mode-light .token.bold[data-v-439bb2a8],.theme-mode-light .token.important[data-v-439bb2a8]{font-weight:700}.theme-mode-light .token.italic[data-v-439bb2a8]{font-style:italic}.theme-mode-light .token.entity[data-v-439bb2a8]{cursor:help}.theme-mode-light div[class*=language-] .highlight-lines .highlighted[data-v-439bb2a8],.theme-mode-light div[class*=language-].line-numbers-mode .highlight-lines .highlighted[data-v-439bb2a8]:before{background-color:hsla(0,0%,78.4%,.4)}.theme-mode-dark[data-v-439bb2a8]{--bodyBg:#27272b;--mainBg:#1e1e22;--sidebarBg:rgba(30,30,34,0.8);--blurBg:rgba(30,30,34,0.8);--customBlockBg:#27272b;--textColor:#9b9baa;--textLightenColor:#0085ad;--borderColor:#30363d;--codeBg:#252526;--codeColor:#fff}.theme-mode-dark code[class*=language-][data-v-439bb2a8],.theme-mode-dark pre[class*=language-][data-v-439bb2a8]{color:#ccc;background:none;text-shadow:none;font-family:Consolas,Monaco,Andale Mono,Ubuntu Mono,monospace;font-size:1em;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;hyphens:none}.theme-mode-dark pre[class*=language-][data-v-439bb2a8]{padding:1em;margin:.5em 0;overflow:auto}.theme-mode-dark :not(pre)>code[class*=language-][data-v-439bb2a8],.theme-mode-dark pre[class*=language-][data-v-439bb2a8]{background:#2d2d2d}.theme-mode-dark :not(pre)>code[class*=language-][data-v-439bb2a8]{padding:.1em;border-radius:.3em;white-space:normal}.theme-mode-dark .token.block-comment[data-v-439bb2a8],.theme-mode-dark .token.cdata[data-v-439bb2a8],.theme-mode-dark .token.comment[data-v-439bb2a8],.theme-mode-dark .token.doctype[data-v-439bb2a8],.theme-mode-dark .token.prolog[data-v-439bb2a8]{color:#999}.theme-mode-dark .token.punctuation[data-v-439bb2a8]{color:#ccc}.theme-mode-dark .token.attr-name[data-v-439bb2a8],.theme-mode-dark .token.deleted[data-v-439bb2a8],.theme-mode-dark .token.namespace[data-v-439bb2a8],.theme-mode-dark .token.tag[data-v-439bb2a8]{color:#e2777a}.theme-mode-dark .token.function-name[data-v-439bb2a8]{color:#6196cc}.theme-mode-dark .token.boolean[data-v-439bb2a8],.theme-mode-dark .token.function[data-v-439bb2a8],.theme-mode-dark .token.number[data-v-439bb2a8]{color:#f08d49}.theme-mode-dark .token.class-name[data-v-439bb2a8],.theme-mode-dark .token.constant[data-v-439bb2a8],.theme-mode-dark .token.property[data-v-439bb2a8],.theme-mode-dark .token.symbol[data-v-439bb2a8]{color:#f8c555}.theme-mode-dark .token.atrule[data-v-439bb2a8],.theme-mode-dark .token.builtin[data-v-439bb2a8],.theme-mode-dark .token.important[data-v-439bb2a8],.theme-mode-dark .token.keyword[data-v-439bb2a8],.theme-mode-dark .token.selector[data-v-439bb2a8]{color:#cc99cd}.theme-mode-dark .token.attr-value[data-v-439bb2a8],.theme-mode-dark .token.char[data-v-439bb2a8],.theme-mode-dark .token.regex[data-v-439bb2a8],.theme-mode-dark .token.string[data-v-439bb2a8],.theme-mode-dark .token.variable[data-v-439bb2a8]{color:#7ec699}.theme-mode-dark .token.entity[data-v-439bb2a8],.theme-mode-dark .token.operator[data-v-439bb2a8],.theme-mode-dark .token.url[data-v-439bb2a8]{color:#67cdcc}.theme-mode-dark .language-css .token.string[data-v-439bb2a8],.theme-mode-dark .style .token.string[data-v-439bb2a8],.theme-mode-dark .token.entity[data-v-439bb2a8],.theme-mode-dark .token.operator[data-v-439bb2a8],.theme-mode-dark .token.url[data-v-439bb2a8]{background:none}.theme-mode-dark .token.bold[data-v-439bb2a8],.theme-mode-dark .token.important[data-v-439bb2a8]{font-weight:700}.theme-mode-dark .token.italic[data-v-439bb2a8]{font-style:italic}.theme-mode-dark .token.entity[data-v-439bb2a8]{cursor:help}.theme-mode-dark .token.inserted[data-v-439bb2a8]{color:green}.theme-mode-read[data-v-439bb2a8]{--bodyBg:#ececcc;--mainBg:#f5f5d5;--sidebarBg:rgba(245,245,213,0.8);--blurBg:rgba(245,245,213,0.9);--customBlockBg:#ececcc;--textColor:#704214;--textLightenColor:#963;--borderColor:rgba(0,0,0,0.15);--codeBg:#282c34;--codeColor:#fff}.theme-mode-read code[class*=language-][data-v-439bb2a8],.theme-mode-read pre[class*=language-][data-v-439bb2a8]{color:#ccc;background:none;text-shadow:none;font-family:Consolas,Monaco,Andale Mono,Ubuntu Mono,monospace;font-size:1em;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;hyphens:none}.theme-mode-read pre[class*=language-][data-v-439bb2a8]{padding:1em;margin:.5em 0;overflow:auto}.theme-mode-read :not(pre)>code[class*=language-][data-v-439bb2a8],.theme-mode-read pre[class*=language-][data-v-439bb2a8]{background:#2d2d2d}.theme-mode-read :not(pre)>code[class*=language-][data-v-439bb2a8]{padding:.1em;border-radius:.3em;white-space:normal}.theme-mode-read .token.block-comment[data-v-439bb2a8],.theme-mode-read .token.cdata[data-v-439bb2a8],.theme-mode-read .token.comment[data-v-439bb2a8],.theme-mode-read .token.doctype[data-v-439bb2a8],.theme-mode-read .token.prolog[data-v-439bb2a8]{color:#999}.theme-mode-read .token.punctuation[data-v-439bb2a8]{color:#ccc}.theme-mode-read .token.attr-name[data-v-439bb2a8],.theme-mode-read .token.deleted[data-v-439bb2a8],.theme-mode-read .token.namespace[data-v-439bb2a8],.theme-mode-read .token.tag[data-v-439bb2a8]{color:#e2777a}.theme-mode-read .token.function-name[data-v-439bb2a8]{color:#6196cc}.theme-mode-read .token.boolean[data-v-439bb2a8],.theme-mode-read .token.function[data-v-439bb2a8],.theme-mode-read .token.number[data-v-439bb2a8]{color:#f08d49}.theme-mode-read .token.class-name[data-v-439bb2a8],.theme-mode-read .token.constant[data-v-439bb2a8],.theme-mode-read .token.property[data-v-439bb2a8],.theme-mode-read .token.symbol[data-v-439bb2a8]{color:#f8c555}.theme-mode-read .token.atrule[data-v-439bb2a8],.theme-mode-read .token.builtin[data-v-439bb2a8],.theme-mode-read .token.important[data-v-439bb2a8],.theme-mode-read .token.keyword[data-v-439bb2a8],.theme-mode-read .token.selector[data-v-439bb2a8]{color:#cc99cd}.theme-mode-read .token.attr-value[data-v-439bb2a8],.theme-mode-read .token.char[data-v-439bb2a8],.theme-mode-read .token.regex[data-v-439bb2a8],.theme-mode-read .token.string[data-v-439bb2a8],.theme-mode-read .token.variable[data-v-439bb2a8]{color:#7ec699}.theme-mode-read .token.entity[data-v-439bb2a8],.theme-mode-read .token.operator[data-v-439bb2a8],.theme-mode-read .token.url[data-v-439bb2a8]{color:#67cdcc}.theme-mode-read .language-css .token.string[data-v-439bb2a8],.theme-mode-read .style .token.string[data-v-439bb2a8],.theme-mode-read .token.entity[data-v-439bb2a8],.theme-mode-read .token.operator[data-v-439bb2a8],.theme-mode-read .token.url[data-v-439bb2a8]{background:none}.theme-mode-read .token.bold[data-v-439bb2a8],.theme-mode-read .token.important[data-v-439bb2a8]{font-weight:700}.theme-mode-read .token.italic[data-v-439bb2a8]{font-style:italic}.theme-mode-read .token.entity[data-v-439bb2a8]{cursor:help}.theme-mode-read .token.inserted[data-v-439bb2a8]{color:green}.theme-style-line.theme-mode-light[data-v-439bb2a8]{--bodyBg:#fff}.theme-style-line.theme-mode-dark[data-v-439bb2a8]{--bodyBg:#1e1e22}.theme-style-line.theme-mode-read[data-v-439bb2a8]{--bodyBg:#f5f5d5}.theme-vdoing-content[data-v-439bb2a8]{margin:3rem auto;padding:1.5rem}.theme-vdoing-content span[data-v-439bb2a8]{font-size:6rem;color:#11a8cd}.searchbox{display:inline-block;position:relative;width:200px;height:32px!important;white-space:nowrap;box-sizing:border-box;visibility:visible!important}.searchbox .algolia-autocomplete{display:block;width:100%;height:100%}.searchbox__wrapper{width:100%;height:100%;z-index:999;position:relative}.searchbox__input{display:inline-block;box-sizing:border-box;transition:box-shadow .4s ease,background .4s ease;border:0;border-radius:16px;box-shadow:inset 0 0 0 1px #ccc;background:#fff!important;padding:0 26px 0 32px;width:100%;height:100%;vertical-align:middle;white-space:normal;font-size:12px;-webkit-appearance:none;-moz-appearance:none;appearance:none}.searchbox__input::-webkit-search-cancel-button,.searchbox__input::-webkit-search-decoration,.searchbox__input::-webkit-search-results-button,.searchbox__input::-webkit-search-results-decoration{display:none}.searchbox__input:hover{box-shadow:inset 0 0 0 1px #b3b3b3}.searchbox__input:active,.searchbox__input:focus{outline:0;box-shadow:inset 0 0 0 1px #aaa;background:#fff}.searchbox__input::-moz-placeholder{color:#aaa}.searchbox__input::placeholder{color:#aaa}.searchbox__submit{position:absolute;top:0;margin:0;border:0;border-radius:16px 0 0 16px;background-color:rgba(69,142,225,0);padding:0;width:32px;height:100%;vertical-align:middle;text-align:center;font-size:inherit;-webkit-user-select:none;-moz-user-select:none;user-select:none;right:inherit;left:0}.searchbox__submit:before{display:inline-block;margin-right:-4px;height:100%;vertical-align:middle;content:""}.searchbox__submit:active,.searchbox__submit:hover{cursor:pointer}.searchbox__submit:focus{outline:0}.searchbox__submit svg{width:14px;height:14px;vertical-align:middle;fill:#6d7e96}.searchbox__reset{display:block;position:absolute;top:8px;right:8px;margin:0;border:0;background:none;cursor:pointer;padding:0;font-size:inherit;-webkit-user-select:none;-moz-user-select:none;user-select:none;fill:rgba(0,0,0,.5)}.searchbox__reset.hide{display:none}.searchbox__reset:focus{outline:0}.searchbox__reset svg{display:block;margin:4px;width:8px;height:8px}.searchbox__input:valid~.searchbox__reset{display:block;animation-name:sbx-reset-in;animation-duration:.15s}@keyframes sbx-reset-in{0%{transform:translate3d(-20%,0,0);opacity:0}to{transform:none;opacity:1}}.algolia-autocomplete.algolia-autocomplete-right .ds-dropdown-menu{right:0!important;left:inherit!important}.algolia-autocomplete.algolia-autocomplete-right .ds-dropdown-menu:before{right:48px}.algolia-autocomplete.algolia-autocomplete-left .ds-dropdown-menu{left:0!important;right:inherit!important}.algolia-autocomplete.algolia-autocomplete-left .ds-dropdown-menu:before{left:48px}.algolia-autocomplete .ds-dropdown-menu{top:-6px;border-radius:4px;margin:6px 0 0;padding:0;text-align:left;height:auto;position:relative;background:transparent;border:none;z-index:999;max-width:600px;min-width:500px;box-shadow:0 1px 0 0 rgba(0,0,0,.2),0 2px 3px 0 rgba(0,0,0,.1)}.algolia-autocomplete .ds-dropdown-menu:before{display:block;position:absolute;content:"";width:14px;height:14px;background:#fff;z-index:1000;top:-7px;border-top:1px solid #d9d9d9;border-right:1px solid #d9d9d9;transform:rotate(-45deg);border-radius:2px}.algolia-autocomplete .ds-dropdown-menu .ds-suggestions{position:relative;z-index:1000;margin-top:8px}.algolia-autocomplete .ds-dropdown-menu .ds-suggestions a:hover{text-decoration:none}.algolia-autocomplete .ds-dropdown-menu .ds-suggestion{cursor:pointer}.algolia-autocomplete .ds-dropdown-menu .ds-suggestion.ds-cursor .algolia-docsearch-suggestion.suggestion-layout-simple,.algolia-autocomplete .ds-dropdown-menu .ds-suggestion.ds-cursor .algolia-docsearch-suggestion:not(.suggestion-layout-simple) .algolia-docsearch-suggestion--content{background-color:rgba(69,142,225,.05)}.algolia-autocomplete .ds-dropdown-menu [class^=ds-dataset-]{position:relative;border:1px solid #d9d9d9;background:#fff;border-radius:4px;overflow:auto;padding:0 8px 8px}.algolia-autocomplete .ds-dropdown-menu *{box-sizing:border-box}.algolia-autocomplete .algolia-docsearch-suggestion{display:block;position:relative;padding:0 8px;background:#fff;color:#02060c;overflow:hidden}.algolia-autocomplete .algolia-docsearch-suggestion--highlight{color:#174d8c;background:rgba(143,187,237,.1);padding:.1em .05em}.algolia-autocomplete .algolia-docsearch-suggestion--category-header .algolia-docsearch-suggestion--category-header-lvl0 .algolia-docsearch-suggestion--highlight,.algolia-autocomplete .algolia-docsearch-suggestion--category-header .algolia-docsearch-suggestion--category-header-lvl1 .algolia-docsearch-suggestion--highlight,.algolia-autocomplete .algolia-docsearch-suggestion--text .algolia-docsearch-suggestion--highlight{padding:0 0 1px;background:inherit;box-shadow:inset 0 -2px 0 0 rgba(69,142,225,.8);color:inherit}.algolia-autocomplete .algolia-docsearch-suggestion--content{display:block;float:right;width:70%;position:relative;padding:5.33333px 0 5.33333px 10.66667px;cursor:pointer}.algolia-autocomplete .algolia-docsearch-suggestion--content:before{content:"";position:absolute;display:block;top:0;height:100%;width:1px;background:#ddd;left:-1px}.algolia-autocomplete .algolia-docsearch-suggestion--category-header{position:relative;border-bottom:1px solid #ddd;display:none;margin-top:8px;padding:4px 0;font-size:1em;color:#33363d}.algolia-autocomplete .algolia-docsearch-suggestion--wrapper{width:100%;float:left;padding:8px 0 0}.algolia-autocomplete .algolia-docsearch-suggestion--subcategory-column{float:left;width:30%;text-align:right;position:relative;padding:5.33333px 10.66667px;color:#a4a7ae;font-size:.9em;word-wrap:break-word}.algolia-autocomplete .algolia-docsearch-suggestion--subcategory-column:before{content:"";position:absolute;display:block;top:0;height:100%;width:1px;background:#ddd;right:0}.algolia-autocomplete .algolia-docsearch-suggestion--subcategory-inline{display:none}.algolia-autocomplete .algolia-docsearch-suggestion--title{margin-bottom:4px;color:#02060c;font-size:.9em;font-weight:700}.algolia-autocomplete .algolia-docsearch-suggestion--text{display:block;line-height:1.2em;font-size:.85em;color:#63676d}.algolia-autocomplete .algolia-docsearch-suggestion--no-results{width:100%;padding:8px 0;text-align:center;font-size:1.2em}.algolia-autocomplete .algolia-docsearch-suggestion--no-results:before{display:none}.algolia-autocomplete .algolia-docsearch-suggestion code{padding:1px 5px;font-size:90%;border:none;color:#222;background-color:#ebebeb;border-radius:3px;font-family:Menlo,Monaco,Consolas,Courier New,monospace}.algolia-autocomplete .algolia-docsearch-suggestion code .algolia-docsearch-suggestion--highlight{background:none}.algolia-autocomplete .algolia-docsearch-suggestion.algolia-docsearch-suggestion__main .algolia-docsearch-suggestion--category-header,.algolia-autocomplete .algolia-docsearch-suggestion.algolia-docsearch-suggestion__secondary{display:block}@media (min-width:768px){.algolia-autocomplete .algolia-docsearch-suggestion .algolia-docsearch-suggestion--subcategory-column{display:block}}@media (max-width:768px){.algolia-autocomplete .algolia-docsearch-suggestion .algolia-docsearch-suggestion--subcategory-column{display:inline-block;width:auto;float:left;padding:0;color:#02060c;font-size:.9em;font-weight:700;text-align:left;opacity:.5}.algolia-autocomplete .algolia-docsearch-suggestion .algolia-docsearch-suggestion--subcategory-column:before{display:none}.algolia-autocomplete .algolia-docsearch-suggestion .algolia-docsearch-suggestion--subcategory-column:after{content:"|"}.algolia-autocomplete .algolia-docsearch-suggestion .algolia-docsearch-suggestion--content{display:inline-block;width:auto;text-align:left;float:left;padding:0}.algolia-autocomplete .algolia-docsearch-suggestion .algolia-docsearch-suggestion--content:before{display:none}}.algolia-autocomplete .suggestion-layout-simple.algolia-docsearch-suggestion{border-bottom:1px solid #eee;padding:8px;margin:0}.algolia-autocomplete .suggestion-layout-simple .algolia-docsearch-suggestion--content{width:100%;padding:0}.algolia-autocomplete .suggestion-layout-simple .algolia-docsearch-suggestion--content:before{display:none}.algolia-autocomplete .suggestion-layout-simple .algolia-docsearch-suggestion--category-header{margin:0;padding:0;display:block;width:100%;border:none}.algolia-autocomplete .suggestion-layout-simple .algolia-docsearch-suggestion--category-header-lvl0,.algolia-autocomplete .suggestion-layout-simple .algolia-docsearch-suggestion--category-header-lvl1{opacity:.6;font-size:.85em}.algolia-autocomplete .suggestion-layout-simple .algolia-docsearch-suggestion--category-header-lvl1:before{background-image:url('data:image/svg+xml;utf8,');content:"";width:10px;height:10px;display:inline-block}.algolia-autocomplete .suggestion-layout-simple .algolia-docsearch-suggestion--wrapper{width:100%;float:left;margin:0;padding:0}.algolia-autocomplete .suggestion-layout-simple .algolia-docsearch-suggestion--duplicate-content,.algolia-autocomplete .suggestion-layout-simple .algolia-docsearch-suggestion--subcategory-inline{display:none!important}.algolia-autocomplete .suggestion-layout-simple .algolia-docsearch-suggestion--title{margin:0;color:#458ee1;font-size:.9em;font-weight:400}.algolia-autocomplete .suggestion-layout-simple .algolia-docsearch-suggestion--title:before{content:"#";font-weight:700;color:#458ee1;display:inline-block}.algolia-autocomplete .suggestion-layout-simple .algolia-docsearch-suggestion--text{margin:4px 0 0;display:block;line-height:1.4em;padding:5.33333px 8px;background:#f8f8f8;font-size:.85em;opacity:.8}.algolia-autocomplete .suggestion-layout-simple .algolia-docsearch-suggestion--text .algolia-docsearch-suggestion--highlight{color:#3f4145;font-weight:700;box-shadow:none}.algolia-autocomplete .algolia-docsearch-footer{width:134px;height:20px;z-index:2000;margin-top:10.66667px;float:right;font-size:0;line-height:0}.algolia-autocomplete .algolia-docsearch-footer--logo{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg width='168' height='24' xmlns='http://www.w3.org/2000/svg'%3E%3Cg fill='none' fill-rule='evenodd'%3E%3Cpath d='M78.988.938h16.594a2.968 2.968 0 012.966 2.966V20.5a2.967 2.967 0 01-2.966 2.964H78.988a2.967 2.967 0 01-2.966-2.964V3.897A2.961 2.961 0 0178.988.938zm41.937 17.866c-4.386.02-4.386-3.54-4.386-4.106l-.007-13.336 2.675-.424v13.254c0 .322 0 2.358 1.718 2.364v2.248zm-10.846-2.18c.821 0 1.43-.047 1.855-.129v-2.719a6.334 6.334 0 00-1.574-.199 5.7 5.7 0 00-.897.069 2.699 2.699 0 00-.814.24c-.24.116-.439.28-.582.491-.15.212-.219.335-.219.656 0 .628.219.991.616 1.23s.938.362 1.615.362zm-.233-9.7c.883 0 1.629.109 2.231.328.602.218 1.088.525 1.444.915.363.396.609.922.76 1.483.157.56.232 1.175.232 1.85v6.874a32.5 32.5 0 01-1.868.314c-.834.123-1.772.185-2.813.185-.69 0-1.327-.069-1.895-.198a4.001 4.001 0 01-1.471-.636 3.085 3.085 0 01-.951-1.134c-.226-.465-.343-1.12-.343-1.803 0-.656.13-1.073.384-1.525a3.24 3.24 0 011.047-1.106c.445-.287.95-.492 1.532-.615a8.8 8.8 0 011.82-.185 8.404 8.404 0 011.972.24v-.438c0-.307-.035-.6-.11-.874a1.88 1.88 0 00-.384-.73 1.784 1.784 0 00-.724-.493 3.164 3.164 0 00-1.143-.205c-.616 0-1.177.075-1.69.164a7.735 7.735 0 00-1.26.307l-.321-2.192c.335-.117.834-.233 1.478-.349a10.98 10.98 0 012.073-.178zm52.842 9.626c.822 0 1.43-.048 1.854-.13V13.7a6.347 6.347 0 00-1.574-.199c-.294 0-.595.021-.896.069a2.7 2.7 0 00-.814.24 1.46 1.46 0 00-.582.491c-.15.212-.218.335-.218.656 0 .628.218.991.615 1.23.404.245.938.362 1.615.362zm-.226-9.694c.883 0 1.629.108 2.231.327.602.219 1.088.526 1.444.915.355.39.609.923.759 1.483a6.8 6.8 0 01.233 1.852v6.873c-.41.088-1.034.19-1.868.314-.834.123-1.772.184-2.813.184-.69 0-1.327-.068-1.895-.198a4.001 4.001 0 01-1.471-.635 3.085 3.085 0 01-.951-1.134c-.226-.465-.343-1.12-.343-1.804 0-.656.13-1.073.384-1.524.26-.45.608-.82 1.047-1.107.445-.286.95-.491 1.532-.614a8.803 8.803 0 012.751-.13c.329.034.671.096 1.04.185v-.437a3.3 3.3 0 00-.109-.875 1.873 1.873 0 00-.384-.731 1.784 1.784 0 00-.724-.492 3.165 3.165 0 00-1.143-.205c-.616 0-1.177.075-1.69.164a7.75 7.75 0 00-1.26.307l-.321-2.193c.335-.116.834-.232 1.478-.348a11.633 11.633 0 012.073-.177zm-8.034-1.271a1.626 1.626 0 01-1.628-1.62c0-.895.725-1.62 1.628-1.62.904 0 1.63.725 1.63 1.62 0 .895-.733 1.62-1.63 1.62zm1.348 13.22h-2.689V7.27l2.69-.423v11.956zm-4.714 0c-4.386.02-4.386-3.54-4.386-4.107l-.008-13.336 2.676-.424v13.254c0 .322 0 2.358 1.718 2.364v2.248zm-8.698-5.903c0-1.156-.253-2.119-.746-2.788-.493-.677-1.183-1.01-2.067-1.01-.882 0-1.574.333-2.065 1.01-.493.676-.733 1.632-.733 2.788 0 1.168.246 1.953.74 2.63.492.683 1.183 1.018 2.066 1.018.882 0 1.574-.342 2.067-1.019.492-.683.738-1.46.738-2.63zm2.737-.007c0 .902-.13 1.584-.397 2.33a5.52 5.52 0 01-1.128 1.906 4.986 4.986 0 01-1.752 1.223c-.685.286-1.739.45-2.265.45-.528-.006-1.574-.157-2.252-.45a5.096 5.096 0 01-1.744-1.223c-.487-.527-.863-1.162-1.137-1.906a6.345 6.345 0 01-.41-2.33c0-.902.123-1.77.397-2.508a5.554 5.554 0 011.15-1.892 5.133 5.133 0 011.75-1.216c.679-.287 1.425-.423 2.232-.423.808 0 1.553.142 2.237.423a4.88 4.88 0 011.753 1.216 5.644 5.644 0 011.135 1.892c.287.738.431 1.606.431 2.508zm-20.138 0c0 1.12.246 2.363.738 2.882.493.52 1.13.78 1.91.78.424 0 .828-.062 1.204-.178.377-.116.677-.253.917-.417V9.33a10.476 10.476 0 00-1.766-.226c-.971-.028-1.71.37-2.23 1.004-.513.636-.773 1.75-.773 2.788zm7.438 5.274c0 1.824-.466 3.156-1.404 4.004-.936.846-2.367 1.27-4.296 1.27-.705 0-2.17-.137-3.34-.396l.431-2.118c.98.205 2.272.26 2.95.26 1.074 0 1.84-.219 2.299-.656.459-.437.684-1.086.684-1.948v-.437a8.07 8.07 0 01-1.047.397c-.43.13-.93.198-1.492.198-.739 0-1.41-.116-2.018-.349a4.206 4.206 0 01-1.567-1.025c-.431-.45-.774-1.017-1.013-1.694-.24-.677-.363-1.885-.363-2.773 0-.834.13-1.88.384-2.577.26-.696.629-1.298 1.129-1.796.493-.498 1.095-.881 1.8-1.162a6.605 6.605 0 012.428-.457c.87 0 1.67.109 2.45.24.78.129 1.444.265 1.985.415V18.17z' fill='%235468FF'/%3E%3Cpath d='M6.972 6.677v1.627c-.712-.446-1.52-.67-2.425-.67-.585 0-1.045.13-1.38.391a1.24 1.24 0 00-.502 1.03c0 .425.164.765.494 1.02.33.256.835.532 1.516.83.447.192.795.356 1.045.495.25.138.537.332.862.582.324.25.563.548.718.894.154.345.23.741.23 1.188 0 .947-.334 1.691-1.004 2.234-.67.542-1.537.814-2.601.814-1.18 0-2.16-.229-2.936-.686v-1.708c.84.628 1.814.942 2.92.942.585 0 1.048-.136 1.388-.407.34-.271.51-.646.51-1.125 0-.287-.1-.55-.302-.79-.203-.24-.42-.42-.655-.542-.234-.123-.585-.29-1.053-.503a61.27 61.27 0 01-.582-.271 13.67 13.67 0 01-.55-.287 4.275 4.275 0 01-.567-.351 6.92 6.92 0 01-.455-.4c-.18-.17-.31-.34-.39-.51-.08-.17-.155-.37-.224-.598a2.553 2.553 0 01-.104-.742c0-.915.333-1.638.998-2.17.664-.532 1.523-.798 2.576-.798.968 0 1.793.17 2.473.51zm7.468 5.696v-.287c-.022-.607-.187-1.088-.495-1.444-.309-.357-.75-.535-1.324-.535-.532 0-.99.194-1.373.583-.382.388-.622.949-.717 1.683h3.909zm1.005 2.792v1.404c-.596.34-1.383.51-2.362.51-1.255 0-2.255-.377-3-1.132-.744-.755-1.116-1.744-1.116-2.968 0-1.297.34-2.316 1.021-3.055.68-.74 1.548-1.11 2.6-1.11 1.033 0 1.852.323 2.458.966.606.644.91 1.572.91 2.784 0 .33-.033.676-.096 1.038h-5.314c.107.702.405 1.239.894 1.611.49.372 1.106.558 1.85.558.862 0 1.58-.202 2.155-.606zm6.605-1.77h-1.212c-.596 0-1.045.116-1.349.35-.303.234-.454.532-.454.894 0 .372.117.664.35.877.235.213.575.32 1.022.32.51 0 .912-.142 1.204-.424.293-.281.44-.651.44-1.108v-.91zm-4.068-2.554V9.325c.627-.361 1.457-.542 2.489-.542 2.116 0 3.175 1.026 3.175 3.08V17h-1.548v-.957c-.415.68-1.143 1.02-2.186 1.02-.766 0-1.38-.22-1.843-.661-.462-.442-.694-1.003-.694-1.684 0-.776.293-1.38.878-1.81.585-.431 1.404-.647 2.457-.647h1.34V11.8c0-.554-.133-.971-.399-1.253-.266-.282-.707-.423-1.324-.423a4.07 4.07 0 00-2.345.718zm9.333-1.93v1.42c.394-1 1.101-1.5 2.123-1.5.148 0 .313.016.494.048v1.531a1.885 1.885 0 00-.75-.143c-.542 0-.989.24-1.34.718-.351.479-.527 1.048-.527 1.707V17h-1.563V8.91h1.563zm5.01 4.084c.022.82.272 1.492.75 2.019.479.526 1.15.79 2.01.79.639 0 1.235-.176 1.788-.527v1.404c-.521.319-1.186.479-1.995.479-1.265 0-2.276-.4-3.031-1.197-.755-.798-1.133-1.792-1.133-2.984 0-1.16.38-2.151 1.14-2.975.761-.825 1.79-1.237 3.088-1.237.702 0 1.346.149 1.93.447v1.436a3.242 3.242 0 00-1.77-.495c-.84 0-1.513.266-2.019.798-.505.532-.758 1.213-.758 2.042zM40.24 5.72v4.579c.458-1 1.293-1.5 2.505-1.5.787 0 1.42.245 1.899.734.479.49.718 1.17.718 2.042V17h-1.564v-5.106c0-.553-.14-.98-.422-1.284-.282-.303-.652-.455-1.11-.455-.531 0-1.002.202-1.411.606-.41.405-.615 1.022-.615 1.851V17h-1.563V5.72h1.563zm14.966 10.02c.596 0 1.096-.253 1.5-.758.404-.506.606-1.157.606-1.955 0-.915-.202-1.62-.606-2.114-.404-.495-.92-.742-1.548-.742-.553 0-1.05.224-1.491.67-.442.447-.662 1.133-.662 2.058 0 .958.212 1.67.638 2.138.425.469.946.703 1.563.703zM53.004 5.72v4.42c.574-.894 1.388-1.341 2.44-1.341 1.022 0 1.857.383 2.506 1.149.649.766.973 1.781.973 3.047 0 1.138-.309 2.109-.925 2.912-.617.803-1.463 1.205-2.537 1.205-1.075 0-1.894-.447-2.457-1.34V17h-1.58V5.72h1.58zm9.908 11.104l-3.223-7.913h1.739l1.005 2.632 1.26 3.415c.096-.32.48-1.458 1.15-3.415l.909-2.632h1.66l-2.92 7.866c-.777 2.074-1.963 3.11-3.559 3.11a2.92 2.92 0 01-.734-.079v-1.34c.17.042.351.064.543.064 1.032 0 1.755-.57 2.17-1.708z' fill='%235D6494'/%3E%3Cpath d='M89.632 5.967v-.772a.978.978 0 00-.978-.977h-2.28a.978.978 0 00-.978.977v.793c0 .088.082.15.171.13a7.127 7.127 0 011.984-.28c.65 0 1.295.088 1.917.259.082.02.164-.04.164-.13m-6.248 1.01l-.39-.389a.977.977 0 00-1.382 0l-.465.465a.973.973 0 000 1.38l.383.383c.062.061.15.047.205-.014.226-.307.472-.601.746-.874.281-.28.568-.526.883-.751.068-.042.075-.137.02-.2m4.16 2.453v3.341c0 .096.104.165.192.117l2.97-1.537c.068-.034.089-.117.055-.184a3.695 3.695 0 00-3.08-1.866c-.068 0-.136.054-.136.13m0 8.048a4.489 4.489 0 01-4.49-4.482 4.488 4.488 0 014.49-4.482 4.488 4.488 0 014.489 4.482 4.484 4.484 0 01-4.49 4.482m0-10.85a6.363 6.363 0 100 12.729 6.37 6.37 0 006.372-6.368 6.358 6.358 0 00-6.371-6.36' fill='%23FFF'/%3E%3C/g%3E%3C/svg%3E");background-repeat:no-repeat;background-position:50%;background-size:100%;overflow:hidden;text-indent:-9000px;padding:0!important;width:100%;height:100%;display:block}.pagination{position:relative;height:60px;text-align:center}@media (max-width:720px){.pagination{margin-left:1px;margin-right:1px}}.pagination span{line-height:1rem;opacity:.9;cursor:pointer}.pagination span:hover{color:#11a8cd}.pagination span.ellipsis{opacity:.5}.pagination span.ellipsis:before{content:"...";font-size:1.2rem}@media (any-hover:hover){.pagination span.ellipsis.ell-two:hover:before{content:"«"}.pagination span.ellipsis.ell-four:hover:before{content:"»"}}.pagination>span{position:absolute;top:0;padding:1rem 1.2rem;font-size:.95rem}.pagination>span:before{font-size:.4rem}.pagination>span.disabled{color:hsla(0,0%,49%,.5)}.pagination>span.prev{left:0}.pagination>span.prev:before{margin-right:.3rem}.pagination>span.next{right:0}.pagination>span.next:before{float:right;margin-left:.3rem}.pagination>span p{display:inline;line-height:.95rem}.pagination .pagination-list span{display:inline-block;width:2.5rem;height:2.5rem;line-height:2.5rem;margin:.3rem}.pagination .pagination-list span.active{background:#11a8cd;color:var(--mainBg)}@media (max-width:800px){.pagination>span{padding:1rem 1.5rem}.pagination>span p{display:none}}@media (max-width:719px){.pagination>span{padding:.9rem 1.5rem}.pagination .pagination-list span{width:2.3rem;height:2.3rem;line-height:2.3rem;margin:.25rem}}@media (max-width:390px){.pagination>span{padding:.8rem 1.3rem}.pagination .pagination-list span{width:2rem;height:2rem;line-height:2rem;margin:.3rem .1rem .1rem}}.blogger-wrapper{height:auto;display:inline-table;padding-top:0!important;overflow:hidden}.blogger-wrapper .avatar{width:100%;overflow:hidden}.blogger-wrapper .avatar img{width:100%;height:100%}.blogger-wrapper .icons{border-top:none;height:35px;line-height:35px}.blogger-wrapper .icons a{font-size:20px;width:33%;color:var(--textColor);display:block;float:left;text-align:center;opacity:.8}.blogger-wrapper .icons a:hover{color:#11a8cd}.blogger-wrapper .blogger{padding:.3rem .95rem 0}.blogger-wrapper .blogger .name{font-size:1.3rem;display:block;margin-bottom:6px}.blogger-wrapper .blogger .slogan{color:var(--textColor)}.categories-wrapper .title{color:var(--textColor);opacity:.9;font-size:1.2rem;padding:0 .95rem}.categories-wrapper .title:before{margin-right:.3rem}.categories-wrapper .categories{margin-top:.6rem}.categories-wrapper .categories a{display:block;padding:8px .95rem 7px;color:var(--textColor);opacity:.8;font-size:.95rem;line-height:.95rem;position:relative;transition:all .2s;border-left:2px solid transparent;margin-top:-1px;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}@media (max-width:719px){.categories-wrapper .categories a{font-weight:400}}.categories-wrapper .categories a:not(.active):hover{color:#11a8cd;background:#f8f8f8;border-color:#11a8cd}.categories-wrapper .categories a:not(.active):hover span{opacity:.8}.categories-wrapper .categories a span{float:right;background-color:var(--textColor);color:var(--mainBg);border-radius:8px;padding:0 .13rem;min-width:1rem;height:1rem;line-height:1rem;font-size:.6rem;text-align:center;opacity:.6;transition:opacity .3s}.categories-wrapper .categories a.active{background:#11a8cd;color:var(--mainBg);padding-left:.8rem;border-radius:1px;border-color:transparent}.theme-mode-dark .categories-wrapper .categories a:not(.active):hover,.theme-mode-read .categories-wrapper .categories a:not(.active):hover{background:var(--customBlockBg)}.tags-wrapper{padding:0 .95rem}.tags-wrapper .title{color:var(--textColor);opacity:.9;font-size:1.2rem}.tags-wrapper .title:before{margin-right:.3rem}.tags-wrapper .tags{text-align:justify;padding:.8rem .5rem .5rem;margin:0 -.5rem -.5rem}.tags-wrapper .tags a{opacity:.8;display:inline-block;padding:.2rem .4rem;transition:all .4s;background-color:var(--textColor);color:var(--mainBg);border-radius:3px;margin:0 .3rem .5rem 0;min-width:2rem;height:1rem;line-height:1rem;font-size:.8rem;text-align:center}@media (max-width:719px){.tags-wrapper .tags a{font-weight:400}}.tags-wrapper .tags a:hover{opacity:1;transform:scale(1.1)}.tags-wrapper .tags a.active{box-shadow:0 5px 10px -5px var(--randomColor,rgba(0,0,0,.15));transform:scale(1.22);opacity:1}.tags-wrapper .tags a.active:hover{text-decoration:none}.search-box{display:inline-block;position:relative;margin-right:1rem}.search-box input{cursor:text;width:10rem;height:2rem;color:var(--textColor);display:inline-block;border:1px solid var(--borderColor,#ccc);border-radius:2rem;font-size:.9rem;line-height:2rem;padding:0 .5rem 0 2rem;outline:none;transition:width .2s ease;background:url(/blogPages/assets/img/search.83621669.svg) .6rem .5rem no-repeat;background-size:1rem}.search-box input:focus{cursor:auto;border-color:#11a8cd}.search-box .suggestions{background:var(--mainBg,#fff);width:20rem;position:absolute;top:1.5rem;border:1px solid var(--borderColor,#ccc);border-radius:6px;padding:.4rem;list-style-type:none}.search-box .suggestions.align-right{right:0}.search-box .suggestion{line-height:1.4;padding:.4rem .6rem;border-radius:4px;cursor:pointer}.search-box .suggestion a{white-space:normal;color:var(--textColor);opacity:.75}.search-box .suggestion a .page-title{font-weight:600}.search-box .suggestion a .header{font-size:.9em;margin-left:.25em}.search-box .suggestion.focused,.search-box .suggestion:hover{background-color:hsla(0,0%,58.8%,.2)}.search-box .suggestion.focused a{color:#11a8cd}@media (max-width:959px){.search-box input{cursor:pointer;width:0;border-color:transparent;position:relative}.search-box input:focus{cursor:text;left:0;width:10rem}}@media (-ms-high-contrast:none){.search-box input{height:2rem}}@media (max-width:959px) and (min-width:719px){.search-box .suggestions{left:0}}@media (max-width:719px){.search-box{margin-right:0}.search-box input{left:1rem}.search-box .suggestions{right:0}}@media (max-width:419px){.search-box .suggestions{width:calc(100vw - 4rem)}.search-box input:focus{width:8rem}}.sidebar-button{cursor:pointer;display:none;width:1.25rem;height:1.25rem;position:absolute;padding:.6rem;top:.6rem;left:1rem}@media (max-width:719px){.sidebar-button{display:block}}.sidebar-button .icon{display:block;width:1.25rem;height:1.25rem}@media (min-width:720px){.sidebar-button{width:40px;height:40px;display:inline-block;position:fixed;left:0;top:4.6rem;text-align:center;line-height:44px;margin:5px 8px;color:#888;border-radius:50%;padding:0;transition:all .2s}.sidebar-button:hover{background:#11a8cd;color:#fff;box-shadow:0 0 6px #11a8cd}.sidebar-button .icon{display:inline;width:1rem;height:1rem}}.dropdown-enter,.dropdown-leave-to{height:0!important}.article-list{padding:1rem 2rem}@media (max-width:959px){.article-list{padding:1rem 1.5rem}}.article-list.no-article-list{display:none}.article-list .article-title{border-bottom:1px solid var(--borderColor);font-size:1.3rem;padding:1rem}.article-list .article-title a{font-size:1.2rem;color:var(--textColor);opacity:.9}.article-list .article-title a:before{margin-right:.4rem;font-size:1.1rem}.article-list .article-wrapper{overflow:hidden}.article-list .article-wrapper dl{border-bottom:1px dotted var(--borderColor);float:left;display:flex;padding:8px 0;margin:0;height:45px;width:100%}.article-list .article-wrapper dl dd{font-size:1.1rem;color:#f17229;width:50px;text-align:center;margin:0;line-height:45px}.article-list .article-wrapper dl dt{flex:1;display:flex}.article-list .article-wrapper dl dt a{color:var(--textColor);flex:1;display:flex;height:45px;align-items:center;font-weight:400}.article-list .article-wrapper dl dt a div{overflow:hidden;white-space:normal;text-overflow:ellipsis;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical}.article-list .article-wrapper dl dt a div .title-tag{border:1px solid #ff5722;color:#ff5722;font-size:.8rem;padding:0 .35rem;border-radius:.2rem;margin-left:0;transform:translateY(-.05rem);display:inline-block}.article-list .article-wrapper dl dt a:hover{text-decoration:underline}.article-list .article-wrapper dl dt a.more{color:#11a8cd}.article-list .article-wrapper dl dt .date{width:50px;margin-right:15px;color:#999;text-align:right;font-size:.9rem;line-height:45px}.theme-mode-light[data-v-7d2bb426]{--bodyBg:#f4f4f4;--mainBg:#fff;--sidebarBg:hsla(0,0%,100%,0.8);--blurBg:hsla(0,0%,100%,0.9);--customBlockBg:#f1f1f1;--textColor:#00323c;--textLightenColor:#0085ad;--borderColor:rgba(0,0,0,0.12);--codeBg:#f6f6f6;--codeColor:#525252}.theme-mode-light code[class*=language-][data-v-7d2bb426],.theme-mode-light pre[class*=language-][data-v-7d2bb426]{color:#000;background:none;text-shadow:0 1px #fff;font-family:Consolas,Monaco,Andale Mono,Ubuntu Mono,monospace;font-size:1em;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;hyphens:none}.theme-mode-light code[class*=language-][data-v-7d2bb426]::-moz-selection,.theme-mode-light code[class*=language-][data-v-7d2bb426] ::-moz-selection,.theme-mode-light pre[class*=language-][data-v-7d2bb426]::-moz-selection,.theme-mode-light pre[class*=language-][data-v-7d2bb426] ::-moz-selection{text-shadow:none;background:#b3d4fc}.theme-mode-light code[class*=language-][data-v-7d2bb426]::selection,.theme-mode-light code[class*=language-][data-v-7d2bb426] ::selection,.theme-mode-light pre[class*=language-][data-v-7d2bb426]::selection,.theme-mode-light pre[class*=language-][data-v-7d2bb426] ::selection{text-shadow:none;background:#b3d4fc}@media print{.theme-mode-light code[class*=language-][data-v-7d2bb426],.theme-mode-light pre[class*=language-][data-v-7d2bb426]{text-shadow:none}}.theme-mode-light pre[class*=language-][data-v-7d2bb426]{padding:1em;margin:.5em 0;overflow:auto}.theme-mode-light :not(pre)>code[class*=language-][data-v-7d2bb426],.theme-mode-light pre[class*=language-][data-v-7d2bb426]{background:#f5f2f0}.theme-mode-light :not(pre)>code[class*=language-][data-v-7d2bb426]{padding:.1em;border-radius:.3em;white-space:normal}.theme-mode-light .token.cdata[data-v-7d2bb426],.theme-mode-light .token.comment[data-v-7d2bb426],.theme-mode-light .token.doctype[data-v-7d2bb426],.theme-mode-light .token.prolog[data-v-7d2bb426]{color:#708090}.theme-mode-light .token.punctuation[data-v-7d2bb426]{color:#999}.theme-mode-light .namespace[data-v-7d2bb426]{opacity:.7}.theme-mode-light .token.boolean[data-v-7d2bb426],.theme-mode-light .token.constant[data-v-7d2bb426],.theme-mode-light .token.deleted[data-v-7d2bb426],.theme-mode-light .token.number[data-v-7d2bb426],.theme-mode-light .token.property[data-v-7d2bb426],.theme-mode-light .token.symbol[data-v-7d2bb426],.theme-mode-light .token.tag[data-v-7d2bb426]{color:#905}.theme-mode-light .token.attr-name[data-v-7d2bb426],.theme-mode-light .token.builtin[data-v-7d2bb426],.theme-mode-light .token.char[data-v-7d2bb426],.theme-mode-light .token.inserted[data-v-7d2bb426],.theme-mode-light .token.selector[data-v-7d2bb426],.theme-mode-light .token.string[data-v-7d2bb426]{color:#690}.theme-mode-light .language-css .token.string[data-v-7d2bb426],.theme-mode-light .style .token.string[data-v-7d2bb426],.theme-mode-light .token.entity[data-v-7d2bb426],.theme-mode-light .token.operator[data-v-7d2bb426],.theme-mode-light .token.url[data-v-7d2bb426]{color:#9a6e3a;background:hsla(0,0%,100%,.5)}.theme-mode-light .token.atrule[data-v-7d2bb426],.theme-mode-light .token.attr-value[data-v-7d2bb426],.theme-mode-light .token.keyword[data-v-7d2bb426]{color:#07a}.theme-mode-light .token.class-name[data-v-7d2bb426],.theme-mode-light .token.function[data-v-7d2bb426]{color:#dd4a68}.theme-mode-light .token.important[data-v-7d2bb426],.theme-mode-light .token.regex[data-v-7d2bb426],.theme-mode-light .token.variable[data-v-7d2bb426]{color:#e90}.theme-mode-light .token.bold[data-v-7d2bb426],.theme-mode-light .token.important[data-v-7d2bb426]{font-weight:700}.theme-mode-light .token.italic[data-v-7d2bb426]{font-style:italic}.theme-mode-light .token.entity[data-v-7d2bb426]{cursor:help}.theme-mode-light div[class*=language-] .highlight-lines .highlighted[data-v-7d2bb426],.theme-mode-light div[class*=language-].line-numbers-mode .highlight-lines .highlighted[data-v-7d2bb426]:before{background-color:hsla(0,0%,78.4%,.4)}.theme-mode-dark[data-v-7d2bb426]{--bodyBg:#27272b;--mainBg:#1e1e22;--sidebarBg:rgba(30,30,34,0.8);--blurBg:rgba(30,30,34,0.8);--customBlockBg:#27272b;--textColor:#9b9baa;--textLightenColor:#0085ad;--borderColor:#30363d;--codeBg:#252526;--codeColor:#fff}.theme-mode-dark code[class*=language-][data-v-7d2bb426],.theme-mode-dark pre[class*=language-][data-v-7d2bb426]{color:#ccc;background:none;text-shadow:none;font-family:Consolas,Monaco,Andale Mono,Ubuntu Mono,monospace;font-size:1em;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;hyphens:none}.theme-mode-dark pre[class*=language-][data-v-7d2bb426]{padding:1em;margin:.5em 0;overflow:auto}.theme-mode-dark :not(pre)>code[class*=language-][data-v-7d2bb426],.theme-mode-dark pre[class*=language-][data-v-7d2bb426]{background:#2d2d2d}.theme-mode-dark :not(pre)>code[class*=language-][data-v-7d2bb426]{padding:.1em;border-radius:.3em;white-space:normal}.theme-mode-dark .token.block-comment[data-v-7d2bb426],.theme-mode-dark .token.cdata[data-v-7d2bb426],.theme-mode-dark .token.comment[data-v-7d2bb426],.theme-mode-dark .token.doctype[data-v-7d2bb426],.theme-mode-dark .token.prolog[data-v-7d2bb426]{color:#999}.theme-mode-dark .token.punctuation[data-v-7d2bb426]{color:#ccc}.theme-mode-dark .token.attr-name[data-v-7d2bb426],.theme-mode-dark .token.deleted[data-v-7d2bb426],.theme-mode-dark .token.namespace[data-v-7d2bb426],.theme-mode-dark .token.tag[data-v-7d2bb426]{color:#e2777a}.theme-mode-dark .token.function-name[data-v-7d2bb426]{color:#6196cc}.theme-mode-dark .token.boolean[data-v-7d2bb426],.theme-mode-dark .token.function[data-v-7d2bb426],.theme-mode-dark .token.number[data-v-7d2bb426]{color:#f08d49}.theme-mode-dark .token.class-name[data-v-7d2bb426],.theme-mode-dark .token.constant[data-v-7d2bb426],.theme-mode-dark .token.property[data-v-7d2bb426],.theme-mode-dark .token.symbol[data-v-7d2bb426]{color:#f8c555}.theme-mode-dark .token.atrule[data-v-7d2bb426],.theme-mode-dark .token.builtin[data-v-7d2bb426],.theme-mode-dark .token.important[data-v-7d2bb426],.theme-mode-dark .token.keyword[data-v-7d2bb426],.theme-mode-dark .token.selector[data-v-7d2bb426]{color:#cc99cd}.theme-mode-dark .token.attr-value[data-v-7d2bb426],.theme-mode-dark .token.char[data-v-7d2bb426],.theme-mode-dark .token.regex[data-v-7d2bb426],.theme-mode-dark .token.string[data-v-7d2bb426],.theme-mode-dark .token.variable[data-v-7d2bb426]{color:#7ec699}.theme-mode-dark .token.entity[data-v-7d2bb426],.theme-mode-dark .token.operator[data-v-7d2bb426],.theme-mode-dark .token.url[data-v-7d2bb426]{color:#67cdcc}.theme-mode-dark .language-css .token.string[data-v-7d2bb426],.theme-mode-dark .style .token.string[data-v-7d2bb426],.theme-mode-dark .token.entity[data-v-7d2bb426],.theme-mode-dark .token.operator[data-v-7d2bb426],.theme-mode-dark .token.url[data-v-7d2bb426]{background:none}.theme-mode-dark .token.bold[data-v-7d2bb426],.theme-mode-dark .token.important[data-v-7d2bb426]{font-weight:700}.theme-mode-dark .token.italic[data-v-7d2bb426]{font-style:italic}.theme-mode-dark .token.entity[data-v-7d2bb426]{cursor:help}.theme-mode-dark .token.inserted[data-v-7d2bb426]{color:green}.theme-mode-read[data-v-7d2bb426]{--bodyBg:#ececcc;--mainBg:#f5f5d5;--sidebarBg:rgba(245,245,213,0.8);--blurBg:rgba(245,245,213,0.9);--customBlockBg:#ececcc;--textColor:#704214;--textLightenColor:#963;--borderColor:rgba(0,0,0,0.15);--codeBg:#282c34;--codeColor:#fff}.theme-mode-read code[class*=language-][data-v-7d2bb426],.theme-mode-read pre[class*=language-][data-v-7d2bb426]{color:#ccc;background:none;text-shadow:none;font-family:Consolas,Monaco,Andale Mono,Ubuntu Mono,monospace;font-size:1em;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;hyphens:none}.theme-mode-read pre[class*=language-][data-v-7d2bb426]{padding:1em;margin:.5em 0;overflow:auto}.theme-mode-read :not(pre)>code[class*=language-][data-v-7d2bb426],.theme-mode-read pre[class*=language-][data-v-7d2bb426]{background:#2d2d2d}.theme-mode-read :not(pre)>code[class*=language-][data-v-7d2bb426]{padding:.1em;border-radius:.3em;white-space:normal}.theme-mode-read .token.block-comment[data-v-7d2bb426],.theme-mode-read .token.cdata[data-v-7d2bb426],.theme-mode-read .token.comment[data-v-7d2bb426],.theme-mode-read .token.doctype[data-v-7d2bb426],.theme-mode-read .token.prolog[data-v-7d2bb426]{color:#999}.theme-mode-read .token.punctuation[data-v-7d2bb426]{color:#ccc}.theme-mode-read .token.attr-name[data-v-7d2bb426],.theme-mode-read .token.deleted[data-v-7d2bb426],.theme-mode-read .token.namespace[data-v-7d2bb426],.theme-mode-read .token.tag[data-v-7d2bb426]{color:#e2777a}.theme-mode-read .token.function-name[data-v-7d2bb426]{color:#6196cc}.theme-mode-read .token.boolean[data-v-7d2bb426],.theme-mode-read .token.function[data-v-7d2bb426],.theme-mode-read .token.number[data-v-7d2bb426]{color:#f08d49}.theme-mode-read .token.class-name[data-v-7d2bb426],.theme-mode-read .token.constant[data-v-7d2bb426],.theme-mode-read .token.property[data-v-7d2bb426],.theme-mode-read .token.symbol[data-v-7d2bb426]{color:#f8c555}.theme-mode-read .token.atrule[data-v-7d2bb426],.theme-mode-read .token.builtin[data-v-7d2bb426],.theme-mode-read .token.important[data-v-7d2bb426],.theme-mode-read .token.keyword[data-v-7d2bb426],.theme-mode-read .token.selector[data-v-7d2bb426]{color:#cc99cd}.theme-mode-read .token.attr-value[data-v-7d2bb426],.theme-mode-read .token.char[data-v-7d2bb426],.theme-mode-read .token.regex[data-v-7d2bb426],.theme-mode-read .token.string[data-v-7d2bb426],.theme-mode-read .token.variable[data-v-7d2bb426]{color:#7ec699}.theme-mode-read .token.entity[data-v-7d2bb426],.theme-mode-read .token.operator[data-v-7d2bb426],.theme-mode-read .token.url[data-v-7d2bb426]{color:#67cdcc}.theme-mode-read .language-css .token.string[data-v-7d2bb426],.theme-mode-read .style .token.string[data-v-7d2bb426],.theme-mode-read .token.entity[data-v-7d2bb426],.theme-mode-read .token.operator[data-v-7d2bb426],.theme-mode-read .token.url[data-v-7d2bb426]{background:none}.theme-mode-read .token.bold[data-v-7d2bb426],.theme-mode-read .token.important[data-v-7d2bb426]{font-weight:700}.theme-mode-read .token.italic[data-v-7d2bb426]{font-style:italic}.theme-mode-read .token.entity[data-v-7d2bb426]{cursor:help}.theme-mode-read .token.inserted[data-v-7d2bb426]{color:green}.theme-style-line.theme-mode-light[data-v-7d2bb426]{--bodyBg:#fff}.theme-style-line.theme-mode-dark[data-v-7d2bb426]{--bodyBg:#1e1e22}.theme-style-line.theme-mode-read[data-v-7d2bb426]{--bodyBg:#f5f5d5}.home-wrapper .banner[data-v-7d2bb426]{width:100%;min-height:450px;margin-top:3.6rem;color:#fff;position:relative;overflow:hidden}.home-wrapper .banner .banner-conent[data-v-7d2bb426]{max-width:1100px;margin:0 auto;position:relative;z-index:1;overflow:hidden}.home-wrapper .banner .banner-conent .hero[data-v-7d2bb426]{text-align:center;margin-top:3rem}.home-wrapper .banner .banner-conent .hero img[data-v-7d2bb426]{max-width:100%;max-height:240px;display:block;margin:2rem auto 1.5rem}.home-wrapper .banner .banner-conent .hero h1[data-v-7d2bb426]{margin:0;font-size:3.2rem}.home-wrapper .banner .banner-conent .hero .action[data-v-7d2bb426],.home-wrapper .banner .banner-conent .hero .description[data-v-7d2bb426]{margin:1.5rem auto}.home-wrapper .banner .banner-conent .hero .description[data-v-7d2bb426]{max-width:40rem;font-size:1.1rem;line-height:1.3;opacity:.9}.home-wrapper .banner .banner-conent .hero .action-button[data-v-7d2bb426]{display:inline-block;font-size:1.2rem;background-color:#11a8cd;padding:.8rem 1.6rem;border-radius:4px;transition:background-color .1s ease;box-sizing:border-box;border-bottom:1px solid #0f97b9;color:#fff}.home-wrapper .banner .banner-conent .hero .action-button[data-v-7d2bb426]:hover{background-color:#13bee8}.home-wrapper .banner .banner-conent .features[data-v-7d2bb426]{padding:2rem 0;margin-top:2.5rem;display:flex;flex-wrap:wrap;align-items:flex-start;align-content:stretch;justify-content:space-between}.home-wrapper .banner .banner-conent .feature[data-v-7d2bb426]{flex-grow:1;flex-basis:30%;max-width:30%;text-align:center}.home-wrapper .banner .banner-conent .feature a[data-v-7d2bb426]{color:inherit}.home-wrapper .banner .banner-conent .feature a .feature-img[data-v-7d2bb426]{width:10rem;height:10rem;animation:heart-7d2bb426 1.2s ease-in-out 0s infinite alternate;animation-play-state:paused}.home-wrapper .banner .banner-conent .feature a h2[data-v-7d2bb426]{font-weight:500;font-size:1.3rem;border-bottom:none;padding-bottom:0}.home-wrapper .banner .banner-conent .feature a p[data-v-7d2bb426]{opacity:.8;padding:0 .8rem}.home-wrapper .banner .banner-conent .feature:hover .feature-img[data-v-7d2bb426]{animation-play-state:running}.home-wrapper .banner .banner-conent .feature:hover h2[data-v-7d2bb426],.home-wrapper .banner .banner-conent .feature:hover p[data-v-7d2bb426]{color:#11a8cd}.home-wrapper .banner .slide-banner[data-v-7d2bb426]{margin-top:2rem}.home-wrapper .banner .slide-banner .banner-wrapper[data-v-7d2bb426]{position:relative}.home-wrapper .banner .slide-banner .slide-banner-scroll[data-v-7d2bb426]{min-height:1px;overflow:hidden}.home-wrapper .banner .slide-banner .slide-banner-wrapper[data-v-7d2bb426]{height:300px}.home-wrapper .banner .slide-banner .slide-banner-wrapper .slide-item[data-v-7d2bb426]{display:inline-block;height:300px;width:100%;text-align:center}.home-wrapper .banner .slide-banner .slide-banner-wrapper .slide-item a[data-v-7d2bb426]{color:inherit}.home-wrapper .banner .slide-banner .slide-banner-wrapper .slide-item a .feature-img[data-v-7d2bb426]{width:10rem;height:10rem}.home-wrapper .banner .slide-banner .slide-banner-wrapper .slide-item a h2[data-v-7d2bb426]{font-size:1.1rem;font-weight:500;border-bottom:none;padding-bottom:0}.home-wrapper .banner .slide-banner .slide-banner-wrapper .slide-item a p[data-v-7d2bb426]{opacity:.8;padding:0 .8rem}.home-wrapper .banner .slide-banner .docs-wrapper[data-v-7d2bb426]{position:absolute;bottom:25px;left:50%;transform:translateX(-50%)}.home-wrapper .banner .slide-banner .docs-wrapper .doc[data-v-7d2bb426]{display:inline-block;margin:0 4px;width:8px;height:8px;border-radius:50%;background:var(--textColor);opacity:.9}.home-wrapper .banner .slide-banner .docs-wrapper .doc.active[data-v-7d2bb426]{opacity:.5}.home-wrapper .banner.hide-banner[data-v-7d2bb426]{display:none}.home-wrapper .banner.hide-banner+.main-wrapper[data-v-7d2bb426]{margin-top:4.5rem}.home-wrapper .main-wrapper[data-v-7d2bb426]{margin-top:2rem}.home-wrapper .main-wrapper .main-left .card-box[data-v-7d2bb426]{margin-bottom:2rem}.home-wrapper .main-wrapper .main-left .pagination[data-v-7d2bb426]{margin-bottom:3rem}.home-wrapper .main-wrapper .main-left .theme-vdoing-content[data-v-7d2bb426]{padding:0 2rem;overflow:hidden;border:none}.home-wrapper .main-wrapper .main-left .theme-vdoing-content[data-v-7d2bb426]>:first-child{padding-top:2rem}.home-wrapper .main-wrapper .main-left .theme-vdoing-content[data-v-7d2bb426]>:last-child{padding-bottom:2rem}.home-wrapper .main-wrapper .main-right .custom-html-box[data-v-7d2bb426]{padding:0;overflow:hidden}@media (max-width:1025px){.home-wrapper .banner .banner-conent .hero h1[data-v-7d2bb426]{font-size:2.5rem}.home-wrapper .banner .banner-conent .hero .description[data-v-7d2bb426]{font-size:1rem}.home-wrapper .banner .banner-conent .feature a h2[data-v-7d2bb426]{font-size:1.1rem}.home-wrapper .banner .banner-conent .feature a .feature-img[data-v-7d2bb426]{width:9rem;height:9rem}}@media (max-width:719px){.home-wrapper .banner .banner-conent .features[data-v-7d2bb426]{display:none!important}}@media (max-width:419px){.home-wrapper .banner-conent[data-v-7d2bb426]{padding-left:1.5rem;padding-right:1.5rem}.home-wrapper .banner-conent .hero img[data-v-7d2bb426]{max-height:210px;margin:2rem auto 1.2rem}.home-wrapper .banner-conent .hero h1[data-v-7d2bb426]{font-size:2rem}.home-wrapper .banner-conent .hero .action[data-v-7d2bb426],.home-wrapper .banner-conent .hero .description[data-v-7d2bb426],.home-wrapper .banner-conent .hero h1[data-v-7d2bb426]{margin:1.2rem auto}.home-wrapper .banner-conent .hero .description[data-v-7d2bb426]{font-size:1.2rem}.home-wrapper .banner-conent .hero .action-button[data-v-7d2bb426]{font-size:1rem;padding:.6rem 1.2rem}.home-wrapper .banner-conent .feature h2[data-v-7d2bb426]{font-size:1.25rem}}@media (max-width:719px){.theme-style-line .main-wrapper[data-v-7d2bb426]{margin-top:-1px}}@keyframes heart-7d2bb426{0%{transform:translate(0)}to{transform:translateY(8px)}}.dropdown-wrapper{cursor:pointer}.dropdown-wrapper .dropdown-title{display:block;font-size:.9rem;font-family:inherit;cursor:inherit;padding:inherit;line-height:1.4rem;background:transparent;border:none;font-weight:500;color:var(--textColor)}.dropdown-wrapper .dropdown-title:hover{border-color:transparent}.dropdown-wrapper .dropdown-title .arrow{vertical-align:middle;margin-top:-1px;margin-left:.4rem}.dropdown-wrapper .nav-dropdown .dropdown-item{color:inherit;line-height:1.7rem}.dropdown-wrapper .nav-dropdown .dropdown-item h4{margin:.45rem 0 0;border-top:1px solid var(--borderColor);padding:.45rem 1.5rem 0 1.25rem}.dropdown-wrapper .nav-dropdown .dropdown-item .dropdown-subitem-wrapper{padding:0;list-style:none}.dropdown-wrapper .nav-dropdown .dropdown-item .dropdown-subitem-wrapper .dropdown-subitem{font-size:.9em}.dropdown-wrapper .nav-dropdown .dropdown-item a{display:block;line-height:1.7rem;position:relative;border-bottom:none;font-weight:400;margin-bottom:0;padding:0 1.5rem 0 1.25rem}.dropdown-wrapper .nav-dropdown .dropdown-item a.router-link-active,.dropdown-wrapper .nav-dropdown .dropdown-item a:hover{color:#11a8cd}.dropdown-wrapper .nav-dropdown .dropdown-item a.router-link-active:after{content:"";width:0;height:0;border-left:5px solid #11a8cd;border-top:3px solid transparent;border-bottom:3px solid transparent;position:absolute;top:calc(50% - 2px);left:9px}.dropdown-wrapper .nav-dropdown .dropdown-item:first-child h4{margin-top:0;padding-top:0;border-top:0}@media (max-width:719px){.dropdown-wrapper.open .dropdown-title{margin-bottom:.5rem}.dropdown-wrapper .dropdown-title{font-weight:600;font-size:inherit}.dropdown-wrapper .dropdown-title:hover{color:#11a8cd}.dropdown-wrapper .dropdown-title .link-title{display:none}.dropdown-wrapper .dropdown-title .title{display:inline-block!important}.dropdown-wrapper .nav-dropdown{transition:height .1s ease-out;overflow:hidden}.dropdown-wrapper .nav-dropdown .dropdown-item h4{border-top:0;margin-top:0;padding-top:0}.dropdown-wrapper .nav-dropdown .dropdown-item>a,.dropdown-wrapper .nav-dropdown .dropdown-item h4{font-size:15px;line-height:2rem}.dropdown-wrapper .nav-dropdown .dropdown-item .dropdown-subitem{font-size:14px;padding-left:1rem}}@media (min-width:719px){.dropdown-wrapper{height:1.8rem}.dropdown-wrapper.open .nav-dropdown,.dropdown-wrapper:hover .nav-dropdown{display:block!important}.dropdown-wrapper.open:blur{display:none}.dropdown-wrapper .dropdown-title .arrow{border-left:4px solid transparent;border-right:4px solid transparent;border-top:6px solid #ccc;border-bottom:0}.dropdown-wrapper .nav-dropdown{display:none;height:auto!important;box-sizing:border-box;max-height:calc(100vh - 2.7rem);overflow-y:auto;position:absolute;top:100%;right:0;background-color:var(--mainBg);padding:.6rem 0;border-bottom-color:var(--borderColor);border:1px solid var(--borderColor);text-align:left;border-radius:.25rem;white-space:nowrap;margin:0}.nav-item .dropdown-title a.router-link-active,.nav-item .dropdown-title a:hover{margin-bottom:-2px;border-bottom:2px solid #13b9e2}}.nav-links{display:inline-block}.nav-links a{line-height:1.4rem;color:inherit}.nav-links a.router-link-active,.nav-links a:hover{color:#11a8cd}.nav-links .nav-item{position:relative;display:inline-block;margin-left:1.5rem;line-height:2rem}.nav-links .nav-item:first-child{margin-left:0}.nav-links .repo-link{margin-left:1.5rem}@media (max-width:959px){.nav-links .nav-item{margin-left:1.2rem}}@media (max-width:719px){.nav-links .nav-item,.nav-links .repo-link{margin-left:0}}@media (min-width:719px){.nav-links a.router-link-active,.nav-links a:hover{color:var(--textColor)}.nav-item>a:not(.external).router-link-active,.nav-item>a:not(.external):hover{margin-bottom:-2px;border-bottom:2px solid #13b9e2}}.navbar{padding:.7rem 1.5rem;line-height:2.2rem;transition:transform .3s}.navbar a,.navbar img,.navbar span{display:inline-block}.navbar .logo{height:2.2rem;min-width:2.2rem;margin-right:.8rem;vertical-align:top}.navbar .site-name{font-size:1.3rem;font-weight:600;color:var(--textColor);position:relative}.navbar .links{padding-left:1.5rem;box-sizing:border-box;white-space:nowrap;font-size:.9rem;position:absolute;right:1.5rem;top:.7rem;display:flex}.navbar .links .search-box{flex:0 0 auto;vertical-align:top}.hide-navbar .navbar{transform:translateY(-100%)}@media (max-width:959px){.navbar .site-name{display:none}}@media (max-width:719px){.navbar{padding-left:4rem}.navbar .can-hide{display:none}.navbar .links{padding-left:1.5rem}.navbar .site-name{width:calc(100vw - 9.4rem);overflow:hidden;white-space:nowrap;text-overflow:ellipsis}}.page-edit{max-width:860px;padding-top:1rem;padding-bottom:1rem;overflow:auto}.page-edit .edit-link{display:inline-block;float:left;margin:0 2rem .5rem 0}.page-edit .edit-link a{margin-right:.25rem}.page-edit .tags{float:left}.page-edit .tags a{margin:0 .8rem .5rem 0;display:inline-block;color:var(--textLightenColor);padding:.2rem .7rem;font-size:.9em;background-color:hsla(0,0%,50.2%,.08);border-radius:3px;opacity:.8}.page-edit .last-updated{float:right;font-size:.9em}.page-edit .last-updated .prefix{font-weight:500;color:var(--textColor);opacity:.8}.page-edit .last-updated .time{font-weight:400;color:#aaa}@media (max-width:719px){.page-edit .edit-link,.page-edit .tags{margin-bottom:.5rem}.page-edit .last-updated{width:100%;font-size:.8em;text-align:left}}.page-nav{max-width:860px;padding-top:1rem;padding-bottom:0}.page-nav .inner{min-height:2rem;margin-top:0;border-top:1px solid var(--borderColor);padding-top:1rem;overflow:auto}.page-nav .next{float:right}.page-nav-centre-wrap .page-nav-centre{position:fixed;top:50%;width:80px;height:70px;margin-top:-35px;outline:0;transition:all .2s;border-radius:3px;opacity:.55;z-index:99}@media (max-width:1340px){.page-nav-centre-wrap .page-nav-centre{width:50px}}@media (max-width:960px){.page-nav-centre-wrap .page-nav-centre{display:none}}.page-nav-centre-wrap .page-nav-centre:hover{background:hsla(0,0%,60%,.15);opacity:1}.page-nav-centre-wrap .page-nav-centre:hover .tooltip{display:block}.page-nav-centre-wrap .page-nav-centre:before{content:"";display:block;width:10px;height:10px;border-top:2px solid #999;border-right:2px solid #999;position:absolute;top:0;right:0;bottom:0;left:0;margin:auto}.page-nav-centre-wrap .page-nav-centre .tooltip{display:none;background:rgba(0,0,0,.5);color:#fff;padding:4px 8px;font-size:13px;border-radius:3px;position:fixed;max-width:200px;z-index:99}.page-nav-centre-wrap .page-nav-centre-prev{left:0}.page-nav-centre-wrap .page-nav-centre-prev:before{transform:rotate(-135deg)}.page-nav-centre-wrap .page-nav-centre-next{right:0}.page-nav-centre-wrap .page-nav-centre-next:before{transform:rotate(45deg)}.sidebar-open .page-nav-centre-wrap .page-nav-centre-prev{left:18rem}.no-sidebar .page-nav-centre-wrap .page-nav-centre-prev{left:0}.theme-mode-light[data-v-06225672]{--bodyBg:#f4f4f4;--mainBg:#fff;--sidebarBg:hsla(0,0%,100%,0.8);--blurBg:hsla(0,0%,100%,0.9);--customBlockBg:#f1f1f1;--textColor:#00323c;--textLightenColor:#0085ad;--borderColor:rgba(0,0,0,0.12);--codeBg:#f6f6f6;--codeColor:#525252}.theme-mode-light code[class*=language-][data-v-06225672],.theme-mode-light pre[class*=language-][data-v-06225672]{color:#000;background:none;text-shadow:0 1px #fff;font-family:Consolas,Monaco,Andale Mono,Ubuntu Mono,monospace;font-size:1em;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;hyphens:none}.theme-mode-light code[class*=language-][data-v-06225672]::-moz-selection,.theme-mode-light code[class*=language-][data-v-06225672] ::-moz-selection,.theme-mode-light pre[class*=language-][data-v-06225672]::-moz-selection,.theme-mode-light pre[class*=language-][data-v-06225672] ::-moz-selection{text-shadow:none;background:#b3d4fc}.theme-mode-light code[class*=language-][data-v-06225672]::selection,.theme-mode-light code[class*=language-][data-v-06225672] ::selection,.theme-mode-light pre[class*=language-][data-v-06225672]::selection,.theme-mode-light pre[class*=language-][data-v-06225672] ::selection{text-shadow:none;background:#b3d4fc}@media print{.theme-mode-light code[class*=language-][data-v-06225672],.theme-mode-light pre[class*=language-][data-v-06225672]{text-shadow:none}}.theme-mode-light pre[class*=language-][data-v-06225672]{padding:1em;margin:.5em 0;overflow:auto}.theme-mode-light :not(pre)>code[class*=language-][data-v-06225672],.theme-mode-light pre[class*=language-][data-v-06225672]{background:#f5f2f0}.theme-mode-light :not(pre)>code[class*=language-][data-v-06225672]{padding:.1em;border-radius:.3em;white-space:normal}.theme-mode-light .token.cdata[data-v-06225672],.theme-mode-light .token.comment[data-v-06225672],.theme-mode-light .token.doctype[data-v-06225672],.theme-mode-light .token.prolog[data-v-06225672]{color:#708090}.theme-mode-light .token.punctuation[data-v-06225672]{color:#999}.theme-mode-light .namespace[data-v-06225672]{opacity:.7}.theme-mode-light .token.boolean[data-v-06225672],.theme-mode-light .token.constant[data-v-06225672],.theme-mode-light .token.deleted[data-v-06225672],.theme-mode-light .token.number[data-v-06225672],.theme-mode-light .token.property[data-v-06225672],.theme-mode-light .token.symbol[data-v-06225672],.theme-mode-light .token.tag[data-v-06225672]{color:#905}.theme-mode-light .token.attr-name[data-v-06225672],.theme-mode-light .token.builtin[data-v-06225672],.theme-mode-light .token.char[data-v-06225672],.theme-mode-light .token.inserted[data-v-06225672],.theme-mode-light .token.selector[data-v-06225672],.theme-mode-light .token.string[data-v-06225672]{color:#690}.theme-mode-light .language-css .token.string[data-v-06225672],.theme-mode-light .style .token.string[data-v-06225672],.theme-mode-light .token.entity[data-v-06225672],.theme-mode-light .token.operator[data-v-06225672],.theme-mode-light .token.url[data-v-06225672]{color:#9a6e3a;background:hsla(0,0%,100%,.5)}.theme-mode-light .token.atrule[data-v-06225672],.theme-mode-light .token.attr-value[data-v-06225672],.theme-mode-light .token.keyword[data-v-06225672]{color:#07a}.theme-mode-light .token.class-name[data-v-06225672],.theme-mode-light .token.function[data-v-06225672]{color:#dd4a68}.theme-mode-light .token.important[data-v-06225672],.theme-mode-light .token.regex[data-v-06225672],.theme-mode-light .token.variable[data-v-06225672]{color:#e90}.theme-mode-light .token.bold[data-v-06225672],.theme-mode-light .token.important[data-v-06225672]{font-weight:700}.theme-mode-light .token.italic[data-v-06225672]{font-style:italic}.theme-mode-light .token.entity[data-v-06225672]{cursor:help}.theme-mode-light div[class*=language-] .highlight-lines .highlighted[data-v-06225672],.theme-mode-light div[class*=language-].line-numbers-mode .highlight-lines .highlighted[data-v-06225672]:before{background-color:hsla(0,0%,78.4%,.4)}.theme-mode-dark[data-v-06225672]{--bodyBg:#27272b;--mainBg:#1e1e22;--sidebarBg:rgba(30,30,34,0.8);--blurBg:rgba(30,30,34,0.8);--customBlockBg:#27272b;--textColor:#9b9baa;--textLightenColor:#0085ad;--borderColor:#30363d;--codeBg:#252526;--codeColor:#fff}.theme-mode-dark code[class*=language-][data-v-06225672],.theme-mode-dark pre[class*=language-][data-v-06225672]{color:#ccc;background:none;text-shadow:none;font-family:Consolas,Monaco,Andale Mono,Ubuntu Mono,monospace;font-size:1em;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;hyphens:none}.theme-mode-dark pre[class*=language-][data-v-06225672]{padding:1em;margin:.5em 0;overflow:auto}.theme-mode-dark :not(pre)>code[class*=language-][data-v-06225672],.theme-mode-dark pre[class*=language-][data-v-06225672]{background:#2d2d2d}.theme-mode-dark :not(pre)>code[class*=language-][data-v-06225672]{padding:.1em;border-radius:.3em;white-space:normal}.theme-mode-dark .token.block-comment[data-v-06225672],.theme-mode-dark .token.cdata[data-v-06225672],.theme-mode-dark .token.comment[data-v-06225672],.theme-mode-dark .token.doctype[data-v-06225672],.theme-mode-dark .token.prolog[data-v-06225672]{color:#999}.theme-mode-dark .token.punctuation[data-v-06225672]{color:#ccc}.theme-mode-dark .token.attr-name[data-v-06225672],.theme-mode-dark .token.deleted[data-v-06225672],.theme-mode-dark .token.namespace[data-v-06225672],.theme-mode-dark .token.tag[data-v-06225672]{color:#e2777a}.theme-mode-dark .token.function-name[data-v-06225672]{color:#6196cc}.theme-mode-dark .token.boolean[data-v-06225672],.theme-mode-dark .token.function[data-v-06225672],.theme-mode-dark .token.number[data-v-06225672]{color:#f08d49}.theme-mode-dark .token.class-name[data-v-06225672],.theme-mode-dark .token.constant[data-v-06225672],.theme-mode-dark .token.property[data-v-06225672],.theme-mode-dark .token.symbol[data-v-06225672]{color:#f8c555}.theme-mode-dark .token.atrule[data-v-06225672],.theme-mode-dark .token.builtin[data-v-06225672],.theme-mode-dark .token.important[data-v-06225672],.theme-mode-dark .token.keyword[data-v-06225672],.theme-mode-dark .token.selector[data-v-06225672]{color:#cc99cd}.theme-mode-dark .token.attr-value[data-v-06225672],.theme-mode-dark .token.char[data-v-06225672],.theme-mode-dark .token.regex[data-v-06225672],.theme-mode-dark .token.string[data-v-06225672],.theme-mode-dark .token.variable[data-v-06225672]{color:#7ec699}.theme-mode-dark .token.entity[data-v-06225672],.theme-mode-dark .token.operator[data-v-06225672],.theme-mode-dark .token.url[data-v-06225672]{color:#67cdcc}.theme-mode-dark .language-css .token.string[data-v-06225672],.theme-mode-dark .style .token.string[data-v-06225672],.theme-mode-dark .token.entity[data-v-06225672],.theme-mode-dark .token.operator[data-v-06225672],.theme-mode-dark .token.url[data-v-06225672]{background:none}.theme-mode-dark .token.bold[data-v-06225672],.theme-mode-dark .token.important[data-v-06225672]{font-weight:700}.theme-mode-dark .token.italic[data-v-06225672]{font-style:italic}.theme-mode-dark .token.entity[data-v-06225672]{cursor:help}.theme-mode-dark .token.inserted[data-v-06225672]{color:green}.theme-mode-read[data-v-06225672]{--bodyBg:#ececcc;--mainBg:#f5f5d5;--sidebarBg:rgba(245,245,213,0.8);--blurBg:rgba(245,245,213,0.9);--customBlockBg:#ececcc;--textColor:#704214;--textLightenColor:#963;--borderColor:rgba(0,0,0,0.15);--codeBg:#282c34;--codeColor:#fff}.theme-mode-read code[class*=language-][data-v-06225672],.theme-mode-read pre[class*=language-][data-v-06225672]{color:#ccc;background:none;text-shadow:none;font-family:Consolas,Monaco,Andale Mono,Ubuntu Mono,monospace;font-size:1em;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;hyphens:none}.theme-mode-read pre[class*=language-][data-v-06225672]{padding:1em;margin:.5em 0;overflow:auto}.theme-mode-read :not(pre)>code[class*=language-][data-v-06225672],.theme-mode-read pre[class*=language-][data-v-06225672]{background:#2d2d2d}.theme-mode-read :not(pre)>code[class*=language-][data-v-06225672]{padding:.1em;border-radius:.3em;white-space:normal}.theme-mode-read .token.block-comment[data-v-06225672],.theme-mode-read .token.cdata[data-v-06225672],.theme-mode-read .token.comment[data-v-06225672],.theme-mode-read .token.doctype[data-v-06225672],.theme-mode-read .token.prolog[data-v-06225672]{color:#999}.theme-mode-read .token.punctuation[data-v-06225672]{color:#ccc}.theme-mode-read .token.attr-name[data-v-06225672],.theme-mode-read .token.deleted[data-v-06225672],.theme-mode-read .token.namespace[data-v-06225672],.theme-mode-read .token.tag[data-v-06225672]{color:#e2777a}.theme-mode-read .token.function-name[data-v-06225672]{color:#6196cc}.theme-mode-read .token.boolean[data-v-06225672],.theme-mode-read .token.function[data-v-06225672],.theme-mode-read .token.number[data-v-06225672]{color:#f08d49}.theme-mode-read .token.class-name[data-v-06225672],.theme-mode-read .token.constant[data-v-06225672],.theme-mode-read .token.property[data-v-06225672],.theme-mode-read .token.symbol[data-v-06225672]{color:#f8c555}.theme-mode-read .token.atrule[data-v-06225672],.theme-mode-read .token.builtin[data-v-06225672],.theme-mode-read .token.important[data-v-06225672],.theme-mode-read .token.keyword[data-v-06225672],.theme-mode-read .token.selector[data-v-06225672]{color:#cc99cd}.theme-mode-read .token.attr-value[data-v-06225672],.theme-mode-read .token.char[data-v-06225672],.theme-mode-read .token.regex[data-v-06225672],.theme-mode-read .token.string[data-v-06225672],.theme-mode-read .token.variable[data-v-06225672]{color:#7ec699}.theme-mode-read .token.entity[data-v-06225672],.theme-mode-read .token.operator[data-v-06225672],.theme-mode-read .token.url[data-v-06225672]{color:#67cdcc}.theme-mode-read .language-css .token.string[data-v-06225672],.theme-mode-read .style .token.string[data-v-06225672],.theme-mode-read .token.entity[data-v-06225672],.theme-mode-read .token.operator[data-v-06225672],.theme-mode-read .token.url[data-v-06225672]{background:none}.theme-mode-read .token.bold[data-v-06225672],.theme-mode-read .token.important[data-v-06225672]{font-weight:700}.theme-mode-read .token.italic[data-v-06225672]{font-style:italic}.theme-mode-read .token.entity[data-v-06225672]{cursor:help}.theme-mode-read .token.inserted[data-v-06225672]{color:green}.theme-style-line.theme-mode-light[data-v-06225672]{--bodyBg:#fff}.theme-style-line.theme-mode-dark[data-v-06225672]{--bodyBg:#1e1e22}.theme-style-line.theme-mode-read[data-v-06225672]{--bodyBg:#f5f5d5}.articleInfo-wrap[data-v-06225672]{max-width:860px}.theme-style-line .articleInfo-wrap .articleInfo[data-v-06225672]{padding-top:.5rem}.articleInfo-wrap[data-v-06225672]{position:relative;z-index:1;color:#888}.articleInfo-wrap .articleInfo[data-v-06225672]{overflow:hidden;font-size:.92rem}.articleInfo-wrap .articleInfo .breadcrumbs[data-v-06225672]{margin:0;padding:0;overflow:hidden;display:inline-block;line-height:2rem}@media (max-width:960px){.articleInfo-wrap .articleInfo .breadcrumbs[data-v-06225672]{width:100%}}.articleInfo-wrap .articleInfo .breadcrumbs li[data-v-06225672]{list-style-type:none;float:left;padding-right:5px}.articleInfo-wrap .articleInfo .breadcrumbs li[data-v-06225672]:after{content:"/";margin-left:5px;color:#999}.articleInfo-wrap .articleInfo .breadcrumbs li[data-v-06225672]:last-child:after{content:""}.articleInfo-wrap .articleInfo .breadcrumbs li a[data-v-06225672]{color:#888}.articleInfo-wrap .articleInfo .breadcrumbs li a[data-v-06225672]:before{font-size:.92rem}.articleInfo-wrap .articleInfo .breadcrumbs li a[data-v-06225672]:hover{color:#11a8cd}.articleInfo-wrap .articleInfo .breadcrumbs li .icon-home[data-v-06225672]{text-decoration:none}.articleInfo-wrap .articleInfo .info[data-v-06225672]{float:right;line-height:32px}@media (max-width:960px){.articleInfo-wrap .articleInfo .info[data-v-06225672]{float:left}}.articleInfo-wrap .articleInfo .info div[data-v-06225672]{float:left;margin-left:20px;font-size:.8rem}@media (max-width:960px){.articleInfo-wrap .articleInfo .info div[data-v-06225672]{margin:0 20px 0 0}}.articleInfo-wrap .articleInfo .info div[data-v-06225672]:before{margin-right:3px}.articleInfo-wrap .articleInfo .info div a[data-v-06225672]{color:#888}.articleInfo-wrap .articleInfo .info div a[data-v-06225672]:hover{text-decoration:none}.articleInfo-wrap .articleInfo .info div a.beLink[data-v-06225672]:hover{color:#11a8cd;text-decoration:underline}.theme-mode-light[data-v-2cf874fa]{--bodyBg:#f4f4f4;--mainBg:#fff;--sidebarBg:hsla(0,0%,100%,0.8);--blurBg:hsla(0,0%,100%,0.9);--customBlockBg:#f1f1f1;--textColor:#00323c;--textLightenColor:#0085ad;--borderColor:rgba(0,0,0,0.12);--codeBg:#f6f6f6;--codeColor:#525252}.theme-mode-light code[class*=language-][data-v-2cf874fa],.theme-mode-light pre[class*=language-][data-v-2cf874fa]{color:#000;background:none;text-shadow:0 1px #fff;font-family:Consolas,Monaco,Andale Mono,Ubuntu Mono,monospace;font-size:1em;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;hyphens:none}.theme-mode-light code[class*=language-][data-v-2cf874fa]::-moz-selection,.theme-mode-light code[class*=language-][data-v-2cf874fa] ::-moz-selection,.theme-mode-light pre[class*=language-][data-v-2cf874fa]::-moz-selection,.theme-mode-light pre[class*=language-][data-v-2cf874fa] ::-moz-selection{text-shadow:none;background:#b3d4fc}.theme-mode-light code[class*=language-][data-v-2cf874fa]::selection,.theme-mode-light code[class*=language-][data-v-2cf874fa] ::selection,.theme-mode-light pre[class*=language-][data-v-2cf874fa]::selection,.theme-mode-light pre[class*=language-][data-v-2cf874fa] ::selection{text-shadow:none;background:#b3d4fc}@media print{.theme-mode-light code[class*=language-][data-v-2cf874fa],.theme-mode-light pre[class*=language-][data-v-2cf874fa]{text-shadow:none}}.theme-mode-light pre[class*=language-][data-v-2cf874fa]{padding:1em;margin:.5em 0;overflow:auto}.theme-mode-light :not(pre)>code[class*=language-][data-v-2cf874fa],.theme-mode-light pre[class*=language-][data-v-2cf874fa]{background:#f5f2f0}.theme-mode-light :not(pre)>code[class*=language-][data-v-2cf874fa]{padding:.1em;border-radius:.3em;white-space:normal}.theme-mode-light .token.cdata[data-v-2cf874fa],.theme-mode-light .token.comment[data-v-2cf874fa],.theme-mode-light .token.doctype[data-v-2cf874fa],.theme-mode-light .token.prolog[data-v-2cf874fa]{color:#708090}.theme-mode-light .token.punctuation[data-v-2cf874fa]{color:#999}.theme-mode-light .namespace[data-v-2cf874fa]{opacity:.7}.theme-mode-light .token.boolean[data-v-2cf874fa],.theme-mode-light .token.constant[data-v-2cf874fa],.theme-mode-light .token.deleted[data-v-2cf874fa],.theme-mode-light .token.number[data-v-2cf874fa],.theme-mode-light .token.property[data-v-2cf874fa],.theme-mode-light .token.symbol[data-v-2cf874fa],.theme-mode-light .token.tag[data-v-2cf874fa]{color:#905}.theme-mode-light .token.attr-name[data-v-2cf874fa],.theme-mode-light .token.builtin[data-v-2cf874fa],.theme-mode-light .token.char[data-v-2cf874fa],.theme-mode-light .token.inserted[data-v-2cf874fa],.theme-mode-light .token.selector[data-v-2cf874fa],.theme-mode-light .token.string[data-v-2cf874fa]{color:#690}.theme-mode-light .language-css .token.string[data-v-2cf874fa],.theme-mode-light .style .token.string[data-v-2cf874fa],.theme-mode-light .token.entity[data-v-2cf874fa],.theme-mode-light .token.operator[data-v-2cf874fa],.theme-mode-light .token.url[data-v-2cf874fa]{color:#9a6e3a;background:hsla(0,0%,100%,.5)}.theme-mode-light .token.atrule[data-v-2cf874fa],.theme-mode-light .token.attr-value[data-v-2cf874fa],.theme-mode-light .token.keyword[data-v-2cf874fa]{color:#07a}.theme-mode-light .token.class-name[data-v-2cf874fa],.theme-mode-light .token.function[data-v-2cf874fa]{color:#dd4a68}.theme-mode-light .token.important[data-v-2cf874fa],.theme-mode-light .token.regex[data-v-2cf874fa],.theme-mode-light .token.variable[data-v-2cf874fa]{color:#e90}.theme-mode-light .token.bold[data-v-2cf874fa],.theme-mode-light .token.important[data-v-2cf874fa]{font-weight:700}.theme-mode-light .token.italic[data-v-2cf874fa]{font-style:italic}.theme-mode-light .token.entity[data-v-2cf874fa]{cursor:help}.theme-mode-light div[class*=language-] .highlight-lines .highlighted[data-v-2cf874fa],.theme-mode-light div[class*=language-].line-numbers-mode .highlight-lines .highlighted[data-v-2cf874fa]:before{background-color:hsla(0,0%,78.4%,.4)}.theme-mode-dark[data-v-2cf874fa]{--bodyBg:#27272b;--mainBg:#1e1e22;--sidebarBg:rgba(30,30,34,0.8);--blurBg:rgba(30,30,34,0.8);--customBlockBg:#27272b;--textColor:#9b9baa;--textLightenColor:#0085ad;--borderColor:#30363d;--codeBg:#252526;--codeColor:#fff}.theme-mode-dark code[class*=language-][data-v-2cf874fa],.theme-mode-dark pre[class*=language-][data-v-2cf874fa]{color:#ccc;background:none;text-shadow:none;font-family:Consolas,Monaco,Andale Mono,Ubuntu Mono,monospace;font-size:1em;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;hyphens:none}.theme-mode-dark pre[class*=language-][data-v-2cf874fa]{padding:1em;margin:.5em 0;overflow:auto}.theme-mode-dark :not(pre)>code[class*=language-][data-v-2cf874fa],.theme-mode-dark pre[class*=language-][data-v-2cf874fa]{background:#2d2d2d}.theme-mode-dark :not(pre)>code[class*=language-][data-v-2cf874fa]{padding:.1em;border-radius:.3em;white-space:normal}.theme-mode-dark .token.block-comment[data-v-2cf874fa],.theme-mode-dark .token.cdata[data-v-2cf874fa],.theme-mode-dark .token.comment[data-v-2cf874fa],.theme-mode-dark .token.doctype[data-v-2cf874fa],.theme-mode-dark .token.prolog[data-v-2cf874fa]{color:#999}.theme-mode-dark .token.punctuation[data-v-2cf874fa]{color:#ccc}.theme-mode-dark .token.attr-name[data-v-2cf874fa],.theme-mode-dark .token.deleted[data-v-2cf874fa],.theme-mode-dark .token.namespace[data-v-2cf874fa],.theme-mode-dark .token.tag[data-v-2cf874fa]{color:#e2777a}.theme-mode-dark .token.function-name[data-v-2cf874fa]{color:#6196cc}.theme-mode-dark .token.boolean[data-v-2cf874fa],.theme-mode-dark .token.function[data-v-2cf874fa],.theme-mode-dark .token.number[data-v-2cf874fa]{color:#f08d49}.theme-mode-dark .token.class-name[data-v-2cf874fa],.theme-mode-dark .token.constant[data-v-2cf874fa],.theme-mode-dark .token.property[data-v-2cf874fa],.theme-mode-dark .token.symbol[data-v-2cf874fa]{color:#f8c555}.theme-mode-dark .token.atrule[data-v-2cf874fa],.theme-mode-dark .token.builtin[data-v-2cf874fa],.theme-mode-dark .token.important[data-v-2cf874fa],.theme-mode-dark .token.keyword[data-v-2cf874fa],.theme-mode-dark .token.selector[data-v-2cf874fa]{color:#cc99cd}.theme-mode-dark .token.attr-value[data-v-2cf874fa],.theme-mode-dark .token.char[data-v-2cf874fa],.theme-mode-dark .token.regex[data-v-2cf874fa],.theme-mode-dark .token.string[data-v-2cf874fa],.theme-mode-dark .token.variable[data-v-2cf874fa]{color:#7ec699}.theme-mode-dark .token.entity[data-v-2cf874fa],.theme-mode-dark .token.operator[data-v-2cf874fa],.theme-mode-dark .token.url[data-v-2cf874fa]{color:#67cdcc}.theme-mode-dark .language-css .token.string[data-v-2cf874fa],.theme-mode-dark .style .token.string[data-v-2cf874fa],.theme-mode-dark .token.entity[data-v-2cf874fa],.theme-mode-dark .token.operator[data-v-2cf874fa],.theme-mode-dark .token.url[data-v-2cf874fa]{background:none}.theme-mode-dark .token.bold[data-v-2cf874fa],.theme-mode-dark .token.important[data-v-2cf874fa]{font-weight:700}.theme-mode-dark .token.italic[data-v-2cf874fa]{font-style:italic}.theme-mode-dark .token.entity[data-v-2cf874fa]{cursor:help}.theme-mode-dark .token.inserted[data-v-2cf874fa]{color:green}.theme-mode-read[data-v-2cf874fa]{--bodyBg:#ececcc;--mainBg:#f5f5d5;--sidebarBg:rgba(245,245,213,0.8);--blurBg:rgba(245,245,213,0.9);--customBlockBg:#ececcc;--textColor:#704214;--textLightenColor:#963;--borderColor:rgba(0,0,0,0.15);--codeBg:#282c34;--codeColor:#fff}.theme-mode-read code[class*=language-][data-v-2cf874fa],.theme-mode-read pre[class*=language-][data-v-2cf874fa]{color:#ccc;background:none;text-shadow:none;font-family:Consolas,Monaco,Andale Mono,Ubuntu Mono,monospace;font-size:1em;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;hyphens:none}.theme-mode-read pre[class*=language-][data-v-2cf874fa]{padding:1em;margin:.5em 0;overflow:auto}.theme-mode-read :not(pre)>code[class*=language-][data-v-2cf874fa],.theme-mode-read pre[class*=language-][data-v-2cf874fa]{background:#2d2d2d}.theme-mode-read :not(pre)>code[class*=language-][data-v-2cf874fa]{padding:.1em;border-radius:.3em;white-space:normal}.theme-mode-read .token.block-comment[data-v-2cf874fa],.theme-mode-read .token.cdata[data-v-2cf874fa],.theme-mode-read .token.comment[data-v-2cf874fa],.theme-mode-read .token.doctype[data-v-2cf874fa],.theme-mode-read .token.prolog[data-v-2cf874fa]{color:#999}.theme-mode-read .token.punctuation[data-v-2cf874fa]{color:#ccc}.theme-mode-read .token.attr-name[data-v-2cf874fa],.theme-mode-read .token.deleted[data-v-2cf874fa],.theme-mode-read .token.namespace[data-v-2cf874fa],.theme-mode-read .token.tag[data-v-2cf874fa]{color:#e2777a}.theme-mode-read .token.function-name[data-v-2cf874fa]{color:#6196cc}.theme-mode-read .token.boolean[data-v-2cf874fa],.theme-mode-read .token.function[data-v-2cf874fa],.theme-mode-read .token.number[data-v-2cf874fa]{color:#f08d49}.theme-mode-read .token.class-name[data-v-2cf874fa],.theme-mode-read .token.constant[data-v-2cf874fa],.theme-mode-read .token.property[data-v-2cf874fa],.theme-mode-read .token.symbol[data-v-2cf874fa]{color:#f8c555}.theme-mode-read .token.atrule[data-v-2cf874fa],.theme-mode-read .token.builtin[data-v-2cf874fa],.theme-mode-read .token.important[data-v-2cf874fa],.theme-mode-read .token.keyword[data-v-2cf874fa],.theme-mode-read .token.selector[data-v-2cf874fa]{color:#cc99cd}.theme-mode-read .token.attr-value[data-v-2cf874fa],.theme-mode-read .token.char[data-v-2cf874fa],.theme-mode-read .token.regex[data-v-2cf874fa],.theme-mode-read .token.string[data-v-2cf874fa],.theme-mode-read .token.variable[data-v-2cf874fa]{color:#7ec699}.theme-mode-read .token.entity[data-v-2cf874fa],.theme-mode-read .token.operator[data-v-2cf874fa],.theme-mode-read .token.url[data-v-2cf874fa]{color:#67cdcc}.theme-mode-read .language-css .token.string[data-v-2cf874fa],.theme-mode-read .style .token.string[data-v-2cf874fa],.theme-mode-read .token.entity[data-v-2cf874fa],.theme-mode-read .token.operator[data-v-2cf874fa],.theme-mode-read .token.url[data-v-2cf874fa]{background:none}.theme-mode-read .token.bold[data-v-2cf874fa],.theme-mode-read .token.important[data-v-2cf874fa]{font-weight:700}.theme-mode-read .token.italic[data-v-2cf874fa]{font-style:italic}.theme-mode-read .token.entity[data-v-2cf874fa]{cursor:help}.theme-mode-read .token.inserted[data-v-2cf874fa]{color:green}.theme-style-line.theme-mode-light[data-v-2cf874fa]{--bodyBg:#fff}.theme-style-line.theme-mode-dark[data-v-2cf874fa]{--bodyBg:#1e1e22}.theme-style-line.theme-mode-read[data-v-2cf874fa]{--bodyBg:#f5f5d5}.theme-vdoing-content[data-v-2cf874fa]{margin-bottom:3.6rem}.title-tag[data-v-2cf874fa]{border:1px solid #ff5722;color:#ff5722;font-size:.8rem;padding:0 .35rem;border-radius:.2rem;margin-left:0;transform:translateY(-.05rem);display:inline-block}dd[data-v-2cf874fa],dl[data-v-2cf874fa]{margin:0}.column-wrapper[data-v-2cf874fa]{margin-top:1rem;display:flex;padding-bottom:2rem;border-bottom:1px solid var(--borderColor)}.column-wrapper img[data-v-2cf874fa]{width:80px;height:80px;border-radius:2px;margin-right:1rem}.column-wrapper .column-info .title[data-v-2cf874fa]{font-size:1.6rem}.column-wrapper .column-info .description[data-v-2cf874fa]{color:var(--textColor);opacity:.8;margin:.5rem 0}.catalogue-wrapper .catalogue-title[data-v-2cf874fa]{font-size:1.45rem;margin:2rem 0}.catalogue-wrapper .catalogue-content dl[data-v-2cf874fa]{margin-bottom:1.8rem}.catalogue-wrapper .catalogue-content dl.inline[data-v-2cf874fa]{display:inline-block;width:50%;margin-bottom:1rem}@media (max-width:419px){.catalogue-wrapper .catalogue-content dl.inline[data-v-2cf874fa]{width:100%}}.catalogue-wrapper .catalogue-content dl.inline a[data-v-2cf874fa]{width:100%}.catalogue-wrapper .catalogue-content dl:not(.inline) dt[data-v-2cf874fa]{margin-top:-3.6rem;padding-top:3.6rem}.catalogue-wrapper .catalogue-content dl dt[data-v-2cf874fa]{font-size:1.1rem}.catalogue-wrapper .catalogue-content dl dt:hover .header-anchor[data-v-2cf874fa]{opacity:1}.catalogue-wrapper .catalogue-content dl dd[data-v-2cf874fa]{margin-top:.7rem;margin-left:1rem}.catalogue-wrapper .catalogue-content dl dd a[data-v-2cf874fa]:not(.header-anchor){margin-bottom:.5rem;display:inline-block;width:50%}.catalogue-wrapper .catalogue-content dl dd a[data-v-2cf874fa]:not(.header-anchor):hover{color:#ff5722;text-decoration:none}@media (max-width:720px){.catalogue-wrapper .catalogue-content dl dd a[data-v-2cf874fa]:not(.header-anchor){width:100%}}.catalogue-wrapper .catalogue-content dl .sub-cat-wrap[data-v-2cf874fa]{margin:5px 0 8px;font-size:.95rem}.catalogue-wrapper .catalogue-content dl .sub-cat-wrap>a[data-v-2cf874fa]{padding-left:1rem;box-sizing:border-box}.catalogue-wrapper .catalogue-content dl .sub-cat-wrap .sub-title[data-v-2cf874fa]{margin-top:-3.6rem;padding-top:3.6rem;margin-bottom:6px;font-size:1rem}.catalogue-wrapper .catalogue-content dl .sub-cat-wrap:hover .header-anchor[data-v-2cf874fa]{opacity:1}.theme-style-line .right-menu-wrapper .right-menu-margin{border-left:1px solid var(--borderColor)}.right-menu-wrapper{width:230px;float:right;margin-right:-285px;position:sticky;top:0;font-size:.8rem}.right-menu-wrapper .right-menu-margin{margin-top:4.6rem;border-radius:3px;overflow:hidden}.right-menu-wrapper .right-menu-title{padding:10px 15px 0;background:var(--mainBg);font-size:1rem}.right-menu-wrapper .right-menu-title:after{content:"";display:block;width:100%;height:1px;background:var(--borderColor);margin-top:10px}.right-menu-wrapper .right-menu-content{max-height:80vh;position:relative;overflow:hidden;background:var(--mainBg);padding:4px 3px 4px 0}.right-menu-wrapper .right-menu-content::-webkit-scrollbar{width:3px;height:3px}.right-menu-wrapper .right-menu-content::-webkit-scrollbar-track-piece{background:none}.right-menu-wrapper .right-menu-content::-webkit-scrollbar-thumb:vertical{background-color:hsla(0,0%,49%,.3)}.right-menu-wrapper .right-menu-content:hover{overflow-y:auto;padding-right:0}.right-menu-wrapper .right-menu-content .right-menu-item{padding:4px 15px;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;position:relative}.right-menu-wrapper .right-menu-content .right-menu-item.level2{font-size:.8rem}.right-menu-wrapper .right-menu-content .right-menu-item.level3{padding-left:27px}.right-menu-wrapper .right-menu-content .right-menu-item.level4{padding-left:37px}.right-menu-wrapper .right-menu-content .right-menu-item.level5{padding-left:47px}.right-menu-wrapper .right-menu-content .right-menu-item.level6{padding-left:57px}.right-menu-wrapper .right-menu-content .right-menu-item.active:before{content:"";position:absolute;top:5px;left:0;width:3px;height:14px;background:#11a8cd;border-radius:0 4px 4px 0}.right-menu-wrapper .right-menu-content .right-menu-item.active a{color:#11a8cd;opacity:1}.right-menu-wrapper .right-menu-content .right-menu-item a{color:var(--textColor);opacity:.75;display:inline-block;width:100%;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.right-menu-wrapper .right-menu-content .right-menu-item a:hover{opacity:1}.right-menu-wrapper .right-menu-content:hover{color:#11a8cd}.page>*{max-width:860px;margin:0 auto;padding:1rem 2.5rem 2rem}.page>:not(.footer){background:var(--mainBg);box-shadow:0 1px 2px 0 rgba(0,0,0,.1);margin-bottom:1rem}@media (min-width:940px){.page>:not(.footer){border-radius:2px}}@media (max-width:959px){.page>*{padding:1rem 2rem}}@media (max-width:419px){.page>*{padding:1rem 1.5rem}}.page{padding-bottom:2rem;display:block}@media (max-width:719px){.page{padding-top:3.6rem}}@media (min-width:719px){.page{padding-top:5.1rem}}@media (min-width:719px){.theme-style-line .page{padding-top:3.6rem}}.theme-style-line .page>:not(.footer){box-shadow:0 0}@media (min-width:720px){.theme-style-line .page .placeholder{height:1.2rem}}.theme-vdoing-wrapper .content-wrapper{position:relative}.theme-vdoing-wrapper h1 .title-tag{height:1.5rem;line-height:1.5rem;border:1px solid #ff5722;color:#ff5722;font-size:1rem;padding:0 .4rem;border-radius:.2rem;margin-left:.5rem;transform:translateY(-.25rem);display:inline-block}.theme-vdoing-wrapper h1 img{margin-bottom:-.2rem;margin-right:.2rem;max-width:2.2rem;max-height:2.2rem}.theme-vdoing-wrapper{--linesColor:rgba(50,0,0,0.05)}.theme-vdoing-wrapper.bg-style-1{background-image:linear-gradient(90deg,var(--linesColor) 3%,transparent 0),linear-gradient(0deg,var(--linesColor) 3%,transparent 0);background-position:50%;background-size:20px 20px}.theme-vdoing-wrapper.bg-style-2{background-image:repeating-linear-gradient(0,var(--linesColor),var(--linesColor) 1px,transparent 0,transparent 50%);background-size:30px 30px}.theme-vdoing-wrapper.bg-style-3{background-image:repeating-linear-gradient(90deg,var(--linesColor),var(--linesColor) 1px,transparent 0,transparent 50%);background-size:30px 30px}.theme-vdoing-wrapper.bg-style-4{background-image:repeating-linear-gradient(-45deg,var(--linesColor),var(--linesColor) 1px,transparent 0,transparent 50%);background-size:20px 20px}.theme-vdoing-wrapper.bg-style-5{background-image:repeating-linear-gradient(45deg,var(--linesColor),var(--linesColor) 1px,transparent 0,transparent 50%);background-size:20px 20px}.theme-vdoing-wrapper.bg-style-6{background-image:radial-gradient(var(--linesColor) 1px,transparent 0);background-size:10px 10px}.theme-mode-dark .theme-vdoing-wrapper{--linesColor:hsla(0,0%,49%,0.05)}@media (min-width:720px) and (max-width:1279px){.have-rightmenu .page{padding-right:.8rem!important}}@media (max-width:1279px){.have-rightmenu .right-menu-wrapper{display:none}}@media (min-width:1280px){.have-rightmenu .sidebar .sidebar-sub-headers{display:none}}.theme-container.only-sidebarItem:not(.have-rightmenu) .sidebar,.theme-container.only-sidebarItem:not(.have-rightmenu) .sidebar-button{display:none}@media (min-width:720px){.theme-container.only-sidebarItem:not(.have-rightmenu) .page{padding-left:.8rem!important}}@media (max-width:719px){.theme-container.only-sidebarItem:not(.have-rightmenu) .page{padding-left:0!important}.theme-container.only-sidebarItem:not(.have-rightmenu) .sidebar,.theme-container.only-sidebarItem:not(.have-rightmenu) .sidebar-button{display:block}}@media (min-width:720px) and (max-width:1279px){.theme-container.only-sidebarItem.have-rightmenu .sidebar,.theme-container.only-sidebarItem.have-rightmenu .sidebar-button{display:block}}@media (min-width:1280px){.theme-container.only-sidebarItem.have-rightmenu .sidebar,.theme-container.only-sidebarItem.have-rightmenu .sidebar-button{display:none}}.categories-page .categories-wrapper{position:sticky;top:4.5rem;max-height:calc(100vh - 10rem);min-height:4.2rem}@media (max-width:719px){.categories-page .categories-wrapper{display:none}}.categories-page .categories-wrapper .categories{padding-right:.5rem;max-height:calc(100vh - 14rem);min-height:2.2rem;overflow-y:auto;transition:all .2s;position:relative}.categories-page .categories-wrapper .categories::-webkit-scrollbar-track-piece{background-color:rgba(0,0,0,.05)}.categories-page .categories-wrapper .categories::-webkit-scrollbar-thumb:vertical{background-color:rgba(0,0,0,.15)}.categories-page .categories-wrapper .categories:hover::-webkit-scrollbar-track-piece{background-color:rgba(0,0,0,.1)}.categories-page .categories-wrapper .categories:hover::-webkit-scrollbar-thumb:vertical{background-color:rgba(0,0,0,.25)}.categories-page .main-left .categories-wrapper{position:relative;top:0;padding:.9rem 1.5rem;margin-bottom:.9rem;max-height:15rem;border-radius:0;display:none}@media (max-width:719px){.categories-page .main-left .categories-wrapper{display:block}}.categories-page .main-left .categories-wrapper .categories{max-height:12.3rem}@media (max-width:719px){.theme-style-line .categories-page .main-left .categories-wrapper{margin-top:-.91rem;margin-bottom:-1px;padding:.9rem .2rem .5rem}}.tags-page .tags-wrapper{position:sticky;top:4.5rem;max-height:calc(100vh - 10rem);min-height:4.2rem}@media (max-width:719px){.tags-page .tags-wrapper{display:none}}.tags-page .tags-wrapper .tags{max-height:calc(100vh - 14rem);min-height:2.2rem;overflow-x:hidden;overflow-y:auto;transition:all .2s}.tags-page .tags-wrapper .tags::-webkit-scrollbar-track-piece{background-color:rgba(0,0,0,.05)}.tags-page .tags-wrapper .tags::-webkit-scrollbar-thumb:vertical{background-color:rgba(0,0,0,.15)}.tags-page .tags-wrapper .tags:hover::-webkit-scrollbar-track-piece{background-color:rgba(0,0,0,.1)}.tags-page .tags-wrapper .tags:hover::-webkit-scrollbar-thumb:vertical{background-color:rgba(0,0,0,.25)}.tags-page .main-left .tags-wrapper{position:relative;top:0;padding:.9rem 1.5rem;margin-bottom:.9rem;max-height:15rem;border-radius:0;display:none}@media (max-width:719px){.tags-page .main-left .tags-wrapper{display:block}}.tags-page .main-left .tags-wrapper .tags{max-height:11.5rem}@media (max-width:719px){.theme-style-line .tags-page .main-left .tags-wrapper{margin-top:-.91rem;margin-bottom:-1px}}.archives-page .theme-vdoing-wrapper{max-width:860px;margin:0 auto;padding:1rem 2.5rem 2rem}.archives-page .theme-vdoing-wrapper:not(.footer){background:var(--mainBg);box-shadow:0 1px 2px 0 rgba(0,0,0,.1);margin-bottom:1rem}@media (min-width:940px){.archives-page .theme-vdoing-wrapper:not(.footer){border-radius:2px}}@media (max-width:959px){.archives-page .theme-vdoing-wrapper{padding:1rem 2rem}}@media (max-width:419px){.archives-page .theme-vdoing-wrapper{padding:1rem 1.5rem}}.theme-style-line .archives-page .theme-vdoing-wrapper{box-shadow:0 0}.archives-page .theme-vdoing-wrapper{position:relative}@media (min-width:940px){.archives-page .theme-vdoing-wrapper{margin-top:1.5rem!important}}.archives-page .theme-vdoing-wrapper .count{text-align:right;margin-top:-2.5rem;font-size:.85rem;opacity:.8}.archives-page .theme-vdoing-wrapper li,.archives-page .theme-vdoing-wrapper ul{margin:0;padding:0}.archives-page .theme-vdoing-wrapper ul{margin-top:2rem}.archives-page .theme-vdoing-wrapper li{list-style:none}.archives-page .theme-vdoing-wrapper li.year{position:sticky;top:3.6rem;background:var(--mainBg);z-index:1}.archives-page .theme-vdoing-wrapper li.year:not(:first-child){margin-top:3.5rem}.archives-page .theme-vdoing-wrapper li h2{margin-bottom:.8rem;font-weight:400;padding:.5rem 0}.archives-page .theme-vdoing-wrapper li h2 span{font-size:.85rem;font-weight:300;float:right;margin-top:1rem}.archives-page .theme-vdoing-wrapper li a{display:block;color:var(--textColor);transition:padding .3s;padding:.5rem 2rem;line-height:1.2rem}.archives-page .theme-vdoing-wrapper li a:hover{padding-left:2.5rem;color:#11a8cd;background:#f9f9f9}@media (max-width:940px){.archives-page .theme-vdoing-wrapper li a{padding:.5rem 1rem;font-weight:400}.archives-page .theme-vdoing-wrapper li a:hover{padding-left:1.5rem}}.archives-page .theme-vdoing-wrapper li a span.date{opacity:.6;font-size:.85rem;font-weight:400;margin-right:.3rem}.archives-page .theme-vdoing-wrapper li a .title-tag{border:1px solid #ff5722;color:#ff5722;font-size:.8rem;padding:0 .35rem;border-radius:.2rem;margin-left:0;transform:translateY(-.05rem);display:inline-block}.archives-page .theme-vdoing-wrapper .loadmore{text-align:center;margin-top:1rem;opacity:.5}.theme-mode-dark .archives-page .theme-vdoing-wrapper li a:hover,.theme-mode-read .archives-page .theme-vdoing-wrapper li a:hover{background:var(--customBlockBg)}.hide-navbar .archives-page .theme-vdoing-wrapper li.year{top:0}.sidebar-group .sidebar-group{padding-left:.5em}.sidebar-group:not(.collapsable) .sidebar-heading:not(.clickable){cursor:auto;color:inherit}.sidebar-group.is-sub-group{padding-left:0}.sidebar-group.is-sub-group>.sidebar-heading{font-size:1.01em;line-height:1.4;font-weight:700;padding-left:2rem}.sidebar-group.is-sub-group>.sidebar-group-items{padding-left:1rem}.sidebar-group.is-sub-group>.sidebar-group-items>li>.sidebar-link{font-size:.98em;border-left:none}.sidebar-group.depth-2>.sidebar-heading{border-left:none}.sidebar-heading{color:var(--textColor);transition:color .15s ease;cursor:pointer;font-size:1.1em;font-weight:700;padding:.35rem 1.5rem .35rem 1.25rem;width:100%;box-sizing:border-box;margin:0;border-left:.25rem solid transparent}.sidebar-heading.open,.sidebar-heading:hover{color:inherit}.sidebar-heading .arrow{position:relative;top:-.12em;left:.5em}.sidebar-heading.clickable.active{font-weight:600;color:#11a8cd;border-left-color:#11a8cd}.sidebar-heading.clickable:hover{color:#11a8cd}.sidebar-group-items{transition:height .1s ease-out;font-size:.95em;overflow:hidden}.sidebar .sidebar-sub-headers{padding-left:1rem;font-size:.95em}.sidebar .sidebar-sub-headers .level4{padding-left:.2rem}.sidebar .sidebar-sub-headers .level5{padding-left:.4rem}.sidebar .sidebar-sub-headers .level6{padding-left:.6rem}a.sidebar-link{font-size:1em;font-weight:400;display:inline-block;color:var(--textColor);border-left:.25rem solid transparent;padding:.35rem 1rem .35rem 1.25rem;line-height:1.4;width:100%;box-sizing:border-box}a.sidebar-link:hover{color:#11a8cd}a.sidebar-link.active{font-weight:600;color:#11a8cd;border-left-color:#11a8cd}.sidebar-group a.sidebar-link{padding-left:2rem}.sidebar-sub-headers a.sidebar-link{padding-top:.25rem;padding-bottom:.25rem;border-left:none}.sidebar-sub-headers a.sidebar-link.active{font-weight:500}.sidebar ul{padding:0;margin:0;list-style-type:none}.sidebar a{display:inline-block}.sidebar .nav-links{display:none;border-bottom:1px solid var(--borderColor);padding:.5rem 0 .75rem}.sidebar .nav-links a{font-weight:600}.sidebar .nav-links .nav-item,.sidebar .nav-links .repo-link{display:block;line-height:1.25rem;font-size:1.1em;padding:.5rem 0 .5rem 1.5rem}.sidebar>.sidebar-links{padding:1.5rem 0}.sidebar>.sidebar-links>li>a.sidebar-link{font-size:1.1em;line-height:1.7;font-weight:700}.sidebar>.sidebar-links>li:not(:first-child){margin-top:.75rem}.sidebar .blogger{display:none;border-bottom:1px solid var(--borderColor)}.sidebar .blogger img{width:60px;height:60px;border-radius:5px;margin:.75rem 1rem}.sidebar .blogger .blogger-info{flex:1;padding:0 .3rem .3rem 0}.sidebar .blogger .blogger-info h3{margin:.95rem 0 .6rem;font-size:1.1rem}.sidebar .blogger .blogger-info .icons .iconfont{font-size:1.2rem;padding-right:.6rem;color:#777}.sidebar .sidebar-slot{margin-bottom:-.5rem;font-size:.85rem}.sidebar .sidebar-slot.sidebar-slot-top{padding:1.5rem 1.5rem 0}.sidebar .sidebar-slot.sidebar-slot-bottom{padding:0 1.5rem 1.5rem}@media (max-width:719px){.sidebar .blogger{display:flex}.sidebar .nav-links{display:block}.sidebar .nav-links .dropdown-wrapper .nav-dropdown .dropdown-item a.router-link-active:after{top:calc(1rem - 2px)}.sidebar>.sidebar-links{padding:1rem 0}}.yellowBorder{border-radius:5px;box-shadow:0 0 15px #ffe089!important}.buttons{position:fixed;right:2rem;bottom:2.5rem;z-index:11}@media (max-width:959px){.buttons{right:1rem;bottom:1.5rem}}.buttons .button{width:2.2rem;height:2.2rem;line-height:2.2rem;border-radius:50%;box-shadow:0 2px 6px rgba(0,0,0,.15);margin-top:.9rem;text-align:center;cursor:pointer;transition:all .5s;background:var(--blurBg)}.buttons .button.hover{background:#11a8cd;box-shadow:0 0 15px #11a8cd}.buttons .button.hover:before{color:#fff}@media (any-hover:hover){.buttons .button:hover{background:#11a8cd;box-shadow:0 0 15px #11a8cd}.buttons .button:hover:before{color:#fff}}.buttons .button .select-box{margin:0;padding:.8rem 0;position:absolute;bottom:0;right:1.5rem;background:var(--mainBg);border:1px solid var(--borderColor);width:120px;border-radius:6px;box-shadow:0 0 15px hsla(0,0%,100%,.2)}.buttons .button .select-box li{list-style:none;line-height:2rem;font-size:.95rem}.buttons .button .select-box li:hover{color:#11a8cd}.buttons .button .select-box li.active{background-color:hsla(0,0%,58.8%,.2);color:#11a8cd}.mode-enter-active,.mode-leave-active{transition:all .3s}.mode-enter,.mode-leave-to{opacity:0;transform:scale(.8)}.fade-enter-active,.fade-leave-active{transition:opacity .2s}.fade-enter,.fade-leave-to{opacity:0}.footer{padding:5rem 1.5rem 2.5rem;text-align:center;color:#666;box-sizing:border-box;font-size:.85rem;transition:all .2s ease}.footer>span{line-height:1.5rem}.footer .icons{margin-bottom:12px}.footer .icons .iconfont{padding:0 10px;font-size:1.3rem}.footer a{color:inherit}.footer a:hover{color:#11a8cd}@media (min-width:720px){.sidebar-open .footer{width:auto;padding-left:19.5rem}}@media (min-width:1520px){.have-rightmenu .footer{padding-right:231.5px}}.no-sidebar .footer{width:auto;padding-left:1.5rem}.body-bg{position:fixed;left:0;top:0;z-index:-999999;height:100vh;width:100vw;transition:background .5s}.theme-mode-light{--bodyBg:#f4f4f4;--mainBg:#fff;--sidebarBg:hsla(0,0%,100%,0.8);--blurBg:hsla(0,0%,100%,0.9);--customBlockBg:#f1f1f1;--textColor:#00323c;--textLightenColor:#0085ad;--borderColor:rgba(0,0,0,0.12);--codeBg:#f6f6f6;--codeColor:#525252}.theme-mode-light code[class*=language-],.theme-mode-light pre[class*=language-]{color:#000;background:none;text-shadow:0 1px #fff;font-family:Consolas,Monaco,Andale Mono,Ubuntu Mono,monospace;font-size:1em;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;hyphens:none}.theme-mode-light code[class*=language-]::-moz-selection,.theme-mode-light code[class*=language-] ::-moz-selection,.theme-mode-light pre[class*=language-]::-moz-selection,.theme-mode-light pre[class*=language-] ::-moz-selection{text-shadow:none;background:#b3d4fc}.theme-mode-light code[class*=language-]::selection,.theme-mode-light code[class*=language-] ::selection,.theme-mode-light pre[class*=language-]::selection,.theme-mode-light pre[class*=language-] ::selection{text-shadow:none;background:#b3d4fc}@media print{.theme-mode-light code[class*=language-],.theme-mode-light pre[class*=language-]{text-shadow:none}}.theme-mode-light pre[class*=language-]{padding:1em;margin:.5em 0;overflow:auto}.theme-mode-light :not(pre)>code[class*=language-],.theme-mode-light pre[class*=language-]{background:#f5f2f0}.theme-mode-light :not(pre)>code[class*=language-]{padding:.1em;border-radius:.3em;white-space:normal}.theme-mode-light .token.cdata,.theme-mode-light .token.comment,.theme-mode-light .token.doctype,.theme-mode-light .token.prolog{color:#708090}.theme-mode-light .token.punctuation{color:#999}.theme-mode-light .namespace{opacity:.7}.theme-mode-light .token.boolean,.theme-mode-light .token.constant,.theme-mode-light .token.deleted,.theme-mode-light .token.number,.theme-mode-light .token.property,.theme-mode-light .token.symbol,.theme-mode-light .token.tag{color:#905}.theme-mode-light .token.attr-name,.theme-mode-light .token.builtin,.theme-mode-light .token.char,.theme-mode-light .token.inserted,.theme-mode-light .token.selector,.theme-mode-light .token.string{color:#690}.theme-mode-light .language-css .token.string,.theme-mode-light .style .token.string,.theme-mode-light .token.entity,.theme-mode-light .token.operator,.theme-mode-light .token.url{color:#9a6e3a;background:hsla(0,0%,100%,.5)}.theme-mode-light .token.atrule,.theme-mode-light .token.attr-value,.theme-mode-light .token.keyword{color:#07a}.theme-mode-light .token.class-name,.theme-mode-light .token.function{color:#dd4a68}.theme-mode-light .token.important,.theme-mode-light .token.regex,.theme-mode-light .token.variable{color:#e90}.theme-mode-light .token.bold,.theme-mode-light .token.important{font-weight:700}.theme-mode-light .token.italic{font-style:italic}.theme-mode-light .token.entity{cursor:help}.theme-mode-light div[class*=language-] .highlight-lines .highlighted,.theme-mode-light div[class*=language-].line-numbers-mode .highlight-lines .highlighted:before{background-color:hsla(0,0%,78.4%,.4)}.theme-mode-dark{--bodyBg:#27272b;--mainBg:#1e1e22;--sidebarBg:rgba(30,30,34,0.8);--blurBg:rgba(30,30,34,0.8);--customBlockBg:#27272b;--textColor:#9b9baa;--textLightenColor:#0085ad;--borderColor:#30363d;--codeBg:#252526;--codeColor:#fff}.theme-mode-dark code[class*=language-],.theme-mode-dark pre[class*=language-]{color:#ccc;background:none;text-shadow:none;font-family:Consolas,Monaco,Andale Mono,Ubuntu Mono,monospace;font-size:1em;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;hyphens:none}.theme-mode-dark pre[class*=language-]{padding:1em;margin:.5em 0;overflow:auto}.theme-mode-dark :not(pre)>code[class*=language-],.theme-mode-dark pre[class*=language-]{background:#2d2d2d}.theme-mode-dark :not(pre)>code[class*=language-]{padding:.1em;border-radius:.3em;white-space:normal}.theme-mode-dark .token.block-comment,.theme-mode-dark .token.cdata,.theme-mode-dark .token.comment,.theme-mode-dark .token.doctype,.theme-mode-dark .token.prolog{color:#999}.theme-mode-dark .token.punctuation{color:#ccc}.theme-mode-dark .token.attr-name,.theme-mode-dark .token.deleted,.theme-mode-dark .token.namespace,.theme-mode-dark .token.tag{color:#e2777a}.theme-mode-dark .token.function-name{color:#6196cc}.theme-mode-dark .token.boolean,.theme-mode-dark .token.function,.theme-mode-dark .token.number{color:#f08d49}.theme-mode-dark .token.class-name,.theme-mode-dark .token.constant,.theme-mode-dark .token.property,.theme-mode-dark .token.symbol{color:#f8c555}.theme-mode-dark .token.atrule,.theme-mode-dark .token.builtin,.theme-mode-dark .token.important,.theme-mode-dark .token.keyword,.theme-mode-dark .token.selector{color:#cc99cd}.theme-mode-dark .token.attr-value,.theme-mode-dark .token.char,.theme-mode-dark .token.regex,.theme-mode-dark .token.string,.theme-mode-dark .token.variable{color:#7ec699}.theme-mode-dark .token.entity,.theme-mode-dark .token.operator,.theme-mode-dark .token.url{color:#67cdcc}.theme-mode-dark .language-css .token.string,.theme-mode-dark .style .token.string,.theme-mode-dark .token.entity,.theme-mode-dark .token.operator,.theme-mode-dark .token.url{background:none}.theme-mode-dark .token.bold,.theme-mode-dark .token.important{font-weight:700}.theme-mode-dark .token.italic{font-style:italic}.theme-mode-dark .token.entity{cursor:help}.theme-mode-dark .token.inserted{color:green}.theme-mode-read{--bodyBg:#ececcc;--mainBg:#f5f5d5;--sidebarBg:rgba(245,245,213,0.8);--blurBg:rgba(245,245,213,0.9);--customBlockBg:#ececcc;--textColor:#704214;--textLightenColor:#963;--borderColor:rgba(0,0,0,0.15);--codeBg:#282c34;--codeColor:#fff}.theme-mode-read code[class*=language-],.theme-mode-read pre[class*=language-]{color:#ccc;background:none;text-shadow:none;font-family:Consolas,Monaco,Andale Mono,Ubuntu Mono,monospace;font-size:1em;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;hyphens:none}.theme-mode-read pre[class*=language-]{padding:1em;margin:.5em 0;overflow:auto}.theme-mode-read :not(pre)>code[class*=language-],.theme-mode-read pre[class*=language-]{background:#2d2d2d}.theme-mode-read :not(pre)>code[class*=language-]{padding:.1em;border-radius:.3em;white-space:normal}.theme-mode-read .token.block-comment,.theme-mode-read .token.cdata,.theme-mode-read .token.comment,.theme-mode-read .token.doctype,.theme-mode-read .token.prolog{color:#999}.theme-mode-read .token.punctuation{color:#ccc}.theme-mode-read .token.attr-name,.theme-mode-read .token.deleted,.theme-mode-read .token.namespace,.theme-mode-read .token.tag{color:#e2777a}.theme-mode-read .token.function-name{color:#6196cc}.theme-mode-read .token.boolean,.theme-mode-read .token.function,.theme-mode-read .token.number{color:#f08d49}.theme-mode-read .token.class-name,.theme-mode-read .token.constant,.theme-mode-read .token.property,.theme-mode-read .token.symbol{color:#f8c555}.theme-mode-read .token.atrule,.theme-mode-read .token.builtin,.theme-mode-read .token.important,.theme-mode-read .token.keyword,.theme-mode-read .token.selector{color:#cc99cd}.theme-mode-read .token.attr-value,.theme-mode-read .token.char,.theme-mode-read .token.regex,.theme-mode-read .token.string,.theme-mode-read .token.variable{color:#7ec699}.theme-mode-read .token.entity,.theme-mode-read .token.operator,.theme-mode-read .token.url{color:#67cdcc}.theme-mode-read .language-css .token.string,.theme-mode-read .style .token.string,.theme-mode-read .token.entity,.theme-mode-read .token.operator,.theme-mode-read .token.url{background:none}.theme-mode-read .token.bold,.theme-mode-read .token.important{font-weight:700}.theme-mode-read .token.italic{font-style:italic}.theme-mode-read .token.entity{cursor:help}.theme-mode-read .token.inserted{color:green}.theme-style-line.theme-mode-light{--bodyBg:#fff}.theme-style-line.theme-mode-dark{--bodyBg:#1e1e22}.theme-style-line.theme-mode-read{--bodyBg:#f5f5d5}.custom-html-window{position:fixed;bottom:0;display:flex;overflow:hidden;font-weight:350}@media (max-width:960px){.custom-html-window{display:none}}.custom-html-window .custom-wrapper{position:relative;max-width:200px;max-height:400px}.custom-html-window .custom-wrapper .close-but{cursor:pointer;position:absolute;right:0;top:0;font-size:1.5rem;line-height:1.5rem;width:1.5rem;height:1.5rem;opacity:0;transition:all .2s}.custom-html-window .custom-wrapper .close-but:hover{opacity:.9}.custom-html-window .custom-wrapper:hover .close-but{opacity:.7}.custom-html-window.custom-html-window-lb{left:0;z-index:99}.custom-html-window.custom-html-window-lb>*{align-self:flex-end}.custom-html-window.custom-html-window-rb{right:80px;z-index:10;justify-content:flex-end}.custom-html-window.custom-html-window-rb>*{align-self:flex-end} \ No newline at end of file diff --git a/assets/img/search.83621669.svg b/assets/img/search.83621669.svg new file mode 100644 index 0000000000..03d83913e8 --- /dev/null +++ b/assets/img/search.83621669.svg @@ -0,0 +1 @@ + diff --git a/assets/js/1.a7be01c9.js b/assets/js/1.a7be01c9.js new file mode 100644 index 0000000000..6901b0908a --- /dev/null +++ b/assets/js/1.a7be01c9.js @@ -0,0 +1,6 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[1,21,24,27,28,29,33,34,35,37],{252:function(t,e,o){"use strict";o.r(e);var i=o(11),s={props:{item:{required:!0}},computed:{link(){return Object(i.c)(this.item.link)},exact(){return this.$site.locales?Object.keys(this.$site.locales).some(t=>t===this.link):"/"===this.link}},methods:{isExternal:i.g,isMailto:i.h,isTel:i.i,focusoutAction(){this.$emit("focusout")}}},r=o(4),n=Object(r.a)(s,(function(){var t=this,e=t._self._c;return t.isExternal(t.link)?e("a",{staticClass:"nav-link external",attrs:{href:t.link,target:t.isMailto(t.link)||t.isTel(t.link)?null:"_blank",rel:t.isMailto(t.link)||t.isTel(t.link)?null:"noopener noreferrer"},on:{focusout:t.focusoutAction}},[t._v("\n "+t._s(t.item.text)+"\n "),e("OutboundLink")],1):e("router-link",{staticClass:"nav-link",attrs:{to:t.link,exact:t.exact},nativeOn:{focusout:function(e){return t.focusoutAction.apply(null,arguments)}}},[t._v(t._s(t.item.text))])}),[],!1,null,null,null);e.default=n.exports},256:function(t,e,o){},257:function(t,e,o){},258:function(t,e,o){},262:function(t,e,o){},263:function(t,e,o){},264:function(t,e,o){},267:function(t,e,o){"use strict";o.r(e);o(25);var i={props:{category:{type:String,default:""},tag:{type:String,default:""},currentPage:{type:Number,default:1},perPage:{type:Number,default:10}},data:()=>({sortPosts:[],postListOffsetTop:0}),created(){this.setPosts()},mounted(){},watch:{currentPage(){this.$route.query.p!=this.currentPage&&this.$router.push({query:{...this.$route.query,p:this.currentPage}}),this.setPosts()},category(){this.setPosts()},tag(){this.setPosts()}},methods:{setPosts(){const t=this.currentPage,e=this.perPage;let o=[];o=this.category?this.$groupPosts.categories[this.category]:this.tag?this.$groupPosts.tags[this.tag]:this.$sortPosts,this.sortPosts=o.slice((t-1)*e,t*e)}}},s=(o(272),o(4)),r=Object(s.a)(i,(function(){var t=this,e=t._self._c;return e("div",{ref:"postList",staticClass:"post-list"},[e("transition-group",{attrs:{tag:"div",name:"post"}},t._l(t.sortPosts,(function(o){return e("div",{key:o.key,staticClass:"post card-box",class:o.frontmatter.sticky&&"iconfont icon-zhiding"},[e("div",{staticClass:"title-wrapper"},[e("h2",[e("router-link",{attrs:{to:o.path}},[t._v("\n "+t._s(o.title)+"\n "),o.frontmatter.titleTag?e("span",{staticClass:"title-tag"},[t._v(t._s(o.frontmatter.titleTag))]):t._e()])],1),t._v(" "),e("div",{staticClass:"article-info"},[o.author&&o.author.href?e("a",{staticClass:"iconfont icon-touxiang",attrs:{title:"作者",target:"_blank",href:o.author.href}},[t._v(t._s(o.author.name?o.author.name:o.author))]):o.author?e("span",{staticClass:"iconfont icon-touxiang",attrs:{title:"作者"}},[t._v(t._s(o.author.name?o.author.name:o.author))]):t._e(),t._v(" "),o.frontmatter.date?e("span",{staticClass:"iconfont icon-riqi",attrs:{title:"创建时间"}},[t._v(t._s(o.frontmatter.date.split(" ")[0]))]):t._e(),t._v(" "),!1!==t.$themeConfig.category&&o.frontmatter.categories?e("span",{staticClass:"iconfont icon-wenjian",attrs:{title:"分类"}},t._l(o.frontmatter.categories,(function(o,i){return e("router-link",{key:i,attrs:{to:"/categories/?category="+encodeURIComponent(o)}},[t._v(t._s(o))])})),1):t._e(),t._v(" "),!1!==t.$themeConfig.tag&&o.frontmatter.tags&&o.frontmatter.tags[0]?e("span",{staticClass:"iconfont icon-biaoqian tags",attrs:{title:"标签"}},t._l(o.frontmatter.tags,(function(o,i){return e("router-link",{key:i,attrs:{to:"/tags/?tag="+encodeURIComponent(o)}},[t._v(t._s(o))])})),1):t._e()])]),t._v(" "),o.excerpt?e("div",{staticClass:"excerpt-wrapper"},[e("div",{staticClass:"excerpt",domProps:{innerHTML:t._s(o.excerpt)}}),t._v(" "),e("router-link",{staticClass:"readmore iconfont icon-jiantou-you",attrs:{to:o.path}},[t._v("阅读全文")])],1):t._e()])})),0)],1)}),[],!1,null,null,null);e.default=r.exports},268:function(t,e,o){"use strict";o.r(e);var i={props:{total:{type:Number,default:10},perPage:{type:Number,default:10},currentPage:{type:Number,default:1}},computed:{pages(){return Math.ceil(this.total/this.perPage)}},methods:{threeNum(){let t=3;const e=this.currentPage,o=this.pages;return t=e<3?3:e>o-3?o-2:e,t},goPrex(){let t=this.currentPage;t>1&&this.handleEmit(--t)},goNext(){let t=this.currentPage;t3,expression:"currentPage > 3"}],staticClass:"ellipsis ell-two",attrs:{title:"上两页"},on:{click:function(e){return t.goIndex(t.currentPage-2)}}}),t._v(" "),e("span",{directives:[{name:"show",rawName:"v-show",value:t.currentPage<=3,expression:"currentPage <= 3"}],staticClass:"card-box",class:{active:2===t.currentPage},on:{click:function(e){return t.goIndex(2)}}},[t._v("2")]),t._v(" "),e("span",{staticClass:"card-box",class:{active:t.currentPage>=3&&t.currentPage<=t.pages-2},on:{click:function(e){t.goIndex(t.threeNum())}}},[t._v(t._s(t.threeNum()))]),t._v(" "),e("span",{directives:[{name:"show",rawName:"v-show",value:t.currentPage=t.pages-2,expression:"currentPage >= pages - 2"}],staticClass:"card-box",class:{active:t.currentPage===t.pages-1},on:{click:function(e){return t.goIndex(t.pages-1)}}},[t._v(t._s(t.pages-1))]),t._v(" "),e("span",{staticClass:"card-box",class:{active:t.currentPage===t.pages},on:{click:function(e){return t.goIndex(t.pages)}}},[t._v(t._s(t.pages))])]),t._v(" "),e("span",{staticClass:"card-box next iconfont icon-jiantou-you",class:{disabled:t.currentPage===t.pages},on:{click:function(e){return t.goNext()}}},[e("p",[t._v("下一页")])])])}),[],!1,null,null,null);e.default=r.exports},270:function(t,e,o){"use strict";o.r(e);o(271);var i=o(4),s=Object(i.a)({},(function(){var t=this._self._c;return t("div",{staticClass:"main-wrapper"},[t("div",{staticClass:"main-left"},[this._t("mainLeft")],2),this._v(" "),t("div",{staticClass:"main-right"},[this._t("mainRight")],2)])}),[],!1,null,null,null);e.default=s.exports},271:function(t,e,o){"use strict";o(256)},272:function(t,e,o){"use strict";o(257)},273:function(t,e,o){"use strict";o(258)},282:function(t,e,o){},286:function(t,e,o){"use strict";o(262)},289:function(t,e,o){"use strict";o(263)},290:function(t,e,o){"use strict";o(264)},300:function(t,e,o){"use strict";o.r(e);var i={props:{category:{type:String,default:""},categoriesData:{type:Array,default:[]},length:{type:[String,Number],default:"all"}},computed:{categories(){return"all"===this.length?this.categoriesData:this.categoriesData.slice(0,this.length)}}},s=(o(286),o(4)),r=Object(s.a)(i,(function(){var t=this,e=t._self._c;return e("div",{staticClass:"categories-wrapper card-box"},[e("router-link",{staticClass:"title iconfont icon-wenjianjia",attrs:{to:"/categories/",title:"全部分类"}},[t._v(t._s("all"===t.length?"全部分类":"文章分类"))]),t._v(" "),e("div",{staticClass:"categories"},[t._l(t.categories,(function(o,i){return e("router-link",{key:i,class:{active:o.key===t.category},attrs:{to:"/categories/?category="+encodeURIComponent(o.key)}},[t._v("\n "+t._s(o.key)+"\n "),e("span",[t._v(t._s(o.length))])])})),t._v(" "),"all"!==t.length&&t.length({tagBgColor:["#11a8cd","#F8B26A","#67CC86","#E15B64","#F47E60","#849B87"],tagStyleList:[]}),created(){for(let t=0,e=this.tags.length;tt.length?e("router-link",{attrs:{to:"/tags/"}},[t._v("更多...")]):t._e()],2)],1)}),[],!1,null,null,null);e.default=r.exports},305:function(t,e,o){"use strict";o.r(e);var i={name:"UpdateArticle",props:{length:{type:[String,Number],default:3},moreArticle:String},data:()=>({posts:[],currentPath:""}),created(){this.posts=this.$site.pages,this.currentPath=this.$page.path},computed:{topPublishPosts(){return this.$sortPostsByDate?this.$sortPostsByDate.filter(t=>{const{path:e}=t;return e!==this.currentPath}).slice(0,this.length):[]},isShowArticle(){const{frontmatter:t}=this.$page;return!(!1!==t.article)}},methods:{getNum:t=>t<9?"0"+(t+1):t+1,getDate:t=>t.frontmatter.date?t.frontmatter.date.split(" ")[0].slice(5,10):""},watch:{$route(){this.currentPath=this.$page.path}}},s=(o(289),o(4)),r=Object(s.a)(i,(function(){var t=this,e=t._self._c;return e("div",{class:["article-list",{"no-article-list":t.isShowArticle}]},[e("div",{staticClass:"article-title"},[e("router-link",{staticClass:"iconfont icon-bi",attrs:{to:t.moreArticle||"/archives/"}},[t._v("最近更新")])],1),t._v(" "),e("div",{staticClass:"article-wrapper"},[t._l(t.topPublishPosts,(function(o,i){return e("dl",{key:i},[e("dd",[t._v(t._s(t.getNum(i)))]),t._v(" "),e("dt",[e("router-link",{attrs:{to:o.path}},[e("div",[t._v("\n "+t._s(o.title)+"\n "),o.frontmatter.titleTag?e("span",{staticClass:"title-tag"},[t._v("\n "+t._s(o.frontmatter.titleTag)+"\n ")]):t._e()])]),t._v(" "),e("span",{staticClass:"date"},[t._v(t._s(t.getDate(o)))])],1)])})),t._v(" "),e("dl",[e("dd"),t._v(" "),e("dt",[e("router-link",{staticClass:"more",attrs:{to:t.moreArticle||"/archives/"}},[t._v("更多文章>")])],1)])],2)])}),[],!1,null,null,null);e.default=r.exports},309:function(t,e,o){"use strict";o(282)},325:function(t,e,o){},333:function(t,e,o){"use strict";o.r(e);var i={computed:{blogger(){return this.$themeConfig.blogger},social(){return this.$themeConfig.social}}},s=(o(309),o(4)),r=Object(s.a)(i,(function(){var t=this,e=t._self._c;return e("aside",{staticClass:"blogger-wrapper card-box"},[e("div",{staticClass:"avatar"},[e("img",{attrs:{src:t.blogger.avatar,alt:"头像",title:"我好看吗"}})]),t._v(" "),t.social&&t.social.icons&&t.social.icons.length?e("div",{staticClass:"icons"},t._l(t.social.icons,(function(o,i){return e("a",{key:i,class:["iconfont",o.iconClass],style:{width:100/t.social.icons.length+"%"},attrs:{href:o.link,title:o.title,target:"_blank"}})})),0):t._e(),t._v(" "),e("div",{staticClass:"blogger"},[e("span",{staticClass:"name"},[t._v(t._s(t.blogger.name))]),t._v(" "),e("span",{staticClass:"slogan"},[t._v(t._s(t.blogger.slogan))])])])}),[],!1,null,null,null);e.default=r.exports},349:function(t,e,o){"use strict";o(325)},355:function(t,e,o){"use strict";o.r(e);var i=o(252),s=function(t,e){return(s=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var o in e)Object.prototype.hasOwnProperty.call(e,o)&&(t[o]=e[o])})(t,e)};function r(t,e){function o(){this.constructor=t}s(t,e),t.prototype=null===e?Object.create(e):(o.prototype=e.prototype,new o)}var n=function(){return(n=Object.assign||function(t){for(var e,o=1,i=arguments.length;o0,d=function(){if("string"==typeof p){var t=/os (\d\d?_\d(_\d)?)/.exec(p);if(!t)return!1;var e=t[1].split("_").map((function(t){return parseInt(t,10)}));return!!(13===e[0]&&e[1]>=4)}return!1}(),f=!1;if(c){try{var v={};Object.defineProperty(v,"passive",{get:function(){f=!0}}),window.addEventListener("test-passive",(function(){}),v)}catch(t){}}function y(){return window.performance&&window.performance.now&&window.performance.timing?window.performance.now()+window.performance.timing.navigationStart:+new Date}var m=function(t,e){for(var o in e)t[o]=e[o];return t};function k(t){return null==t}function P(t,e,o){return to?o:t}var T=c&&document.createElement("div").style,b=function(){if(!c)return!1;for(var t=0,e=[{key:"standard",value:"transform"},{key:"webkit",value:"webkitTransform"},{key:"Moz",value:"MozTransform"},{key:"O",value:"OTransform"},{key:"ms",value:"msTransform"}];tdocument.documentElement.clientWidth-h||a>document.documentElement.clientHeight-h||n0?-1:o<0?1:0},r=s(e.x,t.x),n=s(e.y,t.y),a=o.x-i.x,h=o.y-i.y;return r*a<=0&&n*h<=0})(t,e,r,i)&&o.hooks.trigger(o.hooks.eventTypes.move,r),o.pending||(o.callStopWhenPending?o.callStopWhenPending=!1:o.hooks.trigger(o.hooks.eventTypes.end,r)),i=r,o.pending&&(o.timer=j(s))};this.callStopWhenPending&&this.setCallStop(!1),R(this.timer),s()},e.prototype.transitionTime=function(t){void 0===t&&(t=0),this.style[L.transitionDuration]=t+"ms",this.hooks.trigger(this.hooks.eventTypes.time,t)},e.prototype.transitionTimingFunction=function(t){this.style[L.transitionTimingFunction]=t,this.hooks.trigger(this.hooks.eventTypes.timeFunction,t)},e.prototype.transitionProperty=function(){this.style[L.transitionProperty]=L.transform},e.prototype.move=function(t,e,o,i){this.setPending(o>0),this.transitionTimingFunction(i),this.transitionProperty(),this.transitionTime(o),this.translate(e);var s=3===this.options.probeType;o&&s&&this.startProbe(t,e),o||(this._reflow=this.content.offsetHeight,s&&this.hooks.trigger(this.hooks.eventTypes.move,e),this.hooks.trigger(this.hooks.eventTypes.end,e))},e.prototype.doStop=function(){var t=this.pending;if(this.setForceStopped(!1),this.setCallStop(!1),t){this.setPending(!1),R(this.timer);var e=this.translater.getComputedPosition(),o=e.x,i=e.y;this.transitionTime(),this.translate({x:o,y:i}),this.setForceStopped(!0),this.setCallStop(!0),this.hooks.trigger(this.hooks.eventTypes.forceStop,{x:o,y:i})}return t},e.prototype.stop=function(){this.doStop()&&this.hooks.trigger(this.hooks.eventTypes.callStop)},e}(Z),et=function(t){function e(){return null!==t&&t.apply(this,arguments)||this}return r(e,t),e.prototype.move=function(t,e,o,i){if(!o)return this.translate(e),3===this.options.probeType&&this.hooks.trigger(this.hooks.eventTypes.move,e),void this.hooks.trigger(this.hooks.eventTypes.end,e);this.animate(t,e,o,i)},e.prototype.animate=function(t,e,o,i){var s=this,r=y(),n=r+o,a=3===this.options.probeType,h=function(){var l=y();if(l>=n)return s.translate(e),a&&s.hooks.trigger(s.hooks.eventTypes.move,e),void s.hooks.trigger(s.hooks.eventTypes.end,e);var c=i(l=(l-r)/o),p={};Object.keys(e).forEach((function(o){var i=t[o],s=e[o];p[o]=(s-i)*c+i})),s.translate(p),a&&s.hooks.trigger(s.hooks.eventTypes.move,p),s.pending&&(s.timer=j(h)),s.pending||(s.callStopWhenPending?s.callStopWhenPending=!1:s.hooks.trigger(s.hooks.eventTypes.end,e))};this.setPending(!0),this.callStopWhenPending&&this.setCallStop(!1),R(this.timer),h()},e.prototype.doStop=function(){var t=this.pending;if(this.setForceStopped(!1),this.setCallStop(!1),t){this.setPending(!1),R(this.timer);var e=this.translater.getComputedPosition();this.setForceStopped(!0),this.setCallStop(!0),this.hooks.trigger(this.hooks.eventTypes.forceStop,e)}return t},e.prototype.stop=function(){this.doStop()&&this.hooks.trigger(this.hooks.eventTypes.callStop)},e}(Z);var ot,it,st,rt,nt=function(){function t(t,e,o){this.wrapper=t,this.options=o,this.hooks=new U(["beforeComputeBoundary","computeBoundary","momentum","end","ignoreHasScroll"]),this.refresh(e)}return t.prototype.start=function(){this.dist=0,this.setMovingDirection(0),this.setDirection(0)},t.prototype.move=function(t){return t=this.hasScroll?t:0,this.setMovingDirection(t),this.performDampingAlgorithm(t,this.options.outOfBoundaryDampingFactor)},t.prototype.setMovingDirection=function(t){this.movingDirection=t>0?-1:t<0?1:0},t.prototype.setDirection=function(t){this.direction=t>0?-1:t<0?1:0},t.prototype.performDampingAlgorithm=function(t,e){var o=this.currentPos+t;return(o>this.minScrollPos||othis.minScrollPos&&this.options.bounces[0]||othis.minScrollPos?this.minScrollPos:this.maxScrollPos),o},t.prototype.end=function(t){var e={duration:0},o=Math.abs(this.currentPos-this.startPos);if(this.options.momentum&&tthis.options.momentumLimitDistance){var i=-1===this.direction&&this.options.bounces[0]||1===this.direction&&this.options.bounces[1]?this.wrapperSize:0;e=this.hasScroll?this.momentum(this.currentPos,this.startPos,t,this.maxScrollPos,this.minScrollPos,i,this.options):{destination:this.currentPos,duration:0}}else this.hooks.trigger(this.hooks.eventTypes.end,e);return e},t.prototype.momentum=function(t,e,o,i,s,r,n){void 0===n&&(n=this.options);var a=t-e,h=Math.abs(a)/o,l=n.deceleration,c=n.swipeBounceTime,p=n.swipeTime,u={destination:t+h*h/l*(a<0?-1:1),duration:Math.min(p,2*h/l),rate:15};return this.hooks.trigger(this.hooks.eventTypes.momentum,u,a),u.destinations&&(u.destination=r?Math.min(s+r/4,s+r/u.rate*h):s,u.duration=c),u.destination=Math.round(u.destination),u},t.prototype.updateDirection=function(){var t=this.currentPos-this.absStartPos;this.setDirection(t)},t.prototype.refresh=function(t){var e=this.options.rect,o=e.size,i=e.position,s="static"===window.getComputedStyle(this.wrapper,null).position,r=A(this.wrapper);this.wrapperSize=this.wrapper["width"===o?"clientWidth":"clientHeight"],this.setContent(t);var n=A(this.content);this.contentSize=n[o],this.relativeOffset=n[i],s&&(this.relativeOffset-=r[i]),this.computeBoundary(),this.setDirection(0)},t.prototype.setContent=function(t){t!==this.content&&(this.content=t,this.resetState())},t.prototype.resetState=function(){this.currentPos=0,this.startPos=0,this.dist=0,this.setDirection(0),this.setMovingDirection(0),this.resetStartPos()},t.prototype.computeBoundary=function(){this.hooks.trigger(this.hooks.eventTypes.beforeComputeBoundary);var t={minScrollPos:0,maxScrollPos:this.wrapperSize-this.contentSize};t.maxScrollPos<0&&(t.maxScrollPos-=this.relativeOffset,0===this.options.specifiedIndexAsContent&&(t.minScrollPos=-this.relativeOffset)),this.hooks.trigger(this.hooks.eventTypes.computeBoundary,t),this.minScrollPos=t.minScrollPos,this.maxScrollPos=t.maxScrollPos,this.hasScroll=this.options.scrollable&&this.maxScrollPosthis.minScrollPos?t=this.minScrollPos:te+this.directionLockThreshold?this.directionLocked="horizontal":e>=t+this.directionLockThreshold?this.directionLocked="vertical":this.directionLocked="none")},t.prototype.handleEventPassthrough=function(t){var e=ht[this.directionLocked];if(e){if(this.eventPassthrough===e.yes)return at.yes(t);if(this.eventPassthrough===e.no)return at.no(t)}return!1},t}(),ct=function(){function t(t,e,o,i,s){this.hooks=new U(["start","beforeMove","scrollStart","scroll","beforeEnd","end","scrollEnd","contentNotMoved","detectMovingDirection","coordinateTransformation"]),this.scrollBehaviorX=t,this.scrollBehaviorY=e,this.actionsHandler=o,this.animater=i,this.options=s,this.directionLockAction=new lt(s.directionLockThreshold,s.freeScroll,s.eventPassthrough),this.enabled=!0,this.bindActionsHandler()}return t.prototype.bindActionsHandler=function(){var t=this;this.actionsHandler.hooks.on(this.actionsHandler.hooks.eventTypes.start,(function(e){return!t.enabled||t.handleStart(e)})),this.actionsHandler.hooks.on(this.actionsHandler.hooks.eventTypes.move,(function(e){var o=e.deltaX,i=e.deltaY,s=e.e;if(!t.enabled)return!0;var r=function(t,e,o){return 2===o?[e,-t]:3===o?[-t,-e]:4===o?[-e,t]:[t,e]}(o,i,t.options.quadrant),n={deltaX:r[0],deltaY:r[1]};return t.hooks.trigger(t.hooks.eventTypes.coordinateTransformation,n),t.handleMove(n.deltaX,n.deltaY,s)})),this.actionsHandler.hooks.on(this.actionsHandler.hooks.eventTypes.end,(function(e){return!t.enabled||t.handleEnd(e)})),this.actionsHandler.hooks.on(this.actionsHandler.hooks.eventTypes.click,(function(e){t.enabled&&!e._constructed&&t.handleClick(e)}))},t.prototype.handleStart=function(t){var e=y();this.fingerMoved=!1,this.contentMoved=!1,this.startTime=e,this.directionLockAction.reset(),this.scrollBehaviorX.start(),this.scrollBehaviorY.start(),this.animater.doStop(),this.scrollBehaviorX.resetStartPos(),this.scrollBehaviorY.resetStartPos(),this.hooks.trigger(this.hooks.eventTypes.start,t)},t.prototype.handleMove=function(t,e,o){if(!this.hooks.trigger(this.hooks.eventTypes.beforeMove,o)){var i=this.scrollBehaviorX.getAbsDist(t),s=this.scrollBehaviorY.getAbsDist(e),r=y();if(this.checkMomentum(i,s,r))return!0;if(this.directionLockAction.checkMovingDirection(i,s,o))return this.actionsHandler.setInitiated(),!0;var n=this.directionLockAction.adjustDelta(t,e),a=this.scrollBehaviorX.getCurrentPos(),h=this.scrollBehaviorX.move(n.deltaX),l=this.scrollBehaviorY.getCurrentPos(),c=this.scrollBehaviorY.move(n.deltaY);if(!this.hooks.trigger(this.hooks.eventTypes.detectMovingDirection)){this.fingerMoved||(this.fingerMoved=!0);var p=h!==a||c!==l;this.contentMoved||p||this.hooks.trigger(this.hooks.eventTypes.contentNotMoved),!this.contentMoved&&p&&(this.contentMoved=!0,this.hooks.trigger(this.hooks.eventTypes.scrollStart)),this.contentMoved&&p&&(this.animater.translate({x:h,y:c}),this.dispatchScroll(r))}}},t.prototype.dispatchScroll=function(t){t-this.startTime>this.options.momentumLimitTime&&(this.startTime=t,this.scrollBehaviorX.updateStartPos(),this.scrollBehaviorY.updateStartPos(),1===this.options.probeType&&this.hooks.trigger(this.hooks.eventTypes.scroll,this.getCurrentPos())),this.options.probeType>1&&this.hooks.trigger(this.hooks.eventTypes.scroll,this.getCurrentPos())},t.prototype.checkMomentum=function(t,e,o){return o-this.endTime>this.options.momentumLimitTime&&e0?Math.ceil(e):Math.floor(e),o=o>0?Math.ceil(o):Math.floor(o),{x:e=P(e,r,s),y:o=P(o,h,a)}},t.prototype.handleClick=function(t){I(t.target,this.options.preventDefaultException)||(_(t),t.stopPropagation())},t.prototype.getCurrentPos=function(){return{x:this.scrollBehaviorX.getCurrentPos(),y:this.scrollBehaviorY.getCurrentPos()}},t.prototype.refresh=function(){this.endTime=0},t.prototype.destroy=function(){this.hooks.destroy()},t}();function pt(t,e,o,i){var s=["momentum","momentumLimitTime","momentumLimitDistance","deceleration","swipeBounceTime","swipeTime","outOfBoundaryDampingFactor","specifiedIndexAsContent"].reduce((function(e,o){return e[o]=t[o],e}),{});return s.scrollable=!!t[e],s.bounces=o,s.rect=i,s}function ut(t,e,o){o.forEach((function(o){var i,s;"string"==typeof o?i=s=o:(i=o.source,s=o.target),t.on(i,(function(){for(var t=[],o=0;o1&&t1||e>1))return!0},t.prototype.momentum=function(t,e){var o={time:0,easing:$.swiper,newX:t.x,newY:t.y},i=this.scrollBehaviorX.end(e),s=this.scrollBehaviorY.end(e);if(o.newX=k(i.destination)?o.newX:i.destination,o.newY=k(s.destination)?o.newY:s.destination,o.time=Math.max(i.duration,s.duration),this.hooks.trigger(this.hooks.eventTypes.momentum,o,this),o.newX!==t.x||o.newY!==t.y)return(o.newX>this.scrollBehaviorX.minScrollPos||o.newXthis.scrollBehaviorY.minScrollPos||o.newY=4)}}();if(mt){try{var Pt={};Object.defineProperty(Pt,"passive",{get:function(){!0}}),window.addEventListener("test-passive",(function(){}),Pt)}catch(t){}}var Tt=function(t,e){for(var o in e)t[o]=e[o];return t};function bt(t,e,o){return to?o:t}var xt=mt&&document.createElement("div").style,wt=function(){if(!mt)return!1;for(var t=0,e=[{key:"standard",value:"transform"},{key:"webkit",value:"webkitTransform"},{key:"Moz",value:"MozTransform"},{key:"O",value:"OTransform"},{key:"ms",value:"msTransform"}];t=this.pages[o][0].cx);o++);for(s=this.pages[o]?this.pages[o].length:0;i=this.pages[0][i].cy);i++);return{pageX:o,pageY:i}},t.prototype.buildPagesMatrix=function(t,e){var o,i,s,r,n=[],a=0,h=0,l=this.scroll.scroller.scrollBehaviorX.maxScrollPos,c=this.scroll.scroller.scrollBehaviorY.maxScrollPos;for(i=Math.round(t/2),s=Math.round(e/2);a>-this.scrollerWidth;){for(n[h]=[],r=0,o=0;o>-this.scrollerHeight;)n[h][r]={x:Math.max(a,l),y:Math.max(o,c),width:t,height:e,cx:a-i,cy:o-s},o-=e,r++;a-=t,h++}return n},t}(),Xt=function(){function t(t,e){this.scroll=t,this.slideOptions=e,this.slideX=!1,this.slideY=!1,this.currentPage=Tt({},_t)}return t.prototype.refresh=function(){this.pagesMatrix=new Yt(this.scroll),this.checkSlideLoop(),this.currentPage=this.getAdjustedCurrentPage()},t.prototype.getAdjustedCurrentPage=function(){var t=this.currentPage,e=t.pageX,o=t.pageY;e=Math.min(e,this.pagesMatrix.pageLengthOfX-1),o=Math.min(o,this.pagesMatrix.pageLengthOfY-1),this.loopX&&(e=Math.min(e,this.pagesMatrix.pageLengthOfX-2)),this.loopY&&(o=Math.min(o,this.pagesMatrix.pageLengthOfY-2));var i=this.pagesMatrix.getPageStats(e,o);return{pageX:e,pageY:o,x:i.x,y:i.y}},t.prototype.setCurrentPage=function(t){this.currentPage=t},t.prototype.getInternalPage=function(t,e){t>=this.pagesMatrix.pageLengthOfX?t=this.pagesMatrix.pageLengthOfX-1:t<0&&(t=0),e>=this.pagesMatrix.pageLengthOfY?e=this.pagesMatrix.pageLengthOfY-1:e<0&&(e=0);var o=this.pagesMatrix.getPageStats(t,e);return{pageX:t,pageY:e,x:o.x,y:o.y}},t.prototype.getInitialPage=function(t,e){void 0===t&&(t=!1),void 0===e&&(e=!1);var o=this.slideOptions,i=o.startPageXIndex,s=o.startPageYIndex,r=this.loopX?1:0,n=this.loopY?1:0,a=t?r:this.currentPage.pageX,h=t?n:this.currentPage.pageY;e?(a=this.loopX?i+1:i,h=this.loopY?s+1:s):(a=t?r:this.currentPage.pageX,h=t?n:this.currentPage.pageY);var l=this.pagesMatrix.getPageStats(a,h);return{pageX:a,pageY:h,x:l.x,y:l.y}},t.prototype.getExposedPage=function(t){var e=Tt({},t);return this.loopX&&(e.pageX=this.fixedPage(e.pageX,this.pagesMatrix.pageLengthOfX-2)),this.loopY&&(e.pageY=this.fixedPage(e.pageY,this.pagesMatrix.pageLengthOfY-2)),e},t.prototype.getExposedPageByPageIndex=function(t,e){var o={pageX:t,pageY:e};this.loopX&&(o.pageX=t+1),this.loopY&&(o.pageY=e+1);var i=this.pagesMatrix.getPageStats(o.pageX,o.pageY);return{x:i.x,y:i.y,pageX:t,pageY:e}},t.prototype.getWillChangedPage=function(t){return t=Tt({},t),this.loopX&&(t.pageX=this.fixedPage(t.pageX,this.pagesMatrix.pageLengthOfX-2),t.x=this.pagesMatrix.getPageStats(t.pageX+1,0).x),this.loopY&&(t.pageY=this.fixedPage(t.pageY,this.pagesMatrix.pageLengthOfY-2),t.y=this.pagesMatrix.getPageStats(0,t.pageY+1).y),t},t.prototype.fixedPage=function(t,e){for(var o=[],i=0;i1?this.slideX=!0:this.slideX=!1,this.pagesMatrix.pages[0]&&this.pagesMatrix.pageLengthOfY>1?this.slideY=!0:this.slideY=!1,this.loopX=this.wannaLoop&&this.slideX,this.loopY=this.wannaLoop&&this.slideY,this.slideX&&this.slideY&&yt("slide does not support two direction at the same time.")},t}(),Bt=[{key:"next",name:"next"},{key:"prev",name:"prev"},{key:"goToPage",name:"goToPage"},{key:"getCurrentPage",name:"getCurrentPage"},{key:"startPlay",name:"startPlay"},{key:"pausePlay",name:"pausePlay"}].map((function(t){return{key:t.key,sourceKey:"plugins.slide."+t.name}})),Et=function(){function t(t){this.scroll=t,this.cachedClonedPageDOM=[],this.resetLooping=!1,this.autoplayTimer=0,this.satisfyInitialization()&&this.init()}return t.prototype.satisfyInitialization=function(){return!(this.scroll.scroller.content.children.length<=0)||(yt("slide need at least one slide page to be initialised.please check your DOM layout."),!1)},t.prototype.init=function(){this.willChangeToPage=Tt({},_t),this.handleBScroll(),this.handleOptions(),this.handleHooks(),this.createPages()},t.prototype.createPages=function(){this.pages=new Xt(this.scroll,this.options)},t.prototype.handleBScroll=function(){this.scroll.registerType(["slideWillChange","slidePageChanged"]),this.scroll.proxy(Bt)},t.prototype.handleOptions=function(){var t=!0===this.scroll.options.slide?{}:this.scroll.options.slide,e={loop:!0,threshold:.1,speed:400,easing:Ct.bounce,listenFlick:!0,autoplay:!0,interval:3e3,startPageXIndex:0,startPageYIndex:0};this.options=Tt(e,t)},t.prototype.handleLoop=function(t){var e=this.options.loop,o=this.scroll.scroller.content,i=o.children.length;e&&(o!==t?(this.resetLoopChangedStatus(),this.removeClonedSlidePage(t),i>1&&this.cloneFirstAndLastSlidePage(o)):3===i&&this.initialised?(this.removeClonedSlidePage(o),this.moreToOnePageInLoop=!0,this.oneToMorePagesInLoop=!1):i>1?(this.initialised&&0===this.cachedClonedPageDOM.length?(this.oneToMorePagesInLoop=!0,this.moreToOnePageInLoop=!1):(this.removeClonedSlidePage(o),this.resetLoopChangedStatus()),this.cloneFirstAndLastSlidePage(o)):this.resetLoopChangedStatus())},t.prototype.resetLoopChangedStatus=function(){this.moreToOnePageInLoop=!1,this.oneToMorePagesInLoop=!1},t.prototype.handleHooks=function(){var t=this,e=this.scroll.hooks,o=this.scroll.scroller.hooks,i=this.options.listenFlick;this.prevContent=this.scroll.scroller.content,this.hooksFn=[],this.registerHooks(this.scroll,this.scroll.eventTypes.beforeScrollStart,this.pausePlay),this.registerHooks(this.scroll,this.scroll.eventTypes.scrollEnd,this.modifyCurrentPage),this.registerHooks(this.scroll,this.scroll.eventTypes.scrollEnd,this.startPlay),this.scroll.eventTypes.mousewheelMove&&(this.registerHooks(this.scroll,this.scroll.eventTypes.mousewheelMove,(function(){return!0})),this.registerHooks(this.scroll,this.scroll.eventTypes.mousewheelEnd,(function(e){1!==e.directionX&&1!==e.directionY||t.next(),-1!==e.directionX&&-1!==e.directionY||t.prev()}))),this.registerHooks(e,e.eventTypes.refresh,this.refreshHandler),this.registerHooks(e,e.eventTypes.destroy,this.destroy),this.registerHooks(o,o.eventTypes.beforeRefresh,(function(){t.handleLoop(t.prevContent),t.setSlideInlineStyle()})),this.registerHooks(o,o.eventTypes.momentum,this.modifyScrollMetaHandler),this.registerHooks(o,o.eventTypes.scroll,this.scrollHandler),this.registerHooks(o,o.eventTypes.checkClick,this.startPlay),i&&this.registerHooks(o,o.eventTypes.flick,this.flickHandler)},t.prototype.startPlay=function(){var t=this,e=this.options,o=e.interval;e.autoplay&&(clearTimeout(this.autoplayTimer),this.autoplayTimer=window.setTimeout((function(){t.next()}),o))},t.prototype.pausePlay=function(){this.options.autoplay&&clearTimeout(this.autoplayTimer)},t.prototype.setSlideInlineStyle=function(){var t=this.scroll.scroller,e=t.content,o=t.wrapper,i=this.scroll.options;[{direction:"scrollX",sizeType:"offsetWidth",styleType:"width"},{direction:"scrollY",sizeType:"offsetHeight",styleType:"height"}].forEach((function(t){var s=t.direction,r=t.sizeType,n=t.styleType;if(i[s]){for(var a=o[r],h=e.children,l=h.length,c=0;c({isMQMobile:!1,slide:null,currentPageIndex:0,playTimer:0,mark:0,total:0,perPage:10,currentPage:1}),computed:{homeData(){return{...this.$page.frontmatter}},hasFeatures(){return!(!this.homeData.features||!this.homeData.features.length)},homeSidebarB(){const{htmlModules:t}=this.$themeConfig;return t?t.homeSidebarB:""},showBanner(){return!(this.$route.query.p&&1!=this.$route.query.p&&(!this.homeData.postList||"detailed"===this.homeData.postList))},bannerBgStyle(){let t=this.homeData.bannerBg;return t&&"auto"!==t?"none"===t?this.$themeConfig.bodyBgImg?"":"background: var(--mainBg);color: var(--textColor)":t.indexOf("background:")>-1?t:t.indexOf(".")>-1?`background: url(${this.$withBase(t)}) center center / cover no-repeat`:void 0:this.$themeConfig.bodyBgImg?"":"background: rgb(40,40,45) url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACMAAAAjCAYAAAAe2bNZAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAABOSURBVFhH7c6xCQAgDAVRR9A6E4hLu4uLiWJ7tSnuQcIvr2TRYsw3/zOGGEOMIcYQY4gxxBhiDDGGGEOMIcYQY4gxxBhiDLkx52W4Gn1tuslCtHJvL54AAAAASUVORK5CYII=)"},actionLink(){return{link:this.homeData.actionLink,text:this.homeData.actionText}}},components:{NavLink:i.default,MainLayout:Dt.default,PostList:Lt.default,UpdateArticle:Ot.default,BloggerBar:It.default,CategoriesBar:Ht.default,TagsBar:zt.default,Pagination:At.default},created(){this.total=this.$sortPosts.length},beforeMount(){this.isMQMobile=window.innerWidth<720},mounted(){this.$route.query.p&&(this.currentPage=Number(this.$route.query.p)),!this.hasFeatures||!this.isMQMobile||this.$route.query.p&&1!=this.$route.query.p||this.init(),this.hasFeatures&&window.addEventListener("resize",()=>{this.isMQMobile=window.innerWidth<720,!this.isMQMobile||this.slide||this.mark||(this.mark++,setTimeout(()=>{this.init()},60))})},beforeDestroy(){clearTimeout(this.playTimer),this.slide&&this.slide.destroy()},watch:{"$route.query.p"(){this.$route.query.p?this.currentPage=Number(this.$route.query.p):this.currentPage=1,this.hasFeatures&&1===this.currentPage&&this.isMQMobile&&setTimeout(()=>{this.slide&&this.slide.destroy(),this.init()},0)}},methods:{init(){clearTimeout(this.playTimer),this.slide=new vt(this.$refs.slide,{scrollX:!0,scrollY:!1,slide:{loop:!0,threshold:100},useTransition:!0,momentum:!1,bounce:!1,stopPropagation:!1,probeType:2,preventDefault:!1}),this.slide.on("beforeScrollStart",()=>{clearTimeout(this.playTimer)}),this.slide.on("scrollEnd",()=>{this.autoGoNext()}),this.slide.on("slideWillChange",t=>{this.currentPageIndex=t.pageX}),this.autoGoNext()},autoGoNext(){clearTimeout(this.playTimer),this.playTimer=setTimeout(()=>{this.slide.next()},4e3)},handlePagination(t){this.currentPage=t},getScrollTop:()=>window.pageYOffset||document.documentElement.scrollTop||document.body.scrollTop}},Nt=(o(349),o(4)),Ft=Object(Nt.a)($t,(function(){var t=this,e=t._self._c;return e("div",{staticClass:"home-wrapper"},[e("div",{staticClass:"banner",class:{"hide-banner":!t.showBanner},style:t.bannerBgStyle},[e("div",{staticClass:"banner-conent",style:!t.homeData.features&&!t.homeData.heroImage&&"padding-top: 7rem"},[e("header",{staticClass:"hero"},[t.homeData.heroImage?e("img",{attrs:{src:t.$withBase(t.homeData.heroImage),alt:t.homeData.heroAlt}}):t._e(),t._v(" "),t.homeData.heroText?e("h1",{attrs:{id:"main-title"}},[t._v("\n "+t._s(t.homeData.heroText)+"\n ")]):t._e(),t._v(" "),t.homeData.tagline?e("p",{staticClass:"description"},[t._v("\n "+t._s(t.homeData.tagline)+"\n ")]):t._e(),t._v(" "),t.homeData.actionText&&t.homeData.actionLink?e("p",{staticClass:"action"},[e("NavLink",{staticClass:"action-button",attrs:{item:t.actionLink}})],1):t._e()]),t._v(" "),t.hasFeatures&&!t.isMQMobile?e("div",{staticClass:"features"},t._l(t.homeData.features,(function(o,i){return e("div",{key:i,staticClass:"feature"},[o.link?e("router-link",{attrs:{to:o.link}},[o.imgUrl?e("img",{staticClass:"feature-img",attrs:{src:t.$withBase(o.imgUrl),alt:o.title}}):t._e(),t._v(" "),e("h2",[t._v(t._s(o.title))]),t._v(" "),e("p",[t._v(t._s(o.details))])]):e("a",{attrs:{href:"javascript:;"}},[o.imgUrl?e("img",{staticClass:"feature-img",attrs:{src:t.$withBase(o.imgUrl),alt:o.title}}):t._e(),t._v(" "),e("h2",[t._v(t._s(o.title))]),t._v(" "),e("p",[t._v(t._s(o.details))])])],1)})),0):t._e()]),t._v(" "),t.hasFeatures?e("div",{directives:[{name:"show",rawName:"v-show",value:t.isMQMobile,expression:"isMQMobile"}],staticClass:"slide-banner"},[e("div",{staticClass:"banner-wrapper"},[e("div",{ref:"slide",staticClass:"slide-banner-scroll"},[e("div",{staticClass:"slide-banner-wrapper"},t._l(t.homeData.features,(function(o,i){return e("div",{key:i,staticClass:"slide-item"},[o.link?e("router-link",{attrs:{to:o.link}},[o.imgUrl?e("img",{staticClass:"feature-img",attrs:{src:t.$withBase(o.imgUrl),alt:o.title}}):t._e(),t._v(" "),e("h2",[t._v(t._s(o.title))]),t._v(" "),e("p",[t._v(t._s(o.details))])]):e("a",{attrs:{href:"javascript:;"}},[o.imgUrl?e("img",{staticClass:"feature-img",attrs:{src:t.$withBase(o.imgUrl),alt:o.title}}):t._e(),t._v(" "),e("h2",[t._v(t._s(o.title))]),t._v(" "),e("p",[t._v(t._s(o.details))])])],1)})),0)]),t._v(" "),e("div",{staticClass:"docs-wrapper"},t._l(t.homeData.features.length,(function(o,i){return e("span",{key:i,staticClass:"doc",class:{active:t.currentPageIndex===i}})})),0)])]):t._e()]),t._v(" "),e("MainLayout",{scopedSlots:t._u([{key:"mainLeft",fn:function(){return["simple"===t.homeData.postList?e("UpdateArticle",{staticClass:"card-box",attrs:{length:t.homeData.simplePostListLength||10,moreArticle:t.$themeConfig.updateBar&&t.$themeConfig.updateBar.moreArticle}}):t.homeData.postList&&"detailed"!==t.homeData.postList?t._e():[e("PostList",{attrs:{currentPage:t.currentPage,perPage:t.perPage}}),t._v(" "),e("Pagination",{directives:[{name:"show",rawName:"v-show",value:Math.ceil(t.total/t.perPage)>1,expression:"Math.ceil(total / perPage) > 1"}],attrs:{total:t.total,perPage:t.perPage,currentPage:t.currentPage},on:{getCurrentPage:t.handlePagination}})],t._v(" "),e("Content",{staticClass:"theme-vdoing-content custom card-box"})]},proxy:!0},t.homeData.hideRightBar?null:{key:"mainRight",fn:function(){return[t.$themeConfig.blogger?e("BloggerBar"):t._e(),t._v(" "),!1!==t.$themeConfig.category&&t.$categoriesAndTags.categories.length?e("CategoriesBar",{attrs:{categoriesData:t.$categoriesAndTags.categories,length:10}}):t._e(),t._v(" "),!1!==t.$themeConfig.tag&&t.$categoriesAndTags.tags.length?e("TagsBar",{attrs:{tagsData:t.$categoriesAndTags.tags,length:30}}):t._e(),t._v(" "),t.homeSidebarB?e("div",{staticClass:"custom-html-box card-box",domProps:{innerHTML:t._s(t.homeSidebarB)}}):t._e()]},proxy:!0}],null,!0)})],1)}),[],!1,null,"7d2bb426",null);e.default=Ft.exports}}]); \ No newline at end of file diff --git a/assets/js/10.b8b1c69f.js b/assets/js/10.b8b1c69f.js new file mode 100644 index 0000000000..c3620c4013 --- /dev/null +++ b/assets/js/10.b8b1c69f.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[10,13,15,25,31,37],{251:function(t,e,s){},252:function(t,e,s){"use strict";s.r(e);var i=s(11),n={props:{item:{required:!0}},computed:{link(){return Object(i.c)(this.item.link)},exact(){return this.$site.locales?Object.keys(this.$site.locales).some(t=>t===this.link):"/"===this.link}},methods:{isExternal:i.g,isMailto:i.h,isTel:i.i,focusoutAction(){this.$emit("focusout")}}},o=s(4),r=Object(o.a)(n,(function(){var t=this,e=t._self._c;return t.isExternal(t.link)?e("a",{staticClass:"nav-link external",attrs:{href:t.link,target:t.isMailto(t.link)||t.isTel(t.link)?null:"_blank",rel:t.isMailto(t.link)||t.isTel(t.link)?null:"noopener noreferrer"},on:{focusout:t.focusoutAction}},[t._v("\n "+t._s(t.item.text)+"\n "),e("OutboundLink")],1):e("router-link",{staticClass:"nav-link",attrs:{to:t.link,exact:t.exact},nativeOn:{focusout:function(e){return t.focusoutAction.apply(null,arguments)}}},[t._v(t._s(t.item.text))])}),[],!1,null,null,null);e.default=r.exports},253:function(t,e,s){},254:function(t,e,s){"use strict";s.r(e);var i={name:"DropdownTransition",methods:{setHeight(t){t.style.height=t.scrollHeight+"px"},unsetHeight(t){t.style.height=""}}},n=(s(255),s(4)),o=Object(n.a)(i,(function(){return(0,this._self._c)("transition",{attrs:{name:"dropdown"},on:{enter:this.setHeight,"after-enter":this.unsetHeight,"before-leave":this.setHeight}},[this._t("default")],2)}),[],!1,null,null,null);e.default=o.exports},255:function(t,e,s){"use strict";s(251)},259:function(t,e,s){},261:function(t,e,s){"use strict";s(253)},265:function(t,e,s){},269:function(t,e,s){"use strict";s.r(e);var i=s(252),n=s(254),o=s(97),r=s.n(o),a={components:{NavLink:i.default,DropdownTransition:n.default},data:()=>({open:!1,isMQMobile:!1}),props:{item:{required:!0}},computed:{dropdownAriaLabel(){return this.item.ariaLabel||this.item.text}},beforeMount(){this.isMQMobile=window.innerWidth<720,window.addEventListener("resize",()=>{this.isMQMobile=window.innerWidth<720})},methods:{toggle(){this.isMQMobile&&(this.open=!this.open)},isLastItemOfArray:(t,e)=>r()(e)===t},watch:{$route(){this.open=!1}}},l=(s(261),s(4)),u=Object(l.a)(a,(function(){var t=this,e=t._self._c;return e("div",{staticClass:"dropdown-wrapper",class:{open:t.open}},[e("button",{staticClass:"dropdown-title",attrs:{type:"button","aria-label":t.dropdownAriaLabel},on:{click:t.toggle}},[t.item.link?e("router-link",{staticClass:"link-title",attrs:{to:t.item.link}},[t._v(t._s(t.item.text))]):t._e(),t._v(" "),e("span",{directives:[{name:"show",rawName:"v-show",value:!t.item.link,expression:"!item.link"}],staticClass:"title"},[t._v(t._s(t.item.text))]),t._v(" "),e("span",{staticClass:"arrow",class:t.open?"down":"right"})],1),t._v(" "),e("DropdownTransition",[e("ul",{directives:[{name:"show",rawName:"v-show",value:t.open,expression:"open"}],staticClass:"nav-dropdown"},t._l(t.item.items,(function(s,i){return e("li",{key:s.link||i,staticClass:"dropdown-item"},["links"===s.type?e("h4",[t._v(t._s(s.text))]):t._e(),t._v(" "),"links"===s.type?e("ul",{staticClass:"dropdown-subitem-wrapper"},t._l(s.items,(function(i){return e("li",{key:i.link,staticClass:"dropdown-subitem"},[e("NavLink",{attrs:{item:i},on:{focusout:function(e){t.isLastItemOfArray(i,s.items)&&t.isLastItemOfArray(s,t.item.items)&&t.toggle()}}})],1)})),0):e("NavLink",{attrs:{item:s},on:{focusout:function(e){t.isLastItemOfArray(s,t.item.items)&&t.toggle()}}})],1)})),0)])],1)}),[],!1,null,null,null);e.default=u.exports},274:function(t,e,s){"use strict";s(259)},276:function(t,e,s){"use strict";s.r(e);var i=s(269),n=s(11),o={components:{NavLink:s(252).default,DropdownLink:i.default},computed:{userNav(){return this.$themeLocaleConfig.nav||this.$site.themeConfig.nav||[]},nav(){const{locales:t}=this.$site;if(t&&Object.keys(t).length>1){const e=this.$page.path,s=this.$router.options.routes,i=this.$site.themeConfig.locales||{},n={text:this.$themeLocaleConfig.selectText||"Languages",ariaLabel:this.$themeLocaleConfig.ariaLabel||"Select language",items:Object.keys(t).map(n=>{const o=t[n],r=i[n]&&i[n].label||o.lang;let a;return o.lang===this.$lang?a=e:(a=e.replace(this.$localeConfig.path,n),s.some(t=>t.path===a)||(a=n)),{text:r,link:a}})};return[...this.userNav,n]}return this.userNav},userLinks(){return(this.nav||[]).map(t=>Object.assign(Object(n.k)(t),{items:(t.items||[]).map(n.k)}))},repoLink(){const{repo:t}=this.$site.themeConfig;return t?/^https?:/.test(t)?t:"https://github.com/"+t:null},repoLabel(){if(!this.repoLink)return;if(this.$site.themeConfig.repoLabel)return this.$site.themeConfig.repoLabel;const t=this.repoLink.match(/^https?:\/\/[^/]+/)[0],e=["GitHub","GitLab","Bitbucket"];for(let s=0;s({query:"",focused:!1,focusIndex:0,placeholder:void 0}),mounted(){this.placeholder=this.$site.themeConfig.searchPlaceholder||"",document.addEventListener("keydown",this.onHotkey)},beforeDestroy(){document.removeEventListener("keydown",this.onHotkey)},computed:{showSuggestions(){return this.focused&&this.suggestions},suggestions(){const t=this.query.trim().toLowerCase();if(!t)return;const{pages:e}=this.$site,s=this.$site.themeConfig.searchMaxSuggestions||5,i=this.$localePath,n=e=>e&&e.title&&e.title.toLowerCase().indexOf(t)>-1,o=[];for(let t=0;t=s);t++){const r=e[t];if(this.getPageLocalePath(r)===i&&this.isSearchable(r))if(n(r))o.push(r);else if(r.headers)for(let t=0;t=s);t++){const e=r.headers[t];n(e)&&o.push(Object.assign({},r,{path:r.path+"#"+e.slug,header:e}))}}return[{title:"在MDN中搜索",frontUrl:"https://developer.mozilla.org/zh-CN/search?q=",behindUrl:""},{title:"在Runoob中搜索",frontUrl:"https://www.runoob.com/?s="},{title:"在Vue API中搜索",frontUrl:"https://cn.vuejs.org/v2/api/#"},{title:"在Bing中搜索",frontUrl:"https://cn.bing.com/search?q="}].length&&[{title:"在MDN中搜索",frontUrl:"https://developer.mozilla.org/zh-CN/search?q=",behindUrl:""},{title:"在Runoob中搜索",frontUrl:"https://www.runoob.com/?s="},{title:"在Vue API中搜索",frontUrl:"https://cn.vuejs.org/v2/api/#"},{title:"在Bing中搜索",frontUrl:"https://cn.bing.com/search?q="}].forEach(t=>{t.thirdparty=!0,t.title=`${t.title}"${this.query}"`,t.behindUrl=t.behindUrl||"",o.push(t)}),o},alignRight(){return(this.$site.themeConfig.nav||[]).length+(this.$site.repo?1:0)<=2}},methods:{getPageLocalePath(t){for(const e in this.$site.locales||{})if("/"!==e&&0===t.path.indexOf(e))return e;return"/"},isSearchable(t){let e=null;return null===e||(e=Array.isArray(e)?e:new Array(e),e.filter(e=>t.path.match(e)).length>0)},onHotkey(t){t.srcElement===document.body&&["s","/"].includes(t.key)&&(this.$refs.input.focus(),t.preventDefault())},onUp(){this.showSuggestions&&(this.focusIndex>0?this.focusIndex--:this.focusIndex=this.suggestions.length-1)},onDown(){this.showSuggestions&&(this.focusIndex "+t._s(s.header.title))]):t._e()])])})),0):t._e()])}),[],!1,null,null,null).exports,r=s(306),a=s(276);function l(t,e){return t.ownerDocument.defaultView.getComputedStyle(t,null)[e]}var u={components:{SidebarButton:r.default,NavLinks:a.default,SearchBox:o,AlgoliaSearchBox:{}},data:()=>({linksWrapMaxWidth:null}),mounted(){const t=parseInt(l(this.$el,"paddingLeft"))+parseInt(l(this.$el,"paddingRight")),e=()=>{document.documentElement.clientWidth<719?this.linksWrapMaxWidth=null:this.linksWrapMaxWidth=this.$el.offsetWidth-t-(this.$refs.siteName&&this.$refs.siteName.offsetWidth||0)};e(),window.addEventListener("resize",e,!1)},computed:{algolia(){return this.$themeLocaleConfig.algolia||this.$site.themeConfig.algolia||{}},isAlgoliaSearch(){return this.algolia&&this.algolia.apiKey&&this.algolia.indexName}}},c=(s(316),Object(n.a)(u,(function(){var t=this,e=t._self._c;return e("header",{staticClass:"navbar blur"},[e("SidebarButton",{on:{"toggle-sidebar":function(e){return t.$emit("toggle-sidebar")}}}),t._v(" "),e("router-link",{staticClass:"home-link",attrs:{to:t.$localePath}},[t.$site.themeConfig.logo?e("img",{staticClass:"logo",attrs:{src:t.$withBase(t.$site.themeConfig.logo),alt:t.$siteTitle}}):t._e(),t._v(" "),t.$siteTitle?e("span",{ref:"siteName",staticClass:"site-name",class:{"can-hide":t.$site.themeConfig.logo}},[t._v(t._s(t.$siteTitle))]):t._e()]),t._v(" "),e("div",{staticClass:"links",style:t.linksWrapMaxWidth?{"max-width":t.linksWrapMaxWidth+"px"}:{}},[t.isAlgoliaSearch?e("AlgoliaSearchBox",{attrs:{options:t.algolia}}):!1!==t.$site.themeConfig.search&&!1!==t.$page.frontmatter.search?e("SearchBox"):t._e(),t._v(" "),e("NavLinks",{staticClass:"can-hide"})],1)],1)}),[],!1,null,null,null));e.default=c.exports}}]); \ No newline at end of file diff --git a/assets/js/100.6c889d38.js b/assets/js/100.6c889d38.js new file mode 100644 index 0000000000..3135524924 --- /dev/null +++ b/assets/js/100.6c889d38.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[100],{426:function(a,e,s){"use strict";s.r(e);var t=s(4),v=Object(t.a)({},(function(){var a=this,e=a._self._c;return e("ContentSlotsDistributor",{attrs:{"slot-key":a.$parent.slotKey}},[e("h2",{attrs:{id:"基本"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#基本"}},[a._v("#")]),a._v(" 基本")]),a._v(" "),e("ul",[e("li",[e("code",[a._v(".")]),a._v(": 除换行符以外的所有字符。")]),a._v(" "),e("li",[e("code",[a._v("^")]),a._v(": 字符串开头。")]),a._v(" "),e("li",[e("code",[a._v("$")]),a._v(": 字符串结尾。")]),a._v(" "),e("li",[e("code",[a._v("\\d,\\w,\\s")]),a._v(": 匹配数字、字符、空格。")]),a._v(" "),e("li",[e("code",[a._v("\\D,\\W,\\S")]),a._v(": 匹配非数字、非字符、非空格。")]),a._v(" "),e("li",[e("code",[a._v("[abc]")]),a._v(": 匹配 a、b 或 c 中的一个字母。")]),a._v(" "),e("li",[e("code",[a._v("[a-z]")]),a._v(": 匹配 a 到 z 中的一个字母。")]),a._v(" "),e("li",[e("code",[a._v("[^abc]")]),a._v(": 匹配除了 a、b 或 c 中的其他字母。")]),a._v(" "),e("li",[e("code",[a._v("aa|bb")]),a._v(": 匹配 aa 或 bb。")]),a._v(" "),e("li",[e("code",[a._v("?")]),a._v(": 0 次或 1 次匹配。")]),a._v(" "),e("li",[e("code",[a._v("*")]),a._v(": 匹配 0 次或多次。")]),a._v(" "),e("li",[e("code",[a._v("+")]),a._v(": 匹配 1 次或多次。")]),a._v(" "),e("li",[e("code",[a._v("{n}")]),a._v(": 匹配 n 次。")]),a._v(" "),e("li",[e("code",[a._v("{n,}")]),a._v(": 匹配 n 次以上。")]),a._v(" "),e("li",[e("code",[a._v("{m,n}")]),a._v(": 最少 m 次,最多 n 次匹配。")]),a._v(" "),e("li",[e("code",[a._v("(expr)")]),a._v(": 捕获 expr 子模式,以 \\1 使用它。")]),a._v(" "),e("li",[e("code",[a._v("(?:expr)")]),a._v(": 忽略捕获的子模式。")]),a._v(" "),e("li",[e("code",[a._v("(?=expr)")]),a._v(": 正向预查模式 expr。")]),a._v(" "),e("li",[e("code",[a._v("(?!expr)")]),a._v(": 负向预查模式 expr。")])]),a._v(" "),e("h2",{attrs:{id:"复合"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#复合"}},[a._v("#")]),a._v(" 复合")]),a._v(" "),e("ul",[e("li",[e("code",[a._v("^\\d\\.\\s[^\\x00-\\x7F]+:$")]),a._v(": 单数字开头,随后是一个点号。 后面是空格,随后是若干个非 ASCII 字符,最后是一个冒号。")]),a._v(" "),e("li",[e("code",[a._v("(^[^\\s]+):")]),a._v(":")]),a._v(" "),e("li",[e("code",[a._v("(^[^\\x00-\\x7F]+) ([a-zA-Z]) ([^\\x00-\\x7F]):")]),a._v(": 匹配类似 '按下 i 键:'")])]),a._v(" "),e("h2",{attrs:{id:"其他"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#其他"}},[a._v("#")]),a._v(" 其他")]),a._v(" "),e("h3",{attrs:{id:"n-引用捕获组索引"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#n-引用捕获组索引"}},[a._v("#")]),a._v(" "),e("code",[a._v("$n")]),a._v(",引用捕获组索引")]),a._v(" "),e("blockquote",[e("p",[a._v("了解 $1")])]),a._v(" "),e("p",[a._v("正则表达式中的 "),e("code",[a._v("$1")]),a._v(" 不是用于匹配文本的模式,而是用于在正则表达式替换中引用匹配组(捕获组)的特殊语法。它通常用于替换操作,以便在替换文本中使用匹配的内容。")]),a._v(" "),e("p",[a._v("在正则表达式替换中,通常使用圆括号 "),e("code",[a._v("()")]),a._v(" 来创建捕获组,然后可以使用 "),e("code",[a._v("$1")]),a._v("、"),e("code",[a._v("$2")]),a._v("、"),e("code",[a._v("$3")]),a._v(" 等来引用这些捕获组,以在替换文本中插入匹配的内容。每个 "),e("code",[a._v("$n")]),a._v(" 表示引用第 n 个捕获组的内容。")]),a._v(" "),e("p",[a._v("例如,假设我们有以下文本:")]),a._v(" "),e("div",{staticClass:"language-yaml line-numbers-mode"},[e("pre",{pre:!0,attrs:{class:"language-yaml"}},[e("code",[e("span",{pre:!0,attrs:{class:"token key atrule"}},[a._v("Name")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(":")]),a._v(" John"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(",")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token key atrule"}},[a._v("Age")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(":")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[a._v("30")]),a._v("\n")])]),a._v(" "),e("div",{staticClass:"line-numbers-wrapper"},[e("span",{staticClass:"line-number"},[a._v("1")]),e("br")])]),e("p",[a._v("如果我们想要提取名字和年龄,并在替换文本中使用它们,可以使用正则表达式:")]),a._v(" "),e("div",{staticClass:"language-yaml line-numbers-mode"},[e("pre",{pre:!0,attrs:{class:"language-yaml"}},[e("code",[e("span",{pre:!0,attrs:{class:"token key atrule"}},[a._v("Name")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(":")]),a._v(" (\\w+)"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(",")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token key atrule"}},[a._v("Age")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(":")]),a._v(" (\\d+)\n")])]),a._v(" "),e("div",{staticClass:"line-numbers-wrapper"},[e("span",{staticClass:"line-number"},[a._v("1")]),e("br")])]),e("p",[a._v("在替换文本中,我们可以使用 "),e("code",[a._v("$1")]),a._v(" 来引用第一个捕获组(名字),使用 "),e("code",[a._v("$2")]),a._v(" 来引用第二个捕获组(年龄)。例如,可以将其替换为:")]),a._v(" "),e("div",{staticClass:"language-bash line-numbers-mode"},[e("pre",{pre:!0,attrs:{class:"language-bash"}},[e("code",[a._v("Hello, "),e("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$1")]),e("span",{pre:!0,attrs:{class:"token operator"}},[a._v("!")]),a._v(" You are "),e("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$2")]),a._v(" years old.\n")])]),a._v(" "),e("div",{staticClass:"line-numbers-wrapper"},[e("span",{staticClass:"line-number"},[a._v("1")]),e("br")])]),e("p",[a._v("替换后的文本将是:")]),a._v(" "),e("div",{staticClass:"language-sql line-numbers-mode"},[e("pre",{pre:!0,attrs:{class:"language-sql"}},[e("code",[a._v("Hello"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(",")]),a._v(" John"),e("span",{pre:!0,attrs:{class:"token operator"}},[a._v("!")]),a._v(" You are "),e("span",{pre:!0,attrs:{class:"token number"}},[a._v("30")]),a._v(" years old"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(".")]),a._v("\n")])]),a._v(" "),e("div",{staticClass:"line-numbers-wrapper"},[e("span",{staticClass:"line-number"},[a._v("1")]),e("br")])]),e("p",[a._v("请注意,"),e("code",[a._v("$1")]),a._v(" 在正则表达式模式中不是一个有效的匹配,而是在替换操作中用于引用捕获组的方式。")]),a._v(" "),e("h2",{attrs:{id:"链接"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#链接"}},[a._v("#")]),a._v(" 链接")]),a._v(" "),e("ul",[e("li",[e("a",{attrs:{href:"https://www.runoob.com/regexp/regexp-tutorial.html",target:"_blank",rel:"noopener noreferrer"}},[a._v("正则表达式 - 教程"),e("OutboundLink")],1)]),a._v(" "),e("li",[e("a",{attrs:{href:"https://c.runoob.com/front-end/854/",target:"_blank",rel:"noopener noreferrer"}},[a._v("online-tool"),e("OutboundLink")],1)])])])}),[],!1,null,null,null);e.default=v.exports}}]); \ No newline at end of file diff --git a/assets/js/101.60ad6dbe.js b/assets/js/101.60ad6dbe.js new file mode 100644 index 0000000000..3e2d616d76 --- /dev/null +++ b/assets/js/101.60ad6dbe.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[101],{427:function(t,n,e){"use strict";e.r(n);var s=e(4),a=Object(s.a)({},(function(){var t=this._self._c;return t("ContentSlotsDistributor",{attrs:{"slot-key":this.$parent.slotKey}},[t("blockquote",[t("p",[t("a",{attrs:{href:"https://github.com/shengcaishizhan/kkndme_tianya",target:"_blank",rel:"noopener noreferrer"}},[this._v("https://github.com/shengcaishizhan/kkndme_tianya"),t("OutboundLink")],1),this._v(" 待补充")])])])}),[],!1,null,null,null);n.default=a.exports}}]); \ No newline at end of file diff --git a/assets/js/102.4127c84d.js b/assets/js/102.4127c84d.js new file mode 100644 index 0000000000..ce887357ad --- /dev/null +++ b/assets/js/102.4127c84d.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[102],{428:function(t,a,r){"use strict";r.r(a);var s=r(4),e=Object(s.a)({},(function(){var t=this,a=t._self._c;return a("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[a("blockquote",[a("p",[t._v("娥姐职场分享的提高效率的 5 个关键点, "),a("a",{attrs:{href:"https://www.bilibili.com/video/BV1JY4y1b7wC?spm_id_from=333.999.0.0",target:"_blank",rel:"noopener noreferrer"}},[t._v("原视频链接"),a("OutboundLink")],1)])]),t._v(" "),a("h2",{attrs:{id:"_5-个关键点"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_5-个关键点"}},[t._v("#")]),t._v(" 5 个关键点")]),t._v(" "),a("h3",{attrs:{id:"一、输出倒逼输入"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#一、输出倒逼输入"}},[t._v("#")]),t._v(" 一、输出倒逼输入")]),t._v(" "),a("h3",{attrs:{id:"二、提炼模型"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#二、提炼模型"}},[t._v("#")]),t._v(" 二、提炼模型")]),t._v(" "),a("p",[t._v("从现象中提取模型,用模型思考问题和解法")]),t._v(" "),a("h3",{attrs:{id:"三、利用工具-解放自己的大脑"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#三、利用工具-解放自己的大脑"}},[t._v("#")]),t._v(" 三、利用工具:解放自己的大脑")]),t._v(" "),a("p",[t._v("把我们的大脑从繁琐的事务解放出来,只去记忆和思考更加重要的事情")]),t._v(" "),a("h3",{attrs:{id:"四、研究自己运行规律-找到让自己学习工作、效率更高的方法"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#四、研究自己运行规律-找到让自己学习工作、效率更高的方法"}},[t._v("#")]),t._v(" 四、研究自己运行规律,找到让自己学习工作、效率更高的方法")]),t._v(" "),a("p",[t._v("要具备自我观察和迭代的意识,这样才能持续找到提升效率的机会")]),t._v(" "),a("h3",{attrs:{id:"五、成本可控-释放善意"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#五、成本可控-释放善意"}},[t._v("#")]),t._v(" 五、成本可控,释放善意")])])}),[],!1,null,null,null);a.default=e.exports}}]); \ No newline at end of file diff --git a/assets/js/103.3d9db5eb.js b/assets/js/103.3d9db5eb.js new file mode 100644 index 0000000000..79e254b062 --- /dev/null +++ b/assets/js/103.3d9db5eb.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[103],{429:function(t,e,r){"use strict";r.r(e);var a=r(4),i=Object(a.a)({},(function(){var t=this,e=t._self._c;return e("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[e("h2",{attrs:{id:"sublime-text"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#sublime-text"}},[t._v("#")]),t._v(" Sublime Text")]),t._v(" "),e("h3",{attrs:{id:"选择"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#选择"}},[t._v("#")]),t._v(" 选择")]),t._v(" "),e("p",[t._v("在 macOS 上,Sublime Text 提供了多种选择文本的方式,其中包括块状选择。下面是一些在 Sublime Text 中选择文本的常见方式:")]),t._v(" "),e("ol",[e("li",[t._v("基本选择:")])]),t._v(" "),e("ul",[e("li",[t._v("单词选择:双击单词即可选择整个单词。")]),t._v(" "),e("li",[t._v("行选择:点击行号区域,选中整行。")]),t._v(" "),e("li",[t._v("段落选择:连续按两次 Ctrl(或 Command)键,并单击鼠标,即可选择整个段落。")])]),t._v(" "),e("ol",{attrs:{start:"2"}},[e("li",[t._v("块状选择(多光标选择):")])]),t._v(" "),e("ul",[e("li",[t._v("垂直选择:按住 Option(或 Alt)键,并使用鼠标拖动,可进行垂直方向上的选择。这样可以创建多个光标,使得你可以同时编辑多个位置的文本。")]),t._v(" "),e("li",[t._v("列选择:按住 Shift + Option(或 Shift + Alt)键,并使用鼠标拖动,可进行块状选择。这种选择方式可用于选择多行中相同列位置的文本,非常适用于进行批量编辑。")])]),t._v(" "),e("ol",{attrs:{start:"3"}},[e("li",[t._v("快速选择:")])]),t._v(" "),e("ul",[e("li",[t._v("多重选择:按住 Ctrl(或 Command)键,并单击想要选择的文本,可以进行多重选择。")]),t._v(" "),e("li",[t._v("选择相同内容:选中文本后,按下快捷键 Ctrl + D,Sublime Text 将自动选择下一个相同的内容。可以多次按下该快捷键以选择所有相同内容。")]),t._v(" "),e("li",[t._v("选择括号内容:将光标放在括号上,按下快捷键 Ctrl + Shift + M,Sublime Text 将选择括号内的内容。可以多次按下该快捷键以逐级选择外层的括号。")])]),t._v(" "),e("ol",{attrs:{start:"4"}},[e("li",[t._v("正则表达式选择:")])]),t._v(" "),e("ul",[e("li",[t._v("按下快捷键 Ctrl + F(或 Command + F),在查找框中输入正则表达式,然后按下快捷键 Alt + Enter(或 Option + Enter),Sublime Text 将会选择所有与正则表达式匹配的文本。")])]),t._v(" "),e("p",[t._v("这些选择方式可以帮助你在 Sublime Text 中高效地选择和编辑文本。通过灵活运用这些技巧,你可以快速准确地选择并修改所需的文本内容。")]),t._v(" "),e("h3",{attrs:{id:"批量插入"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#批量插入"}},[t._v("#")]),t._v(" 批量插入")]),t._v(" "),e("blockquote",[e("p",[t._v("【背景】在每一行前添加字符#, 下面的图片是需求背景")])]),t._v(" "),e("p",[e("img",{attrs:{src:"https://cdn.jsdelivr.net/gh/jacky1234/picArchieve@master/uPic/20230723_111201_1lWVVE.png",alt:""}})]),t._v(" "),e("p",[t._v("一、操作步骤")]),t._v(" "),e("ol",[e("li",[t._v("首先使用款选择器,按住 alt 键,选择区域,如下。\n"),e("img",{attrs:{src:"https://cdn.jsdelivr.net/gh/jacky1234/picArchieve@master/uPic/20230723_111431_zNGEYU.png",alt:""}})]),t._v(" "),e("li",[t._v("按下 "),e("code",[t._v("Shift + Command + L")]),t._v(" 快捷键,或者在菜单栏选择 Selection -> Split into Lines。这将把每个多重光标限制在每一行的开头。")]),t._v(" "),e("li",[t._v("在键盘上按下 "),e("code",[t._v("#")]),t._v(" 键。这将在每个多重光标所在行的开头插入 "),e("code",[t._v("#")])])]),t._v(" "),e("p",[t._v("二、总结:\n本质上,上面的方式使用了,多重光标(Multiple Cursors)的功能来在每一行的开头添加 #")]),t._v(" "),e("h3",{attrs:{id:"插件"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#插件"}},[t._v("#")]),t._v(" 插件")]),t._v(" "),e("h4",{attrs:{id:"compare-side-by-side"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#compare-side-by-side"}},[t._v("#")]),t._v(" Compare Side-By-Side")]),t._v(" "),e("blockquote",[e("p",[t._v("https://packagecontrol.io/packages/Compare%20Side-By-Side")])]),t._v(" "),e("h2",{attrs:{id:"常用网址"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#常用网址"}},[t._v("#")]),t._v(" 常用网址")]),t._v(" "),e("ul",[e("li",[e("a",{attrs:{href:"https://xclient.info/",target:"_blank",rel:"noopener noreferrer"}},[t._v("xclient"),e("OutboundLink")],1)]),t._v(" "),e("li",[e("a",{attrs:{href:"https://www.iplaysoft.com/",target:"_blank",rel:"noopener noreferrer"}},[t._v("异次元"),e("OutboundLink")],1)]),t._v(" "),e("li",[e("a",{attrs:{href:"https://www.jizhihezi.com/957/",target:"_blank",rel:"noopener noreferrer"}},[t._v("8 个 mac 常用破解软件网站"),e("OutboundLink")],1)])])])}),[],!1,null,null,null);e.default=i.exports}}]); \ No newline at end of file diff --git a/assets/js/104.46c9c015.js b/assets/js/104.46c9c015.js new file mode 100644 index 0000000000..9a21bc3c14 --- /dev/null +++ b/assets/js/104.46c9c015.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[104],{430:function(v,_,a){"use strict";a.r(_);var t=a(4),r=Object(t.a)({},(function(){var v=this,_=v._self._c;return _("ContentSlotsDistributor",{attrs:{"slot-key":v.$parent.slotKey}},[_("h2",{attrs:{id:"美国非农数据"}},[_("a",{staticClass:"header-anchor",attrs:{href:"#美国非农数据"}},[v._v("#")]),v._v(" 美国非农数据")]),v._v(" "),_("blockquote",[_("p",[v._v("非农数据(Non-Farm Payroll data)是指美国劳工部每月公布的关于美国非农部门就业情况的统计数据。这些数据通常包括非农业部门新增就业人数、失业率以及平均时薪等信息。")])]),v._v(" "),_("p",[v._v("非农数据是经济学家、投资者和市场参与者关注的重要指标之一,对于评估美国经济的健康状况和就业市场的表现具有重要意义。这些数据被视为经济增长和劳动力市场情况的晴雨表,对金融市场和货币政策的决策有着潜在的影响。")]),v._v(" "),_("p",[v._v("投资者通常会关注非农数据的发布,因为它可以提供关于经济活动和就业市场的重要线索。如果非农就业人数增加,失业率下降,并同时伴随着平均时薪的增长,这可能被视为经济繁荣的迹象。相反,如果非农就业数据低于预期,失业率上升,可能暗示着经济放缓或衰退。")]),v._v(" "),_("p",[v._v("非农数据对金融市场也有很大的影响,特别是对外汇市场和股票市场。这些数据的发布通常会引起市场波动,可能导致货币汇率和股票价格的剧烈变动。")]),v._v(" "),_("p",[v._v("总而言之,非农数据是关于美国非农部门就业情况的重要统计数据,对于评估美国经济和劳动力市场的状况以及对金融市场的影响具有重要意义。")]),v._v(" "),_("h3",{attrs:{id:"非农数据对加息决策的影响"}},[_("a",{staticClass:"header-anchor",attrs:{href:"#非农数据对加息决策的影响"}},[v._v("#")]),v._v(" 非农数据对加息决策的影响")]),v._v(" "),_("blockquote",[_("p",[v._v("非农数据通常会对央行的加息决策产生影响,尤其是美国联邦储备系统(Federal Reserve)的决策。这是因为非农数据反映了美国劳动力市场的状况,而就业市场是经济活动和通胀预期的重要指标之一。")])]),v._v(" "),_("p",[v._v("如果非农数据显示就业市场强劲,非农部门新增就业人数增加、失业率下降以及工资水平上升,这可能被视为经济繁荣的迹象。在这种情况下,美联储可能倾向于采取紧缩的货币政策,包括加息。他们可能认为经济已经足够强劲,需要采取措施来控制通胀风险。")]),v._v(" "),_("p",[v._v("相反,如果非农数据显示就业市场疲软,非农部门新增就业人数低于预期、失业率上升或工资增长放缓,这可能表明经济增长放缓或存在风险。在这种情况下,美联储可能倾向于采取宽松的货币政策,延迟加息甚至采取降息措施,以促进经济复苏和就业增长。")]),v._v(" "),_("p",[v._v("需要指出的是,非农数据只是美联储加息决策的一个因素,央行还会考虑其他经济指标、通胀压力、全球经济状况和金融市场的表现等多个因素。此外,市场对非农数据的解读和预期也可能影响货币政策的预期和市场情绪。")]),v._v(" "),_("p",[v._v("总之,非农数据可以影响美联储等央行的加息决策。强劲的非农数据可能导致紧缩货币政策和加息预期,而疲软的非农数据可能导致宽松货币政策和延迟加息。然而,货币政策的决策过程是复杂的,并受到多个因素的影响。")]),v._v(" "),_("h3",{attrs:{id:"非农数据对贵金属的影响"}},[_("a",{staticClass:"header-anchor",attrs:{href:"#非农数据对贵金属的影响"}},[v._v("#")]),v._v(" 非农数据对贵金属的影响")]),v._v(" "),_("p",[v._v("该数据是观察社会经济和金融发展程度和状况的一项重要指标。一般情况下,非农就业人数的公布值高于经济学家的预计值,代表美国经济发展良好利好美元,利空黄金。当非农就业人数的公布值低于经济学家的预计值,则表明美国经济发展陷入困境利好黄金,利空美元。")]),v._v(" "),_("h2",{attrs:{id:"降息对黄金的影响"}},[_("a",{staticClass:"header-anchor",attrs:{href:"#降息对黄金的影响"}},[v._v("#")]),v._v(" 降息对黄金的影响")]),v._v(" "),_("blockquote",[_("p",[v._v("对美联储有降息预期,是否应该投资黄金?")])]),v._v(" "),_("p",[v._v("黄金通常被视为一种避险资产,当投资者对经济前景感到不确定或担忧时,他们可能会倾向于购买黄金作为一种保值手段。如果有降息预期,意味着市场上的流动资金预期会变多,可能会引发对经济增长放缓或不稳定的担忧,这可能会导致投资者寻求避险资产,其中包括黄金。")]),v._v(" "),_("p",[v._v("然而,投资黄金也存在风险和不确定性。黄金价格受多种因素影响,包括"),_("RText",{attrs:{text:"经济状况、通货膨胀预期、货币政策、地缘政治风险",color:"red"}}),v._v("等。预测黄金价格的走势是困难的,市场变化时常不可预测")],1),v._v(" "),_("p",[v._v("在做出投资决策之前,建议你考虑以下几点:")]),v._v(" "),_("ol",[_("li",[v._v("研究和了解黄金市场:了解黄金市场的基本知识和趋势,包括历史表现、市场因素和风险。")]),v._v(" "),_("li",[v._v("多样化投资组合:不要将所有资金都投资于黄金或单一资产类别。考虑将资金分散投资于多个资产类别,以降低风险。")]),v._v(" "),_("li",[v._v("评估自己的投资目标和风险承受能力:确定自己的投资目标、时间范围和风险承受能力。不同的人有不同的投资目标和风险偏好,因此投资策略也会有所不同。")]),v._v(" "),_("li",[v._v("寻求专业意见:如果你不确定应该如何进行投资,考虑咨询金融顾问或专业投资人士,以获取个性化的投资建议。")])]),v._v(" "),_("h2",{attrs:{id:"除权除息"}},[_("a",{staticClass:"header-anchor",attrs:{href:"#除权除息"}},[v._v("#")]),v._v(" 除权除息")]),v._v(" "),_("p",[v._v("除权除息是指股票交易过程中,股票的权益发生变化,例如分红、送股、配股等。一般来说,除权除息对股票投资者来说是一个正常的市场操作,具体是否是好事取决于具体情况和投资者的策略。")]),v._v(" "),_("p",[v._v("在某些情况下,除权除息可能被视为好事。例如,如果公司宣布分红,投资者将获得额外的现金回报,这可以提高投资者的收益。此外,配股可能给投资者提供购买额外股份的机会,从而增加其持股量。")]),v._v(" "),_("p",[v._v("然而,除权除息对每个股票和每个投资者可能具有不同的影响。有时,除权除息可能会导致股价下跌,因为市场预期股票权益变动后的价格调整。此外,除权除息也可能会影响投资者的持股比例和股权结构。")]),v._v(" "),_("p",[v._v("因此,判断除权除息是否是好事需要综合考虑许多因素,包括公司的财务状况、市场环境、投资者的投资目标和时间段等。投资者应该仔细研究和评估相关信息,并根据自己的投资策略做出决策。此外,建议在进行股票投资之前咨询专业的金融顾问或进行充分的研究,以便做出明智的投资决策。")]),v._v(" "),_("h2",{attrs:{id:"tradingview"}},[_("a",{staticClass:"header-anchor",attrs:{href:"#tradingview"}},[v._v("#")]),v._v(" tradingView")]),v._v(" "),_("blockquote",[_("p",[_("a",{attrs:{href:"https://www.tradingview.com/",target:"_blank",rel:"noopener noreferrer"}},[v._v("https://www.tradingview.com/"),_("OutboundLink")],1)])]),v._v(" "),_("p",[_("code",[v._v("tradingView")]),v._v("是一款广受欢迎的在线金融图表分析平台,它提供了丰富的技术分析工具和图表,帮助交易者进行市场分析和决策。尽管 TradingView 是一个功能强大的平台,但它并不直接支持自动化交易。但是,你可以将 TradingView 与一些支持自动化交易的交易平台(如 MetaTrader、NinjaTrader 等)或自己编写的程序进行集成,以实现量化交易策略。")]),v._v(" "),_("p",[v._v("以下是一种使用 TradingView 进行量化交易的基本流程:")]),v._v(" "),_("ol",[_("li",[_("p",[v._v("创建交易策略:在 TradingView 上使用图表和技术指标进行市场分析,开发和测试你的交易策略。你可以使用 TradingView 的 Pine 脚本编程语言编写自定义指标和策略。")])]),v._v(" "),_("li",[_("p",[v._v("设置警报:使用 TradingView 的警报功能,在你的交易策略满足特定条件时触发警报。这些条件可以是技术指标的交叉、价格水平的突破等。")])]),v._v(" "),_("li",[_("p",[v._v("集成交易平台:选择一个支持自动化交易的交易平台,并将其与 TradingView 进行集成。一些交易平台提供与 TradingView 的 API 连接,使你可以接收来自 TradingView 的警报,并执行相应的交易操作。")])]),v._v(" "),_("li",[_("p",[v._v("自动执行交易:一旦 TradingView 触发警报并将其发送到交易平台,交易平台将执行你预先设置的交易指令,如市价单、限价单等。这样,你的交易策略就能自动化地执行。")])])]),v._v(" "),_("p",[v._v("需要注意的是,具体的集成步骤和可用的交易平台取决于你选择的交易平台和相关的 API。你可以在 TradingView 的官方网站上查找有关 API 和交易平台集成的更多信息,或者咨询交易平台的支持团队以获取帮助。")]),v._v(" "),_("h2",{attrs:{id:"lpr"}},[_("a",{staticClass:"header-anchor",attrs:{href:"#lpr"}},[v._v("#")]),v._v(" LPR")]),v._v(" "),_("p",[v._v("LPR 是 "),_("code",[v._v("Loan Prime Rate")]),v._v("(贷款市场报价利率)的缩写,是中国银行系统对商业贷款利率的参考利率。LPR 的设定由中国人民银行(中国的央行)主导,用于引导和调控商业银行的贷款利率水平。")]),v._v(" "),_("p",[v._v("LPR 是一种利率框架,采用基准利率加点的方式确定实际贷款利率。基准利率是由中国人民银行公布的,而加点部分则由商业银行根据借款人的信用状况和风险评估确定。")]),v._v(" "),_("p",[v._v("利率是指在一定时间内借款人向贷款提供者支付的费用,以获取使用贷款资金的权益。利率的高低直接影响到借款成本和借款人的还款负担。通常情况下,贷款利率越低,借款成本越低,借款人的还款压力也相对较小。")]),v._v(" "),_("p",[v._v("利率的设定受多种因素影响,包括货币政策、市场供求关系、经济形势、通胀预期等。央行通过调整政策利率,如 LPR,来影响市场利率水平,以实现宏观经济调控的目标,如促进经济增长、稳定金融市场等。")]),v._v(" "),_("p",[v._v("需要注意的是,利率是根据市场情况和监管政策调整的,会有一定的浮动性和调整周期,不同类型的贷款产品和借款人可能会适用不同的利率标准。借款人在选择贷款时应留意不同利率产品之间的区别,并根据自身情况选择适合的贷款利率。")]),v._v(" "),_("h2",{attrs:{id:"_2023"}},[_("a",{staticClass:"header-anchor",attrs:{href:"#_2023"}},[v._v("#")]),v._v(" 2023")])])}),[],!1,null,null,null);_.default=r.exports}}]); \ No newline at end of file diff --git a/assets/js/105.47aefb8e.js b/assets/js/105.47aefb8e.js new file mode 100644 index 0000000000..2369e470f3 --- /dev/null +++ b/assets/js/105.47aefb8e.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[105],{431:function(t,a,r){"use strict";r.r(a);var s=r(4),e=Object(s.a)({},(function(){var t=this,a=t._self._c;return a("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[a("h2",{attrs:{id:"手机设置"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#手机设置"}},[t._v("#")]),t._v(" 手机设置")]),t._v(" "),a("blockquote",[a("p",[t._v("以 iPhone 手机为例子")])]),t._v(" "),a("ol",[a("li",[t._v("修改日期、时间")]),t._v(" "),a("li",[t._v("设置语言、地区: 改成美国、英语")]),t._v(" "),a("li",[t._v("隐私,关闭定位")]),t._v(" "),a("li",[t._v("关闭广告")])]),t._v(" "),a("h2",{attrs:{id:"科学上网"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#科学上网"}},[t._v("#")]),t._v(" 科学上网")]),t._v(" "),a("ul",[a("li",[t._v("登陆 apple store, 需要美国账号")]),t._v(" "),a("li",[t._v("下载 AStrill")])]),t._v(" "),a("h2",{attrs:{id:"ip查询验证"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#ip查询验证"}},[t._v("#")]),t._v(" ip查询验证")]),t._v(" "),a("blockquote",[a("p",[t._v("")])]),t._v(" "),a("h2",{attrs:{id:"验证手机伪装程度"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#验证手机伪装程度"}},[t._v("#")]),t._v(" 验证手机伪装程度")]),t._v(" "),a("blockquote",[a("p",[t._v(": 验证手机伪装程度")])])])}),[],!1,null,null,null);a.default=e.exports}}]); \ No newline at end of file diff --git a/assets/js/106.11920c46.js b/assets/js/106.11920c46.js new file mode 100644 index 0000000000..b983a096de --- /dev/null +++ b/assets/js/106.11920c46.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[106],{432:function(r,e,t){"use strict";t.r(e);var n=t(4),a=Object(n.a)({},(function(){var r=this,e=r._self._c;return e("ContentSlotsDistributor",{attrs:{"slot-key":r.$parent.slotKey}},[e("h2",{attrs:{id:"推荐"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#推荐"}},[r._v("#")]),r._v(" 推荐")]),r._v(" "),e("ul",[e("li",[e("a",{attrs:{href:"https://panjiachen.github.io/awesome-bookmarks/",target:"_blank",rel:"noopener noreferrer"}},[r._v("panjiachen"),e("OutboundLink")],1),r._v(" by 花裤衩")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://www.code-nav.cn/",target:"_blank",rel:"noopener noreferrer"}},[r._v("编程导航"),e("OutboundLink")],1),r._v(" by 程序员鱼皮")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://r2coding.com/",target:"_blank",rel:"noopener noreferrer"}},[r._v("编程自学之路"),e("OutboundLink")],1),r._v(" by 程序羊")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://gitee.com/jishupang/web_atlas",target:"_blank",rel:"noopener noreferrer"}},[r._v("前端知识图谱+B 站资源整合"),e("OutboundLink")],1),r._v(" by 技术胖")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://shengxinjing.cn/",target:"_blank",rel:"noopener noreferrer"}},[r._v("大圣编程自学网"),e("OutboundLink")],1),r._v(" by 大圣")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://devtool.tech/",target:"_blank",rel:"noopener noreferrer"}},[r._v("开发者武器库"),e("OutboundLink")],1)]),r._v(" "),e("li",[e("a",{attrs:{href:"https://www.fly63.com/tool/home.html",target:"_blank",rel:"noopener noreferrer"}},[r._v("工具大全"),e("OutboundLink")],1)]),r._v(" "),e("li",[e("a",{attrs:{href:"https://c.runoob.com/",target:"_blank",rel:"noopener noreferrer"}},[r._v("菜鸟工具"),e("OutboundLink")],1)]),r._v(" "),e("li",[e("a",{attrs:{href:"https://github.com/timqian/chinese-independent-blogs",target:"_blank",rel:"noopener noreferrer"}},[r._v("chinese-independent-blogs*"),e("OutboundLink")],1)]),r._v(" "),e("li",[e("a",{attrs:{href:"https://sideproject.guide/",target:"_blank",rel:"noopener noreferrer"}},[r._v("Side Project 指南*"),e("OutboundLink")],1),r._v(" 用代码建造一些小工具")])]),r._v(" "),e("h2",{attrs:{id:"成长规范"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#成长规范"}},[r._v("#")]),r._v(" 成长规范")]),r._v(" "),e("ul",[e("li",[e("a",{attrs:{href:"https://github.com/ryanhanwu/How-To-Ask-Questions-The-Smart-Way/blob/main/README-zh_CN.md",target:"_blank",rel:"noopener noreferrer"}},[r._v("提问的智慧"),e("OutboundLink")],1)]),r._v(" "),e("li",[e("a",{attrs:{href:"https://github.com/Tencent/secguide/",target:"_blank",rel:"noopener noreferrer"}},[r._v("Tencent-代码安全指南"),e("OutboundLink")],1)]),r._v(" "),e("li",[e("a",{attrs:{href:"https://www.zhihu.com/question/276356727",target:"_blank",rel:"noopener noreferrer"}},[r._v("知乎-如何减少团队的低质量代码?"),e("OutboundLink")],1)]),r._v(" "),e("li",[e("a",{attrs:{href:"https://mp.weixin.qq.com/s/Dl7umd-Z3QuvOwzjmy3Z4w",target:"_blank",rel:"noopener noreferrer"}},[r._v("大淘宝-如何提高代码质量"),e("OutboundLink")],1)])]),r._v(" "),e("h2",{attrs:{id:"chatgpt"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#chatgpt"}},[r._v("#")]),r._v(" chatgpt")]),r._v(" "),e("ul",[e("li",[e("a",{attrs:{href:"https://openai.com/blog/chatgpt",target:"_blank",rel:"noopener noreferrer"}},[r._v("chatgpt-blog"),e("OutboundLink")],1)]),r._v(" "),e("li",[e("a",{attrs:{href:"https://github.com/stars/acheong08/lists/awesome-chatgpt",target:"_blank",rel:"noopener noreferrer"}},[r._v("awesome-chagpt-list"),e("OutboundLink")],1)]),r._v(" "),e("li",[e("a",{attrs:{href:"https://chatgpt.en.obiscr.com/getting-started/",target:"_blank",rel:"noopener noreferrer"}},[r._v("chatgpt-doc"),e("OutboundLink")],1),r._v(" This project is a plugin that supports ChatGPT running on JetBrains series IDE.")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://github.com/microsoft/TaskMatrix",target:"_blank",rel:"noopener noreferrer"}},[r._v("microsoft TaskMatrix"),e("OutboundLink")],1),r._v("微软 enable sending and receiving images during chatting.")]),r._v(" "),e("li",[r._v("提问\n"),e("ul",[e("li",[e("a",{attrs:{href:"https://openprompt.co/",target:"_blank",rel:"noopener noreferrer"}},[r._v("openprompt"),e("OutboundLink")],1),r._v(" 也是个好项目:"),e("a",{attrs:{href:"https://github.com/search?q=openPrompt&type=repositories",target:"_blank",rel:"noopener noreferrer"}},[r._v("prompt on github"),e("OutboundLink")],1)]),r._v(" "),e("li",[e("a",{attrs:{href:"https://github.com/f/awesome-chatgpt-prompts",target:"_blank",rel:"noopener noreferrer"}},[r._v("awesome-chatgpt-prompts"),e("OutboundLink")],1),r._v(" 提问")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://app.gumroad.com/d/84de0ef398cdf6b6352ebe4ddd979314",target:"_blank",rel:"noopener noreferrer"}},[r._v("The Art of ChatGPT Prompting"),e("OutboundLink")],1),r._v(" 提问")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://github.com/PlexPt/awesome-chatgpt-prompts-zh",target:"_blank",rel:"noopener noreferrer"}},[r._v("awesome-chatgpt-prompts-zh"),e("OutboundLink")],1),r._v(" 提问")])])])]),r._v(" "),e("h2",{attrs:{id:"github-主页"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#github-主页"}},[r._v("#")]),r._v(" github 主页")]),r._v(" "),e("ul",[e("li",[e("a",{attrs:{href:"https://github.com/timqian",target:"_blank",rel:"noopener noreferrer"}},[r._v("timqian"),e("OutboundLink")],1)])]),r._v(" "),e("h2",{attrs:{id:"android"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#android"}},[r._v("#")]),r._v(" Android")]),r._v(" "),e("ul",[e("li",[e("a",{attrs:{href:"https://developer.android.com",target:"_blank",rel:"noopener noreferrer"}},[r._v("Android developer"),e("OutboundLink")],1),r._v(" "),e("ul",[e("li",[e("a",{attrs:{href:"https://source.android.com/docs/core?hl=zh-cn",target:"_blank",rel:"noopener noreferrer"}},[r._v("Android 系统核心主题*"),e("OutboundLink")],1)])])]),r._v(" "),e("li",[e("a",{attrs:{href:"https://www.android.com/",target:"_blank",rel:"noopener noreferrer"}},[r._v("android 官网"),e("OutboundLink")],1)]),r._v(" "),e("li",[e("a",{attrs:{href:"http://androidxref.com/",target:"_blank",rel:"noopener noreferrer"}},[r._v("androidxref"),e("OutboundLink")],1)])]),r._v(" "),e("h2",{attrs:{id:"文档"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#文档"}},[r._v("#")]),r._v(" 文档")]),r._v(" "),e("ul",[e("li",[e("a",{attrs:{href:"https://developer.mozilla.org/zh-CN/docs/Web",target:"_blank",rel:"noopener noreferrer"}},[r._v("MDN"),e("OutboundLink")],1),r._v(" | "),e("a",{attrs:{href:"https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects",target:"_blank",rel:"noopener noreferrer"}},[r._v("MDN-JS 标准内置对象"),e("OutboundLink")],1),r._v(" Web 技术权威文档")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://devdocs.io/",target:"_blank",rel:"noopener noreferrer"}},[r._v("DevDocs"),e("OutboundLink")],1),r._v(" Web 开发技术文档,非常不错的学习手册!")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://zh.javascript.info",target:"_blank",rel:"noopener noreferrer"}},[r._v("现代 JavaScript 教程"),e("OutboundLink")],1),r._v(" 以最新标准为基准的 JS 教程")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://wangdoc.com/javascript/",target:"_blank",rel:"noopener noreferrer"}},[r._v("ES5 教程"),e("OutboundLink")],1),r._v(" 阮一峰的 JS 教程")]),r._v(" "),e("li",[e("a",{attrs:{href:"http://es6.ruanyifeng.com/",target:"_blank",rel:"noopener noreferrer"}},[r._v("ES6 教程"),e("OutboundLink")],1),r._v(" 阮一峰的 ES6 教程")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://wangdoc.com/bash/",target:"_blank",rel:"noopener noreferrer"}},[r._v("Bash 脚本教程"),e("OutboundLink")],1),r._v(" 阮一峰编写")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://www.ecma-international.org/",target:"_blank",rel:"noopener noreferrer"}},[r._v("ECMA"),e("OutboundLink")],1),r._v(" ECMA 官网")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://www.runoob.com/",target:"_blank",rel:"noopener noreferrer"}},[r._v("菜鸟教程"),e("OutboundLink")],1),r._v(" 涵盖多种语言的初级教程")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://cloud.tencent.com/developer/devdocs",target:"_blank",rel:"noopener noreferrer"}},[r._v("腾讯云开发者手册"),e("OutboundLink")],1)])]),r._v(" "),e("h2",{attrs:{id:"社区"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#社区"}},[r._v("#")]),r._v(" 社区")]),r._v(" "),e("ul",[e("li",[e("a",{attrs:{href:"https://github.com/",target:"_blank",rel:"noopener noreferrer"}},[r._v("Github"),e("OutboundLink")],1),r._v(" 程序员同性交友社区")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://juejin.im/",target:"_blank",rel:"noopener noreferrer"}},[r._v("掘金"),e("OutboundLink")],1),r._v(" 一个帮助开发者成长的社区")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://www.jianshu.com/",target:"_blank",rel:"noopener noreferrer"}},[r._v("简书"),e("OutboundLink")],1),r._v(" 有很多频道的创作社区")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://segmentfault.com/",target:"_blank",rel:"noopener noreferrer"}},[r._v("思否"),e("OutboundLink")],1),r._v(" 解决技术问题的社区")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://stackoverflow.com/",target:"_blank",rel:"noopener noreferrer"}},[r._v("stack overflow"),e("OutboundLink")],1),r._v(" 同上,外网的")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://www.infoq.cn/topic/Front-end",target:"_blank",rel:"noopener noreferrer"}},[r._v("InfoQ"),e("OutboundLink")],1),r._v(" 促进软件开发及相关领域知识与创新的传播")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://www.v2ex.com/",target:"_blank",rel:"noopener noreferrer"}},[r._v("V2EX"),e("OutboundLink")],1),r._v(" 创意工作者们的社区")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://mo.fish",target:"_blank",rel:"noopener noreferrer"}},[r._v("鱼塘热榜"),e("OutboundLink")],1),r._v(" 划水网站,收集了很多网站,当天热门文章")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://maliquankai.com/designnav/",target:"_blank",rel:"noopener noreferrer"}},[r._v("码力全开资源库"),e("OutboundLink")],1),r._v(" 很全很强大,独立开发者/设计干货/优质利器/工具资源...")])]),r._v(" "),e("h3",{attrs:{id:"社区互动"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#社区互动"}},[r._v("#")]),r._v(" 社区互动")]),r._v(" "),e("ul",[e("li",[e("a",{attrs:{href:"https://gitter.im/home/explore",target:"_blank",rel:"noopener noreferrer"}},[r._v("gitter"),e("OutboundLink")],1)]),r._v(" "),e("li",[e("a",{attrs:{href:"https://txc.qq.com/",target:"_blank",rel:"noopener noreferrer"}},[r._v("兔小巢"),e("OutboundLink")],1)])]),r._v(" "),e("h2",{attrs:{id:"技巧"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#技巧"}},[r._v("#")]),r._v(" 技巧")]),r._v(" "),e("ul",[e("li",[e("a",{attrs:{href:"https://trends.google.com/trends",target:"_blank",rel:"noopener noreferrer"}},[r._v("Google 趋势"),e("OutboundLink")],1),r._v(" 查看某项技术或关键字的热度趋势,可用于分析某项技术的发展前景,或对比某两项技术的热度。")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://index.baidu.com/v2/index.html#/",target:"_blank",rel:"noopener noreferrer"}},[r._v("百度指数"),e("OutboundLink")],1),r._v(" 同上,但百度的数据仅限国内。")])]),r._v(" "),e("h2",{attrs:{id:"博客"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#博客"}},[r._v("#")]),r._v(" 博客")]),r._v(" "),e("ul",[e("li",[e("a",{attrs:{href:"http://www.ruanyifeng.com/blog/",target:"_blank",rel:"noopener noreferrer"}},[r._v("阮一峰的网络日志"),e("OutboundLink")],1)]),r._v(" "),e("li",[e("a",{attrs:{href:"https://www.samanthaming.com/",target:"_blank",rel:"noopener noreferrer"}},[r._v("samanthaming"),e("OutboundLink")],1),r._v(" 对前端小知识点的总结,并为每个知识点制作精美的小卡片。")])]),r._v(" "),e("h2",{attrs:{id:"电子书"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#电子书"}},[r._v("#")]),r._v(" 电子书")]),r._v(" "),e("ul",[e("li",[e("a",{attrs:{href:"https://ebook.hep.com.cn/ebooks/h5/index.html",target:"_blank",rel:"noopener noreferrer"}},[r._v("高教书苑"),e("OutboundLink")],1),r._v(" 高等教育出版社的书籍,包含多种学科。\n")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://sobooks.cc/",target:"_blank",rel:"noopener noreferrer"}},[r._v("SoBooks"),e("OutboundLink")],1),r._v(" 免费的电子书资源网站")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://www.shidianguji.com/",target:"_blank",rel:"noopener noreferrer"}},[r._v("识典古籍"),e("OutboundLink")],1),r._v(" 古籍数字化平台")])]),r._v(" "),e("h2",{attrs:{id:"优秀文章"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#优秀文章"}},[r._v("#")]),r._v(" 优秀文章")]),r._v(" "),e("ul",[e("li",[e("a",{attrs:{href:"https://coolshell.cn/articles/21672.html",target:"_blank",rel:"noopener noreferrer"}},[r._v("我做系统架构的一些原则"),e("OutboundLink")],1),r._v(" 作者对系统架构的方法论总结")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://coolshell.cn/articles/11656.html",target:"_blank",rel:"noopener noreferrer"}},[r._v("开发团队的效率"),e("OutboundLink")],1),r._v(" WatchDog 的架构模式不应该滥用")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://juejin.im/post/5d4d0ec651882549594e7293",target:"_blank",rel:"noopener noreferrer"}},[r._v("灵活运用 CSS 开发技巧"),e("OutboundLink")],1)]),r._v(" "),e("li",[e("a",{attrs:{href:"https://ishadeed.com/article/defensive-css/",target:"_blank",rel:"noopener noreferrer"}},[r._v("防御性 CSS"),e("OutboundLink")],1)]),r._v(" "),e("li",[e("a",{attrs:{href:"https://github.com/shengcaishizhan/kkndme_tianya",target:"_blank",rel:"noopener noreferrer"}},[r._v("天涯 kkndme 神贴"),e("OutboundLink")],1)])]),r._v(" "),e("h2",{attrs:{id:"视频"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#视频"}},[r._v("#")]),r._v(" 视频")]),r._v(" "),e("ul",[e("li",[e("a",{attrs:{href:"https://www.bilibili.com/",target:"_blank",rel:"noopener noreferrer"}},[r._v("bilibili"),e("OutboundLink")],1),r._v(" B 站,上面很多免费教学视频")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://www.imooc.com/",target:"_blank",rel:"noopener noreferrer"}},[r._v("慕课网"),e("OutboundLink")],1),r._v(" 实战视频教程")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://www.miaov.com/",target:"_blank",rel:"noopener noreferrer"}},[r._v("妙味课堂"),e("OutboundLink")],1),r._v(" 比较系统的前端入门视频教程")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://www.icourse163.org/",target:"_blank",rel:"noopener noreferrer"}},[r._v("中国大学 MOOC"),e("OutboundLink")],1),r._v(" 涵盖计算机、外语、心理学等专业免费课程")]),r._v(" "),e("li",[e("a",{attrs:{href:"http://le.ouchn.cn/",target:"_blank",rel:"noopener noreferrer"}},[r._v("终身教育平台"),e("OutboundLink")],1),r._v(" 涵盖生活、兴趣、职场、技能、老年、学历等免费课程")]),r._v(" "),e("li",[e("a",{attrs:{href:"http://egghead.io",target:"_blank",rel:"noopener noreferrer"}},[r._v("egghead"),e("OutboundLink")],1),r._v(" 质量还不错的短视频教程,外网")])]),r._v(" "),e("h2",{attrs:{id:"github"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#github"}},[r._v("#")]),r._v(" Github")]),r._v(" "),e("ul",[e("li",[e("a",{attrs:{href:"https://repobeats.axiom.co/",target:"_blank",rel:"noopener noreferrer"}},[r._v("Repobeats"),e("OutboundLink")],1),r._v(" 生成仓库的动态数据统计图")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://git.io/",target:"_blank",rel:"noopener noreferrer"}},[r._v("github 短域名服务"),e("OutboundLink")],1)]),r._v(" "),e("li",[e("a",{attrs:{href:"https://shields.io/",target:"_blank",rel:"noopener noreferrer"}},[r._v("shields"),e("OutboundLink")],1),r._v(" 徽章图标")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://wangchujiang.com/github-rank/index.html",target:"_blank",rel:"noopener noreferrer"}},[r._v("followers 全球排名"),e("OutboundLink")],1)]),r._v(" "),e("li",[e("a",{attrs:{href:"https://star-history.t9t.io/",target:"_blank",rel:"noopener noreferrer"}},[r._v("star-history"),e("OutboundLink")],1),r._v(" 展示一个项目 Stars 增长曲线")])]),r._v(" "),e("h2",{attrs:{id:"评论系统"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#评论系统"}},[r._v("#")]),r._v(" 评论系统")]),r._v(" "),e("ul",[e("li",[e("a",{attrs:{href:"https://giscus.app/zh-CN",target:"_blank",rel:"noopener noreferrer"}},[r._v("giscus"),e("OutboundLink")],1),r._v(" 由 "),e("a",{attrs:{href:"https://docs.github.com/en/discussions",target:"_blank",rel:"noopener noreferrer"}},[r._v("GitHub Discussions"),e("OutboundLink")],1),r._v(" 驱动的评论系统")])]),r._v(" "),e("h2",{attrs:{id:"前端小工具"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#前端小工具"}},[r._v("#")]),r._v(" 前端小工具")]),r._v(" "),e("ul",[e("li",[e("a",{attrs:{href:"https://caniuse.com/",target:"_blank",rel:"noopener noreferrer"}},[r._v("Can I use"),e("OutboundLink")],1),r._v(" 查看属性和方法的兼容性")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://30secondsofcode.org/",target:"_blank",rel:"noopener noreferrer"}},[r._v("30 seconds of code"),e("OutboundLink")],1),r._v(" 收集了许多有用的代码小片段")])]),r._v(" "),e("h2",{attrs:{id:"代码编辑"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#代码编辑"}},[r._v("#")]),r._v(" 代码编辑")]),r._v(" "),e("ul",[e("li",[e("a",{attrs:{href:"https://codepen.io",target:"_blank",rel:"noopener noreferrer"}},[r._v("codepen"),e("OutboundLink")],1),r._v(" 在线代码编辑与演示")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://codesandbox.io",target:"_blank",rel:"noopener noreferrer"}},[r._v("codesandbox"),e("OutboundLink")],1),r._v(" 内嵌 VSCode 的在线 IDE")])]),r._v(" "),e("h2",{attrs:{id:"emoji-表情"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#emoji-表情"}},[r._v("#")]),r._v(" Emoji 表情")]),r._v(" "),e("ul",[e("li",[e("a",{attrs:{href:"https://emojipedia.org/",target:"_blank",rel:"noopener noreferrer"}},[r._v("emoji 表情"),e("OutboundLink")],1)]),r._v(" "),e("li",[e("a",{attrs:{href:"https://www.webfx.com/tools/emoji-cheat-sheet",target:"_blank",rel:"noopener noreferrer"}},[r._v("emoji 表情备忘录"),e("OutboundLink")],1)]),r._v(" "),e("li",[e("a",{attrs:{href:"https://translate.yandex.com/?lang=zh-emj",target:"_blank",rel:"noopener noreferrer"}},[r._v("根据文本匹配 emoji"),e("OutboundLink")],1)]),r._v(" "),e("li",[e("a",{attrs:{href:"https://github.com/carloscuesta/gitmoji",target:"_blank",rel:"noopener noreferrer"}},[r._v("gitmoji"),e("OutboundLink")],1),r._v(" 通过 emoji 表达 git 的操作内容")])]),r._v(" "),e("blockquote",[e("p",[r._v("在任意输入框快速打开 emoji 表情方法:"),e("br"),r._v("\nWindows 系统下按"),e("kbd",[r._v("Win")]),r._v(" + "),e("kbd",[r._v(".")]),e("br"),r._v("\nMac 系统下按"),e("kbd",[r._v("Control")]),r._v(" + "),e("kbd",[r._v("Command")]),r._v(" + "),e("kbd",[r._v("空格")])])]),r._v(" "),e("h2",{attrs:{id:"图片工具"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#图片工具"}},[r._v("#")]),r._v(" 图片工具")]),r._v(" "),e("ul",[e("li",[e("a",{attrs:{href:"https://tinypng.com",target:"_blank",rel:"noopener noreferrer"}},[r._v("tinypng 图片压缩"),e("OutboundLink")],1),r._v(" 压缩 png 很有用")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://devtool.tech/tiny-image",target:"_blank",rel:"noopener noreferrer"}},[r._v("微图"),e("OutboundLink")],1),r._v(" 浏览器端图片压缩,不会上传图片到服务器")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://squoosh.app/",target:"_blank",rel:"noopener noreferrer"}},[r._v("Squoosh"),e("OutboundLink")],1),r._v(" 谷歌出品在线免费图片压缩工具(jpg、png 等,压缩效果比 tinypng 稍好)")]),r._v(" "),e("li",[e("a",{attrs:{href:"http://waifu2x.udp.jp/",target:"_blank",rel:"noopener noreferrer"}},[r._v("waifu2x"),e("OutboundLink")],1),r._v(" 通过卷积网络放大图片")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://vectormagic.com/",target:"_blank",rel:"noopener noreferrer"}},[r._v("vectormagic"),e("OutboundLink")],1),r._v(" 转换矢量图")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://www.vectorizer.io/",target:"_blank",rel:"noopener noreferrer"}},[r._v("vectorizer"),e("OutboundLink")],1),r._v(" 真正的 png 转 svg 神器")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://photo.opencool.cn/",target:"_blank",rel:"noopener noreferrer"}},[r._v("在线 AI 图片处理"),e("OutboundLink")],1),r._v(" 黑白修复、无损放大、动漫化、铅笔画等。")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://www.remove.bg/zh",target:"_blank",rel:"noopener noreferrer"}},[r._v("remove"),e("OutboundLink")],1),r._v(" AI 抠图(抠背景)")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://www.magiceraser.io/",target:"_blank",rel:"noopener noreferrer"}},[r._v("magic eraser"),e("OutboundLink")],1),r._v(" AI 抠图(抠前景)")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://github.com/nadermx/backgroundremover",target:"_blank",rel:"noopener noreferrer"}},[r._v("backgroundremover"),e("OutboundLink")],1),r._v(" 又一个抠图的")])]),r._v(" "),e("h2",{attrs:{id:"svg"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#svg"}},[r._v("#")]),r._v(" SVG")]),r._v(" "),e("ul",[e("li",[e("a",{attrs:{href:"https://e2.cool/",target:"_blank",rel:"noopener noreferrer"}},[r._v("svg 编辑器-E2.Cool"),e("OutboundLink")],1)]),r._v(" "),e("li",[e("a",{attrs:{href:"https://x.ipaiban.com/login",target:"_blank",rel:"noopener noreferrer"}},[r._v("svg 编辑器-i 排版"),e("OutboundLink")],1)])]),r._v(" "),e("h2",{attrs:{id:"音视频工具"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#音视频工具"}},[r._v("#")]),r._v(" 音视频工具")]),r._v(" "),e("ul",[e("li",[e("a",{attrs:{href:"https://app.xunjieshipin.com/video-converter/",target:"_blank",rel:"noopener noreferrer"}},[r._v("迅捷视频转换器"),e("OutboundLink")],1),r._v(" 在线转换各种视频格式")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://app.xunjieshipin.com/video-converter/",target:"_blank",rel:"noopener noreferrer"}},[r._v("迅捷音频转换器"),e("OutboundLink")],1),r._v(" 在线转换各种音频格式")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://mp3cut.net/cn/",target:"_blank",rel:"noopener noreferrer"}},[r._v("修剪音频"),e("OutboundLink")],1),r._v(" 在线修剪或剪切任何音频文件")])]),r._v(" "),e("h2",{attrs:{id:"思维导图"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#思维导图"}},[r._v("#")]),r._v(" 思维导图")]),r._v(" "),e("ul",[e("li",[e("a",{attrs:{href:"https://www.processon.com/",target:"_blank",rel:"noopener noreferrer"}},[r._v("processon 在线作图"),e("OutboundLink")],1),r._v(" 流程图、思维导图、原型图等")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://naotu.baidu.com",target:"_blank",rel:"noopener noreferrer"}},[r._v("百度脑图"),e("OutboundLink")],1),r._v(" 思维导图")]),r._v(" "),e("li",[e("a",{attrs:{href:"plectica.com"}},[r._v("plectica")]),r._v(" 绘制知识图谱")])]),r._v(" "),e("h2",{attrs:{id:"css"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#css"}},[r._v("#")]),r._v(" CSS")]),r._v(" "),e("ul",[e("li",[e("p",[e("a",{attrs:{href:"https://juejin.cn/post/7030572979868139551?utm_source=gold_browser_extension",target:"_blank",rel:"noopener noreferrer"}},[r._v("各种 CSS 生成器和 JS 代码片段"),e("OutboundLink")],1)])]),r._v(" "),e("li",[e("p",[e("a",{attrs:{href:"http://css-tricks.neatbang.com/",target:"_blank",rel:"noopener noreferrer"}},[r._v("CSS Tricks"),e("OutboundLink")],1),r._v(" CSS 技巧收集与演示")])]),r._v(" "),e("li",[e("p",[e("a",{attrs:{href:"https://neumorphism.io/",target:"_blank",rel:"noopener noreferrer"}},[r._v("CSS 生成器"),e("OutboundLink")],1)])]),r._v(" "),e("li",[e("p",[e("a",{attrs:{href:"https://www.colorzilla.com/gradient-editor/",target:"_blank",rel:"noopener noreferrer"}},[r._v("CSS 渐变生成器"),e("OutboundLink")],1)])]),r._v(" "),e("li",[e("p",[e("a",{attrs:{href:"https://www.html.cn/tool/css3Preview/Box-Shadow.html",target:"_blank",rel:"noopener noreferrer"}},[r._v("CSS3-Box Shadow(阴影)"),e("OutboundLink")],1)])]),r._v(" "),e("li",[e("p",[e("a",{attrs:{href:"https://cubic-bezier.com",target:"_blank",rel:"noopener noreferrer"}},[r._v("贝塞尔曲线生成器"),e("OutboundLink")],1)])]),r._v(" "),e("li",[e("p",[e("a",{attrs:{href:"http://www.heropatterns.com/",target:"_blank",rel:"noopener noreferrer"}},[r._v("花纹背景生成器"),e("OutboundLink")],1)])]),r._v(" "),e("li",[e("p",[e("a",{attrs:{href:"https://github.com/bansal-io/pattern.css",target:"_blank",rel:"noopener noreferrer"}},[r._v("花纹背景-pattern.css"),e("OutboundLink")],1)])]),r._v(" "),e("li",[e("p",[e("a",{attrs:{href:"https://bennettfeely.com/ztext/",target:"_blank",rel:"noopener noreferrer"}},[r._v("3D 字体"),e("OutboundLink")],1)])]),r._v(" "),e("li",[e("p",[e("a",{attrs:{href:"https://css-tricks.com/",target:"_blank",rel:"noopener noreferrer"}},[r._v("css-tricks"),e("OutboundLink")],1),r._v(" css 技巧文章")])]),r._v(" "),e("li",[e("p",[e("a",{attrs:{href:"https://lhammer.cn/You-need-to-know-css/#/zh-cn/",target:"_blank",rel:"noopener noreferrer"}},[r._v("You-need-to-know-css"),e("OutboundLink")],1),r._v(" CSS 的各种 DEMO,很全")])]),r._v(" "),e("li",[e("p",[e("a",{attrs:{href:"https://animista.net/",target:"_blank",rel:"noopener noreferrer"}},[r._v("animista"),e("OutboundLink")],1),r._v(" CSS 动画可视化工具,复制代码就能用")])]),r._v(" "),e("li",[e("p",[e("a",{attrs:{href:"http://navnav.co/",target:"_blank",rel:"noopener noreferrer"}},[r._v("navnav"),e("OutboundLink")],1),r._v(" 各种炫酷的 CSS 动画组件")])])]),r._v(" "),e("h2",{attrs:{id:"cdn-加速"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#cdn-加速"}},[r._v("#")]),r._v(" CDN 加速")]),r._v(" "),e("ul",[e("li",[e("a",{attrs:{href:"http://www.jsdelivr.com/",target:"_blank",rel:"noopener noreferrer"}},[r._v("jsDelivr"),e("OutboundLink")],1),r._v(" 国外的一家优秀的公共 CDN 服务提供商")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://unpkg.com/",target:"_blank",rel:"noopener noreferrer"}},[r._v("unpkg"),e("OutboundLink")],1),r._v(" cdn 服务")])]),r._v(" "),e("h2",{attrs:{id:"网站托管"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#网站托管"}},[r._v("#")]),r._v(" 网站托管")]),r._v(" "),e("ul",[e("li",[e("a",{attrs:{href:"https://vercel.com/",target:"_blank",rel:"noopener noreferrer"}},[r._v("vercel"),e("OutboundLink")],1),r._v(" 好用的网站托管服务")])]),r._v(" "),e("h2",{attrs:{id:"正则"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#正则"}},[r._v("#")]),r._v(" 正则")]),r._v(" "),e("ul",[e("li",[e("a",{attrs:{href:"https://regex101.com/",target:"_blank",rel:"noopener noreferrer"}},[r._v("正则可视化"),e("OutboundLink")],1)]),r._v(" "),e("li",[e("a",{attrs:{href:"https://ihateregex.io/",target:"_blank",rel:"noopener noreferrer"}},[r._v("iHateRegex"),e("OutboundLink")],1),r._v(" 正则搜索,细节做得很好")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://github.com/qdlaoyao/js-regex-mini-book",target:"_blank",rel:"noopener noreferrer"}},[r._v("正则迷你书"),e("OutboundLink")],1),r._v(" 学习正则的小手册")])]),r._v(" "),e("h2",{attrs:{id:"其他"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#其他"}},[r._v("#")]),r._v(" 其他")]),r._v(" "),e("ul",[e("li",[e("a",{attrs:{href:"https://ipcmen.com/",target:"_blank",rel:"noopener noreferrer"}},[r._v("Linux 命令手册"),e("OutboundLink")],1)]),r._v(" "),e("li",[e("a",{attrs:{href:"https://carbon.now.sh/",target:"_blank",rel:"noopener noreferrer"}},[r._v("carbon 代码图片生成器"),e("OutboundLink")],1),r._v(" 生成好看的代码图片")])]),r._v(" "),e("h2",{attrs:{id:"设计"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#设计"}},[r._v("#")]),r._v(" 设计")]),r._v(" "),e("ul",[e("li",[e("a",{attrs:{href:"http://chuangzaoshi.com/",target:"_blank",rel:"noopener noreferrer"}},[r._v("创造师导航"),e("OutboundLink")],1)]),r._v(" "),e("li",[e("a",{attrs:{href:"http://hao.uisdc.com/",target:"_blank",rel:"noopener noreferrer"}},[r._v("设计师网址导航"),e("OutboundLink")],1)]),r._v(" "),e("li",[e("a",{attrs:{href:"https://www.remove.bg/zh",target:"_blank",rel:"noopener noreferrer"}},[r._v("remove"),e("OutboundLink")],1),r._v(" AI 抠图,抠图算法很厉害")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://www.manypixels.co/gallery/",target:"_blank",rel:"noopener noreferrer"}},[r._v("Manypixels"),e("OutboundLink")],1),r._v(" 插画")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://undraw.co/illustrations",target:"_blank",rel:"noopener noreferrer"}},[r._v("Undraw"),e("OutboundLink")],1),r._v(" 插画")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://storytale.io/",target:"_blank",rel:"noopener noreferrer"}},[r._v("storytale"),e("OutboundLink")],1),r._v(" 插画,种类丰富,包含 3D 插画")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://uimovement.com/",target:"_blank",rel:"noopener noreferrer"}},[r._v("uimovement"),e("OutboundLink")],1),r._v(" 能从这个网站找到不少动画交互的灵感")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://www.awwwards.com/",target:"_blank",rel:"noopener noreferrer"}},[r._v("awwwards"),e("OutboundLink")],1),r._v("是一个一个专门为设计精美的网站以及富有创意的网站颁奖的网站")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://dribbble.com/",target:"_blank",rel:"noopener noreferrer"}},[r._v("dribbble"),e("OutboundLink")],1),r._v(" 经常能在上面找到很多有创意好看的 gif 或者图片")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://www.behance.net/",target:"_blank",rel:"noopener noreferrer"}},[r._v("Bēhance"),e("OutboundLink")],1),r._v(" dribbble 是设计师的微博,Bēhance 是设计师的博客")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://logojoy.com/",target:"_blank",rel:"noopener noreferrer"}},[r._v("Logojoy"),e("OutboundLink")],1),r._v(" 使用 ai 做 logo 的网站,做出来的 logo 质量还不错。")]),r._v(" "),e("li",[e("a",{attrs:{href:"http://brandmark.io/",target:"_blank",rel:"noopener noreferrer"}},[r._v("brandmark"),e("OutboundLink")],1),r._v(" 另一个在线制作 logo 网站")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://instantlogodesign.com/",target:"_blank",rel:"noopener noreferrer"}},[r._v("instant"),e("OutboundLink")],1),r._v(" 又一个 logo 制作网站")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://www.namecheap.com/logo-maker/app/",target:"_blank",rel:"noopener noreferrer"}},[r._v("namecheap"),e("OutboundLink")],1),r._v("又一个 logo 制作网站")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://www.designevo.com/logo-maker/",target:"_blank",rel:"noopener noreferrer"}},[r._v("logo-maker"),e("OutboundLink")],1),r._v(" 又一个 logo 制作网站 这个更简单点 就是选模板之后微调")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://coolors.co/",target:"_blank",rel:"noopener noreferrer"}},[r._v("coolors"),e("OutboundLink")],1),r._v(" 帮你在线配色的网站 你能找到不少配色灵感")]),r._v(" "),e("li",[e("a",{attrs:{href:"http://colorhunt.co/",target:"_blank",rel:"noopener noreferrer"}},[r._v("colorhunt"),e("OutboundLink")],1),r._v(" 另一个配色网站")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://uigradients.com/#SummerDog",target:"_blank",rel:"noopener noreferrer"}},[r._v("uigradients"),e("OutboundLink")],1),r._v(" 渐变色网站")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://www.designcap.com/",target:"_blank",rel:"noopener noreferrer"}},[r._v("designcap"),e("OutboundLink")],1),r._v(" 在线海报设计")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://flatuicolors.com/",target:"_blank",rel:"noopener noreferrer"}},[r._v("Flat UI 色表"),e("OutboundLink")],1),r._v(" Flat UI 色表")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://www.0to255.com/",target:"_blank",rel:"noopener noreferrer"}},[r._v("0to255"),e("OutboundLink")],1),r._v(" 颜色梯度")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://github.com/mikolajdobrucki/ikonate",target:"_blank",rel:"noopener noreferrer"}},[r._v("Ikonate"),e("OutboundLink")],1),r._v(" 提供免费的图标 icons")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://remixicon.com/",target:"_blank",rel:"noopener noreferrer"}},[r._v("remixicon"),e("OutboundLink")],1),r._v(" 又一个提供免费图标 icons")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://github.com/feathericons/feather",target:"_blank",rel:"noopener noreferrer"}},[r._v("feather"),e("OutboundLink")],1),r._v(" 免费的 icons")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://github.com/arcticicestudio/nord",target:"_blank",rel:"noopener noreferrer"}},[r._v("nord"),e("OutboundLink")],1),r._v(" 北欧性冷淡风主题配色")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://unsplash.com/",target:"_blank",rel:"noopener noreferrer"}},[r._v("Unsplash"),e("OutboundLink")],1),r._v(" 提供免费的高清图片")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://www.pexels.com/zh-cn/",target:"_blank",rel:"noopener noreferrer"}},[r._v("Pexels"),e("OutboundLink")],1),r._v(" 提供免费的高清图片")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://colorkitty.com/",target:"_blank",rel:"noopener noreferrer"}},[r._v("colorkitty"),e("OutboundLink")],1),r._v(" 从你的图片中提取配色")]),r._v(" "),e("li",[e("a",{attrs:{href:"http://design.youzan.com/",target:"_blank",rel:"noopener noreferrer"}},[r._v("design.youzan"),e("OutboundLink")],1),r._v(" 有赞设计原则")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://www.iconfont.cn/",target:"_blank",rel:"noopener noreferrer"}},[r._v("iconfont"),e("OutboundLink")],1),r._v(" 阿里巴巴矢量图标库")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://undraw.co/illustrations",target:"_blank",rel:"noopener noreferrer"}},[r._v("undraw"),e("OutboundLink")],1),r._v(" 免费的矢量插画")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://icomoon.io/",target:"_blank",rel:"noopener noreferrer"}},[r._v("icomoon"),e("OutboundLink")],1),r._v(" 矢量图标库")]),r._v(" "),e("li",[e("a",{attrs:{href:"http://cssicon.space/#/",target:"_blank",rel:"noopener noreferrer"}},[r._v("cssicon"),e("OutboundLink")],1),r._v(" 所有的 icon 都是纯 css 画的 缺点:icon 不够多")]),r._v(" "),e("li",[e("a",{attrs:{href:"http://apps.eky.hk/css-triangle-generator/",target:"_blank",rel:"noopener noreferrer"}},[r._v("CSS triangle generator"),e("OutboundLink")],1),r._v(" 帮你快速用 css 做出三角形")]),r._v(" "),e("li",[e("a",{attrs:{href:"http://bennettfeely.com/clippy/",target:"_blank",rel:"noopener noreferrer"}},[r._v("clippy"),e("OutboundLink")],1),r._v(" 在线帮你使用 css clip-path 做出各种形状的图形")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://picsum.photos/",target:"_blank",rel:"noopener noreferrer"}},[r._v("Lorem Picsum"),e("OutboundLink")],1),r._v(" 提供免费的占位图")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://www.canva.cn/",target:"_blank",rel:"noopener noreferrer"}},[r._v("Canva 可画"),e("OutboundLink")],1),r._v(" 生成插画、封面、海报、头像等")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://error404.fun/",target:"_blank",rel:"noopener noreferrer"}},[r._v("404 页"),e("OutboundLink")],1),r._v(" 404 页素材")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://collectui.com/",target:"_blank",rel:"noopener noreferrer"}},[r._v("collectui"),e("OutboundLink")],1),r._v(" 按功能组件分类的设计图")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://smartmockups.com/zh",target:"_blank",rel:"noopener noreferrer"}},[r._v("smartmockups"),e("OutboundLink")],1),r._v(" 产品模板生成工具")])]),r._v(" "),e("h2",{attrs:{id:"图库"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#图库"}},[r._v("#")]),r._v(" 图库")]),r._v(" "),e("ul",[e("li",[e("a",{attrs:{href:"https://uigradients.com/",target:"_blank",rel:"noopener noreferrer"}},[r._v("uigradients"),e("OutboundLink")],1),r._v(" 渐变色生成工具")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://www.freepik.com/",target:"_blank",rel:"noopener noreferrer"}},[r._v("freepik"),e("OutboundLink")],1),r._v(" banner 图库")]),r._v(" "),e("li",[e("a",{attrs:{href:"http://www.51yuansu.com/",target:"_blank",rel:"noopener noreferrer"}},[r._v("觅元素"),e("OutboundLink")],1),r._v("一天免费下载十张 psd(免抠元素)")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://www.gaoding.com/",target:"_blank",rel:"noopener noreferrer"}},[r._v("搞定设计"),e("OutboundLink")],1),r._v(" 可以抠图")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://www.vectorizer.io/",target:"_blank",rel:"noopener noreferrer"}},[r._v("vectorizer"),e("OutboundLink")],1),r._v(" 真正的 png 转 svg 神器")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://www.zcool.com.cn/",target:"_blank",rel:"noopener noreferrer"}},[r._v("站酷"),e("OutboundLink")],1),r._v(" 国内优秀的设计作品展示")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://huaban.com/",target:"_blank",rel:"noopener noreferrer"}},[r._v("花瓣"),e("OutboundLink")],1)]),r._v(" "),e("li",[e("a",{attrs:{href:"https://huke88.com/",target:"_blank",rel:"noopener noreferrer"}},[r._v("虎克"),e("OutboundLink")],1),r._v(" ps 学习教程")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://themes.muffingroup.com/be/splash/",target:"_blank",rel:"noopener noreferrer"}},[r._v("beTheme"),e("OutboundLink")],1)]),r._v(" "),e("li",[e("a",{attrs:{href:"https://www.ui.cn/",target:"_blank",rel:"noopener noreferrer"}},[r._v("UI 中国"),e("OutboundLink")],1)]),r._v(" "),e("li",[e("a",{attrs:{href:"https://alpha.wallhaven.cc/",target:"_blank",rel:"noopener noreferrer"}},[r._v("wallhaven"),e("OutboundLink")],1),r._v(" 壁纸网站-")])]),r._v(" "),e("h2",{attrs:{id:"_3d"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_3d"}},[r._v("#")]),r._v(" 3D")]),r._v(" "),e("ul",[e("li",[e("a",{attrs:{href:"https://sketchfab.com/",target:"_blank",rel:"noopener noreferrer"}},[r._v("sketchfab"),e("OutboundLink")],1),r._v(" 3D 模型")])]),r._v(" "),e("h2",{attrs:{id:"交互"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#交互"}},[r._v("#")]),r._v(" 交互")]),r._v(" "),e("ul",[e("li",[e("p",[e("a",{attrs:{href:"http://aliscued.lofter.com/",target:"_blank",rel:"noopener noreferrer"}},[r._v("微交互"),e("OutboundLink")],1),r._v(" 里面收集了市面上很多很好的微交互例子 值得学习")])]),r._v(" "),e("li",[e("p",[e("a",{attrs:{href:"http://littlebigdetails.com/",target:"_blank",rel:"noopener noreferrer"}},[r._v("Little Big Details"),e("OutboundLink")],1),r._v(" 同上,一个国外微交互汇集网站")])]),r._v(" "),e("li",[e("p",[e("a",{attrs:{href:"https://cruip.com/",target:"_blank",rel:"noopener noreferrer"}},[r._v("cruip"),e("OutboundLink")],1),r._v(" 登录页的各种页面设计,可以免费下载模板")])]),r._v(" "),e("li",[e("p",[e("a",{attrs:{href:"https://comixify.ii.pw.edu.pl/",target:"_blank",rel:"noopener noreferrer"}},[r._v("Comixify"),e("OutboundLink")],1),r._v(" 一个波兰团队做了非常好玩的工具,可以把视频自动转成漫画,上图是他们提供的 demo,效果很棒。")])]),r._v(" "),e("li",[e("p",[e("a",{attrs:{href:"https://github.com/bui/taiko-web",target:"_blank",rel:"noopener noreferrer"}},[r._v("taiko-web"),e("OutboundLink")],1),r._v(" 太鼓达人网页版 只能说很 6")])])]),r._v(" "),e("h2",{attrs:{id:"有趣"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#有趣"}},[r._v("#")]),r._v(" 有趣")]),r._v(" "),e("ul",[e("li",[e("a",{attrs:{href:"https://pranx.com/",target:"_blank",rel:"noopener noreferrer"}},[r._v("电脑恶搞"),e("OutboundLink")],1),r._v(" 收集了一些恶搞小网页,比如 xp 系统蓝屏、黑客界面等")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://neocities.org/browse",target:"_blank",rel:"noopener noreferrer"}},[r._v("neocities"),e("OutboundLink")],1),r._v(" 上面托管了很多有趣的网站")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://fuun.fun/",target:"_blank",rel:"noopener noreferrer"}},[r._v("奇趣网站收藏家"),e("OutboundLink")],1),r._v(" 收藏了很多有趣的网站")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://game.xugaoyi.com/",target:"_blank",rel:"noopener noreferrer"}},[r._v("FC 在线模拟器(小霸王游戏机)"),e("OutboundLink")],1),r._v(" 童年回忆")]),r._v(" "),e("li",[e("a",{attrs:{href:"http://www.baidu-x.com/",target:"_blank",rel:"noopener noreferrer"}},[r._v("帮你百度一下"),e("OutboundLink")],1),r._v(" 可以 "),e("a",{attrs:{href:"http://www.baidu-x.com/?q=%E5%92%8C%E8%B0%90%E6%9C%89%E7%88%B1%E5%AF%8C%E5%BC%BA",target:"_blank",rel:"noopener noreferrer"}},[r._v("点我测试一下"),e("OutboundLink")],1),r._v("-")]),r._v(" "),e("li",[e("a",{attrs:{href:"http://lmgtfy.com/",target:"_blank",rel:"noopener noreferrer"}},[r._v("国际版"),e("OutboundLink")],1),r._v(" 同"),e("code",[r._v("帮我百度一下")]),r._v("-"),e("a",{attrs:{href:"http://lmgtfy.com/?q=a",target:"_blank",rel:"noopener noreferrer"}},[r._v("点我测试一下"),e("OutboundLink")],1),r._v("-")]),r._v(" "),e("li",[e("a",{attrs:{href:"http://matthewrayfield.com/articles/animating-urls-with-javascript-and-emojis/#%F0%9F%8C%96",target:"_blank",rel:"noopener noreferrer"}},[r._v("URL 地址播放 Emojis 动画"),e("OutboundLink")],1),r._v(" 在地址栏里面播放 emoji")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://cantunsee.space/",target:"_blank",rel:"noopener noreferrer"}},[r._v("Can't Unsee"),e("OutboundLink")],1),r._v(" 强烈建议前端、客户端、UI 开发的同学玩下,检查一下自己对设计稿的敏感度怎么样")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://talk.swift.gg/",target:"_blank",rel:"noopener noreferrer"}},[r._v("ggtalk"),e("OutboundLink")],1),r._v(" 平时一直在听的一个技术博客")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://github.com/Blankj/awesome-comment",target:"_blank",rel:"noopener noreferrer"}},[r._v("awesome-comment"),e("OutboundLink")],1),r._v(" 里面收集了很多有趣的代码注释")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://www.text-image.com/index.html",target:"_blank",rel:"noopener noreferrer"}},[r._v("text-img"),e("OutboundLink")],1),r._v(" 都将图片转化为 ascii 用来写注释")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://pessimistress.github.io/ascii/",target:"_blank",rel:"noopener noreferrer"}},[r._v("ascii video"),e("OutboundLink")],1),r._v(" 使用 ascii 编码生成视频动画")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://github.com/beizhedenglong/weird-fonts",target:"_blank",rel:"noopener noreferrer"}},[r._v("weird-fonts"),e("OutboundLink")],1),r._v(" 将普通字母转化为 特殊 unicode")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://github.com/epidemian/snake",target:"_blank",rel:"noopener noreferrer"}},[r._v("snake"),e("OutboundLink")],1),r._v(" 在地址栏里面玩贪吃蛇")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://github.com/yuanfux/zero-width-lib",target:"_blank",rel:"noopener noreferrer"}},[r._v("zero-width-lib"),e("OutboundLink")],1),r._v(" 利用零宽度字符实现 隐形水印、加密信息分享、逃脱词匹配,很有创意")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://www.abbreviations.com/",target:"_blank",rel:"noopener noreferrer"}},[r._v("abbreviations"),e("OutboundLink")],1),r._v(" 查看一个简写是什么意思的网站")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://magi.com/",target:"_blank",rel:"noopener noreferrer"}},[r._v("magi"),e("OutboundLink")],1),r._v(" ai 搜索神器,超屌")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://www.qmsjmfb.com/",target:"_blank",rel:"noopener noreferrer"}},[r._v("在线取名"),e("OutboundLink")],1),r._v(" 解决取名难问题,超多名字生成")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://collet66.web.fc2.com/nijisanji/index.html",target:"_blank",rel:"noopener noreferrer"}},[r._v("像素画 GIF"),e("OutboundLink")],1)]),r._v(" "),e("li",[e("a",{attrs:{href:"https://uchinoko-maker.jp/",target:"_blank",rel:"noopener noreferrer"}},[r._v("猫咪生成器"),e("OutboundLink")],1)])]),r._v(" "),e("h2",{attrs:{id:"生成器"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#生成器"}},[r._v("#")]),r._v(" 生成器")]),r._v(" "),e("ul",[e("li",[e("p",[e("a",{attrs:{href:"https://toonme.com/",target:"_blank",rel:"noopener noreferrer"}},[r._v("卡通头像生成器"),e("OutboundLink")],1),r._v(" 上传真人头像生成卡通头像")])]),r._v(" "),e("li",[e("p",[e("a",{attrs:{href:"https://www.artbreeder.com/",target:"_blank",rel:"noopener noreferrer"}},[r._v("artbreeder"),e("OutboundLink")],1),r._v(" 动漫图生成真人图像")])]),r._v(" "),e("li",[e("p",[e("a",{attrs:{href:"https://neal.fun/ambient-chaos/",target:"_blank",rel:"noopener noreferrer"}},[r._v("声音生成器"),e("OutboundLink")],1),r._v(" 生成下雨、咖啡厅、海浪、火车等声音,可几种声音合成")])]),r._v(" "),e("li",[e("p",[e("a",{attrs:{href:"https://zzkia.noddl.me:8020/",target:"_blank",rel:"noopener noreferrer"}},[r._v("诺基亚短信图片生成器"),e("OutboundLink")],1)])]),r._v(" "),e("li",[e("p",[e("a",{attrs:{href:"https://zfb.xugaoyi.com/",target:"_blank",rel:"noopener noreferrer"}},[r._v("到账语音生成器"),e("OutboundLink")],1),r._v(" 支付宝到账 1 亿元")])])]),r._v(" "),e("h2",{attrs:{id:"元宇宙"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#元宇宙"}},[r._v("#")]),r._v(" 元宇宙")]),r._v(" "),e("p",[r._v("符合元宇宙特征的几个网站,允许用户拥有虚拟土地,在上面构建自己的世界:")]),r._v(" "),e("ul",[e("li",[e("a",{attrs:{href:"https://www.sandbox.game/cn/",target:"_blank",rel:"noopener noreferrer"}},[r._v("沙盒"),e("OutboundLink")],1)]),r._v(" "),e("li",[e("a",{attrs:{href:"https://somniumspace.com/",target:"_blank",rel:"noopener noreferrer"}},[r._v("梦境空间"),e("OutboundLink")],1)]),r._v(" "),e("li",[e("a",{attrs:{href:"https://market.decentraland.org/",target:"_blank",rel:"noopener noreferrer"}},[r._v("Decentraland"),e("OutboundLink")],1)])]),r._v(" "),e("h2",{attrs:{id:"教程"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#教程"}},[r._v("#")]),r._v(" 教程")]),r._v(" "),e("ul",[e("li",[e("a",{attrs:{href:"https://egghead.io/courses/execute-npm-package-binaries-with-the-npx-package-runner",target:"_blank",rel:"noopener noreferrer"}},[r._v("npx"),e("OutboundLink")],1),r._v(" 教你怎么合理的使用 npx")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://www.hacksplaining.com/lessons",target:"_blank",rel:"noopener noreferrer"}},[r._v("hacksplaining"),e("OutboundLink")],1),r._v(" 网络安全学习网站")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://github.com/mcuking/mobile-web-best-practice",target:"_blank",rel:"noopener noreferrer"}},[r._v("mobile-web-best-practice"),e("OutboundLink")],1),r._v(" 移动 web 最佳实践")])]),r._v(" "),e("h2",{attrs:{id:"产品"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#产品"}},[r._v("#")]),r._v(" 产品")]),r._v(" "),e("ul",[e("li",[e("p",[e("a",{attrs:{href:"https://www.producthunt.com/",target:"_blank",rel:"noopener noreferrer"}},[r._v("Product Hunt"),e("OutboundLink")],1),r._v(" 好产品推荐")])]),r._v(" "),e("li",[e("p",[e("a",{attrs:{href:"http://www.pmdaniu.com/",target:"_blank",rel:"noopener noreferrer"}},[r._v("产品大牛"),e("OutboundLink")],1),r._v(" 什么有很多完整的产品原型可以借鉴")])]),r._v(" "),e("li",[e("p",[e("a",{attrs:{href:"https://modao.cc/pricing",target:"_blank",rel:"noopener noreferrer"}},[r._v("磨刀"),e("OutboundLink")],1),r._v(" 快速出 ui 原型")])])]),r._v(" "),e("h2",{attrs:{id:"实用"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#实用"}},[r._v("#")]),r._v(" 实用")]),r._v(" "),e("ul",[e("li",[e("a",{attrs:{href:"https://webden.dev/",target:"_blank",rel:"noopener noreferrer"}},[r._v("webden"),e("OutboundLink")],1),r._v(" 在线网页编辑器,轻便快捷")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://browser-update.org/",target:"_blank",rel:"noopener noreferrer"}},[r._v("browser-update"),e("OutboundLink")],1),r._v(" 浏览器版本更新提示插件")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://admin.typeform.com/signup",target:"_blank",rel:"noopener noreferrer"}},[r._v("typeform"),e("OutboundLink")],1),r._v(" 一个国外的在线调查问卷网站")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://www.videofk.com/",target:"_blank",rel:"noopener noreferrer"}},[r._v("VideoFk"),e("OutboundLink")],1),r._v(" VideoFk 视频在线解析下载")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://www.allhistory.com/",target:"_blank",rel:"noopener noreferrer"}},[r._v("全历史"),e("OutboundLink")],1),r._v(" 历史内容聚合网站")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://www.uzer.me/",target:"_blank",rel:"noopener noreferrer"}},[r._v("UzerMe"),e("OutboundLink")],1),r._v(" 云端办公工具")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://sobooks.cc/",target:"_blank",rel:"noopener noreferrer"}},[r._v("SoBooks"),e("OutboundLink")],1),r._v(" 强大的电子书资源网站")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://www.gaoding.com/",target:"_blank",rel:"noopener noreferrer"}},[r._v("稿定设计"),e("OutboundLink")],1),r._v(" 键式设计工具+智能抠图")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://dalipan.com/",target:"_blank",rel:"noopener noreferrer"}},[r._v("大力盘"),e("OutboundLink")],1),r._v(" 百度网盘搜索")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://www.macbl.com/app/internet/enfi",target:"_blank",rel:"noopener noreferrer"}},[r._v("ENFI 下载器"),e("OutboundLink")],1),r._v(" 不限速下载器")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://www.laihua.com/",target:"_blank",rel:"noopener noreferrer"}},[r._v("来画视频"),e("OutboundLink")],1),r._v(" 像做 PPT 一样做短视频")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://www.arkie.cn/",target:"_blank",rel:"noopener noreferrer"}},[r._v("Arkie 海报制作工具"),e("OutboundLink")],1)]),r._v(" "),e("li",[e("a",{attrs:{href:"http://www.ypppt.com/",target:"_blank",rel:"noopener noreferrer"}},[r._v("优品 PPT"),e("OutboundLink")],1)]),r._v(" "),e("li",[e("a",{attrs:{href:"http://www.tretars.com/",target:"_blank",rel:"noopener noreferrer"}},[r._v("比格 PPT"),e("OutboundLink")],1)]),r._v(" "),e("li",[e("a",{attrs:{href:"https://www.pexels.com/",target:"_blank",rel:"noopener noreferrer"}},[r._v("高清免费图片"),e("OutboundLink")],1)]),r._v(" "),e("li",[e("a",{attrs:{href:"https://unsplash.com/",target:"_blank",rel:"noopener noreferrer"}},[r._v("高清免费图片 2"),e("OutboundLink")],1)]),r._v(" "),e("li",[e("a",{attrs:{href:"https://www.shapedivider.app/",target:"_blank",rel:"noopener noreferrer"}},[r._v("shapedivider"),e("OutboundLink")],1),r._v(" 生成波浪分隔线")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://www.notion.so/",target:"_blank",rel:"noopener noreferrer"}},[r._v("Notion"),e("OutboundLink")],1),r._v(" 知识库、快速笔记、TaskList、日记、读书清单,各种类型,应有尽有")])]),r._v(" "),e("h2",{attrs:{id:"talk"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#talk"}},[r._v("#")]),r._v(" Talk")]),r._v(" "),e("ul",[e("li",[e("a",{attrs:{href:"https://github.com/peerigon/talks",target:"_blank",rel:"noopener noreferrer"}},[r._v("peerigon-talks"),e("OutboundLink")],1),r._v(" 收集了不少有意思的 talks")])]),r._v(" "),e("h2",{attrs:{id:"算法"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#算法"}},[r._v("#")]),r._v(" 算法")]),r._v(" "),e("ul",[e("li",[e("a",{attrs:{href:"https://github.com/azl397985856/leetcode",target:"_blank",rel:"noopener noreferrer"}},[r._v("leetcode"),e("OutboundLink")],1),r._v(" 用 js 刷 leetcode")])]),r._v(" "),e("h2",{attrs:{id:"nginx"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#nginx"}},[r._v("#")]),r._v(" nginx")]),r._v(" "),e("ul",[e("li",[e("a",{attrs:{href:"https://www.digitalocean.com/community/tools/nginx?global.app.lang=zhCN",target:"_blank",rel:"noopener noreferrer"}},[r._v("nginx 可视化配置工具"),e("OutboundLink")],1)])]),r._v(" "),e("h2",{attrs:{id:"生活"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#生活"}},[r._v("#")]),r._v(" 生活")]),r._v(" "),e("ul",[e("li",[e("a",{attrs:{href:"https://www.ventusky.com/",target:"_blank",rel:"noopener noreferrer"}},[r._v("Ventusky"),e("OutboundLink")],1),r._v(" 风雨气温图")])]),r._v(" "),e("h2",{attrs:{id:"营销"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#营销"}},[r._v("#")]),r._v(" 营销")]),r._v(" "),e("ul",[e("li",[e("a",{attrs:{href:"https://www.adguider.com/calendar",target:"_blank",rel:"noopener noreferrer"}},[r._v("营销日历"),e("OutboundLink")],1)])])])}),[],!1,null,null,null);e.default=a.exports}}]); \ No newline at end of file diff --git a/assets/js/107.0b61254d.js b/assets/js/107.0b61254d.js new file mode 100644 index 0000000000..6e22e96353 --- /dev/null +++ b/assets/js/107.0b61254d.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[107],{433:function(t,n,s){"use strict";s.r(n);var e=s(4),o=Object(e.a)({},(function(){return(0,this._self._c)("ContentSlotsDistributor",{attrs:{"slot-key":this.$parent.slotKey}})}),[],!1,null,null,null);n.default=o.exports}}]); \ No newline at end of file diff --git a/assets/js/108.ec9dff6b.js b/assets/js/108.ec9dff6b.js new file mode 100644 index 0000000000..cc61cb3672 --- /dev/null +++ b/assets/js/108.ec9dff6b.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[108],{434:function(t,n,s){"use strict";s.r(n);var e=s(4),o=Object(e.a)({},(function(){return(0,this._self._c)("ContentSlotsDistributor",{attrs:{"slot-key":this.$parent.slotKey}})}),[],!1,null,null,null);n.default=o.exports}}]); \ No newline at end of file diff --git a/assets/js/109.f1deacf5.js b/assets/js/109.f1deacf5.js new file mode 100644 index 0000000000..e4795388d9 --- /dev/null +++ b/assets/js/109.f1deacf5.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[109],{435:function(t,n,s){"use strict";s.r(n);var e=s(4),o=Object(e.a)({},(function(){return(0,this._self._c)("ContentSlotsDistributor",{attrs:{"slot-key":this.$parent.slotKey}})}),[],!1,null,null,null);n.default=o.exports}}]); \ No newline at end of file diff --git a/assets/js/11.5c4cc4bb.js b/assets/js/11.5c4cc4bb.js new file mode 100644 index 0000000000..4ff818e857 --- /dev/null +++ b/assets/js/11.5c4cc4bb.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[11,24,27,28,29],{256:function(t,e,a){},257:function(t,e,a){},258:function(t,e,a){},262:function(t,e,a){},267:function(t,e,a){"use strict";a.r(e);a(25);var s={props:{category:{type:String,default:""},tag:{type:String,default:""},currentPage:{type:Number,default:1},perPage:{type:Number,default:10}},data:()=>({sortPosts:[],postListOffsetTop:0}),created(){this.setPosts()},mounted(){},watch:{currentPage(){this.$route.query.p!=this.currentPage&&this.$router.push({query:{...this.$route.query,p:this.currentPage}}),this.setPosts()},category(){this.setPosts()},tag(){this.setPosts()}},methods:{setPosts(){const t=this.currentPage,e=this.perPage;let a=[];a=this.category?this.$groupPosts.categories[this.category]:this.tag?this.$groupPosts.tags[this.tag]:this.$sortPosts,this.sortPosts=a.slice((t-1)*e,t*e)}}},r=(a(272),a(4)),n=Object(r.a)(s,(function(){var t=this,e=t._self._c;return e("div",{ref:"postList",staticClass:"post-list"},[e("transition-group",{attrs:{tag:"div",name:"post"}},t._l(t.sortPosts,(function(a){return e("div",{key:a.key,staticClass:"post card-box",class:a.frontmatter.sticky&&"iconfont icon-zhiding"},[e("div",{staticClass:"title-wrapper"},[e("h2",[e("router-link",{attrs:{to:a.path}},[t._v("\n "+t._s(a.title)+"\n "),a.frontmatter.titleTag?e("span",{staticClass:"title-tag"},[t._v(t._s(a.frontmatter.titleTag))]):t._e()])],1),t._v(" "),e("div",{staticClass:"article-info"},[a.author&&a.author.href?e("a",{staticClass:"iconfont icon-touxiang",attrs:{title:"作者",target:"_blank",href:a.author.href}},[t._v(t._s(a.author.name?a.author.name:a.author))]):a.author?e("span",{staticClass:"iconfont icon-touxiang",attrs:{title:"作者"}},[t._v(t._s(a.author.name?a.author.name:a.author))]):t._e(),t._v(" "),a.frontmatter.date?e("span",{staticClass:"iconfont icon-riqi",attrs:{title:"创建时间"}},[t._v(t._s(a.frontmatter.date.split(" ")[0]))]):t._e(),t._v(" "),!1!==t.$themeConfig.category&&a.frontmatter.categories?e("span",{staticClass:"iconfont icon-wenjian",attrs:{title:"分类"}},t._l(a.frontmatter.categories,(function(a,s){return e("router-link",{key:s,attrs:{to:"/categories/?category="+encodeURIComponent(a)}},[t._v(t._s(a))])})),1):t._e(),t._v(" "),!1!==t.$themeConfig.tag&&a.frontmatter.tags&&a.frontmatter.tags[0]?e("span",{staticClass:"iconfont icon-biaoqian tags",attrs:{title:"标签"}},t._l(a.frontmatter.tags,(function(a,s){return e("router-link",{key:s,attrs:{to:"/tags/?tag="+encodeURIComponent(a)}},[t._v(t._s(a))])})),1):t._e()])]),t._v(" "),a.excerpt?e("div",{staticClass:"excerpt-wrapper"},[e("div",{staticClass:"excerpt",domProps:{innerHTML:t._s(a.excerpt)}}),t._v(" "),e("router-link",{staticClass:"readmore iconfont icon-jiantou-you",attrs:{to:a.path}},[t._v("阅读全文")])],1):t._e()])})),0)],1)}),[],!1,null,null,null);e.default=n.exports},268:function(t,e,a){"use strict";a.r(e);var s={props:{total:{type:Number,default:10},perPage:{type:Number,default:10},currentPage:{type:Number,default:1}},computed:{pages(){return Math.ceil(this.total/this.perPage)}},methods:{threeNum(){let t=3;const e=this.currentPage,a=this.pages;return t=e<3?3:e>a-3?a-2:e,t},goPrex(){let t=this.currentPage;t>1&&this.handleEmit(--t)},goNext(){let t=this.currentPage;t3,expression:"currentPage > 3"}],staticClass:"ellipsis ell-two",attrs:{title:"上两页"},on:{click:function(e){return t.goIndex(t.currentPage-2)}}}),t._v(" "),e("span",{directives:[{name:"show",rawName:"v-show",value:t.currentPage<=3,expression:"currentPage <= 3"}],staticClass:"card-box",class:{active:2===t.currentPage},on:{click:function(e){return t.goIndex(2)}}},[t._v("2")]),t._v(" "),e("span",{staticClass:"card-box",class:{active:t.currentPage>=3&&t.currentPage<=t.pages-2},on:{click:function(e){t.goIndex(t.threeNum())}}},[t._v(t._s(t.threeNum()))]),t._v(" "),e("span",{directives:[{name:"show",rawName:"v-show",value:t.currentPage=t.pages-2,expression:"currentPage >= pages - 2"}],staticClass:"card-box",class:{active:t.currentPage===t.pages-1},on:{click:function(e){return t.goIndex(t.pages-1)}}},[t._v(t._s(t.pages-1))]),t._v(" "),e("span",{staticClass:"card-box",class:{active:t.currentPage===t.pages},on:{click:function(e){return t.goIndex(t.pages)}}},[t._v(t._s(t.pages))])]),t._v(" "),e("span",{staticClass:"card-box next iconfont icon-jiantou-you",class:{disabled:t.currentPage===t.pages},on:{click:function(e){return t.goNext()}}},[e("p",[t._v("下一页")])])])}),[],!1,null,null,null);e.default=n.exports},270:function(t,e,a){"use strict";a.r(e);a(271);var s=a(4),r=Object(s.a)({},(function(){var t=this._self._c;return t("div",{staticClass:"main-wrapper"},[t("div",{staticClass:"main-left"},[this._t("mainLeft")],2),this._v(" "),t("div",{staticClass:"main-right"},[this._t("mainRight")],2)])}),[],!1,null,null,null);e.default=r.exports},271:function(t,e,a){"use strict";a(256)},272:function(t,e,a){"use strict";a(257)},273:function(t,e,a){"use strict";a(258)},286:function(t,e,a){"use strict";a(262)},287:function(t,e,a){},300:function(t,e,a){"use strict";a.r(e);var s={props:{category:{type:String,default:""},categoriesData:{type:Array,default:[]},length:{type:[String,Number],default:"all"}},computed:{categories(){return"all"===this.length?this.categoriesData:this.categoriesData.slice(0,this.length)}}},r=(a(286),a(4)),n=Object(r.a)(s,(function(){var t=this,e=t._self._c;return e("div",{staticClass:"categories-wrapper card-box"},[e("router-link",{staticClass:"title iconfont icon-wenjianjia",attrs:{to:"/categories/",title:"全部分类"}},[t._v(t._s("all"===t.length?"全部分类":"文章分类"))]),t._v(" "),e("div",{staticClass:"categories"},[t._l(t.categories,(function(a,s){return e("router-link",{key:s,class:{active:a.key===t.category},attrs:{to:"/categories/?category="+encodeURIComponent(a.key)}},[t._v("\n "+t._s(a.key)+"\n "),e("span",[t._v(t._s(a.length))])])})),t._v(" "),"all"!==t.length&&t.length({category:"",total:0,perPage:10,currentPage:1}),components:{MainLayout:s.default,PostList:r.default,Pagination:n.default,CategoriesBar:i.default},mounted(){const t=this.$route.query.category;t?(this.category=t,this.total=this.$groupPosts.categories[t].length):this.total=this.$sortPosts.length,this.$route.query.p&&(this.currentPage=Number(this.$route.query.p));const e=document.querySelector(".categories");e&&setTimeout(()=>{const t=e.querySelector(".active"),a=t?t.offsetTop:0;e.scrollTo({top:a,behavior:"smooth"})},300)},methods:{handlePagination(t){this.currentPage=t}},watch:{"$route.query.category"(t){this.category=t?decodeURIComponent(t):"",this.category?this.total=this.$groupPosts.categories[this.category].length:this.total=this.$sortPosts.length,this.currentPage=1}}},c=(a(313),a(4)),u=Object(c.a)(o,(function(){var t=this,e=t._self._c;return e("div",{staticClass:"custom-page categories-page"},[e("MainLayout",{scopedSlots:t._u([{key:"mainLeft",fn:function(){return[t.$categoriesAndTags.categories.length?e("CategoriesBar",{attrs:{categoriesData:t.$categoriesAndTags.categories,category:t.category}}):t._e(),t._v(" "),e("PostList",{attrs:{currentPage:t.currentPage,perPage:t.perPage,category:t.category}}),t._v(" "),e("Pagination",{directives:[{name:"show",rawName:"v-show",value:Math.ceil(t.total/t.perPage)>1,expression:"Math.ceil(total / perPage) > 1"}],attrs:{total:t.total,perPage:t.perPage,currentPage:t.currentPage},on:{getCurrentPage:t.handlePagination}})]},proxy:!0},{key:"mainRight",fn:function(){return[t.$categoriesAndTags.categories.length?e("CategoriesBar",{attrs:{categoriesData:t.$categoriesAndTags.categories,category:t.category}}):t._e()]},proxy:!0}])})],1)}),[],!1,null,null,null);e.default=u.exports}}]); \ No newline at end of file diff --git a/assets/js/110.d0192926.js b/assets/js/110.d0192926.js new file mode 100644 index 0000000000..a08dafee1e --- /dev/null +++ b/assets/js/110.d0192926.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[110],{436:function(t,n,s){"use strict";s.r(n);var e=s(4),o=Object(e.a)({},(function(){return(0,this._self._c)("ContentSlotsDistributor",{attrs:{"slot-key":this.$parent.slotKey}})}),[],!1,null,null,null);n.default=o.exports}}]); \ No newline at end of file diff --git a/assets/js/111.606d2d81.js b/assets/js/111.606d2d81.js new file mode 100644 index 0000000000..8f771180ee --- /dev/null +++ b/assets/js/111.606d2d81.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[111],{437:function(t,a,e){"use strict";e.r(a);var r=e(4),s=Object(r.a)({},(function(){var t=this,a=t._self._c;return a("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[a("h2",{attrs:{id:"资源"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#资源"}},[t._v("#")]),t._v(" 资源")]),t._v(" "),a("p",[t._v("下载一个百度网盘,登录自己的百度网盘 然后添加用户名:英雄不问出路人 给师傅发送:ns 游戏然后会自动分享给你")]),t._v(" "),a("h3",{attrs:{id:"游戏下载"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#游戏下载"}},[t._v("#")]),t._v(" 游戏下载")]),t._v(" "),a("p",[t._v("下载游戏网址:"),a("a",{attrs:{href:"https://www.bibgame.com/sgame/",target:"_blank",rel:"noopener noreferrer"}},[t._v("https://www.bibgame.com/sgame/"),a("OutboundLink")],1)]),t._v(" "),a("p",[t._v("游戏年轮登陆账号: 用户名:"),a("code",[t._v("游戏年轮")]),t._v(" 密码:"),a("code",[t._v("liming123..")]),t._v(".切记请不要去修改密码,如查询到有修改密码者,不提供使用会员账号,且我们也会把之前的密码重新注销,会导致使用不了,谢谢")]),t._v(" "),a("h4",{attrs:{id:"安装"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#安装"}},[t._v("#")]),t._v(" 安装")]),t._v(" "),a("p",[t._v("把下载好的游戏软件放在内存卡的游戏文件夹 GAMES 里面,然后进入破解系统,选择相册进入,找到小\n女孩的头像进入,选择内存卡安装,找到游戏文件夹,然后按照提示安装游戏即可。支持 nsp 和 xci 两种格式的游戏文件。安装游戏\n时内存卡里面剩余的内存需要比游戏本体大。")]),t._v(" "),a("h2",{attrs:{id:"安装游戏"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#安装游戏"}},[t._v("#")]),t._v(" 安装游戏")]),t._v(" "),a("blockquote",[a("p",[t._v("这里应该是已经破解过的游戏下载,待验证")])]),t._v(" "),a("ol",[a("li",[t._v("关机拔出内存卡,读卡器插上电脑。")]),t._v(" "),a("li",[t._v("下载 xci 或者 nsp 的游戏文件(不要下文件夹)到内存卡 agames 文件夹。")]),t._v(" "),a("li",[t._v("拔出内存卡,插回游戏机。")]),t._v(" "),a("li",[t._v("破解系统相册进入 atmoxl 进行安装,安装完安装包删除。")])]),t._v(" "),a("p",[t._v("【游戏文件名字不能是中文,补丁及 DLC 安装方法和游戏安装方法一样】")]),t._v(" "),a("h2",{attrs:{id:"破解"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#破解"}},[t._v("#")]),t._v(" 破解")]),t._v(" "),a("ul",[a("li",[t._v("大气层破解: "),a("a",{attrs:{href:"https://video3.yangkeduo.com/i1/2020-08-11/0146c0c9ebf5b58958c9713c45e01898.mp4",target:"_blank",rel:"noopener noreferrer"}},[t._v("网址"),a("OutboundLink")],1)])])])}),[],!1,null,null,null);a.default=s.exports}}]); \ No newline at end of file diff --git a/assets/js/112.aa6de9dc.js b/assets/js/112.aa6de9dc.js new file mode 100644 index 0000000000..e43286a60b --- /dev/null +++ b/assets/js/112.aa6de9dc.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[112],{438:function(a,t,s){"use strict";s.r(t);var r=s(4),v=Object(r.a)({},(function(){var a=this,t=a._self._c;return t("ContentSlotsDistributor",{attrs:{"slot-key":a.$parent.slotKey}},[t("h2",{attrs:{id:"大纲"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#大纲"}},[a._v("#")]),a._v(" 大纲")]),a._v(" "),t("h3",{attrs:{id:"第一章-初遇"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#第一章-初遇"}},[a._v("#")]),a._v(" 第一章:初遇")]),a._v(" "),t("p",[a._v("小伟和小娟从小一起长大,他们是邻居,也是最好的朋友。每天放学后,他们都会一起在花园里玩耍,一起分享快乐和烦恼。小伟早已发现自己对小娟有着特殊的感情,但还未敢表白。而小娟,也在心里默默地暗恋着小伟。")]),a._v(" "),t("h3",{attrs:{id:"第二章-心动时刻"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#第二章-心动时刻"}},[a._v("#")]),a._v(" 第二章:心动时刻")]),a._v(" "),t("p",[a._v("随着年龄的增长,小伟开始逐渐明白自己对小娟的感情。一次偶然的相遇,小娟为小伟修理掉了牙齿,他们的手指不小心碰触,让两颗年轻的心砰砰直跳。小伟决定要勇敢面对这份心动,但他担心这样会让他们的友谊变得尴尬。")]),a._v(" "),t("h3",{attrs:{id:"第三章-情窦初开"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#第三章-情窦初开"}},[a._v("#")]),a._v(" 第三章:情窦初开")]),a._v(" "),t("p",[a._v("小伟在日记里默默写下了对小娟的感受,却迟迟没有勇气给她展示。他们在一起的时候,他时常对她投去温柔的目光,但言语间却总是遮掩自己的情感。小娟也察觉到了小伟的变化,但她也不敢轻易表白。")]),a._v(" "),t("h3",{attrs:{id:"第四章-秘密的表白"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#第四章-秘密的表白"}},[a._v("#")]),a._v(" 第四章:秘密的表白")]),a._v(" "),t("p",[a._v("在一个温暖的春日午后,小伟鼓起勇气,在小娟最喜欢的花海中,将自己的情感告诉了她。小娟惊讶又感动,她终于鼓起勇气告诉小伟,她也喜欢他很久了。两人终于坦诚相对,他们的感情更加深厚。")]),a._v(" "),t("h3",{attrs:{id:"第五章-青涩初恋"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#第五章-青涩初恋"}},[a._v("#")]),a._v(" 第五章:青涩初恋")]),a._v(" "),t("p",[a._v("小伟和小娟的初恋在校园里悄然兴起。他们手牵手,在校园里散步,分享着彼此的喜怒哀乐。他们成了同学们眼中的模范情侣,也成了老师们眼中的可爱学生。初恋的甜蜜让他们陶醉其中,但也会面临一些稚嫩的矛盾和挑战。")]),a._v(" "),t("h3",{attrs:{id:"第六章-挑战与成长"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#第六章-挑战与成长"}},[a._v("#")]),a._v(" 第六章:挑战与成长")]),a._v(" "),t("p",[a._v("随着时间的推移,小伟和小娟面临着学业上的考验。他们都渐渐成熟起来,但也开始面临一些分别的压力。小伟的牙医梦想让他要考虑出国深造的可能,而小娟也有自己的理想。两人开始慢慢犹豫和纠结,不知道该如何选择。")]),a._v(" "),t("h3",{attrs:{id:"第七章-距离的考验"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#第七章-距离的考验"}},[a._v("#")]),a._v(" 第七章:距离的考验")]),a._v(" "),t("p",[a._v("最终,小伟和小娟选择了分别。小伟去了一个国外的医学院,而小娟则留在国内继续学业。距离让他们开始怀疑这份感情是否可以长久,但他们也都坚信,只要心中有对方,距离并不能阻挡他们的爱。")]),a._v(" "),t("h3",{attrs:{id:"第八章-短暂的分别"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#第八章-短暂的分别"}},[a._v("#")]),a._v(" 第八章:短暂的分别")]),a._v(" "),t("p",[a._v("在异国他乡,小伟开始了他的学业生涯。虽然他很忙碌,但他依然每天都会和小娟保持联系。每当他们视频通话时,小娟总是鼓励他坚持下去,而小伟也会告诉小娟,他们一定会在未来再次相聚。")]),a._v(" "),t("h3",{attrs:{id:"第九章-新的朋友"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#第九章-新的朋友"}},[a._v("#")]),a._v(" 第九章:新的朋友")]),a._v(" "),t("p",[a._v("在国外,小伟结识了一些新的朋友,其中有一位性格开朗、善解人意的女孩,名叫苏雪。苏雪和小伟逐渐成了很好的朋友,她对小伟的牙医事业也很支持,常常陪着他度过思念小娟的时光。")]),a._v(" "),t("h3",{attrs:{id:"第十章-意外的邂逅"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#第十章-意外的邂逅"}},[a._v("#")]),a._v(" 第十章:意外的邂逅")]),a._v(" "),t("p",[a._v("在一个偶然的聚会中,小伟意外地遇到了小娟的堂弟,名叫小飞。小飞和小娟感情很好,他向小伟透露了小娟最近的近况。原来,小娟也在经历着一些挑战和变化,但她对小伟的思念从未减退。")]),a._v(" "),t("h3",{attrs:{id:"第十一章-思念的夜晚"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#第十一章-思念的夜晚"}},[a._v("#")]),a._v(" 第十一章:思念的夜晚")]),a._v(" "),t("p",[a._v("得知小娟的情况后,小伟更加思念她。每当夜深人静,他会一个人躺在床上,回想起和小娟一起度过的美好时光。在他心中,小娟永远是最特别的存在。同时,小伟开始认真思考他们的未来,他不知道他们之间会有怎样的结局,但他决定要为了他们的爱而努力。")]),a._v(" "),t("h3",{attrs:{id:"第十二章-苏雪的心结"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#第十二章-苏雪的心结"}},[a._v("#")]),a._v(" 第十二章:苏雪的心结")]),a._v(" "),t("p",[a._v("苏雪逐渐发现自己对小伟有着更复杂的情感。她看到小伟坚持不懈地思念着小娟,也看到小娟在他心中的特殊地位。她明白,自己喜欢的人已经心里有了别人。虽然苏雪为自己的情感感到矛盾,但她也不愿伤害小伟的心。")]),a._v(" "),t("h3",{attrs:{id:"第十三章-选择与放手"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#第十三章-选择与放手"}},[a._v("#")]),a._v(" 第十三章:选择与放手")]),a._v(" "),t("p",[a._v("在一个星期天的下午,苏雪找到小伟,坦白地向他表白自己的感情。小伟听后显得有些犹豫,他不愿意伤害苏雪的心,但他也不能对她有所欺瞒。他坦诚地告诉苏雪,他心里一直有一个人,而那个人是小娟。虽然苏雪心痛,但她也理解,于是她选择了放手。")]),a._v(" "),t("h3",{attrs:{id:"第十四章-重逢的喜悦"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#第十四章-重逢的喜悦"}},[a._v("#")]),a._v(" 第十四章:重逢的喜悦")]),a._v(" "),t("p",[a._v("经过了一段时间的分别,小伟终于回到了家乡。当小娟得知他要回来时,内心充满了喜悦。他们在火车站的候车室重逢,小娟含情脉脉地看着小伟,而小伟也拉着小娟的手,告诉她他一直在思念着她。两人紧紧拥抱在一起,那一刻,所有的犹豫和分别都变得微不足道。")]),a._v(" "),t("h3",{attrs:{id:"第十五章-爱的坚持"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#第十五章-爱的坚持"}},[a._v("#")]),a._v(" 第十五章:爱的坚持")]),a._v(" "),t("p",[a._v("小伟和小娟重新走到了一起,他们决定要一直坚守这份爱。他们明白,爱情不是一帆风顺的,但只要心中有对方,他们就能共同克服所有的困难。小伟也向小娟保证,无论将来会面临什么样的选择,他都会坚持他们的爱,无怨无悔地陪在她身边。")]),a._v(" "),t("h3",{attrs:{id:"第十六章-牙医的助力"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#第十六章-牙医的助力"}},[a._v("#")]),a._v(" 第十六章:牙医的助力")]),a._v(" "),t("p",[a._v("小伟在牙医事业上越发有所成就,他的名气逐渐传遍了整个城市。擅长牙医的他,也为小娟提供了许多帮助。小娟因为工作忙碌,常常疏于照顾自己的牙齿。每当她有口腔问题时,小伟总是第一时间出现在她身边,给予专业的建议和治疗。")]),a._v(" "),t("h3",{attrs:{id:"第十七章-幸福的时光"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#第十七章-幸福的时光"}},[a._v("#")]),a._v(" 第十七章:幸福的时光")]),a._v(" "),t("p",[a._v("小伟和小娟在一起的日子里,每一刻都充满了幸福。他们一起看电影,一起逛街,一起分享生活中的点滴喜悦。他们的爱情越发坚定,彼此也变得更加默契。在这段幸福的时光里,他们渐渐成为了对方生命中不可或缺的一部分。")]),a._v(" "),t("h3",{attrs:{id:"第十八章-职业与家庭的平衡"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#第十八章-职业与家庭的平衡"}},[a._v("#")]),a._v(" 第十八章:职业与家庭的平衡")]),a._v(" "),t("p",[a._v("随着家庭的扩大,小伟开始面临职业和家庭的平衡问题。作为一个牙医,他的工作很繁忙,但他也希望能够陪伴在家人身边。小娟理解丈夫的辛苦,她支持他在事业上取得更大的成就,同时也希望他能够更多地参与到家庭中来。")]),a._v(" "),t("p",[a._v("小伟决定要寻找一种平衡,他安排自己的工作时间,尽量不让工作影响到与小娟和孩子相处的时间。每当他在诊所忙碌,他都会通过电话或视频与家人保持联系,分享他们生活中的点滴。")]),a._v(" "),t("h3",{attrs:{id:"第十九章-挑战与困惑"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#第十九章-挑战与困惑"}},[a._v("#")]),a._v(" 第十九章:挑战与困惑")]),a._v(" "),t("p",[a._v("在职业和家庭的平衡中,小伟感到有些困惑。他担心自己不能兼顾好家庭和事业,担心自己会辜负了小娟和孩子。然而,在小娟的鼓励下,他坚定地告诉自己,他可以做到。他要用自己的努力和爱来守护他们的家。")]),a._v(" "),t("p",[a._v("小娟也面临着自己职业和家庭的挑战。虽然她热爱摄影,但时常为了家庭放弃了一些工作机会。她开始思考如何在追求梦想的同时,也更好地照顾家人。两人一同面对着这个人生的新阶段,共同寻找着解决的办法。")]),a._v(" "),t("h3",{attrs:{id:"第二十章-成长的友情"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#第二十章-成长的友情"}},[a._v("#")]),a._v(" 第二十章:成长的友情")]),a._v(" "),t("p",[a._v("在工作中,小伟结识了许多优秀的医生和同事。其中,有一位名叫张林的医生,成为了小伟的好朋友。张林是一位非常聪明和努力的医生,他对小伟的牙医事业表示了很大的钦佩,两人成为了知心朋友,一起分享着成长的喜悦和困难。")]),a._v(" "),t("p",[a._v("张林也和小伟一样,面临着职业和家庭的平衡问题。他是一位出色的医生,但他也希望能够更多地陪伴家人。在小伟和小娟的影响下,张林开始尝试调整工作时间,更多地参与到家庭中来。他们一起交流着在职业和家庭之间找到平衡的经验,成为了彼此的支持和鼓励。")]),a._v(" "),t("h3",{attrs:{id:"第二十一章-家庭的温暖"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#第二十一章-家庭的温暖"}},[a._v("#")]),a._v(" 第二十一章:家庭的温暖")]),a._v(" "),t("p",[a._v("新生命的降临,让小伟和小娟的家庭充满了更多的温暖和喜悦。他们一起照顾着孩子,分享着每一个成长的瞬间。小伟成为了一个贴心的父亲,他用温柔的手指为孩子轻轻擦拭泪水,用悉心的关怀陪伴着孩子成长。")]),a._v(" "),t("h3",{attrs:{id:"第二十二章-职业与家庭的平衡"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#第二十二章-职业与家庭的平衡"}},[a._v("#")]),a._v(" 第二十二章:职业与家庭的平衡")]),a._v(" "),t("p",[a._v("随着家庭的扩大,小伟开始面临职业和家庭的平衡问题。作为一个牙医,他的工作很繁忙,但他也希望能够陪伴在家人身边。小娟理解丈夫的辛苦,她支持他在事业上取得更大的成就,同时也希望他能够更多地参与到家庭中来。")]),a._v(" "),t("h3",{attrs:{id:"第二十三章-挑战与困惑"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#第二十三章-挑战与困惑"}},[a._v("#")]),a._v(" 第二十三章:挑战与困惑")]),a._v(" "),t("p",[a._v("在事业和家庭之间,小伟感到有些困惑。他担心自己不能兼顾好家庭和事业,担心自己会辜负了小娟和孩子。然而,在小娟的鼓励下,他坚定地告诉自己,他可以做到。他要用自己的努力和爱来守护他们的家。")]),a._v(" "),t("h3",{attrs:{id:"第二十四章-成长的友情"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#第二十四章-成长的友情"}},[a._v("#")]),a._v(" 第二十四章:成长的友情")]),a._v(" "),t("p",[a._v("在工作中,小伟结识了许多优秀的医生和同事。其中,有一位名叫张林的医生,成为了小伟的好朋友。张林是一位非常聪明和努力的医生,他对小伟的牙医事业表示了很大的钦佩,两人成为了知心朋友,一起分享着成长的喜悦和困难。")]),a._v(" "),t("h3",{attrs:{id:"第二十五章-家族的团聚"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#第二十五章-家族的团聚"}},[a._v("#")]),a._v(" 第二十五章:家族的团聚")]),a._v(" "),t("p",[a._v("小伟的家人听说他已经结婚并有了孩子,都非常开心,希望能尽早见到小娟和孩子。于是,他们一起计划着一个家族团聚的活动。在一个温馨的周末,小伟和小娟带着孩子回到家乡,与家人一起度过了快乐的时光。")]),a._v(" "),t("h3",{attrs:{id:"第二十六章-新的起点"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#第二十六章-新的起点"}},[a._v("#")]),a._v(" 第二十六章:新的起点")]),a._v(" "),t("p",[a._v("在家人和朋友的祝福下,小伟和小娟决定要重新规划自己的未来。小娟放弃了原本的工作,开始学习摄影。她拍摄了许多感人至深的照片,用镜头记录了家人和朋友的美好瞬间。而小伟也决定要扩大自己的诊所,为更多的人带去健康的笑容。")]),a._v(" "),t("h3",{attrs:{id:"第二十七章-梦想成真"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#第二十七章-梦想成真"}},[a._v("#")]),a._v(" 第二十七章:梦想成真")]),a._v(" "),t("p",[a._v("随着时间的推移,小伟和小娟都实现了自己的梦想。小娟的摄影作品被发表在许多杂志和画廊中,她成为了一名备受赞誉的摄影师。而小伟的诊所也越来越繁忙,他的牙医事业蒸蒸日上。他们的努力得到了回报,也让他们的生活更加丰富多彩。")]),a._v(" "),t("h3",{attrs:{id:"第二十八章-爱的传承"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#第二十八章-爱的传承"}},[a._v("#")]),a._v(" 第二十八章:爱的传承")]),a._v(" "),t("p",[a._v("小伟和小娟的孩子渐渐长大,他们将父母的爱传承下去。他们教导孩子善良、坚强和勇敢,让他们学会珍惜家人和友谊。小伟和小娟也经常带着孩子一起旅行,让他们了解更广阔的世界。")]),a._v(" "),t("h3",{attrs:{id:"第二十九章-美好的未来"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#第二十九章-美好的未来"}},[a._v("#")]),a._v(" 第二十九章:美好的未来")]),a._v(" "),t("p",[a._v("小伟和小娟一起迎接着未来的每一天。他们的爱情依然充满着甜蜜和温暖,他们一直相信着,只要心中有爱,他们的未来会更美好。在家人和朋友的陪伴下,他们共同创造了一个温馨幸福的家庭。")]),a._v(" "),t("h3",{attrs:{id:"第三十章-永恒的爱"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#第三十章-永恒的爱"}},[a._v("#")]),a._v(" 第三十章:永恒的爱")]),a._v(" "),t("p",[a._v("岁月如歌,小伟和小娟的故事还在继续。他们的爱情虽然经历了波折,但它却更加坚定。他们一直相互扶持着,共同创造着属于他们的美好未来。小伟和小娟的故事不仅是一段浪漫的爱情,更是一种真挚而永恒的情感,将在岁月中永远闪耀。")])])}),[],!1,null,null,null);t.default=v.exports}}]); \ No newline at end of file diff --git a/assets/js/113.8766cc3e.js b/assets/js/113.8766cc3e.js new file mode 100644 index 0000000000..b282e50ec5 --- /dev/null +++ b/assets/js/113.8766cc3e.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[113],{439:function(s,t,n){"use strict";n.r(t);var a=n(4),e=Object(a.a)({},(function(){var s=this,t=s._self._c;return t("ContentSlotsDistributor",{attrs:{"slot-key":s.$parent.slotKey}},[t("div",{staticClass:"language-gradle line-numbers-mode"},[t("pre",{pre:!0,attrs:{class:"language-gradle"}},[t("code",[s._v("String ANDROID_PUBLIC_MAVEN_URL "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token string"}},[s._v("'xxx'")]),s._v("\nString MAVEN_USERNAME "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token string"}},[s._v("'xxx'")]),s._v("\nString MAVEN_PASSWORD "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token string"}},[s._v("'xxx'")]),s._v("\n\n"),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("def")]),s._v(" setMavenCredentials "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v(" MavenArtifactRepository repo "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("->")]),s._v("\n repo"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("setAllowInsecureProtocol")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token boolean"}},[s._v("true")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v("\n repo"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),s._v("credentials "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n username "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" MAVEN_USERNAME\n password "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" MAVEN_PASSWORD\n "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n repo"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),s._v("authentication "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("basic")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("BasicAuthentication"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n\n"),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("def")]),s._v(" String "),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("fixedUrl")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("String url"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n url "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" url"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("trim")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("if")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("url"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("endsWith")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token interpolation-string"}},[t("span",{pre:!0,attrs:{class:"token string"}},[s._v('"/"')])]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n url "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" url"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("substring")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("0")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" url"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("length")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("-")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("1")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n return url\n"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n\n"),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("def")]),s._v(" setAndroidPublicMaven "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v(" RepositoryHandler repositoryHandler "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("->")]),s._v("\n repositoryHandler"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),s._v("maven "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v(" MavenArtifactRepository repo "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("->")]),s._v("\n repo"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("url")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("ANDROID_PUBLIC_MAVEN_URL"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("setMavenCredentials")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("repo"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n\n repositoryHandler"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),s._v("all "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v(" ArtifactRepository repo "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("->")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("if")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("repo"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),s._v("class"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),s._v("name "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("==")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token string"}},[s._v("'org.gradle.plugin.use.internal.PluginArtifactRepository'")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n try "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n repo "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" repo"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),s._v("delegate\n "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v(" catch "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("Throwable ignored"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("if")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("repo instanceof "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("MavenArtifactRepository")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n URI uri "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" repo"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),s._v("url\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("if")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("uri "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("!=")]),s._v(" null"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n String url "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" uri"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("normalize")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("toString")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("if")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("fixedUrl")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("url"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("==")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("fixedUrl")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("ANDROID_PUBLIC_MAVEN_URL"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("setMavenCredentials")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("repo"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n\ngradle"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),s._v("beforeSettings "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v(" Settings settings "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("->")]),s._v("\n settings"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),s._v("pluginManagement "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v(" pluginManagementSpec "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("->")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("setAndroidPublicMaven")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("pluginManagementSpec"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("repositories")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("setAndroidPublicMaven")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("settings"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),s._v("buildscript"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("repositories")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v("\n try "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n settings"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),s._v("dependencyResolutionManagement "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v(" dependencyManagementSpec "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("->")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("setAndroidPublicMaven")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("dependencyManagementSpec"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("repositories")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("catch")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("Exception e"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token comment"}},[s._v("// 低版本gradle不支持dependencyResolutionManagement")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n\ngradle"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),s._v("beforeProject "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v(" Project "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("project")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("->")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("setAndroidPublicMaven")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("project")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),s._v("buildscript"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("repositories")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("setAndroidPublicMaven")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("project")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("repositories")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n")])]),s._v(" "),t("div",{staticClass:"line-numbers-wrapper"},[t("span",{staticClass:"line-number"},[s._v("1")]),t("br"),t("span",{staticClass:"line-number"},[s._v("2")]),t("br"),t("span",{staticClass:"line-number"},[s._v("3")]),t("br"),t("span",{staticClass:"line-number"},[s._v("4")]),t("br"),t("span",{staticClass:"line-number"},[s._v("5")]),t("br"),t("span",{staticClass:"line-number"},[s._v("6")]),t("br"),t("span",{staticClass:"line-number"},[s._v("7")]),t("br"),t("span",{staticClass:"line-number"},[s._v("8")]),t("br"),t("span",{staticClass:"line-number"},[s._v("9")]),t("br"),t("span",{staticClass:"line-number"},[s._v("10")]),t("br"),t("span",{staticClass:"line-number"},[s._v("11")]),t("br"),t("span",{staticClass:"line-number"},[s._v("12")]),t("br"),t("span",{staticClass:"line-number"},[s._v("13")]),t("br"),t("span",{staticClass:"line-number"},[s._v("14")]),t("br"),t("span",{staticClass:"line-number"},[s._v("15")]),t("br"),t("span",{staticClass:"line-number"},[s._v("16")]),t("br"),t("span",{staticClass:"line-number"},[s._v("17")]),t("br"),t("span",{staticClass:"line-number"},[s._v("18")]),t("br"),t("span",{staticClass:"line-number"},[s._v("19")]),t("br"),t("span",{staticClass:"line-number"},[s._v("20")]),t("br"),t("span",{staticClass:"line-number"},[s._v("21")]),t("br"),t("span",{staticClass:"line-number"},[s._v("22")]),t("br"),t("span",{staticClass:"line-number"},[s._v("23")]),t("br"),t("span",{staticClass:"line-number"},[s._v("24")]),t("br"),t("span",{staticClass:"line-number"},[s._v("25")]),t("br"),t("span",{staticClass:"line-number"},[s._v("26")]),t("br"),t("span",{staticClass:"line-number"},[s._v("27")]),t("br"),t("span",{staticClass:"line-number"},[s._v("28")]),t("br"),t("span",{staticClass:"line-number"},[s._v("29")]),t("br"),t("span",{staticClass:"line-number"},[s._v("30")]),t("br"),t("span",{staticClass:"line-number"},[s._v("31")]),t("br"),t("span",{staticClass:"line-number"},[s._v("32")]),t("br"),t("span",{staticClass:"line-number"},[s._v("33")]),t("br"),t("span",{staticClass:"line-number"},[s._v("34")]),t("br"),t("span",{staticClass:"line-number"},[s._v("35")]),t("br"),t("span",{staticClass:"line-number"},[s._v("36")]),t("br"),t("span",{staticClass:"line-number"},[s._v("37")]),t("br"),t("span",{staticClass:"line-number"},[s._v("38")]),t("br"),t("span",{staticClass:"line-number"},[s._v("39")]),t("br"),t("span",{staticClass:"line-number"},[s._v("40")]),t("br"),t("span",{staticClass:"line-number"},[s._v("41")]),t("br"),t("span",{staticClass:"line-number"},[s._v("42")]),t("br"),t("span",{staticClass:"line-number"},[s._v("43")]),t("br"),t("span",{staticClass:"line-number"},[s._v("44")]),t("br"),t("span",{staticClass:"line-number"},[s._v("45")]),t("br"),t("span",{staticClass:"line-number"},[s._v("46")]),t("br"),t("span",{staticClass:"line-number"},[s._v("47")]),t("br"),t("span",{staticClass:"line-number"},[s._v("48")]),t("br"),t("span",{staticClass:"line-number"},[s._v("49")]),t("br"),t("span",{staticClass:"line-number"},[s._v("50")]),t("br"),t("span",{staticClass:"line-number"},[s._v("51")]),t("br"),t("span",{staticClass:"line-number"},[s._v("52")]),t("br"),t("span",{staticClass:"line-number"},[s._v("53")]),t("br"),t("span",{staticClass:"line-number"},[s._v("54")]),t("br"),t("span",{staticClass:"line-number"},[s._v("55")]),t("br"),t("span",{staticClass:"line-number"},[s._v("56")]),t("br"),t("span",{staticClass:"line-number"},[s._v("57")]),t("br"),t("span",{staticClass:"line-number"},[s._v("58")]),t("br"),t("span",{staticClass:"line-number"},[s._v("59")]),t("br"),t("span",{staticClass:"line-number"},[s._v("60")]),t("br"),t("span",{staticClass:"line-number"},[s._v("61")]),t("br"),t("span",{staticClass:"line-number"},[s._v("62")]),t("br"),t("span",{staticClass:"line-number"},[s._v("63")]),t("br"),t("span",{staticClass:"line-number"},[s._v("64")]),t("br"),t("span",{staticClass:"line-number"},[s._v("65")]),t("br"),t("span",{staticClass:"line-number"},[s._v("66")]),t("br")])])])}),[],!1,null,null,null);t.default=e.exports}}]); \ No newline at end of file diff --git a/assets/js/114.46b84e3f.js b/assets/js/114.46b84e3f.js new file mode 100644 index 0000000000..19407d537c --- /dev/null +++ b/assets/js/114.46b84e3f.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[114],{440:function(r,e,t){"use strict";t.r(e);var n=t(4),o=Object(n.a)({},(function(){var r=this,e=r._self._c;return e("ContentSlotsDistributor",{attrs:{"slot-key":r.$parent.slotKey}},[e("blockquote",[e("p",[r._v("Android 概述: 对相关知识进行归纳整理")])]),r._v(" "),e("h1",{attrs:{id:"android"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#android"}},[r._v("#")]),r._v(" Android")]),r._v(" "),e("h2",{attrs:{id:"相关链接"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#相关链接"}},[r._v("#")]),r._v(" 相关链接")]),r._v(" "),e("ul",[e("li",[e("a",{attrs:{href:"https://developer.android.com",target:"_blank",rel:"noopener noreferrer"}},[r._v("Android developer"),e("OutboundLink")],1),r._v(" "),e("ul",[e("li",[e("a",{attrs:{href:"https://developer.android.com/samples?hl=zh-cn",target:"_blank",rel:"noopener noreferrer"}},[r._v("sample"),e("OutboundLink")],1)]),r._v(" "),e("li",[e("a",{attrs:{href:"https://source.android.com/docs/core?hl=zh-cn",target:"_blank",rel:"noopener noreferrer"}},[r._v("Android 系统核心主题*"),e("OutboundLink")],1)]),r._v(" "),e("li",[e("a",{attrs:{href:"https://m3.material.io/",target:"_blank",rel:"noopener noreferrer"}},[r._v("Material 3"),e("OutboundLink")],1)]),r._v(" "),e("li",[e("a",{attrs:{href:"https://developer.android.com/kotlin?hl=zh-cn",target:"_blank",rel:"noopener noreferrer"}},[r._v("Kotlin"),e("OutboundLink")],1)])])]),r._v(" "),e("li",[e("a",{attrs:{href:"https://www.android.com/",target:"_blank",rel:"noopener noreferrer"}},[r._v("android 官网"),e("OutboundLink")],1)]),r._v(" "),e("li",[e("a",{attrs:{href:"http://androidxref.com/",target:"_blank",rel:"noopener noreferrer"}},[r._v("androidxref"),e("OutboundLink")],1),r._v(" 源代码查看网站,网站暂停更新了,只有 2011-2018 年的代码收录")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://cs.android.com/",target:"_blank",rel:"noopener noreferrer"}},[r._v("Android Code Search"),e("OutboundLink")],1)])]),r._v(" "),e("h3",{attrs:{id:"工具"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#工具"}},[r._v("#")]),r._v(" 工具")]),r._v(" "),e("ul",[e("li",[e("a",{attrs:{href:"https://perfetto.dev/docs/quickstart/android-tracing",target:"_blank",rel:"noopener noreferrer"}},[r._v("Perfetto"),e("OutboundLink")],1),r._v(" "),e("ul",[e("li",[e("a",{attrs:{href:"https://perfetto.dev/docs/visualization/perfetto-ui",target:"_blank",rel:"noopener noreferrer"}},[r._v("perfetto-ui"),e("OutboundLink")],1)])])])])])}),[],!1,null,null,null);e.default=o.exports}}]); \ No newline at end of file diff --git a/assets/js/115.17cb622d.js b/assets/js/115.17cb622d.js new file mode 100644 index 0000000000..61ebb78a22 --- /dev/null +++ b/assets/js/115.17cb622d.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[115],{441:function(r,a,e){"use strict";e.r(a);var t=e(4),s=Object(t.a)({},(function(){var r=this,a=r._self._c;return a("ContentSlotsDistributor",{attrs:{"slot-key":r.$parent.slotKey}},[a("blockquote",[a("p",[r._v("建议直接参考链接内容")])]),r._v(" "),a("h2",{attrs:{id:"android-图形组件"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#android-图形组件"}},[r._v("#")]),r._v(" Android 图形组件")]),r._v(" "),a("p",[a("img",{attrs:{src:"https://cdn.jsdelivr.net/gh/jacky1234/picArchieve@master/uPic/20230528_162006_84h22U.jpg",alt:""}})]),r._v(" "),a("h3",{attrs:{id:"surface-and-surfaceholder"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#surface-and-surfaceholder"}},[r._v("#")]),r._v(" Surface and SurfaceHolder")]),r._v(" "),a("blockquote",[a("p",[a("a",{attrs:{href:"https://source.android.com/docs/core/graphics/arch-sh?hl=zh-cn",target:"_blank",rel:"noopener noreferrer"}},[r._v("Surface and SurfaceHolder"),a("OutboundLink")],1)])]),r._v(" "),a("h2",{attrs:{id:"链接"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#链接"}},[r._v("#")]),r._v(" 链接")]),r._v(" "),a("ul",[a("li",[a("a",{attrs:{href:"https://source.android.com/docs/core/graphics?hl=zh-cn",target:"_blank",rel:"noopener noreferrer"}},[r._v("android-graphics"),a("OutboundLink")],1)])])])}),[],!1,null,null,null);a.default=s.exports}}]); \ No newline at end of file diff --git a/assets/js/116.f3684c67.js b/assets/js/116.f3684c67.js new file mode 100644 index 0000000000..cd937d85fe --- /dev/null +++ b/assets/js/116.f3684c67.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[116],{442:function(s,t,a){"use strict";a.r(t);var n=a(4),e=Object(n.a)({},(function(){var s=this,t=s._self._c;return t("ContentSlotsDistributor",{attrs:{"slot-key":s.$parent.slotKey}},[t("p",[t("img",{attrs:{src:"https://cdn.jsdelivr.net/gh/jacky1234/picArchieve@master/uPic/20230806_163943_AIZ6ic.png",alt:""}})]),s._v(" "),t("blockquote",[t("p",[s._v("上述 queue 的定义如下: PendingPostQueue")])]),s._v(" "),t("p",[s._v("Feature:")]),s._v(" "),t("ul",[t("li",[s._v("批量处理消息")])]),s._v(" "),t("div",{staticClass:"language-java line-numbers-mode"},[t("pre",{pre:!0,attrs:{class:"language-java"}},[t("code",[t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("final")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("class")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("PendingPostQueue")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[s._v("@Nullable")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("private")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("PendingPost")]),s._v(" head"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[s._v("@Nullable")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("private")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("PendingPost")]),s._v(" tail"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n\n "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("PendingPostQueue")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("synchronized")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("void")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("enqueue")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("PendingPost")]),s._v(" pendingPost"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("if")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("pendingPost "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("==")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("null")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token comment"}},[s._v("// xxx")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("else")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("if")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("this")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),s._v("tail "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("!=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("null")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("this")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),s._v("tail"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),s._v("next "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" pendingPost"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("this")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),s._v("tail "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" pendingPost"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("else")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("if")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("this")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),s._v("head "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("!=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("null")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token comment"}},[s._v("// xxx")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("return")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("this")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),s._v("head "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("this")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),s._v("tail "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" pendingPost"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("this")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("notifyAll")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("synchronized")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("PendingPost")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("poll")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("PendingPost")]),s._v(" pendingPost "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("this")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),s._v("head"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("if")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("this")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),s._v("head "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("!=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("null")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("this")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),s._v("head "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("this")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),s._v("head"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),s._v("next"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("if")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("this")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),s._v("head "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("==")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("null")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("this")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),s._v("tail "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("null")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("return")]),s._v(" pendingPost"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("synchronized")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("PendingPost")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("poll")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("int")]),s._v(" maxMillisToWait"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("throws")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("InterruptedException")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("if")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("this")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),s._v("head "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("==")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("null")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("this")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("wait")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("long")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v("maxMillisToWait"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("return")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("this")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("poll")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n")])]),s._v(" "),t("div",{staticClass:"line-numbers-wrapper"},[t("span",{staticClass:"line-number"},[s._v("1")]),t("br"),t("span",{staticClass:"line-number"},[s._v("2")]),t("br"),t("span",{staticClass:"line-number"},[s._v("3")]),t("br"),t("span",{staticClass:"line-number"},[s._v("4")]),t("br"),t("span",{staticClass:"line-number"},[s._v("5")]),t("br"),t("span",{staticClass:"line-number"},[s._v("6")]),t("br"),t("span",{staticClass:"line-number"},[s._v("7")]),t("br"),t("span",{staticClass:"line-number"},[s._v("8")]),t("br"),t("span",{staticClass:"line-number"},[s._v("9")]),t("br"),t("span",{staticClass:"line-number"},[s._v("10")]),t("br"),t("span",{staticClass:"line-number"},[s._v("11")]),t("br"),t("span",{staticClass:"line-number"},[s._v("12")]),t("br"),t("span",{staticClass:"line-number"},[s._v("13")]),t("br"),t("span",{staticClass:"line-number"},[s._v("14")]),t("br"),t("span",{staticClass:"line-number"},[s._v("15")]),t("br"),t("span",{staticClass:"line-number"},[s._v("16")]),t("br"),t("span",{staticClass:"line-number"},[s._v("17")]),t("br"),t("span",{staticClass:"line-number"},[s._v("18")]),t("br"),t("span",{staticClass:"line-number"},[s._v("19")]),t("br"),t("span",{staticClass:"line-number"},[s._v("20")]),t("br"),t("span",{staticClass:"line-number"},[s._v("21")]),t("br"),t("span",{staticClass:"line-number"},[s._v("22")]),t("br"),t("span",{staticClass:"line-number"},[s._v("23")]),t("br"),t("span",{staticClass:"line-number"},[s._v("24")]),t("br"),t("span",{staticClass:"line-number"},[s._v("25")]),t("br"),t("span",{staticClass:"line-number"},[s._v("26")]),t("br"),t("span",{staticClass:"line-number"},[s._v("27")]),t("br"),t("span",{staticClass:"line-number"},[s._v("28")]),t("br"),t("span",{staticClass:"line-number"},[s._v("29")]),t("br"),t("span",{staticClass:"line-number"},[s._v("30")]),t("br"),t("span",{staticClass:"line-number"},[s._v("31")]),t("br"),t("span",{staticClass:"line-number"},[s._v("32")]),t("br"),t("span",{staticClass:"line-number"},[s._v("33")]),t("br"),t("span",{staticClass:"line-number"},[s._v("34")]),t("br"),t("span",{staticClass:"line-number"},[s._v("35")]),t("br"),t("span",{staticClass:"line-number"},[s._v("36")]),t("br"),t("span",{staticClass:"line-number"},[s._v("37")]),t("br"),t("span",{staticClass:"line-number"},[s._v("38")]),t("br"),t("span",{staticClass:"line-number"},[s._v("39")]),t("br"),t("span",{staticClass:"line-number"},[s._v("40")]),t("br"),t("span",{staticClass:"line-number"},[s._v("41")]),t("br"),t("span",{staticClass:"line-number"},[s._v("42")]),t("br"),t("span",{staticClass:"line-number"},[s._v("43")]),t("br"),t("span",{staticClass:"line-number"},[s._v("44")]),t("br"),t("span",{staticClass:"line-number"},[s._v("45")]),t("br"),t("span",{staticClass:"line-number"},[s._v("46")]),t("br"),t("span",{staticClass:"line-number"},[s._v("47")]),t("br"),t("span",{staticClass:"line-number"},[s._v("48")]),t("br"),t("span",{staticClass:"line-number"},[s._v("49")]),t("br")])])])}),[],!1,null,null,null);t.default=e.exports}}]); \ No newline at end of file diff --git a/assets/js/117.c3b4267e.js b/assets/js/117.c3b4267e.js new file mode 100644 index 0000000000..62cd40bc47 --- /dev/null +++ b/assets/js/117.c3b4267e.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[117],{443:function(t,e,r){"use strict";r.r(e);var s=r(4),a=Object(s.a)({},(function(){var t=this,e=t._self._c;return e("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[e("div",{staticClass:"custom-block tip"},[e("p",{staticClass:"custom-block-title"},[t._v("提示")]),t._v(" "),e("p",[t._v("android 的官网关于性能检查的概览: "),e("a",{attrs:{href:"https://developer.android.com/topic/performance/inspecting-overview",target:"_blank",rel:"noopener noreferrer"}},[t._v("inspecting-overview"),e("OutboundLink")],1)])]),t._v(" "),e("h2",{attrs:{id:"perfetto"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#perfetto"}},[t._v("#")]),t._v(" Perfetto")]),t._v(" "),e("p",[e("RouterLink",{attrs:{to:"/pages/29a4de/"}},[t._v("内网链接")])],1),t._v(" "),e("h2",{attrs:{id:"systrace"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#systrace"}},[t._v("#")]),t._v(" Systrace")])])}),[],!1,null,null,null);e.default=a.exports}}]); \ No newline at end of file diff --git a/assets/js/118.4674f502.js b/assets/js/118.4674f502.js new file mode 100644 index 0000000000..8a196a6e4c --- /dev/null +++ b/assets/js/118.4674f502.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[118],{444:function(e,t,a){"use strict";a.r(t);var s=a(4),r=Object(s.a)({},(function(){var e=this,t=e._self._c;return t("ContentSlotsDistributor",{attrs:{"slot-key":e.$parent.slotKey}},[t("h1",{attrs:{id:"perfetto"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#perfetto"}},[e._v("#")]),e._v(" Perfetto")]),e._v(" "),t("div",{staticClass:"custom-block tip"},[t("p",{staticClass:"custom-block-title"},[e._v("提示")]),e._v(" "),t("p",[e._v("perfetto is a tool that lets you collect performance information from Android devices via the Android Debug Bridge (ADB). Invoke the perfetto tool using the "),t("code",[e._v("adb shell perfetto")]),e._v(" ... command. perfetto uses various sources to collect performance traces from your device, such as:")]),e._v(" "),t("ul",[t("li",[e._v("ftrace for information from the kernel")]),e._v(" "),t("li",[e._v("atrace for user-space annotation in services and apps")]),e._v(" "),t("li",[e._v("heapprofd for native memory usage information of services and apps")])]),e._v(" "),t("p",[e._v("作为客户端开发工程师,更多的会注重在 Android 或者 iOS 客户端的优化,下面以 Android 为主要场景,进行说明\n更多内容参考: "),t("a",{attrs:{href:"https://developer.android.com/tools/perfetto",target:"_blank",rel:"noopener noreferrer"}},[e._v("android 官网给出的 perfetto command line 介绍"),t("OutboundLink")],1)]),e._v(" "),t("ul",[t("li",[t("a",{attrs:{href:"https://perfetto.dev/docs/",target:"_blank",rel:"noopener noreferrer"}},[e._v("Perfetto*"),t("OutboundLink")],1),e._v(" "),t("ul",[t("li",[t("a",{attrs:{href:"https://perfetto.dev/docs/reference/trace-config-proto",target:"_blank",rel:"noopener noreferrer"}},[e._v("Reference-Trace Config proto"),t("OutboundLink")],1)])])]),e._v(" "),t("li",[t("a",{attrs:{href:"https://perfetto.dev/docs/visualization/perfetto-ui",target:"_blank",rel:"noopener noreferrer"}},[e._v("perfetto-ui"),t("OutboundLink")],1)]),e._v(" "),t("li",[t("a",{attrs:{href:"https://developer.android.com/topic/performance/tracing",target:"_blank",rel:"noopener noreferrer"}},[e._v("android system trace 概览"),t("OutboundLink")],1)]),e._v(" "),t("li",[t("a",{attrs:{href:"https://blog.csdn.net/feelabclihu/article/details/126672666",target:"_blank",rel:"noopener noreferrer"}},[e._v("Perfetto 分析进阶-CSDN"),t("OutboundLink")],1)])])]),e._v(" "),t("h2",{attrs:{id:"custom-events"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#custom-events"}},[e._v("#")]),e._v(" custom-events")]),e._v(" "),t("ol",[t("li",[e._v("perfetto 跟 systrace 同样也支持自定义事件。 可以参考 "),t("a",{attrs:{href:"https://developer.android.com/topic/performance/tracing/custom-events?hl=zh-cn#java",target:"_blank",rel:"noopener noreferrer"}},[e._v("custom-events"),t("OutboundLink")],1)]),e._v(" "),t("li",[e._v("使用 perfetto 分析自定义事件时,你可能需要配置 atrace,相关的内容可见: "),t("a",{attrs:{href:"https://perfetto.dev/docs/data-sources/atrace#traceconfig",target:"_blank",rel:"noopener noreferrer"}},[e._v("ATrace: Android system and app trace events"),t("OutboundLink")],1)])]),e._v(" "),t("h2",{attrs:{id:"trace-config"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#trace-config"}},[e._v("#")]),e._v(" trace config")]),e._v(" "),t("blockquote",[t("p",[e._v("这里给出配置的 demo 定义, 将如下内容保存到文件中,比如 config.pbtx 然后运行脚本 "),t("code",[e._v("./record_android_trace -o .perfetto-trace -c config.pbtx")]),e._v("\n此例子参考 "),t("a",{attrs:{href:"https://perfetto.dev/docs/quickstart/android-tracing",target:"_blank",rel:"noopener noreferrer"}},[e._v("Quickstart: Record traces on Android"),t("OutboundLink")],1)])]),e._v(" "),t("div",{staticClass:"language-pbtx line-numbers-mode"},[t("pre",{pre:!0,attrs:{class:"language-text"}},[t("code",[e._v('duration_ms: 10000\n\nbuffers {\n size_kb: 65536\n fill_policy: RING_BUFFER\n}\n\ndata_sources: {\n config {\n name: "linux.ftrace"\n ftrace_config {\n ftrace_events: "sched/sched_switch"\n ftrace_events: "power/suspend_resume"\n ftrace_events: "sched/sched_process_exit"\n ftrace_events: "sched/sched_process_free"\n ftrace_events: "task/task_newtask"\n ftrace_events: "task/task_rename"\n ftrace_events: "ftrace/print"\n atrace_categories: "sched"\n atrace_categories: "freq"\n atrace_categories: "idle"\n atrace_categories: "am"\n atrace_categories: "wm"\n atrace_categories: "gfx"\n atrace_categories: "view"\n atrace_categories: "binder_driver"\n atrace_categories: "hal"\n atrace_categories: "dalvik"\n atrace_categories: "webview"\n atrace_categories: "camera"\n atrace_categories: "power"\n atrace_categories: "res"\n atrace_categories: "memory"\n }\n }\n}\ndata_sources: {\n config {\n name: "linux.process_stats"\n target_buffer: 1\n process_stats_config {\n scan_all_processes_on_start: true\n }\n }\n}\n')])]),e._v(" "),t("div",{staticClass:"line-numbers-wrapper"},[t("span",{staticClass:"line-number"},[e._v("1")]),t("br"),t("span",{staticClass:"line-number"},[e._v("2")]),t("br"),t("span",{staticClass:"line-number"},[e._v("3")]),t("br"),t("span",{staticClass:"line-number"},[e._v("4")]),t("br"),t("span",{staticClass:"line-number"},[e._v("5")]),t("br"),t("span",{staticClass:"line-number"},[e._v("6")]),t("br"),t("span",{staticClass:"line-number"},[e._v("7")]),t("br"),t("span",{staticClass:"line-number"},[e._v("8")]),t("br"),t("span",{staticClass:"line-number"},[e._v("9")]),t("br"),t("span",{staticClass:"line-number"},[e._v("10")]),t("br"),t("span",{staticClass:"line-number"},[e._v("11")]),t("br"),t("span",{staticClass:"line-number"},[e._v("12")]),t("br"),t("span",{staticClass:"line-number"},[e._v("13")]),t("br"),t("span",{staticClass:"line-number"},[e._v("14")]),t("br"),t("span",{staticClass:"line-number"},[e._v("15")]),t("br"),t("span",{staticClass:"line-number"},[e._v("16")]),t("br"),t("span",{staticClass:"line-number"},[e._v("17")]),t("br"),t("span",{staticClass:"line-number"},[e._v("18")]),t("br"),t("span",{staticClass:"line-number"},[e._v("19")]),t("br"),t("span",{staticClass:"line-number"},[e._v("20")]),t("br"),t("span",{staticClass:"line-number"},[e._v("21")]),t("br"),t("span",{staticClass:"line-number"},[e._v("22")]),t("br"),t("span",{staticClass:"line-number"},[e._v("23")]),t("br"),t("span",{staticClass:"line-number"},[e._v("24")]),t("br"),t("span",{staticClass:"line-number"},[e._v("25")]),t("br"),t("span",{staticClass:"line-number"},[e._v("26")]),t("br"),t("span",{staticClass:"line-number"},[e._v("27")]),t("br"),t("span",{staticClass:"line-number"},[e._v("28")]),t("br"),t("span",{staticClass:"line-number"},[e._v("29")]),t("br"),t("span",{staticClass:"line-number"},[e._v("30")]),t("br"),t("span",{staticClass:"line-number"},[e._v("31")]),t("br"),t("span",{staticClass:"line-number"},[e._v("32")]),t("br"),t("span",{staticClass:"line-number"},[e._v("33")]),t("br"),t("span",{staticClass:"line-number"},[e._v("34")]),t("br"),t("span",{staticClass:"line-number"},[e._v("35")]),t("br"),t("span",{staticClass:"line-number"},[e._v("36")]),t("br"),t("span",{staticClass:"line-number"},[e._v("37")]),t("br"),t("span",{staticClass:"line-number"},[e._v("38")]),t("br"),t("span",{staticClass:"line-number"},[e._v("39")]),t("br"),t("span",{staticClass:"line-number"},[e._v("40")]),t("br"),t("span",{staticClass:"line-number"},[e._v("41")]),t("br"),t("span",{staticClass:"line-number"},[e._v("42")]),t("br"),t("span",{staticClass:"line-number"},[e._v("43")]),t("br"),t("span",{staticClass:"line-number"},[e._v("44")]),t("br"),t("span",{staticClass:"line-number"},[e._v("45")]),t("br")])]),t("h4",{attrs:{id:"gfx"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#gfx"}},[e._v("#")]),e._v(" gfx")]),e._v(" "),t("p",[t("code",[e._v('atrace_categories: "gfx"')]),e._v(" 是 Perfetto 中的配置选项,用于指定要跟踪的 Android 图形渲染相关事件的类别。")]),e._v(" "),t("p",[e._v("在 Android 中,gfx 代表图形渲染子系统,它负责处理应用程序的图形渲染和显示。通过启用 "),t("code",[e._v('atrace_categories: "gfx"')]),e._v(",Perfetto 将记录与图形渲染相关的事件,如 GPU 绘制、SurfaceFlinger 操作、GPU 状态变化等。")]),e._v(" "),t("p",[e._v("这样的跟踪对于性能分析和图形渲染优化非常有用,可以帮助开发人员了解图形渲染的性能瓶颈,以及查找和解决与图形渲染相关的问题。")]),e._v(" "),t("p",[e._v("请注意,gfx 是 Perfetto 中预定义的标签,表示图形渲染子系统的跟踪事件。除了 gfx,还有其他可用的预定义标签,用于指定不同的跟踪事件类别。你可以根据需要在配置文件中添加其他标签,以启用不同类型的跟踪数据收集。")]),e._v(" "),t("h2",{attrs:{id:"analysis"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#analysis"}},[e._v("#")]),e._v(" analysis")]),e._v(" "),t("div",{staticClass:"custom-block tip"},[t("p",{staticClass:"custom-block-title"},[e._v("提示")]),e._v(" "),t("p",[e._v("建议查看官网 "),t("a",{attrs:{href:"https://perfetto.dev/docs/analysis/trace-processor#ancestor-slice",target:"_blank",rel:"noopener noreferrer"}},[e._v("Trace analysis"),t("OutboundLink")],1),e._v(" 一节")])]),e._v(" "),t("h3",{attrs:{id:"sql"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#sql"}},[e._v("#")]),e._v(" sql")]),e._v(" "),t("blockquote",[t("p",[t("a",{attrs:{href:"https://perfetto.dev/docs/analysis/sql-tables",target:"_blank",rel:"noopener noreferrer"}},[e._v("sql table"),t("OutboundLink")],1)])]),e._v(" "),t("h4",{attrs:{id:"示例"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#示例"}},[e._v("#")]),e._v(" 示例")]),e._v(" "),t("p",[e._v("一、to get a list of all the threads which emitted a measure slice.")]),e._v(" "),t("blockquote",[t("p",[e._v("see: "),t("a",{attrs:{href:"https://perfetto.dev/docs/analysis/trace-processor#thread-and-process-tables",target:"_blank",rel:"noopener noreferrer"}},[e._v("https://perfetto.dev/docs/analysis/trace-processor#thread-and-process-tables"),t("OutboundLink")],1)])]),e._v(" "),t("div",{staticClass:"language-sql line-numbers-mode"},[t("pre",{pre:!0,attrs:{class:"language-sql"}},[t("code",[t("span",{pre:!0,attrs:{class:"token keyword"}},[e._v("SELECT")]),e._v(" thread"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(".")]),e._v("name "),t("span",{pre:!0,attrs:{class:"token keyword"}},[e._v("AS")]),e._v(" thread_name\n"),t("span",{pre:!0,attrs:{class:"token keyword"}},[e._v("FROM")]),e._v(" slice\n"),t("span",{pre:!0,attrs:{class:"token keyword"}},[e._v("JOIN")]),e._v(" thread_track "),t("span",{pre:!0,attrs:{class:"token keyword"}},[e._v("ON")]),e._v(" slice"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(".")]),e._v("track_id "),t("span",{pre:!0,attrs:{class:"token operator"}},[e._v("=")]),e._v(" thread_track"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(".")]),e._v("id\n"),t("span",{pre:!0,attrs:{class:"token keyword"}},[e._v("JOIN")]),e._v(" thread "),t("span",{pre:!0,attrs:{class:"token keyword"}},[e._v("USING")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("(")]),e._v("utid"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(")")]),e._v("\n"),t("span",{pre:!0,attrs:{class:"token keyword"}},[e._v("WHERE")]),e._v(" slice"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(".")]),e._v("name "),t("span",{pre:!0,attrs:{class:"token operator"}},[e._v("=")]),e._v(" "),t("span",{pre:!0,attrs:{class:"token string"}},[e._v("'measure'")]),e._v("\n"),t("span",{pre:!0,attrs:{class:"token keyword"}},[e._v("GROUP")]),e._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[e._v("BY")]),e._v(" thread_name\n")])]),e._v(" "),t("div",{staticClass:"line-numbers-wrapper"},[t("span",{staticClass:"line-number"},[e._v("1")]),t("br"),t("span",{staticClass:"line-number"},[e._v("2")]),t("br"),t("span",{staticClass:"line-number"},[e._v("3")]),t("br"),t("span",{staticClass:"line-number"},[e._v("4")]),t("br"),t("span",{staticClass:"line-number"},[e._v("5")]),t("br"),t("span",{staticClass:"line-number"},[e._v("6")]),t("br")])]),t("p",[e._v("查询逻辑解释如下:")]),e._v(" "),t("ul",[t("li",[t("code",[e._v("FROM slice")]),e._v(":从 slice 表中选择数据作为查询的主要来源。")]),e._v(" "),t("li",[t("code",[e._v("JOIN thread_track ON slice.track_id = thread_track.id")]),e._v(":通过 JOIN 操作将 slice 表与 thread_track 表关联,以获取关于线程轨迹(track_id)的信息。")]),e._v(" "),t("li",[t("code",[e._v("JOIN thread USING(utid)")]),e._v(":通过 JOIN 操作将 thread 表与 thread_track 表关联,以获取关于线程(thread.name)的信息。这里使用 USING(utid) 来指定连接的列为 utid,表示 thread_track 表和 thread 表通过 utid 字段进行连接。")]),e._v(" "),t("li",[t("code",[e._v("WHERE slice.name = 'measure'")]),e._v(":筛选 slice.name 为 'measure' 的记录,即找到符合条件的事件。")]),e._v(" "),t("li",[t("code",[e._v("GROUP BY thread_name")]),e._v(":按照 thread_name 字段(即线程名)对结果进行分组,以汇总每个线程中包含名为 'measure' 的事件。")])]),e._v(" "),t("p",[e._v("最终查询的结果将返回符合条件的 slice.name 为 'measure' 的事件,并按照线程名进行分组。")]),e._v(" "),t("hr"),e._v(" "),t("p",[e._v("二、查询 slice name 以 "),t("code",[e._v("jack)")]),e._v(" 开头且限定查询到的 "),t("code",[e._v("main thread")]),e._v(" 下面的 slice rows,并按照 slice.desc 降序排序")]),e._v(" "),t("div",{staticClass:"language-sql line-numbers-mode"},[t("pre",{pre:!0,attrs:{class:"language-sql"}},[t("code",[t("span",{pre:!0,attrs:{class:"token keyword"}},[e._v("SELECT")]),e._v(" "),t("span",{pre:!0,attrs:{class:"token operator"}},[e._v("*")]),e._v("\n"),t("span",{pre:!0,attrs:{class:"token keyword"}},[e._v("FROM")]),e._v(" slice\n"),t("span",{pre:!0,attrs:{class:"token keyword"}},[e._v("JOIN")]),e._v(" thread_track "),t("span",{pre:!0,attrs:{class:"token keyword"}},[e._v("ON")]),e._v(" slice"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(".")]),e._v("track_id "),t("span",{pre:!0,attrs:{class:"token operator"}},[e._v("=")]),e._v(" thread_track"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(".")]),e._v("id\n"),t("span",{pre:!0,attrs:{class:"token keyword"}},[e._v("JOIN")]),e._v(" thread "),t("span",{pre:!0,attrs:{class:"token keyword"}},[e._v("USING")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("(")]),e._v("utid"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(")")]),e._v("\n"),t("span",{pre:!0,attrs:{class:"token keyword"}},[e._v("WHERE")]),e._v(" slice"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(".")]),e._v("name "),t("span",{pre:!0,attrs:{class:"token operator"}},[e._v("LIKE")]),e._v(" "),t("span",{pre:!0,attrs:{class:"token string"}},[e._v("'jack)%'")]),e._v("\n"),t("span",{pre:!0,attrs:{class:"token operator"}},[e._v("AND")]),e._v(" thread"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(".")]),e._v("name "),t("span",{pre:!0,attrs:{class:"token operator"}},[e._v("=")]),e._v(" "),t("span",{pre:!0,attrs:{class:"token string"}},[e._v("'<主线程名称>'")]),e._v("\n"),t("span",{pre:!0,attrs:{class:"token keyword"}},[e._v("ORDER")]),e._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[e._v("BY")]),e._v(" slice"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(".")]),e._v("dur "),t("span",{pre:!0,attrs:{class:"token keyword"}},[e._v("DESC")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(";")]),e._v("\n")])]),e._v(" "),t("div",{staticClass:"line-numbers-wrapper"},[t("span",{staticClass:"line-number"},[e._v("1")]),t("br"),t("span",{staticClass:"line-number"},[e._v("2")]),t("br"),t("span",{staticClass:"line-number"},[e._v("3")]),t("br"),t("span",{staticClass:"line-number"},[e._v("4")]),t("br"),t("span",{staticClass:"line-number"},[e._v("5")]),t("br"),t("span",{staticClass:"line-number"},[e._v("6")]),t("br"),t("span",{staticClass:"line-number"},[e._v("7")]),t("br")])]),t("p",[e._v("查询到的结果如下:\n"),t("img",{attrs:{src:"https://cdn.jsdelivr.net/gh/jacky1234/picArchieve@master/uPic/20230726_120125_O1XM95.png",alt:""}})]),e._v(" "),t("h2",{attrs:{id:"问一问"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#问一问"}},[e._v("#")]),e._v(" 问一问")]),e._v(" "),t("blockquote",[t("p",[e._v("一、在 thread_track 我们查出来有一列为 utid, 上面的 26460 看起来跟 utid 又不是一个意思.如下图所示")])]),e._v(" "),t("p",[t("img",{attrs:{src:"https://cdn.jsdelivr.net/gh/jacky1234/picArchieve@master/uPic/20230723_214907_y37V3d.png",alt:""}})]),e._v(" "),t("ul",[t("li",[t("code",[e._v("TID(Thread ID)")]),e._v(':TID 是操作系统中用来唯一标识线程的数字标识符。每个线程都有一个唯一的 TID。在 Perfetto UI 的时间轴上,你会看到类似 "xxx 26460" 这样的标签,其中 "26460" 就是这个事件所属的线程 ID(TID)。')]),e._v(" "),t("li",[t("code",[e._v("utid(Unified Thread ID")]),e._v(":utid 是 Perfetto 中使用的线程标识符,它是在跨平台、跨内核和跨进程的场景下使用的。在某些情况下,Perfetto 可能会使用 utid 代替 TID 来唯一标识线程。utid 可以确保在线程切换和跨进程传递时保持唯一。通常,utid 会在跟踪开始时被分配,并与 TID 相关联。")])]),e._v(" "),t("p",[e._v('因此,虽然 "xxx 26460" 这样的标签中的 "26460" 确实代表线程 ID(TID),但在 Perfetto 中,utid 和 TID 之间有着关联。Perfetto 使用 utid 来确保在线程切换和跨进程传递时,正确地标识和追踪线程。在 Perfetto UI 中,你可以根据线程的 utid 或线程 ID 来筛选和查看特定线程的事件。')]),e._v(" "),t("p",[e._v("二、DisplayHAL jank")]),e._v(" "),t("div",{staticClass:"language- line-numbers-mode"},[t("pre",{pre:!0,attrs:{class:"language-text"}},[t("code",[e._v("DisplayHAL jank refers to the case where SurfaceFlinger finished its work and sent the frame down to the HAL on time, but the frame wasn’t presented on the vsync. It was presented on the next vsync. It could be that SurfaceFlinger did not give enough time for the HAL’s work or it could be that there was a genuine delay in the HAL’s work.\n")])]),e._v(" "),t("div",{staticClass:"line-numbers-wrapper"},[t("span",{staticClass:"line-number"},[e._v("1")]),t("br")])]),t("p",[e._v('"DisplayHAL jank" 是指 SurfaceFlinger 在规定时间内完成工作并将帧传递给硬件抽象层(DisplayHAL),但该帧没有在垂直同步期间(vsync)被显示。而是在下一个 vsync 时刻才被显示。这可能是因为 SurfaceFlinger 没有给予 DisplayHAL 充足的时间来完成其工作,或者可能是 DisplayHAL 的工作出现了真正的延迟。')]),e._v(" "),t("p",[e._v("解释如下:")]),e._v(" "),t("ol",[t("li",[e._v("SurfaceFlinger 是 Android 系统中负责组合和渲染所有应用程序窗口的组件。当 SurfaceFlinger 完成渲染并将帧发送给 DisplayHAL 时,它需要根据设备的垂直同步信号来准确地显示帧。")]),e._v(" "),t("li",[e._v('垂直同步(vsync)是一个硬件信号,指示显示器在下一个刷新周期开始时显示帧。设备通常以固定的帧速率刷新显示,比如 60 Hz。当帧被错过,会导致显示延迟,即 "DisplayHAL jank"。')]),e._v(" "),t("li",[e._v('"DisplayHAL jank" 可能是由于 SurfaceFlinger 没有给予 DisplayHAL 充足的时间来完成帧的显示准备。这可能导致帧错过当前的 vsync 时刻,被推迟到下一个 vsync 时刻。')]),e._v(" "),t("li",[e._v("另一种可能是由于 DisplayHAL 本身的处理过程出现了延迟,导致帧无法及时被显示。")])]),e._v(" "),t("p",[e._v('为了解决 "DisplayHAL jank",需要进一步分析和优化 SurfaceFlinger 和 DisplayHAL 之间的交互和工作流程。通过减少处理时间、优化资源利用和避免冲突,可以降低 "DisplayHAL jank" 的发生频率,从而提高 Android 设备的流畅性和显示性能。')])])}),[],!1,null,null,null);t.default=r.exports}}]); \ No newline at end of file diff --git a/assets/js/119.5d33a787.js b/assets/js/119.5d33a787.js new file mode 100644 index 0000000000..c44c25bbfb --- /dev/null +++ b/assets/js/119.5d33a787.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[119],{445:function(t,a,e){"use strict";e.r(a);var n=e(4),r=Object(n.a)({},(function(){var t=this,a=t._self._c;return a("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[a("h2",{attrs:{id:"背景"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#背景"}},[t._v("#")]),t._v(" 背景")]),t._v(" "),a("h2",{attrs:{id:"asynclayoutinflater"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#asynclayoutinflater"}},[t._v("#")]),t._v(" AsyncLayoutInflater")]),t._v(" "),a("blockquote",[a("p",[a("a",{attrs:{href:"https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:asynclayoutinflater/asynclayoutinflater/src/main/java/androidx/asynclayoutinflater/view/AsyncLayoutInflater.java;l=68?q=asyncLayoutInfla&sq=",target:"_blank",rel:"noopener noreferrer"}},[t._v("源码"),a("OutboundLink")],1)])]),t._v(" "),a("p",[t._v("AsyncLayoutInflater 代码不多,原理也很简单:")]),t._v(" "),a("ul",[a("li",[t._v("创建 AsyncLayoutInflater 时异步线程启动,然后被阻塞队列 take 方法阻塞。")]),t._v(" "),a("li",[t._v("通过 inflate 方法传入构造 View 的信息与回调对象,然后从对象池中取出 InflateRequest 对象进行信息更新,然后放入阻塞队列中。")]),t._v(" "),a("li",[t._v("阻塞队列 take 获取到元素,异步线程开始执行 View 的创建,并在执行完成后发送消息给 Handler。")]),t._v(" "),a("li",[t._v("Handler 回调主线程,执行 OnInflateFinishedListener 回调对象,然后回收 InflateRequest 对象。")])]),t._v(" "),a("p",[t._v("注意事项")]),t._v(" "),a("h2",{attrs:{id:"链接"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#链接"}},[t._v("#")]),t._v(" 链接")]),t._v(" "),a("ul",[a("li",[a("a",{attrs:{href:"https://cloud.tencent.com/developer/article/1190964",target:"_blank",rel:"noopener noreferrer"}},[t._v("Android AsyncLayoutInflater 限制及改进"),a("OutboundLink")],1)])])])}),[],!1,null,null,null);a.default=r.exports}}]); \ No newline at end of file diff --git a/assets/js/12.d7b1a59f.js b/assets/js/12.d7b1a59f.js new file mode 100644 index 0000000000..1165353cbe --- /dev/null +++ b/assets/js/12.d7b1a59f.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[12,27,28,29,33],{256:function(t,e,a){},257:function(t,e,a){},258:function(t,e,a){},264:function(t,e,a){},267:function(t,e,a){"use strict";a.r(e);a(25);var s={props:{category:{type:String,default:""},tag:{type:String,default:""},currentPage:{type:Number,default:1},perPage:{type:Number,default:10}},data:()=>({sortPosts:[],postListOffsetTop:0}),created(){this.setPosts()},mounted(){},watch:{currentPage(){this.$route.query.p!=this.currentPage&&this.$router.push({query:{...this.$route.query,p:this.currentPage}}),this.setPosts()},category(){this.setPosts()},tag(){this.setPosts()}},methods:{setPosts(){const t=this.currentPage,e=this.perPage;let a=[];a=this.category?this.$groupPosts.categories[this.category]:this.tag?this.$groupPosts.tags[this.tag]:this.$sortPosts,this.sortPosts=a.slice((t-1)*e,t*e)}}},r=(a(272),a(4)),n=Object(r.a)(s,(function(){var t=this,e=t._self._c;return e("div",{ref:"postList",staticClass:"post-list"},[e("transition-group",{attrs:{tag:"div",name:"post"}},t._l(t.sortPosts,(function(a){return e("div",{key:a.key,staticClass:"post card-box",class:a.frontmatter.sticky&&"iconfont icon-zhiding"},[e("div",{staticClass:"title-wrapper"},[e("h2",[e("router-link",{attrs:{to:a.path}},[t._v("\n "+t._s(a.title)+"\n "),a.frontmatter.titleTag?e("span",{staticClass:"title-tag"},[t._v(t._s(a.frontmatter.titleTag))]):t._e()])],1),t._v(" "),e("div",{staticClass:"article-info"},[a.author&&a.author.href?e("a",{staticClass:"iconfont icon-touxiang",attrs:{title:"作者",target:"_blank",href:a.author.href}},[t._v(t._s(a.author.name?a.author.name:a.author))]):a.author?e("span",{staticClass:"iconfont icon-touxiang",attrs:{title:"作者"}},[t._v(t._s(a.author.name?a.author.name:a.author))]):t._e(),t._v(" "),a.frontmatter.date?e("span",{staticClass:"iconfont icon-riqi",attrs:{title:"创建时间"}},[t._v(t._s(a.frontmatter.date.split(" ")[0]))]):t._e(),t._v(" "),!1!==t.$themeConfig.category&&a.frontmatter.categories?e("span",{staticClass:"iconfont icon-wenjian",attrs:{title:"分类"}},t._l(a.frontmatter.categories,(function(a,s){return e("router-link",{key:s,attrs:{to:"/categories/?category="+encodeURIComponent(a)}},[t._v(t._s(a))])})),1):t._e(),t._v(" "),!1!==t.$themeConfig.tag&&a.frontmatter.tags&&a.frontmatter.tags[0]?e("span",{staticClass:"iconfont icon-biaoqian tags",attrs:{title:"标签"}},t._l(a.frontmatter.tags,(function(a,s){return e("router-link",{key:s,attrs:{to:"/tags/?tag="+encodeURIComponent(a)}},[t._v(t._s(a))])})),1):t._e()])]),t._v(" "),a.excerpt?e("div",{staticClass:"excerpt-wrapper"},[e("div",{staticClass:"excerpt",domProps:{innerHTML:t._s(a.excerpt)}}),t._v(" "),e("router-link",{staticClass:"readmore iconfont icon-jiantou-you",attrs:{to:a.path}},[t._v("阅读全文")])],1):t._e()])})),0)],1)}),[],!1,null,null,null);e.default=n.exports},268:function(t,e,a){"use strict";a.r(e);var s={props:{total:{type:Number,default:10},perPage:{type:Number,default:10},currentPage:{type:Number,default:1}},computed:{pages(){return Math.ceil(this.total/this.perPage)}},methods:{threeNum(){let t=3;const e=this.currentPage,a=this.pages;return t=e<3?3:e>a-3?a-2:e,t},goPrex(){let t=this.currentPage;t>1&&this.handleEmit(--t)},goNext(){let t=this.currentPage;t3,expression:"currentPage > 3"}],staticClass:"ellipsis ell-two",attrs:{title:"上两页"},on:{click:function(e){return t.goIndex(t.currentPage-2)}}}),t._v(" "),e("span",{directives:[{name:"show",rawName:"v-show",value:t.currentPage<=3,expression:"currentPage <= 3"}],staticClass:"card-box",class:{active:2===t.currentPage},on:{click:function(e){return t.goIndex(2)}}},[t._v("2")]),t._v(" "),e("span",{staticClass:"card-box",class:{active:t.currentPage>=3&&t.currentPage<=t.pages-2},on:{click:function(e){t.goIndex(t.threeNum())}}},[t._v(t._s(t.threeNum()))]),t._v(" "),e("span",{directives:[{name:"show",rawName:"v-show",value:t.currentPage=t.pages-2,expression:"currentPage >= pages - 2"}],staticClass:"card-box",class:{active:t.currentPage===t.pages-1},on:{click:function(e){return t.goIndex(t.pages-1)}}},[t._v(t._s(t.pages-1))]),t._v(" "),e("span",{staticClass:"card-box",class:{active:t.currentPage===t.pages},on:{click:function(e){return t.goIndex(t.pages)}}},[t._v(t._s(t.pages))])]),t._v(" "),e("span",{staticClass:"card-box next iconfont icon-jiantou-you",class:{disabled:t.currentPage===t.pages},on:{click:function(e){return t.goNext()}}},[e("p",[t._v("下一页")])])])}),[],!1,null,null,null);e.default=n.exports},270:function(t,e,a){"use strict";a.r(e);a(271);var s=a(4),r=Object(s.a)({},(function(){var t=this._self._c;return t("div",{staticClass:"main-wrapper"},[t("div",{staticClass:"main-left"},[this._t("mainLeft")],2),this._v(" "),t("div",{staticClass:"main-right"},[this._t("mainRight")],2)])}),[],!1,null,null,null);e.default=r.exports},271:function(t,e,a){"use strict";a(256)},272:function(t,e,a){"use strict";a(257)},273:function(t,e,a){"use strict";a(258)},290:function(t,e,a){"use strict";a(264)},299:function(t,e,a){},301:function(t,e,a){"use strict";a.r(e);a(25);var s={props:{tag:{type:String,default:""},tagsData:{type:Array,default:[]},length:{type:[String,Number],default:"all"}},data:()=>({tagBgColor:["#11a8cd","#F8B26A","#67CC86","#E15B64","#F47E60","#849B87"],tagStyleList:[]}),created(){for(let t=0,e=this.tags.length;tt.length?e("router-link",{attrs:{to:"/tags/"}},[t._v("更多...")]):t._e()],2)],1)}),[],!1,null,null,null);e.default=n.exports},322:function(t,e,a){"use strict";a(299)},343:function(t,e,a){"use strict";a.r(e);var s=a(270),r=a(267),n=a(268),i=a(301),o={data:()=>({tag:"",total:0,perPage:10,currentPage:1}),components:{MainLayout:s.default,PostList:r.default,Pagination:n.default,TagsBar:i.default},mounted(){const t=this.$route.query.tag;t?(this.tag=t,this.total=this.$groupPosts.tags[t].length):this.total=this.$sortPosts.length,this.$route.query.p&&(this.currentPage=Number(this.$route.query.p))},methods:{handlePagination(t){this.currentPage=t}},watch:{"$route.query.tag"(t){this.tag=t?decodeURIComponent(t):"",this.tag?this.total=this.$groupPosts.tags[this.tag].length:this.total=this.$sortPosts.length,this.currentPage=1}}},c=(a(322),a(4)),l=Object(c.a)(o,(function(){var t=this,e=t._self._c;return e("div",{staticClass:"custom-page tags-page"},[e("MainLayout",{scopedSlots:t._u([{key:"mainLeft",fn:function(){return[t.$categoriesAndTags.tags.length?e("TagsBar",{attrs:{tagsData:t.$categoriesAndTags.tags,tag:t.tag}}):t._e(),t._v(" "),e("PostList",{attrs:{currentPage:t.currentPage,perPage:t.perPage,tag:t.tag}}),t._v(" "),e("Pagination",{directives:[{name:"show",rawName:"v-show",value:Math.ceil(t.total/t.perPage)>1,expression:"Math.ceil(total / perPage) > 1"}],attrs:{total:t.total,perPage:t.perPage,currentPage:t.currentPage},on:{getCurrentPage:t.handlePagination}})]},proxy:!0},{key:"mainRight",fn:function(){return[t.$categoriesAndTags.tags.length?e("TagsBar",{attrs:{tagsData:t.$categoriesAndTags.tags,tag:t.tag}}):t._e()]},proxy:!0}])})],1)}),[],!1,null,null,null);e.default=l.exports}}]); \ No newline at end of file diff --git a/assets/js/120.ab526730.js b/assets/js/120.ab526730.js new file mode 100644 index 0000000000..06f039e253 --- /dev/null +++ b/assets/js/120.ab526730.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[120],{446:function(v,_,r){"use strict";r.r(_);var t=r(4),e=Object(t.a)({},(function(){var v=this,_=v._self._c;return _("ContentSlotsDistributor",{attrs:{"slot-key":v.$parent.slotKey}},[_("h2",{attrs:{id:"预热内容"}},[_("a",{staticClass:"header-anchor",attrs:{href:"#预热内容"}},[v._v("#")]),v._v(" 预热内容")]),v._v(" "),_("h3",{attrs:{id:"html-的预渲染原理"}},[_("a",{staticClass:"header-anchor",attrs:{href:"#html-的预渲染原理"}},[v._v("#")]),v._v(" HTML 的预渲染原理")]),v._v(" "),_("p",[_("img",{attrs:{src:"https://cdn.jsdelivr.net/gh/jacky1234/picArchieve@master/uPic/20230822_105129_H9KgEg.png",alt:"html-pre-render"}})]),v._v(" "),_("p",[v._v("预渲染工具是一种用于优化网站性能和搜索引擎优化(SEO)的技术,它的基本原理如下:")]),v._v(" "),_("ol",[_("li",[v._v("构建和打包静态资源: 开发者首先创建一个网站,然后使用构建工具(例如 Webpack、Parcel 等)将网站的所有资源(HTML、CSS、JavaScript、图片等)打包到一个或多个静态文件中。")]),v._v(" "),_("li",[v._v("启动本地 Express 静态服务: 预渲染工具会在本地启动一个 Express 静态服务,这个服务的作用是托管已打包好的静态资源文件。这样,用户可以通过访问本地服务来加载网站内容。")]),v._v(" "),_("li",[v._v("启动无头浏览器(例如 Puppeteer): 预渲染工具会启动一个无头浏览器,例如 Puppeteer。无头浏览器是一个能够以程序化方式运行的浏览器,通常用于进行自动化测试和页面截图等任务。")]),v._v(" "),_("li",[v._v("浏览器请求网页: 无头浏览器会向本地 Express 静态服务发送请求,请求要渲染的网页。这个请求包括网页的 URL 地址。")]),v._v(" "),_("li",[v._v("网页运行时请求首屏接口: 当无头浏览器加载网页后,网页的 JavaScript 代码会运行。通常,网页会通过 API 请求数据,这些数据用于渲染网页的内容。在预渲染中,网页通常会请求首屏接口,获取要在首屏显示的数据。")]),v._v(" "),_("li",[v._v("渲染首屏内容: 接收到首屏接口返回的数据后,网页会使用这些数据来渲染网页的首屏内容。这个内容可能包括文章、产品信息、图片等。")]),v._v(" "),_("li",[v._v("无头浏览器截屏: 一旦首屏内容被渲染出来,无头浏览器会执行截屏操作,将当前网页的内容截取为一张图片。")]),v._v(" "),_("li",[v._v("替换原 HTML: 最后,生成的图片会被嵌入到原始 HTML 中,替换掉原来的 HTML。这样,用户在访问网站时,会首先看到包含内容的首屏图片,而不需要等待网页的 JavaScript 加载和执行。")])]),v._v(" "),_("p",[v._v("通过这个过程,预渲染工具能够显著提高网站的加载速度,因为用户无需等待 JavaScript 代码执行完毕才能看到内容。同时,搜索引擎爬虫也能够直接看到渲染后的内容,从而提高了网站的 SEO 性能。")]),v._v(" "),_("h2",{attrs:{id:"播放质量指标"}},[_("a",{staticClass:"header-anchor",attrs:{href:"#播放质量指标"}},[v._v("#")]),v._v(" 播放质量指标")]),v._v(" "),_("p",[v._v("在介绍我们的技术优化实现之前,先来看一下如何衡量用户体验。")]),v._v(" "),_("p",[v._v("我们将用户体验拆解为播放源质量、交互体验和观看体验三个方向,而用户体验的质量指标一般会分成三个层次:")]),v._v(" "),_("ul",[_("li",[_("code",[v._v("QoS(Quality of Service)")]),v._v(":即播放器本身能够量化的技术指标,主要包括 4 个方面:\n"),_("ul",[_("li",[v._v("播放失败率:基于起播和未起播两个环节,涉及大盘级的播放失败率和起播率。")]),v._v(" "),_("li",[v._v("起播时间:和用户播控时间点相关,涉及首帧时间和 seek 后的起播时间。")]),v._v(" "),_("li",[v._v("卡顿指标:卡顿是影响用户观看体验的一个重要因素,卡顿指标包括卡顿渗透率、百秒卡顿时长、卡顿次数等。")])])]),v._v(" "),_("li",[_("code",[v._v("QoE(Quality of Experience)")]),v._v(":在播放器可以监控到的 QoS 指标之上,我们加入了真实场景中用户行为侧跟业务相关的数据,包括播放次数、播放时长、完播率、投稿量以及投稿率。")]),v._v(" "),_("li",[v._v("业务数据:再往上延伸,每一个业务最终关注的是 DAU 、留存、广告、收入和成本等指标。")])]),v._v(" "),_("p",[v._v("以上三个层次的数据指标可以让我们实现真正对业务增长有收益的播放体验优化。")]),v._v(" "),_("h2",{attrs:{id:"零耗时-首帧优化实践"}},[_("a",{staticClass:"header-anchor",attrs:{href:"#零耗时-首帧优化实践"}},[v._v("#")]),v._v(" “零耗时”首帧优化实践")]),v._v(" "),_("p",[v._v("什么是“零耗时”首帧?耗时本身想描述的是用户侧是否感受到了耗时这件事。所谓“零耗时”,并不是真的 0 毫秒起播,而是指用户在起播时平滑播放,没有首屏的顿感。")]),v._v(" "),_("p",[v._v("从我们现在的大盘来看,核心业务方 50% 的播放首帧都已经小于 100ms 了。从交互设计体验角度来看,小于 200ms 的时间人体感知就已经不明显了。所以我们认为,100ms 对于用户来说就是零耗时的首帧。")]),v._v(" "),_("p",[_("img",{attrs:{src:"https://raw.githubusercontent.com/jacky1234/picArchieve/master/uPic/HqOffk.jpg",alt:"首帧时长构成"}})]),v._v(" "),_("p",[v._v("我们做了哪些优化来达到小于 100ms 的零首帧呢?前面提到对于每一个首帧,我们都细拆了很多环节,不同的环节都进行了有针对性的技术优化。我们梳理了一下,将首帧时长的构成拆解为了 4 个模块:")]),v._v(" "),_("ul",[_("li",[_("p",[_("strong",[v._v("业务相关的页面创建、交互和渲染耗时")]),v._v("。")])]),v._v(" "),_("li",[_("p",[_("strong",[v._v("网络连接耗时")]),v._v(":包括业内常用到的连接复用、预连接等策略。网络层面经常会存在很多不稳定因素,所以对于节点优选和网络超时优化,我们也会基于客户端层面,以单个 VV 实例以及用户相关的上下文去做不同的优化尝试。再者就是比较常规的预加载、 DNS 缓存优化等优化措施。")])]),v._v(" "),_("li",[_("p",[_("strong",[v._v("解码耗时")]),v._v(":解码耗时一方面与播放源格式强相关。例如对于 MP4 格式,如果想减少解码耗时,就要保证 MP4 的 moov box 在前面,避免播放器在下载了部分数据后又要到文件尾部再解析 moov 文件,增加了数据请求耗时。另一方面与设备的软解/硬解方案相关,硬解在下文会有详细介绍。")])]),v._v(" "),_("li",[_("p",[v._v("对于我们自己的播放器来说,在软解方面会有一些自研的低延时模式优化。")])]),v._v(" "),_("li",[_("p",[_("strong",[v._v("播放器策略逻辑耗时")]),v._v(":这个模块更多的是关注指标置换和指标平衡。比如对于起播水位的优化,我们要实现在控制起播水位 buffersize 时,既保证用户对首帧无感知,又保证后续播放流畅。")])])]),v._v(" "),_("p",[v._v("下面会详细介绍我们正在进行或是已经上线的一些优化案例。")]),v._v(" "),_("h3",{attrs:{id:"业务耗时优化-预渲染"}},[_("a",{staticClass:"header-anchor",attrs:{href:"#业务耗时优化-预渲染"}},[v._v("#")]),v._v(" 业务耗时优化:预渲染")]),v._v(" "),_("p",[v._v("预加载是当前通用的优化网络耗时的解决方案,指的是在播放当前视频时,如果网络能力允许,会提前触发后续视频的下载。预加载相当于减少了用户可感知的网络加载和网络连接的耗时。")]),v._v(" "),_("p",[v._v("但是通用的预加载解决方案没有把播放器和网络 IO 进行强紧密的结合,在预加载时只是基于数据模块触发下载任务,而此时播放器的实例还没有创建起来。")]),v._v(" "),_("p",[v._v("对于这种情况,我们在思考能否把播放器创建以及初始化的工作整体前置。")]),v._v(" "),_("p",[v._v("此外,我们还发现当播放的封面图和首帧差异很大的时候,用户会感受到明显的跳变。这个跳变有可能会让用户感受到卡顿,或者是其他不舒适的感觉。所以这一部分也是我们整体的优化目标。")]),v._v(" "),_("p",[v._v("基于以上这些考虑,就产生了我们的"),_("strong",[v._v("预渲染的解决方案:当前任务在播放时,提前起播下一个播放任务,渲染首帧替代封面,从而降低首帧耗时")]),v._v("。")]),v._v(" "),_("h3",{attrs:{id:"网络耗时优化-节点优选"}},[_("a",{staticClass:"header-anchor",attrs:{href:"#网络耗时优化-节点优选"}},[v._v("#")]),v._v(" 网络耗时优化——节点优选")]),v._v(" "),_("h3",{attrs:{id:"网络耗时优化-解码耗时"}},[_("a",{staticClass:"header-anchor",attrs:{href:"#网络耗时优化-解码耗时"}},[v._v("#")]),v._v(" 网络耗时优化——解码耗时")]),v._v(" "),_("p",[v._v("解码耗时的优化是我们相比其他开源播放器在首帧上保持优势的根本原因。")]),v._v(" "),_("p",[v._v("解码本身需要耗时。当一个视频的数据完成准备,在解码过程中至少会经历以下几个环节:")]),v._v(" "),_("ol",[_("li",[_("p",[_("strong",[v._v("格式解析器和分离器(formater 和 demuxer)")]),v._v(":首先,视频文件通常以某种特定的格式(如 MP4、MKV、AVI 等)存储,而格式解析器和分离器的任务是解析文件并提取其中的音频和视频流。这一步骤通常包括解析文件头、查找音频和视频轨道,以及确定它们的编解码格式。")])]),v._v(" "),_("li",[_("p",[_("strong",[v._v("音频和视频解码")]),v._v(":一旦从文件中提取出音频和视频流,接下来就需要对它们进行解码。这涉及将音频和视频数据从其压缩格式(如 H.264 视频编解码器或 AAC 音频编解码器)解压缩为原始音频和视频帧。这一过程可以是计算密集型的,尤其是对于高分辨率的视频和复杂的音频编解码器。")])]),v._v(" "),_("li",[_("p",[_("strong",[v._v("音频和视频的优化")]),v._v(":解码后的音频和视频通常需要进一步处理和优化,以确保它们的质量和格式适合最终的渲染。这可能包括音频的混音、均衡和降噪,以及视频的缩放、剪辑和色彩校正等操作。")])]),v._v(" "),_("li",[_("p",[_("strong",[v._v("端侧渲染")]),v._v(":最后,解码和优化后的音频和视频数据将被传递到端侧,用于渲染。在移动设备或计算机上,通常会使用音频和视频渲染引擎来将数据呈现为音频波形和视频帧,以便用户可以听到声音和观看图像。")])])]),v._v(" "),_("p",[v._v("如果我们不进行任何优化,把以上所有所流程都托管, ffmpeg 进行解复用, MediaCodec 进行解码,整个过程基于不同机型的耗时至少在 100ms 以上。")]),v._v(" "),_("p",[v._v("我们在解码耗时上主要做了如下三个方面的事情:")]),v._v(" "),_("h4",{attrs:{id:"解码初始化耗时"}},[_("a",{staticClass:"header-anchor",attrs:{href:"#解码初始化耗时"}},[v._v("#")]),v._v(" 解码初始化耗时")]),v._v(" "),_("p",[v._v("在视频解码的过程中,初始化硬件解码器通常需要一些时间,一般情况下,这个初始化的平均耗时大于 100 毫秒。硬解码的初始化过程可以理解为向底层的多媒体框架(例如 OpenMAX)提供相关的编解码器标识(Codec ID)或编解码器名称(Codec name),然后由底层多媒体框架负责创建解码器实例。简而言之,正常的解码或初始化流程需要先下载视频数据,然后解析视频流的头部信息,以获取视频的编解码器信息,然后进行硬解码器的初始化。")]),v._v(" "),_("p",[v._v("为了优化这个过程,目前的策略是将硬解码的初始化与头部信息解析以及解复用过程并行处理。在传输视频流时,会提前告知系统当前视频的编解码器信息,这意味着在数据下载和解复用的并行处理过程中,硬解码器的初始化已经完成。这样做的好处是可以减少首帧的等待时间,因为在播放开始时,硬解码器已经准备好接受数据并进行解码,而不需要等待初始化完成。")]),v._v(" "),_("p",[v._v("通过这项优化,平均可以减少首帧的等待时间,通常降低了"),_("strong",[v._v("80 毫秒到 120 毫秒")]),v._v(",从而提升了整体的播放性能和用户体验。这对于实时流媒体和要求低延迟的应用程序尤为重要,因为它可以减少用户等待首帧显示的时间,使用户更快地观看到视频内容。")]),v._v(" "),_("h4",{attrs:{id:"解码器复用"}},[_("a",{staticClass:"header-anchor",attrs:{href:"#解码器复用"}},[v._v("#")]),v._v(" 解码器复用")]),v._v(" "),_("p",[v._v("不重新初始化解码器 MediaCodec,而将解码器直接用于其他播放器解码,称为解码器复用。")]),v._v(" "),_("h5",{attrs:{id:"适合短视频场景的解码器复用方案"}},[_("a",{staticClass:"header-anchor",attrs:{href:"#适合短视频场景的解码器复用方案"}},[v._v("#")]),v._v(" 适合短视频场景的解码器复用方案")]),v._v(" "),_("p",[v._v("以当前短视频比较常见的 feed 流的实现方式为例:当上一个视频完成了解码初始化,下一个视频是否可以直接复用上一个视频的解码器?这里我们使用了 codec_pool 进行相关解码器的复用。在上一个视频完成播放时,我们把相关的 codec 复用到下一个视频,这样就省略了两个视频初始化过程中 stop release 到 start 的耗时。这一部分优化的耗时平均在 40+ms 。而 Google 为了优化清晰度无缝切换时的耗时,在 ExoPlayer 上实现了播放器内的解码器复用。")]),v._v(" "),_("p",[_("strong",[v._v("1. Google 的 ExoPlayer 方案不适合短视频场景")])]),v._v(" "),_("p",[v._v("Google 已经在 ExoPlayer 上进行了解码器复用实践,那么是否可以将对应方案直接应用到我们的业务呢?答案是不能的。ExoPlayer 是一种播放器内部解码器复用方案,即"),_("strong",[v._v("解码器和播放器实例绑定")]),v._v("。对于不同分辨率的视频 A、B、C,下次播放时判断该播放器实例是否可以复用,如果可以,进行复用,否则重新初始化解码器。")]),v._v(" "),_("p",[v._v("总而言之,基于短视频切换频繁的特点,直接使用 ExoPlayer 方案会存在以下困难:")]),v._v(" "),_("ul",[_("li",[_("strong",[v._v("无法在 player 之间复用")]),v._v(",由于有预加载等优化手段,短视频场景一般不同视频对应不同的 player,与方案冲突。")]),v._v(" "),_("li",[_("strong",[v._v("复用率低")]),v._v(",因为 ExoPlayer 方案局限在 player 内部,多个 player 之间不能共享解码器,而解码器复用是有条件限制的,这样会让复用率非常低。")]),v._v(" "),_("li",[_("strong",[v._v("接入困难")]),v._v(",复用逻辑与播放器逻辑耦合严重。")])]),v._v(" "),_("h5",{attrs:{id:"跨播放器解码器复用方案"}},[_("a",{staticClass:"header-anchor",attrs:{href:"#跨播放器解码器复用方案"}},[v._v("#")]),v._v(" 跨播放器解码器复用方案")]),v._v(" "),_("p",[v._v("【短视频复用的特点】")]),v._v(" "),_("ul",[_("li",[v._v("跨播放器复用:解码器能够在多个播放器之间共享,适应多 player 场景。")]),v._v(" "),_("li",[v._v("高复用率:闲置的解码器能够被选择,需要保证播放器在起播时尽可能的复用解码器。")]),v._v(" "),_("li",[v._v("低入侵接入:解码器复用逻辑需要和播放器逻辑解耦,让接入时尽可能减少代码入侵。")]),v._v(" "),_("li",[v._v("通用性高:能够让几乎所有基于 MediaCodec 的播放器都能使用无缝切换方案。")])]),v._v(" "),_("p",[v._v("【跨播放器复用方案的演进】")]),v._v(" "),_("h4",{attrs:{id:"机型能力大数据择优"}},[_("a",{staticClass:"header-anchor",attrs:{href:"#机型能力大数据择优"}},[v._v("#")]),v._v(" 机型能力大数据择优")]),v._v(" "),_("h2",{attrs:{id:"链接"}},[_("a",{staticClass:"header-anchor",attrs:{href:"#链接"}},[v._v("#")]),v._v(" 链接")]),v._v(" "),_("ul",[_("li",[_("a",{attrs:{href:"https://www.infoq.cn/article/yua5huimspppp46lpmg1",target:"_blank",rel:"noopener noreferrer"}},[v._v("“零耗时”首帧视频体验的优化实践"),_("OutboundLink")],1)]),v._v(" "),_("li",[_("a",{attrs:{href:"https://juejin.cn/post/7090567116864094239",target:"_blank",rel:"noopener noreferrer"}},[v._v("首屏加载速度如何优化?试试前端预渲染!"),_("OutboundLink")],1)]),v._v(" "),_("li",[_("a",{attrs:{href:"https://cloud.tencent.com/developer/article/1717107",target:"_blank",rel:"noopener noreferrer"}},[v._v("看点视频秒开优化:解码器复用优化方案篇"),_("OutboundLink")],1)]),v._v(" "),_("li",[_("a",{attrs:{href:"https://developer.android.com/reference/android/media/MediaCodec",target:"_blank",rel:"noopener noreferrer"}},[v._v("Android, MediaCodec"),_("OutboundLink")],1)])])])}),[],!1,null,null,null);_.default=e.exports}}]); \ No newline at end of file diff --git a/assets/js/121.d91fe832.js b/assets/js/121.d91fe832.js new file mode 100644 index 0000000000..d0bbfa16a4 --- /dev/null +++ b/assets/js/121.d91fe832.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[121],{447:function(t,a,s){"use strict";s.r(a);var n=s(4),e=Object(n.a)({},(function(){var t=this,a=t._self._c;return a("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[a("blockquote",[a("p",[t._v("JSBridge 简单来讲,主要是 给 JavaScript 提供调用 Native 功能的接口,让混合开发中的『前端部分』可以方便地使用地址位置、摄像头甚至支付等 Native 功能。")])]),t._v(" "),a("p",[a("img",{attrs:{src:"https://cdn.jsdelivr.net/gh/jacky1234/picArchieve@master/uPic/20230827_154714_v3l1Jg.png",alt:""}})]),t._v(" "),a("p",[a("img",{attrs:{src:"https://cdn.jsdelivr.net/gh/jacky1234/picArchieve@master/uPic/20230827_154750_HYuEMZ.png",alt:""}})]),t._v(" "),a("h2",{attrs:{id:"前置内容"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#前置内容"}},[t._v("#")]),t._v(" 前置内容")]),t._v(" "),a("h3",{attrs:{id:"jsbridge-的起源"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#jsbridge-的起源"}},[t._v("#")]),t._v(" jsbridge 的起源")]),t._v(" "),a("p",[t._v("为什么是 JSBridge ?而不是 PythonBridge 或是 RubyBridge ?")]),t._v(" "),a("p",[t._v("当然不是因为 JavaScript 语言高人一等(虽然斯坦福大学已经把算法导论的语言从 Java 改成 JavaScript,小得意一下,嘻嘻),主要的原因还是因为 JavaScript 主要载体 Web 是当前世界上的 最易编写 、 最易维护 、最易部署 的 UI 构建方式。工程师可以用很简单的 HTML 标签和 CSS 样式快速的构建出一个页面,并且在服务端部署后,用户不需要主动更新,就能看到最新的 UI 展现。")]),t._v(" "),a("p",[t._v("因此,开发维护成本 和 更新成本 较低的 Web 技术成为混合开发中几乎不二的选择,而作为 Web 技术逻辑核心的 JavaScript 也理所应当肩负起与其他技术『桥接』的职责,并且作为移动不可缺少的一部分,任何一个移动操作系统中都包含可运行 JavaScript 的容器,例如 WebView 和 JSCore。所以,运行 JavaScript 不用像运行其他语言时,要额外添加运行环境。因此,基于上面种种原因,JSBridge 应运而生。")]),t._v(" "),a("p",[t._v("PhoneGap(Codova 的前身)作为 Hybrid 鼻祖框架,应该是最先被开发者广泛认知的 JSBridge 的应用场景;而对于 JSBridge 的应用在国内真正兴盛起来,则是因为杀手级应用微信的出现,主要用途是在网页中通过 JSBridge 设置分享内容。")]),t._v(" "),a("p",[t._v("移动端混合开发中的 JSBridge,主要被应用在两种形式的技术方案上:")]),t._v(" "),a("ul",[a("li",[t._v("基于 Web 的 Hybrid 解决方案:例如微信浏览器、各公司的 Hybrid 方案")]),t._v(" "),a("li",[t._v("非基于 Web UI 但业务逻辑基于 JavaScript 的解决方案:例如 React-Native")])]),t._v(" "),a("p",[t._v("【注】:微信小程序基于 Web UI,但是为了追求运行效率,对 UI 展现逻辑和业务逻辑的 JavaScript 进行了隔离。因此小程序的技术方案介于上面描述的两种方式之间。")]),t._v(" "),a("h3",{attrs:{id:"内联框架-iframe"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#内联框架-iframe"}},[t._v("#")]),t._v(" 内联框架 iFrame")]),t._v(" "),a("p",[t._v("在 HTML 中,iFrame(内联框架)是一种用于嵌入另一个 HTML 文档的标记元素。iFrame 允许你将一个独立的 HTML 文档嵌入到当前页面中的特定区域,这个区域被定义为 iFrame 的内容区域。以下是 iFrame 在 HTML 中的主要角色和用途:")]),t._v(" "),a("ol",[a("li",[a("p",[t._v("嵌入外部内容:iFrame 最常见的用途是嵌入来自不同源(即不同的域)的外部内容,例如其他网站、视频、地图等。这使得你可以在自己的网页中嵌入其他网站的内容,或者在网页中显示来自不同服务提供商的内容,而无需离开当前页面。")])]),t._v(" "),a("li",[a("p",[t._v("创建内联框架:iFrame 允许你创建一个内联框架,其中可以加载独立的 HTML 文档。这个内联框架在当前页面中具有自己的独立的文档流,可以包含独立的 HTML、CSS 和 JavaScript 代码。这对于分隔不同部分的内容或加载与主页面无关的内容非常有用。")])]),t._v(" "),a("li",[a("p",[t._v("与第三方服务集成:通过嵌入第三方提供的 iFrame 代码,你可以轻松地将其服务集成到你的网页中。例如,许多社交媒体平台提供了嵌入式 iFrame 代码,使你可以在网页上显示社交媒体帖子、评论框等内容。")])]),t._v(" "),a("li",[a("p",[t._v("实现可重用性:iFrame 可以用于创建可重用的组件或小部件,这些组件可以在多个页面中使用。通过将 iFrame 内嵌到不同的页面中,你可以在多个地方显示相同的内容,而不必重复编写代码。")])])]),t._v(" "),a("p",[t._v("尽管 iFrame 提供了灵活性和功能强大的嵌入功能,但它也需要小心使用。由于可以嵌入来自不同源的内容,因此可能存在安全风险,例如跨站点脚本(XSS)攻击。因此,在使用 iFrame 时,需要确保信任和验证嵌入的内容,以防止潜在的安全问题。")]),t._v(" "),a("h3",{attrs:{id:"js-中的-eval-函数"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#js-中的-eval-函数"}},[t._v("#")]),t._v(" js 中的 eval 函数")]),t._v(" "),a("div",{staticClass:"language-javascript line-numbers-mode"},[a("pre",{pre:!0,attrs:{class:"language-javascript"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("try")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("var")]),t._v(" fn "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("eval")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'WebViewJavascriptBridge.'")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" handlerName"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("catch")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("e"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n console"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("e"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])]),t._v(" "),a("div",{staticClass:"line-numbers-wrapper"},[a("span",{staticClass:"line-number"},[t._v("1")]),a("br"),a("span",{staticClass:"line-number"},[t._v("2")]),a("br"),a("span",{staticClass:"line-number"},[t._v("3")]),a("br"),a("span",{staticClass:"line-number"},[t._v("4")]),a("br"),a("span",{staticClass:"line-number"},[t._v("5")]),a("br")])]),a("p",[t._v("这段代码是JavaScript中的一个片段,它尝试通过字符串拼接来构造一个函数名,然后使用eval函数来执行这个函数。具体来说:")]),t._v(" "),a("ul",[a("li",[a("p",[a("code",[t._v("handlerName")]),t._v(' 是一个变量,它包含一个函数名的字符串,例如 "myFunction"。')])]),t._v(" "),a("li",[a("p",[a("code",[t._v("eval")]),t._v(' 函数用于将字符串解析为JavaScript代码并执行。在这里,它将字符串 "WebViewJavascriptBridge.myFunction" 解析为一个函数并执行它。')])]),t._v(" "),a("li",[a("p",[a("code",[t._v("try...catch")]),t._v(" 语句用于捕获可能在 eval 执行时发生的异常。如果构造的函数名无效或不存在,eval 会引发一个异常,该异常将被 catch 块捕获,并在控制台上记录异常信息。")])])]),t._v(" "),a("h3",{attrs:{id:"什么是双向通道"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#什么是双向通道"}},[t._v("#")]),t._v(" 什么是双向通道")]),t._v(" "),a("p",[t._v("JSBridge 就像其名称中的『Bridge』的意义一样,是 Native 和非 Native 之间的桥梁,它的核心是 构建 Native 和非 Native 间消息通信的通道,而且是 双向通信的通道。")]),t._v(" "),a("p",[a("img",{attrs:{src:"https://cdn.jsdelivr.net/gh/jacky1234/picArchieve@master/uPic/20230825_162448_7pTr5j.png",alt:""}})]),t._v(" "),a("p",[t._v("所谓 双向通信的通道:")]),t._v(" "),a("ul",[a("li",[t._v("JS 向 Native 发送消息 : 调用相关功能、通知 Native 当前 JS 的相关状态等。")]),t._v(" "),a("li",[t._v("Native 向 JS 发送消息 : 回溯调用结果、消息推送、通知 JS 当前 Native 的状态等。")])]),t._v(" "),a("h2",{attrs:{id:"实现原理"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#实现原理"}},[t._v("#")]),t._v(" 实现原理")]),t._v(" "),a("p",[t._v("JavaScript 是运行在一个单独的 JS Context 中(例如,WebView 的 Webkit 引擎、JSCore)。由于这些 Context 与原生运行环境的天然隔离,我们可以将这种情况与 RPC(Remote Procedure Call,远程过程调用)通信进行类比,将 Native 与 JavaScript 的每次互相调用看做一次 RPC 调用。")]),t._v(" "),a("p",[t._v("在 JSBridge 的设计中,可以把前端看做 RPC 的客户端,把 Native 端看做 RPC 的服务器端,从而 JSBridge 要实现的主要逻辑就出现了:通信调用(Native 与 JS 通信) 和 句柄解析调用。(如果你是个前端,而且并不熟悉 RPC 的话,你也可以把这个流程类比成 JSONP 的流程)")]),t._v(" "),a("p",[t._v("通过以上的分析,可以清楚地知晓 JSBridge 主要的功能和职责,接下来就以 Hybrid 方案 为案例从这几点来剖析 JSBridge 的实现原理。")]),t._v(" "),a("h3",{attrs:{id:"js-通信原理"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#js-通信原理"}},[t._v("#")]),t._v(" js 通信原理")]),t._v(" "),a("h4",{attrs:{id:"javascript-调用-native"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#javascript-调用-native"}},[t._v("#")]),t._v(" JavaScript 调用 Native")]),t._v(" "),a("p",[a("strong",[t._v("Android")])]),t._v(" "),a("p",[t._v("一、addJavascriptInterface。")]),t._v(" "),a("p",[t._v("在 4.2 版本之前 Android 注入 JavaScript 对象的接口是 addJavascriptInterface。 在 4.2 中引入新的接口 @JavascriptInterface(上面代码中使用的)来替代这个接口,解决安全问题。所以 Android 注入对对象的方式是 有兼容性问题的")]),t._v(" "),a("p",[t._v("二、拦截 URL SCHEME")]),t._v(" "),a("p",[t._v("Web 端通过某种方式(例如 iframe.src)发送 URL Scheme 请求,之后 Native 拦截到请求并根据 URL SCHEME(包括所带的参数)进行相关操作。")]),t._v(" "),a("p",[t._v("在时间过程中,这种方式有一定的 缺陷:")]),t._v(" "),a("ul",[a("li",[t._v("使用 iframe.src 发送 URL SCHEME 会有 url 长度的隐患。")]),t._v(" "),a("li",[t._v("创建请求,需要一定的耗时,比注入 API 的方式调用同样的功能,耗时会较长。")])]),t._v(" "),a("p",[t._v("但是之前为什么很多方案使用这种方式呢?因为它 支持 iOS6。")]),t._v(" "),a("p",[t._v("【注】:有些方案为了规避 url 长度隐患的缺陷,在 iOS 上采用了使用 Ajax 发送同域请求的方式,并将参数放到 head 或 body 里。这样,虽然规避了 url 长度的隐患,但是 WKWebView 并不支持这样的方式。")]),t._v(" "),a("p",[t._v("【注 2】:为什么选择 iframe.src 不选择 locaiton.href ?因为如果通过 location.href 连续调用 Native,很容易丢失一些调用。")]),t._v(" "),a("h4",{attrs:{id:"native-调用-javascript"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#native-调用-javascript"}},[t._v("#")]),t._v(" Native 调用 JavaScript")]),t._v(" "),a("p",[t._v("相比于 JavaScript 调用 Native, Native 调用 JavaScript 较为简单,毕竟不管是 iOS 的 UIWebView 还是 WKWebView,还是 Android 的 WebView 组件,都以子组件的形式存在于 View/Activity 中,直接调用相应的 API 即可。")]),t._v(" "),a("p",[a("strong",[t._v("Android")])]),t._v(" "),a("p",[t._v("在 Kitkat(4.4)之前并没有提供 iOS 类似的调用方式,只能用 loadUrl 一段 JavaScript 代码 "),a("code",[t._v('webView.loadUrl("javascript:" + javaScriptString);')]),t._v(". Kitkat 之后的版本,也可以用 evaluateJavascript 方法实现:")]),t._v(" "),a("div",{staticClass:"language-java line-numbers-mode"},[a("pre",{pre:!0,attrs:{class:"language-java"}},[a("code",[t._v("webView"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("evaluateJavascript")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("javaScriptString"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ValueCallback")]),a("span",{pre:!0,attrs:{class:"token generics"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Override")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("public")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("onReceiveValue")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),t._v(" value"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])]),t._v(" "),a("div",{staticClass:"line-numbers-wrapper"},[a("span",{staticClass:"line-number"},[t._v("1")]),a("br"),a("span",{staticClass:"line-number"},[t._v("2")]),a("br"),a("span",{staticClass:"line-number"},[t._v("3")]),a("br"),a("span",{staticClass:"line-number"},[t._v("4")]),a("br"),a("span",{staticClass:"line-number"},[t._v("5")]),a("br"),a("span",{staticClass:"line-number"},[t._v("6")]),a("br")])]),a("p",[t._v("【注】:使用 loadUrl 的方式,并不能获取 JavaScript 执行后的结果。")]),t._v(" "),a("p",[a("strong",[t._v("iOS")])]),t._v(" "),a("h3",{attrs:{id:"jsbridge-接口实现"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#jsbridge-接口实现"}},[t._v("#")]),t._v(" JSBridge 接口实现")]),t._v(" "),a("p",[t._v("从上面的剖析中,可以得知,JSBridge 的接口主要功能有两个:调用 Native(给 Native 发消息) 和 接被 Native 调用(接收 Native 消息)。因此,JSBridge 可以设计如下:")]),t._v(" "),a("div",{staticClass:"language-javascript line-numbers-mode"},[a("pre",{pre:!0,attrs:{class:"language-javascript"}},[a("code",[t._v("window"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("JSBridge "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n\t"),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 调用 Native")]),t._v("\n\t"),a("span",{pre:!0,attrs:{class:"token function-variable function"}},[t._v("invoke")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("function")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("msg")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n\t\t"),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 判断环境,获取不同的 nativeBridge")]),t._v("\n\t\tnativeBridge"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("postMessage")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("msg"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\t"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n\t"),a("span",{pre:!0,attrs:{class:"token function-variable function"}},[t._v("receiveMessage")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("function")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("msg")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n\t\t"),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 处理 msg")]),t._v("\n\t"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])]),t._v(" "),a("div",{staticClass:"line-numbers-wrapper"},[a("span",{staticClass:"line-number"},[t._v("1")]),a("br"),a("span",{staticClass:"line-number"},[t._v("2")]),a("br"),a("span",{staticClass:"line-number"},[t._v("3")]),a("br"),a("span",{staticClass:"line-number"},[t._v("4")]),a("br"),a("span",{staticClass:"line-number"},[t._v("5")]),a("br"),a("span",{staticClass:"line-number"},[t._v("6")]),a("br"),a("span",{staticClass:"line-number"},[t._v("7")]),a("br"),a("span",{staticClass:"line-number"},[t._v("8")]),a("br"),a("span",{staticClass:"line-number"},[t._v("9")]),a("br"),a("span",{staticClass:"line-number"},[t._v("10")]),a("br")])]),a("p",[t._v("在上面的文章中,提到过 RPC 中有一个非常重要的环节是 句柄解析调用 ,这点在 JSBridge 中体现为 句柄与功能对应关系。同时,我们将句柄抽象为 桥名(BridgeName),最终演化为 一个 BridgeName 对应一个 Native 功能或者一类 Native 消息。 基于此点,JSBridge 的实现可以优化为如下:")]),t._v(" "),a("div",{staticClass:"language-javascript line-numbers-mode"},[a("pre",{pre:!0,attrs:{class:"language-javascript"}},[a("code",[t._v("window"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("JSBridge "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n\t"),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 调用 Native")]),t._v("\n\t"),a("span",{pre:!0,attrs:{class:"token function-variable function"}},[t._v("invoke")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("function")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("bridgeName"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" data")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n\t\t"),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 判断环境,获取不同的 nativeBridge")]),t._v("\n\t\tnativeBridge"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("postMessage")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n\t\t\t"),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("bridgeName")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" bridgeName"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n\t\t\t"),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("data")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" data "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("||")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n\t\t"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\t"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n\t"),a("span",{pre:!0,attrs:{class:"token function-variable function"}},[t._v("receiveMessage")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("function")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("msg")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n\t\t"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("var")]),t._v(" bridgeName "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" msg"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("bridgeName"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n\t\t\tdata "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" msg"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("data "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("||")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\t\t"),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 具体逻辑")]),t._v("\n\t"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])]),t._v(" "),a("div",{staticClass:"line-numbers-wrapper"},[a("span",{staticClass:"line-number"},[t._v("1")]),a("br"),a("span",{staticClass:"line-number"},[t._v("2")]),a("br"),a("span",{staticClass:"line-number"},[t._v("3")]),a("br"),a("span",{staticClass:"line-number"},[t._v("4")]),a("br"),a("span",{staticClass:"line-number"},[t._v("5")]),a("br"),a("span",{staticClass:"line-number"},[t._v("6")]),a("br"),a("span",{staticClass:"line-number"},[t._v("7")]),a("br"),a("span",{staticClass:"line-number"},[t._v("8")]),a("br"),a("span",{staticClass:"line-number"},[t._v("9")]),a("br"),a("span",{staticClass:"line-number"},[t._v("10")]),a("br"),a("span",{staticClass:"line-number"},[t._v("11")]),a("br"),a("span",{staticClass:"line-number"},[t._v("12")]),a("br"),a("span",{staticClass:"line-number"},[t._v("13")]),a("br"),a("span",{staticClass:"line-number"},[t._v("14")]),a("br"),a("span",{staticClass:"line-number"},[t._v("15")]),a("br")])]),a("p",[t._v("JSBridge 大概的雏形出现了。现在终于可以着手解决这个问题了:消息都是单向的,那么调用 Native 功能时 Callback 怎么实现的?")]),t._v(" "),a("p",[t._v("对于 JSBridge 的 Callback ,其实就是 RPC 框架的回调机制。当然也可以用更简单的 JSONP 机制解释:")]),t._v(" "),a("blockquote",[a("p",[t._v("当发送 JSONP 请求时,url 参数里会有 callback 参数,其值是 当前页面唯一 的,而同时以此参数值为 key 将回调函数存到 window 上,随后,服务器返回 script 中,也会以此参数值作为句柄,调用相应的回调函数。")])]),t._v(" "),a("p",[t._v("由此可见,callback 参数这个 唯一标识 是这个回调逻辑的关键。这样,我们可以参照这个逻辑来实现 JSBridge:用一个自增的唯一 id,来标识并存储回调函数,并把此 id 以参数形式传递给 Native,而 Native 也以此 id 作为回溯的标识。这样,即可实现 Callback 回调逻辑。")]),t._v(" "),a("div",{staticClass:"language-javascript line-numbers-mode"},[a("pre",{pre:!0,attrs:{class:"language-javascript"}},[a("code",[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("function")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("var")]),t._v(" id "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n callbacks "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n window"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("JSBridge "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 调用 Native")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token function-variable function"}},[t._v("invoke")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("function")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("bridgeName"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" callback"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" data")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 判断环境,获取不同的 nativeBridge")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("var")]),t._v(" thisId "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" id "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("++")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 获取唯一 id")]),t._v("\n callbacks"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("thisId"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" callback"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 存储 Callback")]),t._v("\n nativeBridge"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("postMessage")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("bridgeName")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" bridgeName"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("data")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" data "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("||")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("callbackId")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" thisId "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 传到 Native 端")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token function-variable function"}},[t._v("receiveMessage")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("function")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("msg")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("var")]),t._v(" bridgeName "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" msg"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("bridgeName"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n data "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" msg"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("data "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("||")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n callbackId "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" msg"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("callbackId"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Native 将 callbackId 原封不动传回")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 具体逻辑")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// bridgeName 和 callbackId 不会同时存在")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("callbackId"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("callbacks"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("callbackId"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 找到相应句柄")]),t._v("\n callbacks"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("callbackId"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("msg"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("data"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 执行调用")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("elseif")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("bridgeName")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])]),t._v(" "),a("div",{staticClass:"line-numbers-wrapper"},[a("span",{staticClass:"line-number"},[t._v("1")]),a("br"),a("span",{staticClass:"line-number"},[t._v("2")]),a("br"),a("span",{staticClass:"line-number"},[t._v("3")]),a("br"),a("span",{staticClass:"line-number"},[t._v("4")]),a("br"),a("span",{staticClass:"line-number"},[t._v("5")]),a("br"),a("span",{staticClass:"line-number"},[t._v("6")]),a("br"),a("span",{staticClass:"line-number"},[t._v("7")]),a("br"),a("span",{staticClass:"line-number"},[t._v("8")]),a("br"),a("span",{staticClass:"line-number"},[t._v("9")]),a("br"),a("span",{staticClass:"line-number"},[t._v("10")]),a("br"),a("span",{staticClass:"line-number"},[t._v("11")]),a("br"),a("span",{staticClass:"line-number"},[t._v("12")]),a("br"),a("span",{staticClass:"line-number"},[t._v("13")]),a("br"),a("span",{staticClass:"line-number"},[t._v("14")]),a("br"),a("span",{staticClass:"line-number"},[t._v("15")]),a("br"),a("span",{staticClass:"line-number"},[t._v("16")]),a("br"),a("span",{staticClass:"line-number"},[t._v("17")]),a("br"),a("span",{staticClass:"line-number"},[t._v("18")]),a("br"),a("span",{staticClass:"line-number"},[t._v("19")]),a("br"),a("span",{staticClass:"line-number"},[t._v("20")]),a("br"),a("span",{staticClass:"line-number"},[t._v("21")]),a("br"),a("span",{staticClass:"line-number"},[t._v("22")]),a("br"),a("span",{staticClass:"line-number"},[t._v("23")]),a("br"),a("span",{staticClass:"line-number"},[t._v("24")]),a("br"),a("span",{staticClass:"line-number"},[t._v("25")]),a("br"),a("span",{staticClass:"line-number"},[t._v("26")]),a("br"),a("span",{staticClass:"line-number"},[t._v("27")]),a("br"),a("span",{staticClass:"line-number"},[t._v("28")]),a("br"),a("span",{staticClass:"line-number"},[t._v("29")]),a("br"),a("span",{staticClass:"line-number"},[t._v("30")]),a("br"),a("span",{staticClass:"line-number"},[t._v("31")]),a("br"),a("span",{staticClass:"line-number"},[t._v("32")]),a("br")])]),a("p",[t._v("最后用同样的方式加上 Native 调用的回调逻辑,同时对代码进行一些优化,就大概实现了一个功能比较完整的 JSBridge。其代码如下:")]),t._v(" "),a("p",[t._v("主要的代码逻辑是:")]),t._v(" "),a("div",{staticClass:"language-javascript line-numbers-mode"},[a("pre",{pre:!0,attrs:{class:"language-javascript"}},[a("code",[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("function")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("var")]),t._v(" id "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n callbacks "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n registerFuncs "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n window"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("JSBridge "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 调用 Native")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token function-variable function"}},[t._v("invoke")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("function")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("bridgeName"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" callback"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" data")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 判断环境,获取不同的 nativeBridge")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("var")]),t._v(" thisId "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" id "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("++")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 获取唯一 id")]),t._v("\n callbacks"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("thisId"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" callback"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 存储 Callback")]),t._v("\n nativeBridge"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("postMessage")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("bridgeName")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" bridgeName"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("data")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" data "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("||")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("callbackId")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" thisId "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 传到 Native 端")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token function-variable function"}},[t._v("receiveMessage")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("function")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("msg")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("var")]),t._v(" bridgeName "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" msg"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("bridgeName"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n data "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" msg"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("data "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("||")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n callbackId "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" msg"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("callbackId"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Native 将 callbackId 原封不动传回")]),t._v("\n responstId "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" msg"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("responstId"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 具体逻辑")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// bridgeName 和 callbackId 不会同时存在")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("callbackId"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("callbacks"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("callbackId"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 找到相应句柄")]),t._v("\n callbacks"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("callbackId"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("msg"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("data"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 执行调用")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("elseif")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("bridgeName")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("registerFuncs"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("bridgeName"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 通过 bridgeName 找到句柄")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("var")]),t._v(" ret "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n flag "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("false")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n registerFuncs"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("bridgeName"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("forEach")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("function")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("callback")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("callback")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("data"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("function")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("r")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n flag "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("true")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n ret "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Object"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("assign")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("ret"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" r"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("flag"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n nativeBridge"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("postMessage")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 回调 Native")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("responstId")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" responstId"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("ret")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" ret\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token function-variable function"}},[t._v("register")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("function")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("bridgeName"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" callback")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!")]),t._v("registerFuncs"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("bridgeName"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n registerFuncs"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("bridgeName"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n registerFuncs"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("bridgeName"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("push")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("callback"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 存储回调")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])]),t._v(" "),a("div",{staticClass:"line-numbers-wrapper"},[a("span",{staticClass:"line-number"},[t._v("1")]),a("br"),a("span",{staticClass:"line-number"},[t._v("2")]),a("br"),a("span",{staticClass:"line-number"},[t._v("3")]),a("br"),a("span",{staticClass:"line-number"},[t._v("4")]),a("br"),a("span",{staticClass:"line-number"},[t._v("5")]),a("br"),a("span",{staticClass:"line-number"},[t._v("6")]),a("br"),a("span",{staticClass:"line-number"},[t._v("7")]),a("br"),a("span",{staticClass:"line-number"},[t._v("8")]),a("br"),a("span",{staticClass:"line-number"},[t._v("9")]),a("br"),a("span",{staticClass:"line-number"},[t._v("10")]),a("br"),a("span",{staticClass:"line-number"},[t._v("11")]),a("br"),a("span",{staticClass:"line-number"},[t._v("12")]),a("br"),a("span",{staticClass:"line-number"},[t._v("13")]),a("br"),a("span",{staticClass:"line-number"},[t._v("14")]),a("br"),a("span",{staticClass:"line-number"},[t._v("15")]),a("br"),a("span",{staticClass:"line-number"},[t._v("16")]),a("br"),a("span",{staticClass:"line-number"},[t._v("17")]),a("br"),a("span",{staticClass:"line-number"},[t._v("18")]),a("br"),a("span",{staticClass:"line-number"},[t._v("19")]),a("br"),a("span",{staticClass:"line-number"},[t._v("20")]),a("br"),a("span",{staticClass:"line-number"},[t._v("21")]),a("br"),a("span",{staticClass:"line-number"},[t._v("22")]),a("br"),a("span",{staticClass:"line-number"},[t._v("23")]),a("br"),a("span",{staticClass:"line-number"},[t._v("24")]),a("br"),a("span",{staticClass:"line-number"},[t._v("25")]),a("br"),a("span",{staticClass:"line-number"},[t._v("26")]),a("br"),a("span",{staticClass:"line-number"},[t._v("27")]),a("br"),a("span",{staticClass:"line-number"},[t._v("28")]),a("br"),a("span",{staticClass:"line-number"},[t._v("29")]),a("br"),a("span",{staticClass:"line-number"},[t._v("30")]),a("br"),a("span",{staticClass:"line-number"},[t._v("31")]),a("br"),a("span",{staticClass:"line-number"},[t._v("32")]),a("br"),a("span",{staticClass:"line-number"},[t._v("33")]),a("br"),a("span",{staticClass:"line-number"},[t._v("34")]),a("br"),a("span",{staticClass:"line-number"},[t._v("35")]),a("br"),a("span",{staticClass:"line-number"},[t._v("36")]),a("br"),a("span",{staticClass:"line-number"},[t._v("37")]),a("br"),a("span",{staticClass:"line-number"},[t._v("38")]),a("br"),a("span",{staticClass:"line-number"},[t._v("39")]),a("br"),a("span",{staticClass:"line-number"},[t._v("40")]),a("br"),a("span",{staticClass:"line-number"},[t._v("41")]),a("br"),a("span",{staticClass:"line-number"},[t._v("42")]),a("br"),a("span",{staticClass:"line-number"},[t._v("43")]),a("br"),a("span",{staticClass:"line-number"},[t._v("44")]),a("br"),a("span",{staticClass:"line-number"},[t._v("45")]),a("br"),a("span",{staticClass:"line-number"},[t._v("46")]),a("br"),a("span",{staticClass:"line-number"},[t._v("47")]),a("br"),a("span",{staticClass:"line-number"},[t._v("48")]),a("br"),a("span",{staticClass:"line-number"},[t._v("49")]),a("br"),a("span",{staticClass:"line-number"},[t._v("50")]),a("br"),a("span",{staticClass:"line-number"},[t._v("51")]),a("br"),a("span",{staticClass:"line-number"},[t._v("52")]),a("br"),a("span",{staticClass:"line-number"},[t._v("53")]),a("br"),a("span",{staticClass:"line-number"},[t._v("54")]),a("br"),a("span",{staticClass:"line-number"},[t._v("55")]),a("br")])]),a("p",[t._v("当然,这段代码片段只是一个示例,主要用于剖析 JSBridge 的原理和流程,里面存在诸多省略和不完善的代码逻辑,读者们可以自行完善。")]),t._v(" "),a("p",[t._v("在 Native 端配合实现 JSBridge 的 JavaScript 调用 Native 逻辑也很简单,主要的代码逻辑是")]),t._v(" "),a("ul",[a("li",[t._v("接收到 JavaScript 消息")]),t._v(" "),a("li",[t._v("解析参数,拿到 bridgeName、data 和 callbackId")]),t._v(" "),a("li",[t._v("根据 bridgeName 找到功能方法,以 data 为参数执行")]),t._v(" "),a("li",[t._v("执行返回值和 callbackId 一起回传前端")])]),t._v(" "),a("blockquote",[a("p",[t._v("Native 调用 JavaScript 也同样简单,直接自动生成一个唯一的 ResponseId,并存储句柄,然后和 data 一起发送给前端即可。")])]),t._v(" "),a("h2",{attrs:{id:"todo"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#todo"}},[t._v("#")]),t._v(" TODO")]),t._v(" "),a("ul",[a("li",[t._v("jsbridge 源码中为什么有两个 iframe,是为了解决什么问题")])]),t._v(" "),a("h2",{attrs:{id:"参考"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#参考"}},[t._v("#")]),t._v(" 参考")]),t._v(" "),a("ul",[a("li",[a("a",{attrs:{href:"https://github.com/lzyzsd/JsBridge",target:"_blank",rel:"noopener noreferrer"}},[t._v("jsbridge"),a("OutboundLink")],1)]),t._v(" "),a("li",[a("a",{attrs:{href:"https://juejin.cn/post/6844903585268891662",target:"_blank",rel:"noopener noreferrer"}},[t._v("jsbridge 原理"),a("OutboundLink")],1)]),t._v(" "),a("li",[a("a",{attrs:{href:"https://juejin.cn/post/6844903976505344013",target:"_blank",rel:"noopener noreferrer"}},[t._v("一分钟说完 JSONP 请求,面试满分答案"),a("OutboundLink")],1)])])])}),[],!1,null,null,null);a.default=e.exports}}]); \ No newline at end of file diff --git a/assets/js/122.c8f1bccc.js b/assets/js/122.c8f1bccc.js new file mode 100644 index 0000000000..57dc553693 --- /dev/null +++ b/assets/js/122.c8f1bccc.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[122],{448:function(t,r,s){"use strict";s.r(r);var e=s(4),n=Object(e.a)({},(function(){var t=this._self._c;return t("ContentSlotsDistributor",{attrs:{"slot-key":this.$parent.slotKey}},[t("p",[t("img",{attrs:{src:"https://raw.githubusercontent.com/jacky1234/picArchieve/master/uPic/9ybw5i.jpg",alt:"大纲"}})]),this._v(" "),t("h2",{attrs:{id:"参考"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#参考"}},[this._v("#")]),this._v(" 参考")]),this._v(" "),t("ul",[t("li",[t("a",{attrs:{href:"https://juejin.cn/post/6844903972587716621",target:"_blank",rel:"noopener noreferrer"}},[this._v("深入探索Android稳定性优化"),t("OutboundLink")],1)])])])}),[],!1,null,null,null);r.default=n.exports}}]); \ No newline at end of file diff --git a/assets/js/123.d7a6cea8.js b/assets/js/123.d7a6cea8.js new file mode 100644 index 0000000000..800a7deff3 --- /dev/null +++ b/assets/js/123.d7a6cea8.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[123],{449:function(t,e,i){"use strict";i.r(e);var a=i(4),n=Object(a.a)({},(function(){var t=this,e=t._self._c;return e("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[e("h2",{attrs:{id:"runtime-getmemory-与-activitymanager-memoryinfo"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#runtime-getmemory-与-activitymanager-memoryinfo"}},[t._v("#")]),t._v(" Runtime getMemory 与 ActivityManager.MemoryInfo")]),t._v(" "),e("p",[t._v("在 Android 中,你可以使用不同的 API 来获取设备的内存信息,其中包括 Runtime 类的 getRuntime()方法和 ActivityManager.MemoryInfo 类。它们各自用于不同的内存信息获取目的,以下是它们之间的区别:")]),t._v(" "),e("ol",[e("li",[e("code",[t._v("Runtime.getFreeMemory()")]),t._v("、"),e("code",[t._v("Runtime.totalMemory()")]),t._v(" 和 "),e("code",[t._v("Runtime.maxMemory()")]),t._v(":")])]),t._v(" "),e("ul",[e("li",[t._v("Runtime 是 Java 标准库的一部分,而不是 Android 特定的 API。它提供了一种在 Java 虚拟机中获取内存信息的方式。")]),t._v(" "),e("li",[t._v("Runtime.getRuntime().freeMemory()返回当前可用的内存大小,它表示 Java 虚拟机中当前空闲的内存。")]),t._v(" "),e("li",[t._v("Runtime.getRuntime().totalMemory()返回 Java 虚拟机当前已分配的总内存大小。")]),t._v(" "),e("li",[t._v("Runtime.getRuntime().maxMemory()返回 Java 虚拟机试图使用的最大内存大小。")])]),t._v(" "),e("p",[t._v("这些方法主要用于监测应用在 Java 虚拟机中的内存使用情况,而不是整个设备的内存信息。在 Android 中,通常更推荐使用 Android 特定的内存管理 API 来获取设备内存信息。")]),t._v(" "),e("ol",{attrs:{start:"2"}},[e("li",[e("code",[t._v("ActivityManager.MemoryInfo")]),t._v(":")])]),t._v(" "),e("ul",[e("li",[t._v("ActivityManager.MemoryInfo 是 Android 的 API,它提供了关于设备内存的详细信息。")]),t._v(" "),e("li",[t._v("通过创建 ActivityManager.MemoryInfo 的实例,并使用 ActivityManager 的 getMemoryInfo()方法,你可以获取包括总内存、可用内存、低内存阈值等在内的更多内存信息。")]),t._v(" "),e("li",[t._v("这些信息有助于你监测设备上的内存使用情况,以便更好地管理应用程序的资源,并在必要时采取措施来释放内存。")])]),t._v(" "),e("p",[t._v("总的来说,Runtime 类的方法主要用于监测 Java 虚拟机内存,而 ActivityManager.MemoryInfo 用于监测设备上的系统内存。如果你关心应用程序在设备上的内存使用情况,通常更建议使用 ActivityManager.MemoryInfo 来获取内存信息,因为它提供了更多关于设备内存状态的详细信息,有助于更好地优化你的应用程序。")])])}),[],!1,null,null,null);e.default=n.exports}}]); \ No newline at end of file diff --git a/assets/js/124.ed03c543.js b/assets/js/124.ed03c543.js new file mode 100644 index 0000000000..51d4ef5438 --- /dev/null +++ b/assets/js/124.ed03c543.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[124],{450:function(t,s,r){"use strict";r.r(s);var e=r(4),n=Object(e.a)({},(function(){var t=this._self._c;return t("ContentSlotsDistributor",{attrs:{"slot-key":this.$parent.slotKey}},[t("h2",{attrs:{id:"参考"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#参考"}},[this._v("#")]),this._v(" 参考")]),this._v(" "),t("ul",[t("li",[t("a",{attrs:{href:"https://juejin.cn/post/7134904047080865805",target:"_blank",rel:"noopener noreferrer"}},[this._v("百度 App 低端机优化-启动性能优化(概述篇)"),t("OutboundLink")],1)])])])}),[],!1,null,null,null);s.default=n.exports}}]); \ No newline at end of file diff --git a/assets/js/125.51f4a6cc.js b/assets/js/125.51f4a6cc.js new file mode 100644 index 0000000000..7718dc326e --- /dev/null +++ b/assets/js/125.51f4a6cc.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[125],{451:function(t,s,n){"use strict";n.r(s);var o=n(4),e=Object(o.a)({},(function(){var t=this._self._c;return t("ContentSlotsDistributor",{attrs:{"slot-key":this.$parent.slotKey}},[t("blockquote",[t("p",[this._v("https://juejin.cn/post/6844904031077482509")])]),this._v(" "),t("p",[this._v("【总结】:所谓 Retrofit 就是利用了注解和动态代理两大方法 ,注解用来标识一个个不同的 Http 请求的模型(所谓模型就是一个 http 请求所必要的参数比如 url,是 get 还是 post 还是其他方法,参数样式如何,等),然后利用动态代理将注解出来的值一个个组成我们需要的 OKhttpCall,等于替代了原生 OkHttp 拼装 url,参数以及返回值解析等大量的重复代码工作,并且可读性更好")])])}),[],!1,null,null,null);s.default=e.exports}}]); \ No newline at end of file diff --git a/assets/js/126.ea9e102c.js b/assets/js/126.ea9e102c.js new file mode 100644 index 0000000000..8d95ea5e3f --- /dev/null +++ b/assets/js/126.ea9e102c.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[126],{452:function(t,e,r){"use strict";r.r(e);var n=r(4),o=Object(n.a)({},(function(){var t=this._self._c;return t("ContentSlotsDistributor",{attrs:{"slot-key":this.$parent.slotKey}},[t("h2",{attrs:{id:"链接"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#链接"}},[this._v("#")]),this._v(" 链接")]),this._v(" "),t("ul",[t("li",[this._v("官方文档\n"),t("ul",[t("li",[t("a",{attrs:{href:"https://developer.apple.com/documentation",target:"_blank",rel:"noopener noreferrer"}},[this._v("document"),t("OutboundLink")],1)]),this._v(" "),t("li",[t("a",{attrs:{href:"https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/ProgrammingWithObjectiveC/Introduction/Introduction.html",target:"_blank",rel:"noopener noreferrer"}},[this._v("OC"),t("OutboundLink")],1)])])])])])}),[],!1,null,null,null);e.default=o.exports}}]); \ No newline at end of file diff --git a/assets/js/127.0d747633.js b/assets/js/127.0d747633.js new file mode 100644 index 0000000000..c6d1b7538e --- /dev/null +++ b/assets/js/127.0d747633.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[127],{453:function(t,s,a){"use strict";a.r(s);var n=a(4),e=Object(n.a)({},(function(){var t=this,s=t._self._c;return s("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[s("h2",{attrs:{id:"setuptools-打包"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#setuptools-打包"}},[t._v("#")]),t._v(" setuptools 打包")]),t._v(" "),s("div",{staticClass:"custom-block tip"},[s("p",{staticClass:"custom-block-title"},[t._v("提示")]),t._v(" "),s("p",[t._v("要打包 Python 脚本,你可以使用 Python 的内置模块 "),s("code",[t._v("distutils")]),t._v(" 或第三方模块 "),s("code",[t._v("setuptools")]),t._v("。这些工具可用于创建可分发的 Python 软件包,以便其他人可以轻松安装和使用你的脚本。")]),t._v(" "),s("p",[t._v("下面的例子也是基于 "),s("code",[t._v("setuptools")]),t._v(" 展开")]),t._v(" "),s("ul",[s("li",[s("code",[t._v("setuptools")]),t._v(": Easily download, build, install, upgrade, and uninstall Python packages. 更多内容请参阅"),s("a",{attrs:{href:"https://pypi.org/project/setuptools/",target:"_blank",rel:"noopener noreferrer"}},[t._v("官方文档"),s("OutboundLink")],1),t._v("。")])])]),t._v(" "),s("h3",{attrs:{id:"打包"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#打包"}},[t._v("#")]),t._v(" 打包")]),t._v(" "),s("p",[t._v("下面是使用 "),s("code",[t._v("setuptools")]),t._v(" 工具 创建 Python 脚本的示例:")]),t._v(" "),s("p",[t._v("1.确保你的项目目录结构如下所示:")]),t._v(" "),s("div",{staticClass:"language-lua line-numbers-mode"},[s("pre",{pre:!0,attrs:{class:"language-lua"}},[s("code",[t._v("my_script"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("|")]),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("-- setup.py")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("|")]),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("-- my_script/")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("|")]),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("-- __init__.py")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("|")]),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("-- script.py")]),t._v("\n")])]),t._v(" "),s("div",{staticClass:"line-numbers-wrapper"},[s("span",{staticClass:"line-number"},[t._v("1")]),s("br"),s("span",{staticClass:"line-number"},[t._v("2")]),s("br"),s("span",{staticClass:"line-number"},[t._v("3")]),s("br"),s("span",{staticClass:"line-number"},[t._v("4")]),s("br"),s("span",{staticClass:"line-number"},[t._v("5")]),s("br")])]),s("p",[t._v("2.在项目根目录下创建 "),s("code",[t._v("setup.py")]),t._v(" 文件,并添加以下内容:")]),t._v(" "),s("div",{staticClass:"language-python line-numbers-mode"},[s("pre",{pre:!0,attrs:{class:"language-python"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("from")]),t._v(" setuptools "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" setup\n\nsetup"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n name"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'my_script'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n version"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'1.0'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n packages"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'my_script'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n install_requires"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n entry_points"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'console_scripts'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'aaa = my_script.script:main'")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])]),t._v(" "),s("div",{staticClass:"line-numbers-wrapper"},[s("span",{staticClass:"line-number"},[t._v("1")]),s("br"),s("span",{staticClass:"line-number"},[t._v("2")]),s("br"),s("span",{staticClass:"line-number"},[t._v("3")]),s("br"),s("span",{staticClass:"line-number"},[t._v("4")]),s("br"),s("span",{staticClass:"line-number"},[t._v("5")]),s("br"),s("span",{staticClass:"line-number"},[t._v("6")]),s("br"),s("span",{staticClass:"line-number"},[t._v("7")]),s("br"),s("span",{staticClass:"line-number"},[t._v("8")]),s("br"),s("span",{staticClass:"line-number"},[t._v("9")]),s("br"),s("span",{staticClass:"line-number"},[t._v("10")]),s("br"),s("span",{staticClass:"line-number"},[t._v("11")]),s("br"),s("span",{staticClass:"line-number"},[t._v("12")]),s("br"),s("span",{staticClass:"line-number"},[t._v("13")]),s("br"),s("span",{staticClass:"line-number"},[t._v("14")]),s("br"),s("span",{staticClass:"line-number"},[t._v("15")]),s("br")])]),s("p",[t._v("在 setup 函数中,你需要指定包的名称、版本号、包含的模块等信息。")]),t._v(" "),s("ul",[s("li",[s("code",[t._v("install_requires")]),t._v("参数用于指定项目的依赖项,这些依赖项将在安装项目时自动安装")]),t._v(" "),s("li",[s("code",[t._v("entry_points")]),t._v(" 部分用于将你的脚本与可执行命令关联起来")])]),t._v(" "),s("p",[t._v("通过上面的配置打包后,当你安装软件包并在终端中运行 "),s("code",[t._v("aaa")]),t._v(" 命令时,将执行 my_script.script 模块中的 "),s("code",[t._v("main")]),t._v(" 函数。")]),t._v(" "),s("p",[t._v("3.在 my_script 目录下创建 "),s("code",[t._v("__init__.py")]),t._v(" 文件,可以留空。")]),t._v(" "),s("p",[t._v("4.在 my_script 目录下创建你的 Python 脚本文件 "),s("code",[t._v("script.py")]),t._v(",并添加你的脚本代码。例如:")]),t._v(" "),s("div",{staticClass:"language-python line-numbers-mode"},[s("pre",{pre:!0,attrs:{class:"language-python"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("def")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("main")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("print")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Hello, World!"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" __name__ "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'__main__'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v("\n main"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n")])]),t._v(" "),s("div",{staticClass:"line-numbers-wrapper"},[s("span",{staticClass:"line-number"},[t._v("1")]),s("br"),s("span",{staticClass:"line-number"},[t._v("2")]),s("br"),s("span",{staticClass:"line-number"},[t._v("3")]),s("br"),s("span",{staticClass:"line-number"},[t._v("4")]),s("br"),s("span",{staticClass:"line-number"},[t._v("5")]),s("br"),s("span",{staticClass:"line-number"},[t._v("6")]),s("br")])]),s("p",[t._v("5.打开终端,导航到项目根目录,并运行以下命令来构建软件包:")]),t._v(" "),s("div",{staticClass:"language-shell line-numbers-mode"},[s("pre",{pre:!0,attrs:{class:"language-shell"}},[s("code",[t._v("python setup.py sdist\n")])]),t._v(" "),s("div",{staticClass:"line-numbers-wrapper"},[s("span",{staticClass:"line-number"},[t._v("1")]),s("br")])]),s("p",[t._v("这将在 dist 目录中生成一个压缩文件,其中包含你的软件包。")]),t._v(" "),s("p",[t._v("6.如果你希望其他人能够使用 pip 命令安装你的软件包,可以将软件包上传到 PyPI 或创建一个本地仓库。要上传到 PyPI,请按照官方文档中的说明进行操作。如果要创建本地仓库,可以使用工具如 devpi 或 twine。")]),t._v(" "),s("h3",{attrs:{id:"安装"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#安装"}},[t._v("#")]),t._v(" 安装")]),t._v(" "),s("p",[t._v("经过上面的流程后安装包位置在 "),s("code",[t._v("./dist/my_script-1.0.tar.gz")]),t._v(". 通过 "),s("code",[t._v("pip3")]),t._v(" 命令安装")]),t._v(" "),s("div",{staticClass:"language-shell line-numbers-mode"},[s("pre",{pre:!0,attrs:{class:"language-shell"}},[s("code",[t._v("pip3 "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("install")]),t._v(" dist/my_script-1.0.tar.gz\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("# 强制重新安装")]),t._v("\npip3 "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("install")]),t._v(" dist/my_script-1.0.tar.gz --force-reinstall\n")])]),t._v(" "),s("div",{staticClass:"line-numbers-wrapper"},[s("span",{staticClass:"line-number"},[t._v("1")]),s("br"),s("span",{staticClass:"line-number"},[t._v("2")]),s("br"),s("span",{staticClass:"line-number"},[t._v("3")]),s("br")])]),s("p",[t._v("之后应该就可以正常上使用上面的 "),s("code",[t._v("aaa")]),t._v(" 命令了")]),t._v(" "),s("h2",{attrs:{id:"概念"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#概念"}},[t._v("#")]),t._v(" 概念")]),t._v(" "),s("h3",{attrs:{id:"init-py文件"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#init-py文件"}},[t._v("#")]),t._v(" "),s("code",[t._v("__init__.py")]),t._v("文件")]),t._v(" "),s("p",[t._v("在 Python 中,"),s("code",[t._v("__init__.py")]),t._v("是一个特殊的文件,用于标识一个目录作为 Python 包。当一个目录中包含了"),s("code",[t._v("__init__.py")]),t._v("文件时,Python 会将该目录视为一个包,并可以通过导入该包来访问其中的模块和资源。")]),t._v(" "),s("p",[t._v("以下是"),s("code",[t._v("__init__.py")]),t._v("文件的一些常见用途:")]),t._v(" "),s("ol",[s("li",[t._v("声明包级别的初始化代码:你可以在"),s("code",[t._v("__init__.py")]),t._v("文件中编写一些需要在导入包时执行的初始化代码。这些代码可以包括变量初始化、设置环境、导入子模块等。")]),t._v(" "),s("li",[t._v("导入模块:在"),s("code",[t._v("__init__.py")]),t._v("文件中,你可以导入该包下的模块,使得在导入包时可以直接访问这些模块。这样,在导入包时,你可以使用更方便的包级别导入方式,而不需要逐个导入每个模块。")]),t._v(" "),s("li",[t._v("定义包的接口:"),s("code",[t._v("__init__.py")]),t._v("文件可以作为包的接口,提供外部使用该包时的接口定义。你可以在该文件中选择性地导入并重新导出包内的模块、类、函数等,从而控制外部对包的可见性。")])]),t._v(" "),s("p",[t._v("需要注意的是,"),s("code",[t._v("__init__.py")]),t._v("文件并非必需的。在 Python 3.3 及以上的版本中,如果你的目录仅作为包的容器而不包含额外的初始化代码或接口定义,可以省略"),s("code",[t._v("__init__.py")]),t._v("文件。在这种情况下,Python 仍会将目录视为包,但它将是一个隐式的包。")]),t._v(" "),s("p",[t._v("总之,"),s("code",[t._v("__init__.py")]),t._v("文件是用于标识一个目录作为 Python 包的文件,在其中可以编写初始化代码、导入模块以及定义包的接口。")]),t._v(" "),s("h2",{attrs:{id:"链接"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#链接"}},[t._v("#")]),t._v(" 链接")]),t._v(" "),s("ul",[s("li",[s("a",{attrs:{href:"https://docs.python.org/3/tutorial/index.html",target:"_blank",rel:"noopener noreferrer"}},[t._v("python tutorial"),s("OutboundLink")],1)]),t._v(" "),s("li",[s("a",{attrs:{href:"https://github.com/jacky1234/learnPython",target:"_blank",rel:"noopener noreferrer"}},[t._v("learnPython"),s("OutboundLink")],1)]),t._v(" "),s("li",[s("a",{attrs:{href:"https://github.com/lgwsgc/python",target:"_blank",rel:"noopener noreferrer"}},[t._v("https://github.com/lgwsgc/python"),s("OutboundLink")],1)]),t._v(" "),s("li",[s("a",{attrs:{href:"https://github.com/jacky1234/python_script",target:"_blank",rel:"noopener noreferrer"}},[t._v("https://github.com/jacky1234/python_script"),s("OutboundLink")],1)]),t._v(" "),s("li",[s("a",{attrs:{href:"https://github.com/lijin-THU/notes-python",target:"_blank",rel:"noopener noreferrer"}},[t._v("https://github.com/lijin-THU/notes-python"),s("OutboundLink")],1)])])])}),[],!1,null,null,null);s.default=e.exports}}]); \ No newline at end of file diff --git a/assets/js/128.080e33e7.js b/assets/js/128.080e33e7.js new file mode 100644 index 0000000000..08f4f222cf --- /dev/null +++ b/assets/js/128.080e33e7.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[128],{454:function(s,t,a){"use strict";a.r(t);var n=a(4),r=Object(n.a)({},(function(){var s=this,t=s._self._c;return t("ContentSlotsDistributor",{attrs:{"slot-key":s.$parent.slotKey}},[t("h2",{attrs:{id:"格式化"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#格式化"}},[s._v("#")]),s._v(" 格式化")]),s._v(" "),t("h3",{attrs:{id:"f-strings"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#f-strings"}},[s._v("#")]),s._v(" f-strings")]),s._v(" "),t("blockquote",[t("p",[s._v("Formatted string literals (also called f-strings for short) let you include the value of Python expressions inside a string by prefixing the string with f or F and writing expressions as {expression}.\n"),t("a",{attrs:{href:"https://docs.python.org/3/tutorial/inputoutput.html#the-string-format-method",target:"_blank",rel:"noopener noreferrer"}},[s._v("内容导航"),t("OutboundLink")],1)])]),s._v(" "),t("div",{staticClass:"language-python line-numbers-mode"},[t("pre",{pre:!0,attrs:{class:"language-python"}},[t("code",[s._v("name "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token string"}},[s._v("'knights'")]),s._v("\nword "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token string"}},[s._v("'Ni'")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("print")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token string-interpolation"}},[t("span",{pre:!0,attrs:{class:"token string"}},[s._v("f'We are the ")]),t("span",{pre:!0,attrs:{class:"token interpolation"}},[t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("name"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")])]),t("span",{pre:!0,attrs:{class:"token string"}},[s._v(' who say "')]),t("span",{pre:!0,attrs:{class:"token interpolation"}},[t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("word"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")])]),t("span",{pre:!0,attrs:{class:"token string"}},[s._v("!\"'")])]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v("\n")])]),s._v(" "),t("div",{staticClass:"line-numbers-wrapper"},[t("span",{staticClass:"line-number"},[s._v("1")]),t("br"),t("span",{staticClass:"line-number"},[s._v("2")]),t("br"),t("span",{staticClass:"line-number"},[s._v("3")]),t("br")])]),t("p",[s._v("二、条件表达")]),s._v(" "),t("blockquote",[t("p",[t("code",[s._v("{expression if condition else expression}")])])]),s._v(" "),t("div",{staticClass:"language-python line-numbers-mode"},[t("pre",{pre:!0,attrs:{class:"language-python"}},[t("code",[s._v("isMarkdown "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token boolean"}},[s._v("True")]),s._v("\nname "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token string"}},[s._v("'John'")]),s._v("\n\nformatted_string "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token string-interpolation"}},[t("span",{pre:!0,attrs:{class:"token string"}},[s._v('f"Hello, ')]),t("span",{pre:!0,attrs:{class:"token interpolation"}},[t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("name"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")])]),t("span",{pre:!0,attrs:{class:"token string"}},[s._v('{ "')])]),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("**")]),t("span",{pre:!0,attrs:{class:"token string"}},[s._v('""')]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("if")]),s._v(" isMarkdown "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("else")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token string"}},[s._v('""')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v('!"\n'),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("print")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("formatted_string"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v("\n")])]),s._v(" "),t("div",{staticClass:"line-numbers-wrapper"},[t("span",{staticClass:"line-number"},[s._v("1")]),t("br"),t("span",{staticClass:"line-number"},[s._v("2")]),t("br"),t("span",{staticClass:"line-number"},[s._v("3")]),t("br"),t("span",{staticClass:"line-number"},[s._v("4")]),t("br"),t("span",{staticClass:"line-number"},[s._v("5")]),t("br")])]),t("h3",{attrs:{id:"str-format"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#str-format"}},[s._v("#")]),s._v(" str.format()")]),s._v(" "),t("h3",{attrs:{id:"old-string-formatting"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#old-string-formatting"}},[s._v("#")]),s._v(" Old string formatting")]),s._v(" "),t("blockquote",[t("p",[s._v("使用 % 符号")])]),s._v(" "),t("div",{staticClass:"language-shell line-numbers-mode"},[t("pre",{pre:!0,attrs:{class:"language-shell"}},[t("code",[t("span",{pre:!0,attrs:{class:"token operator"}},[s._v(">>")]),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v(">")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("import")]),s._v(" math\n"),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v(">>")]),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v(">")]),s._v(" print"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token string"}},[s._v("'The value of pi is approximately %5.3f.'")]),s._v(" % math.pi"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v("\nThe value of pi is approximately "),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("3.142")]),s._v(".\n")])]),s._v(" "),t("div",{staticClass:"line-numbers-wrapper"},[t("span",{staticClass:"line-number"},[s._v("1")]),t("br"),t("span",{staticClass:"line-number"},[s._v("2")]),t("br"),t("span",{staticClass:"line-number"},[s._v("3")]),t("br")])])])}),[],!1,null,null,null);t.default=r.exports}}]); \ No newline at end of file diff --git a/assets/js/129.da1e979c.js b/assets/js/129.da1e979c.js new file mode 100644 index 0000000000..518aeb7483 --- /dev/null +++ b/assets/js/129.da1e979c.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[129],{455:function(e,s,t){"use strict";t.r(s);var a=t(4),n=Object(a.a)({},(function(){var e=this,s=e._self._c;return s("ContentSlotsDistributor",{attrs:{"slot-key":e.$parent.slotKey}},[s("h2",{attrs:{id:"断言"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#断言"}},[e._v("#")]),e._v(" 断言")]),e._v(" "),s("blockquote",[s("p",[s("a",{attrs:{href:"https://github.com/hluwa/Wallbreaker/blob/master/wallbreaker/connection.py",target:"_blank",rel:"noopener noreferrer"}},[e._v("https://github.com/hluwa/Wallbreaker/blob/master/wallbreaker/connection.py"),s("OutboundLink")],1)])]),e._v(" "),s("div",{staticClass:"language-python line-numbers-mode"},[s("pre",{pre:!0,attrs:{class:"language-python"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[e._v("try")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(":")]),e._v("\n device "),s("span",{pre:!0,attrs:{class:"token operator"}},[e._v("=")]),e._v(" frida"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(".")]),e._v("get_usb_device"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(")")]),e._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[e._v("if")]),e._v(" device "),s("span",{pre:!0,attrs:{class:"token keyword"}},[e._v("is")]),e._v(" "),s("span",{pre:!0,attrs:{class:"token boolean"}},[e._v("None")]),e._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[e._v("else")]),e._v(" device\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[e._v("except")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(":")]),e._v("\n device "),s("span",{pre:!0,attrs:{class:"token operator"}},[e._v("=")]),e._v(" frida"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(".")]),e._v("get_remote_device"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(")")]),e._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[e._v("if")]),e._v(" device "),s("span",{pre:!0,attrs:{class:"token keyword"}},[e._v("is")]),e._v(" "),s("span",{pre:!0,attrs:{class:"token boolean"}},[e._v("None")]),e._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[e._v("else")]),e._v(" device\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[e._v("assert")]),e._v(" device"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(",")]),e._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[e._v('"Unable to connect android device"')]),e._v("\n")])]),e._v(" "),s("div",{staticClass:"line-numbers-wrapper"},[s("span",{staticClass:"line-number"},[e._v("1")]),s("br"),s("span",{staticClass:"line-number"},[e._v("2")]),s("br"),s("span",{staticClass:"line-number"},[e._v("3")]),s("br"),s("span",{staticClass:"line-number"},[e._v("4")]),s("br"),s("span",{staticClass:"line-number"},[e._v("5")]),s("br")])]),s("p",[e._v("说明")]),e._v(" "),s("ul",[s("li",[s("code",[e._v("device = frida.get_usb_device() if device is None else device")]),e._v(":这是一个条件语句,用于获取 USB 连接的 Frida 设备对象。如果在之前的代码中已经定义了 device 变量,那么不再执行 "),s("code",[e._v("frida.get_usb_device()")]),e._v(",而直接使用已有的 device。 (后置 if 条件写法,也被称为条件表达式或三元条件表达式)。等价于:")])]),e._v(" "),s("div",{staticClass:"language- line-numbers-mode"},[s("pre",{pre:!0,attrs:{class:"language-text"}},[s("code",[e._v("if device is None:\n device = frida.get_usb_device()\n")])]),e._v(" "),s("div",{staticClass:"line-numbers-wrapper"},[s("span",{staticClass:"line-number"},[e._v("1")]),s("br"),s("span",{staticClass:"line-number"},[e._v("2")]),s("br")])])])}),[],!1,null,null,null);s.default=n.exports}}]); \ No newline at end of file diff --git a/assets/js/13.fc723977.js b/assets/js/13.fc723977.js new file mode 100644 index 0000000000..3d8c21abc2 --- /dev/null +++ b/assets/js/13.fc723977.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[13,15,25,37],{251:function(t,e,i){},252:function(t,e,i){"use strict";i.r(e);var n=i(11),s={props:{item:{required:!0}},computed:{link(){return Object(n.c)(this.item.link)},exact(){return this.$site.locales?Object.keys(this.$site.locales).some(t=>t===this.link):"/"===this.link}},methods:{isExternal:n.g,isMailto:n.h,isTel:n.i,focusoutAction(){this.$emit("focusout")}}},o=i(4),r=Object(o.a)(s,(function(){var t=this,e=t._self._c;return t.isExternal(t.link)?e("a",{staticClass:"nav-link external",attrs:{href:t.link,target:t.isMailto(t.link)||t.isTel(t.link)?null:"_blank",rel:t.isMailto(t.link)||t.isTel(t.link)?null:"noopener noreferrer"},on:{focusout:t.focusoutAction}},[t._v("\n "+t._s(t.item.text)+"\n "),e("OutboundLink")],1):e("router-link",{staticClass:"nav-link",attrs:{to:t.link,exact:t.exact},nativeOn:{focusout:function(e){return t.focusoutAction.apply(null,arguments)}}},[t._v(t._s(t.item.text))])}),[],!1,null,null,null);e.default=r.exports},253:function(t,e,i){},254:function(t,e,i){"use strict";i.r(e);var n={name:"DropdownTransition",methods:{setHeight(t){t.style.height=t.scrollHeight+"px"},unsetHeight(t){t.style.height=""}}},s=(i(255),i(4)),o=Object(s.a)(n,(function(){return(0,this._self._c)("transition",{attrs:{name:"dropdown"},on:{enter:this.setHeight,"after-enter":this.unsetHeight,"before-leave":this.setHeight}},[this._t("default")],2)}),[],!1,null,null,null);e.default=o.exports},255:function(t,e,i){"use strict";i(251)},259:function(t,e,i){},261:function(t,e,i){"use strict";i(253)},269:function(t,e,i){"use strict";i.r(e);var n=i(252),s=i(254),o=i(97),r=i.n(o),a={components:{NavLink:n.default,DropdownTransition:s.default},data:()=>({open:!1,isMQMobile:!1}),props:{item:{required:!0}},computed:{dropdownAriaLabel(){return this.item.ariaLabel||this.item.text}},beforeMount(){this.isMQMobile=window.innerWidth<720,window.addEventListener("resize",()=>{this.isMQMobile=window.innerWidth<720})},methods:{toggle(){this.isMQMobile&&(this.open=!this.open)},isLastItemOfArray:(t,e)=>r()(e)===t},watch:{$route(){this.open=!1}}},l=(i(261),i(4)),u=Object(l.a)(a,(function(){var t=this,e=t._self._c;return e("div",{staticClass:"dropdown-wrapper",class:{open:t.open}},[e("button",{staticClass:"dropdown-title",attrs:{type:"button","aria-label":t.dropdownAriaLabel},on:{click:t.toggle}},[t.item.link?e("router-link",{staticClass:"link-title",attrs:{to:t.item.link}},[t._v(t._s(t.item.text))]):t._e(),t._v(" "),e("span",{directives:[{name:"show",rawName:"v-show",value:!t.item.link,expression:"!item.link"}],staticClass:"title"},[t._v(t._s(t.item.text))]),t._v(" "),e("span",{staticClass:"arrow",class:t.open?"down":"right"})],1),t._v(" "),e("DropdownTransition",[e("ul",{directives:[{name:"show",rawName:"v-show",value:t.open,expression:"open"}],staticClass:"nav-dropdown"},t._l(t.item.items,(function(i,n){return e("li",{key:i.link||n,staticClass:"dropdown-item"},["links"===i.type?e("h4",[t._v(t._s(i.text))]):t._e(),t._v(" "),"links"===i.type?e("ul",{staticClass:"dropdown-subitem-wrapper"},t._l(i.items,(function(n){return e("li",{key:n.link,staticClass:"dropdown-subitem"},[e("NavLink",{attrs:{item:n},on:{focusout:function(e){t.isLastItemOfArray(n,i.items)&&t.isLastItemOfArray(i,t.item.items)&&t.toggle()}}})],1)})),0):e("NavLink",{attrs:{item:i},on:{focusout:function(e){t.isLastItemOfArray(i,t.item.items)&&t.toggle()}}})],1)})),0)])],1)}),[],!1,null,null,null);e.default=u.exports},274:function(t,e,i){"use strict";i(259)},276:function(t,e,i){"use strict";i.r(e);var n=i(269),s=i(11),o={components:{NavLink:i(252).default,DropdownLink:n.default},computed:{userNav(){return this.$themeLocaleConfig.nav||this.$site.themeConfig.nav||[]},nav(){const{locales:t}=this.$site;if(t&&Object.keys(t).length>1){const e=this.$page.path,i=this.$router.options.routes,n=this.$site.themeConfig.locales||{},s={text:this.$themeLocaleConfig.selectText||"Languages",ariaLabel:this.$themeLocaleConfig.ariaLabel||"Select language",items:Object.keys(t).map(s=>{const o=t[s],r=n[s]&&n[s].label||o.lang;let a;return o.lang===this.$lang?a=e:(a=e.replace(this.$localeConfig.path,s),i.some(t=>t.path===a)||(a=s)),{text:r,link:a}})};return[...this.userNav,s]}return this.userNav},userLinks(){return(this.nav||[]).map(t=>Object.assign(Object(s.k)(t),{items:(t.items||[]).map(s.k)}))},repoLink(){const{repo:t}=this.$site.themeConfig;return t?/^https?:/.test(t)?t:"https://github.com/"+t:null},repoLabel(){if(!this.repoLink)return;if(this.$site.themeConfig.repoLabel)return this.$site.themeConfig.repoLabel;const t=this.repoLink.match(/^https?:\/\/[^/]+/)[0],e=["GitHub","GitLab","Bitbucket"];for(let i=0;i")]),s._v("/dev/null "),a("span",{pre:!0,attrs:{class:"token operator"}},[a("span",{pre:!0,attrs:{class:"token file-descriptor important"}},[s._v("2")]),s._v(">")]),a("span",{pre:!0,attrs:{class:"token file-descriptor important"}},[s._v("&1")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("then")]),s._v("\n "),a("span",{pre:!0,attrs:{class:"token builtin class-name"}},[s._v("eval")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[s._v('"'),a("span",{pre:!0,attrs:{class:"token variable"}},[a("span",{pre:!0,attrs:{class:"token variable"}},[s._v("$(")]),s._v("pyenv init -"),a("span",{pre:!0,attrs:{class:"token variable"}},[s._v(")")])]),s._v('"')]),s._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("fi")]),s._v("\n\n"),a("span",{pre:!0,attrs:{class:"token comment"}},[s._v("# 让修改生效")]),s._v("\n"),a("span",{pre:!0,attrs:{class:"token builtin class-name"}},[s._v("source")]),s._v(" ~/.zshrc\n")])]),s._v(" "),a("div",{staticClass:"line-numbers-wrapper"},[a("span",{staticClass:"line-number"},[s._v("1")]),a("br"),a("span",{staticClass:"line-number"},[s._v("2")]),a("br"),a("span",{staticClass:"line-number"},[s._v("3")]),a("br"),a("span",{staticClass:"line-number"},[s._v("4")]),a("br"),a("span",{staticClass:"line-number"},[s._v("5")]),a("br"),a("span",{staticClass:"line-number"},[s._v("6")]),a("br"),a("span",{staticClass:"line-number"},[s._v("7")]),a("br"),a("span",{staticClass:"line-number"},[s._v("8")]),a("br"),a("span",{staticClass:"line-number"},[s._v("9")]),a("br"),a("span",{staticClass:"line-number"},[s._v("10")]),a("br"),a("span",{staticClass:"line-number"},[s._v("11")]),a("br"),a("span",{staticClass:"line-number"},[s._v("12")]),a("br")])]),a("h2",{attrs:{id:"常用命令"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#常用命令"}},[s._v("#")]),s._v(" 常用命令")]),s._v(" "),a("ul",[a("li",[a("code",[s._v("pyenv -h")])]),s._v(" "),a("li",[a("code",[s._v("pyenv versions")]),s._v(": 查看 pyenv 已经管理了哪些 python 版本")]),s._v(" "),a("li",[a("code",[s._v("pyenv install -v ")]),s._v(": 使用 pyenv 安装指定的 Python 版本")]),s._v(" "),a("li",[a("code",[s._v("pyenv global ")]),s._v(": 把 Python 切换到指定版本")]),s._v(" "),a("li",[a("code",[s._v("pyenv local ")])]),s._v(" "),a("li",[a("code",[s._v("pyenv install --list")]),s._v(": 查看 pyenv 当前支持哪些 Python 版本")])])])}),[],!1,null,null,null);a.default=e.exports}}]); \ No newline at end of file diff --git a/assets/js/131.0f269eb9.js b/assets/js/131.0f269eb9.js new file mode 100644 index 0000000000..62d50c9203 --- /dev/null +++ b/assets/js/131.0f269eb9.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[131],{457:function(s,t,a){"use strict";a.r(t);var n=a(4),e=Object(n.a)({},(function(){var s=this,t=s._self._c;return t("ContentSlotsDistributor",{attrs:{"slot-key":s.$parent.slotKey}},[t("h2",{attrs:{id:"获取子元素"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#获取子元素"}},[s._v("#")]),s._v(" 获取子元素")]),s._v(" "),t("p",[s._v("使用 BeautifulSoup,你可以使用 "),t("code",[s._v(".find()")]),s._v(" 方法来获取指定节点的第一个子元素。")]),s._v(" "),t("blockquote",[t("p",[s._v("假设你已经将 HTML 文档解析为 BeautifulSoup 对象,并且你有一个名为 sublineDom 的节点,你可以使用以下方式获取它的第一个子元素:")])]),s._v(" "),t("div",{staticClass:"language-python line-numbers-mode"},[t("pre",{pre:!0,attrs:{class:"language-python"}},[t("code",[s._v("first_child "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" sublineDom"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),s._v("find"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v("\n")])]),s._v(" "),t("div",{staticClass:"line-numbers-wrapper"},[t("span",{staticClass:"line-number"},[s._v("1")]),t("br")])]),t("p",[s._v("上述代码中的 "),t("code",[s._v(".find()")]),s._v(" 方法没有传递任何参数,这将返回 sublineDom 的第一个子元素。如果你希望通过标签名或其他属性来选择子元素,可以将相应的参数传递给 "),t("code",[s._v(".find()")]),s._v(" 方法。")]),s._v(" "),t("p",[s._v("例如")]),s._v(" "),t("ol",[t("li",[s._v("如果你要获取 sublineDom 的第一个 "),t("code",[s._v("
")]),s._v(" 子元素,可以使用以下代码:")])]),s._v(" "),t("div",{staticClass:"language-python line-numbers-mode"},[t("pre",{pre:!0,attrs:{class:"language-python"}},[t("code",[s._v("first"),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("*")]),s._v("div "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" sublineDom"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),s._v("find"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token string"}},[s._v('"div"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v("\n")])]),s._v(" "),t("div",{staticClass:"line-numbers-wrapper"},[t("span",{staticClass:"line-number"},[s._v("1")]),t("br")])]),t("ol",{attrs:{start:"2"}},[t("li",[s._v("如果你希望获取具有特定类名的子元素,可以传递 "),t("code",[s._v("class\\*")]),s._v(" 参数:")])]),s._v(" "),t("div",{staticClass:"language-python line-numbers-mode"},[t("pre",{pre:!0,attrs:{class:"language-python"}},[t("code",[s._v("first"),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("*")]),s._v("child_with_class "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" sublineDom"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),s._v("find"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("class")]),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("*=")]),t("span",{pre:!0,attrs:{class:"token string"}},[s._v('"my-class"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v("\n")])]),s._v(" "),t("div",{staticClass:"line-numbers-wrapper"},[t("span",{staticClass:"line-number"},[s._v("1")]),t("br")])]),t("p",[s._v("请注意,"),t("code",[s._v(".find()")]),s._v(" 方法只返回找到的第一个匹配的子元素。如果你想获取所有匹配的子元素,可以使用 "),t("code",[s._v(".find_all()")]),s._v(" 方法。")]),s._v(" "),t("ol",{attrs:{start:"3"}},[t("li",[s._v("获取子元素的最后一个节点")])]),s._v(" "),t("div",{staticClass:"language-python line-numbers-mode"},[t("pre",{pre:!0,attrs:{class:"language-python"}},[t("code",[s._v("all_children "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" sublineDom"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),s._v("find_all"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v("\n\n"),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("if")]),s._v(" all_children"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(":")]),s._v("\n last_child "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" all_children"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("[")]),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("-")]),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("1")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("]")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("print")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("last_child"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("else")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(":")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("print")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token string"}},[s._v('"sublineDom 没有子元素节点"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v("\n")])]),s._v(" "),t("div",{staticClass:"line-numbers-wrapper"},[t("span",{staticClass:"line-number"},[s._v("1")]),t("br"),t("span",{staticClass:"line-number"},[s._v("2")]),t("br"),t("span",{staticClass:"line-number"},[s._v("3")]),t("br"),t("span",{staticClass:"line-number"},[s._v("4")]),t("br"),t("span",{staticClass:"line-number"},[s._v("5")]),t("br"),t("span",{staticClass:"line-number"},[s._v("6")]),t("br"),t("span",{staticClass:"line-number"},[s._v("7")]),t("br")])]),t("h3",{attrs:{id:"href-正则"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#href-正则"}},[s._v("#")]),s._v(" href 正则")]),s._v(" "),t("blockquote",[t("p",[s._v("使用正则表达式匹配 href 属性的值,以查找满足特定格式的链接。re.compile(r'user?id=') 将会编译一个正则表达式对象,匹配以 user?id= 开头的 href 值")])]),s._v(" "),t("div",{staticClass:"language-python line-numbers-mode"},[t("pre",{pre:!0,attrs:{class:"language-python"}},[t("code",[s._v("sublineDom"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),s._v("find"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token string"}},[s._v('"a"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" href"),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v("re"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token builtin"}},[s._v("compile")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token string"}},[s._v("r'user\\?id='")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v("\n")])]),s._v(" "),t("div",{staticClass:"line-numbers-wrapper"},[t("span",{staticClass:"line-number"},[s._v("1")]),t("br")])]),t("p",[s._v("通过将选择器参数设置为 a 标签,并将 href 属性与正则表达式进行匹配,我们可以定位到所需的节点。")]),s._v(" "),t("h2",{attrs:{id:"获取父元素"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#获取父元素"}},[s._v("#")]),s._v(" 获取父元素")]),s._v(" "),t("p",[s._v("如果你想要在 BeautifulSoup 中进行反向搜索,即从一个节点向上搜索其父节点、祖先节点等,可以使用 "),t("code",[s._v(".find_parents()")]),s._v(" 或 "),t("code",[s._v(".find_parent()")]),s._v(" 方法。)")]),s._v(" "),t("p",[t("code",[s._v(".find_parents()")]),s._v(" 方法返回一个迭代器,用于按顺序返回所有父节点和祖先节点。你可以对迭代器进行循环遍历来处理这些节点。")]),s._v(" "),t("p",[s._v("以下是一个示例代码,展示了如何使用 .find_parents() 方法进行反向搜索:")]),s._v(" "),t("div",{staticClass:"language-python line-numbers-mode"},[t("pre",{pre:!0,attrs:{class:"language-python"}},[t("code",[t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("for")]),s._v(" parent "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("in")]),s._v(" sublineDom"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),s._v("find_parents"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(":")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("print")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("parent"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v("\n")])]),s._v(" "),t("div",{staticClass:"line-numbers-wrapper"},[t("span",{staticClass:"line-number"},[s._v("1")]),t("br"),t("span",{staticClass:"line-number"},[s._v("2")]),t("br")])]),t("p",[s._v("上述代码将打印出 sublineDom 节点的所有父节点和祖先节点。")]),s._v(" "),t("p",[s._v("如果你只想获取第一个父节点或祖先节点,可以使用 "),t("code",[s._v(".find_parent()")]),s._v(" 方法:")]),s._v(" "),t("div",{staticClass:"language-python line-numbers-mode"},[t("pre",{pre:!0,attrs:{class:"language-python"}},[t("code",[s._v("parent "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" sublineDom"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),s._v("find_parent"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("print")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("parent"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v("\n")])]),s._v(" "),t("div",{staticClass:"line-numbers-wrapper"},[t("span",{staticClass:"line-number"},[s._v("1")]),t("br"),t("span",{staticClass:"line-number"},[s._v("2")]),t("br")])]),t("p",[s._v("上述代码将返回 sublineDom 的第一个父节点或祖先节点。")]),s._v(" "),t("p",[s._v("需要注意的是,这些方法会返回与搜索条件匹配的节点,如果你想要进一步筛选结果,可以使用参数来指定标签名、类名等属性。")]),s._v(" "),t("h2",{attrs:{id:"获取兄弟节点"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#获取兄弟节点"}},[s._v("#")]),s._v(" 获取兄弟节点")]),s._v(" "),t("blockquote",[t("p",[t("code",[s._v(".find_next_sibling()")]),s._v(" 方法来获取当前节点的下一个兄弟节点。")])]),s._v(" "),t("p",[s._v("以下是使用 "),t("code",[s._v(".find_next_sibling()")]),s._v(" 方法的示例代码:")]),s._v(" "),t("div",{staticClass:"language-python line-numbers-mode"},[t("pre",{pre:!0,attrs:{class:"language-python"}},[t("code",[s._v("next_sibling "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" sublineDom"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),s._v("find_next_sibling"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v("\n")])]),s._v(" "),t("div",{staticClass:"line-numbers-wrapper"},[t("span",{staticClass:"line-number"},[s._v("1")]),t("br")])]),t("p",[s._v("上述代码中的 "),t("code",[s._v(".find_next_sibling()")]),s._v(" 方法没有传递任何参数,它将返回 sublineDom 的下一个兄弟节点。如果 sublineDom 没有下一个兄弟节点,则返回 None。")]),s._v(" "),t("p",[s._v("如果你希望通过标签名或其他属性来选择下一个兄弟节点,可以将相应的参数传递给 .find_next_sibling() 方法。")]),s._v(" "),t("p",[s._v("例如,如果你要获取 sublineDom 的下一个 "),t("code",[s._v("
")]),s._v(" 兄弟节点,可以使用以下代码:")]),s._v(" "),t("div",{staticClass:"language-python line-numbers-mode"},[t("pre",{pre:!0,attrs:{class:"language-python"}},[t("code",[t("span",{pre:!0,attrs:{class:"token builtin"}},[s._v("next")]),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("*")]),s._v("div_sibling "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" sublineDom"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),s._v("find_next_sibling"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token string"}},[s._v('"div"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v("\n")])]),s._v(" "),t("div",{staticClass:"line-numbers-wrapper"},[t("span",{staticClass:"line-number"},[s._v("1")]),t("br")])]),t("p",[s._v("如果你希望获取具有特定类名的下一个兄弟节点,可以传递 "),t("code",[s._v("class\\*")]),s._v(" 参数:")]),s._v(" "),t("div",{staticClass:"language-python line-numbers-mode"},[t("pre",{pre:!0,attrs:{class:"language-python"}},[t("code",[t("span",{pre:!0,attrs:{class:"token builtin"}},[s._v("next")]),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("*")]),s._v("sibling_with_class "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" sublineDom"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),s._v("find_next_sibling"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("class")]),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("*=")]),t("span",{pre:!0,attrs:{class:"token string"}},[s._v('"my-class"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v("\n")])]),s._v(" "),t("div",{staticClass:"line-numbers-wrapper"},[t("span",{staticClass:"line-number"},[s._v("1")]),t("br")])]),t("p",[s._v("请注意,"),t("code",[s._v(".find_next_sibling()")]),s._v(" 方法只返回找到的第一个匹配的兄弟节点。如果你想获取所有匹配的兄弟节点,可以使用 "),t("code",[s._v(".find_next_siblings()")]),s._v(" 方法。")])])}),[],!1,null,null,null);t.default=e.exports}}]); \ No newline at end of file diff --git a/assets/js/132.da58fe07.js b/assets/js/132.da58fe07.js new file mode 100644 index 0000000000..b35545f632 --- /dev/null +++ b/assets/js/132.da58fe07.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[132],{458:function(t,s,a){"use strict";a.r(s);var e=a(4),n=Object(e.a)({},(function(){var t=this,s=t._self._c;return s("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[s("h2",{attrs:{id:"usecontext"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#usecontext"}},[t._v("#")]),t._v(" useContext")]),t._v(" "),s("blockquote",[s("p",[t._v("useContext is a React Hook that lets you read and subscribe to context from your component.")])]),t._v(" "),s("p",[t._v("TODO")]),t._v(" "),s("h2",{attrs:{id:"useimperativehandle"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#useimperativehandle"}},[t._v("#")]),t._v(" useImperativeHandle")]),t._v(" "),s("blockquote",[s("p",[t._v("useImperativeHandle is a React Hook that lets you customize the handle exposed as a ref. "),s("a",{attrs:{href:"https://react.dev/reference/react/useImperativeHandle",target:"_blank",rel:"noopener noreferrer"}},[t._v("forward"),s("OutboundLink")],1)])]),t._v(" "),s("p",[s("strong",[t._v("在函数组件中使用 "),s("code",[t._v("forwardRef")]),t._v(" 和 "),s("code",[t._v("useImperativeHandle")]),t._v(" 的一般步骤如下:")])]),t._v(" "),s("ul",[s("li",[t._v("使用 "),s("code",[t._v("forwardRef")]),t._v(" 包裹你的组件函数,以便能够接收 "),s("code",[t._v("ref")]),t._v(" 参数。")]),t._v(" "),s("li",[t._v("在组件函数中定义内部的 "),s("code",[t._v("handle")]),t._v(" 对象,它包含你想要暴露给父组件的方法和属性。")]),t._v(" "),s("li",[t._v("使用 "),s("code",[t._v("useImperativeHandle")]),t._v(" 钩子,将 "),s("code",[t._v("ref")]),t._v(" 和回调函数作为参数传递给它。回调函数应返回你定义的 "),s("code",[t._v("handle")]),t._v(" 对象。")]),t._v(" "),s("li",[t._v("如果有必要,可以在第三个参数中传递依赖项数组,以在依赖项发生变化时重新生成 "),s("code",[t._v("handle")]),t._v(" 对象")])]),t._v(" "),s("p",[s("strong",[t._v("示例:")])]),t._v(" "),s("div",{staticClass:"language-jsx line-numbers-mode"},[s("pre",{pre:!0,attrs:{class:"language-jsx"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" React"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" forwardRef"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" useImperativeHandle "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("from")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'react'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" CustomComponent "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("forwardRef")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("props"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" ref")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Declare your handle object with desired methods")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" handle "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Custom methods and properties")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Expose the handle to the parent component")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("useImperativeHandle")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("ref"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" handle"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/* dependencies */")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Rest of your component code")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// JSX for your component")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("export")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("default")]),t._v(" CustomComponent"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])]),t._v(" "),s("div",{staticClass:"line-numbers-wrapper"},[s("span",{staticClass:"line-number"},[t._v("1")]),s("br"),s("span",{staticClass:"line-number"},[t._v("2")]),s("br"),s("span",{staticClass:"line-number"},[t._v("3")]),s("br"),s("span",{staticClass:"line-number"},[t._v("4")]),s("br"),s("span",{staticClass:"line-number"},[t._v("5")]),s("br"),s("span",{staticClass:"line-number"},[t._v("6")]),s("br"),s("span",{staticClass:"line-number"},[t._v("7")]),s("br"),s("span",{staticClass:"line-number"},[t._v("8")]),s("br"),s("span",{staticClass:"line-number"},[t._v("9")]),s("br"),s("span",{staticClass:"line-number"},[t._v("10")]),s("br"),s("span",{staticClass:"line-number"},[t._v("11")]),s("br"),s("span",{staticClass:"line-number"},[t._v("12")]),s("br"),s("span",{staticClass:"line-number"},[t._v("13")]),s("br"),s("span",{staticClass:"line-number"},[t._v("14")]),s("br"),s("span",{staticClass:"line-number"},[t._v("15")]),s("br"),s("span",{staticClass:"line-number"},[t._v("16")]),s("br"),s("span",{staticClass:"line-number"},[t._v("17")]),s("br"),s("span",{staticClass:"line-number"},[t._v("18")]),s("br"),s("span",{staticClass:"line-number"},[t._v("19")]),s("br")])]),s("p",[t._v("在上述示例中,我们使用 "),s("code",[t._v("forwardRef")]),t._v(" 将组件包装起来,以便能够接收 "),s("code",[t._v("ref")]),t._v(" 属性。然后,我们在组件的顶层使用 "),s("code",[t._v("useImperativeHandle")]),t._v(",将自定义的 "),s("code",[t._v("handle")]),t._v(" 对象作为第一个参数传递给该钩子函数。通过这样做,我们可以自定义暴露给父组件的引用对象。")]),t._v(" "),s("p",[t._v("确保将自定义的方法和属性添加到 handle 对象中,并根据需要调整 "),s("code",[t._v("useImperativeHandle")]),t._v(" 中的依赖项列表。这样,在使用组件时,父组件就可以通过引用对象"),s("code",[t._v("ref.current")]),t._v("调用自定义的方法和访问属性.")])])}),[],!1,null,null,null);s.default=n.exports}}]); \ No newline at end of file diff --git a/assets/js/133.4a51e59f.js b/assets/js/133.4a51e59f.js new file mode 100644 index 0000000000..18324b75ff --- /dev/null +++ b/assets/js/133.4a51e59f.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[133],{459:function(t,n,s){"use strict";s.r(n);var e=s(4),o=Object(e.a)({},(function(){return(0,this._self._c)("ContentSlotsDistributor",{attrs:{"slot-key":this.$parent.slotKey}})}),[],!1,null,null,null);n.default=o.exports}}]); \ No newline at end of file diff --git a/assets/js/134.dc9c8690.js b/assets/js/134.dc9c8690.js new file mode 100644 index 0000000000..343a44c0b2 --- /dev/null +++ b/assets/js/134.dc9c8690.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[134],{460:function(t,e,a){"use strict";a.r(e);var s=a(4),r=Object(s.a)({},(function(){var t=this,e=t._self._c;return e("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[e("h2",{attrs:{id:"使用-legacy-react-apis-定义组件"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#使用-legacy-react-apis-定义组件"}},[t._v("#")]),t._v(" 使用 Legacy React APIS 定义组件")]),t._v(" "),e("div",{staticClass:"custom-block tip"},[e("p",{staticClass:"custom-block-title"},[t._v("提示")]),t._v(" "),e("p",[t._v("更多内容可见: "),e("a",{attrs:{href:"https://react.dev/reference/react/Component#component",target:"_blank",rel:"noopener noreferrer"}},[t._v("define a React component as a class"),e("OutboundLink")],1)])]),t._v(" "),e("p",[t._v("一、我们需要掌握:")]),t._v(" "),e("ol",[e("li",[t._v("生命周期的回调顺序")])])])}),[],!1,null,null,null);e.default=r.exports}}]); \ No newline at end of file diff --git a/assets/js/135.dbd7a88c.js b/assets/js/135.dbd7a88c.js new file mode 100644 index 0000000000..c4fb2df430 --- /dev/null +++ b/assets/js/135.dbd7a88c.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[135],{461:function(s,t,a){"use strict";a.r(t);var n=a(4),e=Object(n.a)({},(function(){var s=this,t=s._self._c;return t("ContentSlotsDistributor",{attrs:{"slot-key":s.$parent.slotKey}},[t("h2",{attrs:{id:"背景"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#背景"}},[s._v("#")]),s._v(" 背景")]),s._v(" "),t("p",[s._v("这是我在平时的开发中遇到的一个场景,具体如下:假设我需要在 A 组件调用 B 组件的一个方法,此方法之前是没有参数传递的。现在我需要传入一个回调函数,用于知道 B 组件当前是否可见。下面是精简的初始代码")]),s._v(" "),t("div",{staticClass:"language-ts line-numbers-mode"},[t("pre",{pre:!0,attrs:{class:"language-ts"}},[t("code",[t("span",{pre:!0,attrs:{class:"token comment"}},[s._v("// @ts-ignore")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("import")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("*")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("as")]),s._v(" React "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("from")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token string"}},[s._v("'react'")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("export")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("class")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[t("span",{pre:!0,attrs:{class:"token constant"}},[s._v("B")])]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("extends")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("React")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),s._v("Component "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("static")]),s._v(" show"),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v(":")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("|")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("isVisibleCallback"),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("?")]),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v(":")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("isVisible"),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v(":")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token builtin"}},[s._v("boolean")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=>")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("void")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=>")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("void")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("|")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("undefined")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("undefined")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n\n showStateCallback"),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v(":")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("isVisible"),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v(":")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token builtin"}},[s._v("boolean")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=>")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("void")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("|")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("undefined")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("undefined")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n\n "),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("constructor")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("props"),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v(":")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token builtin"}},[s._v("any")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("super")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("props"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token comment"}},[s._v("// this.initState();")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token constant"}},[s._v("B")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),s._v("show "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("this")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("show")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("bind")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("this")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n\n "),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("show")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("showStateCallback"),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("?")]),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v(":")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("isVisible"),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v(":")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token builtin"}},[s._v("boolean")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=>")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("void")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token comment"}},[s._v("// 注入当前的 callback")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("this")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),s._v("showStateCallback "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" showStateCallback"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token comment"}},[s._v("// @ts-ignore")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("this")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("setState")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v(" show"),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v(":")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token boolean"}},[s._v("true")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" bottom"),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v(":")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("100")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token comment"}},[s._v("// ...")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n\n "),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("close")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token comment"}},[s._v("// @ts-ignore")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("this")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("setState")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v(" show"),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v(":")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token boolean"}},[s._v("false")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n\n "),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("componentDidUpdate")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("prevProps"),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v(":")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token builtin"}},[s._v("any")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" prevState"),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v(":")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token builtin"}},[s._v("any")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token comment"}},[s._v("// @ts-ignore")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("if")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("this")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),s._v("state"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),s._v("show "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("!==")]),s._v(" prevState"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),s._v("show"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token comment"}},[s._v("// show state changed and callback")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token comment"}},[s._v("// @ts-ignore")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("this")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),s._v("showStateCallback "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("&&")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("this")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("showStateCallback")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("this")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),s._v("state"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),s._v("show"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n\n "),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("render")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token comment"}},[s._v("// @ts-ignore")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("return")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("<")]),s._v("h1"),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v(">")]),s._v("Hello"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("this")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),s._v("props"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),s._v("name"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("!")]),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("<")]),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("/")]),s._v("h1"),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v(">")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n")])]),s._v(" "),t("div",{staticClass:"line-numbers-wrapper"},[t("span",{staticClass:"line-number"},[s._v("1")]),t("br"),t("span",{staticClass:"line-number"},[s._v("2")]),t("br"),t("span",{staticClass:"line-number"},[s._v("3")]),t("br"),t("span",{staticClass:"line-number"},[s._v("4")]),t("br"),t("span",{staticClass:"line-number"},[s._v("5")]),t("br"),t("span",{staticClass:"line-number"},[s._v("6")]),t("br"),t("span",{staticClass:"line-number"},[s._v("7")]),t("br"),t("span",{staticClass:"line-number"},[s._v("8")]),t("br"),t("span",{staticClass:"line-number"},[s._v("9")]),t("br"),t("span",{staticClass:"line-number"},[s._v("10")]),t("br"),t("span",{staticClass:"line-number"},[s._v("11")]),t("br"),t("span",{staticClass:"line-number"},[s._v("12")]),t("br"),t("span",{staticClass:"line-number"},[s._v("13")]),t("br"),t("span",{staticClass:"line-number"},[s._v("14")]),t("br"),t("span",{staticClass:"line-number"},[s._v("15")]),t("br"),t("span",{staticClass:"line-number"},[s._v("16")]),t("br"),t("span",{staticClass:"line-number"},[s._v("17")]),t("br"),t("span",{staticClass:"line-number"},[s._v("18")]),t("br"),t("span",{staticClass:"line-number"},[s._v("19")]),t("br"),t("span",{staticClass:"line-number"},[s._v("20")]),t("br"),t("span",{staticClass:"line-number"},[s._v("21")]),t("br"),t("span",{staticClass:"line-number"},[s._v("22")]),t("br"),t("span",{staticClass:"line-number"},[s._v("23")]),t("br"),t("span",{staticClass:"line-number"},[s._v("24")]),t("br"),t("span",{staticClass:"line-number"},[s._v("25")]),t("br"),t("span",{staticClass:"line-number"},[s._v("26")]),t("br"),t("span",{staticClass:"line-number"},[s._v("27")]),t("br"),t("span",{staticClass:"line-number"},[s._v("28")]),t("br"),t("span",{staticClass:"line-number"},[s._v("29")]),t("br"),t("span",{staticClass:"line-number"},[s._v("30")]),t("br"),t("span",{staticClass:"line-number"},[s._v("31")]),t("br"),t("span",{staticClass:"line-number"},[s._v("32")]),t("br"),t("span",{staticClass:"line-number"},[s._v("33")]),t("br"),t("span",{staticClass:"line-number"},[s._v("34")]),t("br"),t("span",{staticClass:"line-number"},[s._v("35")]),t("br"),t("span",{staticClass:"line-number"},[s._v("36")]),t("br"),t("span",{staticClass:"line-number"},[s._v("37")]),t("br"),t("span",{staticClass:"line-number"},[s._v("38")]),t("br"),t("span",{staticClass:"line-number"},[s._v("39")]),t("br"),t("span",{staticClass:"line-number"},[s._v("40")]),t("br"),t("span",{staticClass:"line-number"},[s._v("41")]),t("br"),t("span",{staticClass:"line-number"},[s._v("42")]),t("br")])]),t("p",[s._v("如上,将对象中的方法通过 "),t("code",[s._v("bind")]),s._v(" 方法,赋值给 B 的静态变量 show")]),s._v(" "),t("h2",{attrs:{id:"剖析"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#剖析"}},[s._v("#")]),s._v(" 剖析")]),s._v(" "),t("h3",{attrs:{id:"设计-show-方法"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#设计-show-方法"}},[s._v("#")]),s._v(" 设计 show 方法")]),s._v(" "),t("p",[s._v("希望 show 可以回调到 panel 的状态 (弹起/关闭), 下面是我在 B 组件将 show 方法改成如下格式(这里注释了)")]),s._v(" "),t("div",{staticClass:"language-ts line-numbers-mode"},[t("pre",{pre:!0,attrs:{class:"language-ts"}},[t("code",[t("span",{pre:!0,attrs:{class:"token comment"}},[s._v("// static show: ((isVisibleCallback?: (isVisible: boolean) => void) => void) | undefined = undefined;")]),s._v("\n")])]),s._v(" "),t("div",{staticClass:"line-numbers-wrapper"},[t("span",{staticClass:"line-number"},[s._v("1")]),t("br")])]),t("p",[t("strong",[s._v("为什么有两个 "),t("code",[s._v("==>")])])]),s._v(" "),t("p",[s._v("使用两个 "),t("code",[s._v("=> void")]),s._v(" 表示两个函数类型的返回值都是 void。")]),s._v(" "),t("ul",[t("li",[s._v("第一个 "),t("code",[s._v("=> void")]),s._v(" 是用于指定 isVisibleCallback 这个回调函数的返回值为 void")]),s._v(" "),t("li",[s._v("第二个 "),t("code",[s._v("=> void")]),s._v(" 是用于指定 show 方法本身的返回值为 void。")])]),s._v(" "),t("p",[s._v("这样定义的 show 方法可以接受一个可选的回调函数 isVisibleCallback,这个回调函数接受一个布尔值参数 isVisible 并且没有返回值。同时,show 方法本身也没有返回值。")]),s._v(" "),t("h3",{attrs:{id:"调用"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#调用"}},[s._v("#")]),s._v(" 调用")]),s._v(" "),t("p",[s._v("在 A 组件调用方式如下:")]),s._v(" "),t("div",{staticClass:"language-typescript line-numbers-mode"},[t("pre",{pre:!0,attrs:{class:"language-typescript"}},[t("code",[t("span",{pre:!0,attrs:{class:"token constant"}},[s._v("B")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),s._v("show"),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("?.")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("isVisible"),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v(":")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token builtin"}},[s._v("boolean")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=>")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("setXXXVisible")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("isVisible "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("?")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("2")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v(":")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("1")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n")])]),s._v(" "),t("div",{staticClass:"line-numbers-wrapper"},[t("span",{staticClass:"line-number"},[s._v("1")]),t("br"),t("span",{staticClass:"line-number"},[s._v("2")]),t("br"),t("span",{staticClass:"line-number"},[s._v("3")]),t("br")])]),t("p",[s._v("这样我们 A 组件就可以见听到 B 组件 panel 的状态了")]),s._v(" "),t("h2",{attrs:{id:"总结"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#总结"}},[s._v("#")]),s._v(" 总结")]),s._v(" "),t("p",[s._v("此问题并不是复杂,这里记录下解体思路。 另外 B 中 show 方法的定义确实也不熟悉,摸索成功后果断记录。 回头想其实挺简单的")])])}),[],!1,null,null,null);t.default=e.exports}}]); \ No newline at end of file diff --git a/assets/js/136.a4874667.js b/assets/js/136.a4874667.js new file mode 100644 index 0000000000..72b4b43aa2 --- /dev/null +++ b/assets/js/136.a4874667.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[136],{462:function(t,n,s){"use strict";s.r(n);var e=s(4),o=Object(e.a)({},(function(){return(0,this._self._c)("ContentSlotsDistributor",{attrs:{"slot-key":this.$parent.slotKey}})}),[],!1,null,null,null);n.default=o.exports}}]); \ No newline at end of file diff --git a/assets/js/137.7205d03d.js b/assets/js/137.7205d03d.js new file mode 100644 index 0000000000..d0467b7908 --- /dev/null +++ b/assets/js/137.7205d03d.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[137],{463:function(r,t,e){"use strict";e.r(t);var o=e(4),a=Object(o.a)({},(function(){var r=this,t=r._self._c;return t("ContentSlotsDistributor",{attrs:{"slot-key":r.$parent.slotKey}},[t("h2",{attrs:{id:"注解"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#注解"}},[r._v("#")]),r._v(" 注解")]),r._v(" "),t("h3",{attrs:{id:"spring-mvc-和-rest-注解"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#spring-mvc-和-rest-注解"}},[r._v("#")]),r._v(" Spring MVC 和 REST 注解")]),r._v(" "),t("h4",{attrs:{id:"restcontroller"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#restcontroller"}},[r._v("#")]),r._v(" @RestController")]),r._v(" "),t("p",[t("code",[r._v("@RestController")]),r._v("是 Spring Framework 中的一个注解,用于标识一个类是 RESTful 风格的控制器(Controller)。与传统的 Spring MVC 控制器不同,"),t("code",[r._v("@RestController")]),r._v("注解告诉 Spring 框架,该控制器返回的不是视图(HTML、JSP 等),而是数据,通常以 JSON 格式返回给客户端。这意味着使用"),t("code",[r._v("@RestController")]),r._v("的类中的方法通常用于处理 RESTful API 请求")]),r._v(" "),t("p",[r._v("具体来说,"),t("strong",[r._v("@RestController 注解的作用包括:")])]),r._v(" "),t("ul",[t("li",[t("p",[r._v("组合注解:@RestController 注解实际上是@Controller 和@ResponseBody 两个注解的组合。@Controller 标识该类是一个控制器,而@ResponseBody 表示方法返回的数据将被直接写入 HTTP 响应体中,而不是被解释为视图名称。")])]),r._v(" "),t("li",[t("p",[r._v("返回数据:@RestController 标识的类中的方法通常返回领域对象、数据对象或 DTO(数据传输对象)。这些数据对象将以 JSON 或 XML 等格式直接返回给客户端,而不是渲染到视图中。")])]),r._v(" "),t("li",[t("p",[r._v("简化开发:使用@RestController 可以简化开发 RESTful API 的过程,因为开发人员无需处理视图解析和模型视图的问题,只需关注数据的处理和响应。")])])]),r._v(" "),t("h2",{attrs:{id:"相关概念"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#相关概念"}},[r._v("#")]),r._v(" 相关概念")]),r._v(" "),t("h3",{attrs:{id:"actuator"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#actuator"}},[r._v("#")]),r._v(" "),t("a",{attrs:{href:"https://www.cnblogs.com/caoweixiong/p/15325382.html",target:"_blank",rel:"noopener noreferrer"}},[r._v("Actuator"),t("OutboundLink")],1)]),r._v(" "),t("blockquote",[t("p",[r._v("Spring Boot Actuator 模块提供了生产级别的功能,比如健康检查,审计,指标收集,HTTP 跟踪等,帮助我们监控和管理 Spring Boot 应用。")])]),r._v(" "),t("h2",{attrs:{id:"其他"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#其他"}},[r._v("#")]),r._v(" 其他")]),r._v(" "),t("h3",{attrs:{id:"微服务"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#微服务"}},[r._v("#")]),r._v(" 微服务")]),r._v(" "),t("blockquote",[t("p",[r._v("Microservices with Spring Boot: "),t("a",{attrs:{href:"https://spring.io/microservices",target:"_blank",rel:"noopener noreferrer"}},[r._v("https://spring.io/microservices"),t("OutboundLink")],1)])]),r._v(" "),t("h3",{attrs:{id:"autowired-原理"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#autowired-原理"}},[r._v("#")]),r._v(" autowired 原理")]),r._v(" "),t("h2",{attrs:{id:"链接"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#链接"}},[r._v("#")]),r._v(" 链接")]),r._v(" "),t("ul",[t("li",[t("a",{attrs:{href:"https://spring.io/",target:"_blank",rel:"noopener noreferrer"}},[r._v("spring 官网"),t("OutboundLink")],1)]),r._v(" "),t("li",[t("a",{attrs:{href:"https://spring.io/guides#topicals",target:"_blank",rel:"noopener noreferrer"}},[r._v("spring tutorial"),t("OutboundLink")],1)]),r._v(" "),t("li",[r._v("学习 spring 项目\n"),t("ul",[t("li",[t("a",{attrs:{href:"https://github.com/xkcoding/spring-boot-demo",target:"_blank",rel:"noopener noreferrer"}},[r._v("🚀 一个用来深入学习并实战 Spring Boot 的项目。"),t("OutboundLink")],1)]),r._v(" "),t("li",[t("a",{attrs:{href:"https://github.com/jacky1234/learnSpring",target:"_blank",rel:"noopener noreferrer"}},[r._v("learnSpring"),t("OutboundLink")],1)]),r._v(" "),t("li",[t("a",{attrs:{href:"https://github.com/macrozheng/mall",target:"_blank",rel:"noopener noreferrer"}},[r._v("mall 商城完整项目"),t("OutboundLink")],1)]),r._v(" "),t("li",[t("a",{attrs:{href:"https://github.com/lmxdawn/exchange",target:"_blank",rel:"noopener noreferrer"}},[r._v("exchange 交易所"),t("OutboundLink")],1)])])]),r._v(" "),t("li",[r._v("其他\n"),t("ul",[t("li",[t("a",{attrs:{href:"https://blog.51cto.com/u_15490474/5686903",target:"_blank",rel:"noopener noreferrer"}},[r._v("Spring 最常用的 36 个注解大全,你都会了吗"),t("OutboundLink")],1)])])])])])}),[],!1,null,null,null);t.default=a.exports}}]); \ No newline at end of file diff --git a/assets/js/138.2df4a0de.js b/assets/js/138.2df4a0de.js new file mode 100644 index 0000000000..4109735e2b --- /dev/null +++ b/assets/js/138.2df4a0de.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[138],{464:function(t,a,n){"use strict";n.r(a);var e=n(4),s=Object(e.a)({},(function(){var t=this,a=t._self._c;return a("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[a("h2",{attrs:{id:"configurableapplicationcontext接口"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#configurableapplicationcontext接口"}},[t._v("#")]),t._v(" ConfigurableApplicationContext接口")]),t._v(" "),a("blockquote",[a("p",[t._v("介绍 spring中的ConfigurableApplicationContext接口")])]),t._v(" "),a("p",[t._v("ConfigurableApplicationContext接口是Spring框架中的一个重要接口,它扩展了ApplicationContext接口,提供了一些用于配置和控制应用上下文的额外方法。这个接口的主要目的是允许开发人员对应用上下文进行更高级别的配置和管理。")]),t._v(" "),a("p",[t._v("以下是ConfigurableApplicationContext接口的一些重要方法和功能:")]),t._v(" "),a("ul",[a("li",[a("p",[a("code",[t._v("refresh()方法:")]),t._v(":这是ConfigurableApplicationContext最重要的方法之一。它用于刷新应用上下文,重新加载所有bean定义,并触发bean的初始化。通常,在创建应用上下文之后,您需要调用refresh()方法才能使其生效。")])]),t._v(" "),a("li",[a("p",[a("code",[t._v("registerShutdownHook()方法:")]),t._v(":这个方法用于注册一个JVM关闭钩子,以确保在JVM关闭时正常关闭Spring应用上下文。这对于释放资源和执行清理操作非常有用。")])]),t._v(" "),a("li",[a("p",[a("code",[t._v("close()方法:")]),t._v(":这个方法用于关闭应用上下文。在应用程序完成后,应该显式调用close()方法以释放资源和清理应用上下文。")])]),t._v(" "),a("li",[a("p",[a("code",[t._v("setId(String id):")]),t._v(":设置应用上下文的唯一标识符,通常作为一个字符串。这可以用于标识不同的应用上下文。")])]),t._v(" "),a("li",[a("p",[a("code",[t._v("setDisplayName(String displayName):")]),t._v(":设置应用上下文的显示名称,通常用于日志和诊断目的。")])]),t._v(" "),a("li",[a("p",[a("code",[t._v("setParent(ApplicationContext parent):")]),t._v(":设置父应用上下文。这允许您创建多层次的应用上下文体系结构,其中子上下文可以访问父上下文中定义的bean。")])]),t._v(" "),a("li",[a("p",[a("code",[t._v("addApplicationListener(ApplicationListener listener):")]),t._v(":注册一个应用程序事件监听器,以便在应用上下文中的事件发生时接收通知。")])]),t._v(" "),a("li",[a("p",[a("code",[t._v("setEnvironment(ConfigurableEnvironment environment):")]),t._v(":设置应用上下文的环境,包括属性源和配置文件的处理。")])])]),t._v(" "),a("p",[t._v("ConfigurableApplicationContext接口的实现类包括GenericApplicationContext和AnnotationConfigApplicationContext等。这些实现类提供了不同的应用上下文配置方式,允许您使用XML配置、注解配置或混合配置等多种方式来构建应用上下文。")]),t._v(" "),a("p",[t._v("总之,ConfigurableApplicationContext接口为Spring应用程序提供了更高级别的配置和管理功能,允许您以更灵活的方式控制应用上下文的行为和生命周期。这对于大型和复杂的应用程序特别有用。")]),t._v(" "),a("h2",{attrs:{id:"beandefinition"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#beandefinition"}},[t._v("#")]),t._v(" BeanDefinition")]),t._v(" "),a("p",[t._v("在Spring框架中,BeanDefinition是一个重要的概念,它用于描述Spring容器中的Bean的元数据信息,包括Bean的类名、依赖关系、作用域、生命周期回调等信息。BeanDefinition的主要作用是告诉Spring容器如何创建和管理Bean。")]),t._v(" "),a("p",[t._v("以下是BeanDefinition的一些关键属性和功能:")]),t._v(" "),a("ul",[a("li",[a("p",[a("strong",[t._v("Bean的类名")]),t._v(": BeanDefinition包括一个属性,用于指定要创建的Bean的完全限定类名。这告诉Spring容器要实例化哪个类来创建Bean。")])]),t._v(" "),a("li",[a("p",[a("strong",[t._v("Bean的作用域")]),t._v(": BeanDefinition可以指定Bean的作用域,例如Singleton(单例)或Prototype(原型)。Singleton表示在容器中只有一个Bean实例,而Prototype表示每次请求都创建一个新的实例。")])]),t._v(" "),a("li",[a("p",[a("strong",[t._v("依赖关系")]),t._v(": BeanDefinition可以描述Bean与其他Bean之间的依赖关系。这包括构造函数注入、属性注入和方法注入等。")])]),t._v(" "),a("li",[a("p",[a("strong",[t._v("初始化和销毁回调")]),t._v(": 您可以通过BeanDefinition指定Bean的初始化方法和销毁方法。这些方法在Bean的生命周期中自动调用。")])]),t._v(" "),a("li",[a("p",[a("strong",[t._v("Bean的懒加载")]),t._v(": BeanDefinition可以指定Bean是否懒加载。如果设置为懒加载,Bean将在首次访问时才被实例化。")])]),t._v(" "),a("li",[a("p",[a("strong",[t._v("Bean的描述信息")]),t._v(": BeanDefinition可以包含一个描述信息,通常用于提供有关Bean用途和配置的文档。")])])]),t._v(" "),a("p",[t._v("BeanDefinition是Spring IoC容器的核心概念之一,它允许开发人员以声明性的方式配置应用程序中的Bean,而不需要硬编码Bean的创建和管理。通常,BeanDefinition由配置文件(如XML配置文件或Java配置类)中的Bean定义来创建和填充。")]),t._v(" "),a("p",[t._v("以下是一个示例XML配置中的BeanDefinition:")]),t._v(" "),a("div",{staticClass:"language-xml line-numbers-mode"},[a("pre",{pre:!0,attrs:{class:"language-xml"}},[a("code",[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("bean")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("id")]),a("span",{pre:!0,attrs:{class:"token attr-value"}},[a("span",{pre:!0,attrs:{class:"token punctuation attr-equals"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')]),t._v("myBean"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')])]),t._v(" "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("class")]),a("span",{pre:!0,attrs:{class:"token attr-value"}},[a("span",{pre:!0,attrs:{class:"token punctuation attr-equals"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')]),t._v("com.example.MyBean"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("property")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("name")]),a("span",{pre:!0,attrs:{class:"token attr-value"}},[a("span",{pre:!0,attrs:{class:"token punctuation attr-equals"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')]),t._v("name"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')])]),t._v(" "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("value")]),a("span",{pre:!0,attrs:{class:"token attr-value"}},[a("span",{pre:!0,attrs:{class:"token punctuation attr-equals"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')]),t._v("John"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("/>")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("property")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("name")]),a("span",{pre:!0,attrs:{class:"token attr-value"}},[a("span",{pre:!0,attrs:{class:"token punctuation attr-equals"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')]),t._v("age"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')])]),t._v(" "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("value")]),a("span",{pre:!0,attrs:{class:"token attr-value"}},[a("span",{pre:!0,attrs:{class:"token punctuation attr-equals"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')]),t._v("30"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("/>")])]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),t._v("\n")])]),t._v(" "),a("div",{staticClass:"line-numbers-wrapper"},[a("span",{staticClass:"line-number"},[t._v("1")]),a("br"),a("span",{staticClass:"line-number"},[t._v("2")]),a("br"),a("span",{staticClass:"line-number"},[t._v("3")]),a("br"),a("span",{staticClass:"line-number"},[t._v("4")]),a("br")])]),a("p",[t._v('在这个示例中,BeanDefinition描述了一个名为myBean的Bean,它是com.example.MyBean类的实例,并且有两个属性name和age,它们被设置为"John"和30。')]),t._v(" "),a("p",[t._v("总之,BeanDefinition是Spring框架中用于定义和配置Bean的关键元素,它使开发人员能够以灵活和可维护的方式管理应用程序中的Bean。通过使用BeanDefinition,Spring容器可以根据描述信息创建和管理Bean的实例,从而实现了IoC(Inversion of Control)的概念。")]),t._v(" "),a("h2",{attrs:{id:"attributeaccessor"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#attributeaccessor"}},[t._v("#")]),t._v(" AttributeAccessor")]),t._v(" "),a("p",[t._v("AttributeAccessor 接口是Spring Framework中的一个接口,用于提供在对象上设置和获取属性(attributes)的通用方法。属性通常是与对象关联的附加信息,它们可以用于各种用途,如配置、元数据、状态管理等。AttributeAccessor接口定义了以下方法:")]),t._v(" "),a("ul",[a("li",[a("p",[a("code",[t._v("void setAttribute(String name, Object value)")]),t._v(": 通过名称设置一个属性的值。")])]),t._v(" "),a("li",[a("p",[a("code",[t._v("Object getAttribute(String name)")]),t._v(": 通过名称获取属性的值。")])]),t._v(" "),a("li",[a("p",[a("code",[t._v("Object removeAttribute(String name)")]),t._v(": 通过名称删除属性,并返回被删除的属性的值。")])]),t._v(" "),a("li",[a("p",[a("code",[t._v("boolean hasAttribute(String name)")]),t._v(": 检查是否存在具有指定名称的属性。")])]),t._v(" "),a("li",[a("p",[a("code",[t._v("String[] attributeNames()")]),t._v(": 获取所有属性名称的数组。")])])]),t._v(" "),a("p",[t._v("AttributeAccessor接口通常由Spring框架内部使用,以及一些与Spring集成的第三方库使用,来处理对象上的属性。这个接口的一个常见用途是处理Bean的属性,例如在BeanFactory和ApplicationContext中,这些容器可以使用AttributeAccessor来管理Bean的配置属性。")]),t._v(" "),a("p",[t._v("此外,Spring提供了几个实现AttributeAccessor接口的类,如AbstractAttributeAccessor,它提供了通用的属性操作方法的默认实现。开发人员也可以实现AttributeAccessor接口来自定义对象的属性操作行为。")]),t._v(" "),a("p",[t._v("总之,AttributeAccessor接口提供了一种通用的方式来处理对象上的属性,使开发人员可以轻松地设置、获取和管理这些属性,从而增强了Spring框架的灵活性和可扩展性。")]),t._v(" "),a("h2",{attrs:{id:"lazy-注解"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#lazy-注解"}},[t._v("#")]),t._v(" lazy 注解")]),t._v(" "),a("p",[t._v("在Spring框架中,@Lazy注解用于控制bean的懒加载行为。懒加载是指在应用程序启动时不立即创建bean实例,而是在第一次访问该bean时才进行创建。这可以帮助提高应用程序的性能,尤其是在应用程序中存在大量的bean时。")]),t._v(" "),a("p",[t._v("使用@Lazy注解,您可以将其应用于Spring的bean定义,以指示Spring容器在需要时才创建该bean。以下是一些关于@Lazy注解的重要信息:")]),t._v(" "),a("ol",[a("li",[t._v("使用方式:\n要将@Lazy注解应用于bean,只需将它放置在bean定义的类上。例如:")])]),t._v(" "),a("div",{staticClass:"language-java line-numbers-mode"},[a("pre",{pre:!0,attrs:{class:"language-java"}},[a("code",[a("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Component")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Lazy")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("public")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("MyLazyBean")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Bean的定义")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])]),t._v(" "),a("div",{staticClass:"line-numbers-wrapper"},[a("span",{staticClass:"line-number"},[t._v("1")]),a("br"),a("span",{staticClass:"line-number"},[t._v("2")]),a("br"),a("span",{staticClass:"line-number"},[t._v("3")]),a("br"),a("span",{staticClass:"line-number"},[t._v("4")]),a("br"),a("span",{staticClass:"line-number"},[t._v("5")]),a("br")])]),a("p",[t._v("在这个示例中,MyLazyBean将作为懒加载bean进行创建。")]),t._v(" "),a("ol",{attrs:{start:"2"}},[a("li",[a("p",[t._v("默认值:\n如果您没有显式指定@Lazy注解,Spring容器会默认使用懒加载行为。")])]),t._v(" "),a("li",[a("p",[t._v("使用场景:\n懒加载通常用于那些在应用程序启动时不需要立即初始化的bean,特别是对于一些资源密集型的bean。这可以帮助减少启动时间和内存占用。")])]),t._v(" "),a("li",[a("p",[t._v("注意事项:")])])]),t._v(" "),a("ul",[a("li",[t._v("懒加载可能会导致在访问懒加载bean时出现延迟,因为Spring容器要在需要时才创建bean实例。")]),t._v(" "),a("li",[t._v("懒加载适用于单例作用域的bean,默认情况下,所有Spring bean都是单例的。")])]),t._v(" "),a("p",[t._v("总之,@Lazy注解是Spring中用于懒加载bean的一种方式,它允许您在需要时才创建bean实例,从而提高应用程序的性能和资源利用率。")])])}),[],!1,null,null,null);a.default=s.exports}}]); \ No newline at end of file diff --git a/assets/js/139.380116d5.js b/assets/js/139.380116d5.js new file mode 100644 index 0000000000..2d17fc7d3a --- /dev/null +++ b/assets/js/139.380116d5.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[139],{465:function(t,r,s){"use strict";s.r(r);var a=s(4),e=Object(a.a)({},(function(){var t=this,r=t._self._c;return r("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[r("h2",{attrs:{id:"数据库"}},[r("a",{staticClass:"header-anchor",attrs:{href:"#数据库"}},[t._v("#")]),t._v(" 数据库")]),t._v(" "),r("h3",{attrs:{id:"redius"}},[r("a",{staticClass:"header-anchor",attrs:{href:"#redius"}},[t._v("#")]),t._v(" Redius")]),t._v(" "),r("ul",[r("li",[r("a",{attrs:{href:"https://redis.io/commands",target:"_blank",rel:"noopener noreferrer"}},[t._v("redius command"),r("OutboundLink")],1)]),t._v(" "),r("li",[r("a",{attrs:{href:"https://maoxian.de/2015/08/1342.html",target:"_blank",rel:"noopener noreferrer"}},[t._v("redis-cli 命令总结"),r("OutboundLink")],1)])]),t._v(" "),r("h3",{attrs:{id:"mysql"}},[r("a",{staticClass:"header-anchor",attrs:{href:"#mysql"}},[t._v("#")]),t._v(" MySQL")]),t._v(" "),r("p",[t._v("MySQL 是一种关系型数据库管理系统,它支持 SQL 语言和 ACID 事务,也支持存储大量的结构化数据。MySQL 被广泛应用于 Web 应用程序、企业应用程序、分布式应用程序等领域。")]),t._v(" "),r("p",[t._v("MySQL 的优点:")]),t._v(" "),r("ul",[r("li",[r("strong",[t._v("数据安全")]),t._v(":MySQL 支持 ACID 事务,可以保证数据的一致性和安全性")]),t._v(" "),r("li",[r("strong",[t._v("大规模数据存储")]),t._v(":MySQL 可以存储大量结构化数据,可以适应企业应用程序的需求")]),t._v(" "),r("li",[r("strong",[t._v("可扩展性")]),t._v(":MySQL 支持水平扩展和垂直扩展,可以根据需求灵活调整数据库性能")])]),t._v(" "),r("h2",{attrs:{id:"其他"}},[r("a",{staticClass:"header-anchor",attrs:{href:"#其他"}},[t._v("#")]),t._v(" 其他")])])}),[],!1,null,null,null);r.default=e.exports}}]); \ No newline at end of file diff --git a/assets/js/14.285cce9e.js b/assets/js/14.285cce9e.js new file mode 100644 index 0000000000..0fe5c9b1ce --- /dev/null +++ b/assets/js/14.285cce9e.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[14],{323:function(e,t,a){"use strict";var i=TypeError;e.exports=function(e,t){if(e({placeholder:void 0}),mounted(){this.initialize(this.options,this.$lang),this.placeholder=this.$site.themeConfig.searchPlaceholder||""},methods:{initialize(e,t){Promise.all([Promise.all([a.e(0),a.e(8)]).then(a.t.bind(null,357,7)),Promise.all([a.e(0),a.e(8)]).then(a.t.bind(null,358,7))]).then(([a])=>{a=a.default;const{algoliaOptions:i={}}=e;a(Object.assign({},e,{inputSelector:"#algolia-search-input",algoliaOptions:Object.assign({facetFilters:["lang:"+t].concat(i.facetFilters||[])},i),handleSelected:(e,t,a)=>{const{pathname:i,hash:n}=new URL(a.url),s=i.replace(this.$site.base,"/"),r=decodeURIComponent(n);this.$router.push(`${s}${r}`)}}))})},update(e,t){this.$el.innerHTML='',this.initialize(e,t)}},watch:{$lang(e){this.update(this.options,e)},options(e){this.update(e,this.$lang)}}},n=(a(348),a(4)),s=Object(n.a)(i,(function(){var e=this._self._c;return e("form",{staticClass:"algolia-search-wrapper search-box",attrs:{id:"search-form",role:"search"}},[e("input",{staticClass:"search-query",attrs:{id:"algolia-search-input",placeholder:this.placeholder}})])}),[],!1,null,null,null);t.default=s.exports}}]); \ No newline at end of file diff --git a/assets/js/140.69abfa8c.js b/assets/js/140.69abfa8c.js new file mode 100644 index 0000000000..491fb00537 --- /dev/null +++ b/assets/js/140.69abfa8c.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[140],{466:function(s,n,a){"use strict";a.r(n);var e=a(4),t=Object(e.a)({},(function(){var s=this,n=s._self._c;return n("ContentSlotsDistributor",{attrs:{"slot-key":s.$parent.slotKey}},[n("p",[s._v("link: "),n("a",{attrs:{href:"https://github.com/hjzCy/sql_node/blob/master/mysql/MySQL%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0.md",target:"_blank",rel:"noopener noreferrer"}},[s._v("https://github.com/hjzCy/sql_node/blob/master/mysql/MySQL学习笔记.md"),n("OutboundLink")],1)]),s._v(" "),n("h2",{attrs:{id:"环境及使用"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#环境及使用"}},[s._v("#")]),s._v(" 环境及使用")]),s._v(" "),n("p",[s._v("一、使用 brew 安装启动")]),s._v(" "),n("ul",[n("li",[n("code",[s._v("brew install mysql")])]),s._v(" "),n("li",[n("code",[s._v("brew services start mysql")])])]),s._v(" "),n("p",[s._v("二、客户端")]),s._v(" "),n("ul",[n("li",[n("a",{attrs:{href:"https://www.mysql.com/products/workbench/",target:"_blank",rel:"noopener noreferrer"}},[s._v("MySql workbench"),n("OutboundLink")],1)])]),s._v(" "),n("h2",{attrs:{id:"命令"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#命令"}},[s._v("#")]),s._v(" 命令")]),s._v(" "),n("p",[s._v("进入 mysql shell 中,通过 "),n("code",[s._v("help")]),s._v(" 查看帮助命令, For server side help, type "),n("code",[s._v("help contents")])]),s._v(" "),n("h3",{attrs:{id:"通用"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#通用"}},[s._v("#")]),s._v(" 通用")]),s._v(" "),n("ul",[n("li",[n("code",[s._v("mysql -h 127.0.0.1 -u root -p")]),s._v(": 使用密码登录 MySQL 服务器")]),s._v(" "),n("li",[n("code",[s._v("exit;")]),s._v(": 退出 MySQL 数据库服务器")]),s._v(" "),n("li",[n("code",[s._v("show databases;")]),s._v(": 显示所有数据库")]),s._v(" "),n("li",[n("code",[s._v("CREATE DATABASE ;")]),s._v(": 创建数据库")]),s._v(" "),n("li",[n("code",[s._v("use ;")]),s._v(": 切换数据库")]),s._v(" "),n("li",[n("code",[s._v("show tables;")]),s._v(": 显示数据库中的所有表")]),s._v(" "),n("li",[n("code",[s._v("drop database ;")]),s._v(": 删除表")]),s._v(" "),n("li",[n("code",[s._v("create table ")]),s._v(": create table 表名(列名 1:列的类型 列名 2:列的类型 列名 3:列的类型 )")]),s._v(" "),n("li",[n("code",[s._v("desc ")]),s._v(": 显示表结构")]),s._v(" "),n("li",[n("code",[s._v("show create table ;")]),s._v(": 显示创建表的语法")]),s._v(" "),n("li",[n("code",[s._v("alter table add column 列名 类型;")]),s._v(": 添加列")])]),s._v(" "),n("h3",{attrs:{id:"gurd"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#gurd"}},[s._v("#")]),s._v(" GURD")]),s._v(" "),n("ul",[n("li",[n("code",[s._v("select \\* from ;")]),s._v(": 查询所有数据")]),s._v(" "),n("li",[n("code",[s._v("SELECT \\* FROM WHERE id = 1;")]),s._v(": 条件查询")]),s._v(" "),n("li",[n("code",[s._v("DELETE FROM pet where name = 'squirrel';")]),s._v(": 删除")]),s._v(" "),n("li",[n("code",[s._v("UPDATE pet SET name = 'squirrel' where owner = 'Diane';")]),s._v(" 更新记录")]),s._v(" "),n("li",[n("code",[s._v("INSERT INTO")]),s._v("test"),n("code",[s._v(".")]),s._v("orm_user"),n("code",[s._v("(")]),s._v("name"),n("code",[s._v(",")]),s._v("password"),n("code",[s._v(",")]),s._v("salt"),n("code",[s._v(",")]),s._v("email"),n("code",[s._v(",")]),s._v("phone_number"),n("code",[s._v(") VALUES ('user_27', 'xxx', 'xxx', 'xxx', 'xxx')")]),s._v(": 插入数据")])]),s._v(" "),n("h2",{attrs:{id:"建表约束"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#建表约束"}},[s._v("#")]),s._v(" 建表约束")]),s._v(" "),n("h3",{attrs:{id:"主键约束"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#主键约束"}},[s._v("#")]),s._v(" 主键约束")]),s._v(" "),n("div",{staticClass:"language-mysql line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v("-- 主键约束\n-- 使某个字段不重复且不得为空,确保表内所有数据的唯一性。\nCREATE TABLE user (\n id INT PRIMARY KEY,\n name VARCHAR(20)\n);\n\n-- 联合主键\n-- 联合主键中的每个字段都不能为空,并且加起来不能和已设置的联合主键重复。\nCREATE TABLE user (\n id INT,\n name VARCHAR(20),\n password VARCHAR(20),\n PRIMARY KEY(id, name)\n);\n\n-- 自增约束\n-- 自增约束的主键由系统自动递增分配。\nCREATE TABLE user (\n id INT PRIMARY KEY AUTO_INCREMENT,\n name VARCHAR(20)\n);\n\n-- 添加主键约束\n-- 如果忘记设置主键,还可以通过SQL语句设置(两种方式):\nALTER TABLE user ADD PRIMARY KEY(id);\nALTER TABLE user MODIFY id INT PRIMARY KEY;\n\n-- 删除主键\nALTER TABLE user drop PRIMARY KEY;\n")])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br"),n("span",{staticClass:"line-number"},[s._v("8")]),n("br"),n("span",{staticClass:"line-number"},[s._v("9")]),n("br"),n("span",{staticClass:"line-number"},[s._v("10")]),n("br"),n("span",{staticClass:"line-number"},[s._v("11")]),n("br"),n("span",{staticClass:"line-number"},[s._v("12")]),n("br"),n("span",{staticClass:"line-number"},[s._v("13")]),n("br"),n("span",{staticClass:"line-number"},[s._v("14")]),n("br"),n("span",{staticClass:"line-number"},[s._v("15")]),n("br"),n("span",{staticClass:"line-number"},[s._v("16")]),n("br"),n("span",{staticClass:"line-number"},[s._v("17")]),n("br"),n("span",{staticClass:"line-number"},[s._v("18")]),n("br"),n("span",{staticClass:"line-number"},[s._v("19")]),n("br"),n("span",{staticClass:"line-number"},[s._v("20")]),n("br"),n("span",{staticClass:"line-number"},[s._v("21")]),n("br"),n("span",{staticClass:"line-number"},[s._v("22")]),n("br"),n("span",{staticClass:"line-number"},[s._v("23")]),n("br"),n("span",{staticClass:"line-number"},[s._v("24")]),n("br"),n("span",{staticClass:"line-number"},[s._v("25")]),n("br"),n("span",{staticClass:"line-number"},[s._v("26")]),n("br"),n("span",{staticClass:"line-number"},[s._v("27")]),n("br"),n("span",{staticClass:"line-number"},[s._v("28")]),n("br"),n("span",{staticClass:"line-number"},[s._v("29")]),n("br"),n("span",{staticClass:"line-number"},[s._v("30")]),n("br")])]),n("h3",{attrs:{id:"唯一主键"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#唯一主键"}},[s._v("#")]),s._v(" 唯一主键")]),s._v(" "),n("div",{staticClass:"language-mysql line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v("-- 建表时创建唯一主键\nCREATE TABLE user (\n id INT,\n name VARCHAR(20),\n UNIQUE(name)\n);\n\n-- 添加唯一主键\n-- 如果建表时没有设置唯一建,还可以通过SQL语句设置(两种方式):\nALTER TABLE user ADD UNIQUE(name);\nALTER TABLE user MODIFY name VARCHAR(20) UNIQUE;\n\n-- 删除唯一主键\nALTER TABLE user DROP INDEX name;\n")])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br"),n("span",{staticClass:"line-number"},[s._v("8")]),n("br"),n("span",{staticClass:"line-number"},[s._v("9")]),n("br"),n("span",{staticClass:"line-number"},[s._v("10")]),n("br"),n("span",{staticClass:"line-number"},[s._v("11")]),n("br"),n("span",{staticClass:"line-number"},[s._v("12")]),n("br"),n("span",{staticClass:"line-number"},[s._v("13")]),n("br"),n("span",{staticClass:"line-number"},[s._v("14")]),n("br")])]),n("h3",{attrs:{id:"非空约束"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#非空约束"}},[s._v("#")]),s._v(" 非空约束")]),s._v(" "),n("div",{staticClass:"language-mysql line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v("-- 建表时添加非空约束\n-- 约束某个字段不能为空\nCREATE TABLE user (\n id INT,\n name VARCHAR(20) NOT NULL\n);\n\n-- 移除非空约束\nALTER TABLE user MODIFY name VARCHAR(20);\n")])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br"),n("span",{staticClass:"line-number"},[s._v("8")]),n("br"),n("span",{staticClass:"line-number"},[s._v("9")]),n("br")])]),n("h3",{attrs:{id:"默认约束"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#默认约束"}},[s._v("#")]),s._v(" 默认约束")]),s._v(" "),n("div",{staticClass:"language-mysql line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v("-- 建表时添加默认约束\n-- 约束某个字段的默认值\nCREATE TABLE user2 (\n id INT,\n name VARCHAR(20),\n age INT DEFAULT 10\n);\n\n-- 移除非空约束\nALTER TABLE user MODIFY age INT;\n")])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br"),n("span",{staticClass:"line-number"},[s._v("8")]),n("br"),n("span",{staticClass:"line-number"},[s._v("9")]),n("br"),n("span",{staticClass:"line-number"},[s._v("10")]),n("br")])]),n("h3",{attrs:{id:"外键约束"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#外键约束"}},[s._v("#")]),s._v(" 外键约束")]),s._v(" "),n("div",{staticClass:"language-mysql line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v("-- 班级\nCREATE TABLE classes (\n id INT PRIMARY KEY,\n name VARCHAR(20)\n);\n\n-- 学生表\nCREATE TABLE students (\n id INT PRIMARY KEY,\n name VARCHAR(20),\n -- 这里的 class_id 要和 classes 中的 id 字段相关联\n class_id INT,\n -- 表示 class_id 的值必须来自于 classes 中的 id 字段值\n FOREIGN KEY(class_id) REFERENCES classes(id)\n);\n\n-- 1. 主表(父表)classes 中没有的数据值,在副表(子表)students 中,是不可以使用的;\n-- 2. 主表中的记录被副表引用时,主表不可以被删除。\n")])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br"),n("span",{staticClass:"line-number"},[s._v("8")]),n("br"),n("span",{staticClass:"line-number"},[s._v("9")]),n("br"),n("span",{staticClass:"line-number"},[s._v("10")]),n("br"),n("span",{staticClass:"line-number"},[s._v("11")]),n("br"),n("span",{staticClass:"line-number"},[s._v("12")]),n("br"),n("span",{staticClass:"line-number"},[s._v("13")]),n("br"),n("span",{staticClass:"line-number"},[s._v("14")]),n("br"),n("span",{staticClass:"line-number"},[s._v("15")]),n("br"),n("span",{staticClass:"line-number"},[s._v("16")]),n("br"),n("span",{staticClass:"line-number"},[s._v("17")]),n("br"),n("span",{staticClass:"line-number"},[s._v("18")]),n("br")])]),n("h2",{attrs:{id:"数据库的三大设计范式"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#数据库的三大设计范式"}},[s._v("#")]),s._v(" 数据库的三大设计范式")]),s._v(" "),n("h3",{attrs:{id:"_1nf"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#_1nf"}},[s._v("#")]),s._v(" 1NF")]),s._v(" "),n("p",[s._v("只要字段值还可以继续拆分,就不满足第一范式。")]),s._v(" "),n("p",[s._v("范式设计得越详细,对某些实际操作可能会更好,但并非都有好处,需要对项目的实际情况进行设定。")]),s._v(" "),n("h3",{attrs:{id:"_2nf"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#_2nf"}},[s._v("#")]),s._v(" 2NF")]),s._v(" "),n("p",[s._v("在满足第一范式的前提下,其他列都必须完全依赖于主键列。如果出现不完全依赖,只可能发生在联合主键的情况下:")]),s._v(" "),n("div",{staticClass:"language-mysql line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v("-- 订单表\nCREATE TABLE myorder (\n product_id INT,\n customer_id INT,\n product_name VARCHAR(20),\n customer_name VARCHAR(20),\n PRIMARY KEY (product_id, customer_id)\n);\n")])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br"),n("span",{staticClass:"line-number"},[s._v("8")]),n("br")])]),n("p",[s._v("实际上,在这张订单表中,"),n("code",[s._v("product_name")]),s._v(" 只依赖于 "),n("code",[s._v("product_id")]),s._v(" ,"),n("code",[s._v("customer_name")]),s._v(" 只依赖于 "),n("code",[s._v("customer_id")]),s._v(" 。也就是说,"),n("code",[s._v("product_name")]),s._v(" 和 "),n("code",[s._v("customer_id")]),s._v(" 是没用关系的,"),n("code",[s._v("customer_name")]),s._v(" 和 "),n("code",[s._v("product_id")]),s._v(" 也是没有关系的。")]),s._v(" "),n("p",[s._v("这就不满足第二范式:其他列都必须完全依赖于主键列!")]),s._v(" "),n("div",{staticClass:"language-mysql line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v("CREATE TABLE myorder (\n order_id INT PRIMARY KEY,\n product_id INT,\n customer_id INT\n);\n\nCREATE TABLE product (\n id INT PRIMARY KEY,\n name VARCHAR(20)\n);\n\nCREATE TABLE customer (\n id INT PRIMARY KEY,\n name VARCHAR(20)\n);\n")])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br"),n("span",{staticClass:"line-number"},[s._v("8")]),n("br"),n("span",{staticClass:"line-number"},[s._v("9")]),n("br"),n("span",{staticClass:"line-number"},[s._v("10")]),n("br"),n("span",{staticClass:"line-number"},[s._v("11")]),n("br"),n("span",{staticClass:"line-number"},[s._v("12")]),n("br"),n("span",{staticClass:"line-number"},[s._v("13")]),n("br"),n("span",{staticClass:"line-number"},[s._v("14")]),n("br"),n("span",{staticClass:"line-number"},[s._v("15")]),n("br")])]),n("p",[s._v("拆分之后,"),n("code",[s._v("myorder")]),s._v(" 表中的 "),n("code",[s._v("product_id")]),s._v(" 和 "),n("code",[s._v("customer_id")]),s._v(" 完全依赖于 "),n("code",[s._v("order_id")]),s._v(" 主键,而 "),n("code",[s._v("product")]),s._v(" 和 "),n("code",[s._v("customer")]),s._v(" 表中的其他字段又完全依赖于主键。满足了第二范式的设计!")]),s._v(" "),n("h3",{attrs:{id:"_3nf"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#_3nf"}},[s._v("#")]),s._v(" 3NF")]),s._v(" "),n("p",[s._v("在满足第二范式的前提下,除了主键列之外,其他列之间不能有传递依赖关系。")]),s._v(" "),n("div",{staticClass:"language-mysql line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v("CREATE TABLE myorder (\n order_id INT PRIMARY KEY,\n product_id INT,\n customer_id INT,\n customer_phone VARCHAR(15)\n);\n")])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br")])]),n("p",[s._v("表中的 "),n("code",[s._v("customer_phone")]),s._v(" 有可能依赖于 "),n("code",[s._v("order_id")]),s._v(" 、 "),n("code",[s._v("customer_id")]),s._v(" 两列,也就不满足了第三范式的设计:其他列之间不能有传递依赖关系。")]),s._v(" "),n("div",{staticClass:"language-mysql line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v("CREATE TABLE myorder (\n order_id INT PRIMARY KEY,\n product_id INT,\n customer_id INT\n);\n\nCREATE TABLE customer (\n id INT PRIMARY KEY,\n name VARCHAR(20),\n phone VARCHAR(15)\n);\n")])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br"),n("span",{staticClass:"line-number"},[s._v("8")]),n("br"),n("span",{staticClass:"line-number"},[s._v("9")]),n("br"),n("span",{staticClass:"line-number"},[s._v("10")]),n("br"),n("span",{staticClass:"line-number"},[s._v("11")]),n("br")])]),n("p",[s._v("修改后就不存在其他列之间的传递依赖关系,其他列都只依赖于主键列,满足了第三范式的设计!")]),s._v(" "),n("h2",{attrs:{id:"查询练习"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#查询练习"}},[s._v("#")]),s._v(" 查询练习")]),s._v(" "),n("h3",{attrs:{id:"准备数据"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#准备数据"}},[s._v("#")]),s._v(" 准备数据")]),s._v(" "),n("div",{staticClass:"language-mysql line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v("-- 创建数据库\nCREATE DATABASE select_test;\n-- 切换数据库\nUSE select_test;\n\n-- 创建学生表\nCREATE TABLE student (\n no VARCHAR(20) PRIMARY KEY,\n name VARCHAR(20) NOT NULL,\n sex VARCHAR(10) NOT NULL,\n birthday DATE, -- 生日\n class VARCHAR(20) -- 所在班级\n);\n\n-- 创建教师表\nCREATE TABLE teacher (\n no VARCHAR(20) PRIMARY KEY,\n name VARCHAR(20) NOT NULL,\n sex VARCHAR(10) NOT NULL,\n birthday DATE,\n profession VARCHAR(20) NOT NULL, -- 职称\n department VARCHAR(20) NOT NULL -- 部门\n);\n\n-- 创建课程表\nCREATE TABLE course (\n no VARCHAR(20) PRIMARY KEY,\n name VARCHAR(20) NOT NULL,\n t_no VARCHAR(20) NOT NULL, -- 教师编号\n -- 表示该 tno 来自于 teacher 表中的 no 字段值\n FOREIGN KEY(t_no) REFERENCES teacher(no)\n);\n\n-- 成绩表\nCREATE TABLE score (\n s_no VARCHAR(20) NOT NULL, -- 学生编号\n c_no VARCHAR(20) NOT NULL, -- 课程号\n degree DECIMAL, -- 成绩\n -- 表示该 s_no, c_no 分别来自于 student, course 表中的 no 字段值\n FOREIGN KEY(s_no) REFERENCES student(no),\n FOREIGN KEY(c_no) REFERENCES course(no),\n -- 设置 s_no, c_no 为联合主键\n PRIMARY KEY(s_no, c_no)\n);\n\n-- 查看所有表\nSHOW TABLES;\n\n-- 添加学生表数据\nINSERT INTO student VALUES('101', '曾华', '男', '1977-09-01', '95033');\nINSERT INTO student VALUES('102', '匡明', '男', '1975-10-02', '95031');\nINSERT INTO student VALUES('103', '王丽', '女', '1976-01-23', '95033');\nINSERT INTO student VALUES('104', '李军', '男', '1976-02-20', '95033');\nINSERT INTO student VALUES('105', '王芳', '女', '1975-02-10', '95031');\nINSERT INTO student VALUES('106', '陆军', '男', '1974-06-03', '95031');\nINSERT INTO student VALUES('107', '王尼玛', '男', '1976-02-20', '95033');\nINSERT INTO student VALUES('108', '张全蛋', '男', '1975-02-10', '95031');\nINSERT INTO student VALUES('109', '赵铁柱', '男', '1974-06-03', '95031');\n\n-- 添加教师表数据\nINSERT INTO teacher VALUES('804', '李诚', '男', '1958-12-02', '副教授', '计算机系');\nINSERT INTO teacher VALUES('856', '张旭', '男', '1969-03-12', '讲师', '电子工程系');\nINSERT INTO teacher VALUES('825', '王萍', '女', '1972-05-05', '助教', '计算机系');\nINSERT INTO teacher VALUES('831', '刘冰', '女', '1977-08-14', '助教', '电子工程系');\n\n-- 添加课程表数据\nINSERT INTO course VALUES('3-105', '计算机导论', '825');\nINSERT INTO course VALUES('3-245', '操作系统', '804');\nINSERT INTO course VALUES('6-166', '数字电路', '856');\nINSERT INTO course VALUES('9-888', '高等数学', '831');\n\n-- 添加添加成绩表数据\nINSERT INTO score VALUES('103', '3-105', '92');\nINSERT INTO score VALUES('103', '3-245', '86');\nINSERT INTO score VALUES('103', '6-166', '85');\nINSERT INTO score VALUES('105', '3-105', '88');\nINSERT INTO score VALUES('105', '3-245', '75');\nINSERT INTO score VALUES('105', '6-166', '79');\nINSERT INTO score VALUES('109', '3-105', '76');\nINSERT INTO score VALUES('109', '3-245', '68');\nINSERT INTO score VALUES('109', '6-166', '81');\n\n-- 查看表结构\nSELECT * FROM course;\nSELECT * FROM score;\nSELECT * FROM student;\nSELECT * FROM teacher;\n")])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br"),n("span",{staticClass:"line-number"},[s._v("8")]),n("br"),n("span",{staticClass:"line-number"},[s._v("9")]),n("br"),n("span",{staticClass:"line-number"},[s._v("10")]),n("br"),n("span",{staticClass:"line-number"},[s._v("11")]),n("br"),n("span",{staticClass:"line-number"},[s._v("12")]),n("br"),n("span",{staticClass:"line-number"},[s._v("13")]),n("br"),n("span",{staticClass:"line-number"},[s._v("14")]),n("br"),n("span",{staticClass:"line-number"},[s._v("15")]),n("br"),n("span",{staticClass:"line-number"},[s._v("16")]),n("br"),n("span",{staticClass:"line-number"},[s._v("17")]),n("br"),n("span",{staticClass:"line-number"},[s._v("18")]),n("br"),n("span",{staticClass:"line-number"},[s._v("19")]),n("br"),n("span",{staticClass:"line-number"},[s._v("20")]),n("br"),n("span",{staticClass:"line-number"},[s._v("21")]),n("br"),n("span",{staticClass:"line-number"},[s._v("22")]),n("br"),n("span",{staticClass:"line-number"},[s._v("23")]),n("br"),n("span",{staticClass:"line-number"},[s._v("24")]),n("br"),n("span",{staticClass:"line-number"},[s._v("25")]),n("br"),n("span",{staticClass:"line-number"},[s._v("26")]),n("br"),n("span",{staticClass:"line-number"},[s._v("27")]),n("br"),n("span",{staticClass:"line-number"},[s._v("28")]),n("br"),n("span",{staticClass:"line-number"},[s._v("29")]),n("br"),n("span",{staticClass:"line-number"},[s._v("30")]),n("br"),n("span",{staticClass:"line-number"},[s._v("31")]),n("br"),n("span",{staticClass:"line-number"},[s._v("32")]),n("br"),n("span",{staticClass:"line-number"},[s._v("33")]),n("br"),n("span",{staticClass:"line-number"},[s._v("34")]),n("br"),n("span",{staticClass:"line-number"},[s._v("35")]),n("br"),n("span",{staticClass:"line-number"},[s._v("36")]),n("br"),n("span",{staticClass:"line-number"},[s._v("37")]),n("br"),n("span",{staticClass:"line-number"},[s._v("38")]),n("br"),n("span",{staticClass:"line-number"},[s._v("39")]),n("br"),n("span",{staticClass:"line-number"},[s._v("40")]),n("br"),n("span",{staticClass:"line-number"},[s._v("41")]),n("br"),n("span",{staticClass:"line-number"},[s._v("42")]),n("br"),n("span",{staticClass:"line-number"},[s._v("43")]),n("br"),n("span",{staticClass:"line-number"},[s._v("44")]),n("br"),n("span",{staticClass:"line-number"},[s._v("45")]),n("br"),n("span",{staticClass:"line-number"},[s._v("46")]),n("br"),n("span",{staticClass:"line-number"},[s._v("47")]),n("br"),n("span",{staticClass:"line-number"},[s._v("48")]),n("br"),n("span",{staticClass:"line-number"},[s._v("49")]),n("br"),n("span",{staticClass:"line-number"},[s._v("50")]),n("br"),n("span",{staticClass:"line-number"},[s._v("51")]),n("br"),n("span",{staticClass:"line-number"},[s._v("52")]),n("br"),n("span",{staticClass:"line-number"},[s._v("53")]),n("br"),n("span",{staticClass:"line-number"},[s._v("54")]),n("br"),n("span",{staticClass:"line-number"},[s._v("55")]),n("br"),n("span",{staticClass:"line-number"},[s._v("56")]),n("br"),n("span",{staticClass:"line-number"},[s._v("57")]),n("br"),n("span",{staticClass:"line-number"},[s._v("58")]),n("br"),n("span",{staticClass:"line-number"},[s._v("59")]),n("br"),n("span",{staticClass:"line-number"},[s._v("60")]),n("br"),n("span",{staticClass:"line-number"},[s._v("61")]),n("br"),n("span",{staticClass:"line-number"},[s._v("62")]),n("br"),n("span",{staticClass:"line-number"},[s._v("63")]),n("br"),n("span",{staticClass:"line-number"},[s._v("64")]),n("br"),n("span",{staticClass:"line-number"},[s._v("65")]),n("br"),n("span",{staticClass:"line-number"},[s._v("66")]),n("br"),n("span",{staticClass:"line-number"},[s._v("67")]),n("br"),n("span",{staticClass:"line-number"},[s._v("68")]),n("br"),n("span",{staticClass:"line-number"},[s._v("69")]),n("br"),n("span",{staticClass:"line-number"},[s._v("70")]),n("br"),n("span",{staticClass:"line-number"},[s._v("71")]),n("br"),n("span",{staticClass:"line-number"},[s._v("72")]),n("br"),n("span",{staticClass:"line-number"},[s._v("73")]),n("br"),n("span",{staticClass:"line-number"},[s._v("74")]),n("br"),n("span",{staticClass:"line-number"},[s._v("75")]),n("br"),n("span",{staticClass:"line-number"},[s._v("76")]),n("br"),n("span",{staticClass:"line-number"},[s._v("77")]),n("br"),n("span",{staticClass:"line-number"},[s._v("78")]),n("br"),n("span",{staticClass:"line-number"},[s._v("79")]),n("br"),n("span",{staticClass:"line-number"},[s._v("80")]),n("br"),n("span",{staticClass:"line-number"},[s._v("81")]),n("br"),n("span",{staticClass:"line-number"},[s._v("82")]),n("br"),n("span",{staticClass:"line-number"},[s._v("83")]),n("br"),n("span",{staticClass:"line-number"},[s._v("84")]),n("br"),n("span",{staticClass:"line-number"},[s._v("85")]),n("br"),n("span",{staticClass:"line-number"},[s._v("86")]),n("br"),n("span",{staticClass:"line-number"},[s._v("87")]),n("br")])]),n("h3",{attrs:{id:"_1-到-10"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#_1-到-10"}},[s._v("#")]),s._v(" 1 到 10")]),s._v(" "),n("div",{staticClass:"language-mysql line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v("-- 查询 student 表的所有行\nSELECT * FROM student;\n\n-- 查询 student 表中的 name、sex 和 class 字段的所有行\nSELECT name, sex, class FROM student;\n\n-- 查询 teacher 表中不重复的 department 列\n-- department: 去重查询\nSELECT DISTINCT department FROM teacher;\n\n-- 查询 score 表中成绩在60-80之间的所有行(区间查询和运算符查询)\n-- BETWEEN xx AND xx: 查询区间, AND 表示 \"并且\"\nSELECT * FROM score WHERE degree BETWEEN 60 AND 80;\nSELECT * FROM score WHERE degree > 60 AND degree < 80;\n\n-- 查询 score 表中成绩为 85, 86 或 88 的行\n-- IN: 查询规定中的多个值\nSELECT * FROM score WHERE degree IN (85, 86, 88);\n\n-- 查询 student 表中 '95031' 班或性别为 '女' 的所有行\n-- or: 表示或者关系\nSELECT * FROM student WHERE class = '95031' or sex = '女';\n\n-- 以 class 降序的方式查询 student 表的所有行\n-- DESC: 降序,从高到低\n-- ASC(默认): 升序,从低到高\nSELECT * FROM student ORDER BY class DESC;\nSELECT * FROM student ORDER BY class ASC;\n\n-- 以 c_no 升序、degree 降序查询 score 表的所有行\nSELECT * FROM score ORDER BY c_no ASC, degree DESC;\n\n-- 查询 \"95031\" 班的学生人数\n-- COUNT: 统计\nSELECT COUNT(*) FROM student WHERE class = '95031';\n\n-- 查询 score 表中的最高分的学生学号和课程编号(子查询或排序查询)。\n-- (SELECT MAX(degree) FROM score): 子查询,算出最高分\nSELECT s_no, c_no FROM score WHERE degree = (SELECT MAX(degree) FROM score);\n\n-- 排序查询\n-- LIMIT r, n: 表示从第r行开始,查询n条数据\nSELECT s_no, c_no, degree FROM score ORDER BY degree DESC LIMIT 0, 1;\n")])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br"),n("span",{staticClass:"line-number"},[s._v("8")]),n("br"),n("span",{staticClass:"line-number"},[s._v("9")]),n("br"),n("span",{staticClass:"line-number"},[s._v("10")]),n("br"),n("span",{staticClass:"line-number"},[s._v("11")]),n("br"),n("span",{staticClass:"line-number"},[s._v("12")]),n("br"),n("span",{staticClass:"line-number"},[s._v("13")]),n("br"),n("span",{staticClass:"line-number"},[s._v("14")]),n("br"),n("span",{staticClass:"line-number"},[s._v("15")]),n("br"),n("span",{staticClass:"line-number"},[s._v("16")]),n("br"),n("span",{staticClass:"line-number"},[s._v("17")]),n("br"),n("span",{staticClass:"line-number"},[s._v("18")]),n("br"),n("span",{staticClass:"line-number"},[s._v("19")]),n("br"),n("span",{staticClass:"line-number"},[s._v("20")]),n("br"),n("span",{staticClass:"line-number"},[s._v("21")]),n("br"),n("span",{staticClass:"line-number"},[s._v("22")]),n("br"),n("span",{staticClass:"line-number"},[s._v("23")]),n("br"),n("span",{staticClass:"line-number"},[s._v("24")]),n("br"),n("span",{staticClass:"line-number"},[s._v("25")]),n("br"),n("span",{staticClass:"line-number"},[s._v("26")]),n("br"),n("span",{staticClass:"line-number"},[s._v("27")]),n("br"),n("span",{staticClass:"line-number"},[s._v("28")]),n("br"),n("span",{staticClass:"line-number"},[s._v("29")]),n("br"),n("span",{staticClass:"line-number"},[s._v("30")]),n("br"),n("span",{staticClass:"line-number"},[s._v("31")]),n("br"),n("span",{staticClass:"line-number"},[s._v("32")]),n("br"),n("span",{staticClass:"line-number"},[s._v("33")]),n("br"),n("span",{staticClass:"line-number"},[s._v("34")]),n("br"),n("span",{staticClass:"line-number"},[s._v("35")]),n("br"),n("span",{staticClass:"line-number"},[s._v("36")]),n("br"),n("span",{staticClass:"line-number"},[s._v("37")]),n("br"),n("span",{staticClass:"line-number"},[s._v("38")]),n("br"),n("span",{staticClass:"line-number"},[s._v("39")]),n("br"),n("span",{staticClass:"line-number"},[s._v("40")]),n("br"),n("span",{staticClass:"line-number"},[s._v("41")]),n("br"),n("span",{staticClass:"line-number"},[s._v("42")]),n("br"),n("span",{staticClass:"line-number"},[s._v("43")]),n("br")])]),n("h3",{attrs:{id:"分组计算平均成绩"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#分组计算平均成绩"}},[s._v("#")]),s._v(" 分组计算平均成绩")]),s._v(" "),n("p",[n("strong",[s._v("查询每门课的平均成绩。")])]),s._v(" "),n("div",{staticClass:"language-mysql line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v("-- AVG: 平均值\nSELECT AVG(degree) FROM score WHERE c_no = '3-105';\nSELECT AVG(degree) FROM score WHERE c_no = '3-245';\nSELECT AVG(degree) FROM score WHERE c_no = '6-166';\n\n-- GROUP BY: 分组查询\nSELECT c_no, AVG(degree) FROM score GROUP BY c_no;\n")])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br")])]),n("h3",{attrs:{id:"分组条件与模糊查询"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#分组条件与模糊查询"}},[s._v("#")]),s._v(" 分组条件与模糊查询")]),s._v(" "),n("p",[n("strong",[s._v("查询 "),n("code",[s._v("score")]),s._v(" 表中至少有 2 名学生选修,并以 3 开头的课程的平均分数。")])]),s._v(" "),n("div",{staticClass:"language-mysql line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v("SELECT * FROM score;\n-- c_no 课程编号\n+------+-------+--------+\n- s_no: c_no : degree\n+------+-------+--------+\n- 103 : 3-105: 92\n- 103 : 3-245: 86\n- 103 : 6-166: 85\n- 105 : 3-105: 88\n- 105 : 3-245: 75\n- 105 : 6-166: 79\n- 109 : 3-105: 76\n- 109 : 3-245: 68\n- 109 : 6-166: 81\n+------+-------+--------+\n")])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br"),n("span",{staticClass:"line-number"},[s._v("8")]),n("br"),n("span",{staticClass:"line-number"},[s._v("9")]),n("br"),n("span",{staticClass:"line-number"},[s._v("10")]),n("br"),n("span",{staticClass:"line-number"},[s._v("11")]),n("br"),n("span",{staticClass:"line-number"},[s._v("12")]),n("br"),n("span",{staticClass:"line-number"},[s._v("13")]),n("br"),n("span",{staticClass:"line-number"},[s._v("14")]),n("br"),n("span",{staticClass:"line-number"},[s._v("15")]),n("br")])]),n("p",[s._v("分析表发现,至少有 2 名学生选修的课程是 "),n("code",[s._v("3-105")]),s._v(" 、"),n("code",[s._v("3-245")]),s._v(" 、"),n("code",[s._v("6-166")]),s._v(" ,以 3 开头的课程是 "),n("code",[s._v("3-105")]),s._v(" 、"),n("code",[s._v("3-245")]),s._v(" 。也就是说,我们要查询所有 "),n("code",[s._v("3-105")]),s._v(" 和 "),n("code",[s._v("3-245")]),s._v(" 的 "),n("code",[s._v("degree")]),s._v(" 平均分。")]),s._v(" "),n("div",{staticClass:"language-mysql line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v("-- 首先把 c_no, AVG(degree) 通过分组查询出来\nSELECT c_no, AVG(degree) FROM score GROUP BY c_no\n+-------+-------------+\n- c_no : AVG(degree)\n+-------+-------------+\n- 3-105: 85.3333\n- 3-245: 76.3333\n- 6-166: 81.6667\n+-------+-------------+\n\n-- 再查询出至少有 2 名学生选修的课程\n-- HAVING: 表示持有\nHAVING COUNT(c_no) >= 2\n\n-- 并且是以 3 开头的课程\n-- LIKE 表示模糊查询,\"%\" 是一个通配符,匹配 \"3\" 后面的任意字符。\nAND c_no LIKE '3%';\n\n-- 把前面的SQL语句拼接起来,\n-- 后面加上一个 COUNT(*),表示将每个分组的个数也查询出来。\nSELECT c_no, AVG(degree), COUNT(*) FROM score GROUP BY c_no\nHAVING COUNT(c_no) >= 2 AND c_no LIKE '3%';\n+-------+-------------+----------+\n- c_no : AVG(degree): COUNT(*)\n+-------+-------------+----------+\n- 3-105: 85.3333: 3\n- 3-245: 76.3333: 3\n+-------+-------------+----------+\n")])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br"),n("span",{staticClass:"line-number"},[s._v("8")]),n("br"),n("span",{staticClass:"line-number"},[s._v("9")]),n("br"),n("span",{staticClass:"line-number"},[s._v("10")]),n("br"),n("span",{staticClass:"line-number"},[s._v("11")]),n("br"),n("span",{staticClass:"line-number"},[s._v("12")]),n("br"),n("span",{staticClass:"line-number"},[s._v("13")]),n("br"),n("span",{staticClass:"line-number"},[s._v("14")]),n("br"),n("span",{staticClass:"line-number"},[s._v("15")]),n("br"),n("span",{staticClass:"line-number"},[s._v("16")]),n("br"),n("span",{staticClass:"line-number"},[s._v("17")]),n("br"),n("span",{staticClass:"line-number"},[s._v("18")]),n("br"),n("span",{staticClass:"line-number"},[s._v("19")]),n("br"),n("span",{staticClass:"line-number"},[s._v("20")]),n("br"),n("span",{staticClass:"line-number"},[s._v("21")]),n("br"),n("span",{staticClass:"line-number"},[s._v("22")]),n("br"),n("span",{staticClass:"line-number"},[s._v("23")]),n("br"),n("span",{staticClass:"line-number"},[s._v("24")]),n("br"),n("span",{staticClass:"line-number"},[s._v("25")]),n("br"),n("span",{staticClass:"line-number"},[s._v("26")]),n("br"),n("span",{staticClass:"line-number"},[s._v("27")]),n("br"),n("span",{staticClass:"line-number"},[s._v("28")]),n("br")])]),n("h3",{attrs:{id:"多表查询-1"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#多表查询-1"}},[s._v("#")]),s._v(" 多表查询 - 1")]),s._v(" "),n("p",[n("strong",[s._v("查询所有学生的 "),n("code",[s._v("name")]),s._v(",以及该学生在 "),n("code",[s._v("score")]),s._v(" 表中对应的 "),n("code",[s._v("c_no")]),s._v(" 和 "),n("code",[s._v("degree")]),s._v(" 。")])]),s._v(" "),n("div",{staticClass:"language-mysql line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v("SELECT no, name FROM student;\n+-----+-----------+\n- no : name\n+-----+-----------+\n- 101: 曾华\n- 102: 匡明\n- 103: 王丽\n- 104: 李军\n- 105: 王芳\n- 106: 陆军\n- 107: 王尼玛\n- 108: 张全蛋\n- 109: 赵铁柱\n+-----+-----------+\n\nSELECT s_no, c_no, degree FROM score;\n+------+-------+--------+\n- s_no: c_no : degree\n+------+-------+--------+\n- 103 : 3-105: 92\n- 103 : 3-245: 86\n- 103 : 6-166: 85\n- 105 : 3-105: 88\n- 105 : 3-245: 75\n- 105 : 6-166: 79\n- 109 : 3-105: 76\n- 109 : 3-245: 68\n- 109 : 6-166: 81\n+------+-------+--------+\n")])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br"),n("span",{staticClass:"line-number"},[s._v("8")]),n("br"),n("span",{staticClass:"line-number"},[s._v("9")]),n("br"),n("span",{staticClass:"line-number"},[s._v("10")]),n("br"),n("span",{staticClass:"line-number"},[s._v("11")]),n("br"),n("span",{staticClass:"line-number"},[s._v("12")]),n("br"),n("span",{staticClass:"line-number"},[s._v("13")]),n("br"),n("span",{staticClass:"line-number"},[s._v("14")]),n("br"),n("span",{staticClass:"line-number"},[s._v("15")]),n("br"),n("span",{staticClass:"line-number"},[s._v("16")]),n("br"),n("span",{staticClass:"line-number"},[s._v("17")]),n("br"),n("span",{staticClass:"line-number"},[s._v("18")]),n("br"),n("span",{staticClass:"line-number"},[s._v("19")]),n("br"),n("span",{staticClass:"line-number"},[s._v("20")]),n("br"),n("span",{staticClass:"line-number"},[s._v("21")]),n("br"),n("span",{staticClass:"line-number"},[s._v("22")]),n("br"),n("span",{staticClass:"line-number"},[s._v("23")]),n("br"),n("span",{staticClass:"line-number"},[s._v("24")]),n("br"),n("span",{staticClass:"line-number"},[s._v("25")]),n("br"),n("span",{staticClass:"line-number"},[s._v("26")]),n("br"),n("span",{staticClass:"line-number"},[s._v("27")]),n("br"),n("span",{staticClass:"line-number"},[s._v("28")]),n("br"),n("span",{staticClass:"line-number"},[s._v("29")]),n("br")])]),n("p",[s._v("通过分析可以发现,只要把 "),n("code",[s._v("score")]),s._v(" 表中的 "),n("code",[s._v("s_no")]),s._v(" 字段值替换成 "),n("code",[s._v("student")]),s._v(" 表中对应的 "),n("code",[s._v("name")]),s._v(" 字段值就可以了,如何做呢?")]),s._v(" "),n("div",{staticClass:"language-mysql line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v("-- FROM...: 表示从 student, score 表中查询\n-- WHERE 的条件表示为,只有在 student.no 和 score.s_no 相等时才显示出来。\nSELECT name, c_no, degree FROM student, score\nWHERE student.no = score.s_no;\n+-----------+-------+--------+\n- name : c_no : degree\n+-----------+-------+--------+\n- 王丽 : 3-105: 92\n- 王丽 : 3-245: 86\n- 王丽 : 6-166: 85\n- 王芳 : 3-105: 88\n- 王芳 : 3-245: 75\n- 王芳 : 6-166: 79\n- 赵铁柱 : 3-105: 76\n- 赵铁柱 : 3-245: 68\n- 赵铁柱 : 6-166: 81\n+-----------+-------+--------+\n")])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br"),n("span",{staticClass:"line-number"},[s._v("8")]),n("br"),n("span",{staticClass:"line-number"},[s._v("9")]),n("br"),n("span",{staticClass:"line-number"},[s._v("10")]),n("br"),n("span",{staticClass:"line-number"},[s._v("11")]),n("br"),n("span",{staticClass:"line-number"},[s._v("12")]),n("br"),n("span",{staticClass:"line-number"},[s._v("13")]),n("br"),n("span",{staticClass:"line-number"},[s._v("14")]),n("br"),n("span",{staticClass:"line-number"},[s._v("15")]),n("br"),n("span",{staticClass:"line-number"},[s._v("16")]),n("br"),n("span",{staticClass:"line-number"},[s._v("17")]),n("br")])]),n("h3",{attrs:{id:"多表查询-2"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#多表查询-2"}},[s._v("#")]),s._v(" 多表查询 - 2")]),s._v(" "),n("p",[n("strong",[s._v("查询所有学生的 "),n("code",[s._v("no")]),s._v(" 、课程名称 ( "),n("code",[s._v("course")]),s._v(" 表中的 "),n("code",[s._v("name")]),s._v(" ) 和成绩 ( "),n("code",[s._v("score")]),s._v(" 表中的 "),n("code",[s._v("degree")]),s._v(" ) 列。")])]),s._v(" "),n("p",[s._v("只有 "),n("code",[s._v("score")]),s._v(" 关联学生的 "),n("code",[s._v("no")]),s._v(" ,因此只要查询 "),n("code",[s._v("score")]),s._v(" 表,就能找出所有和学生相关的 "),n("code",[s._v("no")]),s._v(" 和 "),n("code",[s._v("degree")]),s._v(" :")]),s._v(" "),n("div",{staticClass:"language-mysql line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v("SELECT s_no, c_no, degree FROM score;\n+------+-------+--------+\n- s_no: c_no : degree\n+------+-------+--------+\n- 103 : 3-105: 92\n- 103 : 3-245: 86\n- 103 : 6-166: 85\n- 105 : 3-105: 88\n- 105 : 3-245: 75\n- 105 : 6-166: 79\n- 109 : 3-105: 76\n- 109 : 3-245: 68\n- 109 : 6-166: 81\n+------+-------+--------+\n")])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br"),n("span",{staticClass:"line-number"},[s._v("8")]),n("br"),n("span",{staticClass:"line-number"},[s._v("9")]),n("br"),n("span",{staticClass:"line-number"},[s._v("10")]),n("br"),n("span",{staticClass:"line-number"},[s._v("11")]),n("br"),n("span",{staticClass:"line-number"},[s._v("12")]),n("br"),n("span",{staticClass:"line-number"},[s._v("13")]),n("br"),n("span",{staticClass:"line-number"},[s._v("14")]),n("br")])]),n("p",[s._v("然后查询 "),n("code",[s._v("course")]),s._v(" 表:")]),s._v(" "),n("div",{staticClass:"language-mysql line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v("+-------+-----------------+\n- no : name\n+-------+-----------------+\n- 3-105: 计算机导论\n- 3-245: 操作系统\n- 6-166: 数字电路\n- 9-888: 高等数学\n+-------+-----------------+\n")])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br"),n("span",{staticClass:"line-number"},[s._v("8")]),n("br")])]),n("p",[s._v("只要把 "),n("code",[s._v("score")]),s._v(" 表中的 "),n("code",[s._v("c_no")]),s._v(" 替换成 "),n("code",[s._v("course")]),s._v(" 表中对应的 "),n("code",[s._v("name")]),s._v(" 字段值就可以了。")]),s._v(" "),n("div",{staticClass:"language-mysql line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v("-- 增加一个查询字段 name,分别从 score、course 这两个表中查询。\n-- as 表示取一个该字段的别名。\nSELECT s_no, name as c_name, degree FROM score, course\nWHERE score.c_no = course.no;\n+------+-----------------+--------+\n- s_no: c_name : degree\n+------+-----------------+--------+\n- 103 : 计算机导论 : 92\n- 105 : 计算机导论 : 88\n- 109 : 计算机导论 : 76\n- 103 : 操作系统 : 86\n- 105 : 操作系统 : 75\n- 109 : 操作系统 : 68\n- 103 : 数字电路 : 85\n- 105 : 数字电路 : 79\n- 109 : 数字电路 : 81\n+------+-----------------+--------+\n")])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br"),n("span",{staticClass:"line-number"},[s._v("8")]),n("br"),n("span",{staticClass:"line-number"},[s._v("9")]),n("br"),n("span",{staticClass:"line-number"},[s._v("10")]),n("br"),n("span",{staticClass:"line-number"},[s._v("11")]),n("br"),n("span",{staticClass:"line-number"},[s._v("12")]),n("br"),n("span",{staticClass:"line-number"},[s._v("13")]),n("br"),n("span",{staticClass:"line-number"},[s._v("14")]),n("br"),n("span",{staticClass:"line-number"},[s._v("15")]),n("br"),n("span",{staticClass:"line-number"},[s._v("16")]),n("br"),n("span",{staticClass:"line-number"},[s._v("17")]),n("br")])]),n("h3",{attrs:{id:"三表关联查询"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#三表关联查询"}},[s._v("#")]),s._v(" 三表关联查询")]),s._v(" "),n("p",[n("strong",[s._v("查询所有学生的 "),n("code",[s._v("name")]),s._v(" 、课程名 ( "),n("code",[s._v("course")]),s._v(" 表中的 "),n("code",[s._v("name")]),s._v(" ) 和 "),n("code",[s._v("degree")]),s._v(" 。")])]),s._v(" "),n("p",[s._v("只有 "),n("code",[s._v("score")]),s._v(" 表中关联学生的学号和课堂号,我们只要围绕着 "),n("code",[s._v("score")]),s._v(" 这张表查询就好了。")]),s._v(" "),n("div",{staticClass:"language-mysql line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v("SELECT * FROM score;\n+------+-------+--------+\n- s_no: c_no : degree\n+------+-------+--------+\n- 103 : 3-105: 92\n- 103 : 3-245: 86\n- 103 : 6-166: 85\n- 105 : 3-105: 88\n- 105 : 3-245: 75\n- 105 : 6-166: 79\n- 109 : 3-105: 76\n- 109 : 3-245: 68\n- 109 : 6-166: 81\n+------+-------+--------+\n")])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br"),n("span",{staticClass:"line-number"},[s._v("8")]),n("br"),n("span",{staticClass:"line-number"},[s._v("9")]),n("br"),n("span",{staticClass:"line-number"},[s._v("10")]),n("br"),n("span",{staticClass:"line-number"},[s._v("11")]),n("br"),n("span",{staticClass:"line-number"},[s._v("12")]),n("br"),n("span",{staticClass:"line-number"},[s._v("13")]),n("br"),n("span",{staticClass:"line-number"},[s._v("14")]),n("br")])]),n("p",[s._v("只要把 "),n("code",[s._v("s_no")]),s._v(" 和 "),n("code",[s._v("c_no")]),s._v(" 替换成 "),n("code",[s._v("student")]),s._v(" 和 "),n("code",[s._v("srouse")]),s._v(" 表中对应的 "),n("code",[s._v("name")]),s._v(" 字段值就好了。")]),s._v(" "),n("p",[s._v("首先把 "),n("code",[s._v("s_no")]),s._v(" 替换成 "),n("code",[s._v("student")]),s._v(" 表中的 "),n("code",[s._v("name")]),s._v(" 字段:")]),s._v(" "),n("div",{staticClass:"language-mysql line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v("SELECT name, c_no, degree FROM student, score WHERE student.no = score.s_no;\n+-----------+-------+--------+\n- name : c_no : degree\n+-----------+-------+--------+\n- 王丽 : 3-105: 92\n- 王丽 : 3-245: 86\n- 王丽 : 6-166: 85\n- 王芳 : 3-105: 88\n- 王芳 : 3-245: 75\n- 王芳 : 6-166: 79\n- 赵铁柱 : 3-105: 76\n- 赵铁柱 : 3-245: 68\n- 赵铁柱 : 6-166: 81\n+-----------+-------+--------+\n")])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br"),n("span",{staticClass:"line-number"},[s._v("8")]),n("br"),n("span",{staticClass:"line-number"},[s._v("9")]),n("br"),n("span",{staticClass:"line-number"},[s._v("10")]),n("br"),n("span",{staticClass:"line-number"},[s._v("11")]),n("br"),n("span",{staticClass:"line-number"},[s._v("12")]),n("br"),n("span",{staticClass:"line-number"},[s._v("13")]),n("br"),n("span",{staticClass:"line-number"},[s._v("14")]),n("br")])]),n("p",[s._v("再把 "),n("code",[s._v("c_no")]),s._v(" 替换成 "),n("code",[s._v("course")]),s._v(" 表中的 "),n("code",[s._v("name")]),s._v(" 字段:")]),s._v(" "),n("div",{staticClass:"language-mysql line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v('-- 课程表\nSELECT no, name FROM course;\n+-------+-----------------+\n- no : name\n+-------+-----------------+\n- 3-105: 计算机导论\n- 3-245: 操作系统\n- 6-166: 数字电路\n- 9-888: 高等数学\n+-------+-----------------+\n\n-- 由于字段名存在重复,使用 "表名.字段名 as 别名" 代替。\nSELECT student.name as s_name, course.name as c_name, degree\nFROM student, score, course\nWHERE student.NO = score.s_no\nAND score.c_no = course.no;\n')])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br"),n("span",{staticClass:"line-number"},[s._v("8")]),n("br"),n("span",{staticClass:"line-number"},[s._v("9")]),n("br"),n("span",{staticClass:"line-number"},[s._v("10")]),n("br"),n("span",{staticClass:"line-number"},[s._v("11")]),n("br"),n("span",{staticClass:"line-number"},[s._v("12")]),n("br"),n("span",{staticClass:"line-number"},[s._v("13")]),n("br"),n("span",{staticClass:"line-number"},[s._v("14")]),n("br"),n("span",{staticClass:"line-number"},[s._v("15")]),n("br"),n("span",{staticClass:"line-number"},[s._v("16")]),n("br")])]),n("h3",{attrs:{id:"子查询加分组求平均分"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#子查询加分组求平均分"}},[s._v("#")]),s._v(" 子查询加分组求平均分")]),s._v(" "),n("p",[n("strong",[s._v("查询 "),n("code",[s._v("95031")]),s._v(" 班学生每门课程的平均成绩。")])]),s._v(" "),n("p",[s._v("在 "),n("code",[s._v("score")]),s._v(" 表中根据 "),n("code",[s._v("student")]),s._v(" 表的学生编号筛选出学生的课堂号和成绩:")]),s._v(" "),n("div",{staticClass:"language-mysql line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v("-- IN (..): 将筛选出的学生号当做 s_no 的条件查询\nSELECT s_no, c_no, degree FROM score\nWHERE s_no IN (SELECT no FROM student WHERE class = '95031');\n+------+-------+--------+\n- s_no: c_no : degree\n+------+-------+--------+\n- 105 : 3-105: 88\n- 105 : 3-245: 75\n- 105 : 6-166: 79\n- 109 : 3-105: 76\n- 109 : 3-245: 68\n- 109 : 6-166: 81\n+------+-------+--------+\n")])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br"),n("span",{staticClass:"line-number"},[s._v("8")]),n("br"),n("span",{staticClass:"line-number"},[s._v("9")]),n("br"),n("span",{staticClass:"line-number"},[s._v("10")]),n("br"),n("span",{staticClass:"line-number"},[s._v("11")]),n("br"),n("span",{staticClass:"line-number"},[s._v("12")]),n("br"),n("span",{staticClass:"line-number"},[s._v("13")]),n("br")])]),n("p",[s._v("这时只要将 "),n("code",[s._v("c_no")]),s._v(" 分组一下就能得出 "),n("code",[s._v("95031")]),s._v(" 班学生每门课的平均成绩:")]),s._v(" "),n("div",{staticClass:"language-mysql line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v("SELECT c_no, AVG(degree) FROM score\nWHERE s_no IN (SELECT no FROM student WHERE class = '95031')\nGROUP BY c_no;\n+-------+-------------+\n- c_no : AVG(degree)\n+-------+-------------+\n- 3-105: 82.0000\n- 3-245: 71.5000\n- 6-166: 80.0000\n+-------+-------------+\n")])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br"),n("span",{staticClass:"line-number"},[s._v("8")]),n("br"),n("span",{staticClass:"line-number"},[s._v("9")]),n("br"),n("span",{staticClass:"line-number"},[s._v("10")]),n("br")])]),n("h3",{attrs:{id:"子查询-1"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#子查询-1"}},[s._v("#")]),s._v(" 子查询 - 1")]),s._v(" "),n("p",[n("strong",[s._v("查询在 "),n("code",[s._v("3-105")]),s._v(" 课程中,所有成绩高于 "),n("code",[s._v("109")]),s._v(" 号同学的记录。")])]),s._v(" "),n("p",[s._v("首先筛选出课堂号为 "),n("code",[s._v("3-105")]),s._v(" ,在找出所有成绩高于 "),n("code",[s._v("109")]),s._v(" 号同学的的行。")]),s._v(" "),n("div",{staticClass:"language-mysql line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v("SELECT * FROM score\nWHERE c_no = '3-105'\nAND degree > (SELECT degree FROM score WHERE s_no = '109' AND c_no = '3-105');\n")])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br")])]),n("h3",{attrs:{id:"子查询-2"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#子查询-2"}},[s._v("#")]),s._v(" 子查询 - 2")]),s._v(" "),n("p",[n("strong",[s._v("查询所有成绩高于 "),n("code",[s._v("109")]),s._v(" 号同学的 "),n("code",[s._v("3-105")]),s._v(" 课程成绩记录。")])]),s._v(" "),n("div",{staticClass:"language-mysql line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v("-- 不限制课程号,只要成绩大于109号同学的3-105课程成绩就可以。\nSELECT * FROM score\nWHERE degree > (SELECT degree FROM score WHERE s_no = '109' AND c_no = '3-105');\n")])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br")])]),n("h3",{attrs:{id:"year-函数与带-in-关键字查询"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#year-函数与带-in-关键字查询"}},[s._v("#")]),s._v(" YEAR 函数与带 IN 关键字查询")]),s._v(" "),n("p",[n("strong",[s._v("查询所有和 "),n("code",[s._v("101")]),s._v(" 、"),n("code",[s._v("108")]),s._v(" 号学生同年出生的 "),n("code",[s._v("no")]),s._v(" 、"),n("code",[s._v("name")]),s._v(" 、"),n("code",[s._v("birthday")]),s._v(" 列。")])]),s._v(" "),n("div",{staticClass:"language-mysql line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v("-- YEAR(..): 取出日期中的年份\nSELECT no, name, birthday FROM student\nWHERE YEAR(birthday) IN (SELECT YEAR(birthday) FROM student WHERE no IN (101, 108));\n")])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br")])]),n("h3",{attrs:{id:"多层嵌套子查询"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#多层嵌套子查询"}},[s._v("#")]),s._v(" 多层嵌套子查询")]),s._v(" "),n("p",[n("strong",[s._v("查询 "),n("code",[s._v("'张旭'")]),s._v(" 教师任课的学生成绩表。")])]),s._v(" "),n("p",[s._v("首先找到教师编号:")]),s._v(" "),n("div",{staticClass:"language-mysql line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v("SELECT NO FROM teacher WHERE NAME = '张旭'\n")])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br")])]),n("p",[s._v("通过 "),n("code",[s._v("sourse")]),s._v(" 表找到该教师课程号:")]),s._v(" "),n("div",{staticClass:"language-mysql line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v("SELECT NO FROM course WHERE t_no = ( SELECT NO FROM teacher WHERE NAME = '张旭' );\n")])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br")])]),n("p",[s._v("通过筛选出的课程号查询成绩表:")]),s._v(" "),n("div",{staticClass:"language-mysql line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v("SELECT * FROM score WHERE c_no = (\n SELECT no FROM course WHERE t_no = (\n SELECT no FROM teacher WHERE NAME = '张旭'\n )\n);\n")])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br")])]),n("h3",{attrs:{id:"多表查询"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#多表查询"}},[s._v("#")]),s._v(" 多表查询")]),s._v(" "),n("p",[n("strong",[s._v("查询某选修课程多于 5 个同学的教师姓名。")])]),s._v(" "),n("p",[s._v("首先在 "),n("code",[s._v("teacher")]),s._v(" 表中,根据 "),n("code",[s._v("no")]),s._v(" 字段来判断该教师的同一门课程是否有至少 5 名学员选修:")]),s._v(" "),n("div",{staticClass:"language-mysql line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v("-- 查询 teacher 表\nSELECT no, name FROM teacher;\n+-----+--------+\n- no : name\n+-----+--------+\n- 804: 李诚\n- 825: 王萍\n- 831: 刘冰\n- 856: 张旭\n+-----+--------+\n\nSELECT name FROM teacher WHERE no IN (\n -- 在这里找到对应的条件\n);\n")])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br"),n("span",{staticClass:"line-number"},[s._v("8")]),n("br"),n("span",{staticClass:"line-number"},[s._v("9")]),n("br"),n("span",{staticClass:"line-number"},[s._v("10")]),n("br"),n("span",{staticClass:"line-number"},[s._v("11")]),n("br"),n("span",{staticClass:"line-number"},[s._v("12")]),n("br"),n("span",{staticClass:"line-number"},[s._v("13")]),n("br"),n("span",{staticClass:"line-number"},[s._v("14")]),n("br")])]),n("p",[s._v("查看和教师编号有有关的表的信息:")]),s._v(" "),n("div",{staticClass:"language-mysql line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v("SELECT * FROM course;\n-- t_no: 教师编号\n+-------+-----------------+------+\n- no : name : t_no\n+-------+-----------------+------+\n- 3-105: 计算机导论 : 825\n- 3-245: 操作系统 : 804\n- 6-166: 数字电路 : 856\n- 9-888: 高等数学 : 831\n+-------+-----------------+------+\n")])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br"),n("span",{staticClass:"line-number"},[s._v("8")]),n("br"),n("span",{staticClass:"line-number"},[s._v("9")]),n("br"),n("span",{staticClass:"line-number"},[s._v("10")]),n("br")])]),n("p",[s._v("我们已经找到和教师编号有关的字段就在 "),n("code",[s._v("course")]),s._v(" 表中,但是还无法知道哪门课程至少有 5 名学生选修,所以还需要根据 "),n("code",[s._v("score")]),s._v(" 表来查询:")]),s._v(" "),n("div",{staticClass:"language-mysql line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v("-- 在此之前向 score 插入一些数据,以便丰富查询条件。\nINSERT INTO score VALUES ('101', '3-105', '90');\nINSERT INTO score VALUES ('102', '3-105', '91');\nINSERT INTO score VALUES ('104', '3-105', '89');\n\n-- 查询 score 表\nSELECT * FROM score;\n+------+-------+--------+\n- s_no: c_no : degree\n+------+-------+--------+\n- 101 : 3-105: 90\n- 102 : 3-105: 91\n- 103 : 3-105: 92\n- 103 : 3-245: 86\n- 103 : 6-166: 85\n- 104 : 3-105: 89\n- 105 : 3-105: 88\n- 105 : 3-245: 75\n- 105 : 6-166: 79\n- 109 : 3-105: 76\n- 109 : 3-245: 68\n- 109 : 6-166: 81\n+------+-------+--------+\n\n-- 在 score 表中将 c_no 作为分组,并且限制 c_no 持有至少 5 条数据。\nSELECT c_no FROM score GROUP BY c_no HAVING COUNT(*) > 5;\n+-------+\n- c_no\n+-------+\n- 3-105\n+-------+\n")])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br"),n("span",{staticClass:"line-number"},[s._v("8")]),n("br"),n("span",{staticClass:"line-number"},[s._v("9")]),n("br"),n("span",{staticClass:"line-number"},[s._v("10")]),n("br"),n("span",{staticClass:"line-number"},[s._v("11")]),n("br"),n("span",{staticClass:"line-number"},[s._v("12")]),n("br"),n("span",{staticClass:"line-number"},[s._v("13")]),n("br"),n("span",{staticClass:"line-number"},[s._v("14")]),n("br"),n("span",{staticClass:"line-number"},[s._v("15")]),n("br"),n("span",{staticClass:"line-number"},[s._v("16")]),n("br"),n("span",{staticClass:"line-number"},[s._v("17")]),n("br"),n("span",{staticClass:"line-number"},[s._v("18")]),n("br"),n("span",{staticClass:"line-number"},[s._v("19")]),n("br"),n("span",{staticClass:"line-number"},[s._v("20")]),n("br"),n("span",{staticClass:"line-number"},[s._v("21")]),n("br"),n("span",{staticClass:"line-number"},[s._v("22")]),n("br"),n("span",{staticClass:"line-number"},[s._v("23")]),n("br"),n("span",{staticClass:"line-number"},[s._v("24")]),n("br"),n("span",{staticClass:"line-number"},[s._v("25")]),n("br"),n("span",{staticClass:"line-number"},[s._v("26")]),n("br"),n("span",{staticClass:"line-number"},[s._v("27")]),n("br"),n("span",{staticClass:"line-number"},[s._v("28")]),n("br"),n("span",{staticClass:"line-number"},[s._v("29")]),n("br"),n("span",{staticClass:"line-number"},[s._v("30")]),n("br"),n("span",{staticClass:"line-number"},[s._v("31")]),n("br")])]),n("p",[s._v("根据筛选出来的课程号,找出在某课程中,拥有至少 5 名学员的教师编号:")]),s._v(" "),n("div",{staticClass:"language-mysql line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v("SELECT t_no FROM course WHERE no IN (\n SELECT c_no FROM score GROUP BY c_no HAVING COUNT(*) > 5\n);\n+------+\n- t_no\n+------+\n- 825\n+------+\n")])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br"),n("span",{staticClass:"line-number"},[s._v("8")]),n("br")])]),n("p",[s._v("在 "),n("code",[s._v("teacher")]),s._v(" 表中,根据筛选出来的教师编号找到教师姓名:")]),s._v(" "),n("div",{staticClass:"language-mysql line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v("SELECT name FROM teacher WHERE no IN (\n -- 最终条件\n SELECT t_no FROM course WHERE no IN (\n SELECT c_no FROM score GROUP BY c_no HAVING COUNT(*) > 5\n )\n);\n")])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br")])]),n("h3",{attrs:{id:"子查询-3"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#子查询-3"}},[s._v("#")]),s._v(" 子查询 - 3")]),s._v(" "),n("p",[n("strong",[s._v("查询 “计算机系” 课程的成绩表。")])]),s._v(" "),n("p",[s._v("思路是,先找出 "),n("code",[s._v("course")]),s._v(" 表中所有 "),n("code",[s._v("计算机系")]),s._v(" 课程的编号,然后根据这个编号查询 "),n("code",[s._v("score")]),s._v(" 表。")]),s._v(" "),n("div",{staticClass:"language-mysql line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v("-- 通过 teacher 表查询所有 `计算机系` 的教师编号\nSELECT no, name, department FROM teacher WHERE department = '计算机系'\n+-----+--------+--------------+\n- no : name : department\n+-----+--------+--------------+\n- 804: 李诚 : 计算机系\n- 825: 王萍 : 计算机系\n+-----+--------+--------------+\n\n-- 通过 course 表查询该教师的课程编号\nSELECT no FROM course WHERE t_no IN (\n SELECT no FROM teacher WHERE department = '计算机系'\n);\n+-------+\n- no\n+-------+\n- 3-245\n- 3-105\n+-------+\n\n-- 根据筛选出来的课程号查询成绩表\nSELECT * FROM score WHERE c_no IN (\n SELECT no FROM course WHERE t_no IN (\n SELECT no FROM teacher WHERE department = '计算机系'\n )\n);\n+------+-------+--------+\n- s_no: c_no : degree\n+------+-------+--------+\n- 103 : 3-245: 86\n- 105 : 3-245: 75\n- 109 : 3-245: 68\n- 101 : 3-105: 90\n- 102 : 3-105: 91\n- 103 : 3-105: 92\n- 104 : 3-105: 89\n- 105 : 3-105: 88\n- 109 : 3-105: 76\n+------+-------+--------+\n")])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br"),n("span",{staticClass:"line-number"},[s._v("8")]),n("br"),n("span",{staticClass:"line-number"},[s._v("9")]),n("br"),n("span",{staticClass:"line-number"},[s._v("10")]),n("br"),n("span",{staticClass:"line-number"},[s._v("11")]),n("br"),n("span",{staticClass:"line-number"},[s._v("12")]),n("br"),n("span",{staticClass:"line-number"},[s._v("13")]),n("br"),n("span",{staticClass:"line-number"},[s._v("14")]),n("br"),n("span",{staticClass:"line-number"},[s._v("15")]),n("br"),n("span",{staticClass:"line-number"},[s._v("16")]),n("br"),n("span",{staticClass:"line-number"},[s._v("17")]),n("br"),n("span",{staticClass:"line-number"},[s._v("18")]),n("br"),n("span",{staticClass:"line-number"},[s._v("19")]),n("br"),n("span",{staticClass:"line-number"},[s._v("20")]),n("br"),n("span",{staticClass:"line-number"},[s._v("21")]),n("br"),n("span",{staticClass:"line-number"},[s._v("22")]),n("br"),n("span",{staticClass:"line-number"},[s._v("23")]),n("br"),n("span",{staticClass:"line-number"},[s._v("24")]),n("br"),n("span",{staticClass:"line-number"},[s._v("25")]),n("br"),n("span",{staticClass:"line-number"},[s._v("26")]),n("br"),n("span",{staticClass:"line-number"},[s._v("27")]),n("br"),n("span",{staticClass:"line-number"},[s._v("28")]),n("br"),n("span",{staticClass:"line-number"},[s._v("29")]),n("br"),n("span",{staticClass:"line-number"},[s._v("30")]),n("br"),n("span",{staticClass:"line-number"},[s._v("31")]),n("br"),n("span",{staticClass:"line-number"},[s._v("32")]),n("br"),n("span",{staticClass:"line-number"},[s._v("33")]),n("br"),n("span",{staticClass:"line-number"},[s._v("34")]),n("br"),n("span",{staticClass:"line-number"},[s._v("35")]),n("br"),n("span",{staticClass:"line-number"},[s._v("36")]),n("br"),n("span",{staticClass:"line-number"},[s._v("37")]),n("br"),n("span",{staticClass:"line-number"},[s._v("38")]),n("br"),n("span",{staticClass:"line-number"},[s._v("39")]),n("br")])]),n("h3",{attrs:{id:"union-和-notin-的使用"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#union-和-notin-的使用"}},[s._v("#")]),s._v(" UNION 和 NOTIN 的使用")]),s._v(" "),n("p",[n("strong",[s._v("查询 "),n("code",[s._v("计算机系")]),s._v(" 与 "),n("code",[s._v("电子工程系")]),s._v(" 中的不同职称的教师。")])]),s._v(" "),n("div",{staticClass:"language-mysql line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v("-- NOT: 代表逻辑非\nSELECT * FROM teacher WHERE department = '计算机系' AND profession NOT IN (\n SELECT profession FROM teacher WHERE department = '电子工程系'\n)\n-- 合并两个集\nUNION\nSELECT * FROM teacher WHERE department = '电子工程系' AND profession NOT IN (\n SELECT profession FROM teacher WHERE department = '计算机系'\n);\n")])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br"),n("span",{staticClass:"line-number"},[s._v("8")]),n("br"),n("span",{staticClass:"line-number"},[s._v("9")]),n("br")])]),n("h3",{attrs:{id:"any-表示至少一个-desc-降序"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#any-表示至少一个-desc-降序"}},[s._v("#")]),s._v(" ANY 表示至少一个 - DESC ( 降序 )")]),s._v(" "),n("p",[n("strong",[s._v("查询课程 "),n("code",[s._v("3-105")]),s._v(" 且成绩 "),n("u",[s._v("至少")]),s._v(" 高于 "),n("code",[s._v("3-245")]),s._v(" 的 "),n("code",[s._v("score")]),s._v(" 表。")])]),s._v(" "),n("div",{staticClass:"language-mysql line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v("SELECT * FROM score WHERE c_no = '3-105';\n+------+-------+--------+\n- s_no: c_no : degree\n+------+-------+--------+\n- 101 : 3-105: 90\n- 102 : 3-105: 91\n- 103 : 3-105: 92\n- 104 : 3-105: 89\n- 105 : 3-105: 88\n- 109 : 3-105: 76\n+------+-------+--------+\n\nSELECT * FROM score WHERE c_no = '3-245';\n+------+-------+--------+\n- s_no: c_no : degree\n+------+-------+--------+\n- 103 : 3-245: 86\n- 105 : 3-245: 75\n- 109 : 3-245: 68\n+------+-------+--------+\n\n-- ANY: 符合SQL语句中的任意条件。\n-- 也就是说,在 3-105 成绩中,只要有一个大于从 3-245 筛选出来的任意行就符合条件,\n-- 最后根据降序查询结果。\nSELECT * FROM score WHERE c_no = '3-105' AND degree > ANY(\n SELECT degree FROM score WHERE c_no = '3-245'\n) ORDER BY degree DESC;\n+------+-------+--------+\n- s_no: c_no : degree\n+------+-------+--------+\n- 103 : 3-105: 92\n- 102 : 3-105: 91\n- 101 : 3-105: 90\n- 104 : 3-105: 89\n- 105 : 3-105: 88\n- 109 : 3-105: 76\n+------+-------+--------+\n")])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br"),n("span",{staticClass:"line-number"},[s._v("8")]),n("br"),n("span",{staticClass:"line-number"},[s._v("9")]),n("br"),n("span",{staticClass:"line-number"},[s._v("10")]),n("br"),n("span",{staticClass:"line-number"},[s._v("11")]),n("br"),n("span",{staticClass:"line-number"},[s._v("12")]),n("br"),n("span",{staticClass:"line-number"},[s._v("13")]),n("br"),n("span",{staticClass:"line-number"},[s._v("14")]),n("br"),n("span",{staticClass:"line-number"},[s._v("15")]),n("br"),n("span",{staticClass:"line-number"},[s._v("16")]),n("br"),n("span",{staticClass:"line-number"},[s._v("17")]),n("br"),n("span",{staticClass:"line-number"},[s._v("18")]),n("br"),n("span",{staticClass:"line-number"},[s._v("19")]),n("br"),n("span",{staticClass:"line-number"},[s._v("20")]),n("br"),n("span",{staticClass:"line-number"},[s._v("21")]),n("br"),n("span",{staticClass:"line-number"},[s._v("22")]),n("br"),n("span",{staticClass:"line-number"},[s._v("23")]),n("br"),n("span",{staticClass:"line-number"},[s._v("24")]),n("br"),n("span",{staticClass:"line-number"},[s._v("25")]),n("br"),n("span",{staticClass:"line-number"},[s._v("26")]),n("br"),n("span",{staticClass:"line-number"},[s._v("27")]),n("br"),n("span",{staticClass:"line-number"},[s._v("28")]),n("br"),n("span",{staticClass:"line-number"},[s._v("29")]),n("br"),n("span",{staticClass:"line-number"},[s._v("30")]),n("br"),n("span",{staticClass:"line-number"},[s._v("31")]),n("br"),n("span",{staticClass:"line-number"},[s._v("32")]),n("br"),n("span",{staticClass:"line-number"},[s._v("33")]),n("br"),n("span",{staticClass:"line-number"},[s._v("34")]),n("br"),n("span",{staticClass:"line-number"},[s._v("35")]),n("br"),n("span",{staticClass:"line-number"},[s._v("36")]),n("br"),n("span",{staticClass:"line-number"},[s._v("37")]),n("br")])]),n("h3",{attrs:{id:"表示所有的-all"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#表示所有的-all"}},[s._v("#")]),s._v(" 表示所有的 ALL")]),s._v(" "),n("p",[n("strong",[s._v("查询课程 "),n("code",[s._v("3-105")]),s._v(" 且成绩高于 "),n("code",[s._v("3-245")]),s._v(" 的 "),n("code",[s._v("score")]),s._v(" 表。")])]),s._v(" "),n("div",{staticClass:"language-mysql line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v("-- 只需对上一道题稍作修改。\n-- ALL: 符合SQL语句中的所有条件。\n-- 也就是说,在 3-105 每一行成绩中,都要大于从 3-245 筛选出来全部行才算符合条件。\nSELECT * FROM score WHERE c_no = '3-105' AND degree > ALL(\n SELECT degree FROM score WHERE c_no = '3-245'\n);\n+------+-------+--------+\n- s_no: c_no : degree\n+------+-------+--------+\n- 101 : 3-105: 90\n- 102 : 3-105: 91\n- 103 : 3-105: 92\n- 104 : 3-105: 89\n- 105 : 3-105: 88\n+------+-------+--------+\n")])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br"),n("span",{staticClass:"line-number"},[s._v("8")]),n("br"),n("span",{staticClass:"line-number"},[s._v("9")]),n("br"),n("span",{staticClass:"line-number"},[s._v("10")]),n("br"),n("span",{staticClass:"line-number"},[s._v("11")]),n("br"),n("span",{staticClass:"line-number"},[s._v("12")]),n("br"),n("span",{staticClass:"line-number"},[s._v("13")]),n("br"),n("span",{staticClass:"line-number"},[s._v("14")]),n("br"),n("span",{staticClass:"line-number"},[s._v("15")]),n("br")])]),n("h3",{attrs:{id:"复制表的数据作为条件查询"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#复制表的数据作为条件查询"}},[s._v("#")]),s._v(" 复制表的数据作为条件查询")]),s._v(" "),n("p",[n("strong",[s._v("查询某课程成绩比该课程平均成绩低的 "),n("code",[s._v("score")]),s._v(" 表。")])]),s._v(" "),n("div",{staticClass:"language-mysql line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v("-- 查询平均分\nSELECT c_no, AVG(degree) FROM score GROUP BY c_no;\n+-------+-------------+\n- c_no : AVG(degree)\n+-------+-------------+\n- 3-105: 87.6667\n- 3-245: 76.3333\n- 6-166: 81.6667\n+-------+-------------+\n\n-- 查询 score 表\nSELECT degree FROM score;\n+--------+\n- degree\n+--------+\n- 90\n- 91\n- 92\n- 86\n- 85\n- 89\n- 88\n- 75\n- 79\n- 76\n- 68\n- 81\n+--------+\n\n-- 将表 b 作用于表 a 中查询数据\n-- score a (b): 将表声明为 a (b),\n-- 如此就能用 a.c_no = b.c_no 作为条件执行查询了。\nSELECT * FROM score a WHERE degree < (\n (SELECT AVG(degree) FROM score b WHERE a.c_no = b.c_no)\n);\n+------+-------+--------+\n- s_no: c_no : degree\n+------+-------+--------+\n- 105 : 3-245: 75\n- 105 : 6-166: 79\n- 109 : 3-105: 76\n- 109 : 3-245: 68\n- 109 : 6-166: 81\n+------+-------+--------+\n")])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br"),n("span",{staticClass:"line-number"},[s._v("8")]),n("br"),n("span",{staticClass:"line-number"},[s._v("9")]),n("br"),n("span",{staticClass:"line-number"},[s._v("10")]),n("br"),n("span",{staticClass:"line-number"},[s._v("11")]),n("br"),n("span",{staticClass:"line-number"},[s._v("12")]),n("br"),n("span",{staticClass:"line-number"},[s._v("13")]),n("br"),n("span",{staticClass:"line-number"},[s._v("14")]),n("br"),n("span",{staticClass:"line-number"},[s._v("15")]),n("br"),n("span",{staticClass:"line-number"},[s._v("16")]),n("br"),n("span",{staticClass:"line-number"},[s._v("17")]),n("br"),n("span",{staticClass:"line-number"},[s._v("18")]),n("br"),n("span",{staticClass:"line-number"},[s._v("19")]),n("br"),n("span",{staticClass:"line-number"},[s._v("20")]),n("br"),n("span",{staticClass:"line-number"},[s._v("21")]),n("br"),n("span",{staticClass:"line-number"},[s._v("22")]),n("br"),n("span",{staticClass:"line-number"},[s._v("23")]),n("br"),n("span",{staticClass:"line-number"},[s._v("24")]),n("br"),n("span",{staticClass:"line-number"},[s._v("25")]),n("br"),n("span",{staticClass:"line-number"},[s._v("26")]),n("br"),n("span",{staticClass:"line-number"},[s._v("27")]),n("br"),n("span",{staticClass:"line-number"},[s._v("28")]),n("br"),n("span",{staticClass:"line-number"},[s._v("29")]),n("br"),n("span",{staticClass:"line-number"},[s._v("30")]),n("br"),n("span",{staticClass:"line-number"},[s._v("31")]),n("br"),n("span",{staticClass:"line-number"},[s._v("32")]),n("br"),n("span",{staticClass:"line-number"},[s._v("33")]),n("br"),n("span",{staticClass:"line-number"},[s._v("34")]),n("br"),n("span",{staticClass:"line-number"},[s._v("35")]),n("br"),n("span",{staticClass:"line-number"},[s._v("36")]),n("br"),n("span",{staticClass:"line-number"},[s._v("37")]),n("br"),n("span",{staticClass:"line-number"},[s._v("38")]),n("br"),n("span",{staticClass:"line-number"},[s._v("39")]),n("br"),n("span",{staticClass:"line-number"},[s._v("40")]),n("br"),n("span",{staticClass:"line-number"},[s._v("41")]),n("br"),n("span",{staticClass:"line-number"},[s._v("42")]),n("br"),n("span",{staticClass:"line-number"},[s._v("43")]),n("br"),n("span",{staticClass:"line-number"},[s._v("44")]),n("br")])]),n("h3",{attrs:{id:"子查询-4"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#子查询-4"}},[s._v("#")]),s._v(" 子查询 - 4")]),s._v(" "),n("p",[n("strong",[s._v("查询所有任课 ( 在 "),n("code",[s._v("course")]),s._v(" 表里有课程 ) 教师的 "),n("code",[s._v("name")]),s._v(" 和 "),n("code",[s._v("department")])]),s._v(" 。")]),s._v(" "),n("div",{staticClass:"language-mysql line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v("SELECT name, department FROM teacher WHERE no IN (SELECT t_no FROM course);\n+--------+-----------------+\n- name : department\n+--------+-----------------+\n- 李诚 : 计算机系\n- 王萍 : 计算机系\n- 刘冰 : 电子工程系\n- 张旭 : 电子工程系\n+--------+-----------------+\n")])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br"),n("span",{staticClass:"line-number"},[s._v("8")]),n("br"),n("span",{staticClass:"line-number"},[s._v("9")]),n("br")])]),n("h3",{attrs:{id:"条件加组筛选"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#条件加组筛选"}},[s._v("#")]),s._v(" 条件加组筛选")]),s._v(" "),n("p",[n("strong",[s._v("查询 "),n("code",[s._v("student")]),s._v(" 表中至少有 2 名男生的 "),n("code",[s._v("class")]),s._v(" 。")])]),s._v(" "),n("div",{staticClass:"language-mysql line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v("-- 查看学生表信息\nSELECT * FROM student;\n+-----+-----------+-----+------------+-------+\n- no : name : sex: birthday : class\n+-----+-----------+-----+------------+-------+\n- 101: 曾华 : 男 : 1977-09-01: 95033\n- 102: 匡明 : 男 : 1975-10-02: 95031\n- 103: 王丽 : 女 : 1976-01-23: 95033\n- 104: 李军 : 男 : 1976-02-20: 95033\n- 105: 王芳 : 女 : 1975-02-10: 95031\n- 106: 陆军 : 男 : 1974-06-03: 95031\n- 107: 王尼玛 : 男 : 1976-02-20: 95033\n- 108: 张全蛋 : 男 : 1975-02-10: 95031\n- 109: 赵铁柱 : 男 : 1974-06-03: 95031\n- 110: 张飞 : 男 : 1974-06-03: 95038\n+-----+-----------+-----+------------+-------+\n\n-- 只查询性别为男,然后按 class 分组,并限制 class 行大于 1。\nSELECT class FROM student WHERE sex = '男' GROUP BY class HAVING COUNT(*) > 1;\n+-------+\n- class\n+-------+\n- 95033\n- 95031\n+-------+\n")])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br"),n("span",{staticClass:"line-number"},[s._v("8")]),n("br"),n("span",{staticClass:"line-number"},[s._v("9")]),n("br"),n("span",{staticClass:"line-number"},[s._v("10")]),n("br"),n("span",{staticClass:"line-number"},[s._v("11")]),n("br"),n("span",{staticClass:"line-number"},[s._v("12")]),n("br"),n("span",{staticClass:"line-number"},[s._v("13")]),n("br"),n("span",{staticClass:"line-number"},[s._v("14")]),n("br"),n("span",{staticClass:"line-number"},[s._v("15")]),n("br"),n("span",{staticClass:"line-number"},[s._v("16")]),n("br"),n("span",{staticClass:"line-number"},[s._v("17")]),n("br"),n("span",{staticClass:"line-number"},[s._v("18")]),n("br"),n("span",{staticClass:"line-number"},[s._v("19")]),n("br"),n("span",{staticClass:"line-number"},[s._v("20")]),n("br"),n("span",{staticClass:"line-number"},[s._v("21")]),n("br"),n("span",{staticClass:"line-number"},[s._v("22")]),n("br"),n("span",{staticClass:"line-number"},[s._v("23")]),n("br"),n("span",{staticClass:"line-number"},[s._v("24")]),n("br"),n("span",{staticClass:"line-number"},[s._v("25")]),n("br")])]),n("h3",{attrs:{id:"notlike-模糊查询取反"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#notlike-模糊查询取反"}},[s._v("#")]),s._v(" NOTLIKE 模糊查询取反")]),s._v(" "),n("p",[n("strong",[s._v("查询 "),n("code",[s._v("student")]),s._v(' 表中不姓 "王" 的同学记录。')])]),s._v(" "),n("div",{staticClass:"language-mysql line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v("-- NOT: 取反\n-- LIKE: 模糊查询\nmysql> SELECT * FROM student WHERE name NOT LIKE '王%';\n+-----+-----------+-----+------------+-------+\n- no : name : sex: birthday : class\n+-----+-----------+-----+------------+-------+\n- 101: 曾华 : 男 : 1977-09-01: 95033\n- 102: 匡明 : 男 : 1975-10-02: 95031\n- 104: 李军 : 男 : 1976-02-20: 95033\n- 106: 陆军 : 男 : 1974-06-03: 95031\n- 108: 张全蛋 : 男 : 1975-02-10: 95031\n- 109: 赵铁柱 : 男 : 1974-06-03: 95031\n- 110: 张飞 : 男 : 1974-06-03: 95038\n+-----+-----------+-----+------------+-------+\n")])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br"),n("span",{staticClass:"line-number"},[s._v("8")]),n("br"),n("span",{staticClass:"line-number"},[s._v("9")]),n("br"),n("span",{staticClass:"line-number"},[s._v("10")]),n("br"),n("span",{staticClass:"line-number"},[s._v("11")]),n("br"),n("span",{staticClass:"line-number"},[s._v("12")]),n("br"),n("span",{staticClass:"line-number"},[s._v("13")]),n("br"),n("span",{staticClass:"line-number"},[s._v("14")]),n("br")])]),n("h3",{attrs:{id:"year-与-now-函数"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#year-与-now-函数"}},[s._v("#")]),s._v(" YEAR 与 NOW 函数")]),s._v(" "),n("p",[n("strong",[s._v("查询 "),n("code",[s._v("student")]),s._v(" 表中每个学生的姓名和年龄。")])]),s._v(" "),n("div",{staticClass:"language-mysql line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v("-- 使用函数 YEAR(NOW()) 计算出当前年份,减去出生年份后得出年龄。\nSELECT name, YEAR(NOW()) - YEAR(birthday) as age FROM student;\n+-----------+------+\n- name : age\n+-----------+------+\n- 曾华 : 42\n- 匡明 : 44\n- 王丽 : 43\n- 李军 : 43\n- 王芳 : 44\n- 陆军 : 45\n- 王尼玛 : 43\n- 张全蛋 : 44\n- 赵铁柱 : 45\n- 张飞 : 45\n+-----------+------+\n")])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br"),n("span",{staticClass:"line-number"},[s._v("8")]),n("br"),n("span",{staticClass:"line-number"},[s._v("9")]),n("br"),n("span",{staticClass:"line-number"},[s._v("10")]),n("br"),n("span",{staticClass:"line-number"},[s._v("11")]),n("br"),n("span",{staticClass:"line-number"},[s._v("12")]),n("br"),n("span",{staticClass:"line-number"},[s._v("13")]),n("br"),n("span",{staticClass:"line-number"},[s._v("14")]),n("br"),n("span",{staticClass:"line-number"},[s._v("15")]),n("br"),n("span",{staticClass:"line-number"},[s._v("16")]),n("br")])]),n("h3",{attrs:{id:"max-与-min-函数"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#max-与-min-函数"}},[s._v("#")]),s._v(" MAX 与 MIN 函数")]),s._v(" "),n("p",[n("strong",[s._v("查询 "),n("code",[s._v("student")]),s._v(" 表中最大和最小的 "),n("code",[s._v("birthday")]),s._v(" 值。")])]),s._v(" "),n("div",{staticClass:"language-mysql line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v("SELECT MAX(birthday), MIN(birthday) FROM student;\n+---------------+---------------+\n- MAX(birthday): MIN(birthday)\n+---------------+---------------+\n- 1977-09-01 : 1974-06-03\n+---------------+---------------+\n")])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br")])]),n("h3",{attrs:{id:"多段排序"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#多段排序"}},[s._v("#")]),s._v(" 多段排序")]),s._v(" "),n("p",[n("strong",[s._v("以 "),n("code",[s._v("class")]),s._v(" 和 "),n("code",[s._v("birthday")]),s._v(" 从大到小的顺序查询 "),n("code",[s._v("student")]),s._v(" 表。")])]),s._v(" "),n("div",{staticClass:"language-mysql line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v("SELECT * FROM student ORDER BY class DESC, birthday;\n+-----+-----------+-----+------------+-------+\n- no : name : sex: birthday : class\n+-----+-----------+-----+------------+-------+\n- 110: 张飞 : 男 : 1974-06-03: 95038\n- 103: 王丽 : 女 : 1976-01-23: 95033\n- 104: 李军 : 男 : 1976-02-20: 95033\n- 107: 王尼玛 : 男 : 1976-02-20: 95033\n- 101: 曾华 : 男 : 1977-09-01: 95033\n- 106: 陆军 : 男 : 1974-06-03: 95031\n- 109: 赵铁柱 : 男 : 1974-06-03: 95031\n- 105: 王芳 : 女 : 1975-02-10: 95031\n- 108: 张全蛋 : 男 : 1975-02-10: 95031\n- 102: 匡明 : 男 : 1975-10-02: 95031\n+-----+-----------+-----+------------+-------+\n")])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br"),n("span",{staticClass:"line-number"},[s._v("8")]),n("br"),n("span",{staticClass:"line-number"},[s._v("9")]),n("br"),n("span",{staticClass:"line-number"},[s._v("10")]),n("br"),n("span",{staticClass:"line-number"},[s._v("11")]),n("br"),n("span",{staticClass:"line-number"},[s._v("12")]),n("br"),n("span",{staticClass:"line-number"},[s._v("13")]),n("br"),n("span",{staticClass:"line-number"},[s._v("14")]),n("br"),n("span",{staticClass:"line-number"},[s._v("15")]),n("br")])]),n("h3",{attrs:{id:"子查询-5"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#子查询-5"}},[s._v("#")]),s._v(" 子查询 - 5")]),s._v(" "),n("p",[n("strong",[s._v('查询 "男" 教师及其所上的课程。')])]),s._v(" "),n("div",{staticClass:"language-mysql line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v("SELECT * FROM course WHERE t_no in (SELECT no FROM teacher WHERE sex = '男');\n+-------+--------------+------+\n- no : name : t_no\n+-------+--------------+------+\n- 3-245: 操作系统 : 804\n- 6-166: 数字电路 : 856\n+-------+--------------+------+\n")])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br")])]),n("h3",{attrs:{id:"max-函数与子查询"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#max-函数与子查询"}},[s._v("#")]),s._v(" MAX 函数与子查询")]),s._v(" "),n("p",[n("strong",[s._v("查询最高分同学的 "),n("code",[s._v("score")]),s._v(" 表。")])]),s._v(" "),n("div",{staticClass:"language-mysql line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v("-- 找出最高成绩(该查询只能有一个结果)\nSELECT MAX(degree) FROM score;\n\n-- 根据上面的条件筛选出所有最高成绩表,\n-- 该查询可能有多个结果,假设 degree 值多次符合条件。\nSELECT * FROM score WHERE degree = (SELECT MAX(degree) FROM score);\n+------+-------+--------+\n- s_no: c_no : degree\n+------+-------+--------+\n- 103 : 3-105: 92\n+------+-------+--------+\n")])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br"),n("span",{staticClass:"line-number"},[s._v("8")]),n("br"),n("span",{staticClass:"line-number"},[s._v("9")]),n("br"),n("span",{staticClass:"line-number"},[s._v("10")]),n("br"),n("span",{staticClass:"line-number"},[s._v("11")]),n("br")])]),n("h3",{attrs:{id:"子查询-6"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#子查询-6"}},[s._v("#")]),s._v(" 子查询 - 6")]),s._v(" "),n("p",[n("strong",[s._v('查询和 "李军" 同性别的所有同学 '),n("code",[s._v("name")]),s._v(" 。")])]),s._v(" "),n("div",{staticClass:"language-mysql line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v("-- 首先将李军的性别作为条件取出来\nSELECT sex FROM student WHERE name = '李军';\n+-----+\n- sex\n+-----+\n- 男\n+-----+\n\n-- 根据性别查询 name 和 sex\nSELECT name, sex FROM student WHERE sex = (\n SELECT sex FROM student WHERE name = '李军'\n);\n+-----------+-----+\n- name : sex\n+-----------+-----+\n- 曾华 : 男\n- 匡明 : 男\n- 李军 : 男\n- 陆军 : 男\n- 王尼玛 : 男\n- 张全蛋 : 男\n- 赵铁柱 : 男\n- 张飞 : 男\n+-----------+-----+\n")])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br"),n("span",{staticClass:"line-number"},[s._v("8")]),n("br"),n("span",{staticClass:"line-number"},[s._v("9")]),n("br"),n("span",{staticClass:"line-number"},[s._v("10")]),n("br"),n("span",{staticClass:"line-number"},[s._v("11")]),n("br"),n("span",{staticClass:"line-number"},[s._v("12")]),n("br"),n("span",{staticClass:"line-number"},[s._v("13")]),n("br"),n("span",{staticClass:"line-number"},[s._v("14")]),n("br"),n("span",{staticClass:"line-number"},[s._v("15")]),n("br"),n("span",{staticClass:"line-number"},[s._v("16")]),n("br"),n("span",{staticClass:"line-number"},[s._v("17")]),n("br"),n("span",{staticClass:"line-number"},[s._v("18")]),n("br"),n("span",{staticClass:"line-number"},[s._v("19")]),n("br"),n("span",{staticClass:"line-number"},[s._v("20")]),n("br"),n("span",{staticClass:"line-number"},[s._v("21")]),n("br"),n("span",{staticClass:"line-number"},[s._v("22")]),n("br"),n("span",{staticClass:"line-number"},[s._v("23")]),n("br"),n("span",{staticClass:"line-number"},[s._v("24")]),n("br")])]),n("h3",{attrs:{id:"子查询-7"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#子查询-7"}},[s._v("#")]),s._v(" 子查询 - 7")]),s._v(" "),n("p",[n("strong",[s._v('查询和 "李军" 同性别且同班的同学 '),n("code",[s._v("name")]),s._v(" 。")])]),s._v(" "),n("div",{staticClass:"language-mysql line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v("SELECT name, sex, class FROM student WHERE sex = (\n SELECT sex FROM student WHERE name = '李军'\n) AND class = (\n SELECT class FROM student WHERE name = '李军'\n);\n+-----------+-----+-------+\n- name : sex: class\n+-----------+-----+-------+\n- 曾华 : 男 : 95033\n- 李军 : 男 : 95033\n- 王尼玛 : 男 : 95033\n+-----------+-----+-------+\n")])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br"),n("span",{staticClass:"line-number"},[s._v("8")]),n("br"),n("span",{staticClass:"line-number"},[s._v("9")]),n("br"),n("span",{staticClass:"line-number"},[s._v("10")]),n("br"),n("span",{staticClass:"line-number"},[s._v("11")]),n("br"),n("span",{staticClass:"line-number"},[s._v("12")]),n("br")])]),n("h3",{attrs:{id:"子查询-8"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#子查询-8"}},[s._v("#")]),s._v(" 子查询 - 8")]),s._v(" "),n("p",[n("strong",[s._v('查询所有选修 "计算机导论" 课程的 "男" 同学成绩表。')])]),s._v(" "),n("p",[s._v('需要的 "计算机导论" 和性别为 "男" 的编号可以在 '),n("code",[s._v("course")]),s._v(" 和 "),n("code",[s._v("student")]),s._v(" 表中找到。")]),s._v(" "),n("div",{staticClass:"language-mysql line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v("SELECT * FROM score WHERE c_no = (\n SELECT no FROM course WHERE name = '计算机导论'\n) AND s_no IN (\n SELECT no FROM student WHERE sex = '男'\n);\n+------+-------+--------+\n- s_no: c_no : degree\n+------+-------+--------+\n- 101 : 3-105: 90\n- 102 : 3-105: 91\n- 104 : 3-105: 89\n- 109 : 3-105: 76\n+------+-------+--------+\n")])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br"),n("span",{staticClass:"line-number"},[s._v("8")]),n("br"),n("span",{staticClass:"line-number"},[s._v("9")]),n("br"),n("span",{staticClass:"line-number"},[s._v("10")]),n("br"),n("span",{staticClass:"line-number"},[s._v("11")]),n("br"),n("span",{staticClass:"line-number"},[s._v("12")]),n("br"),n("span",{staticClass:"line-number"},[s._v("13")]),n("br")])]),n("h3",{attrs:{id:"按等级查询"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#按等级查询"}},[s._v("#")]),s._v(" 按等级查询")]),s._v(" "),n("p",[s._v("建立一个 "),n("code",[s._v("grade")]),s._v(" 表代表学生的成绩等级,并插入数据:")]),s._v(" "),n("div",{staticClass:"language-mysql line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v("CREATE TABLE grade (\n low INT(3),\n upp INT(3),\n grade char(1)\n);\n\nINSERT INTO grade VALUES (90, 100, 'A');\nINSERT INTO grade VALUES (80, 89, 'B');\nINSERT INTO grade VALUES (70, 79, 'C');\nINSERT INTO grade VALUES (60, 69, 'D');\nINSERT INTO grade VALUES (0, 59, 'E');\n\nSELECT * FROM grade;\n+------+------+-------+\n- low : upp : grade\n+------+------+-------+\n- 90: 100: A\n- 80: 89: B\n- 70: 79: C\n- 60: 69: D\n- 0: 59: E\n+------+------+-------+\n")])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br"),n("span",{staticClass:"line-number"},[s._v("8")]),n("br"),n("span",{staticClass:"line-number"},[s._v("9")]),n("br"),n("span",{staticClass:"line-number"},[s._v("10")]),n("br"),n("span",{staticClass:"line-number"},[s._v("11")]),n("br"),n("span",{staticClass:"line-number"},[s._v("12")]),n("br"),n("span",{staticClass:"line-number"},[s._v("13")]),n("br"),n("span",{staticClass:"line-number"},[s._v("14")]),n("br"),n("span",{staticClass:"line-number"},[s._v("15")]),n("br"),n("span",{staticClass:"line-number"},[s._v("16")]),n("br"),n("span",{staticClass:"line-number"},[s._v("17")]),n("br"),n("span",{staticClass:"line-number"},[s._v("18")]),n("br"),n("span",{staticClass:"line-number"},[s._v("19")]),n("br"),n("span",{staticClass:"line-number"},[s._v("20")]),n("br"),n("span",{staticClass:"line-number"},[s._v("21")]),n("br"),n("span",{staticClass:"line-number"},[s._v("22")]),n("br")])]),n("p",[n("strong",[s._v("查询所有学生的 "),n("code",[s._v("s_no")]),s._v(" 、"),n("code",[s._v("c_no")]),s._v(" 和 "),n("code",[s._v("grade")]),s._v(" 列。")])]),s._v(" "),n("p",[s._v("思路是,使用区间 ( "),n("code",[s._v("BETWEEN")]),s._v(" ) 查询,判断学生的成绩 ( "),n("code",[s._v("degree")]),s._v(" ) 在 "),n("code",[s._v("grade")]),s._v(" 表的 "),n("code",[s._v("low")]),s._v(" 和 "),n("code",[s._v("upp")]),s._v(" 之间。")]),s._v(" "),n("div",{staticClass:"language-mysql line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v("SELECT s_no, c_no, grade FROM score, grade\nWHERE degree BETWEEN low AND upp;\n+------+-------+-------+\n- s_no: c_no : grade\n+------+-------+-------+\n- 101 : 3-105: A\n- 102 : 3-105: A\n- 103 : 3-105: A\n- 103 : 3-245: B\n- 103 : 6-166: B\n- 104 : 3-105: B\n- 105 : 3-105: B\n- 105 : 3-245: C\n- 105 : 6-166: C\n- 109 : 3-105: C\n- 109 : 3-245: D\n- 109 : 6-166: B\n+------+-------+-------+\n")])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br"),n("span",{staticClass:"line-number"},[s._v("8")]),n("br"),n("span",{staticClass:"line-number"},[s._v("9")]),n("br"),n("span",{staticClass:"line-number"},[s._v("10")]),n("br"),n("span",{staticClass:"line-number"},[s._v("11")]),n("br"),n("span",{staticClass:"line-number"},[s._v("12")]),n("br"),n("span",{staticClass:"line-number"},[s._v("13")]),n("br"),n("span",{staticClass:"line-number"},[s._v("14")]),n("br"),n("span",{staticClass:"line-number"},[s._v("15")]),n("br"),n("span",{staticClass:"line-number"},[s._v("16")]),n("br"),n("span",{staticClass:"line-number"},[s._v("17")]),n("br"),n("span",{staticClass:"line-number"},[s._v("18")]),n("br")])]),n("h3",{attrs:{id:"连接查询"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#连接查询"}},[s._v("#")]),s._v(" 连接查询")]),s._v(" "),n("p",[s._v("准备用于测试连接查询的数据:")]),s._v(" "),n("div",{staticClass:"language-mysql line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v("CREATE DATABASE testJoin;\n\nCREATE TABLE person (\n id INT,\n name VARCHAR(20),\n cardId INT\n);\n\nCREATE TABLE card (\n id INT,\n name VARCHAR(20)\n);\n\nINSERT INTO card VALUES (1, '饭卡'), (2, '建行卡'), (3, '农行卡'), (4, '工商卡'), (5, '邮政卡');\nSELECT * FROM card;\n+------+-----------+\n- id : name\n+------+-----------+\n- 1: 饭卡\n- 2: 建行卡\n- 3: 农行卡\n- 4: 工商卡\n- 5: 邮政卡\n+------+-----------+\n\nINSERT INTO person VALUES (1, '张三', 1), (2, '李四', 3), (3, '王五', 6);\nSELECT * FROM person;\n+------+--------+--------+\n- id : name : cardId\n+------+--------+--------+\n- 1: 张三 : 1\n- 2: 李四 : 3\n- 3: 王五 : 6\n+------+--------+--------+\n")])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br"),n("span",{staticClass:"line-number"},[s._v("8")]),n("br"),n("span",{staticClass:"line-number"},[s._v("9")]),n("br"),n("span",{staticClass:"line-number"},[s._v("10")]),n("br"),n("span",{staticClass:"line-number"},[s._v("11")]),n("br"),n("span",{staticClass:"line-number"},[s._v("12")]),n("br"),n("span",{staticClass:"line-number"},[s._v("13")]),n("br"),n("span",{staticClass:"line-number"},[s._v("14")]),n("br"),n("span",{staticClass:"line-number"},[s._v("15")]),n("br"),n("span",{staticClass:"line-number"},[s._v("16")]),n("br"),n("span",{staticClass:"line-number"},[s._v("17")]),n("br"),n("span",{staticClass:"line-number"},[s._v("18")]),n("br"),n("span",{staticClass:"line-number"},[s._v("19")]),n("br"),n("span",{staticClass:"line-number"},[s._v("20")]),n("br"),n("span",{staticClass:"line-number"},[s._v("21")]),n("br"),n("span",{staticClass:"line-number"},[s._v("22")]),n("br"),n("span",{staticClass:"line-number"},[s._v("23")]),n("br"),n("span",{staticClass:"line-number"},[s._v("24")]),n("br"),n("span",{staticClass:"line-number"},[s._v("25")]),n("br"),n("span",{staticClass:"line-number"},[s._v("26")]),n("br"),n("span",{staticClass:"line-number"},[s._v("27")]),n("br"),n("span",{staticClass:"line-number"},[s._v("28")]),n("br"),n("span",{staticClass:"line-number"},[s._v("29")]),n("br"),n("span",{staticClass:"line-number"},[s._v("30")]),n("br"),n("span",{staticClass:"line-number"},[s._v("31")]),n("br"),n("span",{staticClass:"line-number"},[s._v("32")]),n("br"),n("span",{staticClass:"line-number"},[s._v("33")]),n("br"),n("span",{staticClass:"line-number"},[s._v("34")]),n("br")])]),n("p",[s._v("分析两张表发现,"),n("code",[s._v("person")]),s._v(" 表并没有为 "),n("code",[s._v("cardId")]),s._v(" 字段设置一个在 "),n("code",[s._v("card")]),s._v(" 表中对应的 "),n("code",[s._v("id")]),s._v(" 外键。如果设置了的话,"),n("code",[s._v("person")]),s._v(" 中 "),n("code",[s._v("cardId")]),s._v(" 字段值为 "),n("code",[s._v("6")]),s._v(" 的行就插不进去,因为该 "),n("code",[s._v("cardId")]),s._v(" 值在 "),n("code",[s._v("card")]),s._v(" 表中并没有。")]),s._v(" "),n("h4",{attrs:{id:"内连接"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#内连接"}},[s._v("#")]),s._v(" 内连接")]),s._v(" "),n("p",[s._v("要查询这两张表中有关系的数据,可以使用 "),n("code",[s._v("INNER JOIN")]),s._v(" ( 内连接 ) 将它们连接在一起。")]),s._v(" "),n("div",{staticClass:"language-mysql line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v("-- INNER JOIN: 表示为内连接,将两张表拼接在一起。\n-- on: 表示要执行某个条件。\nSELECT * FROM person INNER JOIN card on person.cardId = card.id;\n+------+--------+--------+------+-----------+\n- id : name : cardId: id : name\n+------+--------+--------+------+-----------+\n- 1: 张三 : 1: 1: 饭卡\n- 2: 李四 : 3: 3: 农行卡\n+------+--------+--------+------+-----------+\n\n-- 将 INNER 关键字省略掉,结果也是一样的。\n-- SELECT * FROM person JOIN card on person.cardId = card.id;\n")])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br"),n("span",{staticClass:"line-number"},[s._v("8")]),n("br"),n("span",{staticClass:"line-number"},[s._v("9")]),n("br"),n("span",{staticClass:"line-number"},[s._v("10")]),n("br"),n("span",{staticClass:"line-number"},[s._v("11")]),n("br"),n("span",{staticClass:"line-number"},[s._v("12")]),n("br")])]),n("blockquote",[n("p",[s._v("注意:"),n("code",[s._v("card")]),s._v(" 的整张表被连接到了右边。")])]),s._v(" "),n("h4",{attrs:{id:"左外连接"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#左外连接"}},[s._v("#")]),s._v(" 左外连接")]),s._v(" "),n("p",[s._v("完整显示左边的表 ( "),n("code",[s._v("person")]),s._v(" ) ,右边的表如果符合条件就显示,不符合则补 "),n("code",[s._v("NULL")]),s._v(" 。")]),s._v(" "),n("div",{staticClass:"language-mysql line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v("-- LEFT JOIN 也叫做 LEFT OUTER JOIN,用这两种方式的查询结果是一样的。\nSELECT * FROM person LEFT JOIN card on person.cardId = card.id;\n+------+--------+--------+------+-----------+\n- id : name : cardId: id : name\n+------+--------+--------+------+-----------+\n- 1: 张三 : 1: 1: 饭卡\n- 2: 李四 : 3: 3: 农行卡\n- 3: 王五 : 6: NULL: NULL\n+------+--------+--------+------+-----------+\n")])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br"),n("span",{staticClass:"line-number"},[s._v("8")]),n("br"),n("span",{staticClass:"line-number"},[s._v("9")]),n("br")])]),n("h4",{attrs:{id:"右外链接"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#右外链接"}},[s._v("#")]),s._v(" 右外链接")]),s._v(" "),n("p",[s._v("完整显示右边的表 ( "),n("code",[s._v("card")]),s._v(" ) ,左边的表如果符合条件就显示,不符合则补 "),n("code",[s._v("NULL")]),s._v(" 。")]),s._v(" "),n("div",{staticClass:"language-mysql line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v("SELECT * FROM person RIGHT JOIN card on person.cardId = card.id;\n+------+--------+--------+------+-----------+\n- id : name : cardId: id : name\n+------+--------+--------+------+-----------+\n- 1: 张三 : 1: 1: 饭卡\n- 2: 李四 : 3: 3: 农行卡\n- NULL: NULL : NULL: 2: 建行卡\n- NULL: NULL : NULL: 4: 工商卡\n- NULL: NULL : NULL: 5: 邮政卡\n+------+--------+--------+------+-----------+\n")])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br"),n("span",{staticClass:"line-number"},[s._v("8")]),n("br"),n("span",{staticClass:"line-number"},[s._v("9")]),n("br"),n("span",{staticClass:"line-number"},[s._v("10")]),n("br")])]),n("h4",{attrs:{id:"全外链接"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#全外链接"}},[s._v("#")]),s._v(" 全外链接")]),s._v(" "),n("p",[s._v("完整显示两张表的全部数据。")]),s._v(" "),n("div",{staticClass:"language-mysql line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v("-- MySQL 不支持这种语法的全外连接\n-- SELECT * FROM person FULL JOIN card on person.cardId = card.id;\n-- 出现错误:\n-- ERROR 1054 (42S22): Unknown column 'person.cardId' in 'on clause'\n\n-- MySQL全连接语法,使用 UNION 将两张表合并在一起。\nSELECT * FROM person LEFT JOIN card on person.cardId = card.id\nUNION\nSELECT * FROM person RIGHT JOIN card on person.cardId = card.id;\n+------+--------+--------+------+-----------+\n- id : name : cardId: id : name\n+------+--------+--------+------+-----------+\n- 1: 张三 : 1: 1: 饭卡\n- 2: 李四 : 3: 3: 农行卡\n- 3: 王五 : 6: NULL: NULL\n- NULL: NULL : NULL: 2: 建行卡\n- NULL: NULL : NULL: 4: 工商卡\n- NULL: NULL : NULL: 5: 邮政卡\n+------+--------+--------+------+-----------+\n")])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br"),n("span",{staticClass:"line-number"},[s._v("8")]),n("br"),n("span",{staticClass:"line-number"},[s._v("9")]),n("br"),n("span",{staticClass:"line-number"},[s._v("10")]),n("br"),n("span",{staticClass:"line-number"},[s._v("11")]),n("br"),n("span",{staticClass:"line-number"},[s._v("12")]),n("br"),n("span",{staticClass:"line-number"},[s._v("13")]),n("br"),n("span",{staticClass:"line-number"},[s._v("14")]),n("br"),n("span",{staticClass:"line-number"},[s._v("15")]),n("br"),n("span",{staticClass:"line-number"},[s._v("16")]),n("br"),n("span",{staticClass:"line-number"},[s._v("17")]),n("br"),n("span",{staticClass:"line-number"},[s._v("18")]),n("br"),n("span",{staticClass:"line-number"},[s._v("19")]),n("br")])]),n("h2",{attrs:{id:"事务"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#事务"}},[s._v("#")]),s._v(" 事务")]),s._v(" "),n("p",[s._v("在 MySQL 中,事务其实是一个最小的不可分割的工作单元。事务能够"),n("strong",[s._v("保证一个业务的完整性")]),s._v("。")]),s._v(" "),n("p",[s._v("比如我们的银行转账:")]),s._v(" "),n("div",{staticClass:"language-mysql line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v("-- a -> -100\nUPDATE user set money = money - 100 WHERE name = 'a';\n\n-- b -> +100\nUPDATE user set money = money + 100 WHERE name = 'b';\n")])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br")])]),n("p",[s._v("在实际项目中,假设只有一条 SQL 语句执行成功,而另外一条执行失败了,就会出现数据前后不一致。")]),s._v(" "),n("p",[s._v("因此,在执行多条有关联 SQL 语句时,"),n("strong",[s._v("事务")]),s._v("可能会要求这些 SQL 语句要么同时执行成功,要么就都执行失败。")]),s._v(" "),n("h3",{attrs:{id:"如何控制事务-commit-rollback"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#如何控制事务-commit-rollback"}},[s._v("#")]),s._v(" 如何控制事务 - COMMIT / ROLLBACK")]),s._v(" "),n("p",[s._v("在 MySQL 中,事务的"),n("strong",[s._v("自动提交")]),s._v("状态默认是开启的。")]),s._v(" "),n("div",{staticClass:"language-mysql line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v("-- 查询事务的自动提交状态\nSELECT @@AUTOCOMMIT;\n+--------------+\n- @@AUTOCOMMIT\n+--------------+\n- 1\n+--------------+\n")])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br")])]),n("p",[n("strong",[s._v("自动提交的作用")]),s._v(":当我们执行一条 SQL 语句的时候,其产生的效果就会立即体现出来,且不能"),n("strong",[s._v("回滚")]),s._v("。")]),s._v(" "),n("p",[s._v("什么是回滚?举个例子:")]),s._v(" "),n("div",{staticClass:"language-mysql line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v("CREATE DATABASE bank;\n\nUSE bank;\n\nCREATE TABLE user (\n id INT PRIMARY KEY,\n name VARCHAR(20),\n money INT\n);\n\nINSERT INTO user VALUES (1, 'a', 1000);\n\nSELECT * FROM user;\n+----+------+-------+\n- id: name: money\n+----+------+-------+\n- 1: a : 1000\n+----+------+-------+\n")])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br"),n("span",{staticClass:"line-number"},[s._v("8")]),n("br"),n("span",{staticClass:"line-number"},[s._v("9")]),n("br"),n("span",{staticClass:"line-number"},[s._v("10")]),n("br"),n("span",{staticClass:"line-number"},[s._v("11")]),n("br"),n("span",{staticClass:"line-number"},[s._v("12")]),n("br"),n("span",{staticClass:"line-number"},[s._v("13")]),n("br"),n("span",{staticClass:"line-number"},[s._v("14")]),n("br"),n("span",{staticClass:"line-number"},[s._v("15")]),n("br"),n("span",{staticClass:"line-number"},[s._v("16")]),n("br"),n("span",{staticClass:"line-number"},[s._v("17")]),n("br"),n("span",{staticClass:"line-number"},[s._v("18")]),n("br")])]),n("p",[s._v("可以看到,在执行插入语句后数据立刻生效,原因是 MySQL 中的事务自动将它"),n("strong",[s._v("提交")]),s._v("到了数据库中。那么所谓"),n("strong",[s._v("回滚")]),s._v("的意思就是,撤销执行过的所有 SQL 语句,使其回滚到"),n("strong",[s._v("最后一次提交")]),s._v("数据时的状态。")]),s._v(" "),n("p",[s._v("在 MySQL 中使用 "),n("code",[s._v("ROLLBACK")]),s._v(" 执行回滚:")]),s._v(" "),n("div",{staticClass:"language-mysql line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v("-- 回滚到最后一次提交\nROLLBACK;\n\nSELECT * FROM user;\n+----+------+-------+\n- id: name: money\n+----+------+-------+\n- 1: a : 1000\n+----+------+-------+\n")])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br"),n("span",{staticClass:"line-number"},[s._v("8")]),n("br"),n("span",{staticClass:"line-number"},[s._v("9")]),n("br")])]),n("p",[s._v("由于所有执行过的 SQL 语句都已经被提交过了,所以数据并没有发生回滚。那如何让数据可以发生回滚?")]),s._v(" "),n("div",{staticClass:"language-mysql line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v("-- 关闭自动提交\nSET AUTOCOMMIT = 0;\n\n-- 查询自动提交状态\nSELECT @@AUTOCOMMIT;\n+--------------+\n- @@AUTOCOMMIT\n+--------------+\n- 0\n+--------------+\n")])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br"),n("span",{staticClass:"line-number"},[s._v("8")]),n("br"),n("span",{staticClass:"line-number"},[s._v("9")]),n("br"),n("span",{staticClass:"line-number"},[s._v("10")]),n("br")])]),n("p",[s._v("将自动提交关闭后,测试数据回滚:")]),s._v(" "),n("div",{staticClass:"language-mysql line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v("INSERT INTO user VALUES (2, 'b', 1000);\n\n-- 关闭 AUTOCOMMIT 后,数据的变化是在一张虚拟的临时数据表中展示,\n-- 发生变化的数据并没有真正插入到数据表中。\nSELECT * FROM user;\n+----+------+-------+\n- id: name: money\n+----+------+-------+\n- 1: a : 1000\n- 2: b : 1000\n+----+------+-------+\n\n-- 数据表中的真实数据其实还是:\n+----+------+-------+\n- id: name: money\n+----+------+-------+\n- 1: a : 1000\n+----+------+-------+\n\n-- 由于数据还没有真正提交,可以使用回滚\nROLLBACK;\n\n-- 再次查询\nSELECT * FROM user;\n+----+------+-------+\n- id: name: money\n+----+------+-------+\n- 1: a : 1000\n+----+------+-------+\n")])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br"),n("span",{staticClass:"line-number"},[s._v("8")]),n("br"),n("span",{staticClass:"line-number"},[s._v("9")]),n("br"),n("span",{staticClass:"line-number"},[s._v("10")]),n("br"),n("span",{staticClass:"line-number"},[s._v("11")]),n("br"),n("span",{staticClass:"line-number"},[s._v("12")]),n("br"),n("span",{staticClass:"line-number"},[s._v("13")]),n("br"),n("span",{staticClass:"line-number"},[s._v("14")]),n("br"),n("span",{staticClass:"line-number"},[s._v("15")]),n("br"),n("span",{staticClass:"line-number"},[s._v("16")]),n("br"),n("span",{staticClass:"line-number"},[s._v("17")]),n("br"),n("span",{staticClass:"line-number"},[s._v("18")]),n("br"),n("span",{staticClass:"line-number"},[s._v("19")]),n("br"),n("span",{staticClass:"line-number"},[s._v("20")]),n("br"),n("span",{staticClass:"line-number"},[s._v("21")]),n("br"),n("span",{staticClass:"line-number"},[s._v("22")]),n("br"),n("span",{staticClass:"line-number"},[s._v("23")]),n("br"),n("span",{staticClass:"line-number"},[s._v("24")]),n("br"),n("span",{staticClass:"line-number"},[s._v("25")]),n("br"),n("span",{staticClass:"line-number"},[s._v("26")]),n("br"),n("span",{staticClass:"line-number"},[s._v("27")]),n("br"),n("span",{staticClass:"line-number"},[s._v("28")]),n("br"),n("span",{staticClass:"line-number"},[s._v("29")]),n("br")])]),n("p",[s._v("那如何将虚拟的数据真正提交到数据库中?使用 "),n("code",[s._v("COMMIT")]),s._v(" :")]),s._v(" "),n("div",{staticClass:"language-mysql line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v("INSERT INTO user VALUES (2, 'b', 1000);\n-- 手动提交数据(持久性),\n-- 将数据真正提交到数据库中,执行后不能再回滚提交过的数据。\nCOMMIT;\n\n-- 提交后测试回滚\nROLLBACK;\n\n-- 再次查询(回滚无效了)\nSELECT * FROM user;\n+----+------+-------+\n- id: name: money\n+----+------+-------+\n- 1: a : 1000\n- 2: b : 1000\n+----+------+-------+\n")])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br"),n("span",{staticClass:"line-number"},[s._v("8")]),n("br"),n("span",{staticClass:"line-number"},[s._v("9")]),n("br"),n("span",{staticClass:"line-number"},[s._v("10")]),n("br"),n("span",{staticClass:"line-number"},[s._v("11")]),n("br"),n("span",{staticClass:"line-number"},[s._v("12")]),n("br"),n("span",{staticClass:"line-number"},[s._v("13")]),n("br"),n("span",{staticClass:"line-number"},[s._v("14")]),n("br"),n("span",{staticClass:"line-number"},[s._v("15")]),n("br"),n("span",{staticClass:"line-number"},[s._v("16")]),n("br")])]),n("blockquote",[n("p",[n("strong",[s._v("总结")])]),s._v(" "),n("ol",[n("li",[n("p",[n("strong",[s._v("自动提交")])]),s._v(" "),n("ul",[n("li",[n("p",[s._v("查看自动提交状态:"),n("code",[s._v("SELECT @@AUTOCOMMIT")]),s._v(" ;")])]),s._v(" "),n("li",[n("p",[s._v("设置自动提交状态:"),n("code",[s._v("SET AUTOCOMMIT = 0")]),s._v(" 。")])])])]),s._v(" "),n("li",[n("p",[n("strong",[s._v("手动提交")])]),s._v(" "),n("p",[n("code",[s._v("@@AUTOCOMMIT = 0")]),s._v(" 时,使用 "),n("code",[s._v("COMMIT")]),s._v(" 命令提交事务。")])]),s._v(" "),n("li",[n("p",[n("strong",[s._v("事务回滚")])]),s._v(" "),n("p",[n("code",[s._v("@@AUTOCOMMIT = 0")]),s._v(" 时,使用 "),n("code",[s._v("ROLLBACK")]),s._v(" 命令回滚事务。")])])])]),s._v(" "),n("p",[n("strong",[s._v("事务的实际应用")]),s._v(",让我们再回到银行转账项目:")]),s._v(" "),n("div",{staticClass:"language-mysql line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v("-- 转账\nUPDATE user set money = money - 100 WHERE name = 'a';\n\n-- 到账\nUPDATE user set money = money + 100 WHERE name = 'b';\n\nSELECT * FROM user;\n+----+------+-------+\n- id: name: money\n+----+------+-------+\n- 1: a : 900\n- 2: b : 1100\n+----+------+-------+\n")])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br"),n("span",{staticClass:"line-number"},[s._v("8")]),n("br"),n("span",{staticClass:"line-number"},[s._v("9")]),n("br"),n("span",{staticClass:"line-number"},[s._v("10")]),n("br"),n("span",{staticClass:"line-number"},[s._v("11")]),n("br"),n("span",{staticClass:"line-number"},[s._v("12")]),n("br"),n("span",{staticClass:"line-number"},[s._v("13")]),n("br")])]),n("p",[s._v("这时假设在转账时发生了意外,就可以使用 "),n("code",[s._v("ROLLBACK")]),s._v(" 回滚到最后一次提交的状态:")]),s._v(" "),n("div",{staticClass:"language-mysql line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v("-- 假设转账发生了意外,需要回滚。\nROLLBACK;\n\nSELECT * FROM user;\n+----+------+-------+\n- id: name: money\n+----+------+-------+\n- 1: a : 1000\n- 2: b : 1000\n+----+------+-------+\n")])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br"),n("span",{staticClass:"line-number"},[s._v("8")]),n("br"),n("span",{staticClass:"line-number"},[s._v("9")]),n("br"),n("span",{staticClass:"line-number"},[s._v("10")]),n("br")])]),n("p",[s._v("这时我们又回到了发生意外之前的状态,也就是说,事务给我们提供了一个可以反悔的机会。假设数据没有发生意外,这时可以手动将数据真正提交到数据表中:"),n("code",[s._v("COMMIT")]),s._v(" 。")]),s._v(" "),n("h3",{attrs:{id:"手动开启事务-begin-start-transaction"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#手动开启事务-begin-start-transaction"}},[s._v("#")]),s._v(" 手动开启事务 - BEGIN / START TRANSACTION")]),s._v(" "),n("p",[s._v("事务的默认提交被开启 ( "),n("code",[s._v("@@AUTOCOMMIT = 1")]),s._v(" ) 后,此时就不能使用事务回滚了。但是我们还可以手动开启一个事务处理事件,使其可以发生回滚:")]),s._v(" "),n("div",{staticClass:"language-mysql line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v("-- 使用 BEGIN 或者 START TRANSACTION 手动开启一个事务\n-- START TRANSACTION;\nBEGIN;\nUPDATE user set money = money - 100 WHERE name = 'a';\nUPDATE user set money = money + 100 WHERE name = 'b';\n\n-- 由于手动开启的事务没有开启自动提交,\n-- 此时发生变化的数据仍然是被保存在一张临时表中。\nSELECT * FROM user;\n+----+------+-------+\n- id: name: money\n+----+------+-------+\n- 1: a : 900\n- 2: b : 1100\n+----+------+-------+\n\n-- 测试回滚\nROLLBACK;\n\nSELECT * FROM user;\n+----+------+-------+\n- id: name: money\n+----+------+-------+\n- 1: a : 1000\n- 2: b : 1000\n+----+------+-------+\n")])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br"),n("span",{staticClass:"line-number"},[s._v("8")]),n("br"),n("span",{staticClass:"line-number"},[s._v("9")]),n("br"),n("span",{staticClass:"line-number"},[s._v("10")]),n("br"),n("span",{staticClass:"line-number"},[s._v("11")]),n("br"),n("span",{staticClass:"line-number"},[s._v("12")]),n("br"),n("span",{staticClass:"line-number"},[s._v("13")]),n("br"),n("span",{staticClass:"line-number"},[s._v("14")]),n("br"),n("span",{staticClass:"line-number"},[s._v("15")]),n("br"),n("span",{staticClass:"line-number"},[s._v("16")]),n("br"),n("span",{staticClass:"line-number"},[s._v("17")]),n("br"),n("span",{staticClass:"line-number"},[s._v("18")]),n("br"),n("span",{staticClass:"line-number"},[s._v("19")]),n("br"),n("span",{staticClass:"line-number"},[s._v("20")]),n("br"),n("span",{staticClass:"line-number"},[s._v("21")]),n("br"),n("span",{staticClass:"line-number"},[s._v("22")]),n("br"),n("span",{staticClass:"line-number"},[s._v("23")]),n("br"),n("span",{staticClass:"line-number"},[s._v("24")]),n("br"),n("span",{staticClass:"line-number"},[s._v("25")]),n("br"),n("span",{staticClass:"line-number"},[s._v("26")]),n("br")])]),n("p",[s._v("仍然使用 "),n("code",[s._v("COMMIT")]),s._v(" 提交数据,提交后无法再发生本次事务的回滚。")]),s._v(" "),n("div",{staticClass:"language-mysql line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v("BEGIN;\nUPDATE user set money = money - 100 WHERE name = 'a';\nUPDATE user set money = money + 100 WHERE name = 'b';\n\nSELECT * FROM user;\n+----+------+-------+\n- id: name: money\n+----+------+-------+\n- 1: a : 900\n- 2: b : 1100\n+----+------+-------+\n\n-- 提交数据\nCOMMIT;\n\n-- 测试回滚(无效,因为表的数据已经被提交)\nROLLBACK;\n")])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br"),n("span",{staticClass:"line-number"},[s._v("8")]),n("br"),n("span",{staticClass:"line-number"},[s._v("9")]),n("br"),n("span",{staticClass:"line-number"},[s._v("10")]),n("br"),n("span",{staticClass:"line-number"},[s._v("11")]),n("br"),n("span",{staticClass:"line-number"},[s._v("12")]),n("br"),n("span",{staticClass:"line-number"},[s._v("13")]),n("br"),n("span",{staticClass:"line-number"},[s._v("14")]),n("br"),n("span",{staticClass:"line-number"},[s._v("15")]),n("br"),n("span",{staticClass:"line-number"},[s._v("16")]),n("br"),n("span",{staticClass:"line-number"},[s._v("17")]),n("br")])]),n("h3",{attrs:{id:"事务的-acid-特征与使用"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#事务的-acid-特征与使用"}},[s._v("#")]),s._v(" 事务的 ACID 特征与使用")]),s._v(" "),n("p",[n("strong",[s._v("事务的四大特征:")])]),s._v(" "),n("ul",[n("li",[n("strong",[s._v("A 原子性")]),s._v(":事务是最小的单位,不可以再分割;")]),s._v(" "),n("li",[n("strong",[s._v("C 一致性")]),s._v(":要求同一事务中的 SQL 语句,必须保证同时成功或者失败;")]),s._v(" "),n("li",[n("strong",[s._v("I 隔离性")]),s._v(":事务 1 和 事务 2 之间是具有隔离性的;")]),s._v(" "),n("li",[n("strong",[s._v("D 持久性")]),s._v(":事务一旦结束 ( "),n("code",[s._v("COMMIT")]),s._v(" ) ,就不可以再返回了 ( "),n("code",[s._v("ROLLBACK")]),s._v(" ) 。")])]),s._v(" "),n("h3",{attrs:{id:"事务的隔离性"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#事务的隔离性"}},[s._v("#")]),s._v(" 事务的隔离性")]),s._v(" "),n("p",[n("strong",[s._v("事务的隔离性可分为四种 ( 性能从低到高 )")]),s._v(" :")]),s._v(" "),n("ol",[n("li",[n("p",[n("strong",[s._v("READ UNCOMMITTED ( 读取未提交 )")])]),s._v(" "),n("p",[s._v("如果有多个事务,那么任意事务都可以看见其他事务的"),n("strong",[s._v("未提交数据")]),s._v("。")])]),s._v(" "),n("li",[n("p",[n("strong",[s._v("READ COMMITTED ( 读取已提交 )")])]),s._v(" "),n("p",[s._v("只能读取到其他事务"),n("strong",[s._v("已经提交的数据")]),s._v("。")])]),s._v(" "),n("li",[n("p",[n("strong",[s._v("REPEATABLE READ ( 可被重复读 )")])]),s._v(" "),n("p",[s._v("如果有多个连接都开启了事务,那么事务之间不能共享数据记录,否则只能共享已提交的记录。")])]),s._v(" "),n("li",[n("p",[n("strong",[s._v("SERIALIZABLE ( 串行化 )")])]),s._v(" "),n("p",[s._v("所有的事务都会按照"),n("strong",[s._v("固定顺序执行")]),s._v(",执行完一个事务后再继续执行下一个事务的"),n("strong",[s._v("写入操作")]),s._v("。")])])]),s._v(" "),n("p",[s._v("查看当前数据库的默认隔离级别:")]),s._v(" "),n("div",{staticClass:"language-mysql line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v("-- MySQL 8.x, GLOBAL 表示系统级别,不加表示会话级别。\nSELECT @@GLOBAL.TRANSACTION_ISOLATION;\nSELECT @@TRANSACTION_ISOLATION;\n+--------------------------------+\n- @@GLOBAL.TRANSACTION_ISOLATION\n+--------------------------------+\n- REPEATABLE-READ : -- MySQL的默认隔离级别,可以重复读。\n+--------------------------------+\n\n-- MySQL 5.x\nSELECT @@GLOBAL.TX_ISOLATION;\nSELECT @@TX_ISOLATION;\n")])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br"),n("span",{staticClass:"line-number"},[s._v("8")]),n("br"),n("span",{staticClass:"line-number"},[s._v("9")]),n("br"),n("span",{staticClass:"line-number"},[s._v("10")]),n("br"),n("span",{staticClass:"line-number"},[s._v("11")]),n("br"),n("span",{staticClass:"line-number"},[s._v("12")]),n("br")])]),n("p",[s._v("修改隔离级别:")]),s._v(" "),n("div",{staticClass:"language-mysql line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v("-- 设置系统隔离级别,LEVEL 后面表示要设置的隔离级别 (READ UNCOMMITTED)。\nSET GLOBAL TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;\n\n-- 查询系统隔离级别,发现已经被修改。\nSELECT @@GLOBAL.TRANSACTION_ISOLATION;\n+--------------------------------+\n- @@GLOBAL.TRANSACTION_ISOLATION\n+--------------------------------+\n- READ-UNCOMMITTED\n+--------------------------------+\n")])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br"),n("span",{staticClass:"line-number"},[s._v("8")]),n("br"),n("span",{staticClass:"line-number"},[s._v("9")]),n("br"),n("span",{staticClass:"line-number"},[s._v("10")]),n("br")])]),n("h4",{attrs:{id:"脏读"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#脏读"}},[s._v("#")]),s._v(" 脏读")]),s._v(" "),n("p",[s._v("测试 "),n("strong",[s._v("READ UNCOMMITTED ( 读取未提交 )")]),s._v(" 的隔离性:")]),s._v(" "),n("div",{staticClass:"language-mysql line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v("INSERT INTO user VALUES (3, '小明', 1000);\nINSERT INTO user VALUES (4, '淘宝店', 1000);\n\nSELECT * FROM user;\n+----+-----------+-------+\n- id: name : money\n+----+-----------+-------+\n- 1: a : 900\n- 2: b : 1100\n- 3: 小明 : 1000\n- 4: 淘宝店 : 1000\n+----+-----------+-------+\n\n-- 开启一个事务操作数据\n-- 假设小明在淘宝店买了一双800块钱的鞋子:\nSTART TRANSACTION;\nUPDATE user SET money = money - 800 WHERE name = '小明';\nUPDATE user SET money = money + 800 WHERE name = '淘宝店';\n\n-- 然后淘宝店在另一方查询结果,发现钱已到账。\nSELECT * FROM user;\n+----+-----------+-------+\n- id: name : money\n+----+-----------+-------+\n- 1: a : 900\n- 2: b : 1100\n- 3: 小明 : 200\n- 4: 淘宝店 : 1800\n+----+-----------+-------+\n")])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br"),n("span",{staticClass:"line-number"},[s._v("8")]),n("br"),n("span",{staticClass:"line-number"},[s._v("9")]),n("br"),n("span",{staticClass:"line-number"},[s._v("10")]),n("br"),n("span",{staticClass:"line-number"},[s._v("11")]),n("br"),n("span",{staticClass:"line-number"},[s._v("12")]),n("br"),n("span",{staticClass:"line-number"},[s._v("13")]),n("br"),n("span",{staticClass:"line-number"},[s._v("14")]),n("br"),n("span",{staticClass:"line-number"},[s._v("15")]),n("br"),n("span",{staticClass:"line-number"},[s._v("16")]),n("br"),n("span",{staticClass:"line-number"},[s._v("17")]),n("br"),n("span",{staticClass:"line-number"},[s._v("18")]),n("br"),n("span",{staticClass:"line-number"},[s._v("19")]),n("br"),n("span",{staticClass:"line-number"},[s._v("20")]),n("br"),n("span",{staticClass:"line-number"},[s._v("21")]),n("br"),n("span",{staticClass:"line-number"},[s._v("22")]),n("br"),n("span",{staticClass:"line-number"},[s._v("23")]),n("br"),n("span",{staticClass:"line-number"},[s._v("24")]),n("br"),n("span",{staticClass:"line-number"},[s._v("25")]),n("br"),n("span",{staticClass:"line-number"},[s._v("26")]),n("br"),n("span",{staticClass:"line-number"},[s._v("27")]),n("br"),n("span",{staticClass:"line-number"},[s._v("28")]),n("br"),n("span",{staticClass:"line-number"},[s._v("29")]),n("br")])]),n("p",[s._v("由于小明的转账是在新开启的事务上进行操作的,而该操作的结果是可以被其他事务(另一方的淘宝店)看见的,因此淘宝店的查询结果是正确的,淘宝店确认到账。但就在这时,如果小明在它所处的事务上又执行了 "),n("code",[s._v("ROLLBACK")]),s._v(" 命令,会发生什么?")]),s._v(" "),n("div",{staticClass:"language-mysql line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v("-- 小明所处的事务\nROLLBACK;\n\n-- 此时无论对方是谁,如果再去查询结果就会发现:\nSELECT * FROM user;\n+----+-----------+-------+\n- id: name : money\n+----+-----------+-------+\n- 1: a : 900\n- 2: b : 1100\n- 3: 小明 : 1000\n- 4: 淘宝店 : 1000\n+----+-----------+-------+\n")])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br"),n("span",{staticClass:"line-number"},[s._v("8")]),n("br"),n("span",{staticClass:"line-number"},[s._v("9")]),n("br"),n("span",{staticClass:"line-number"},[s._v("10")]),n("br"),n("span",{staticClass:"line-number"},[s._v("11")]),n("br"),n("span",{staticClass:"line-number"},[s._v("12")]),n("br"),n("span",{staticClass:"line-number"},[s._v("13")]),n("br")])]),n("p",[s._v("这就是所谓的"),n("strong",[s._v("脏读")]),s._v(",一个事务读取到另外一个事务还未提交的数据。这在实际开发中是不允许出现的。")]),s._v(" "),n("h4",{attrs:{id:"读取已提交"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#读取已提交"}},[s._v("#")]),s._v(" 读取已提交")]),s._v(" "),n("p",[s._v("把隔离级别设置为 "),n("strong",[s._v("READ COMMITTED")]),s._v(" :")]),s._v(" "),n("div",{staticClass:"language-mysql line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v("SET GLOBAL TRANSACTION ISOLATION LEVEL READ COMMITTED;\nSELECT @@GLOBAL.TRANSACTION_ISOLATION;\n+--------------------------------+\n- @@GLOBAL.TRANSACTION_ISOLATION\n+--------------------------------+\n- READ-COMMITTED\n+--------------------------------+\n")])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br")])]),n("p",[s._v("这样,再有新的事务连接进来时,它们就只能查询到已经提交过的事务数据了。但是对于当前事务来说,它们看到的还是未提交的数据,例如:")]),s._v(" "),n("div",{staticClass:"language-mysql line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v("-- 正在操作数据事务(当前事务)\nSTART TRANSACTION;\nUPDATE user SET money = money - 800 WHERE name = '小明';\nUPDATE user SET money = money + 800 WHERE name = '淘宝店';\n\n-- 虽然隔离级别被设置为了 READ COMMITTED,但在当前事务中,\n-- 它看到的仍然是数据表中临时改变数据,而不是真正提交过的数据。\nSELECT * FROM user;\n+----+-----------+-------+\n- id: name : money\n+----+-----------+-------+\n- 1: a : 900\n- 2: b : 1100\n- 3: 小明 : 200\n- 4: 淘宝店 : 1800\n+----+-----------+-------+\n\n\n-- 假设此时在远程开启了一个新事务,连接到数据库。\n$ mysql -u root -p12345612\n\n-- 此时远程连接查询到的数据只能是已经提交过的\nSELECT * FROM user;\n+----+-----------+-------+\n- id: name : money\n+----+-----------+-------+\n- 1: a : 900\n- 2: b : 1100\n- 3: 小明 : 1000\n- 4: 淘宝店 : 1000\n+----+-----------+-------+\n")])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br"),n("span",{staticClass:"line-number"},[s._v("8")]),n("br"),n("span",{staticClass:"line-number"},[s._v("9")]),n("br"),n("span",{staticClass:"line-number"},[s._v("10")]),n("br"),n("span",{staticClass:"line-number"},[s._v("11")]),n("br"),n("span",{staticClass:"line-number"},[s._v("12")]),n("br"),n("span",{staticClass:"line-number"},[s._v("13")]),n("br"),n("span",{staticClass:"line-number"},[s._v("14")]),n("br"),n("span",{staticClass:"line-number"},[s._v("15")]),n("br"),n("span",{staticClass:"line-number"},[s._v("16")]),n("br"),n("span",{staticClass:"line-number"},[s._v("17")]),n("br"),n("span",{staticClass:"line-number"},[s._v("18")]),n("br"),n("span",{staticClass:"line-number"},[s._v("19")]),n("br"),n("span",{staticClass:"line-number"},[s._v("20")]),n("br"),n("span",{staticClass:"line-number"},[s._v("21")]),n("br"),n("span",{staticClass:"line-number"},[s._v("22")]),n("br"),n("span",{staticClass:"line-number"},[s._v("23")]),n("br"),n("span",{staticClass:"line-number"},[s._v("24")]),n("br"),n("span",{staticClass:"line-number"},[s._v("25")]),n("br"),n("span",{staticClass:"line-number"},[s._v("26")]),n("br"),n("span",{staticClass:"line-number"},[s._v("27")]),n("br"),n("span",{staticClass:"line-number"},[s._v("28")]),n("br"),n("span",{staticClass:"line-number"},[s._v("29")]),n("br"),n("span",{staticClass:"line-number"},[s._v("30")]),n("br"),n("span",{staticClass:"line-number"},[s._v("31")]),n("br")])]),n("p",[s._v("但是这样还有问题,那就是假设一个事务在操作数据时,其他事务干扰了这个事务的数据。例如:")]),s._v(" "),n("div",{staticClass:"language-mysql line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v("-- 小张在查询数据的时候发现:\nSELECT * FROM user;\n+----+-----------+-------+\n- id: name : money\n+----+-----------+-------+\n- 1: a : 900\n- 2: b : 1100\n- 3: 小明 : 200\n- 4: 淘宝店 : 1800\n+----+-----------+-------+\n\n-- 在小张求表的 money 平均值之前,小王做了一个操作:\nSTART TRANSACTION;\nINSERT INTO user VALUES (5, 'c', 100);\nCOMMIT;\n\n-- 此时表的真实数据是:\nSELECT * FROM user;\n+----+-----------+-------+\n- id: name : money\n+----+-----------+-------+\n- 1: a : 900\n- 2: b : 1100\n- 3: 小明 : 1000\n- 4: 淘宝店 : 1000\n- 5: c : 100\n+----+-----------+-------+\n\n-- 这时小张再求平均值的时候,就会出现计算不相符合的情况:\nSELECT AVG(money) FROM user;\n+------------+\n- AVG(money)\n+------------+\n- 820.0000\n+------------+\n")])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br"),n("span",{staticClass:"line-number"},[s._v("8")]),n("br"),n("span",{staticClass:"line-number"},[s._v("9")]),n("br"),n("span",{staticClass:"line-number"},[s._v("10")]),n("br"),n("span",{staticClass:"line-number"},[s._v("11")]),n("br"),n("span",{staticClass:"line-number"},[s._v("12")]),n("br"),n("span",{staticClass:"line-number"},[s._v("13")]),n("br"),n("span",{staticClass:"line-number"},[s._v("14")]),n("br"),n("span",{staticClass:"line-number"},[s._v("15")]),n("br"),n("span",{staticClass:"line-number"},[s._v("16")]),n("br"),n("span",{staticClass:"line-number"},[s._v("17")]),n("br"),n("span",{staticClass:"line-number"},[s._v("18")]),n("br"),n("span",{staticClass:"line-number"},[s._v("19")]),n("br"),n("span",{staticClass:"line-number"},[s._v("20")]),n("br"),n("span",{staticClass:"line-number"},[s._v("21")]),n("br"),n("span",{staticClass:"line-number"},[s._v("22")]),n("br"),n("span",{staticClass:"line-number"},[s._v("23")]),n("br"),n("span",{staticClass:"line-number"},[s._v("24")]),n("br"),n("span",{staticClass:"line-number"},[s._v("25")]),n("br"),n("span",{staticClass:"line-number"},[s._v("26")]),n("br"),n("span",{staticClass:"line-number"},[s._v("27")]),n("br"),n("span",{staticClass:"line-number"},[s._v("28")]),n("br"),n("span",{staticClass:"line-number"},[s._v("29")]),n("br"),n("span",{staticClass:"line-number"},[s._v("30")]),n("br"),n("span",{staticClass:"line-number"},[s._v("31")]),n("br"),n("span",{staticClass:"line-number"},[s._v("32")]),n("br"),n("span",{staticClass:"line-number"},[s._v("33")]),n("br"),n("span",{staticClass:"line-number"},[s._v("34")]),n("br"),n("span",{staticClass:"line-number"},[s._v("35")]),n("br")])]),n("p",[s._v("虽然 "),n("strong",[s._v("READ COMMITTED")]),s._v(" 让我们只能读取到其他事务已经提交的数据,但还是会出现问题,就是"),n("strong",[s._v("在读取同一个表的数据时,可能会发生前后不一致的情况。"),n("strong",[s._v("这被称为")]),s._v("不可重复读现象 ( READ COMMITTED )")]),s._v(" 。")]),s._v(" "),n("h4",{attrs:{id:"幻读"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#幻读"}},[s._v("#")]),s._v(" 幻读")]),s._v(" "),n("p",[s._v("将隔离级别设置为 "),n("strong",[s._v("REPEATABLE READ ( 可被重复读取 )")]),s._v(" :")]),s._v(" "),n("div",{staticClass:"language-mysql line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v("SET GLOBAL TRANSACTION ISOLATION LEVEL REPEATABLE READ;\nSELECT @@GLOBAL.TRANSACTION_ISOLATION;\n+--------------------------------+\n- @@GLOBAL.TRANSACTION_ISOLATION\n+--------------------------------+\n- REPEATABLE-READ\n+--------------------------------+\n")])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br")])]),n("p",[s._v("测试 "),n("strong",[s._v("REPEATABLE READ")]),s._v(" ,假设在两个不同的连接上分别执行 "),n("code",[s._v("START TRANSACTION")]),s._v(" :")]),s._v(" "),n("div",{staticClass:"language-sql line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-sql"}},[n("code",[n("span",{pre:!0,attrs:{class:"token comment"}},[s._v("-- 小张 - 成都")]),s._v("\n"),n("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("START")]),s._v(" "),n("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("TRANSACTION")]),n("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n"),n("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("INSERT")]),s._v(" "),n("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("INTO")]),s._v(" "),n("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("user")]),s._v(" "),n("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("VALUES")]),s._v(" "),n("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),n("span",{pre:!0,attrs:{class:"token number"}},[s._v("6")]),n("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" "),n("span",{pre:!0,attrs:{class:"token string"}},[s._v("'d'")]),n("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" "),n("span",{pre:!0,attrs:{class:"token number"}},[s._v("1000")]),n("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),n("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n\n"),n("span",{pre:!0,attrs:{class:"token comment"}},[s._v("-- 小王 - 北京")]),s._v("\n"),n("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("START")]),s._v(" "),n("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("TRANSACTION")]),n("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n\n"),n("span",{pre:!0,attrs:{class:"token comment"}},[s._v("-- 小张 - 成都")]),s._v("\n"),n("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("COMMIT")]),n("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n")])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br"),n("span",{staticClass:"line-number"},[s._v("8")]),n("br"),n("span",{staticClass:"line-number"},[s._v("9")]),n("br")])]),n("p",[s._v("当前事务开启后,没提交之前,查询不到,提交后可以被查询到。但是,在提交之前其他事务被开启了,那么在这条事务线上,就不会查询到当前有操作事务的连接。相当于开辟出一条单独的线程。")]),s._v(" "),n("p",[s._v("无论小张是否执行过 "),n("code",[s._v("COMMIT")]),s._v(" ,在小王这边,都不会查询到小张的事务记录,而是只会查询到自己所处事务的记录:")]),s._v(" "),n("div",{staticClass:"language-sql line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-sql"}},[n("code",[n("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("SELECT")]),s._v(" "),n("span",{pre:!0,attrs:{class:"token operator"}},[s._v("*")]),s._v(" "),n("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("FROM")]),s._v(" "),n("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("user")]),n("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n"),n("span",{pre:!0,attrs:{class:"token operator"}},[s._v("+")]),n("span",{pre:!0,attrs:{class:"token comment"}},[s._v("----+-----------+-------+")]),s._v("\n"),n("span",{pre:!0,attrs:{class:"token operator"}},[s._v("-")]),s._v(" id: name : money\n"),n("span",{pre:!0,attrs:{class:"token operator"}},[s._v("+")]),n("span",{pre:!0,attrs:{class:"token comment"}},[s._v("----+-----------+-------+")]),s._v("\n"),n("span",{pre:!0,attrs:{class:"token operator"}},[s._v("-")]),s._v(" "),n("span",{pre:!0,attrs:{class:"token number"}},[s._v("1")]),s._v(": a : "),n("span",{pre:!0,attrs:{class:"token number"}},[s._v("900")]),s._v("\n"),n("span",{pre:!0,attrs:{class:"token operator"}},[s._v("-")]),s._v(" "),n("span",{pre:!0,attrs:{class:"token number"}},[s._v("2")]),s._v(": b : "),n("span",{pre:!0,attrs:{class:"token number"}},[s._v("1100")]),s._v("\n"),n("span",{pre:!0,attrs:{class:"token operator"}},[s._v("-")]),s._v(" "),n("span",{pre:!0,attrs:{class:"token number"}},[s._v("3")]),s._v(": 小明 : "),n("span",{pre:!0,attrs:{class:"token number"}},[s._v("1000")]),s._v("\n"),n("span",{pre:!0,attrs:{class:"token operator"}},[s._v("-")]),s._v(" "),n("span",{pre:!0,attrs:{class:"token number"}},[s._v("4")]),s._v(": 淘宝店 : "),n("span",{pre:!0,attrs:{class:"token number"}},[s._v("1000")]),s._v("\n"),n("span",{pre:!0,attrs:{class:"token operator"}},[s._v("-")]),s._v(" "),n("span",{pre:!0,attrs:{class:"token number"}},[s._v("5")]),s._v(": c : "),n("span",{pre:!0,attrs:{class:"token number"}},[s._v("100")]),s._v("\n"),n("span",{pre:!0,attrs:{class:"token operator"}},[s._v("+")]),n("span",{pre:!0,attrs:{class:"token comment"}},[s._v("----+-----------+-------+")]),s._v("\n")])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br"),n("span",{staticClass:"line-number"},[s._v("8")]),n("br"),n("span",{staticClass:"line-number"},[s._v("9")]),n("br"),n("span",{staticClass:"line-number"},[s._v("10")]),n("br")])]),n("p",[s._v("这是"),n("strong",[s._v("因为小王在此之前开启了一个新的事务 ( "),n("code",[s._v("START TRANSACTION")]),s._v(" )")]),s._v(",那么"),n("strong",[s._v("在他的这条新事务的线上,跟其他事务是没有联系的")]),s._v(",也就是说,此时如果其他事务正在操作数据,它是不知道的。")]),s._v(" "),n("p",[s._v("然而事实是,在真实的数据表中,小张已经插入了一条数据。但是小王此时并不知道,也插入了同一条数据,会发生什么呢?")]),s._v(" "),n("div",{staticClass:"language-sql line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-sql"}},[n("code",[n("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("INSERT")]),s._v(" "),n("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("INTO")]),s._v(" "),n("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("user")]),s._v(" "),n("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("VALUES")]),s._v(" "),n("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),n("span",{pre:!0,attrs:{class:"token number"}},[s._v("6")]),n("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" "),n("span",{pre:!0,attrs:{class:"token string"}},[s._v("'d'")]),n("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" "),n("span",{pre:!0,attrs:{class:"token number"}},[s._v("1000")]),n("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),n("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n"),n("span",{pre:!0,attrs:{class:"token comment"}},[s._v("-- ERROR 1062 (23000): Duplicate entry '6' for key 'PRIMARY'")]),s._v("\n")])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br")])]),n("p",[s._v("报错了,操作被告知已存在主键为 "),n("code",[s._v("6")]),s._v(" 的字段。这种现象也被称为"),n("strong",[s._v("幻读,一个事务提交的数据,不能被其他事务读取到")]),s._v("。")]),s._v(" "),n("h4",{attrs:{id:"串行化"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#串行化"}},[s._v("#")]),s._v(" 串行化")]),s._v(" "),n("p",[s._v("顾名思义,就是所有事务的"),n("strong",[s._v("写入操作")]),s._v("全都是串行化的。什么意思?把隔离级别修改成 "),n("strong",[s._v("SERIALIZABLE")]),s._v(" :")]),s._v(" "),n("div",{staticClass:"language-mysql line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v("SET GLOBAL TRANSACTION ISOLATION LEVEL SERIALIZABLE;\nSELECT @@GLOBAL.TRANSACTION_ISOLATION;\n+--------------------------------+\n- @@GLOBAL.TRANSACTION_ISOLATION\n+--------------------------------+\n- SERIALIZABLE\n+--------------------------------+\n")])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br")])]),n("p",[s._v("还是拿小张和小王来举例:")]),s._v(" "),n("div",{staticClass:"language-mysql line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v("-- 小张 - 成都\nSTART TRANSACTION;\n\n-- 小王 - 北京\nSTART TRANSACTION;\n\n-- 开启事务之前先查询表,准备操作数据。\nSELECT * FROM user;\n+----+-----------+-------+\n- id: name : money\n+----+-----------+-------+\n- 1: a : 900\n- 2: b : 1100\n- 3: 小明 : 1000\n- 4: 淘宝店 : 1000\n- 5: c : 100\n- 6: d : 1000\n+----+-----------+-------+\n\n-- 发现没有 7 号王小花,于是插入一条数据:\nINSERT INTO user VALUES (7, '王小花', 1000);\n")])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br"),n("span",{staticClass:"line-number"},[s._v("8")]),n("br"),n("span",{staticClass:"line-number"},[s._v("9")]),n("br"),n("span",{staticClass:"line-number"},[s._v("10")]),n("br"),n("span",{staticClass:"line-number"},[s._v("11")]),n("br"),n("span",{staticClass:"line-number"},[s._v("12")]),n("br"),n("span",{staticClass:"line-number"},[s._v("13")]),n("br"),n("span",{staticClass:"line-number"},[s._v("14")]),n("br"),n("span",{staticClass:"line-number"},[s._v("15")]),n("br"),n("span",{staticClass:"line-number"},[s._v("16")]),n("br"),n("span",{staticClass:"line-number"},[s._v("17")]),n("br"),n("span",{staticClass:"line-number"},[s._v("18")]),n("br"),n("span",{staticClass:"line-number"},[s._v("19")]),n("br"),n("span",{staticClass:"line-number"},[s._v("20")]),n("br"),n("span",{staticClass:"line-number"},[s._v("21")]),n("br")])]),n("p",[s._v("此时会发生什么呢?由于现在的隔离级别是 "),n("strong",[s._v("SERIALIZABLE ( 串行化 )")]),s._v(" ,串行化的意思就是:假设把所有的事务都放在一个串行的队列中,那么所有的事务都会按照"),n("strong",[s._v("固定顺序执行")]),s._v(",执行完一个事务后再继续执行下一个事务的"),n("strong",[s._v("写入操作")]),s._v(" ( "),n("strong",[s._v("这意味着队列中同时只能执行一个事务的写入操作")]),s._v(" ) 。")]),s._v(" "),n("p",[s._v("根据这个解释,小王在插入数据时,会出现等待状态,直到小张执行 "),n("code",[s._v("COMMIT")]),s._v(" 结束它所处的事务,或者出现等待超时。")]),s._v(" "),n("h2",{attrs:{id:"其他"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#其他"}},[s._v("#")]),s._v(" 其他")]),s._v(" "),n("h3",{attrs:{id:"导出-sql-数据"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#导出-sql-数据"}},[s._v("#")]),s._v(" 导出 sql 数据")]),s._v(" "),n("p",[s._v("SQL 数据导出到文件,可以使用 mysqldump 工具\n"),n("code",[s._v("mysqldump -u test -p xxl_job > 12.sql")]),s._v("\n其中,test 是你的 MySQL 用户名,xxl_job 是要导出的数据库名称,12.sql 是要导出到的文件名称。注意,这个命令应该在操作系统的命令行中执行,而不是在 MySQL 命令行中执行。")]),s._v(" "),n("h3",{attrs:{id:"执行-sql-shell"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#执行-sql-shell"}},[s._v("#")]),s._v(" 执行 sql shell")]),s._v(" "),n("div",{staticClass:"language-shell line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-shell"}},[n("code",[s._v("mysql"),n("span",{pre:!0,attrs:{class:"token operator"}},[s._v(">")]),s._v(" use xxl_job"),n("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v(" -- 选择要导入数据的数据库\nmysql"),n("span",{pre:!0,attrs:{class:"token operator"}},[s._v(">")]),s._v(" "),n("span",{pre:!0,attrs:{class:"token builtin class-name"}},[s._v("source")]),s._v(" ./doc/db/tables_xxl_job.sql"),n("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v(" -- 导入 SQL 文件\n")])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br")])]),n("h3",{attrs:{id:"用户及权限"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#用户及权限"}},[s._v("#")]),s._v(" 用户及权限")]),s._v(" "),n("blockquote",[n("p",[s._v("mysql 的账户系统,是在 mysql 数据库的 user 表进行管理的。 所以在操作前,我们先进入通过 "),n("code",[s._v("mysql -u root")]),s._v(" 进入 sql shell")])]),s._v(" "),n("p",[s._v("一、增加用户")]),s._v(" "),n("ul",[n("li",[n("code",[s._v("CREATE USER 'new_user'@'localhost' IDENTIFIED BY 'password';")])]),s._v(" "),n("li",[n("code",[s._v("GRANT SELECT, INSERT, UPDATE, DELETE ON TO ''@'localhost';")]),s._v(": 授权 CURD 指定的 database 的 test 表")]),s._v(" "),n("li",[n("code",[s._v("GRANT USAGE ON *.* TO 'test'@'localhost'")]),s._v(": 授权 CURD 指定的 database")]),s._v(" "),n("li",[n("code",[s._v("FLUSH PRIVILEGES;")]),s._v(": Flush the privileges to ensure that the changes take effect")])]),s._v(" "),n("p",[s._v("二、查询用户")]),s._v(" "),n("ul",[n("li",[n("p",[n("code",[s._v("SELECT user, host, Super_priv, Create_priv, Drop_priv, Grant_priv, Shutdown_priv FROM mysql.user;")])]),s._v(" "),n("p",[s._v("权限信息,包括 Super_priv(超级用户权限)、Create_priv(创建数据库权限)、Drop_priv(删除数据库权限)、Grant_priv(授权权限)和 Shutdown_priv(关闭 MySQL 服务器权限)")])])]),s._v(" "),n("p",[s._v("三、删除用户")]),s._v(" "),n("ul",[n("li",[n("code",[s._v("DELETE FROM mysql.user WHERE user = 'myuser';")])])]),s._v(" "),n("p",[s._v("四、查询用户权限")]),s._v(" "),n("p",[n("code",[s._v("SHOW GRANTS FOR ''@'localhost';")])]),s._v(" "),n("h3",{attrs:{id:"sql-shell"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#sql-shell"}},[s._v("#")]),s._v(" sql shell")]),s._v(" "),n("ul",[n("li",[n("code",[s._v("ctrl + u")]),s._v(": 删除已经输入的命令")]),s._v(" "),n("li",[n("code",[s._v("ctrl + a")]),s._v(": 光标跳转到行首")]),s._v(" "),n("li",[n("code",[s._v("ctrl + e")]),s._v(": 光标跳转到行尾")])]),s._v(" "),n("h2",{attrs:{id:"链接"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#链接"}},[s._v("#")]),s._v(" 链接")]),s._v(" "),n("ul",[n("li",[n("a",{attrs:{href:"http://www.mysqlab.net/docs/view/refman-5.1-zh/chapter/index.html",target:"_blank",rel:"noopener noreferrer"}},[s._v("mysql 实验室"),n("OutboundLink")],1)])])])}),[],!1,null,null,null);n.default=t.exports}}]); \ No newline at end of file diff --git a/assets/js/141.3ceb723f.js b/assets/js/141.3ceb723f.js new file mode 100644 index 0000000000..3bad452b8a --- /dev/null +++ b/assets/js/141.3ceb723f.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[141],{467:function(s,e,a){"use strict";a.r(e);var t=a(4),r=Object(t.a)({},(function(){var s=this,e=s._self._c;return e("ContentSlotsDistributor",{attrs:{"slot-key":s.$parent.slotKey}},[e("h2",{attrs:{id:"解释说明-sql-语句的作用"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#解释说明-sql-语句的作用"}},[s._v("#")]),s._v(" 解释说明 sql 语句的作用")]),s._v(" "),e("h3",{attrs:{id:"perfetto-查询"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#perfetto-查询"}},[s._v("#")]),s._v(" perfetto 查询")]),s._v(" "),e("div",{staticClass:"language-sql line-numbers-mode"},[e("pre",{pre:!0,attrs:{class:"language-sql"}},[e("code",[e("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("SELECT")]),s._v(" track"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),e("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("type")]),s._v("\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("FROM")]),s._v(" slice\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("JOIN")]),s._v(" track "),e("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("ON")]),s._v(" track"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),s._v("id "),e("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" slice"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),s._v("track_id\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("WHERE")]),s._v(" slice"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),s._v("name "),e("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[s._v("'measure'")]),s._v("\n")])]),s._v(" "),e("div",{staticClass:"line-numbers-wrapper"},[e("span",{staticClass:"line-number"},[s._v("1")]),e("br"),e("span",{staticClass:"line-number"},[s._v("2")]),e("br"),e("span",{staticClass:"line-number"},[s._v("3")]),e("br"),e("span",{staticClass:"line-number"},[s._v("4")]),e("br")])]),e("p",[s._v("这个 SQL 查询语句用于从 Perfetto 数据库中获取与名称为 'measure' 的切片(slice)关联的跟踪(track)的类型(type)。")]),s._v(" "),e("p",[s._v("解析查询语句:")]),s._v(" "),e("ul",[e("li",[e("code",[s._v("SELECT track.type")]),s._v(": 这是查询的目标,表示要从结果中选择跟踪的类型字段。")]),s._v(" "),e("li",[e("code",[s._v("FROM slice")]),s._v(': 这是查询的主要数据表,表示要从 "slice" 表中检索数据。')]),s._v(" "),e("li",[e("code",[s._v("JOIN track ON track.id = slice.track_id")]),s._v(': 这是一个 JOIN 操作,它将 "slice" 表与 "track" 表进行关联。它将使用 "track" 表中的 "id" 字段与 "slice" 表中的 "track_id" 字段进行匹配,从而获取与切片相关联的跟踪信息。')]),s._v(" "),e("li",[e("code",[s._v("WHERE slice.name = 'measure'")]),s._v(": 这是一个过滤条件,表示只选择 \"slice\" 表中 \"name\" 字段值为 'measure' 的记录。这将限制查询结果仅包含名称为 'measure' 的切片。")])]),s._v(" "),e("p",[s._v("因此,该 SQL 查询的结果将返回与名称为 'measure' 的切片关联的跟踪的类型(type)。你将获得与 'measure' 切片相关联的跟踪类型的信息,这对于了解跟踪数据中不同类型的跟踪信息非常有帮助。")]),s._v(" "),e("h4",{attrs:{id:"查询-slice-名字中包含固定字符串"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#查询-slice-名字中包含固定字符串"}},[s._v("#")]),s._v(" 查询 slice 名字中包含固定字符串")]),s._v(" "),e("div",{staticClass:"language- line-numbers-mode"},[e("pre",{pre:!0,attrs:{class:"language-text"}},[e("code",[s._v("SELECT * FROM slice JOIN thread_track ON thread_track.id = slice.track_id WHERE slice.name LIKE 'jack)%'\n")])]),s._v(" "),e("div",{staticClass:"line-numbers-wrapper"},[e("span",{staticClass:"line-number"},[s._v("1")]),e("br")])])])}),[],!1,null,null,null);e.default=r.exports}}]); \ No newline at end of file diff --git a/assets/js/142.f960d1ce.js b/assets/js/142.f960d1ce.js new file mode 100644 index 0000000000..e6153afca0 --- /dev/null +++ b/assets/js/142.f960d1ce.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[142],{468:function(e,s,t){"use strict";t.r(s);var a=t(4),c=Object(a.a)({},(function(){var e=this,s=e._self._c;return s("ContentSlotsDistributor",{attrs:{"slot-key":e.$parent.slotKey}},[s("h2",{attrs:{id:"介绍"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#介绍"}},[e._v("#")]),e._v(" 介绍")]),e._v(" "),s("div",{staticClass:"custom-block tip"},[s("p",{staticClass:"custom-block-title"},[e._v("提示")]),e._v(" "),s("p",[e._v("Elasticsearch is a distributed document store. Instead of storing information as rows of columnar data, Elasticsearch stores complex data structures that have been serialized as JSON documents. When you have multiple Elasticsearch nodes in a cluster, stored documents are distributed across the cluster and can be accessed immediately from any node.")]),e._v(" "),s("ul",[s("li",[e._v("Distributed Document Store(分布式文档存储)")]),e._v(" "),s("li",[e._v("Complex Data Structures(复杂数据结构)")]),e._v(" "),s("li",[e._v("Clustered Architecture(集群架构)")]),e._v(" "),s("li",[e._v("Immediate Access(即时访问)")])])]),e._v(" "),s("p",[e._v("以下是 Elasticsearch 的主要特点和功能:")]),e._v(" "),s("ul",[s("li",[s("p",[s("strong",[e._v("全文搜索")]),e._v(":Elasticsearch 是一个全文搜索引擎,可以对大量文本数据进行高效的全文搜索。它支持复杂的查询,包括模糊搜索、通配符搜索、短语匹配等。")])]),e._v(" "),s("li",[s("p",[s("strong",[e._v("实时数据")]),e._v(":Elasticsearch 具有实时性,能够在数据被索引后立即提供查询结果。这使得它非常适合用于监控、日志分析和应用程序性能分析等实时场景。")])]),e._v(" "),s("li",[s("p",[s("strong",[e._v("分布式架构")]),e._v(":Elasticsearch 是一个分布式系统,可以水平扩展以处理大规模的数据和高并发查询。它将数据分散存储在多个节点上,提供高可用性和容错性。")])]),e._v(" "),s("li",[s("p",[s("strong",[e._v("多种数据类型支持")]),e._v(":Elasticsearch 支持多种数据类型,包括文本、数字、日期、地理位置等,可以用于处理各种类型的数据。")])]),e._v(" "),s("li",[s("p",[s("strong",[e._v("复杂查询")]),e._v(":Elasticsearch 使用结构化的 JSON 查询语言(DSL),允许用户执行各种复杂的查询操作,包括过滤、聚合、排序、分组和分页等。")])]),e._v(" "),s("li",[s("p",[s("strong",[e._v("近似搜索")]),e._v(":Elasticsearch 支持近似搜索算法,如模糊搜索和近似字符串匹配,使用户能够在不完全匹配的情况下找到相关的结果。")])]),e._v(" "),s("li",[s("p",[s("strong",[e._v("地理空间搜索")]),e._v(":Elasticsearch 具有强大的地理信息系统(GIS)支持,可以用于地理空间数据的搜索和分析,包括地理坐标点、多边形和距离计算。")])]),e._v(" "),s("li",[s("p",[s("strong",[e._v("数据聚合")]),e._v(":Elasticsearch 具有数据聚合功能,允许用户执行汇总和统计操作,生成各种报告和图表,用于洞察数据趋势。")])]),e._v(" "),s("li",[s("p",[s("strong",[e._v("插件和扩展")]),e._v(":Elasticsearch 是可扩展的,可以通过插件来扩展其功能,满足不同的需求。Elastic 提供了大量的官方插件,同时社区也提供了许多第三方插件。")])]),e._v(" "),s("li",[s("p",[s("strong",[e._v("安全性和访问控制")]),e._v(":Elasticsearch 支持用户认证和授权,可以配置不同用户和角色的访问权限,以保护敏感数据。")])]),e._v(" "),s("li",[s("p",[s("strong",[e._v("弹性和可恢复性")]),e._v(":Elasticsearch 具有弹性和自动恢复功能,能够处理硬件故障、数据丢失和节点添加/删除等情况。")])]),e._v(" "),s("li",[s("p",[s("strong",[e._v("社区和生态系统")]),e._v(":Elasticsearch 拥有庞大的社区和生态系统,提供了大量的文档、教程和支持资源。")])])]),e._v(" "),s("h2",{attrs:{id:"安装及使用"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#安装及使用"}},[e._v("#")]),e._v(" 安装及使用")]),e._v(" "),s("blockquote",[s("p",[e._v("说明在 docker 下安装 elasticsearch, 版本以 8.8.2 为例子,的使用示例")])]),e._v(" "),s("ul",[s("li",[s("code",[e._v("docker pull 'elasticsearch:8.8.2'")]),e._v(": 从 dockerHub,pull elasticsearch 镜像")]),e._v(" "),s("li",[s("code",[e._v("docker run -d -p 9200:9200 -p 9300:9300 --name elasticsearch-8.8.2 elasticsearch:8.8.2")]),e._v(" "),s("ul",[s("li",[s("code",[e._v("-d")]),e._v(":这是 docker run 命令的一个选项,表示以后台(守护进程)模式运行容器。容器将在后台运行,而不会占用你的终端。")]),e._v(" "),s("li",[s("code",[e._v("-p 9200:9200 -p 9300:9300")]),e._v(":这是端口映射的选项。它将容器内部的端口 9200 映射到主机上的端口 9200,以便你可以通过主机上的端口访问 Elasticsearch 的 HTTP API。同样,端口 9300 也进行了类似的映射,用于 Elasticsearch 集群内部节点之间的通信。")])])]),e._v(" "),s("li",[s("code",[e._v("docker exec -it /bin/bash")]),e._v(": 进入容器. (你可能需要以 root 身份进入 container shell)\n"),s("ul",[s("li",[s("code",[e._v("-u root")]),e._v(": 以root身份份运行")])])]),e._v(" "),s("li",[s("code",[e._v("./bin/elasticsearch-plugin install https://github.com/medcl/elasticsearch-analysis-ik/releases/download/v8.8.2/elasticsearch-analysis-ik-8.8.2.zip")]),e._v(": 使用 elasticsearch-plugin 安装 ik 分词器")]),e._v(" "),s("li",[s("code",[e._v("修改 es 配置文件:")]),e._v("vi ./config/elasticsearch.yml`.\ntodo")]),e._v(" "),s("li",[s("code",[e._v("exit")]),e._v(":")]),e._v(" "),s("li",[s("code",[e._v("docker stop elasticsearch-8.8.2")]),e._v(": 停止容器")]),e._v(" "),s("li",[s("code",[e._v("docker start elasticsearch-8.8.2")]),e._v(": 运行容器")])]),e._v(" "),s("h2",{attrs:{id:"链接"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#链接"}},[e._v("#")]),e._v(" 链接")]),e._v(" "),s("ul",[s("li",[s("a",{attrs:{href:"https://www.elastic.co/guide/en/elasticsearch/reference/index.html",target:"_blank",rel:"noopener noreferrer"}},[e._v("elasticsearch-guide"),s("OutboundLink")],1)])])])}),[],!1,null,null,null);s.default=c.exports}}]); \ No newline at end of file diff --git a/assets/js/143.6b32cab5.js b/assets/js/143.6b32cab5.js new file mode 100644 index 0000000000..000300017d --- /dev/null +++ b/assets/js/143.6b32cab5.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[143],{469:function(r,t,o){"use strict";o.r(t);var e=o(4),v=Object(e.a)({},(function(){var r=this,t=r._self._c;return t("ContentSlotsDistributor",{attrs:{"slot-key":r.$parent.slotKey}},[t("h2",{attrs:{id:"spring"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#spring"}},[r._v("#")]),r._v(" spring")]),r._v(" "),t("h3",{attrs:{id:"ioc-的实现机制"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#ioc-的实现机制"}},[r._v("#")]),r._v(" IOC 的实现机制")]),r._v(" "),t("blockquote",[t("p",[r._v("好的,这个问题我会从几个方面来回答。")])]),r._v(" "),t("ul",[t("li",[t("strong",[r._v("IOC 是什么")]),r._v("\nIOC 的全称是 Inversion Of Control, 也就是控制反转,它的核心思想是把对象的管理权限交给容器。")]),r._v(" "),t("li",[t("strong",[r._v("Bean 的声明方式")]),r._v("\n应用程序如果需要使用到某个对象实例,直接从 IOC 容器中去获取就行,这样设计的好处是降低了程序里面对象与对象之间的耦合性。")]),r._v(" "),t("li",[t("strong",[r._v("IOC 的工作流程")]),r._v(": Spring IOC 的工作流程大致可以分为三个阶段。\n"),t("ul",[t("li",[r._v("IOC 容器的初始化")]),r._v(" "),t("li",[r._v("完成 Bean 初始化及依赖注入")]),r._v(" "),t("li",[r._v("Bean 的使用")])])])]),r._v(" "),t("p",[t("strong",[r._v("链接")])]),r._v(" "),t("ul",[t("li",[t("a",{attrs:{href:"https://javadoop.com/post/spring-ioc",target:"_blank",rel:"noopener noreferrer"}},[r._v("spring-ioc"),t("OutboundLink")],1)]),r._v(" "),t("li",[t("a",{attrs:{href:"https://zhuanlan.zhihu.com/p/532742267",target:"_blank",rel:"noopener noreferrer"}},[r._v("面试官:介绍下 Spring IoC 的工作流程 你会怎么回答?"),t("OutboundLink")],1)])]),r._v(" "),t("h3",{attrs:{id:"spring-aop-与-aspectj-aop"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#spring-aop-与-aspectj-aop"}},[r._v("#")]),r._v(" Spring AOP 与 AspectJ AOP")]),r._v(" "),t("p",[r._v("Spring AOP 属于运行时增强,而 AspectJ 是编译时增强。 Spring AOP 基于代理(Proxying),而 AspectJ 基于字节码操作(Bytecode Manipulation)。")]),r._v(" "),t("h2",{attrs:{id:"其他"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#其他"}},[r._v("#")]),r._v(" 其他")]),r._v(" "),t("h3",{attrs:{id:"docker-与传统虚拟机的区别"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#docker-与传统虚拟机的区别"}},[r._v("#")]),r._v(" docker 与传统虚拟机的区别")]),r._v(" "),t("blockquote",[t("p",[r._v("docker 与不同虚拟机的区别,如何实现隔离?资源如何控制?")])]),r._v(" "),t("p",[r._v("Docker 与传统虚拟机(VM)之间有一些重要的区别,主要集中在隔离、资源控制和运行效率等方面。下面是它们之间的主要区别:")]),r._v(" "),t("ul",[t("li",[t("strong",[r._v("虚拟化层次不同")]),r._v(":\n"),t("ul",[t("li",[r._v("Docker:Docker 使用容器技术,它在操作系统层面实现隔离。容器共享宿主操作系统的内核,但在用户空间中提供隔离的文件系统、进程空间和网络等。这使得 Docker 容器更轻量级,启动更快。")]),r._v(" "),t("li",[r._v("传统虚拟机:传统虚拟机使用全虚拟化或半虚拟化技术,它们在物理硬件上运行一个完整的操作系统。这意味着每个虚拟机都有自己的内核,占用更多资源,并且启动较慢。")])])]),r._v(" "),t("li",[t("strong",[r._v("资源占用")]),r._v(":\n"),t("ul",[t("li",[r._v("Docker:Docker 容器通常比传统虚拟机更轻量级,因为它们共享宿主操作系统的内核和系统库。这使得 Docker 容器的资源占用更少,更适合在大规模部署中使用。")]),r._v(" "),t("li",[r._v("传统虚拟机:传统虚拟机需要较多的资源,包括内存和处理器,因为每个虚拟机都运行一个完整的操作系统。")])])]),r._v(" "),t("li",[t("strong",[r._v("隔离层次")]),r._v(":\n"),t("ul",[t("li",[r._v("Docker:Docker 提供了一定程度的隔离,如命名空间和控制组。容器之间隔离运行,但仍然共享操作系统内核。这使得容器之间的隔离较为薄弱,但通常足够满足大多数应用的需求。")]),r._v(" "),t("li",[r._v("传统虚拟机:传统虚拟机提供了更强的隔离,因为它们运行独立的操作系统实例。这使得虚拟机之间的隔离更强大,但也导致了更多的资源开销。")])])]),r._v(" "),t("li",[t("strong",[r._v("启动时间")]),r._v(":\n"),t("ul",[t("li",[r._v("Docker:Docker 容器启动速度非常快,通常在几秒钟内就可以启动一个新容器。")]),r._v(" "),t("li",[r._v("传统虚拟机:传统虚拟机启动速度相对较慢,通常需要几分钟来启动一个新虚拟机。")])])]),r._v(" "),t("li",[t("strong",[r._v("资源控制")]),r._v(":\n"),t("ul",[t("li",[r._v("Docker:Docker 提供了丰富的资源控制选项,如 CPU 限制、内存限制、网络控制等。这些控制可以通过 Docker Compose 文件或 Docker 命令行选项进行配置。")]),r._v(" "),t("li",[r._v("传统虚拟机:传统虚拟机也提供资源控制选项,但配置通常更复杂,需要在虚拟化平台中进行设置。")])])])]),r._v(" "),t("p",[r._v("总之,Docker 适合轻量级、快速部署和隔离要求不太严格的应用程序,而传统虚拟机适合需要更强隔离和独立操作系统实例的应用程序。资源控制可以在两种情况下进行配置,但 Docker 提供了更简单和灵活的方式来管理容器的资源")])])}),[],!1,null,null,null);t.default=v.exports}}]); \ No newline at end of file diff --git a/assets/js/144.0f0e34e1.js b/assets/js/144.0f0e34e1.js new file mode 100644 index 0000000000..c2fa985a79 --- /dev/null +++ b/assets/js/144.0f0e34e1.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[144],{470:function(e,t,o){"use strict";o.r(t);var _=o(4),v=Object(_.a)({},(function(){var e=this,t=e._self._c;return t("ContentSlotsDistributor",{attrs:{"slot-key":e.$parent.slotKey}},[t("p",[e._v("WebSocket 是一种协议,用于在 Web 应用程序中创建实时、双向的通信通道。")]),e._v(" "),t("p",[e._v("传统的 HTTP 请求通常是一次请求一次响应的,而 WebSocket 则可以建立一个持久连接,允许服务器即时向客户端推送数据,同时也可以接收客户端发送的数据。WebSocket 相比于传统的轮询或长轮询方式,能够显著减少网络流量和延迟,提高数据传输的效率和速度。")]),e._v(" "),t("h2",{attrs:{id:"websocket-原理"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#websocket-原理"}},[e._v("#")]),e._v(" websocket 原理")]),e._v(" "),t("p",[e._v("WebSocket 是 HTML5 开始推出的基于 TCP 协议的双向通信协议,其优势在于与 HTTP 协议兼容、开销小、通信高效。WebSocket 让客户端和服务器之间建立连接,并通过这个持久连接实时地进行双向数据传输。它的原理基于以下几个关键点")]),e._v(" "),t("ul",[t("li",[t("p",[t("strong",[e._v("握手阶段")]),e._v(": WebSocket 连接的建立是通过 HTTP 协议的握手来实现的。客户端发送一个 HTTP 请求,其中包含一些特殊的头部信息,告诉服务器它想要升级到 WebSocket 协议。服务器收到请求后,如果支持 WebSocket,就会发送 HTTP 101 状态码(Switching Protocols)作为响应,表示升级成功。")])]),e._v(" "),t("li",[t("p",[t("strong",[e._v("双向通信")]),e._v(": 一旦 WebSocket 连接建立成功,客户端和服务器之间就可以实现双向通信,不再受限于 HTTP 的请求-响应模式。WebSocket 连接保持持久性,双方可以随时发送消息给对方,而不需要重新建立连接。")])]),e._v(" "),t("li",[t("p",[t("strong",[e._v("帧(Frame)")]),e._v(": WebSocket 通信使用帧来传输数据。帧是 WebSocket 协议中的基本数据单元,可以包含文本数据、二进制数据等。WebSocket 帧可以被分成多个片段,每个片段都包含了数据的一部分,并可以有不同的类型和用途(例如,文本帧、二进制帧、Ping 帧、Pong 帧等)。")])]),e._v(" "),t("li",[t("p",[t("strong",[e._v("使用 TCP 协议")]),e._v(": WebSocket 建立在 TCP 协议之上,因此它是一种可靠的通信协议,适用于需要稳定连接和低延迟的应用场景。")])]),e._v(" "),t("li",[t("p",[t("strong",[e._v("数据格式")]),e._v(": WebSocket 协议的数据格式相对简单,通常是纯文本或二进制数据,没有 HTTP 协议中的请求头等复杂结构。这使得 WebSocket 在数据传输效率上相对较高。")])]),e._v(" "),t("li",[t("p",[t("strong",[e._v("状态管理")]),e._v(": WebSocket 协议定义了一些状态码,用于表示连接状态和错误情况。例如,状态码 1001 表示 WebSocket 连接关闭。")])])]),e._v(" "),t("p",[e._v("总结:WebSocket 是一种基于 HTTP 握手的通信协议,它允许客户端和服务器之间建立持久连接,实现双向通信。WebSocket 使用 TCP 协议传输数据,帧是其基本数据单元,数据格式相对简单。WebSocket 通常用于构建实时互动性应用,如在线游戏、在线聊天等。")]),e._v(" "),t("h3",{attrs:{id:"连接过程"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#连接过程"}},[e._v("#")]),e._v(" 连接过程")]),e._v(" "),t("p",[e._v("WebSocket 是基于 HTTP/1.1 实现的。WebSocket 连接建立时,客户端和服务器之间会首先使用 HTTP/1.1 进行握手,然后协议会升级到 WebSocket 协议。这个握手过程使得 WebSocket 能够通过现有的 HTTP 基础设施进行连接,然后转换到 WebSocket 协议,实现双向通信。")]),e._v(" "),t("p",[e._v("具体来说,WebSocket 连接建立的过程如下:")]),e._v(" "),t("ul",[t("li",[t("p",[e._v("客户端发送一个 HTTP 请求,其中包含特殊的 WebSocket 头部信息,如 Upgrade 和 Connection 字段。")])]),e._v(" "),t("li",[t("p",[e._v('服务器收到请求后,会检查这些特殊的头部信息,如果发现 Upgrade 字段的值为"websocket",并且 Connection 字段包含"Upgrade",则表示客户端希望升级到 WebSocket 协议。')])]),e._v(" "),t("li",[t("p",[e._v("服务器返回一个 HTTP 101 状态码(Switching Protocols)的响应,表示升级成功,并且通过 Connection 字段的值确认了协议的切换。")])]),e._v(" "),t("li",[t("p",[e._v("客户端和服务器之间的连接现在已经升级到 WebSocket 协议,双方可以通过 WebSocket 帧进行双向通信。")])])]),e._v(" "),t("p",[e._v("这种方式使得 WebSocket 能够与现有的 HTTP 基础设施兼容,同时允许建立持久连接,实现实时双向通信。这是 WebSocket 协议的一个重要特点。")]),e._v(" "),t("hr"),e._v(" "),t("p",[e._v("【"),t("strong",[e._v("掩码")]),e._v("】")]),e._v(" "),t("p",[e._v("在 WebSocket 中,客户端向服务器传输的数据帧在大多数情况下是需要进行掩码处理的。WebSocket 协议的设计考虑了安全性和隐私保护,因此规定了以下规则:")]),e._v(" "),t("ol",[t("li",[e._v("客户端向服务器发送的数据帧必须进行掩码处理。")]),e._v(" "),t("li",[e._v("服务器向客户端发送的数据帧不需要进行掩码处理。")])]),e._v(" "),t("p",[e._v("掩码处理是为了保护数据的完整性,防止数据在传输过程中被恶意篡改。当客户端发送数据给服务器时,客户端会生成一个随机的 32 位掩码密钥,然后将要发送的数据按字节与这个掩码密钥进行"),t("strong",[e._v("异或")]),e._v("操作,然后才将数据发送到服务器。服务器在接收到数据后,会根据掩码密钥对数据进行解码,还原出原始数据。")]),e._v(" "),t("p",[e._v("这个掩码处理过程确保了数据在传输过程中不容易被拦截和篡改。服务器不需要对发送给客户端的数据帧进行掩码处理,因为在 WebSocket 中,服务器生成的数据通常是受信任的,不需要额外的保护。")]),e._v(" "),t("p",[e._v("需要注意的是,WebSocket 客户端通常会自动处理掩码,不需要开发者手动操作。WebSocket 库和框架会自动处理数据帧的掩码处理,开发者只需关注数据的发送和接收即可。")]),e._v(" "),t("h2",{attrs:{id:"websocket-和-http-的关系"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#websocket-和-http-的关系"}},[e._v("#")]),e._v(" WebSocket 和 HTTP 的关系?")]),e._v(" "),t("p",[t("img",{attrs:{src:"https://apifox.com/apiskills/content/images/2023/07/image-2071.png",alt:""}})]),e._v(" "),t("p",[e._v("两种协议都是用于网络通信的。")]),e._v(" "),t("ol",[t("li",[e._v("HTTP (Hypertext Transfer Protocol) 是一个基于请求和响应模式的协议,最早用于 Web 应用。")]),e._v(" "),t("li",[e._v("WebSocket 是一种双向通信协议,可以在客户端和服务器之间建立持久的连接,以实现实时通信。")]),e._v(" "),t("li",[e._v("WebSocket 协议在建立连接时需要使用 HTTP 协议。 具体来说,当客户端想要建立 WebSocket 连接时,它们需要通过 HTTP 请求发送一个握手请求。如果服务器同意握手,它将发送一个握手响应,HTTP 协议随后会升级到 WebSocket 协议。")]),e._v(" "),t("li",[e._v("HTTP 和 WebSocket 协议在用途上也有所不同。HTTP 协议主要用于客户端和服务器之间的请求和响应通信,而 WebSocket 协议主要用于实现实时通信和服务器推送。通俗的说,HTTP 协议是“一问一答”,WebSocket 协议是“对话”。")])]),e._v(" "),t("p",[e._v("总之,WebSocket 和 HTTP 是两种不同的协议,它们在通信模式、用途和建立连接时都有所不同,但是它们之间也有联系。")]),e._v(" "),t("h2",{attrs:{id:"链接"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#链接"}},[e._v("#")]),e._v(" 链接")]),e._v(" "),t("ul",[t("li",[t("a",{attrs:{href:"https://jayqiu.github.io/blog/2017/05/blog_05_11_17.html",target:"_blank",rel:"noopener noreferrer"}},[e._v("WebSocket 原理及技术简介"),t("OutboundLink")],1)]),e._v(" "),t("li",[t("a",{attrs:{href:"https://apifox.com/apiskills/what-is-websocket/#websocket-%E6%98%AF%E4%BB%80%E4%B9%88",target:"_blank",rel:"noopener noreferrer"}},[e._v("WebSocket 是什么?你需要知道的一切"),t("OutboundLink")],1)]),e._v(" "),t("li",[t("a",{attrs:{href:"https://www.zhihu.com/question/20215561",target:"_blank",rel:"noopener noreferrer"}},[e._v("WebSocket 是什么原理?为什么可以实现持久连接?"),t("OutboundLink")],1)])])])}),[],!1,null,null,null);t.default=v.exports}}]); \ No newline at end of file diff --git a/assets/js/145.77ccd494.js b/assets/js/145.77ccd494.js new file mode 100644 index 0000000000..d953c07847 --- /dev/null +++ b/assets/js/145.77ccd494.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[145],{471:function(t,s,l){"use strict";l.r(s);var o=l(4),i=Object(o.a)({},(function(){var t=this._self._c;return t("ContentSlotsDistributor",{attrs:{"slot-key":this.$parent.slotKey}},[t("div",{staticClass:"custom-block tip"},[t("p",{staticClass:"custom-block-title"},[this._v("提示")])])])}),[],!1,null,null,null);s.default=i.exports}}]); \ No newline at end of file diff --git a/assets/js/146.44102b53.js b/assets/js/146.44102b53.js new file mode 100644 index 0000000000..c5ea9d961a --- /dev/null +++ b/assets/js/146.44102b53.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[146],{472:function(e,r,t){"use strict";t.r(r);var n=t(4),o=Object(n.a)({},(function(){var e=this,r=e._self._c;return r("ContentSlotsDistributor",{attrs:{"slot-key":e.$parent.slotKey}},[r("h2",{attrs:{id:"介绍"}},[r("a",{staticClass:"header-anchor",attrs:{href:"#介绍"}},[e._v("#")]),e._v(" 介绍")]),e._v(" "),r("h3",{attrs:{id:"element-ui"}},[r("a",{staticClass:"header-anchor",attrs:{href:"#element-ui"}},[e._v("#")]),e._v(" element-ui")]),e._v(" "),r("blockquote",[r("p",[r("a",{attrs:{href:"https://juejin.cn/post/7130967588657430541",target:"_blank",rel:"noopener noreferrer"}},[e._v("https://juejin.cn/post/7130967588657430541"),r("OutboundLink")],1)])]),e._v(" "),r("h2",{attrs:{id:"链接"}},[r("a",{staticClass:"header-anchor",attrs:{href:"#链接"}},[e._v("#")]),e._v(" 链接")]),e._v(" "),r("ul",[r("li",[r("a",{attrs:{href:"https://cli.vuejs.org/guide/",target:"_blank",rel:"noopener noreferrer"}},[e._v("guide"),r("OutboundLink")],1)]),e._v(" "),r("li",[r("a",{attrs:{href:"https://cli.vuejs.org/config/",target:"_blank",rel:"noopener noreferrer"}},[e._v("config"),r("OutboundLink")],1),e._v(" "),r("ul",[r("li",[r("a",{attrs:{href:"https://cli.vuejs.org/config/#vue-config-js",target:"_blank",rel:"noopener noreferrer"}},[e._v("vue-config-js"),r("OutboundLink")],1)]),e._v(" "),r("li",[e._v("babel")]),e._v(" "),r("li",[e._v("eslint")]),e._v(" "),r("li",[e._v("typescript")])])]),e._v(" "),r("li",[e._v("Ecosystem\n"),r("ul",[r("li",[r("a",{attrs:{href:"https://router.vuejs.org",target:"_blank",rel:"noopener noreferrer"}},[e._v("vue-router"),r("OutboundLink")],1)]),e._v(" "),r("li",[r("a",{attrs:{href:"https://vuex.vuejs.org",target:"_blank",rel:"noopener noreferrer"}},[e._v("vuex"),r("OutboundLink")],1)]),e._v(" "),r("li",[r("a",{attrs:{href:"https://github.com/vuejs/vue-devtools#vue-devtools",target:"_blank",rel:"noopener noreferrer"}},[e._v("vue-devtools"),r("OutboundLink")],1)]),e._v(" "),r("li",[r("a",{attrs:{href:"https://vue-loader.vuejs.org",target:"_blank",rel:"noopener noreferrer"}},[e._v("vue-loader"),r("OutboundLink")],1)]),e._v(" "),r("li",[r("a",{attrs:{href:"https://github.com/vuejs/awesome-vue",target:"_blank",rel:"noopener noreferrer"}},[e._v("awesome-vue"),r("OutboundLink")],1)])])])])])}),[],!1,null,null,null);r.default=o.exports}}]); \ No newline at end of file diff --git a/assets/js/147.4c7d9048.js b/assets/js/147.4c7d9048.js new file mode 100644 index 0000000000..f9e02d7bf4 --- /dev/null +++ b/assets/js/147.4c7d9048.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[147],{488:function(e,t,v){"use strict";v.r(t);var a=v(4),_=Object(a.a)({},(function(){var e=this,t=e._self._c;return t("ContentSlotsDistributor",{attrs:{"slot-key":e.$parent.slotKey}},[t("h2",{attrs:{id:"vue2"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#vue2"}},[e._v("#")]),e._v(" vue2")]),e._v(" "),t("h3",{attrs:{id:"概述"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#概述"}},[e._v("#")]),e._v(" 概述")]),e._v(" "),t("p",[e._v("Vue 2 的核心原理是数据驱动,也就是说视图(View)是根据数据(Data)自动渲染出来的,这样可以将业务逻辑和视图分离,提高开发效率。Vue 2 的数据驱动原理主要分为以下几个部分:")]),e._v(" "),t("ol",[t("li",[e._v("数据响应式:Vue 2 使用了 "),t("code",[e._v("Object.defineProperty()")]),e._v(" 方法来实现数据响应式,该方法可以监控对象属性的变化,并在属性发生变化时触发相关操作。当一个组件被创建时,Vue 2 会对其数据进行响应式处理,从而可以在数据变化时更新视图。")]),e._v(" "),t("li",[e._v("模板编译:Vue 2 使用了模板编译技术将模板转换成渲染函数,渲染函数可以直接操作数据,生成真实的 DOM 节点。模板编译分为以下几个步骤:解析模板,生成 AST(抽象语法树),优化 AST,生成代码字符串,将代码字符串转换成可执行函数。")]),e._v(" "),t("li",[e._v("虚拟 DOM:Vue 2 使用了虚拟 DOM 来提高渲染性能,虚拟 DOM 是一个 JavaScript 对象,可以描述真实 DOM 树的结构和属性。在更新视图时,Vue 2 会先根据数据生成一个新的虚拟 DOM 树,然后将新的虚拟 DOM 树和旧的虚拟 DOM 树进行比较,找出差异并更新到真实 DOM 上。")]),e._v(" "),t("li",[e._v("生命周期:Vue 2 的组件生命周期分为创建阶段、更新阶段和销毁阶段。在每个阶段,Vue 2 都会触发一些钩子函数,开发者可以在钩子函数中执行一些操作,比如初始化数据、发送网络请求、监听事件等。")]),e._v(" "),t("li",[e._v("组件通信:Vue 2 支持多种组件通信方式,包括父子组件通信、兄弟组件通信、任意组件通信等。其中父子组件通信主要通过 props 和事件来实现,兄弟组件通信可以通过一个共同的父组件来实现,任意组件通信可以使用 Vuex 状态管理库来实现。")])]),e._v(" "),t("p",[e._v("以上就是 Vue 2 的核心原理,理解这些原理可以帮助开发者更好地使用 Vue 2 来构建应用程序。")]),e._v(" "),t("h3",{attrs:{id:"虚拟-dom"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#虚拟-dom"}},[e._v("#")]),e._v(" 虚拟 DOM")]),e._v(" "),t("p",[e._v("在 Vue2 中,虚拟 DOM 被广泛地应用于渲染组件。当 Vue 实例的状态发生变化时,Vue 会通过比较前后状态来计算出需要更新的组件,并且使用虚拟 DOM 来减少渲染次数。")]),e._v(" "),t("p",[e._v("具体地说,Vue 会在内存中维护一个虚拟 DOM,称为 VNode(Vue 节点),它是一个 JavaScript 对象,表示真实 DOM 中的一个节点。当 Vue 组件渲染时,会将 VNode 转换为真实的 DOM 节点,并挂载到文档中。当 Vue 组件的状态发生变化时,Vue 会重新计算出新的 VNode,然后通过比较新旧 VNode,找出需要更新的部分,最后将更新的部分重新渲染到真实的 DOM 中。")]),e._v(" "),t("p",[e._v("Vue 的虚拟 DOM 实现采用了 Diff 算法,Diff 算法是通过比较新旧 VNode 的差异,然后将差异应用到真实 DOM 上,以达到更新视图的目的。Vue2 中的虚拟 DOM 还可以结合模板编译优化,将模板编译为渲染函数,以提高组件渲染性能。")]),e._v(" "),t("p",[e._v("总之,Vue2 中的虚拟 DOM 在组件的渲染和更新过程中起到了至关重要的作用,它通过比较前后状态,减少不必要的 DOM 操作,提高了组件的渲染性能。")]),e._v(" "),t("h3",{attrs:{id:"template-函数"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#template-函数"}},[e._v("#")]),e._v(" template 函数")]),e._v(" "),t("p",[e._v("在 Vue2 中,模板函数负责将组件的模板转换为渲染函数。在组件渲染时,Vue 将模板编译成渲染函数,并使用该函数来生成虚拟 DOM。模板函数将模板字符串解析为 AST(抽象语法树),然后将 AST 转换为渲染函数。")]),e._v(" "),t("p",[e._v("渲染函数是实际用于渲染虚拟 DOM 的 JavaScript 函数。Vue 将渲染函数生成并缓存起来,以便在需要更新组件时快速调用。渲染函数接收上下文对象作为参数,可以使用该对象中的数据和方法来动态生成虚拟 DOM。")]),e._v(" "),t("p",[e._v("虽然 Vue2 中的模板函数可以使编写模板变得更加简单直观,但是它也会带来一些性能问题,如模板解析和编译成渲染函数需要额外的开销,而且模板不支持一些 JavaScript 语言特性,如条件渲染需要使用 v-if 指令,而无法像在渲染函数中那样使用 if 语句。因此,Vue3 中推荐使用 JSX 语法和渲染函数来编写组件")]),e._v(" "),t("h2",{attrs:{id:"vue3"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#vue3"}},[e._v("#")]),e._v(" vue3")]),e._v(" "),t("blockquote",[t("p",[e._v("Vue 2.x 的模板在运行时被解析和转换为渲染函数。这个过程是在浏览器中发生的,因此需要一定的运行时间和性能消耗。这种方式的好处是可以在模板中使用常规的 HTML 和 JavaScript 语法,对开发人员比较友好,但也会带来一些性能上的损失。")])]),e._v(" "),t("p",[e._v("Vue 3.x 中使用了基于编译时的模板静态分析和优化的方式,将模板编译成渲染函数并进行缓存,以提高渲染性能。这种方式可以避免运行时的解析和转换,因此在渲染时具有更高的性能表现。")])])}),[],!1,null,null,null);t.default=_.exports}}]); \ No newline at end of file diff --git a/assets/js/148.71d7c7b3.js b/assets/js/148.71d7c7b3.js new file mode 100644 index 0000000000..98f5b4da0a --- /dev/null +++ b/assets/js/148.71d7c7b3.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[148],{487:function(e,t,r){"use strict";r.r(t);var n=r(4),s=Object(n.a)({},(function(){var e=this,t=e._self._c;return t("ContentSlotsDistributor",{attrs:{"slot-key":e.$parent.slotKey}},[t("h1",{attrs:{id:"前言"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#前言"}},[e._v("#")]),e._v(" 前言")]),e._v(" "),t("div",{staticClass:"custom-block tip"},[t("p",{staticClass:"custom-block-title"},[e._v("提示")]),e._v(" "),t("p",[e._v("本课程来自于《极客时间》vue 的学习课程\n"),t("a",{attrs:{href:"https://github.com/geektime-geekbang/geektime-vue-1",target:"_blank",rel:"noopener noreferrer"}},[e._v("源代码及课件源码地址"),t("OutboundLink")],1)]),e._v(" "),t("ul",[t("li",[e._v("目前 vue3.0 已经发布, 要了解最新 vue 的更新内容,请查看 "),t("a",{attrs:{href:"https://cn.vuejs.org/",target:"_blank",rel:"noopener noreferrer"}},[e._v("vuejs-cn"),t("OutboundLink")],1)]),e._v(" "),t("li",[e._v("如果要了解 vue 的技术原理,可以查看 "),t("a",{attrs:{href:"https://ustbhuangyi.github.io/vue-analysis/",target:"_blank",rel:"noopener noreferrer"}},[e._v("Vue.js 技术揭秘"),t("OutboundLink")],1)]),e._v(" "),t("li",[e._v("一个有可能用到的企业级 UI 组件库, "),t("a",{attrs:{href:"https://www.antdv.com/components/overview",target:"_blank",rel:"noopener noreferrer"}},[e._v("Ant Design Vue"),t("OutboundLink")],1)])])])])}),[],!1,null,null,null);t.default=s.exports}}]); \ No newline at end of file diff --git a/assets/js/149.6f0e763c.js b/assets/js/149.6f0e763c.js new file mode 100644 index 0000000000..832db9b4b6 --- /dev/null +++ b/assets/js/149.6f0e763c.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[149],{473:function(t,s,r){"use strict";r.r(s);var e=r(4),a=Object(e.a)({},(function(){var t=this._self._c;return t("ContentSlotsDistributor",{attrs:{"slot-key":this.$parent.slotKey}},[t("h2",{attrs:{id:"分类"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#分类"}},[this._v("#")]),this._v(" 分类")]),this._v(" "),t("p",[t("img",{attrs:{src:"https://cdn.jsdelivr.net/gh/jacky1234/picArchieve@master/uPic/20230522_174439_JRjV0b.png",alt:""}})])])}),[],!1,null,null,null);s.default=a.exports}}]); \ No newline at end of file diff --git a/assets/js/15.d6e839a3.js b/assets/js/15.d6e839a3.js new file mode 100644 index 0000000000..68d32023d0 --- /dev/null +++ b/assets/js/15.d6e839a3.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[15,25,37],{251:function(t,e,i){},252:function(t,e,i){"use strict";i.r(e);var s=i(11),n={props:{item:{required:!0}},computed:{link(){return Object(s.c)(this.item.link)},exact(){return this.$site.locales?Object.keys(this.$site.locales).some(t=>t===this.link):"/"===this.link}},methods:{isExternal:s.g,isMailto:s.h,isTel:s.i,focusoutAction(){this.$emit("focusout")}}},o=i(4),l=Object(o.a)(n,(function(){var t=this,e=t._self._c;return t.isExternal(t.link)?e("a",{staticClass:"nav-link external",attrs:{href:t.link,target:t.isMailto(t.link)||t.isTel(t.link)?null:"_blank",rel:t.isMailto(t.link)||t.isTel(t.link)?null:"noopener noreferrer"},on:{focusout:t.focusoutAction}},[t._v("\n "+t._s(t.item.text)+"\n "),e("OutboundLink")],1):e("router-link",{staticClass:"nav-link",attrs:{to:t.link,exact:t.exact},nativeOn:{focusout:function(e){return t.focusoutAction.apply(null,arguments)}}},[t._v(t._s(t.item.text))])}),[],!1,null,null,null);e.default=l.exports},253:function(t,e,i){},254:function(t,e,i){"use strict";i.r(e);var s={name:"DropdownTransition",methods:{setHeight(t){t.style.height=t.scrollHeight+"px"},unsetHeight(t){t.style.height=""}}},n=(i(255),i(4)),o=Object(n.a)(s,(function(){return(0,this._self._c)("transition",{attrs:{name:"dropdown"},on:{enter:this.setHeight,"after-enter":this.unsetHeight,"before-leave":this.setHeight}},[this._t("default")],2)}),[],!1,null,null,null);e.default=o.exports},255:function(t,e,i){"use strict";i(251)},261:function(t,e,i){"use strict";i(253)},269:function(t,e,i){"use strict";i.r(e);var s=i(252),n=i(254),o=i(97),l=i.n(o),r={components:{NavLink:s.default,DropdownTransition:n.default},data:()=>({open:!1,isMQMobile:!1}),props:{item:{required:!0}},computed:{dropdownAriaLabel(){return this.item.ariaLabel||this.item.text}},beforeMount(){this.isMQMobile=window.innerWidth<720,window.addEventListener("resize",()=>{this.isMQMobile=window.innerWidth<720})},methods:{toggle(){this.isMQMobile&&(this.open=!this.open)},isLastItemOfArray:(t,e)=>l()(e)===t},watch:{$route(){this.open=!1}}},a=(i(261),i(4)),u=Object(a.a)(r,(function(){var t=this,e=t._self._c;return e("div",{staticClass:"dropdown-wrapper",class:{open:t.open}},[e("button",{staticClass:"dropdown-title",attrs:{type:"button","aria-label":t.dropdownAriaLabel},on:{click:t.toggle}},[t.item.link?e("router-link",{staticClass:"link-title",attrs:{to:t.item.link}},[t._v(t._s(t.item.text))]):t._e(),t._v(" "),e("span",{directives:[{name:"show",rawName:"v-show",value:!t.item.link,expression:"!item.link"}],staticClass:"title"},[t._v(t._s(t.item.text))]),t._v(" "),e("span",{staticClass:"arrow",class:t.open?"down":"right"})],1),t._v(" "),e("DropdownTransition",[e("ul",{directives:[{name:"show",rawName:"v-show",value:t.open,expression:"open"}],staticClass:"nav-dropdown"},t._l(t.item.items,(function(i,s){return e("li",{key:i.link||s,staticClass:"dropdown-item"},["links"===i.type?e("h4",[t._v(t._s(i.text))]):t._e(),t._v(" "),"links"===i.type?e("ul",{staticClass:"dropdown-subitem-wrapper"},t._l(i.items,(function(s){return e("li",{key:s.link,staticClass:"dropdown-subitem"},[e("NavLink",{attrs:{item:s},on:{focusout:function(e){t.isLastItemOfArray(s,i.items)&&t.isLastItemOfArray(i,t.item.items)&&t.toggle()}}})],1)})),0):e("NavLink",{attrs:{item:i},on:{focusout:function(e){t.isLastItemOfArray(i,t.item.items)&&t.toggle()}}})],1)})),0)])],1)}),[],!1,null,null,null);e.default=u.exports}}]); \ No newline at end of file diff --git a/assets/js/150.70b791a5.js b/assets/js/150.70b791a5.js new file mode 100644 index 0000000000..2287e92826 --- /dev/null +++ b/assets/js/150.70b791a5.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[150],{474:function(t,e,r){"use strict";r.r(e);var n=r(4),a=Object(n.a)({},(function(){var t=this,e=t._self._c;return e("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[e("h2",{attrs:{id:"分类"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#分类"}},[t._v("#")]),t._v(" 分类")]),t._v(" "),e("p",[e("img",{attrs:{src:"https://static001.geekbang.org/resource/image/78/ba/78876b0a7262847ad6433024c01fc9ba.jpeg",alt:""}})]),t._v(" "),e("h2",{attrs:{id:"链接"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#链接"}},[t._v("#")]),t._v(" 链接")]),t._v(" "),e("ul",[e("li",[e("a",{attrs:{href:"https://cn.vuejs.org/v2/guide/components.html",target:"_blank",rel:"noopener noreferrer"}},[t._v("Vue 组件基础"),e("OutboundLink")],1)]),t._v(" "),e("li",[e("a",{attrs:{href:"https://cn.vuejs.org/v2/guide/components-registration.html",target:"_blank",rel:"noopener noreferrer"}},[t._v("组件注册"),e("OutboundLink")],1)]),t._v(" "),e("li",[e("a",{attrs:{href:"https://cn.vuejs.org/v2/guide/components-props.html",target:"_blank",rel:"noopener noreferrer"}},[t._v("属性"),e("OutboundLink")],1)])])])}),[],!1,null,null,null);e.default=a.exports}}]); \ No newline at end of file diff --git a/assets/js/151.2fbf46c6.js b/assets/js/151.2fbf46c6.js new file mode 100644 index 0000000000..0e585db76a --- /dev/null +++ b/assets/js/151.2fbf46c6.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[151],{476:function(n,s,e){"use strict";e.r(s);var a=e(4),t=Object(a.a)({},(function(){var n=this,s=n._self._c;return s("ContentSlotsDistributor",{attrs:{"slot-key":n.$parent.slotKey}},[s("p",[n._v("双向绑定和单项数据流不冲突:\ndemo:1.2")]),n._v(" "),s("p",[n._v("v-model: 语法糖")]),n._v(" "),s("div",{staticClass:"language- line-numbers-mode"},[s("pre",{pre:!0,attrs:{class:"language-text"}},[s("code",[n._v('\n\n\n')])]),n._v(" "),s("div",{staticClass:"line-numbers-wrapper"},[s("span",{staticClass:"line-number"},[n._v("1")]),s("br"),s("span",{staticClass:"line-number"},[n._v("2")]),s("br"),s("span",{staticClass:"line-number"},[n._v("3")]),s("br"),s("span",{staticClass:"line-number"},[n._v("4")]),s("br"),s("span",{staticClass:"line-number"},[n._v("5")]),s("br"),s("span",{staticClass:"line-number"},[n._v("6")]),s("br"),s("span",{staticClass:"line-number"},[n._v("7")]),s("br"),s("span",{staticClass:"line-number"},[n._v("8")]),s("br")])]),s("p",[n._v("习题:\n验证手机号是否正确:\n父控件向子组件传递 validate 方法验证,如1.2_a")])])}),[],!1,null,null,null);s.default=t.exports}}]); \ No newline at end of file diff --git a/assets/js/152.4667a007.js b/assets/js/152.4667a007.js new file mode 100644 index 0000000000..d8912a6225 --- /dev/null +++ b/assets/js/152.4667a007.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[152],{475:function(v,l,t){"use strict";t.r(l);var i=t(4),_=Object(i.a)({},(function(){var v=this,l=v._self._c;return l("ContentSlotsDistributor",{attrs:{"slot-key":v.$parent.slotKey}},[l("h2",{attrs:{id:"内置指令"}},[l("a",{staticClass:"header-anchor",attrs:{href:"#内置指令"}},[v._v("#")]),v._v(" 内置指令")]),v._v(" "),l("ul",[l("li",[v._v("v-if; v-else-if; v-else")]),v._v(" "),l("li",[v._v("v-show"),l("br"),v._v("\n值false代表"),l("code",[v._v("display:none")]),v._v(" 类似于android中的 invisible")]),v._v(" "),l("li",[v._v("v-bind bind property,可以省略")]),v._v(" "),l("li",[v._v("v-once 只渲染元素和组件一次。随后的重新渲染,元素/组件及其所有的子节点将被视为静态内容并跳过。这可以用于优化更新性能。")]),v._v(" "),l("li",[v._v("v-for")]),v._v(" "),l("li",[v._v("v-text")]),v._v(" "),l("li",[v._v("v-html")]),v._v(" "),l("li",[v._v("v-on:click @click 事件符号")]),v._v(" "),l("li",[v._v("v-model")]),v._v(" "),l("li",[v._v("v-pre")]),v._v(" "),l("li",[v._v("v-cloak")])]),v._v(" "),l("h2",{attrs:{id:"自定义指令"}},[l("a",{staticClass:"header-anchor",attrs:{href:"#自定义指令"}},[v._v("#")]),v._v(" 自定义指令")])])}),[],!1,null,null,null);l.default=_.exports}}]); \ No newline at end of file diff --git a/assets/js/153.d59db30c.js b/assets/js/153.d59db30c.js new file mode 100644 index 0000000000..948a0736d7 --- /dev/null +++ b/assets/js/153.d59db30c.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[153],{478:function(t,a,s){"use strict";s.r(a);var n=s(4),e=Object(n.a)({},(function(){var t=this,a=t._self._c;return a("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[a("h4",{attrs:{id:"app-vue-调用组件todoitem-vue-并产生回调"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#app-vue-调用组件todoitem-vue-并产生回调"}},[t._v("#")]),t._v(" App.vue 调用组件TodoItem.vue. 并产生回调")]),t._v(" "),a("ul",[a("li",[t._v("TodoItem.vue中定义插槽"),a("div",{staticClass:"language-html line-numbers-mode"},[a("pre",{pre:!0,attrs:{class:"language-html"}},[a("code",[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("li")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("class")]),a("span",{pre:!0,attrs:{class:"token attr-value"}},[a("span",{pre:!0,attrs:{class:"token punctuation attr-equals"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')]),t._v("item"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("input")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("type")]),a("span",{pre:!0,attrs:{class:"token attr-value"}},[a("span",{pre:!0,attrs:{class:"token punctuation attr-equals"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')]),t._v("checkbox"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')])]),t._v(" "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("v-model")]),a("span",{pre:!0,attrs:{class:"token attr-value"}},[a("span",{pre:!0,attrs:{class:"token punctuation attr-equals"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')]),t._v("checked"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("\x3c!-- 把checked状态传递出去,bind必须是一个对象 --\x3e")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("slot")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("name")]),a("span",{pre:!0,attrs:{class:"token attr-value"}},[a("span",{pre:!0,attrs:{class:"token punctuation attr-equals"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')]),t._v("item"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')])]),t._v(" "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("v-bind")]),a("span",{pre:!0,attrs:{class:"token attr-value"}},[a("span",{pre:!0,attrs:{class:"token punctuation attr-equals"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')]),t._v("{checked}"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("slot")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("name")]),a("span",{pre:!0,attrs:{class:"token attr-value"}},[a("span",{pre:!0,attrs:{class:"token punctuation attr-equals"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')]),t._v("item2"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')])]),t._v(" "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("v-bind")]),a("span",{pre:!0,attrs:{class:"token attr-value"}},[a("span",{pre:!0,attrs:{class:"token punctuation attr-equals"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')]),t._v("{checked}"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),t._v("\n")])]),t._v(" "),a("div",{staticClass:"line-numbers-wrapper"},[a("span",{staticClass:"line-number"},[t._v("1")]),a("br"),a("span",{staticClass:"line-number"},[t._v("2")]),a("br"),a("span",{staticClass:"line-number"},[t._v("3")]),a("br"),a("span",{staticClass:"line-number"},[t._v("4")]),a("br"),a("span",{staticClass:"line-number"},[t._v("5")]),a("br"),a("span",{staticClass:"line-number"},[t._v("6")]),a("br")])])]),t._v(" "),a("li",[t._v("App.vue"),a("div",{staticClass:"language-html line-numbers-mode"},[a("pre",{pre:!0,attrs:{class:"language-html"}},[a("code",[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("ul")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("todo-item")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("v-for")]),a("span",{pre:!0,attrs:{class:"token attr-value"}},[a("span",{pre:!0,attrs:{class:"token punctuation attr-equals"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')]),t._v("item in list"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')])]),t._v(" "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v(":item")]),a("span",{pre:!0,attrs:{class:"token attr-value"}},[a("span",{pre:!0,attrs:{class:"token punctuation attr-equals"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')]),t._v("item"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')])]),t._v(" "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v(":key")]),a("span",{pre:!0,attrs:{class:"token attr-value"}},[a("span",{pre:!0,attrs:{class:"token punctuation attr-equals"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')]),t._v("item"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("template")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[a("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("v-slot:")]),t._v("item")]),a("span",{pre:!0,attrs:{class:"token attr-value"}},[a("span",{pre:!0,attrs:{class:"token punctuation attr-equals"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')]),t._v("itemProps"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("\x3c!-- :->对象的形式 --\x3e")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("span")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v(":style")]),a("span",{pre:!0,attrs:{class:"token attr-value"}},[a("span",{pre:!0,attrs:{class:"token punctuation attr-equals"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')]),t._v("{fontSize: '20px', color: itemProps.checked ? 'red': 'blue'}"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v("{{item}}"),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("template")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[a("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("v-slot:")]),t._v("item2")]),a("span",{pre:!0,attrs:{class:"token attr-value"}},[a("span",{pre:!0,attrs:{class:"token punctuation attr-equals"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')]),t._v("itemProps"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("p")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token special-attr"}},[a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("style")]),a("span",{pre:!0,attrs:{class:"token attr-value"}},[a("span",{pre:!0,attrs:{class:"token punctuation attr-equals"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("'")]),a("span",{pre:!0,attrs:{class:"token value css language-css"}},[a("span",{pre:!0,attrs:{class:"token property"}},[t._v("display")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" inline"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),a("span",{pre:!0,attrs:{class:"token property"}},[t._v("marginLeft")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" 30px")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("'")])])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v("{{isSelected(itemProps)}}"),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),t._v("\n")])]),t._v(" "),a("div",{staticClass:"line-numbers-wrapper"},[a("span",{staticClass:"line-number"},[t._v("1")]),a("br"),a("span",{staticClass:"line-number"},[t._v("2")]),a("br"),a("span",{staticClass:"line-number"},[t._v("3")]),a("br"),a("span",{staticClass:"line-number"},[t._v("4")]),a("br"),a("span",{staticClass:"line-number"},[t._v("5")]),a("br"),a("span",{staticClass:"line-number"},[t._v("6")]),a("br"),a("span",{staticClass:"line-number"},[t._v("7")]),a("br"),a("span",{staticClass:"line-number"},[t._v("8")]),a("br"),a("span",{staticClass:"line-number"},[t._v("9")]),a("br"),a("span",{staticClass:"line-number"},[t._v("10")]),a("br"),a("span",{staticClass:"line-number"},[t._v("11")]),a("br")])])])])])}),[],!1,null,null,null);a.default=e.exports}}]); \ No newline at end of file diff --git a/assets/js/154.f826c41c.js b/assets/js/154.f826c41c.js new file mode 100644 index 0000000000..160f05a52e --- /dev/null +++ b/assets/js/154.f826c41c.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[154],{477:function(t,e,i){"use strict";i.r(e);var s=i(4),n=Object(s.a)({},(function(){var t=this._self._c;return t("ContentSlotsDistributor",{attrs:{"slot-key":this.$parent.slotKey}},[t("p",[this._v("10.理解虚拟Dom和key属性的作用")]),this._v(" "),t("p",[this._v("demo: 1.3")]),this._v(" "),t("p",[this._v("最好 "),t("strong",[this._v("不要用index作为key")]),this._v(",用index作为key有时候还会导致bug,尤其是item是具有某种状态的时候。。举个简单的例子,如果有ABC三个item,其中第一个A是选中的,这个时候如果我在A前面添加D,如果用index作为key就会变成D是选中的了,建议用唯一id来作为key")])])}),[],!1,null,null,null);e.default=n.exports}}]); \ No newline at end of file diff --git a/assets/js/155.2037fa4f.js b/assets/js/155.2037fa4f.js new file mode 100644 index 0000000000..d2aee0f86c --- /dev/null +++ b/assets/js/155.2037fa4f.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[155],{479:function(s,n,a){"use strict";a.r(n);var t=a(4),e=Object(t.a)({},(function(){var s=this,n=s._self._c;return n("ContentSlotsDistributor",{attrs:{"slot-key":s.$parent.slotKey}},[n("p",[s._v("11.如何触发组件更新")]),s._v(" "),n("h1",{attrs:{id:"数据来源-单向的"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#数据来源-单向的"}},[s._v("#")]),s._v(" 数据来源 (单向的)")]),s._v(" "),n("ol",[n("li",[s._v("来自父元素的属性")]),s._v(" "),n("li",[s._v("来自自身状态 data")]),s._v(" "),n("li",[s._v("来自状态管理 如 vuex Vue.observable")])]),s._v(" "),n("p",[s._v("响应式更新原理: https://cn.vuejs.org/v2/guide/reactivity.html")]),s._v(" "),n("h1",{attrs:{id:"demo"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#demo"}},[s._v("#")]),s._v(" Demo")]),s._v(" "),n("p",[s._v("父控件传递info给子控件,子控件打印 info demo")]),s._v(" "),n("div",{staticClass:"language- line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v('//1\ndata() {\n return {\n info: {\n number: undefined //提前声明,对 info下面字段进行响应式设置\n }\n }\n}\nthis.info.number = 1; \n\n//2 \ndata() {\n return {\n info: {}\n }\n} \nthis.$set(this.info, "number", 1); \n\n课后习题: \n 数组有哪些方式支持响应式更新?\n 如不支持如何处理,底层原理如何实现的?')])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br"),n("span",{staticClass:"line-number"},[s._v("8")]),n("br"),n("span",{staticClass:"line-number"},[s._v("9")]),n("br"),n("span",{staticClass:"line-number"},[s._v("10")]),n("br"),n("span",{staticClass:"line-number"},[s._v("11")]),n("br"),n("span",{staticClass:"line-number"},[s._v("12")]),n("br"),n("span",{staticClass:"line-number"},[s._v("13")]),n("br"),n("span",{staticClass:"line-number"},[s._v("14")]),n("br"),n("span",{staticClass:"line-number"},[s._v("15")]),n("br"),n("span",{staticClass:"line-number"},[s._v("16")]),n("br"),n("span",{staticClass:"line-number"},[s._v("17")]),n("br"),n("span",{staticClass:"line-number"},[s._v("18")]),n("br"),n("span",{staticClass:"line-number"},[s._v("19")]),n("br"),n("span",{staticClass:"line-number"},[s._v("20")]),n("br")])])])}),[],!1,null,null,null);n.default=e.exports}}]); \ No newline at end of file diff --git a/assets/js/156.118c9123.js b/assets/js/156.118c9123.js new file mode 100644 index 0000000000..9bf1df060a --- /dev/null +++ b/assets/js/156.118c9123.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[156],{480:function(t,s,i){"use strict";i.r(s);var l=i(4),n=Object(l.a)({},(function(){var t=this._self._c;return t("ContentSlotsDistributor",{attrs:{"slot-key":this.$parent.slotKey}},[t("p",[this._v("demo:1.9")]),this._v(" "),t("p",[this._v("callback ref")]),this._v(" "),t("ul",[t("li",[this._v("主动通知")]),this._v(" "),t("li",[this._v("主动获取")])])])}),[],!1,null,null,null);s.default=n.exports}}]); \ No newline at end of file diff --git a/assets/js/157.9bff072a.js b/assets/js/157.9bff072a.js new file mode 100644 index 0000000000..3b2f03595a --- /dev/null +++ b/assets/js/157.9bff072a.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[157],{481:function(t,s,a){"use strict";a.r(s);var n=a(4),e=Object(n.a)({},(function(){var t=this,s=t._self._c;return s("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[s("h2",{attrs:{id:"给对象赋值简写"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#给对象赋值简写"}},[t._v("#")]),t._v(" 给对象赋值简写")]),t._v(" "),s("blockquote",[s("p",[t._v("示例,简写如下代码")])]),t._v(" "),s("div",{staticClass:"language- line-numbers-mode"},[s("pre",{pre:!0,attrs:{class:"language-text"}},[s("code",[t._v("const model: OneClickPublishModel = {\n template_id: prompt?.ext?.template_id,\n biz_id: prompt?.ext?.biz_id,\n cell_text: prompt?.ext?.cell_text,\n friend_avatars: prompt?.ext?.friend_avatars,\n elements: prompt?.ext?.elements,\n cell_type: prompt?.ext?.cell_type,\n ext: prompt?.ext\n}\n")])]),t._v(" "),s("div",{staticClass:"line-numbers-wrapper"},[s("span",{staticClass:"line-number"},[t._v("1")]),s("br"),s("span",{staticClass:"line-number"},[t._v("2")]),s("br"),s("span",{staticClass:"line-number"},[t._v("3")]),s("br"),s("span",{staticClass:"line-number"},[t._v("4")]),s("br"),s("span",{staticClass:"line-number"},[t._v("5")]),s("br"),s("span",{staticClass:"line-number"},[t._v("6")]),s("br"),s("span",{staticClass:"line-number"},[t._v("7")]),s("br"),s("span",{staticClass:"line-number"},[t._v("8")]),s("br"),s("span",{staticClass:"line-number"},[t._v("9")]),s("br")])]),s("hr"),t._v(" "),s("p",[t._v("写法一:")]),t._v(" "),s("div",{staticClass:"language-javascript line-numbers-mode"},[s("pre",{pre:!0,attrs:{class:"language-javascript"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("model")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" OneClickPublishModel "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n\t"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("...")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("prompt"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?.")]),t._v("ext "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("||")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n\t"),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("ext")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" prompt"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?.")]),t._v("ext"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])]),t._v(" "),s("div",{staticClass:"line-numbers-wrapper"},[s("span",{staticClass:"line-number"},[t._v("1")]),s("br"),s("span",{staticClass:"line-number"},[t._v("2")]),s("br"),s("span",{staticClass:"line-number"},[t._v("3")]),s("br"),s("span",{staticClass:"line-number"},[t._v("4")]),s("br")])]),s("p",[t._v("这行代码会将 prompt.ext 中定义的属性直接复制到 model 对象中,前提是 prompt.ext 不为 null 或 undefined。这种方法更加简洁和精炼。")]),t._v(" "),s("p",[t._v("写法二:")]),t._v(" "),s("div",{staticClass:"language-javascript line-numbers-mode"},[s("pre",{pre:!0,attrs:{class:"language-javascript"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" template_id"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" biz_id"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" cell_text"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" friend_avatars"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" elements"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" cell_type "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" prompt"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?.")]),t._v("ext "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("||")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("model")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" OneClickPublishModel "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n\ttemplate_id"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n\tbiz_id"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n\tcell_text"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n\tfriend_avatars"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n\telements"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n\tcell_type"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])]),t._v(" "),s("div",{staticClass:"line-numbers-wrapper"},[s("span",{staticClass:"line-number"},[t._v("1")]),s("br"),s("span",{staticClass:"line-number"},[t._v("2")]),s("br"),s("span",{staticClass:"line-number"},[t._v("3")]),s("br"),s("span",{staticClass:"line-number"},[t._v("4")]),s("br"),s("span",{staticClass:"line-number"},[t._v("5")]),s("br"),s("span",{staticClass:"line-number"},[t._v("6")]),s("br"),s("span",{staticClass:"line-number"},[t._v("7")]),s("br"),s("span",{staticClass:"line-number"},[t._v("8")]),s("br"),s("span",{staticClass:"line-number"},[t._v("9")]),s("br"),s("span",{staticClass:"line-number"},[t._v("10")]),s("br")])]),s("p",[t._v("这段代码首先使用可选链 prompt?.ext 来安全地访问对象属性。如果 prompt?.ext 为 null 或 undefined,则解构赋值的目标对象将为空对象 {},不会引发错误。然后,您可以直接从解构后的属性创建 model 对象。这可以使代码更加简洁和可读。")])])}),[],!1,null,null,null);s.default=e.exports}}]); \ No newline at end of file diff --git a/assets/js/158.e0fbd9d4.js b/assets/js/158.e0fbd9d4.js new file mode 100644 index 0000000000..9af30a22c2 --- /dev/null +++ b/assets/js/158.e0fbd9d4.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[158],{482:function(e,t,r){"use strict";r.r(t);var a=r(4),n=Object(a.a)({},(function(){var e=this,t=e._self._c;return t("ContentSlotsDistributor",{attrs:{"slot-key":e.$parent.slotKey}},[t("h2",{attrs:{id:"base"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#base"}},[e._v("#")]),e._v(" Base")]),e._v(" "),t("ul",[t("li",[t("a",{attrs:{href:"https://developer.mozilla.org/en-US/blog/",target:"_blank",rel:"noopener noreferrer"}},[e._v("MDN blog"),t("OutboundLink")],1),e._v(": This set of articles aims to guide complete beginners to web development with all that they need to start coding websites.\n"),t("ul",[t("li",[t("a",{attrs:{href:"https://developer.mozilla.org/en-US/docs/Web/HTML",target:"_blank",rel:"noopener noreferrer"}},[e._v("Structuring the web with HTML"),t("OutboundLink")],1)]),e._v(" "),t("li",[t("a",{attrs:{href:"https://developer.mozilla.org/zh-CN/docs/Web/CSS",target:"_blank",rel:"noopener noreferrer"}},[e._v("Learn to style HTML using CSS"),t("OutboundLink")],1)]),e._v(" "),t("li",[t("a",{attrs:{href:"https://developer.mozilla.org/en-US/docs/Web/JavaScript",target:"_blank",rel:"noopener noreferrer"}},[e._v("JavaScript — Dynamic client-side scripting"),t("OutboundLink")],1)])])]),e._v(" "),t("li",[t("a",{attrs:{href:"https://q.shanyue.tech/engineering/",target:"_blank",rel:"noopener noreferrer"}},[e._v("大厂面试题每日一题"),t("OutboundLink")],1),e._v(": by 山月")]),e._v(" "),t("li",[t("RouterLink",{attrs:{to:"/pages/4f876a/"}},[e._v("web 工具及涉及的概念")]),e._v(" 整理的 web 工具如 npm, 和设计的概念等")],1)]),e._v(" "),t("h3",{attrs:{id:"javascript"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#javascript"}},[e._v("#")]),e._v(" javascript")]),e._v(" "),t("ul",[t("li",[t("RouterLink",{attrs:{to:"/pages/548959/"}},[e._v("javascript 内链")])],1)]),e._v(" "),t("h2",{attrs:{id:"react"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#react"}},[e._v("#")]),e._v(" react")]),e._v(" "),t("blockquote",[t("p",[e._v("React 是一个非常流行的 JavaScript 库,用于构建用户界面。以下是 React 学习路线:")])]),e._v(" "),t("ul",[t("li",[t("a",{attrs:{href:"https://react.dev/",target:"_blank",rel:"noopener noreferrer"}},[e._v("React 官方文档"),t("OutboundLink")],1)]),e._v(" "),t("li",[t("a",{attrs:{href:"https://reactnative.dev/",target:"_blank",rel:"noopener noreferrer"}},[e._v("react native"),t("OutboundLink")],1),e._v(" "),t("ul",[t("li",[t("a",{attrs:{href:"https://reactnative.dev/docs/getting-started",target:"_blank",rel:"noopener noreferrer"}},[e._v("get started"),t("OutboundLink")],1)])])]),e._v(" "),t("li",[t("RouterLink",{attrs:{to:"/react/"}},[e._v("react 内链")])],1)]),e._v(" "),t("h2",{attrs:{id:"微信小程序"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#微信小程序"}},[e._v("#")]),e._v(" 微信小程序")]),e._v(" "),t("blockquote",[t("p",[t("a",{attrs:{href:"https://developers.weixin.qq.com/miniprogram/dev/framework/",target:"_blank",rel:"noopener noreferrer"}},[e._v("开发指南"),t("OutboundLink")],1)])])])}),[],!1,null,null,null);t.default=n.exports}}]); \ No newline at end of file diff --git a/assets/js/159.7adbcbd6.js b/assets/js/159.7adbcbd6.js new file mode 100644 index 0000000000..4a7d6d49da --- /dev/null +++ b/assets/js/159.7adbcbd6.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[159],{483:function(t,n,s){"use strict";s.r(n);var e=s(4),a=Object(e.a)({},(function(){var t=this,n=t._self._c;return n("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[n("blockquote",[n("p",[n("a",{attrs:{href:"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference",target:"_blank",rel:"noopener noreferrer"}},[t._v("https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference"),n("OutboundLink")],1)])]),t._v(" "),n("h2",{attrs:{id:"function"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#function"}},[t._v("#")]),t._v(" Function")]),t._v(" "),n("h3",{attrs:{id:"methods"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#methods"}},[t._v("#")]),t._v(" methods")]),t._v(" "),n("p",[t._v("下面主要介绍方法原型的方法")]),t._v(" "),n("h4",{attrs:{id:"bind"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#bind"}},[t._v("#")]),t._v(" bind")]),t._v(" "),n("blockquote",[n("p",[t._v("The bind() method creates a new function that, when called, has its this keyword set to the provided value, with a given sequence of arguments preceding any provided when the new function is called.\n介绍: "),n("a",{attrs:{href:"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind",target:"_blank",rel:"noopener noreferrer"}},[t._v("https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind"),n("OutboundLink")],1)])]),t._v(" "),n("div",{staticClass:"language-javascript line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-javascript"}},[n("code",[n("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" module "),n("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n\t"),n("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("x")]),n("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),n("span",{pre:!0,attrs:{class:"token number"}},[t._v("42")]),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n\t"),n("span",{pre:!0,attrs:{class:"token function-variable function"}},[t._v("getX")]),n("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),n("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("function")]),t._v(" "),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n\t\t"),n("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),n("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("this")]),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("x\n\t"),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n"),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),n("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" unboundGetX "),n("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" module"),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("getX\nconsole"),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),n("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),n("span",{pre:!0,attrs:{class:"token function"}},[t._v("unboundGetX")]),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),n("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// The function gets invoked at the global scope")]),t._v("\n"),n("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Expected output: undefined")]),t._v("\n\n"),n("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" boundGetX "),n("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),n("span",{pre:!0,attrs:{class:"token function"}},[t._v("unboundGetX")]),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),n("span",{pre:!0,attrs:{class:"token function"}},[t._v("bind")]),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("module"),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\nconsole"),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),n("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),n("span",{pre:!0,attrs:{class:"token function"}},[t._v("boundGetX")]),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),n("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Expected output: 42")]),t._v("\n")])]),t._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[t._v("1")]),n("br"),n("span",{staticClass:"line-number"},[t._v("2")]),n("br"),n("span",{staticClass:"line-number"},[t._v("3")]),n("br"),n("span",{staticClass:"line-number"},[t._v("4")]),n("br"),n("span",{staticClass:"line-number"},[t._v("5")]),n("br"),n("span",{staticClass:"line-number"},[t._v("6")]),n("br"),n("span",{staticClass:"line-number"},[t._v("7")]),n("br"),n("span",{staticClass:"line-number"},[t._v("8")]),n("br"),n("span",{staticClass:"line-number"},[t._v("9")]),n("br"),n("span",{staticClass:"line-number"},[t._v("10")]),n("br"),n("span",{staticClass:"line-number"},[t._v("11")]),n("br"),n("span",{staticClass:"line-number"},[t._v("12")]),n("br"),n("span",{staticClass:"line-number"},[t._v("13")]),n("br"),n("span",{staticClass:"line-number"},[t._v("14")]),n("br")])]),n("p",[t._v("解释如下:")]),t._v(" "),n("ul",[n("li",[n("p",[t._v("第一个 console.log(unboundGetX()); 中的 unboundGetX() 函数在全局作用域中被调用,由于在此情况下函数内部的 this 指向全局对象(在浏览器中为 window),而全局对象没有 x 属性,因此返回 undefined。")])]),t._v(" "),n("li",[n("p",[t._v("第二个 console.log(boundGetX()); 中的 boundGetX() 函数通过 bind() 方法绑定到了 module 对象,所以在函数内部的 this 指向 module 对象。因此,它能够访问 module 对象中的 x 属性,返回 42。")])])]),t._v(" "),n("p",[t._v("通过使用 bind() 方法,我们可以将函数绑定到特定的对象上,确保函数内部的 "),n("code",[t._v("this")]),t._v(" 指向所绑定的对象。这样可以避免函数在不同上下文中执行时 "),n("code",[t._v("this")]),t._v(" 的指向问题。在这个例子中,unboundGetX 是一个没有绑定到任何对象的函数,因此在全局作用域中调用它会导致 "),n("code",[t._v("this")]),t._v("s 指向全局对象。而通过 bind() 方法将其绑定到 module 对象上,就可以确保在调用 boundGetX 时 "),n("code",[t._v("this")]),t._v(" 指向 module 对象。")]),t._v(" "),n("h2",{attrs:{id:"links"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#links"}},[t._v("#")]),t._v(" links")]),t._v(" "),n("ul",[n("li",[n("a",{attrs:{href:"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference",target:"_blank",rel:"noopener noreferrer"}},[t._v("reference"),n("OutboundLink")],1)])])])}),[],!1,null,null,null);n.default=a.exports}}]); \ No newline at end of file diff --git a/assets/js/16.42aaf4fa.js b/assets/js/16.42aaf4fa.js new file mode 100644 index 0000000000..ba2daac002 --- /dev/null +++ b/assets/js/16.42aaf4fa.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[16],{278:function(t,e){t.exports=function(t){return null==t}},295:function(t,e,n){},318:function(t,e,n){var r=n(13),o=n(5),i=n(12);t.exports=function(t){return"string"==typeof t||!o(t)&&i(t)&&"[object String]"==r(t)}},319:function(t,e,n){"use strict";n(295)},340:function(t,e,n){"use strict";n.r(e);n(25);var r=n(11),o=n(318),i=n.n(o),s=n(278),a=n.n(s),p={name:"PageNav",props:["sidebarItems"],computed:{prev(){return u(l.PREV,this)},next(){return u(l.NEXT,this)}},methods:{showTooltip(t){const e=document.body.clientWidth,n=t.clientX,r=t.target.querySelector(".tooltip");if(!r)return;const o=r.style;nt,getPageLinkConfig:({frontmatter:t})=>t.next},PREV:{resolveLink:function(t,e){return c(t,e,-1)},getThemeLinkConfig:({prevLinks:t})=>t,getPageLinkConfig:({frontmatter:t})=>t.prev}};function u(t,{$themeConfig:e,$page:n,$route:o,$site:s,sidebarItems:p}){const{resolveLink:l,getThemeLinkConfig:u,getPageLinkConfig:c}=t,v=u(e),g=c(n),f=a()(g)?v:g;return!1===f?void 0:i()(f)?Object(r.l)(s.pages,f,o.path):l(n,p)}function c(t,e,n){const r=[];!function t(e,n){for(let r=0,o=e.length;r({badges:["data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAYAAAA7MK6iAAAAAXNSR0IArs4c6QAABGpJREFUSA3tVVtoXFUU3fvOI53UlmCaKIFmwEhsE7QK0ipFEdHEKpXaZGrp15SINsXUWvBDpBgQRKi0+KKoFeJHfZA+ED9KKoIU2gYD9UejTW4rVIzm0VSTziPzuNu1z507dibTTjL4U/DAzLn3nL3X2o91ziX6f9wMFdh6Jvbm9nNSV0msViVO6tN1Rm7NMu2OpeJ9lWBUTDxrJbYTS0hInuwciu9eLHlFxCLCZEk3MegsJmZ5K/JD6t7FkFdEvGUo1g7qJoG3MHImqRIn8/nzY1K9UPKKiJmtnUqHVE3Gbuay6vJE/N2FEmuxFjW2nUuE0yQXRRxLiTUAzs36zhZvOXJPdX850EVnnLZkB8prodQoM5JGj7Xk2mvC7JB8tG04Ef5PiXtG0UtxupRQSfTnBoCy554x18yJHI6I+G5Eru4LHmPJZEQsrvPUbMiA8G/WgMK7w7I+ez7++o2ANfbrjvaOl1tFMs+htG3IrZH9/hDX1Pr8Tc0UvH8tcX29KzAgIGcEkINyW5BF9x891hw6VYqgJHEk0huccS7vh3C6gTiODL+26huuBtbct8eZnqLML8PkxGYpuPZBqtqwkSjgc4mB5gbgig5i+y0UDK35LMxXisn9xQtK+nd26gTIHsHe/oblK/b29fUmN/8Y+9jAQrnBp56m1LcDlDp9irKTExSKduXJVWSqdBMA08pEJnEIOB3FPPMybu/oeV8zFeYN3xx576Q6RH+VmplE4ncQV5v+5rzSoyOU7PuEAg8g803PwBJ0CExno/jcMbN8tONYeOmHiuUNryvm3fRUy4tMPVLdAGkUhNWuggGrJcXPv+ouCjz0MKUHz1J2/E8IC9nqTabcxgaBYM0hPhD5Y65FsbxRQKxCQrDjDctW7PUM3HuZunFyifSAqEfuzCp48Il24luWUWZoyJCaPR82jE0+kFA643wRFVni4RYSq3ohJO2pZ7B5dO4xkDWbEpossJPLSrPjYID8rS2UHTlvyNxqIGsg674XJJ7vnh5L7PNwC4hh2sjCI96mzszOTpxLF0T7l88Yz7lAuK6OnL8gXLOnTvpzSb22YG8W7us3jSebFHeeqnXRG1vt+MoUM84LQIBmMsCTAcOauTh0T0l0neQK7m2bLMt2mGxU3HYssS0J2cdv5wljlPsrIuZLAG/2DOZIXgCYT8uMGZN+e2kSirfxZOPCsC0f24nTZzspnVn9VePS1Z5vubmAGGXG8ZFno9Hel0yfA5ZPhF7Dh972BQJ2qCpgH67lmWtBYbvk6sz02wjky2vXyz0XErP/kFB619js1BtwfOV4OPRqOQBjy3Qbk18vigUPPSD5ceHnwck7W9bhAqZdd7SuG7w4/P2F/GaJh8c7e9qgow+Q7cGBo+98WsLkuktFqiZabtXuQTu/Y5ETbR0v7tNSFnvrmu6pjdoan2KjMu8q/Hmj1EfCO2ZGfEIbIXKUlw8qaX9/b2oeSJmFksSeT/Fn0V3nSypChh4Gjh74ybO9aeZ/AN2dwciu2/MhAAAAAElFTkSuQmCC","data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAYAAAA7MK6iAAAAAXNSR0IArs4c6QAABH1JREFUSA3tVl1oHFUUPmdmd2ltklqbpJDiNnXFmgbFktho7YMPNiJSSZM0+CAYSkUELVhM6YuwIPpgoOKDqOBDC0XE2CQoNtQXBUFTTcCi+Wlh1V2TQExsUzcltd3M9Tt3ZjZzZ2fT+OJTL8yeM+eee757fmeJbq//KQL8X3DUSFOcfr7cRsRtxNQMWueeVzOkaITIGqQHNg5y8+jNW9ldM7A6nTpAjuolUikAwq7CE3WcM2RRDz+XGVgN3FptU/aUSlvq9Pa3iZ1+sgAqJyyAFqkipd9dqiwHF3P65YycLWc/6sqGrvoEoIp6DOFaX5h6+dnfjkWprwqsPk0dUGq5vySwDImC10KxFHgGL1SWoc92O3eVht09qdXNH11I2SsTsJYqMWzihqGMi+A+Garf3BAuuLI5oGlULyNfyB/HYNujwktOfRrMr5t77NmevqaUopx0grnKAyvVpmwUDB4x6FPXuGvYLTDwWsejwgtgkYKPqRJg8SV6xaiZ3ZTppGneS4yfH5/66fZSDHv+QZci/+h5c5UHtpy67JUqGppM0sh0Nc1dW6/N1W5Yoqat8/TU/VnadmdeW2PLLSyh0cvxBs3KbqTmwYPpxN4do/mzE8nEpvX/UMu2Wbp74zUAK5q6WkHns7V0eWkdPbPzd3rxkTGybadYySumVzhcaJFbs5UrEkQ/+CK8gF5dnh/6ciIZ73gwQ927L1IitoxKLXYP3SjYdOrHHfTZhRRlFyrorafPk20B3HPD1y2G3qKZME5Jcf3t/HUC13/8tSd++vqFveMUTwAUxSUFI1QekR1+bIze3D9MF2aq6cPvG72CgnldWCFqyRw3lwH8ZMerjTD9ElRO7Gv44wNpC90aASqGfVlz/Rx17srQ57/UU26hkhQqUB7dBR71WmzQhHUnblGmVOEw0jhbV1n9OlXUDCIRGaNV5Jp43N516fN7JmnTHdfp7Hgy0luO4aMhtkLL8Bi3bUWYvzh5Mn1dTxrL6QmGuRhGL/TiTTxRoEdTszSaq9GR0NGA3KdkOz3hqSV3MIDhQ5IVX/Ivx3umBti2es2h4eZby7x8br1rkf7Mo90AqC8aQ3sJeNzqFRu+vSANAQe3PL7l0HGOAdwDCeZYvNKeoZp1Qfs6Aipndh86HmFRi0LAnEO47wsqM6cdfjh3jBPUzhZy7nvlUfFsamED1VQt6aISHVymXZ/B2aCtIG8AI8xfobj2d3en1wWVhOeHELKmLQ1s211s88comkv4UCwWyF787mJdYXtNfhKAXVqnKTq8QZvGAGGOfaTo5pGZ/PwbUCr5+DPr/1J92JNHr9aOl/F3iI5+O1nfybsGxoimvZ3ViWSluDITw3P37mypheDIPY0tw7+O/5ApbkYw+zpfaUVu32Pi98+defdUhEpZkRFq0aqyNh9FuL9hpYbEm6iwi0z2REd09ZmyENEbuhjDWzKvZXTqKYaBIr3tt5kuPtQBZFvEUwHt60vfCNu41XsksH9Ij1BMMz1Y0OOunHNShFIP5868g5zeXmuLwL9T4b6Q2+KejgAAAABJRU5ErkJggg==","data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAYAAAA7MK6iAAAAAXNSR0IArs4c6QAABKFJREFUSA3tVl1oFVcQnrMbrak3QUgkya1akpJYcrUtIqW1JvFBE9LiQ5v6JmJpolbMg32rVrhgoYK0QiMY6i9Y6EMaW5D+xFJaTYItIuK2Kr3+BJNwkxBj05sQY3b3nM6cs2dv9t7NT/vQJw/sndk5M/PNzJkzewGerP+pAmy+ON8lLzUJgA8ZYxYIYZmGYRnctDaWvJJAmTtfP1pvXsBCCPP8QFcCaRkZYACgDZFO4stNIcBCajEOlmmC9XpJ9bAGCaPaPmzPl32dvLSVu3BWCTQs0XQQ6g0DYgwLIoAZbBCdW/i+781o1VVlm/410mw4h06Y7bIPHNyWDyL4FHkX03Q8SrzNhZTZriieckWt7cL6MM85YcLpsi/7O9/iXFT6MswI0DmmpkSaJ0qLxFIm3+i1THHB3zmBH3PYx9CcykcLOeQVVa7QtdxTgQgEleX2AjHYfwA+2ddV77ruGoJUbhGDI09YSNXyMpUt5ylOzxgbUmtOp7NmbNt8v3arjTBfYELmLUV+M+nSawNNAUqpT3ClJWg5I3BLT+cGW/DXNGCa6tx1aakCGEigArTn4TDIPdrXXYKCZNrHLMCOEPvHBlLQ99s9eHB7EB6NTki73CVPQ2F5MSx/uRQixfmq7rK0wYD8w8E905bnPDfwoWs/rfv93NWN/ZfvwsLIU7A09gxECyISeGJkHAau98L97tuw7NXnoPyNF8FcYGLGKsOs0mN3OEyec9esGW/ZEl945dTP34wlR2FZVQWU1q0Cw8Tr7p+hgLLNL0FPxx/Q35mA8aEUrH6nCgwEl0tn7wUiZYJnNRh6DK4UH/k0lfyrsBKdPVv/AriGIQcEDQZ65LBAGe2Rzui9Ybjz7XUppz1/uKBbyVPGkN3ZAeC6hr0x7Nr38N5+EqkoOm17xpoqR9ohQF55ERSvr4Dkr3chNfC3DMzGJlNBElW8w9nsGQvhNGIzDkXzCg8cLK951xHsFBlTJspJNi3ZFIMF2AeDV3q8DNOB+YHi6QTrChDIWDBRi5U5f+ZMfJLu3ccrqxtdxk4SKH336LFxSmkqefwU5T8fhdSdQf9IVKD6aNiwI/hnmcAZ91isYMJIaCUCx9W098+LgruikeTqzqqxKPUwqJyCPJiyemVVZBOijDGjD38Os0jOiSPL1z3SPjXNANbiNPXAdzTfukjjuknNBbyz3nwgTd3AVFqUJ5hpHlq9MveLnWwttUfoygBmvVjuikxND3znrhsELnZk7k+OjIGxeNEkomyLVta0xxn+HZhjBc4YZ/AFjHjz9u3xRZl2BN4aq9nFwWh16IrQ1aHHEd3j1+4/dB9OtH4e29A2H1DyHQRmOSfQZ1Fy7MHBTGB6J/Djq6p3OxyO2cB+4Car7v/o3GXgfAkj23+x9ID1Teoamo/SXcbvSf2PX7Vc8DdCmE1vN9di+32P9/5YR3vLnhCVGUWBjEkr3yh4H8v9CzmsbdhzOKzsJKM90iFdaTMjRPhGVsakRvOaRidljo6H6G7j+ctrJpsP+4COhDIl0La2+FS4+5mlocBaXY5QnGZysIBYoeSsl5qQzrSj/cgNrfuEzlWBfwA+EjrZyWUvpAAAAABJRU5ErkJggg=="],currentBadge:""}),created(){this.$themeConfig.titleBadgeIcons&&(this.badges=this.$themeConfig.titleBadgeIcons),this.currentBadge=this.getBadge()},watch:{"$route.path"(){this.currentBadge=this.getBadge()}},methods:{getBadge(){return this.badges[Math.floor(Math.random()*this.badges.length)]}}}},307:function(t,e,s){"use strict";s(280)},331:function(t,e,s){"use strict";s.r(e);var a=s(16),n=s.n(a),i=s(11),r={mixins:[s(303).a],data:()=>({postsList:[],countByYear:{},perPage:80,currentPage:1}),created(){this.getPageData();const{$sortPostsByDate:t,countByYear:e}=this;for(let s=0;s{if(this.postsList.lengtha&&s+a>=n-250&&this.loadmore()}},200))},methods:{getPageData(){const t=this.currentPage,e=this.perPage;this.postsList=this.postsList.concat(this.$sortPostsByDate.slice((t-1)*e,t*e))},loadmore(){this.currentPage=this.currentPage+1,this.getPageData()},getYear(t){const e=this.postsList[t];if(!e)return;const{frontmatter:{date:s}}=e;return s&&"string"===Object(i.n)(s)?s.slice(0,4):void 0},getDate(t){const{frontmatter:{date:e}}=t;if(e&&"string"===Object(i.n)(e))return e.slice(5,10)}}},A=(s(307),s(4)),o=Object(A.a)(r,(function(){var t=this,e=t._self._c;return e("div",{staticClass:"custom-page archives-page"},[e("div",{staticClass:"theme-vdoing-wrapper"},[e("h1",[!1!==t.$themeConfig.titleBadge?e("img",{attrs:{src:t.currentBadge}}):t._e(),t._v("\n "+t._s(t.$page.title)+"\n ")]),t._v(" "),e("div",{staticClass:"count"},[t._v("\n 总共 "),e("i",[t._v(t._s(t.$sortPostsByDate.length))]),t._v(" 篇文章\n ")]),t._v(" "),e("ul",[t._l(t.postsList,(function(s,a){return[(t.year=t.getYear(a))!==t.getYear(a-1)?e("li",{key:a+t.$sortPostsByDate.length,staticClass:"year"},[e("h2",[t._v("\n "+t._s(t.year)+"\n "),e("span",[e("i",[t._v(t._s(t.countByYear[t.year]))]),t._v(" 篇\n ")])])]):t._e(),t._v(" "),e("li",{key:a},[e("router-link",{attrs:{to:s.path}},[e("span",{staticClass:"date"},[t._v(t._s(t.getDate(s)))]),t._v("\n "+t._s(s.title)+"\n "),s.frontmatter.titleTag?e("span",{staticClass:"title-tag"},[t._v("\n "+t._s(s.frontmatter.titleTag)+"\n ")]):t._e()])],1)]}))],2)])])}),[],!1,null,null,null);e.default=o.exports}}]); \ No newline at end of file diff --git a/assets/js/18.311ef653.js b/assets/js/18.311ef653.js new file mode 100644 index 0000000000..5ee5b07650 --- /dev/null +++ b/assets/js/18.311ef653.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[18],{284:function(t,o,e){},304:function(t,o,e){"use strict";var s=Object.assign||function(t){for(var o=1;o({threshold:100,scrollTop:null,showCommentBut:!1,commentTop:null,currentMode:"",showModeBox:!1,modeList:[{name:"跟随系统",icon:"icon-zidong",KEY:"auto"},{name:"浅色模式",icon:"icon-rijianmoshi",KEY:"light"},{name:"深色模式",icon:"icon-yejianmoshi",KEY:"dark"},{name:"阅读模式",icon:"icon-yuedu",KEY:"read"}],_scrollTimer:null,_textareaEl:null,_recordScrollTop:null,COMMENT_SELECTOR_1:"#vuepress-plugin-comment",COMMENT_SELECTOR_2:"#valine-vuepress-comment",COMMENT_SELECTOR_3:".vssue"}),mounted(){if(this.currentMode=i.a.get("mode")||this.$themeConfig.defaultMode||"auto",this.scrollTop=this.getScrollTop(),window.addEventListener("scroll",n()(()=>{this.scrollTop=this.getScrollTop()},100)),window.addEventListener("load",()=>{this.getCommentTop()}),document.documentElement.clientWidth<719){this.$refs.modeBox.onclick=()=>{this.showModeBox=!1},window.addEventListener("scroll",n()(()=>{this.showModeBox&&(this.showModeBox=!1)},100))}const t=document.querySelectorAll(".buttons .button");for(let o=0;o{e.classList.remove("hover")},150)}))}},computed:{showToTop(){return this.scrollTop>this.threshold}},methods:{toggleMode(t){this.currentMode=t,this.$emit("toggle-theme-mode",t)},getScrollTop:()=>window.pageYOffset||document.documentElement.scrollTop||document.body.scrollTop||0,scrollToTop(){window.scrollTo({top:0,behavior:"smooth"}),this.scrollTop=0},getCommentTop(){setTimeout(()=>{let t=document.querySelector(this.COMMENT_SELECTOR_1)||document.querySelector(this.COMMENT_SELECTOR_2)||document.querySelector(this.COMMENT_SELECTOR_3);t&&(this.showCommentBut=!1!==this.$frontmatter.comment&&!0!==this.$frontmatter.home,this.commentTop=t.offsetTop-58)},500)},scrollToComment(){window.scrollTo({top:this.commentTop,behavior:"smooth"}),this._textareaEl=document.querySelector(this.COMMENT_SELECTOR_1+" textarea")||document.querySelector(this.COMMENT_SELECTOR_2+" input")||document.querySelector(this.COMMENT_SELECTOR_3+" textarea"),this._textareaEl&&this.getScrollTop()!==this._recordScrollTop?document.addEventListener("scroll",this._handleListener):this._textareaEl&&this.getScrollTop()===this._recordScrollTop&&this._handleFocus()},_handleListener(){clearTimeout(this._scrollTimer),this._scrollTimer=setTimeout(()=>{document.removeEventListener("scroll",this._handleListener),this._recordScrollTop=this.getScrollTop(),this._handleFocus()},30)},_handleFocus(){this._textareaEl.focus(),this._textareaEl.classList.add("yellowBorder"),setTimeout(()=>{this._textareaEl.classList.remove("yellowBorder")},500)}},watch:{"$route.path"(){this.showCommentBut=!1,this.getCommentTop()}}},l=(e(311),e(4)),c=Object(l.a)(r,(function(){var t=this,o=t._self._c;return o("div",{staticClass:"buttons"},[o("transition",{attrs:{name:"fade"}},[o("div",{directives:[{name:"show",rawName:"v-show",value:t.showToTop,expression:"showToTop"}],staticClass:"button blur go-to-top iconfont icon-fanhuidingbu",attrs:{title:"返回顶部"},on:{click:t.scrollToTop}})]),t._v(" "),o("div",{directives:[{name:"show",rawName:"v-show",value:t.showCommentBut,expression:"showCommentBut"}],staticClass:"button blur go-to-comment iconfont icon-pinglun",attrs:{title:"去评论"},on:{click:t.scrollToComment}}),t._v(" "),o("div",{staticClass:"button blur theme-mode-but iconfont icon-zhuti",attrs:{title:"主题模式"},on:{mouseenter:function(o){t.showModeBox=!0},mouseleave:function(o){t.showModeBox=!1},click:function(o){t.showModeBox=!0}}},[o("transition",{attrs:{name:"mode"}},[o("ul",{directives:[{name:"show",rawName:"v-show",value:t.showModeBox,expression:"showModeBox"}],ref:"modeBox",staticClass:"select-box",on:{click:function(t){t.stopPropagation()},touchstart:function(t){t.stopPropagation()}}},t._l(t.modeList,(function(e){return o("li",{key:e.KEY,staticClass:"iconfont",class:[e.icon,{active:e.KEY===t.currentMode}],on:{click:function(o){return t.toggleMode(e.KEY)}}},[t._v("\n "+t._s(e.name)+"\n ")])})),0)])],1)],1)}),[],!1,null,null,null);o.default=c.exports}}]); \ No newline at end of file diff --git a/assets/js/19.86c15ae6.js b/assets/js/19.86c15ae6.js new file mode 100644 index 0000000000..cd07c84080 --- /dev/null +++ b/assets/js/19.86c15ae6.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[19],{278:function(t,e){t.exports=function(t){return null==t}},294:function(t,e,i){},317:function(t,e,i){"use strict";i(294)},339:function(t,e,i){"use strict";i.r(e);var s=i(278),a=i.n(s),n=i(11),r={name:"PageEdit",computed:{tags(){return this.$frontmatter.tags},lastUpdated(){return this.$page.lastUpdated},lastUpdatedText(){return"string"==typeof this.$themeLocaleConfig.lastUpdated?this.$themeLocaleConfig.lastUpdated:"string"==typeof this.$site.themeConfig.lastUpdated?this.$site.themeConfig.lastUpdated:"Last Updated"},editLink(){const t=a()(this.$page.frontmatter.editLink)?this.$site.themeConfig.editLinks:this.$page.frontmatter.editLink,{repo:e,docsDir:i="",docsBranch:s="master",docsRepo:n=e}=this.$site.themeConfig;return t&&n&&this.$page.relativePath?this.createEditLink(e,n,i,s,this.$page.relativePath):null},editLinkText(){return this.$themeLocaleConfig.editLinkText||this.$site.themeConfig.editLinkText||"Edit this page"}},methods:{createEditLink(t,e,i,s,a){if(/bitbucket.org/.test(e)){return e.replace(n.b,"")+"/src"+`/${s}/`+(i?i.replace(n.b,"")+"/":"")+a+`?mode=edit&spa=0&at=${s}&fileviewer=file-view-default`}if(/gitlab.com/.test(e)){return e.replace(n.b,"")+"/-/edit"+`/${s}/`+(i?i.replace(n.b,"")+"/":"")+a}const r=/gitee.com/;if(r.test(e)){return e.replace(r,"gitee.com/-/ide/project")+"/edit"+`/${s}/-/`+(i?i.replace(n.b,"")+"/":"")+a}return(n.j.test(e)?e:"https://github.com/"+e).replace(n.b,"")+"/edit"+`/${s}/`+(i?i.replace(n.b,"")+"/":"")+a}}},d=(i(317),i(4)),o=Object(d.a)(r,(function(){var t=this,e=t._self._c;return e("div",{staticClass:"page-edit"},[t.editLink?e("div",{staticClass:"edit-link"},[e("a",{attrs:{href:t.editLink,target:"_blank",rel:"noopener noreferrer"}},[t._v(t._s(t.editLinkText))]),t._v(" "),e("OutboundLink")],1):t._e(),t._v(" "),!1!==t.$themeConfig.tag&&t.tags&&t.tags[0]?e("div",{staticClass:"tags"},t._l(t.tags,(function(i,s){return e("router-link",{key:s,attrs:{to:"/tags/?tag="+encodeURIComponent(i),title:"标签"}},[t._v("#"+t._s(i))])})),1):t._e(),t._v(" "),t.lastUpdated?e("div",{staticClass:"last-updated"},[e("span",{staticClass:"prefix"},[t._v(t._s(t.lastUpdatedText)+":")]),t._v(" "),e("span",{staticClass:"time"},[t._v(t._s(t.lastUpdated))])]):t._e()])}),[],!1,null,null,null);e.default=o.exports}}]); \ No newline at end of file diff --git a/assets/js/2.4938589e.js b/assets/js/2.4938589e.js new file mode 100644 index 0000000000..7fee6ff9d0 --- /dev/null +++ b/assets/js/2.4938589e.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[2,16,19,20,23,30],{278:function(t,e){t.exports=function(t){return null==t}},281:function(t,e,a){},285:function(t,e,a){},294:function(t,e,a){},295:function(t,e,a){},296:function(t,e,a){},303:function(t,e,a){"use strict";e.a={data:()=>({badges:["data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAYAAAA7MK6iAAAAAXNSR0IArs4c6QAABGpJREFUSA3tVVtoXFUU3fvOI53UlmCaKIFmwEhsE7QK0ipFEdHEKpXaZGrp15SINsXUWvBDpBgQRKi0+KKoFeJHfZA+ED9KKoIU2gYD9UejTW4rVIzm0VSTziPzuNu1z507dibTTjL4U/DAzLn3nL3X2o91ziX6f9wMFdh6Jvbm9nNSV0msViVO6tN1Rm7NMu2OpeJ9lWBUTDxrJbYTS0hInuwciu9eLHlFxCLCZEk3MegsJmZ5K/JD6t7FkFdEvGUo1g7qJoG3MHImqRIn8/nzY1K9UPKKiJmtnUqHVE3Gbuay6vJE/N2FEmuxFjW2nUuE0yQXRRxLiTUAzs36zhZvOXJPdX850EVnnLZkB8prodQoM5JGj7Xk2mvC7JB8tG04Ef5PiXtG0UtxupRQSfTnBoCy554x18yJHI6I+G5Eru4LHmPJZEQsrvPUbMiA8G/WgMK7w7I+ez7++o2ANfbrjvaOl1tFMs+htG3IrZH9/hDX1Pr8Tc0UvH8tcX29KzAgIGcEkINyW5BF9x891hw6VYqgJHEk0huccS7vh3C6gTiODL+26huuBtbct8eZnqLML8PkxGYpuPZBqtqwkSjgc4mB5gbgig5i+y0UDK35LMxXisn9xQtK+nd26gTIHsHe/oblK/b29fUmN/8Y+9jAQrnBp56m1LcDlDp9irKTExSKduXJVWSqdBMA08pEJnEIOB3FPPMybu/oeV8zFeYN3xx576Q6RH+VmplE4ncQV5v+5rzSoyOU7PuEAg8g803PwBJ0CExno/jcMbN8tONYeOmHiuUNryvm3fRUy4tMPVLdAGkUhNWuggGrJcXPv+ouCjz0MKUHz1J2/E8IC9nqTabcxgaBYM0hPhD5Y65FsbxRQKxCQrDjDctW7PUM3HuZunFyifSAqEfuzCp48Il24luWUWZoyJCaPR82jE0+kFA643wRFVni4RYSq3ohJO2pZ7B5dO4xkDWbEpossJPLSrPjYID8rS2UHTlvyNxqIGsg674XJJ7vnh5L7PNwC4hh2sjCI96mzszOTpxLF0T7l88Yz7lAuK6OnL8gXLOnTvpzSb22YG8W7us3jSebFHeeqnXRG1vt+MoUM84LQIBmMsCTAcOauTh0T0l0neQK7m2bLMt2mGxU3HYssS0J2cdv5wljlPsrIuZLAG/2DOZIXgCYT8uMGZN+e2kSirfxZOPCsC0f24nTZzspnVn9VePS1Z5vubmAGGXG8ZFno9Hel0yfA5ZPhF7Dh972BQJ2qCpgH67lmWtBYbvk6sz02wjky2vXyz0XErP/kFB619js1BtwfOV4OPRqOQBjy3Qbk18vigUPPSD5ceHnwck7W9bhAqZdd7SuG7w4/P2F/GaJh8c7e9qgow+Q7cGBo+98WsLkuktFqiZabtXuQTu/Y5ETbR0v7tNSFnvrmu6pjdoan2KjMu8q/Hmj1EfCO2ZGfEIbIXKUlw8qaX9/b2oeSJmFksSeT/Fn0V3nSypChh4Gjh74ybO9aeZ/AN2dwciu2/MhAAAAAElFTkSuQmCC","data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAYAAAA7MK6iAAAAAXNSR0IArs4c6QAABH1JREFUSA3tVl1oHFUUPmdmd2ltklqbpJDiNnXFmgbFktho7YMPNiJSSZM0+CAYSkUELVhM6YuwIPpgoOKDqOBDC0XE2CQoNtQXBUFTTcCi+Wlh1V2TQExsUzcltd3M9Tt3ZjZzZ2fT+OJTL8yeM+eee757fmeJbq//KQL8X3DUSFOcfr7cRsRtxNQMWueeVzOkaITIGqQHNg5y8+jNW9ldM7A6nTpAjuolUikAwq7CE3WcM2RRDz+XGVgN3FptU/aUSlvq9Pa3iZ1+sgAqJyyAFqkipd9dqiwHF3P65YycLWc/6sqGrvoEoIp6DOFaX5h6+dnfjkWprwqsPk0dUGq5vySwDImC10KxFHgGL1SWoc92O3eVht09qdXNH11I2SsTsJYqMWzihqGMi+A+Garf3BAuuLI5oGlULyNfyB/HYNujwktOfRrMr5t77NmevqaUopx0grnKAyvVpmwUDB4x6FPXuGvYLTDwWsejwgtgkYKPqRJg8SV6xaiZ3ZTppGneS4yfH5/66fZSDHv+QZci/+h5c5UHtpy67JUqGppM0sh0Nc1dW6/N1W5Yoqat8/TU/VnadmdeW2PLLSyh0cvxBs3KbqTmwYPpxN4do/mzE8nEpvX/UMu2Wbp74zUAK5q6WkHns7V0eWkdPbPzd3rxkTGybadYySumVzhcaJFbs5UrEkQ/+CK8gF5dnh/6ciIZ73gwQ927L1IitoxKLXYP3SjYdOrHHfTZhRRlFyrorafPk20B3HPD1y2G3qKZME5Jcf3t/HUC13/8tSd++vqFveMUTwAUxSUFI1QekR1+bIze3D9MF2aq6cPvG72CgnldWCFqyRw3lwH8ZMerjTD9ElRO7Gv44wNpC90aASqGfVlz/Rx17srQ57/UU26hkhQqUB7dBR71WmzQhHUnblGmVOEw0jhbV1n9OlXUDCIRGaNV5Jp43N516fN7JmnTHdfp7Hgy0luO4aMhtkLL8Bi3bUWYvzh5Mn1dTxrL6QmGuRhGL/TiTTxRoEdTszSaq9GR0NGA3KdkOz3hqSV3MIDhQ5IVX/Ivx3umBti2es2h4eZby7x8br1rkf7Mo90AqC8aQ3sJeNzqFRu+vSANAQe3PL7l0HGOAdwDCeZYvNKeoZp1Qfs6Aipndh86HmFRi0LAnEO47wsqM6cdfjh3jBPUzhZy7nvlUfFsamED1VQt6aISHVymXZ/B2aCtIG8AI8xfobj2d3en1wWVhOeHELKmLQ1s211s88comkv4UCwWyF787mJdYXtNfhKAXVqnKTq8QZvGAGGOfaTo5pGZ/PwbUCr5+DPr/1J92JNHr9aOl/F3iI5+O1nfybsGxoimvZ3ViWSluDITw3P37mypheDIPY0tw7+O/5ApbkYw+zpfaUVu32Pi98+defdUhEpZkRFq0aqyNh9FuL9hpYbEm6iwi0z2REd09ZmyENEbuhjDWzKvZXTqKYaBIr3tt5kuPtQBZFvEUwHt60vfCNu41XsksH9Ij1BMMz1Y0OOunHNShFIP5868g5zeXmuLwL9T4b6Q2+KejgAAAABJRU5ErkJggg==","data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAYAAAA7MK6iAAAAAXNSR0IArs4c6QAABKFJREFUSA3tVl1oFVcQnrMbrak3QUgkya1akpJYcrUtIqW1JvFBE9LiQ5v6JmJpolbMg32rVrhgoYK0QiMY6i9Y6EMaW5D+xFJaTYItIuK2Kr3+BJNwkxBj05sQY3b3nM6cs2dv9t7NT/vQJw/sndk5M/PNzJkzewGerP+pAmy+ON8lLzUJgA8ZYxYIYZmGYRnctDaWvJJAmTtfP1pvXsBCCPP8QFcCaRkZYACgDZFO4stNIcBCajEOlmmC9XpJ9bAGCaPaPmzPl32dvLSVu3BWCTQs0XQQ6g0DYgwLIoAZbBCdW/i+781o1VVlm/410mw4h06Y7bIPHNyWDyL4FHkX03Q8SrzNhZTZriieckWt7cL6MM85YcLpsi/7O9/iXFT6MswI0DmmpkSaJ0qLxFIm3+i1THHB3zmBH3PYx9CcykcLOeQVVa7QtdxTgQgEleX2AjHYfwA+2ddV77ruGoJUbhGDI09YSNXyMpUt5ylOzxgbUmtOp7NmbNt8v3arjTBfYELmLUV+M+nSawNNAUqpT3ClJWg5I3BLT+cGW/DXNGCa6tx1aakCGEigArTn4TDIPdrXXYKCZNrHLMCOEPvHBlLQ99s9eHB7EB6NTki73CVPQ2F5MSx/uRQixfmq7rK0wYD8w8E905bnPDfwoWs/rfv93NWN/ZfvwsLIU7A09gxECyISeGJkHAau98L97tuw7NXnoPyNF8FcYGLGKsOs0mN3OEyec9esGW/ZEl945dTP34wlR2FZVQWU1q0Cw8Tr7p+hgLLNL0FPxx/Q35mA8aEUrH6nCgwEl0tn7wUiZYJnNRh6DK4UH/k0lfyrsBKdPVv/AriGIQcEDQZ65LBAGe2Rzui9Ybjz7XUppz1/uKBbyVPGkN3ZAeC6hr0x7Nr38N5+EqkoOm17xpoqR9ohQF55ERSvr4Dkr3chNfC3DMzGJlNBElW8w9nsGQvhNGIzDkXzCg8cLK951xHsFBlTJspJNi3ZFIMF2AeDV3q8DNOB+YHi6QTrChDIWDBRi5U5f+ZMfJLu3ccrqxtdxk4SKH336LFxSmkqefwU5T8fhdSdQf9IVKD6aNiwI/hnmcAZ91isYMJIaCUCx9W098+LgruikeTqzqqxKPUwqJyCPJiyemVVZBOijDGjD38Os0jOiSPL1z3SPjXNANbiNPXAdzTfukjjuknNBbyz3nwgTd3AVFqUJ5hpHlq9MveLnWwttUfoygBmvVjuikxND3znrhsELnZk7k+OjIGxeNEkomyLVta0xxn+HZhjBc4YZ/AFjHjz9u3xRZl2BN4aq9nFwWh16IrQ1aHHEd3j1+4/dB9OtH4e29A2H1DyHQRmOSfQZ1Fy7MHBTGB6J/Djq6p3OxyO2cB+4Car7v/o3GXgfAkj23+x9ID1Teoamo/SXcbvSf2PX7Vc8DdCmE1vN9di+32P9/5YR3vLnhCVGUWBjEkr3yh4H8v9CzmsbdhzOKzsJKM90iFdaTMjRPhGVsakRvOaRidljo6H6G7j+ctrJpsP+4COhDIl0La2+FS4+5mlocBaXY5QnGZysIBYoeSsl5qQzrSj/cgNrfuEzlWBfwA+EjrZyWUvpAAAAABJRU5ErkJggg=="],currentBadge:""}),created(){this.$themeConfig.titleBadgeIcons&&(this.badges=this.$themeConfig.titleBadgeIcons),this.currentBadge=this.getBadge()},watch:{"$route.path"(){this.currentBadge=this.getBadge()}},methods:{getBadge(){return this.badges[Math.floor(Math.random()*this.badges.length)]}}}},308:function(t,e,a){"use strict";a(281)},312:function(t,e,a){"use strict";a(285)},317:function(t,e,a){"use strict";a(294)},318:function(t,e,a){var s=a(13),i=a(5),n=a(12);t.exports=function(t){return"string"==typeof t||!i(t)&&n(t)&&"[object String]"==s(t)}},319:function(t,e,a){"use strict";a(295)},320:function(t,e,a){"use strict";a(296)},326:function(t,e,a){},332:function(t,e,a){"use strict";a.r(e);a(25);var s={data:()=>({date:"",classify1:"",classifyList:[],cataloguePermalink:"",author:null,categories:[]}),created(){this.getPageInfo()},watch:{"$route.path"(){this.classifyList=[],this.getPageInfo()}},methods:{getPageInfo(){const t=this.$page,{relativePath:e}=t,{sidebar:a}=this.$themeConfig,s=e.split("/");s.forEach((t,e)=>{const a=t.split(".");if(e!==s.length-1)if(1===a)this.classifyList.push(a[0]);else{const e=t.indexOf(".");this.classifyList.push(t.substring(e+1)||"")}}),this.classify1=this.classifyList[0];const i=a&&a.catalogue?a.catalogue[this.classify1]:"",n=this.$frontmatter.author||this.$themeConfig.author;let r=(t.frontmatter.date||"").split(" ")[0];const{categories:o}=this.$frontmatter;this.date=r,this.cataloguePermalink=i,this.author=n,this.categories=o},getLink(t){const{cataloguePermalink:e}=this;return t===e?e:`${e}${"/"===e.charAt(e.length-1)?"":"/"}#${t}`}}},i=(a(308),a(4)),n=Object(i.a)(s,(function(){var t=this,e=t._self._c;return e("div",{staticClass:"articleInfo-wrap"},[e("div",{staticClass:"articleInfo"},[t.classify1&&"_posts"!==t.classify1?e("ul",{staticClass:"breadcrumbs"},[e("li",[e("router-link",{staticClass:"iconfont icon-home",attrs:{to:"/",title:"首页"}})],1),t._v(" "),t._l(t.classifyList,(function(a){return e("li",{key:a},[t.cataloguePermalink?e("router-link",{attrs:{to:t.getLink(a)}},[t._v(t._s(a))]):!1!==t.$themeConfig.category?e("router-link",{attrs:{to:"/categories/?category="+encodeURIComponent(a),title:"分类"}},[t._v(t._s(a))]):e("span",[t._v(t._s(a))])],1)}))],2):t._e(),t._v(" "),e("div",{staticClass:"info"},[t.author?e("div",{staticClass:"author iconfont icon-touxiang",attrs:{title:"作者"}},[t.author.href||t.author.link&&"string"==typeof t.author.link?e("a",{staticClass:"beLink",attrs:{href:t.author.href||t.author.link,target:"_blank",title:"作者"}},[t._v(t._s(t.author.name))]):e("a",{attrs:{href:"javascript:;"}},[t._v(t._s(t.author.name||t.author))])]):t._e(),t._v(" "),t.date?e("div",{staticClass:"date iconfont icon-riqi",attrs:{title:"创建时间"}},[e("a",{attrs:{href:"javascript:;"}},[t._v(t._s(t.date))])]):t._e(),t._v(" "),!1===t.$themeConfig.category||t.classify1&&"_posts"!==t.classify1||!t.categories?t._e():e("div",{staticClass:"date iconfont icon-wenjian",attrs:{title:"分类"}},t._l(t.categories,(function(a,s){return e("router-link",{key:s,attrs:{to:"/categories/?category="+encodeURIComponent(a)}},[t._v(t._s(a+" "))])})),1)])])])}),[],!1,null,"06225672",null);e.default=n.exports},336:function(t,e,a){"use strict";a.r(e);var s={data:()=>({pageData:null,isStructuring:!0,appointDir:{}}),created(){this.getPageData();const t=this.$themeConfig.sidebar;t&&"auto"!==t||(this.isStructuring=!1,console.error("目录页数据依赖于结构化的侧边栏数据,请在主题设置中将侧边栏字段设置为'structuring',否则无法获取目录数据。"))},methods:{getPageData(){const t=this.$frontmatter.pageComponent;t&&t.data?this.pageData={...t.data,title:this.$frontmatter.title}:console.error("请在front matter中设置pageComponent和pageComponent.data数据")},getCatalogueList(){const{sidebar:t}=this.$site.themeConfig,{data:e}=this.$frontmatter.pageComponent;let a=(e.path||e.key).split("/"),s=t[`/${a[0]}/`];return a.length>1&&(a.shift(),s=this.appointDirDeal(0,a,s)),s||console.error("未获取到目录数据,请查看front matter中设置的path是否正确。"),s},type:t=>Object.prototype.toString.call(t).match(/\[object (.*?)\]/)[1].toLowerCase(),appointDirDeal(t,e,a){let s=e[t];void 0!==s&&-1!==s.indexOf(".")&&(s=s.substring(s.indexOf(".")+1));for(let i=0;it,getPageLinkConfig:({frontmatter:t})=>t.next},PREV:{resolveLink:function(t,e){return u(t,e,-1)},getThemeLinkConfig:({prevLinks:t})=>t,getPageLinkConfig:({frontmatter:t})=>t.prev}};function h(t,{$themeConfig:e,$page:a,$route:i,$site:r,sidebarItems:l}){const{resolveLink:c,getThemeLinkConfig:h,getPageLinkConfig:u}=t,g=h(e),p=u(a),d=o()(p)?g:p;return!1===d?void 0:n()(d)?Object(s.l)(r.pages,d,i.path):c(a,l)}function u(t,e,a){const s=[];!function t(e,a){for(let s=0,i=e.length;s({headers:[],hashText:""}),mounted(){this.getHeadersData(),this.getHashText()},watch:{$route(){this.headers=this.$page.headers,this.getHashText()}},methods:{getHeadersData(){this.headers=this.$page.headers},getHashText(){this.hashText=decodeURIComponent(window.location.hash.slice(1))}}},i=(a(320),a(4)),n=Object(i.a)(s,(function(){var t=this,e=t._self._c;return e("div",{staticClass:"right-menu-wrapper"},[e("div",{staticClass:"right-menu-margin"},[e("div",{staticClass:"right-menu-title"},[t._v("目录")]),t._v(" "),e("div",{staticClass:"right-menu-content"},t._l(t.headers,(function(a,s){return e("div",{key:s,class:["right-menu-item","level"+a.level,{active:a.slug===t.hashText}]},[e("a",{attrs:{href:"#"+a.slug}},[t._v(t._s(a.title))])])})),0)])])}),[],!1,null,null,null);e.default=n.exports},350:function(t,e,a){"use strict";a(326)},356:function(t,e,a){"use strict";a.r(e);var s=a(339),i=a(340),n=a(332),r=a(336),o=a(305),l=a(341),c={mixins:[a(303).a],data:()=>({updateBarConfig:null}),props:["sidebarItems"],components:{PageEdit:s.default,PageNav:i.default,ArticleInfo:n.default,Catalogue:r.default,UpdateArticle:o.default,RightMenu:l.default},created(){this.updateBarConfig=this.$themeConfig.updateBar},computed:{bgStyle(){const{contentBgStyle:t}=this.$themeConfig;return t?"bg-style-"+t:""},isShowUpdateBar(){return!this.updateBarConfig||!1!==this.updateBarConfig.showToArticle},showTitle(){return!this.$frontmatter.pageComponent},showRightMenu(){const{$frontmatter:t,$themeConfig:e,$page:a}=this,{sidebar:s}=t;return!1!==e.rightMenuBar&&a.headers&&!1!==(t&&s&&!1!==s)},pageComponent(){return!!this.$frontmatter.pageComponent&&this.$frontmatter.pageComponent.name},isShowSlotT(){return this.getShowStatus("pageTshowMode")},isShowSlotB(){return this.getShowStatus("pageBshowMode")}},methods:{getShowStatus(t){const{htmlModules:e}=this.$themeConfig;return!!e&&("article"===e[t]?this.isArticle():"custom"!==e[t]||!this.isArticle())},isArticle(){return!1!==this.$frontmatter.article}}},h=(a(350),a(4)),u=Object(h.a)(c,(function(){var t=this,e=t._self._c;return e("div",[e("main",{staticClass:"page"},[e("div",{class:"theme-vdoing-wrapper "+t.bgStyle},[t.isArticle()?e("ArticleInfo"):e("div",{staticClass:"placeholder"}),t._v(" "),t.pageComponent?e(t.pageComponent,{tag:"component",staticClass:"theme-vdoing-content"}):t._e(),t._v(" "),e("div",{staticClass:"content-wrapper"},[t.showRightMenu?e("RightMenu"):t._e(),t._v(" "),t.showTitle?e("h1",[!1!==t.$themeConfig.titleBadge?e("img",{attrs:{src:t.currentBadge}}):t._e(),t._v(t._s(this.$page.title)),t.$frontmatter.titleTag?e("span",{staticClass:"title-tag"},[t._v(t._s(t.$frontmatter.titleTag))]):t._e()]):t._e(),t._v(" "),t.isShowSlotT?t._t("top"):t._e(),t._v(" "),e("Content",{staticClass:"theme-vdoing-content"})],2),t._v(" "),t.isShowSlotB?t._t("bottom"):t._e(),t._v(" "),e("PageEdit"),t._v(" "),e("PageNav",t._b({},"PageNav",{sidebarItems:t.sidebarItems},!1))],2),t._v(" "),t.isShowUpdateBar?e("UpdateArticle",{attrs:{length:3,moreArticle:t.updateBarConfig&&t.updateBarConfig.moreArticle}}):t._e()],1)])}),[],!1,null,null,null);e.default=u.exports}}]); \ No newline at end of file diff --git a/assets/js/20.38b68893.js b/assets/js/20.38b68893.js new file mode 100644 index 0000000000..a520c17e18 --- /dev/null +++ b/assets/js/20.38b68893.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[20],{281:function(t,s,a){},308:function(t,s,a){"use strict";a(281)},332:function(t,s,a){"use strict";a.r(s);a(25);var i={data:()=>({date:"",classify1:"",classifyList:[],cataloguePermalink:"",author:null,categories:[]}),created(){this.getPageInfo()},watch:{"$route.path"(){this.classifyList=[],this.getPageInfo()}},methods:{getPageInfo(){const t=this.$page,{relativePath:s}=t,{sidebar:a}=this.$themeConfig,i=s.split("/");i.forEach((t,s)=>{const a=t.split(".");if(s!==i.length-1)if(1===a)this.classifyList.push(a[0]);else{const s=t.indexOf(".");this.classifyList.push(t.substring(s+1)||"")}}),this.classify1=this.classifyList[0];const e=a&&a.catalogue?a.catalogue[this.classify1]:"",o=this.$frontmatter.author||this.$themeConfig.author;let r=(t.frontmatter.date||"").split(" ")[0];const{categories:n}=this.$frontmatter;this.date=r,this.cataloguePermalink=e,this.author=o,this.categories=n},getLink(t){const{cataloguePermalink:s}=this;return t===s?s:`${s}${"/"===s.charAt(s.length-1)?"":"/"}#${t}`}}},e=(a(308),a(4)),o=Object(e.a)(i,(function(){var t=this,s=t._self._c;return s("div",{staticClass:"articleInfo-wrap"},[s("div",{staticClass:"articleInfo"},[t.classify1&&"_posts"!==t.classify1?s("ul",{staticClass:"breadcrumbs"},[s("li",[s("router-link",{staticClass:"iconfont icon-home",attrs:{to:"/",title:"首页"}})],1),t._v(" "),t._l(t.classifyList,(function(a){return s("li",{key:a},[t.cataloguePermalink?s("router-link",{attrs:{to:t.getLink(a)}},[t._v(t._s(a))]):!1!==t.$themeConfig.category?s("router-link",{attrs:{to:"/categories/?category="+encodeURIComponent(a),title:"分类"}},[t._v(t._s(a))]):s("span",[t._v(t._s(a))])],1)}))],2):t._e(),t._v(" "),s("div",{staticClass:"info"},[t.author?s("div",{staticClass:"author iconfont icon-touxiang",attrs:{title:"作者"}},[t.author.href||t.author.link&&"string"==typeof t.author.link?s("a",{staticClass:"beLink",attrs:{href:t.author.href||t.author.link,target:"_blank",title:"作者"}},[t._v(t._s(t.author.name))]):s("a",{attrs:{href:"javascript:;"}},[t._v(t._s(t.author.name||t.author))])]):t._e(),t._v(" "),t.date?s("div",{staticClass:"date iconfont icon-riqi",attrs:{title:"创建时间"}},[s("a",{attrs:{href:"javascript:;"}},[t._v(t._s(t.date))])]):t._e(),t._v(" "),!1===t.$themeConfig.category||t.classify1&&"_posts"!==t.classify1||!t.categories?t._e():s("div",{staticClass:"date iconfont icon-wenjian",attrs:{title:"分类"}},t._l(t.categories,(function(a,i){return s("router-link",{key:i,attrs:{to:"/categories/?category="+encodeURIComponent(a)}},[t._v(t._s(a+" "))])})),1)])])])}),[],!1,null,"06225672",null);s.default=o.exports}}]); \ No newline at end of file diff --git a/assets/js/21.e59a9fa2.js b/assets/js/21.e59a9fa2.js new file mode 100644 index 0000000000..24ad554d37 --- /dev/null +++ b/assets/js/21.e59a9fa2.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[21],{282:function(s,t,a){},309:function(s,t,a){"use strict";a(282)},333:function(s,t,a){"use strict";a.r(t);var i={computed:{blogger(){return this.$themeConfig.blogger},social(){return this.$themeConfig.social}}},l=(a(309),a(4)),n=Object(l.a)(i,(function(){var s=this,t=s._self._c;return t("aside",{staticClass:"blogger-wrapper card-box"},[t("div",{staticClass:"avatar"},[t("img",{attrs:{src:s.blogger.avatar,alt:"头像",title:"我好看吗"}})]),s._v(" "),s.social&&s.social.icons&&s.social.icons.length?t("div",{staticClass:"icons"},s._l(s.social.icons,(function(a,i){return t("a",{key:i,class:["iconfont",a.iconClass],style:{width:100/s.social.icons.length+"%"},attrs:{href:a.link,title:a.title,target:"_blank"}})})),0):s._e(),s._v(" "),t("div",{staticClass:"blogger"},[t("span",{staticClass:"name"},[s._v(s._s(s.blogger.name))]),s._v(" "),t("span",{staticClass:"slogan"},[s._v(s._s(s.blogger.slogan))])])])}),[],!1,null,null,null);t.default=n.exports}}]); \ No newline at end of file diff --git a/assets/js/22.ba3d4daa.js b/assets/js/22.ba3d4daa.js new file mode 100644 index 0000000000..5afab638ee --- /dev/null +++ b/assets/js/22.ba3d4daa.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[22],{283:function(t,e,n){},310:function(t,e,n){"use strict";n(283)},334:function(t,e,n){"use strict";n.r(e);var i=n(11),s={data:()=>({bgImg:"",opacity:.5}),mounted(){let{bodyBgImg:t,bodyBgImgOpacity:e,bodyBgImgInterval:n=15}=this.$themeConfig;if("string"===Object(i.n)(t))this.bgImg=t;else if("array"===Object(i.n)(t)){let e=0,i=null;this.bgImg=t[e],clearInterval(i),i=setInterval(()=>{if(++e>=t.length&&(e=0),this.bgImg=t[e],t[e+1]){(new Image).src=t[e+1]}},1e3*n)}void 0!==e&&(this.opacity=e)}},c=(n(310),n(4)),a=Object(c.a)(s,(function(){return(0,this._self._c)("div",{staticClass:"body-bg",style:`background: url(${this.bgImg}) center center / cover no-repeat;opacity:${this.opacity}`})}),[],!1,null,null,null);e.default=a.exports}}]); \ No newline at end of file diff --git a/assets/js/23.5330affd.js b/assets/js/23.5330affd.js new file mode 100644 index 0000000000..aa7f9e6d6c --- /dev/null +++ b/assets/js/23.5330affd.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[23],{285:function(t,a,e){},312:function(t,a,e){"use strict";e(285)},336:function(t,a,e){"use strict";e.r(a);var s={data:()=>({pageData:null,isStructuring:!0,appointDir:{}}),created(){this.getPageData();const t=this.$themeConfig.sidebar;t&&"auto"!==t||(this.isStructuring=!1,console.error("目录页数据依赖于结构化的侧边栏数据,请在主题设置中将侧边栏字段设置为'structuring',否则无法获取目录数据。"))},methods:{getPageData(){const t=this.$frontmatter.pageComponent;t&&t.data?this.pageData={...t.data,title:this.$frontmatter.title}:console.error("请在front matter中设置pageComponent和pageComponent.data数据")},getCatalogueList(){const{sidebar:t}=this.$site.themeConfig,{data:a}=this.$frontmatter.pageComponent;let e=(a.path||a.key).split("/"),s=t[`/${e[0]}/`];return e.length>1&&(e.shift(),s=this.appointDirDeal(0,e,s)),s||console.error("未获取到目录数据,请查看front matter中设置的path是否正确。"),s},type:t=>Object.prototype.toString.call(t).match(/\[object (.*?)\]/)[1].toLowerCase(),appointDirDeal(t,a,e){let s=a[t];void 0!==s&&-1!==s.indexOf(".")&&(s=s.substring(s.indexOf(".")+1));for(let i=0;ia-3?a-2:t,e},goPrex(){let e=this.currentPage;e>1&&this.handleEmit(--e)},goNext(){let e=this.currentPage;e3,expression:"currentPage > 3"}],staticClass:"ellipsis ell-two",attrs:{title:"上两页"},on:{click:function(t){return e.goIndex(e.currentPage-2)}}}),e._v(" "),t("span",{directives:[{name:"show",rawName:"v-show",value:e.currentPage<=3,expression:"currentPage <= 3"}],staticClass:"card-box",class:{active:2===e.currentPage},on:{click:function(t){return e.goIndex(2)}}},[e._v("2")]),e._v(" "),t("span",{staticClass:"card-box",class:{active:e.currentPage>=3&&e.currentPage<=e.pages-2},on:{click:function(t){e.goIndex(e.threeNum())}}},[e._v(e._s(e.threeNum()))]),e._v(" "),t("span",{directives:[{name:"show",rawName:"v-show",value:e.currentPage=e.pages-2,expression:"currentPage >= pages - 2"}],staticClass:"card-box",class:{active:e.currentPage===e.pages-1},on:{click:function(t){return e.goIndex(e.pages-1)}}},[e._v(e._s(e.pages-1))]),e._v(" "),t("span",{staticClass:"card-box",class:{active:e.currentPage===e.pages},on:{click:function(t){return e.goIndex(e.pages)}}},[e._v(e._s(e.pages))])]),e._v(" "),t("span",{staticClass:"card-box next iconfont icon-jiantou-you",class:{disabled:e.currentPage===e.pages},on:{click:function(t){return e.goNext()}}},[t("p",[e._v("下一页")])])])}),[],!1,null,null,null);t.default=r.exports},273:function(e,t,a){"use strict";a(258)}}]); \ No newline at end of file diff --git a/assets/js/29.be2fe3f7.js b/assets/js/29.be2fe3f7.js new file mode 100644 index 0000000000..6a241adfc1 --- /dev/null +++ b/assets/js/29.be2fe3f7.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[29],{257:function(t,s,e){},267:function(t,s,e){"use strict";e.r(s);e(25);var a={props:{category:{type:String,default:""},tag:{type:String,default:""},currentPage:{type:Number,default:1},perPage:{type:Number,default:10}},data:()=>({sortPosts:[],postListOffsetTop:0}),created(){this.setPosts()},mounted(){},watch:{currentPage(){this.$route.query.p!=this.currentPage&&this.$router.push({query:{...this.$route.query,p:this.currentPage}}),this.setPosts()},category(){this.setPosts()},tag(){this.setPosts()}},methods:{setPosts(){const t=this.currentPage,s=this.perPage;let e=[];e=this.category?this.$groupPosts.categories[this.category]:this.tag?this.$groupPosts.tags[this.tag]:this.$sortPosts,this.sortPosts=e.slice((t-1)*s,t*s)}}},r=(e(272),e(4)),o=Object(r.a)(a,(function(){var t=this,s=t._self._c;return s("div",{ref:"postList",staticClass:"post-list"},[s("transition-group",{attrs:{tag:"div",name:"post"}},t._l(t.sortPosts,(function(e){return s("div",{key:e.key,staticClass:"post card-box",class:e.frontmatter.sticky&&"iconfont icon-zhiding"},[s("div",{staticClass:"title-wrapper"},[s("h2",[s("router-link",{attrs:{to:e.path}},[t._v("\n "+t._s(e.title)+"\n "),e.frontmatter.titleTag?s("span",{staticClass:"title-tag"},[t._v(t._s(e.frontmatter.titleTag))]):t._e()])],1),t._v(" "),s("div",{staticClass:"article-info"},[e.author&&e.author.href?s("a",{staticClass:"iconfont icon-touxiang",attrs:{title:"作者",target:"_blank",href:e.author.href}},[t._v(t._s(e.author.name?e.author.name:e.author))]):e.author?s("span",{staticClass:"iconfont icon-touxiang",attrs:{title:"作者"}},[t._v(t._s(e.author.name?e.author.name:e.author))]):t._e(),t._v(" "),e.frontmatter.date?s("span",{staticClass:"iconfont icon-riqi",attrs:{title:"创建时间"}},[t._v(t._s(e.frontmatter.date.split(" ")[0]))]):t._e(),t._v(" "),!1!==t.$themeConfig.category&&e.frontmatter.categories?s("span",{staticClass:"iconfont icon-wenjian",attrs:{title:"分类"}},t._l(e.frontmatter.categories,(function(e,a){return s("router-link",{key:a,attrs:{to:"/categories/?category="+encodeURIComponent(e)}},[t._v(t._s(e))])})),1):t._e(),t._v(" "),!1!==t.$themeConfig.tag&&e.frontmatter.tags&&e.frontmatter.tags[0]?s("span",{staticClass:"iconfont icon-biaoqian tags",attrs:{title:"标签"}},t._l(e.frontmatter.tags,(function(e,a){return s("router-link",{key:a,attrs:{to:"/tags/?tag="+encodeURIComponent(e)}},[t._v(t._s(e))])})),1):t._e()])]),t._v(" "),e.excerpt?s("div",{staticClass:"excerpt-wrapper"},[s("div",{staticClass:"excerpt",domProps:{innerHTML:t._s(e.excerpt)}}),t._v(" "),s("router-link",{staticClass:"readmore iconfont icon-jiantou-you",attrs:{to:e.path}},[t._v("阅读全文")])],1):t._e()])})),0)],1)}),[],!1,null,null,null);s.default=o.exports},272:function(t,s,e){"use strict";e(257)}}]); \ No newline at end of file diff --git a/assets/js/3.c591ef2f.js b/assets/js/3.c591ef2f.js new file mode 100644 index 0000000000..36932d9804 --- /dev/null +++ b/assets/js/3.c591ef2f.js @@ -0,0 +1,9 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[3,4,18,22,25,26,31,32],{251:function(t,n,e){},253:function(t,n,e){},254:function(t,n,e){"use strict";e.r(n);var r={name:"DropdownTransition",methods:{setHeight(t){t.style.height=t.scrollHeight+"px"},unsetHeight(t){t.style.height=""}}},i=(e(255),e(4)),o=Object(i.a)(r,(function(){return(0,this._self._c)("transition",{attrs:{name:"dropdown"},on:{enter:this.setHeight,"after-enter":this.unsetHeight,"before-leave":this.setHeight}},[this._t("default")],2)}),[],!1,null,null,null);n.default=o.exports},255:function(t,n,e){"use strict";e(251)},259:function(t,n,e){},260:function(t,n,e){},261:function(t,n,e){"use strict";e(253)},265:function(t,n,e){},266:function(t,n,e){},269:function(t,n,e){"use strict";e.r(n);var r=e(252),i=e(254),o=e(97),u=e.n(o),a={components:{NavLink:r.default,DropdownTransition:i.default},data:()=>({open:!1,isMQMobile:!1}),props:{item:{required:!0}},computed:{dropdownAriaLabel(){return this.item.ariaLabel||this.item.text}},beforeMount(){this.isMQMobile=window.innerWidth<720,window.addEventListener("resize",()=>{this.isMQMobile=window.innerWidth<720})},methods:{toggle(){this.isMQMobile&&(this.open=!this.open)},isLastItemOfArray:(t,n)=>u()(n)===t},watch:{$route(){this.open=!1}}},s=(e(261),e(4)),c=Object(s.a)(a,(function(){var t=this,n=t._self._c;return n("div",{staticClass:"dropdown-wrapper",class:{open:t.open}},[n("button",{staticClass:"dropdown-title",attrs:{type:"button","aria-label":t.dropdownAriaLabel},on:{click:t.toggle}},[t.item.link?n("router-link",{staticClass:"link-title",attrs:{to:t.item.link}},[t._v(t._s(t.item.text))]):t._e(),t._v(" "),n("span",{directives:[{name:"show",rawName:"v-show",value:!t.item.link,expression:"!item.link"}],staticClass:"title"},[t._v(t._s(t.item.text))]),t._v(" "),n("span",{staticClass:"arrow",class:t.open?"down":"right"})],1),t._v(" "),n("DropdownTransition",[n("ul",{directives:[{name:"show",rawName:"v-show",value:t.open,expression:"open"}],staticClass:"nav-dropdown"},t._l(t.item.items,(function(e,r){return n("li",{key:e.link||r,staticClass:"dropdown-item"},["links"===e.type?n("h4",[t._v(t._s(e.text))]):t._e(),t._v(" "),"links"===e.type?n("ul",{staticClass:"dropdown-subitem-wrapper"},t._l(e.items,(function(r){return n("li",{key:r.link,staticClass:"dropdown-subitem"},[n("NavLink",{attrs:{item:r},on:{focusout:function(n){t.isLastItemOfArray(r,e.items)&&t.isLastItemOfArray(e,t.item.items)&&t.toggle()}}})],1)})),0):n("NavLink",{attrs:{item:e},on:{focusout:function(n){t.isLastItemOfArray(e,t.item.items)&&t.toggle()}}})],1)})),0)])],1)}),[],!1,null,null,null);n.default=c.exports},274:function(t,n,e){"use strict";e(259)},275:function(t,n,e){"use strict";e(260)},276:function(t,n,e){"use strict";e.r(n);var r=e(269),i=e(11),o={components:{NavLink:e(252).default,DropdownLink:r.default},computed:{userNav(){return this.$themeLocaleConfig.nav||this.$site.themeConfig.nav||[]},nav(){const{locales:t}=this.$site;if(t&&Object.keys(t).length>1){const n=this.$page.path,e=this.$router.options.routes,r=this.$site.themeConfig.locales||{},i={text:this.$themeLocaleConfig.selectText||"Languages",ariaLabel:this.$themeLocaleConfig.ariaLabel||"Select language",items:Object.keys(t).map(i=>{const o=t[i],u=r[i]&&r[i].label||o.lang;let a;return o.lang===this.$lang?a=n:(a=n.replace(this.$localeConfig.path,i),e.some(t=>t.path===a)||(a=i)),{text:u,link:a}})};return[...this.userNav,i]}return this.userNav},userLinks(){return(this.nav||[]).map(t=>Object.assign(Object(i.k)(t),{items:(t.items||[]).map(i.k)}))},repoLink(){const{repo:t}=this.$site.themeConfig;return t?/^https?:/.test(t)?t:"https://github.com/"+t:null},repoLabel(){if(!this.repoLink)return;if(this.$site.themeConfig.repoLabel)return this.$site.themeConfig.repoLabel;const t=this.repoLink.match(/^https?:\/\/[^/]+/)[0],n=["GitHub","GitLab","Bitbucket"];for(let e=0;e"group"===n.type?u(t,n):"page"===n.type&&Object(o.f)(t,n.path))}var a={name:"SidebarLinks",components:{SidebarGroup:r.default,SidebarLink:i.default},props:["items","depth","sidebarDepth","initialOpenGroupIndex"],data(){return{openGroupIndex:this.initialOpenGroupIndex||0}},created(){this.refreshIndex()},watch:{$route(){this.refreshIndex()}},methods:{refreshIndex(){const t=function(t,n){for(let e=0;e-1&&(this.openGroupIndex=t)},toggleGroup(t){this.openGroupIndex=t===this.openGroupIndex?-1:t},isActive(t){return Object(o.f)(this.$route,t.regularPath)}}},s=e(4),c=Object(s.a)(a,(function(){var t=this,n=t._self._c;return t.items.length?n("ul",{staticClass:"sidebar-links"},t._l(t.items,(function(e,r){return n("li",{key:r},["group"===e.type?n("SidebarGroup",{attrs:{item:e,open:r===t.openGroupIndex,collapsable:e.collapsable||e.collapsible,depth:t.depth},on:{toggle:function(n){return t.toggleGroup(r)}}}):n("SidebarLink",{attrs:{sidebarDepth:t.sidebarDepth,item:e}})],1)})),0):t._e()}),[],!1,null,null,null);n.default=c.exports},279:function(t,n,e){"use strict";e.r(n);var r=e(11);function i(t,n,e,r){return t("router-link",{props:{to:n,activeClass:"",exactActiveClass:""},class:{active:r,"sidebar-link":!0}},e)}function o(t,n,e,u,a,s=1){return!n||s>a?null:t("ul",{class:"sidebar-sub-headers"},n.map(n=>{const c=Object(r.f)(u,e+"#"+n.slug);return t("li",{class:"sidebar-sub-header level"+n.level},[i(t,e+"#"+n.slug,n.title,c),o(t,n.children,e,u,a,s+1)])}))}var u={functional:!0,props:["item","sidebarDepth"],render(t,{parent:{$page:n,$site:e,$route:u,$themeConfig:a,$themeLocaleConfig:s},props:{item:c,sidebarDepth:l}}){const f=Object(r.f)(u,c.path),h="auto"===c.type?f||c.children.some(t=>Object(r.f)(u,c.basePath+"#"+t.slug)):f,d="external"===c.type?function(t,n,e){return t("a",{attrs:{href:n,target:"_blank",rel:"noopener noreferrer"},class:{"sidebar-link":!0}},[e,t("OutboundLink")])}(t,c.path,c.title||c.path):i(t,c.path,c.title||c.path,h),v=[n.frontmatter.sidebarDepth,l,s.sidebarDepth,a.sidebarDepth,1].find(t=>void 0!==t),p=s.displayAllHeaders||a.displayAllHeaders;if("auto"===c.type)return[d,o(t,c.children,c.basePath,u,v)];if((h||p)&&c.headers&&!r.e.test(c.path)){return[d,o(t,Object(r.d)(c.headers),c.path,u,v)]}return d}},a=(e(275),e(4)),s=Object(a.a)(u,void 0,void 0,!1,null,null,null);n.default=s.exports},280:function(t,n,e){},283:function(t,n,e){},284:function(t,n,e){},287:function(t,n,e){},288:function(t,n,e){},291:function(t,n,e){},292:function(t,n,e){"use strict";e(265)},293:function(t,n,e){},297:function(t,n,e){"use strict";e(266)},298:function(t,n,e){},299:function(t,n,e){},302:function(t,n,e){"use strict";e.r(n);var r=e(11),i={name:"SidebarGroup",props:["item","open","collapsable","depth"],components:{DropdownTransition:e(254).default},beforeCreate(){this.$options.components.SidebarLinks=e(277).default},methods:{isActive:r.f}},o=(e(297),e(4)),u=Object(o.a)(i,(function(){var t=this,n=t._self._c;return n("section",{staticClass:"sidebar-group",class:[{collapsable:t.collapsable,"is-sub-group":0!==t.depth},"depth-"+t.depth]},[t.item.path?n("router-link",{staticClass:"sidebar-heading clickable",class:{open:t.open,active:t.isActive(t.$route,t.item.path)},attrs:{to:t.item.path},nativeOn:{click:function(n){return t.$emit("toggle")}}},[n("span",[t._v(t._s(t.item.title))]),t._v(" "),t.collapsable?n("span",{staticClass:"arrow",class:t.open?"down":"right"}):t._e()]):n("p",{staticClass:"sidebar-heading",class:{open:t.open},on:{click:function(n){return t.$emit("toggle")}}},[n("span",[t._v(t._s(t.item.title))]),t._v(" "),t.collapsable?n("span",{staticClass:"arrow",class:t.open?"down":"right"}):t._e()]),t._v(" "),n("DropdownTransition",[t.open||!t.collapsable?n("SidebarLinks",{staticClass:"sidebar-group-items",attrs:{items:t.item.children,"sidebar-depth":t.item.sidebarDepth,"initial-open-group-index":t.item.initialOpenGroupIndex,depth:t.depth+1}}):t._e()],1)],1)}),[],!1,null,null,null);n.default=u.exports},304:function(t,n,e){"use strict";var r=Object.assign||function(t){for(var n=1;n({query:"",focused:!1,focusIndex:0,placeholder:void 0}),mounted(){this.placeholder=this.$site.themeConfig.searchPlaceholder||"",document.addEventListener("keydown",this.onHotkey)},beforeDestroy(){document.removeEventListener("keydown",this.onHotkey)},computed:{showSuggestions(){return this.focused&&this.suggestions},suggestions(){const t=this.query.trim().toLowerCase();if(!t)return;const{pages:n}=this.$site,e=this.$site.themeConfig.searchMaxSuggestions||5,r=this.$localePath,i=n=>n&&n.title&&n.title.toLowerCase().indexOf(t)>-1,o=[];for(let t=0;t=e);t++){const u=n[t];if(this.getPageLocalePath(u)===r&&this.isSearchable(u))if(i(u))o.push(u);else if(u.headers)for(let t=0;t=e);t++){const n=u.headers[t];i(n)&&o.push(Object.assign({},u,{path:u.path+"#"+n.slug,header:n}))}}return[{title:"在MDN中搜索",frontUrl:"https://developer.mozilla.org/zh-CN/search?q=",behindUrl:""},{title:"在Runoob中搜索",frontUrl:"https://www.runoob.com/?s="},{title:"在Vue API中搜索",frontUrl:"https://cn.vuejs.org/v2/api/#"},{title:"在Bing中搜索",frontUrl:"https://cn.bing.com/search?q="}].length&&[{title:"在MDN中搜索",frontUrl:"https://developer.mozilla.org/zh-CN/search?q=",behindUrl:""},{title:"在Runoob中搜索",frontUrl:"https://www.runoob.com/?s="},{title:"在Vue API中搜索",frontUrl:"https://cn.vuejs.org/v2/api/#"},{title:"在Bing中搜索",frontUrl:"https://cn.bing.com/search?q="}].forEach(t=>{t.thirdparty=!0,t.title=`${t.title}"${this.query}"`,t.behindUrl=t.behindUrl||"",o.push(t)}),o},alignRight(){return(this.$site.themeConfig.nav||[]).length+(this.$site.repo?1:0)<=2}},methods:{getPageLocalePath(t){for(const n in this.$site.locales||{})if("/"!==n&&0===t.path.indexOf(n))return n;return"/"},isSearchable(t){let n=null;return null===n||(n=Array.isArray(n)?n:new Array(n),n.filter(n=>t.path.match(n)).length>0)},onHotkey(t){t.srcElement===document.body&&["s","/"].includes(t.key)&&(this.$refs.input.focus(),t.preventDefault())},onUp(){this.showSuggestions&&(this.focusIndex>0?this.focusIndex--:this.focusIndex=this.suggestions.length-1)},onDown(){this.showSuggestions&&(this.focusIndex "+t._s(e.header.title))]):t._e()])])})),0):t._e()])}),[],!1,null,null,null).exports,u=e(306),a=e(276);function s(t,n){return t.ownerDocument.defaultView.getComputedStyle(t,null)[n]}var c={components:{SidebarButton:u.default,NavLinks:a.default,SearchBox:o,AlgoliaSearchBox:{}},data:()=>({linksWrapMaxWidth:null}),mounted(){const t=parseInt(s(this.$el,"paddingLeft"))+parseInt(s(this.$el,"paddingRight")),n=()=>{document.documentElement.clientWidth<719?this.linksWrapMaxWidth=null:this.linksWrapMaxWidth=this.$el.offsetWidth-t-(this.$refs.siteName&&this.$refs.siteName.offsetWidth||0)};n(),window.addEventListener("resize",n,!1)},computed:{algolia(){return this.$themeLocaleConfig.algolia||this.$site.themeConfig.algolia||{}},isAlgoliaSearch(){return this.algolia&&this.algolia.apiKey&&this.algolia.indexName}}},l=(e(316),Object(i.a)(c,(function(){var t=this,n=t._self._c;return n("header",{staticClass:"navbar blur"},[n("SidebarButton",{on:{"toggle-sidebar":function(n){return t.$emit("toggle-sidebar")}}}),t._v(" "),n("router-link",{staticClass:"home-link",attrs:{to:t.$localePath}},[t.$site.themeConfig.logo?n("img",{staticClass:"logo",attrs:{src:t.$withBase(t.$site.themeConfig.logo),alt:t.$siteTitle}}):t._e(),t._v(" "),t.$siteTitle?n("span",{ref:"siteName",staticClass:"site-name",class:{"can-hide":t.$site.themeConfig.logo}},[t._v(t._s(t.$siteTitle))]):t._e()]),t._v(" "),n("div",{staticClass:"links",style:t.linksWrapMaxWidth?{"max-width":t.linksWrapMaxWidth+"px"}:{}},[t.isAlgoliaSearch?n("AlgoliaSearchBox",{attrs:{options:t.algolia}}):!1!==t.$site.themeConfig.search&&!1!==t.$page.frontmatter.search?n("SearchBox"):t._e(),t._v(" "),n("NavLinks",{staticClass:"can-hide"})],1)],1)}),[],!1,null,null,null));n.default=l.exports},331:function(t,n,e){"use strict";e.r(n);var r=e(16),i=e.n(r),o=e(11),u={mixins:[e(303).a],data:()=>({postsList:[],countByYear:{},perPage:80,currentPage:1}),created(){this.getPageData();const{$sortPostsByDate:t,countByYear:n}=this;for(let e=0;e{if(this.postsList.lengthr&&e+r>=i-250&&this.loadmore()}},200))},methods:{getPageData(){const t=this.currentPage,n=this.perPage;this.postsList=this.postsList.concat(this.$sortPostsByDate.slice((t-1)*n,t*n))},loadmore(){this.currentPage=this.currentPage+1,this.getPageData()},getYear(t){const n=this.postsList[t];if(!n)return;const{frontmatter:{date:e}}=n;return e&&"string"===Object(o.n)(e)?e.slice(0,4):void 0},getDate(t){const{frontmatter:{date:n}}=t;if(n&&"string"===Object(o.n)(n))return n.slice(5,10)}}},a=(e(307),e(4)),s=Object(a.a)(u,(function(){var t=this,n=t._self._c;return n("div",{staticClass:"custom-page archives-page"},[n("div",{staticClass:"theme-vdoing-wrapper"},[n("h1",[!1!==t.$themeConfig.titleBadge?n("img",{attrs:{src:t.currentBadge}}):t._e(),t._v("\n "+t._s(t.$page.title)+"\n ")]),t._v(" "),n("div",{staticClass:"count"},[t._v("\n 总共 "),n("i",[t._v(t._s(t.$sortPostsByDate.length))]),t._v(" 篇文章\n ")]),t._v(" "),n("ul",[t._l(t.postsList,(function(e,r){return[(t.year=t.getYear(r))!==t.getYear(r-1)?n("li",{key:r+t.$sortPostsByDate.length,staticClass:"year"},[n("h2",[t._v("\n "+t._s(t.year)+"\n "),n("span",[n("i",[t._v(t._s(t.countByYear[t.year]))]),t._v(" 篇\n ")])])]):t._e(),t._v(" "),n("li",{key:r},[n("router-link",{attrs:{to:e.path}},[n("span",{staticClass:"date"},[t._v(t._s(t.getDate(e)))]),t._v("\n "+t._s(e.title)+"\n "),e.frontmatter.titleTag?n("span",{staticClass:"title-tag"},[t._v("\n "+t._s(e.frontmatter.titleTag)+"\n ")]):t._e()])],1)]}))],2)])])}),[],!1,null,null,null);n.default=s.exports},334:function(t,n,e){"use strict";e.r(n);var r=e(11),i={data:()=>({bgImg:"",opacity:.5}),mounted(){let{bodyBgImg:t,bodyBgImgOpacity:n,bodyBgImgInterval:e=15}=this.$themeConfig;if("string"===Object(r.n)(t))this.bgImg=t;else if("array"===Object(r.n)(t)){let n=0,r=null;this.bgImg=t[n],clearInterval(r),r=setInterval(()=>{if(++n>=t.length&&(n=0),this.bgImg=t[n],t[n+1]){(new Image).src=t[n+1]}},1e3*e)}void 0!==n&&(this.opacity=n)}},o=(e(310),e(4)),u=Object(o.a)(i,(function(){return(0,this._self._c)("div",{staticClass:"body-bg",style:`background: url(${this.bgImg}) center center / cover no-repeat;opacity:${this.opacity}`})}),[],!1,null,null,null);n.default=u.exports},335:function(t,n,e){"use strict";e.r(n);var r=e(16),i=e.n(r),o=e(304);var u={data:()=>({threshold:100,scrollTop:null,showCommentBut:!1,commentTop:null,currentMode:"",showModeBox:!1,modeList:[{name:"跟随系统",icon:"icon-zidong",KEY:"auto"},{name:"浅色模式",icon:"icon-rijianmoshi",KEY:"light"},{name:"深色模式",icon:"icon-yejianmoshi",KEY:"dark"},{name:"阅读模式",icon:"icon-yuedu",KEY:"read"}],_scrollTimer:null,_textareaEl:null,_recordScrollTop:null,COMMENT_SELECTOR_1:"#vuepress-plugin-comment",COMMENT_SELECTOR_2:"#valine-vuepress-comment",COMMENT_SELECTOR_3:".vssue"}),mounted(){if(this.currentMode=o.a.get("mode")||this.$themeConfig.defaultMode||"auto",this.scrollTop=this.getScrollTop(),window.addEventListener("scroll",i()(()=>{this.scrollTop=this.getScrollTop()},100)),window.addEventListener("load",()=>{this.getCommentTop()}),document.documentElement.clientWidth<719){this.$refs.modeBox.onclick=()=>{this.showModeBox=!1},window.addEventListener("scroll",i()(()=>{this.showModeBox&&(this.showModeBox=!1)},100))}const t=document.querySelectorAll(".buttons .button");for(let n=0;n{e.classList.remove("hover")},150)}))}},computed:{showToTop(){return this.scrollTop>this.threshold}},methods:{toggleMode(t){this.currentMode=t,this.$emit("toggle-theme-mode",t)},getScrollTop:()=>window.pageYOffset||document.documentElement.scrollTop||document.body.scrollTop||0,scrollToTop(){window.scrollTo({top:0,behavior:"smooth"}),this.scrollTop=0},getCommentTop(){setTimeout(()=>{let t=document.querySelector(this.COMMENT_SELECTOR_1)||document.querySelector(this.COMMENT_SELECTOR_2)||document.querySelector(this.COMMENT_SELECTOR_3);t&&(this.showCommentBut=!1!==this.$frontmatter.comment&&!0!==this.$frontmatter.home,this.commentTop=t.offsetTop-58)},500)},scrollToComment(){window.scrollTo({top:this.commentTop,behavior:"smooth"}),this._textareaEl=document.querySelector(this.COMMENT_SELECTOR_1+" textarea")||document.querySelector(this.COMMENT_SELECTOR_2+" input")||document.querySelector(this.COMMENT_SELECTOR_3+" textarea"),this._textareaEl&&this.getScrollTop()!==this._recordScrollTop?document.addEventListener("scroll",this._handleListener):this._textareaEl&&this.getScrollTop()===this._recordScrollTop&&this._handleFocus()},_handleListener(){clearTimeout(this._scrollTimer),this._scrollTimer=setTimeout(()=>{document.removeEventListener("scroll",this._handleListener),this._recordScrollTop=this.getScrollTop(),this._handleFocus()},30)},_handleFocus(){this._textareaEl.focus(),this._textareaEl.classList.add("yellowBorder"),setTimeout(()=>{this._textareaEl.classList.remove("yellowBorder")},500)}},watch:{"$route.path"(){this.showCommentBut=!1,this.getCommentTop()}}},a=(e(311),e(4)),s=Object(a.a)(u,(function(){var t=this,n=t._self._c;return n("div",{staticClass:"buttons"},[n("transition",{attrs:{name:"fade"}},[n("div",{directives:[{name:"show",rawName:"v-show",value:t.showToTop,expression:"showToTop"}],staticClass:"button blur go-to-top iconfont icon-fanhuidingbu",attrs:{title:"返回顶部"},on:{click:t.scrollToTop}})]),t._v(" "),n("div",{directives:[{name:"show",rawName:"v-show",value:t.showCommentBut,expression:"showCommentBut"}],staticClass:"button blur go-to-comment iconfont icon-pinglun",attrs:{title:"去评论"},on:{click:t.scrollToComment}}),t._v(" "),n("div",{staticClass:"button blur theme-mode-but iconfont icon-zhuti",attrs:{title:"主题模式"},on:{mouseenter:function(n){t.showModeBox=!0},mouseleave:function(n){t.showModeBox=!1},click:function(n){t.showModeBox=!0}}},[n("transition",{attrs:{name:"mode"}},[n("ul",{directives:[{name:"show",rawName:"v-show",value:t.showModeBox,expression:"showModeBox"}],ref:"modeBox",staticClass:"select-box",on:{click:function(t){t.stopPropagation()},touchstart:function(t){t.stopPropagation()}}},t._l(t.modeList,(function(e){return n("li",{key:e.KEY,staticClass:"iconfont",class:[e.icon,{active:e.KEY===t.currentMode}],on:{click:function(n){return t.toggleMode(e.KEY)}}},[t._v("\n "+t._s(e.name)+"\n ")])})),0)])],1)],1)}),[],!1,null,null,null);n.default=s.exports},337:function(t,n,e){"use strict";e.r(n);var r=e(270),i=e(267),o=e(268),u=e(300),a={data:()=>({category:"",total:0,perPage:10,currentPage:1}),components:{MainLayout:r.default,PostList:i.default,Pagination:o.default,CategoriesBar:u.default},mounted(){const t=this.$route.query.category;t?(this.category=t,this.total=this.$groupPosts.categories[t].length):this.total=this.$sortPosts.length,this.$route.query.p&&(this.currentPage=Number(this.$route.query.p));const n=document.querySelector(".categories");n&&setTimeout(()=>{const t=n.querySelector(".active"),e=t?t.offsetTop:0;n.scrollTo({top:e,behavior:"smooth"})},300)},methods:{handlePagination(t){this.currentPage=t}},watch:{"$route.query.category"(t){this.category=t?decodeURIComponent(t):"",this.category?this.total=this.$groupPosts.categories[this.category].length:this.total=this.$sortPosts.length,this.currentPage=1}}},s=(e(313),e(4)),c=Object(s.a)(a,(function(){var t=this,n=t._self._c;return n("div",{staticClass:"custom-page categories-page"},[n("MainLayout",{scopedSlots:t._u([{key:"mainLeft",fn:function(){return[t.$categoriesAndTags.categories.length?n("CategoriesBar",{attrs:{categoriesData:t.$categoriesAndTags.categories,category:t.category}}):t._e(),t._v(" "),n("PostList",{attrs:{currentPage:t.currentPage,perPage:t.perPage,category:t.category}}),t._v(" "),n("Pagination",{directives:[{name:"show",rawName:"v-show",value:Math.ceil(t.total/t.perPage)>1,expression:"Math.ceil(total / perPage) > 1"}],attrs:{total:t.total,perPage:t.perPage,currentPage:t.currentPage},on:{getCurrentPage:t.handlePagination}})]},proxy:!0},{key:"mainRight",fn:function(){return[t.$categoriesAndTags.categories.length?n("CategoriesBar",{attrs:{categoriesData:t.$categoriesAndTags.categories,category:t.category}}):t._e()]},proxy:!0}])})],1)}),[],!1,null,null,null);n.default=c.exports},338:function(t,n,e){"use strict";e.r(n);var r={computed:{social(){return this.$themeConfig.social},footer(){return this.$themeConfig.footer}}},i=(e(314),e(4)),o=Object(i.a)(r,(function(){var t=this,n=t._self._c;return n("div",{staticClass:"footer"},[t.social&&t.social.icons?n("div",{staticClass:"icons"},t._l(t.social.icons,(function(t,e){return n("a",{key:e,class:["iconfont",t.iconClass],attrs:{href:t.link,title:t.title,target:"_blank"}})})),0):t._e(),t._v(" "),t._v("\n Theme by\n "),n("a",{attrs:{href:"https://github.com/xugaoyi/vuepress-theme-vdoing",target:"_blank",title:"本站主题"}},[t._v("Vdoing")]),t._v(" "),t.footer?[t._v("\n | Copyright © "+t._s(t.footer.createYear)+"-"+t._s((new Date).getFullYear())+"\n "),n("span",{domProps:{innerHTML:t._s(t.footer.copyrightInfo)}})]:t._e()],2)}),[],!1,null,null,null);n.default=o.exports},342:function(t,n,e){"use strict";e.r(n);var r=e(277),i=e(276),o={name:"Sidebar",components:{SidebarLinks:r.default,NavLinks:i.default},props:["items"],computed:{blogger(){return this.$themeConfig.blogger}}},u=(e(321),e(4)),a=Object(u.a)(o,(function(){var t=this,n=t._self._c;return n("aside",{staticClass:"sidebar"},[t.blogger?n("div",{staticClass:"blogger"},[n("img",{attrs:{src:t.blogger.avatar}}),t._v(" "),n("div",{staticClass:"blogger-info"},[n("h3",[t._v(t._s(t.blogger.name))]),t._v(" "),t.blogger.social?n("div",{staticClass:"icons"},t._l(t.blogger.social.icons,(function(t,e){return n("a",{key:e,class:["iconfont",t.iconClass],attrs:{href:t.link,title:t.title,target:"_blank"}})})),0):n("span",[t._v(t._s(t.blogger.slogan))])])]):t._e(),t._v(" "),n("NavLinks"),t._v(" "),t._t("top"),t._v(" "),n("SidebarLinks",{attrs:{depth:0,items:t.items}}),t._v(" "),t._t("bottom")],2)}),[],!1,null,null,null);n.default=a.exports},343:function(t,n,e){"use strict";e.r(n);var r=e(270),i=e(267),o=e(268),u=e(301),a={data:()=>({tag:"",total:0,perPage:10,currentPage:1}),components:{MainLayout:r.default,PostList:i.default,Pagination:o.default,TagsBar:u.default},mounted(){const t=this.$route.query.tag;t?(this.tag=t,this.total=this.$groupPosts.tags[t].length):this.total=this.$sortPosts.length,this.$route.query.p&&(this.currentPage=Number(this.$route.query.p))},methods:{handlePagination(t){this.currentPage=t}},watch:{"$route.query.tag"(t){this.tag=t?decodeURIComponent(t):"",this.tag?this.total=this.$groupPosts.tags[this.tag].length:this.total=this.$sortPosts.length,this.currentPage=1}}},s=(e(322),e(4)),c=Object(s.a)(a,(function(){var t=this,n=t._self._c;return n("div",{staticClass:"custom-page tags-page"},[n("MainLayout",{scopedSlots:t._u([{key:"mainLeft",fn:function(){return[t.$categoriesAndTags.tags.length?n("TagsBar",{attrs:{tagsData:t.$categoriesAndTags.tags,tag:t.tag}}):t._e(),t._v(" "),n("PostList",{attrs:{currentPage:t.currentPage,perPage:t.perPage,tag:t.tag}}),t._v(" "),n("Pagination",{directives:[{name:"show",rawName:"v-show",value:Math.ceil(t.total/t.perPage)>1,expression:"Math.ceil(total / perPage) > 1"}],attrs:{total:t.total,perPage:t.perPage,currentPage:t.currentPage},on:{getCurrentPage:t.handlePagination}})]},proxy:!0},{key:"mainRight",fn:function(){return[t.$categoriesAndTags.tags.length?n("TagsBar",{attrs:{tagsData:t.$categoriesAndTags.tags,tag:t.tag}}):t._e()]},proxy:!0}])})],1)}),[],!1,null,null,null);n.default=c.exports},353:function(t,n,e){(function(t){var r; +/** + * @license + * Lodash + * Copyright OpenJS Foundation and other contributors + * Released under MIT license + * Based on Underscore.js 1.8.3 + * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors + */(function(){var i="Expected a function",o="__lodash_placeholder__",u=[["ary",128],["bind",1],["bindKey",2],["curry",8],["curryRight",16],["flip",512],["partial",32],["partialRight",64],["rearg",256]],a="[object Arguments]",s="[object Array]",c="[object Boolean]",l="[object Date]",f="[object Error]",h="[object Function]",d="[object GeneratorFunction]",v="[object Map]",p="[object Number]",g="[object Object]",_="[object RegExp]",m="[object Set]",y="[object String]",b="[object Symbol]",w="[object WeakMap]",x="[object ArrayBuffer]",C="[object DataView]",k="[object Float32Array]",S="[object Float64Array]",L="[object Int8Array]",T="[object Int16Array]",$="[object Int32Array]",O="[object Uint8Array]",j="[object Uint16Array]",E="[object Uint32Array]",P=/\b__p \+= '';/g,B=/\b(__p \+=) '' \+/g,A=/(__e\(.*?\)|\b__t\)) \+\n'';/g,I=/&(?:amp|lt|gt|quot|#39);/g,M=/[&<>"']/g,R=RegExp(I.source),N=RegExp(M.source),D=/<%-([\s\S]+?)%>/g,W=/<%([\s\S]+?)%>/g,z=/<%=([\s\S]+?)%>/g,U=/\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,q=/^\w*$/,H=/[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g,F=/[\\^$.*+?()[\]{}|]/g,Y=RegExp(F.source),G=/^\s+/,K=/\s/,V=/\{(?:\n\/\* \[wrapped with .+\] \*\/)?\n?/,Z=/\{\n\/\* \[wrapped with (.+)\] \*/,J=/,? & /,Q=/[^\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\x7f]+/g,X=/[()=,{}\[\]\/\s]/,tt=/\\(\\)?/g,nt=/\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g,et=/\w*$/,rt=/^[-+]0x[0-9a-f]+$/i,it=/^0b[01]+$/i,ot=/^\[object .+?Constructor\]$/,ut=/^0o[0-7]+$/i,at=/^(?:0|[1-9]\d*)$/,st=/[\xc0-\xd6\xd8-\xf6\xf8-\xff\u0100-\u017f]/g,ct=/($^)/,lt=/['\n\r\u2028\u2029\\]/g,ft="\\u0300-\\u036f\\ufe20-\\ufe2f\\u20d0-\\u20ff",ht="\\xac\\xb1\\xd7\\xf7\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf\\u2000-\\u206f \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000",dt="[\\ud800-\\udfff]",vt="["+ht+"]",pt="["+ft+"]",gt="\\d+",_t="[\\u2700-\\u27bf]",mt="[a-z\\xdf-\\xf6\\xf8-\\xff]",yt="[^\\ud800-\\udfff"+ht+gt+"\\u2700-\\u27bfa-z\\xdf-\\xf6\\xf8-\\xffA-Z\\xc0-\\xd6\\xd8-\\xde]",bt="\\ud83c[\\udffb-\\udfff]",wt="[^\\ud800-\\udfff]",xt="(?:\\ud83c[\\udde6-\\uddff]){2}",Ct="[\\ud800-\\udbff][\\udc00-\\udfff]",kt="[A-Z\\xc0-\\xd6\\xd8-\\xde]",St="(?:"+mt+"|"+yt+")",Lt="(?:"+kt+"|"+yt+")",Tt="(?:"+pt+"|"+bt+")"+"?",$t="[\\ufe0e\\ufe0f]?"+Tt+("(?:\\u200d(?:"+[wt,xt,Ct].join("|")+")[\\ufe0e\\ufe0f]?"+Tt+")*"),Ot="(?:"+[_t,xt,Ct].join("|")+")"+$t,jt="(?:"+[wt+pt+"?",pt,xt,Ct,dt].join("|")+")",Et=RegExp("['’]","g"),Pt=RegExp(pt,"g"),Bt=RegExp(bt+"(?="+bt+")|"+jt+$t,"g"),At=RegExp([kt+"?"+mt+"+(?:['’](?:d|ll|m|re|s|t|ve))?(?="+[vt,kt,"$"].join("|")+")",Lt+"+(?:['’](?:D|LL|M|RE|S|T|VE))?(?="+[vt,kt+St,"$"].join("|")+")",kt+"?"+St+"+(?:['’](?:d|ll|m|re|s|t|ve))?",kt+"+(?:['’](?:D|LL|M|RE|S|T|VE))?","\\d*(?:1ST|2ND|3RD|(?![123])\\dTH)(?=\\b|[a-z_])","\\d*(?:1st|2nd|3rd|(?![123])\\dth)(?=\\b|[A-Z_])",gt,Ot].join("|"),"g"),It=RegExp("[\\u200d\\ud800-\\udfff"+ft+"\\ufe0e\\ufe0f]"),Mt=/[a-z][A-Z]|[A-Z]{2}[a-z]|[0-9][a-zA-Z]|[a-zA-Z][0-9]|[^a-zA-Z0-9 ]/,Rt=["Array","Buffer","DataView","Date","Error","Float32Array","Float64Array","Function","Int8Array","Int16Array","Int32Array","Map","Math","Object","Promise","RegExp","Set","String","Symbol","TypeError","Uint8Array","Uint8ClampedArray","Uint16Array","Uint32Array","WeakMap","_","clearTimeout","isFinite","parseInt","setTimeout"],Nt=-1,Dt={};Dt[k]=Dt[S]=Dt[L]=Dt[T]=Dt[$]=Dt[O]=Dt["[object Uint8ClampedArray]"]=Dt[j]=Dt[E]=!0,Dt[a]=Dt[s]=Dt[x]=Dt[c]=Dt[C]=Dt[l]=Dt[f]=Dt[h]=Dt[v]=Dt[p]=Dt[g]=Dt[_]=Dt[m]=Dt[y]=Dt[w]=!1;var Wt={};Wt[a]=Wt[s]=Wt[x]=Wt[C]=Wt[c]=Wt[l]=Wt[k]=Wt[S]=Wt[L]=Wt[T]=Wt[$]=Wt[v]=Wt[p]=Wt[g]=Wt[_]=Wt[m]=Wt[y]=Wt[b]=Wt[O]=Wt["[object Uint8ClampedArray]"]=Wt[j]=Wt[E]=!0,Wt[f]=Wt[h]=Wt[w]=!1;var zt={"\\":"\\","'":"'","\n":"n","\r":"r","\u2028":"u2028","\u2029":"u2029"},Ut=parseFloat,qt=parseInt,Ht="object"==typeof global&&global&&global.Object===Object&&global,Ft="object"==typeof self&&self&&self.Object===Object&&self,Yt=Ht||Ft||Function("return this")(),Gt=n&&!n.nodeType&&n,Kt=Gt&&"object"==typeof t&&t&&!t.nodeType&&t,Vt=Kt&&Kt.exports===Gt,Zt=Vt&&Ht.process,Jt=function(){try{var t=Kt&&Kt.require&&Kt.require("util").types;return t||Zt&&Zt.binding&&Zt.binding("util")}catch(t){}}(),Qt=Jt&&Jt.isArrayBuffer,Xt=Jt&&Jt.isDate,tn=Jt&&Jt.isMap,nn=Jt&&Jt.isRegExp,en=Jt&&Jt.isSet,rn=Jt&&Jt.isTypedArray;function on(t,n,e){switch(e.length){case 0:return t.call(n);case 1:return t.call(n,e[0]);case 2:return t.call(n,e[0],e[1]);case 3:return t.call(n,e[0],e[1],e[2])}return t.apply(n,e)}function un(t,n,e,r){for(var i=-1,o=null==t?0:t.length;++i-1}function hn(t,n,e){for(var r=-1,i=null==t?0:t.length;++r-1;);return e}function In(t,n){for(var e=t.length;e--&&wn(n,t[e],0)>-1;);return e}function Mn(t,n){for(var e=t.length,r=0;e--;)t[e]===n&&++r;return r}var Rn=Ln({"À":"A","Á":"A","Â":"A","Ã":"A","Ä":"A","Å":"A","à":"a","á":"a","â":"a","ã":"a","ä":"a","å":"a","Ç":"C","ç":"c","Ð":"D","ð":"d","È":"E","É":"E","Ê":"E","Ë":"E","è":"e","é":"e","ê":"e","ë":"e","Ì":"I","Í":"I","Î":"I","Ï":"I","ì":"i","í":"i","î":"i","ï":"i","Ñ":"N","ñ":"n","Ò":"O","Ó":"O","Ô":"O","Õ":"O","Ö":"O","Ø":"O","ò":"o","ó":"o","ô":"o","õ":"o","ö":"o","ø":"o","Ù":"U","Ú":"U","Û":"U","Ü":"U","ù":"u","ú":"u","û":"u","ü":"u","Ý":"Y","ý":"y","ÿ":"y","Æ":"Ae","æ":"ae","Þ":"Th","þ":"th","ß":"ss","Ā":"A","Ă":"A","Ą":"A","ā":"a","ă":"a","ą":"a","Ć":"C","Ĉ":"C","Ċ":"C","Č":"C","ć":"c","ĉ":"c","ċ":"c","č":"c","Ď":"D","Đ":"D","ď":"d","đ":"d","Ē":"E","Ĕ":"E","Ė":"E","Ę":"E","Ě":"E","ē":"e","ĕ":"e","ė":"e","ę":"e","ě":"e","Ĝ":"G","Ğ":"G","Ġ":"G","Ģ":"G","ĝ":"g","ğ":"g","ġ":"g","ģ":"g","Ĥ":"H","Ħ":"H","ĥ":"h","ħ":"h","Ĩ":"I","Ī":"I","Ĭ":"I","Į":"I","İ":"I","ĩ":"i","ī":"i","ĭ":"i","į":"i","ı":"i","Ĵ":"J","ĵ":"j","Ķ":"K","ķ":"k","ĸ":"k","Ĺ":"L","Ļ":"L","Ľ":"L","Ŀ":"L","Ł":"L","ĺ":"l","ļ":"l","ľ":"l","ŀ":"l","ł":"l","Ń":"N","Ņ":"N","Ň":"N","Ŋ":"N","ń":"n","ņ":"n","ň":"n","ŋ":"n","Ō":"O","Ŏ":"O","Ő":"O","ō":"o","ŏ":"o","ő":"o","Ŕ":"R","Ŗ":"R","Ř":"R","ŕ":"r","ŗ":"r","ř":"r","Ś":"S","Ŝ":"S","Ş":"S","Š":"S","ś":"s","ŝ":"s","ş":"s","š":"s","Ţ":"T","Ť":"T","Ŧ":"T","ţ":"t","ť":"t","ŧ":"t","Ũ":"U","Ū":"U","Ŭ":"U","Ů":"U","Ű":"U","Ų":"U","ũ":"u","ū":"u","ŭ":"u","ů":"u","ű":"u","ų":"u","Ŵ":"W","ŵ":"w","Ŷ":"Y","ŷ":"y","Ÿ":"Y","Ź":"Z","Ż":"Z","Ž":"Z","ź":"z","ż":"z","ž":"z","IJ":"IJ","ij":"ij","Œ":"Oe","œ":"oe","ʼn":"'n","ſ":"s"}),Nn=Ln({"&":"&","<":"<",">":">",'"':""","'":"'"});function Dn(t){return"\\"+zt[t]}function Wn(t){return It.test(t)}function zn(t){var n=-1,e=Array(t.size);return t.forEach((function(t,r){e[++n]=[r,t]})),e}function Un(t,n){return function(e){return t(n(e))}}function qn(t,n){for(var e=-1,r=t.length,i=0,u=[];++e",""":'"',"'":"'"});var Zn=function t(n){var e,r=(n=null==n?Yt:Zn.defaults(Yt.Object(),n,Zn.pick(Yt,Rt))).Array,K=n.Date,ft=n.Error,ht=n.Function,dt=n.Math,vt=n.Object,pt=n.RegExp,gt=n.String,_t=n.TypeError,mt=r.prototype,yt=ht.prototype,bt=vt.prototype,wt=n["__core-js_shared__"],xt=yt.toString,Ct=bt.hasOwnProperty,kt=0,St=(e=/[^.]+$/.exec(wt&&wt.keys&&wt.keys.IE_PROTO||""))?"Symbol(src)_1."+e:"",Lt=bt.toString,Tt=xt.call(vt),$t=Yt._,Ot=pt("^"+xt.call(Ct).replace(F,"\\$&").replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g,"$1.*?")+"$"),jt=Vt?n.Buffer:void 0,Bt=n.Symbol,It=n.Uint8Array,zt=jt?jt.allocUnsafe:void 0,Ht=Un(vt.getPrototypeOf,vt),Ft=vt.create,Gt=bt.propertyIsEnumerable,Kt=mt.splice,Zt=Bt?Bt.isConcatSpreadable:void 0,Jt=Bt?Bt.iterator:void 0,mn=Bt?Bt.toStringTag:void 0,Ln=function(){try{var t=to(vt,"defineProperty");return t({},"",{}),t}catch(t){}}(),Jn=n.clearTimeout!==Yt.clearTimeout&&n.clearTimeout,Qn=K&&K.now!==Yt.Date.now&&K.now,Xn=n.setTimeout!==Yt.setTimeout&&n.setTimeout,te=dt.ceil,ne=dt.floor,ee=vt.getOwnPropertySymbols,re=jt?jt.isBuffer:void 0,ie=n.isFinite,oe=mt.join,ue=Un(vt.keys,vt),ae=dt.max,se=dt.min,ce=K.now,le=n.parseInt,fe=dt.random,he=mt.reverse,de=to(n,"DataView"),ve=to(n,"Map"),pe=to(n,"Promise"),ge=to(n,"Set"),_e=to(n,"WeakMap"),me=to(vt,"create"),ye=_e&&new _e,be={},we=$o(de),xe=$o(ve),Ce=$o(pe),ke=$o(ge),Se=$o(_e),Le=Bt?Bt.prototype:void 0,Te=Le?Le.valueOf:void 0,$e=Le?Le.toString:void 0;function Oe(t){if(Fu(t)&&!Au(t)&&!(t instanceof Be)){if(t instanceof Pe)return t;if(Ct.call(t,"__wrapped__"))return Oo(t)}return new Pe(t)}var je=function(){function t(){}return function(n){if(!Hu(n))return{};if(Ft)return Ft(n);t.prototype=n;var e=new t;return t.prototype=void 0,e}}();function Ee(){}function Pe(t,n){this.__wrapped__=t,this.__actions__=[],this.__chain__=!!n,this.__index__=0,this.__values__=void 0}function Be(t){this.__wrapped__=t,this.__actions__=[],this.__dir__=1,this.__filtered__=!1,this.__iteratees__=[],this.__takeCount__=4294967295,this.__views__=[]}function Ae(t){var n=-1,e=null==t?0:t.length;for(this.clear();++n=n?t:n)),t}function Je(t,n,e,r,i,o){var u,s=1&n,f=2&n,w=4&n;if(e&&(u=i?e(t,r,i,o):e(t)),void 0!==u)return u;if(!Hu(t))return t;var P=Au(t);if(P){if(u=function(t){var n=t.length,e=new t.constructor(n);n&&"string"==typeof t[0]&&Ct.call(t,"index")&&(e.index=t.index,e.input=t.input);return e}(t),!s)return mi(t,u)}else{var B=ro(t),A=B==h||B==d;if(Nu(t))return hi(t,s);if(B==g||B==a||A&&!i){if(u=f||A?{}:oo(t),!s)return f?function(t,n){return yi(t,eo(t),n)}(t,function(t,n){return t&&yi(n,xa(n),t)}(u,t)):function(t,n){return yi(t,no(t),n)}(t,Ge(u,t))}else{if(!Wt[B])return i?t:{};u=function(t,n,e){var r=t.constructor;switch(n){case x:return di(t);case c:case l:return new r(+t);case C:return function(t,n){var e=n?di(t.buffer):t.buffer;return new t.constructor(e,t.byteOffset,t.byteLength)}(t,e);case k:case S:case L:case T:case $:case O:case"[object Uint8ClampedArray]":case j:case E:return vi(t,e);case v:return new r;case p:case y:return new r(t);case _:return function(t){var n=new t.constructor(t.source,et.exec(t));return n.lastIndex=t.lastIndex,n}(t);case m:return new r;case b:return i=t,Te?vt(Te.call(i)):{}}var i}(t,B,s)}}o||(o=new Ne);var I=o.get(t);if(I)return I;o.set(t,u),Zu(t)?t.forEach((function(r){u.add(Je(r,n,e,r,t,o))})):Yu(t)&&t.forEach((function(r,i){u.set(i,Je(r,n,e,i,t,o))}));var M=P?void 0:(w?f?Gi:Yi:f?xa:wa)(t);return an(M||t,(function(r,i){M&&(r=t[i=r]),He(u,i,Je(r,n,e,i,t,o))})),u}function Qe(t,n,e){var r=e.length;if(null==t)return!r;for(t=vt(t);r--;){var i=e[r],o=n[i],u=t[i];if(void 0===u&&!(i in t)||!o(u))return!1}return!0}function Xe(t,n,e){if("function"!=typeof t)throw new _t(i);return wo((function(){t.apply(void 0,e)}),n)}function tr(t,n,e,r){var i=-1,o=fn,u=!0,a=t.length,s=[],c=n.length;if(!a)return s;e&&(n=dn(n,En(e))),r?(o=hn,u=!1):n.length>=200&&(o=Bn,u=!1,n=new Re(n));t:for(;++i-1},Ie.prototype.set=function(t,n){var e=this.__data__,r=Fe(e,t);return r<0?(++this.size,e.push([t,n])):e[r][1]=n,this},Me.prototype.clear=function(){this.size=0,this.__data__={hash:new Ae,map:new(ve||Ie),string:new Ae}},Me.prototype.delete=function(t){var n=Qi(this,t).delete(t);return this.size-=n?1:0,n},Me.prototype.get=function(t){return Qi(this,t).get(t)},Me.prototype.has=function(t){return Qi(this,t).has(t)},Me.prototype.set=function(t,n){var e=Qi(this,t),r=e.size;return e.set(t,n),this.size+=e.size==r?0:1,this},Re.prototype.add=Re.prototype.push=function(t){return this.__data__.set(t,"__lodash_hash_undefined__"),this},Re.prototype.has=function(t){return this.__data__.has(t)},Ne.prototype.clear=function(){this.__data__=new Ie,this.size=0},Ne.prototype.delete=function(t){var n=this.__data__,e=n.delete(t);return this.size=n.size,e},Ne.prototype.get=function(t){return this.__data__.get(t)},Ne.prototype.has=function(t){return this.__data__.has(t)},Ne.prototype.set=function(t,n){var e=this.__data__;if(e instanceof Ie){var r=e.__data__;if(!ve||r.length<199)return r.push([t,n]),this.size=++e.size,this;e=this.__data__=new Me(r)}return e.set(t,n),this.size=e.size,this};var nr=xi(cr),er=xi(lr,!0);function rr(t,n){var e=!0;return nr(t,(function(t,r,i){return e=!!n(t,r,i)})),e}function ir(t,n,e){for(var r=-1,i=t.length;++r0&&e(a)?n>1?ur(a,n-1,e,r,i):vn(i,a):r||(i[i.length]=a)}return i}var ar=Ci(),sr=Ci(!0);function cr(t,n){return t&&ar(t,n,wa)}function lr(t,n){return t&&sr(t,n,wa)}function fr(t,n){return ln(n,(function(n){return zu(t[n])}))}function hr(t,n){for(var e=0,r=(n=si(n,t)).length;null!=t&&en}function gr(t,n){return null!=t&&Ct.call(t,n)}function _r(t,n){return null!=t&&n in vt(t)}function mr(t,n,e){for(var i=e?hn:fn,o=t[0].length,u=t.length,a=u,s=r(u),c=1/0,l=[];a--;){var f=t[a];a&&n&&(f=dn(f,En(n))),c=se(f.length,c),s[a]=!e&&(n||o>=120&&f.length>=120)?new Re(a&&f):void 0}f=t[0];var h=-1,d=s[0];t:for(;++h=a)return s;var c=e[r];return s*("desc"==c?-1:1)}}return t.index-n.index}(t,n,e)}))}function Ar(t,n,e){for(var r=-1,i=n.length,o={};++r-1;)a!==t&&Kt.call(a,s,1),Kt.call(t,s,1);return t}function Mr(t,n){for(var e=t?n.length:0,r=e-1;e--;){var i=n[e];if(e==r||i!==o){var o=i;ao(i)?Kt.call(t,i,1):ti(t,i)}}return t}function Rr(t,n){return t+ne(fe()*(n-t+1))}function Nr(t,n){var e="";if(!t||n<1||n>9007199254740991)return e;do{n%2&&(e+=t),(n=ne(n/2))&&(t+=t)}while(n);return e}function Dr(t,n){return xo(go(t,n,Ga),t+"")}function Wr(t){return We(ja(t))}function zr(t,n){var e=ja(t);return So(e,Ze(n,0,e.length))}function Ur(t,n,e,r){if(!Hu(t))return t;for(var i=-1,o=(n=si(n,t)).length,u=o-1,a=t;null!=a&&++io?0:o+n),(e=e>o?o:e)<0&&(e+=o),o=n>e?0:e-n>>>0,n>>>=0;for(var u=r(o);++i>>1,u=t[o];null!==u&&!Qu(u)&&(e?u<=n:u=200){var c=n?null:Ni(t);if(c)return Hn(c);u=!1,i=Bn,s=new Re}else s=n?[]:a;t:for(;++r=r?t:Yr(t,n,e)}var fi=Jn||function(t){return Yt.clearTimeout(t)};function hi(t,n){if(n)return t.slice();var e=t.length,r=zt?zt(e):new t.constructor(e);return t.copy(r),r}function di(t){var n=new t.constructor(t.byteLength);return new It(n).set(new It(t)),n}function vi(t,n){var e=n?di(t.buffer):t.buffer;return new t.constructor(e,t.byteOffset,t.length)}function pi(t,n){if(t!==n){var e=void 0!==t,r=null===t,i=t==t,o=Qu(t),u=void 0!==n,a=null===n,s=n==n,c=Qu(n);if(!a&&!c&&!o&&t>n||o&&u&&s&&!a&&!c||r&&u&&s||!e&&s||!i)return 1;if(!r&&!o&&!c&&t1?e[i-1]:void 0,u=i>2?e[2]:void 0;for(o=t.length>3&&"function"==typeof o?(i--,o):void 0,u&&so(e[0],e[1],u)&&(o=i<3?void 0:o,i=1),n=vt(n);++r-1?i[o?n[u]:u]:void 0}}function $i(t){return Fi((function(n){var e=n.length,r=e,o=Pe.prototype.thru;for(t&&n.reverse();r--;){var u=n[r];if("function"!=typeof u)throw new _t(i);if(o&&!a&&"wrapper"==Vi(u))var a=new Pe([],!0)}for(r=a?r:e;++r1&&y.reverse(),f&&ca))return!1;var c=o.get(t),l=o.get(n);if(c&&l)return c==n&&l==t;var f=-1,h=!0,d=2&e?new Re:void 0;for(o.set(t,n),o.set(n,t);++f-1&&t%1==0&&t1?"& ":"")+n[r],n=n.join(e>2?", ":" "),t.replace(V,"{\n/* [wrapped with "+n+"] */\n")}(r,function(t,n){return an(u,(function(e){var r="_."+e[0];n&e[1]&&!fn(t,r)&&t.push(r)})),t.sort()}(function(t){var n=t.match(Z);return n?n[1].split(J):[]}(r),e)))}function ko(t){var n=0,e=0;return function(){var r=ce(),i=16-(r-e);if(e=r,i>0){if(++n>=800)return arguments[0]}else n=0;return t.apply(void 0,arguments)}}function So(t,n){var e=-1,r=t.length,i=r-1;for(n=void 0===n?r:n;++e1?t[n-1]:void 0;return e="function"==typeof e?(t.pop(),e):void 0,Vo(t,e)}));function eu(t){var n=Oe(t);return n.__chain__=!0,n}function ru(t,n){return n(t)}var iu=Fi((function(t){var n=t.length,e=n?t[0]:0,r=this.__wrapped__,i=function(n){return Ve(n,t)};return!(n>1||this.__actions__.length)&&r instanceof Be&&ao(e)?((r=r.slice(e,+e+(n?1:0))).__actions__.push({func:ru,args:[i],thisArg:void 0}),new Pe(r,this.__chain__).thru((function(t){return n&&!t.length&&t.push(void 0),t}))):this.thru(i)}));var ou=bi((function(t,n,e){Ct.call(t,e)?++t[e]:Ke(t,e,1)}));var uu=Ti(Bo),au=Ti(Ao);function su(t,n){return(Au(t)?an:nr)(t,Ji(n,3))}function cu(t,n){return(Au(t)?sn:er)(t,Ji(n,3))}var lu=bi((function(t,n,e){Ct.call(t,e)?t[e].push(n):Ke(t,e,[n])}));var fu=Dr((function(t,n,e){var i=-1,o="function"==typeof n,u=Mu(t)?r(t.length):[];return nr(t,(function(t){u[++i]=o?on(n,t,e):yr(t,n,e)})),u})),hu=bi((function(t,n,e){Ke(t,e,n)}));function du(t,n){return(Au(t)?dn:$r)(t,Ji(n,3))}var vu=bi((function(t,n,e){t[e?0:1].push(n)}),(function(){return[[],[]]}));var pu=Dr((function(t,n){if(null==t)return[];var e=n.length;return e>1&&so(t,n[0],n[1])?n=[]:e>2&&so(n[0],n[1],n[2])&&(n=[n[0]]),Br(t,ur(n,1),[])})),gu=Qn||function(){return Yt.Date.now()};function _u(t,n,e){return n=e?void 0:n,Wi(t,128,void 0,void 0,void 0,void 0,n=t&&null==n?t.length:n)}function mu(t,n){var e;if("function"!=typeof n)throw new _t(i);return t=ia(t),function(){return--t>0&&(e=n.apply(this,arguments)),t<=1&&(n=void 0),e}}var yu=Dr((function(t,n,e){var r=1;if(e.length){var i=qn(e,Zi(yu));r|=32}return Wi(t,r,n,e,i)})),bu=Dr((function(t,n,e){var r=3;if(e.length){var i=qn(e,Zi(bu));r|=32}return Wi(n,r,t,e,i)}));function wu(t,n,e){var r,o,u,a,s,c,l=0,f=!1,h=!1,d=!0;if("function"!=typeof t)throw new _t(i);function v(n){var e=r,i=o;return r=o=void 0,l=n,a=t.apply(i,e)}function p(t){return l=t,s=wo(_,n),f?v(t):a}function g(t){var e=t-c;return void 0===c||e>=n||e<0||h&&t-l>=u}function _(){var t=gu();if(g(t))return m(t);s=wo(_,function(t){var e=n-(t-c);return h?se(e,u-(t-l)):e}(t))}function m(t){return s=void 0,d&&r?v(t):(r=o=void 0,a)}function y(){var t=gu(),e=g(t);if(r=arguments,o=this,c=t,e){if(void 0===s)return p(c);if(h)return fi(s),s=wo(_,n),v(c)}return void 0===s&&(s=wo(_,n)),a}return n=ua(n)||0,Hu(e)&&(f=!!e.leading,u=(h="maxWait"in e)?ae(ua(e.maxWait)||0,n):u,d="trailing"in e?!!e.trailing:d),y.cancel=function(){void 0!==s&&fi(s),l=0,r=c=o=s=void 0},y.flush=function(){return void 0===s?a:m(gu())},y}var xu=Dr((function(t,n){return Xe(t,1,n)})),Cu=Dr((function(t,n,e){return Xe(t,ua(n)||0,e)}));function ku(t,n){if("function"!=typeof t||null!=n&&"function"!=typeof n)throw new _t(i);var e=function(){var r=arguments,i=n?n.apply(this,r):r[0],o=e.cache;if(o.has(i))return o.get(i);var u=t.apply(this,r);return e.cache=o.set(i,u)||o,u};return e.cache=new(ku.Cache||Me),e}function Su(t){if("function"!=typeof t)throw new _t(i);return function(){var n=arguments;switch(n.length){case 0:return!t.call(this);case 1:return!t.call(this,n[0]);case 2:return!t.call(this,n[0],n[1]);case 3:return!t.call(this,n[0],n[1],n[2])}return!t.apply(this,n)}}ku.Cache=Me;var Lu=ci((function(t,n){var e=(n=1==n.length&&Au(n[0])?dn(n[0],En(Ji())):dn(ur(n,1),En(Ji()))).length;return Dr((function(r){for(var i=-1,o=se(r.length,e);++i=n})),Bu=br(function(){return arguments}())?br:function(t){return Fu(t)&&Ct.call(t,"callee")&&!Gt.call(t,"callee")},Au=r.isArray,Iu=Qt?En(Qt):function(t){return Fu(t)&&vr(t)==x};function Mu(t){return null!=t&&qu(t.length)&&!zu(t)}function Ru(t){return Fu(t)&&Mu(t)}var Nu=re||us,Du=Xt?En(Xt):function(t){return Fu(t)&&vr(t)==l};function Wu(t){if(!Fu(t))return!1;var n=vr(t);return n==f||"[object DOMException]"==n||"string"==typeof t.message&&"string"==typeof t.name&&!Ku(t)}function zu(t){if(!Hu(t))return!1;var n=vr(t);return n==h||n==d||"[object AsyncFunction]"==n||"[object Proxy]"==n}function Uu(t){return"number"==typeof t&&t==ia(t)}function qu(t){return"number"==typeof t&&t>-1&&t%1==0&&t<=9007199254740991}function Hu(t){var n=typeof t;return null!=t&&("object"==n||"function"==n)}function Fu(t){return null!=t&&"object"==typeof t}var Yu=tn?En(tn):function(t){return Fu(t)&&ro(t)==v};function Gu(t){return"number"==typeof t||Fu(t)&&vr(t)==p}function Ku(t){if(!Fu(t)||vr(t)!=g)return!1;var n=Ht(t);if(null===n)return!0;var e=Ct.call(n,"constructor")&&n.constructor;return"function"==typeof e&&e instanceof e&&xt.call(e)==Tt}var Vu=nn?En(nn):function(t){return Fu(t)&&vr(t)==_};var Zu=en?En(en):function(t){return Fu(t)&&ro(t)==m};function Ju(t){return"string"==typeof t||!Au(t)&&Fu(t)&&vr(t)==y}function Qu(t){return"symbol"==typeof t||Fu(t)&&vr(t)==b}var Xu=rn?En(rn):function(t){return Fu(t)&&qu(t.length)&&!!Dt[vr(t)]};var ta=Ii(Tr),na=Ii((function(t,n){return t<=n}));function ea(t){if(!t)return[];if(Mu(t))return Ju(t)?Gn(t):mi(t);if(Jt&&t[Jt])return function(t){for(var n,e=[];!(n=t.next()).done;)e.push(n.value);return e}(t[Jt]());var n=ro(t);return(n==v?zn:n==m?Hn:ja)(t)}function ra(t){return t?(t=ua(t))===1/0||t===-1/0?17976931348623157e292*(t<0?-1:1):t==t?t:0:0===t?t:0}function ia(t){var n=ra(t),e=n%1;return n==n?e?n-e:n:0}function oa(t){return t?Ze(ia(t),0,4294967295):0}function ua(t){if("number"==typeof t)return t;if(Qu(t))return NaN;if(Hu(t)){var n="function"==typeof t.valueOf?t.valueOf():t;t=Hu(n)?n+"":n}if("string"!=typeof t)return 0===t?t:+t;t=jn(t);var e=it.test(t);return e||ut.test(t)?qt(t.slice(2),e?2:8):rt.test(t)?NaN:+t}function aa(t){return yi(t,xa(t))}function sa(t){return null==t?"":Qr(t)}var ca=wi((function(t,n){if(ho(n)||Mu(n))yi(n,wa(n),t);else for(var e in n)Ct.call(n,e)&&He(t,e,n[e])})),la=wi((function(t,n){yi(n,xa(n),t)})),fa=wi((function(t,n,e,r){yi(n,xa(n),t,r)})),ha=wi((function(t,n,e,r){yi(n,wa(n),t,r)})),da=Fi(Ve);var va=Dr((function(t,n){t=vt(t);var e=-1,r=n.length,i=r>2?n[2]:void 0;for(i&&so(n[0],n[1],i)&&(r=1);++e1),n})),yi(t,Gi(t),e),r&&(e=Je(e,7,qi));for(var i=n.length;i--;)ti(e,n[i]);return e}));var La=Fi((function(t,n){return null==t?{}:function(t,n){return Ar(t,n,(function(n,e){return _a(t,e)}))}(t,n)}));function Ta(t,n){if(null==t)return{};var e=dn(Gi(t),(function(t){return[t]}));return n=Ji(n),Ar(t,e,(function(t,e){return n(t,e[0])}))}var $a=Di(wa),Oa=Di(xa);function ja(t){return null==t?[]:Pn(t,wa(t))}var Ea=Si((function(t,n,e){return n=n.toLowerCase(),t+(e?Pa(n):n)}));function Pa(t){return Wa(sa(t).toLowerCase())}function Ba(t){return(t=sa(t))&&t.replace(st,Rn).replace(Pt,"")}var Aa=Si((function(t,n,e){return t+(e?"-":"")+n.toLowerCase()})),Ia=Si((function(t,n,e){return t+(e?" ":"")+n.toLowerCase()})),Ma=ki("toLowerCase");var Ra=Si((function(t,n,e){return t+(e?"_":"")+n.toLowerCase()}));var Na=Si((function(t,n,e){return t+(e?" ":"")+Wa(n)}));var Da=Si((function(t,n,e){return t+(e?" ":"")+n.toUpperCase()})),Wa=ki("toUpperCase");function za(t,n,e){return t=sa(t),void 0===(n=e?void 0:n)?function(t){return Mt.test(t)}(t)?function(t){return t.match(At)||[]}(t):function(t){return t.match(Q)||[]}(t):t.match(n)||[]}var Ua=Dr((function(t,n){try{return on(t,void 0,n)}catch(t){return Wu(t)?t:new ft(t)}})),qa=Fi((function(t,n){return an(n,(function(n){n=To(n),Ke(t,n,yu(t[n],t))})),t}));function Ha(t){return function(){return t}}var Fa=$i(),Ya=$i(!0);function Ga(t){return t}function Ka(t){return kr("function"==typeof t?t:Je(t,1))}var Va=Dr((function(t,n){return function(e){return yr(e,t,n)}})),Za=Dr((function(t,n){return function(e){return yr(t,e,n)}}));function Ja(t,n,e){var r=wa(n),i=fr(n,r);null!=e||Hu(n)&&(i.length||!r.length)||(e=n,n=t,t=this,i=fr(n,wa(n)));var o=!(Hu(e)&&"chain"in e&&!e.chain),u=zu(t);return an(i,(function(e){var r=n[e];t[e]=r,u&&(t.prototype[e]=function(){var n=this.__chain__;if(o||n){var e=t(this.__wrapped__),i=e.__actions__=mi(this.__actions__);return i.push({func:r,args:arguments,thisArg:t}),e.__chain__=n,e}return r.apply(t,vn([this.value()],arguments))})})),t}function Qa(){}var Xa=Pi(dn),ts=Pi(cn),ns=Pi(_n);function es(t){return co(t)?Sn(To(t)):function(t){return function(n){return hr(n,t)}}(t)}var rs=Ai(),is=Ai(!0);function os(){return[]}function us(){return!1}var as=Ei((function(t,n){return t+n}),0),ss=Ri("ceil"),cs=Ei((function(t,n){return t/n}),1),ls=Ri("floor");var fs,hs=Ei((function(t,n){return t*n}),1),ds=Ri("round"),vs=Ei((function(t,n){return t-n}),0);return Oe.after=function(t,n){if("function"!=typeof n)throw new _t(i);return t=ia(t),function(){if(--t<1)return n.apply(this,arguments)}},Oe.ary=_u,Oe.assign=ca,Oe.assignIn=la,Oe.assignInWith=fa,Oe.assignWith=ha,Oe.at=da,Oe.before=mu,Oe.bind=yu,Oe.bindAll=qa,Oe.bindKey=bu,Oe.castArray=function(){if(!arguments.length)return[];var t=arguments[0];return Au(t)?t:[t]},Oe.chain=eu,Oe.chunk=function(t,n,e){n=(e?so(t,n,e):void 0===n)?1:ae(ia(n),0);var i=null==t?0:t.length;if(!i||n<1)return[];for(var o=0,u=0,a=r(te(i/n));oi?0:i+e),(r=void 0===r||r>i?i:ia(r))<0&&(r+=i),r=e>r?0:oa(r);e>>0)?(t=sa(t))&&("string"==typeof n||null!=n&&!Vu(n))&&!(n=Qr(n))&&Wn(t)?li(Gn(t),0,e):t.split(n,e):[]},Oe.spread=function(t,n){if("function"!=typeof t)throw new _t(i);return n=null==n?0:ae(ia(n),0),Dr((function(e){var r=e[n],i=li(e,0,n);return r&&vn(i,r),on(t,this,i)}))},Oe.tail=function(t){var n=null==t?0:t.length;return n?Yr(t,1,n):[]},Oe.take=function(t,n,e){return t&&t.length?Yr(t,0,(n=e||void 0===n?1:ia(n))<0?0:n):[]},Oe.takeRight=function(t,n,e){var r=null==t?0:t.length;return r?Yr(t,(n=r-(n=e||void 0===n?1:ia(n)))<0?0:n,r):[]},Oe.takeRightWhile=function(t,n){return t&&t.length?ei(t,Ji(n,3),!1,!0):[]},Oe.takeWhile=function(t,n){return t&&t.length?ei(t,Ji(n,3)):[]},Oe.tap=function(t,n){return n(t),t},Oe.throttle=function(t,n,e){var r=!0,o=!0;if("function"!=typeof t)throw new _t(i);return Hu(e)&&(r="leading"in e?!!e.leading:r,o="trailing"in e?!!e.trailing:o),wu(t,n,{leading:r,maxWait:n,trailing:o})},Oe.thru=ru,Oe.toArray=ea,Oe.toPairs=$a,Oe.toPairsIn=Oa,Oe.toPath=function(t){return Au(t)?dn(t,To):Qu(t)?[t]:mi(Lo(sa(t)))},Oe.toPlainObject=aa,Oe.transform=function(t,n,e){var r=Au(t),i=r||Nu(t)||Xu(t);if(n=Ji(n,4),null==e){var o=t&&t.constructor;e=i?r?new o:[]:Hu(t)&&zu(o)?je(Ht(t)):{}}return(i?an:cr)(t,(function(t,r,i){return n(e,t,r,i)})),e},Oe.unary=function(t){return _u(t,1)},Oe.union=Fo,Oe.unionBy=Yo,Oe.unionWith=Go,Oe.uniq=function(t){return t&&t.length?Xr(t):[]},Oe.uniqBy=function(t,n){return t&&t.length?Xr(t,Ji(n,2)):[]},Oe.uniqWith=function(t,n){return n="function"==typeof n?n:void 0,t&&t.length?Xr(t,void 0,n):[]},Oe.unset=function(t,n){return null==t||ti(t,n)},Oe.unzip=Ko,Oe.unzipWith=Vo,Oe.update=function(t,n,e){return null==t?t:ni(t,n,ai(e))},Oe.updateWith=function(t,n,e,r){return r="function"==typeof r?r:void 0,null==t?t:ni(t,n,ai(e),r)},Oe.values=ja,Oe.valuesIn=function(t){return null==t?[]:Pn(t,xa(t))},Oe.without=Zo,Oe.words=za,Oe.wrap=function(t,n){return Tu(ai(n),t)},Oe.xor=Jo,Oe.xorBy=Qo,Oe.xorWith=Xo,Oe.zip=tu,Oe.zipObject=function(t,n){return oi(t||[],n||[],He)},Oe.zipObjectDeep=function(t,n){return oi(t||[],n||[],Ur)},Oe.zipWith=nu,Oe.entries=$a,Oe.entriesIn=Oa,Oe.extend=la,Oe.extendWith=fa,Ja(Oe,Oe),Oe.add=as,Oe.attempt=Ua,Oe.camelCase=Ea,Oe.capitalize=Pa,Oe.ceil=ss,Oe.clamp=function(t,n,e){return void 0===e&&(e=n,n=void 0),void 0!==e&&(e=(e=ua(e))==e?e:0),void 0!==n&&(n=(n=ua(n))==n?n:0),Ze(ua(t),n,e)},Oe.clone=function(t){return Je(t,4)},Oe.cloneDeep=function(t){return Je(t,5)},Oe.cloneDeepWith=function(t,n){return Je(t,5,n="function"==typeof n?n:void 0)},Oe.cloneWith=function(t,n){return Je(t,4,n="function"==typeof n?n:void 0)},Oe.conformsTo=function(t,n){return null==n||Qe(t,n,wa(n))},Oe.deburr=Ba,Oe.defaultTo=function(t,n){return null==t||t!=t?n:t},Oe.divide=cs,Oe.endsWith=function(t,n,e){t=sa(t),n=Qr(n);var r=t.length,i=e=void 0===e?r:Ze(ia(e),0,r);return(e-=n.length)>=0&&t.slice(e,i)==n},Oe.eq=ju,Oe.escape=function(t){return(t=sa(t))&&N.test(t)?t.replace(M,Nn):t},Oe.escapeRegExp=function(t){return(t=sa(t))&&Y.test(t)?t.replace(F,"\\$&"):t},Oe.every=function(t,n,e){var r=Au(t)?cn:rr;return e&&so(t,n,e)&&(n=void 0),r(t,Ji(n,3))},Oe.find=uu,Oe.findIndex=Bo,Oe.findKey=function(t,n){return yn(t,Ji(n,3),cr)},Oe.findLast=au,Oe.findLastIndex=Ao,Oe.findLastKey=function(t,n){return yn(t,Ji(n,3),lr)},Oe.floor=ls,Oe.forEach=su,Oe.forEachRight=cu,Oe.forIn=function(t,n){return null==t?t:ar(t,Ji(n,3),xa)},Oe.forInRight=function(t,n){return null==t?t:sr(t,Ji(n,3),xa)},Oe.forOwn=function(t,n){return t&&cr(t,Ji(n,3))},Oe.forOwnRight=function(t,n){return t&&lr(t,Ji(n,3))},Oe.get=ga,Oe.gt=Eu,Oe.gte=Pu,Oe.has=function(t,n){return null!=t&&io(t,n,gr)},Oe.hasIn=_a,Oe.head=Mo,Oe.identity=Ga,Oe.includes=function(t,n,e,r){t=Mu(t)?t:ja(t),e=e&&!r?ia(e):0;var i=t.length;return e<0&&(e=ae(i+e,0)),Ju(t)?e<=i&&t.indexOf(n,e)>-1:!!i&&wn(t,n,e)>-1},Oe.indexOf=function(t,n,e){var r=null==t?0:t.length;if(!r)return-1;var i=null==e?0:ia(e);return i<0&&(i=ae(r+i,0)),wn(t,n,i)},Oe.inRange=function(t,n,e){return n=ra(n),void 0===e?(e=n,n=0):e=ra(e),function(t,n,e){return t>=se(n,e)&&t=-9007199254740991&&t<=9007199254740991},Oe.isSet=Zu,Oe.isString=Ju,Oe.isSymbol=Qu,Oe.isTypedArray=Xu,Oe.isUndefined=function(t){return void 0===t},Oe.isWeakMap=function(t){return Fu(t)&&ro(t)==w},Oe.isWeakSet=function(t){return Fu(t)&&"[object WeakSet]"==vr(t)},Oe.join=function(t,n){return null==t?"":oe.call(t,n)},Oe.kebabCase=Aa,Oe.last=Wo,Oe.lastIndexOf=function(t,n,e){var r=null==t?0:t.length;if(!r)return-1;var i=r;return void 0!==e&&(i=(i=ia(e))<0?ae(r+i,0):se(i,r-1)),n==n?function(t,n,e){for(var r=e+1;r--;)if(t[r]===n)return r;return r}(t,n,i):bn(t,Cn,i,!0)},Oe.lowerCase=Ia,Oe.lowerFirst=Ma,Oe.lt=ta,Oe.lte=na,Oe.max=function(t){return t&&t.length?ir(t,Ga,pr):void 0},Oe.maxBy=function(t,n){return t&&t.length?ir(t,Ji(n,2),pr):void 0},Oe.mean=function(t){return kn(t,Ga)},Oe.meanBy=function(t,n){return kn(t,Ji(n,2))},Oe.min=function(t){return t&&t.length?ir(t,Ga,Tr):void 0},Oe.minBy=function(t,n){return t&&t.length?ir(t,Ji(n,2),Tr):void 0},Oe.stubArray=os,Oe.stubFalse=us,Oe.stubObject=function(){return{}},Oe.stubString=function(){return""},Oe.stubTrue=function(){return!0},Oe.multiply=hs,Oe.nth=function(t,n){return t&&t.length?Pr(t,ia(n)):void 0},Oe.noConflict=function(){return Yt._===this&&(Yt._=$t),this},Oe.noop=Qa,Oe.now=gu,Oe.pad=function(t,n,e){t=sa(t);var r=(n=ia(n))?Yn(t):0;if(!n||r>=n)return t;var i=(n-r)/2;return Bi(ne(i),e)+t+Bi(te(i),e)},Oe.padEnd=function(t,n,e){t=sa(t);var r=(n=ia(n))?Yn(t):0;return n&&rn){var r=t;t=n,n=r}if(e||t%1||n%1){var i=fe();return se(t+i*(n-t+Ut("1e-"+((i+"").length-1))),n)}return Rr(t,n)},Oe.reduce=function(t,n,e){var r=Au(t)?pn:Tn,i=arguments.length<3;return r(t,Ji(n,4),e,i,nr)},Oe.reduceRight=function(t,n,e){var r=Au(t)?gn:Tn,i=arguments.length<3;return r(t,Ji(n,4),e,i,er)},Oe.repeat=function(t,n,e){return n=(e?so(t,n,e):void 0===n)?1:ia(n),Nr(sa(t),n)},Oe.replace=function(){var t=arguments,n=sa(t[0]);return t.length<3?n:n.replace(t[1],t[2])},Oe.result=function(t,n,e){var r=-1,i=(n=si(n,t)).length;for(i||(i=1,t=void 0);++r9007199254740991)return[];var e=4294967295,r=se(t,4294967295);t-=4294967295;for(var i=On(r,n=Ji(n));++e=o)return t;var a=e-Yn(r);if(a<1)return r;var s=u?li(u,0,a).join(""):t.slice(0,a);if(void 0===i)return s+r;if(u&&(a+=s.length-a),Vu(i)){if(t.slice(a).search(i)){var c,l=s;for(i.global||(i=pt(i.source,sa(et.exec(i))+"g")),i.lastIndex=0;c=i.exec(l);)var f=c.index;s=s.slice(0,void 0===f?a:f)}}else if(t.indexOf(Qr(i),a)!=a){var h=s.lastIndexOf(i);h>-1&&(s=s.slice(0,h))}return s+r},Oe.unescape=function(t){return(t=sa(t))&&R.test(t)?t.replace(I,Vn):t},Oe.uniqueId=function(t){var n=++kt;return sa(t)+n},Oe.upperCase=Da,Oe.upperFirst=Wa,Oe.each=su,Oe.eachRight=cu,Oe.first=Mo,Ja(Oe,(fs={},cr(Oe,(function(t,n){Ct.call(Oe.prototype,n)||(fs[n]=t)})),fs),{chain:!1}),Oe.VERSION="4.17.21",an(["bind","bindKey","curry","curryRight","partial","partialRight"],(function(t){Oe[t].placeholder=Oe})),an(["drop","take"],(function(t,n){Be.prototype[t]=function(e){e=void 0===e?1:ae(ia(e),0);var r=this.__filtered__&&!n?new Be(this):this.clone();return r.__filtered__?r.__takeCount__=se(e,r.__takeCount__):r.__views__.push({size:se(e,4294967295),type:t+(r.__dir__<0?"Right":"")}),r},Be.prototype[t+"Right"]=function(n){return this.reverse()[t](n).reverse()}})),an(["filter","map","takeWhile"],(function(t,n){var e=n+1,r=1==e||3==e;Be.prototype[t]=function(t){var n=this.clone();return n.__iteratees__.push({iteratee:Ji(t,3),type:e}),n.__filtered__=n.__filtered__||r,n}})),an(["head","last"],(function(t,n){var e="take"+(n?"Right":"");Be.prototype[t]=function(){return this[e](1).value()[0]}})),an(["initial","tail"],(function(t,n){var e="drop"+(n?"":"Right");Be.prototype[t]=function(){return this.__filtered__?new Be(this):this[e](1)}})),Be.prototype.compact=function(){return this.filter(Ga)},Be.prototype.find=function(t){return this.filter(t).head()},Be.prototype.findLast=function(t){return this.reverse().find(t)},Be.prototype.invokeMap=Dr((function(t,n){return"function"==typeof t?new Be(this):this.map((function(e){return yr(e,t,n)}))})),Be.prototype.reject=function(t){return this.filter(Su(Ji(t)))},Be.prototype.slice=function(t,n){t=ia(t);var e=this;return e.__filtered__&&(t>0||n<0)?new Be(e):(t<0?e=e.takeRight(-t):t&&(e=e.drop(t)),void 0!==n&&(e=(n=ia(n))<0?e.dropRight(-n):e.take(n-t)),e)},Be.prototype.takeRightWhile=function(t){return this.reverse().takeWhile(t).reverse()},Be.prototype.toArray=function(){return this.take(4294967295)},cr(Be.prototype,(function(t,n){var e=/^(?:filter|find|map|reject)|While$/.test(n),r=/^(?:head|last)$/.test(n),i=Oe[r?"take"+("last"==n?"Right":""):n],o=r||/^find/.test(n);i&&(Oe.prototype[n]=function(){var n=this.__wrapped__,u=r?[1]:arguments,a=n instanceof Be,s=u[0],c=a||Au(n),l=function(t){var n=i.apply(Oe,vn([t],u));return r&&f?n[0]:n};c&&e&&"function"==typeof s&&1!=s.length&&(a=c=!1);var f=this.__chain__,h=!!this.__actions__.length,d=o&&!f,v=a&&!h;if(!o&&c){n=v?n:new Be(this);var p=t.apply(n,u);return p.__actions__.push({func:ru,args:[l],thisArg:void 0}),new Pe(p,f)}return d&&v?t.apply(this,u):(p=this.thru(l),d?r?p.value()[0]:p.value():p)})})),an(["pop","push","shift","sort","splice","unshift"],(function(t){var n=mt[t],e=/^(?:push|sort|unshift)$/.test(t)?"tap":"thru",r=/^(?:pop|shift)$/.test(t);Oe.prototype[t]=function(){var t=arguments;if(r&&!this.__chain__){var i=this.value();return n.apply(Au(i)?i:[],t)}return this[e]((function(e){return n.apply(Au(e)?e:[],t)}))}})),cr(Be.prototype,(function(t,n){var e=Oe[n];if(e){var r=e.name+"";Ct.call(be,r)||(be[r]=[]),be[r].push({name:n,func:e})}})),be[Oi(void 0,2).name]=[{name:"wrapper",func:void 0}],Be.prototype.clone=function(){var t=new Be(this.__wrapped__);return t.__actions__=mi(this.__actions__),t.__dir__=this.__dir__,t.__filtered__=this.__filtered__,t.__iteratees__=mi(this.__iteratees__),t.__takeCount__=this.__takeCount__,t.__views__=mi(this.__views__),t},Be.prototype.reverse=function(){if(this.__filtered__){var t=new Be(this);t.__dir__=-1,t.__filtered__=!0}else(t=this.clone()).__dir__*=-1;return t},Be.prototype.value=function(){var t=this.__wrapped__.value(),n=this.__dir__,e=Au(t),r=n<0,i=e?t.length:0,o=function(t,n,e){var r=-1,i=e.length;for(;++r=this.__values__.length;return{done:t,value:t?void 0:this.__values__[this.__index__++]}},Oe.prototype.plant=function(t){for(var n,e=this;e instanceof Ee;){var r=Oo(e);r.__index__=0,r.__values__=void 0,n?i.__wrapped__=r:n=r;var i=r;e=e.__wrapped__}return i.__wrapped__=t,n},Oe.prototype.reverse=function(){var t=this.__wrapped__;if(t instanceof Be){var n=t;return this.__actions__.length&&(n=new Be(this)),(n=n.reverse()).__actions__.push({func:ru,args:[Ho],thisArg:void 0}),new Pe(n,this.__chain__)}return this.thru(Ho)},Oe.prototype.toJSON=Oe.prototype.valueOf=Oe.prototype.value=function(){return ri(this.__wrapped__,this.__actions__)},Oe.prototype.first=Oe.prototype.head,Jt&&(Oe.prototype[Jt]=function(){return this}),Oe}();Yt._=Zn,void 0===(r=function(){return Zn}.call(n,e,n,t))||(t.exports=r)}).call(this)}).call(this,e(48)(t))},354:function(t,n,e){"use strict";e(329)},361:function(t,n,e){"use strict";e.r(n);var r=e(355),i=e(330),o=e(356),u=e(337),a=e(343),s=e(331),c=e(342),l=e(335),f=e(338),h=e(334),d=e(11),v=e(304),p=e(353),g=e.n(p);var _={components:{Home:r.default,Navbar:i.default,Page:o.default,CategoriesPage:u.default,TagsPage:a.default,ArchivesPage:s.default,Sidebar:c.default,Footer:f.default,Buttons:l.default,BodyBgImg:h.default},data:()=>({hideNavbar:!1,isSidebarOpen:!0,showSidebar:!1,themeMode:"auto",showWindowLB:!0,showWindowRB:!0}),computed:{sidebarSlotTop(){return this.getHtmlStr("sidebarT")},sidebarSlotBottom(){return this.getHtmlStr("sidebarB")},pageSlotTop(){return this.getHtmlStr("pageT")},pageSlotBottom(){return this.getHtmlStr("pageB")},windowLB(){return this.getHtmlStr("windowLB")},windowRB(){return this.getHtmlStr("windowRB")},showRightMenu(){const{headers:t}=this.$page;return!this.$frontmatter.home&&!1!==this.$themeConfig.rightMenuBar&&t&&t.length&&!1!==this.$frontmatter.sidebar},shouldShowNavbar(){const{themeConfig:t}=this.$site,{frontmatter:n}=this.$page;return!1!==n.navbar&&!1!==t.navbar&&(this.$title||t.logo||t.repo||t.nav||this.$themeLocaleConfig.nav)},shouldShowSidebar(){const{frontmatter:t}=this.$page;return!t.home&&!1!==t.sidebar&&this.sidebarItems.length&&!1!==t.showSidebar},sidebarItems(){return Object(d.m)(this.$page,this.$page.regularPath,this.$site,this.$localePath)},pageClasses(){const t=this.$page.frontmatter.pageClass;return[{"no-navbar":!this.shouldShowNavbar,"hide-navbar":this.hideNavbar,"sidebar-open":this.isSidebarOpen,"no-sidebar":!this.shouldShowSidebar,"have-rightmenu":this.showRightMenu,"have-body-img":this.$themeConfig.bodyBgImg,"only-sidebarItem":1===this.sidebarItems.length&&"page"===this.sidebarItems[0].type},t]}},created(){const t=this.$themeConfig.sidebarOpen;!1===t&&(this.isSidebarOpen=t)},beforeMount(){this.isSidebarOpenOfclientWidth();const t=v.a.get("mode"),{defaultMode:n}=this.$themeConfig;n&&"auto"!==n&&!t?this.themeMode=n:t&&"auto"!==t&&"auto"!==n?this.themeMode=t:this._autoMode(),this.setBodyClass();const e=this.$themeConfig.social;if(e&&e.iconfontCssFile){let t=document.createElement("link");t.setAttribute("rel","stylesheet"),t.setAttribute("type","text/css"),t.setAttribute("href",e.iconfontCssFile),document.head.appendChild(t)}},mounted(){const t=document.location.hash;if(t.length>1){const n=decodeURIComponent(t.substring(1)),e=document.getElementById(n);e&&e.scrollIntoView()}this.showSidebar=!0,this.$router.afterEach(()=>{this.isSidebarOpenOfclientWidth()});let n=0,e=0;window.addEventListener("scroll",g.a.throttle(()=>{this.isSidebarOpen||(n=this.getScrollTop(),this.hideNavbar=e58,setTimeout(()=>{e=n},0))},300))},watch:{isSidebarOpen(){this.isSidebarOpen&&(this.hideNavbar=!1)},themeMode(){this.setBodyClass()}},methods:{getHtmlStr(t){const{htmlModules:n}=this.$themeConfig;return n?n[t]:""},setBodyClass(){let{pageStyle:t="card",bodyBgImg:n}=this.$themeConfig;("card"!==t&&"line"!==t||n)&&(t="card"),document.body.className=`theme-mode-${this.themeMode} theme-style-${t}`},getScrollTop:()=>window.pageYOffset||document.documentElement.scrollTop||document.body.scrollTop||0,isSidebarOpenOfclientWidth(){document.documentElement.clientWidth<719&&(this.isSidebarOpen=!1)},toggleSidebar(t){this.isSidebarOpen="boolean"==typeof t?t:!this.isSidebarOpen,this.$emit("toggle-sidebar",this.isSidebarOpen)},_autoMode(){window.matchMedia("(prefers-color-scheme: dark)").matches?this.themeMode="dark":this.themeMode="light"},toggleThemeMode(t){"auto"===t?this._autoMode():this.themeMode=t,v.a.set("mode",t)},onTouchStart(t){this.touchStart={x:t.changedTouches[0].clientX,y:t.changedTouches[0].clientY}},onTouchEnd(t){const n=t.changedTouches[0].clientX-this.touchStart.x,e=t.changedTouches[0].clientY-this.touchStart.y;Math.abs(n)>Math.abs(e)&&Math.abs(n)>40&&(n>0&&this.touchStart.x<=80?this.toggleSidebar(!0):this.toggleSidebar(!1))}}},m=(e(354),e(4)),y=Object(m.a)(_,(function(){var t=this,n=t._self._c;return n("div",{staticClass:"theme-container",class:t.pageClasses,on:{touchstart:t.onTouchStart,touchend:t.onTouchEnd}},[t.shouldShowNavbar?n("Navbar",{on:{"toggle-sidebar":t.toggleSidebar}}):t._e(),t._v(" "),n("div",{staticClass:"sidebar-mask",on:{click:function(n){return t.toggleSidebar(!1)}}}),t._v(" "),!1!==t.$themeConfig.sidebarHoverTriggerOpen?n("div",{staticClass:"sidebar-hover-trigger"}):t._e(),t._v(" "),n("Sidebar",{directives:[{name:"show",rawName:"v-show",value:t.showSidebar,expression:"showSidebar"}],attrs:{items:t.sidebarItems},on:{"toggle-sidebar":t.toggleSidebar},scopedSlots:t._u([t.sidebarSlotTop?{key:"top",fn:function(){return[n("div",{staticClass:"sidebar-slot sidebar-slot-top",domProps:{innerHTML:t._s(t.sidebarSlotTop)}})]},proxy:!0}:null,t.sidebarSlotBottom?{key:"bottom",fn:function(){return[n("div",{staticClass:"sidebar-slot sidebar-slot-bottom",domProps:{innerHTML:t._s(t.sidebarSlotBottom)}})]},proxy:!0}:null],null,!0)}),t._v(" "),t.$page.frontmatter.home?n("Home"):t.$page.frontmatter.categoriesPage?n("CategoriesPage"):t.$page.frontmatter.tagsPage?n("TagsPage"):t.$page.frontmatter.archivesPage?n("ArchivesPage"):n("Page",{attrs:{"sidebar-items":t.sidebarItems},scopedSlots:t._u([t.pageSlotTop?{key:"top",fn:function(){return[n("div",{staticClass:"page-slot page-slot-top",domProps:{innerHTML:t._s(t.pageSlotTop)}})]},proxy:!0}:null,t.pageSlotBottom?{key:"bottom",fn:function(){return[n("div",{staticClass:"page-slot page-slot-bottom",domProps:{innerHTML:t._s(t.pageSlotBottom)}})]},proxy:!0}:null],null,!0)}),t._v(" "),n("Footer"),t._v(" "),n("Buttons",{ref:"buttons",on:{"toggle-theme-mode":t.toggleThemeMode}}),t._v(" "),t.$themeConfig.bodyBgImg?n("BodyBgImg"):t._e(),t._v(" "),t.windowLB?n("div",{directives:[{name:"show",rawName:"v-show",value:t.showWindowLB,expression:"showWindowLB"}],staticClass:"custom-html-window custom-html-window-lb"},[n("div",{staticClass:"custom-wrapper"},[n("span",{staticClass:"close-but",on:{click:function(n){t.showWindowLB=!1}}},[t._v("×")]),t._v(" "),n("div",{domProps:{innerHTML:t._s(t.windowLB)}})])]):t._e(),t._v(" "),t.windowRB?n("div",{directives:[{name:"show",rawName:"v-show",value:t.showWindowRB,expression:"showWindowRB"}],staticClass:"custom-html-window custom-html-window-rb"},[n("div",{staticClass:"custom-wrapper"},[n("span",{staticClass:"close-but",on:{click:function(n){t.showWindowRB=!1}}},[t._v("×")]),t._v(" "),n("div",{domProps:{innerHTML:t._s(t.windowRB)}})])]):t._e()],1)}),[],!1,null,null,null);n.default=y.exports}}]); \ No newline at end of file diff --git a/assets/js/30.65c53f6e.js b/assets/js/30.65c53f6e.js new file mode 100644 index 0000000000..0ef117184e --- /dev/null +++ b/assets/js/30.65c53f6e.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[30],{296:function(t,e,s){},320:function(t,e,s){"use strict";s(296)},341:function(t,e,s){"use strict";s.r(e);var a={data:()=>({headers:[],hashText:""}),mounted(){this.getHeadersData(),this.getHashText()},watch:{$route(){this.headers=this.$page.headers,this.getHashText()}},methods:{getHeadersData(){this.headers=this.$page.headers},getHashText(){this.hashText=decodeURIComponent(window.location.hash.slice(1))}}},i=(s(320),s(4)),h=Object(i.a)(a,(function(){var t=this,e=t._self._c;return e("div",{staticClass:"right-menu-wrapper"},[e("div",{staticClass:"right-menu-margin"},[e("div",{staticClass:"right-menu-title"},[t._v("目录")]),t._v(" "),e("div",{staticClass:"right-menu-content"},t._l(t.headers,(function(s,a){return e("div",{key:a,class:["right-menu-item","level"+s.level,{active:s.slug===t.hashText}]},[e("a",{attrs:{href:"#"+s.slug}},[t._v(t._s(s.title))])])})),0)])])}),[],!1,null,null,null);e.default=h.exports}}]); \ No newline at end of file diff --git a/assets/js/31.0ea24d9d.js b/assets/js/31.0ea24d9d.js new file mode 100644 index 0000000000..264c10fca2 --- /dev/null +++ b/assets/js/31.0ea24d9d.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[31],{265:function(t,c,n){},292:function(t,c,n){"use strict";n(265)},306:function(t,c,n){"use strict";n.r(c);n(292);var i=n(4),s=Object(i.a)({},(function(){var t=this,c=t._self._c;return c("div",{staticClass:"sidebar-button",attrs:{title:"目录"},on:{click:function(c){return t.$emit("toggle-sidebar")}}},[c("svg",{staticClass:"icon",attrs:{xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",role:"img",viewBox:"0 0 448 512"}},[c("path",{attrs:{fill:"currentColor",d:"M436 124H12c-6.627 0-12-5.373-12-12V80c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12z"}})])])}),[],!1,null,null,null);c.default=s.exports}}]); \ No newline at end of file diff --git a/assets/js/32.0181ccd5.js b/assets/js/32.0181ccd5.js new file mode 100644 index 0000000000..e6ecb1ba56 --- /dev/null +++ b/assets/js/32.0181ccd5.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[32],{260:function(e,t,r){},275:function(e,t,r){"use strict";r(260)},279:function(e,t,r){"use strict";r.r(t);var a=r(11);function s(e,t,r,a){return e("router-link",{props:{to:t,activeClass:"",exactActiveClass:""},class:{active:a,"sidebar-link":!0}},r)}function n(e,t,r,i,l,o=1){return!t||o>l?null:e("ul",{class:"sidebar-sub-headers"},t.map(t=>{const u=Object(a.f)(i,r+"#"+t.slug);return e("li",{class:"sidebar-sub-header level"+t.level},[s(e,r+"#"+t.slug,t.title,u),n(e,t.children,r,i,l,o+1)])}))}var i={functional:!0,props:["item","sidebarDepth"],render(e,{parent:{$page:t,$site:r,$route:i,$themeConfig:l,$themeLocaleConfig:o},props:{item:u,sidebarDepth:p}}){const c=Object(a.f)(i,u.path),d="auto"===u.type?c||u.children.some(e=>Object(a.f)(i,u.basePath+"#"+e.slug)):c,h="external"===u.type?function(e,t,r){return e("a",{attrs:{href:t,target:"_blank",rel:"noopener noreferrer"},class:{"sidebar-link":!0}},[r,e("OutboundLink")])}(e,u.path,u.title||u.path):s(e,u.path,u.title||u.path,d),b=[t.frontmatter.sidebarDepth,p,o.sidebarDepth,l.sidebarDepth,1].find(e=>void 0!==e),f=o.displayAllHeaders||l.displayAllHeaders;if("auto"===u.type)return[h,n(e,u.children,u.basePath,i,b)];if((d||f)&&u.headers&&!a.e.test(u.path)){return[h,n(e,Object(a.d)(u.headers),u.path,i,b)]}return h}},l=(r(275),r(4)),o=Object(l.a)(i,void 0,void 0,!1,null,null,null);t.default=o.exports}}]); \ No newline at end of file diff --git a/assets/js/33.f7b2a77f.js b/assets/js/33.f7b2a77f.js new file mode 100644 index 0000000000..1ce9829def --- /dev/null +++ b/assets/js/33.f7b2a77f.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[33],{264:function(t,a,e){},290:function(t,a,e){"use strict";e(264)},301:function(t,a,e){"use strict";e.r(a);e(25);var s={props:{tag:{type:String,default:""},tagsData:{type:Array,default:[]},length:{type:[String,Number],default:"all"}},data:()=>({tagBgColor:["#11a8cd","#F8B26A","#67CC86","#E15B64","#F47E60","#849B87"],tagStyleList:[]}),created(){for(let t=0,a=this.tags.length;tt.length?a("router-link",{attrs:{to:"/tags/"}},[t._v("更多...")]):t._e()],2)],1)}),[],!1,null,null,null);a.default=n.exports}}]); \ No newline at end of file diff --git a/assets/js/34.4d583feb.js b/assets/js/34.4d583feb.js new file mode 100644 index 0000000000..d66e8f56e6 --- /dev/null +++ b/assets/js/34.4d583feb.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[34,35],{263:function(t,e,s){},289:function(t,e,s){"use strict";s(263)},305:function(t,e,s){"use strict";s.r(e);var r={name:"UpdateArticle",props:{length:{type:[String,Number],default:3},moreArticle:String},data:()=>({posts:[],currentPath:""}),created(){this.posts=this.$site.pages,this.currentPath=this.$page.path},computed:{topPublishPosts(){return this.$sortPostsByDate?this.$sortPostsByDate.filter(t=>{const{path:e}=t;return e!==this.currentPath}).slice(0,this.length):[]},isShowArticle(){const{frontmatter:t}=this.$page;return!(!1!==t.article)}},methods:{getNum:t=>t<9?"0"+(t+1):t+1,getDate:t=>t.frontmatter.date?t.frontmatter.date.split(" ")[0].slice(5,10):""},watch:{$route(){this.currentPath=this.$page.path}}},i=(s(289),s(4)),a=Object(i.a)(r,(function(){var t=this,e=t._self._c;return e("div",{class:["article-list",{"no-article-list":t.isShowArticle}]},[e("div",{staticClass:"article-title"},[e("router-link",{staticClass:"iconfont icon-bi",attrs:{to:t.moreArticle||"/archives/"}},[t._v("最近更新")])],1),t._v(" "),e("div",{staticClass:"article-wrapper"},[t._l(t.topPublishPosts,(function(s,r){return e("dl",{key:r},[e("dd",[t._v(t._s(t.getNum(r)))]),t._v(" "),e("dt",[e("router-link",{attrs:{to:s.path}},[e("div",[t._v("\n "+t._s(s.title)+"\n "),s.frontmatter.titleTag?e("span",{staticClass:"title-tag"},[t._v("\n "+t._s(s.frontmatter.titleTag)+"\n ")]):t._e()])]),t._v(" "),e("span",{staticClass:"date"},[t._v(t._s(t.getDate(s)))])],1)])})),t._v(" "),e("dl",[e("dd"),t._v(" "),e("dt",[e("router-link",{staticClass:"more",attrs:{to:t.moreArticle||"/archives/"}},[t._v("更多文章>")])],1)])],2)])}),[],!1,null,null,null);e.default=a.exports}}]); \ No newline at end of file diff --git a/assets/js/35.d32af94e.js b/assets/js/35.d32af94e.js new file mode 100644 index 0000000000..39d3072b12 --- /dev/null +++ b/assets/js/35.d32af94e.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[35,34],{263:function(t,e,s){},289:function(t,e,s){"use strict";s(263)},305:function(t,e,s){"use strict";s.r(e);var r={name:"UpdateArticle",props:{length:{type:[String,Number],default:3},moreArticle:String},data:()=>({posts:[],currentPath:""}),created(){this.posts=this.$site.pages,this.currentPath=this.$page.path},computed:{topPublishPosts(){return this.$sortPostsByDate?this.$sortPostsByDate.filter(t=>{const{path:e}=t;return e!==this.currentPath}).slice(0,this.length):[]},isShowArticle(){const{frontmatter:t}=this.$page;return!(!1!==t.article)}},methods:{getNum:t=>t<9?"0"+(t+1):t+1,getDate:t=>t.frontmatter.date?t.frontmatter.date.split(" ")[0].slice(5,10):""},watch:{$route(){this.currentPath=this.$page.path}}},i=(s(289),s(4)),a=Object(i.a)(r,(function(){var t=this,e=t._self._c;return e("div",{class:["article-list",{"no-article-list":t.isShowArticle}]},[e("div",{staticClass:"article-title"},[e("router-link",{staticClass:"iconfont icon-bi",attrs:{to:t.moreArticle||"/archives/"}},[t._v("最近更新")])],1),t._v(" "),e("div",{staticClass:"article-wrapper"},[t._l(t.topPublishPosts,(function(s,r){return e("dl",{key:r},[e("dd",[t._v(t._s(t.getNum(r)))]),t._v(" "),e("dt",[e("router-link",{attrs:{to:s.path}},[e("div",[t._v("\n "+t._s(s.title)+"\n "),s.frontmatter.titleTag?e("span",{staticClass:"title-tag"},[t._v("\n "+t._s(s.frontmatter.titleTag)+"\n ")]):t._e()])]),t._v(" "),e("span",{staticClass:"date"},[t._v(t._s(t.getDate(s)))])],1)])})),t._v(" "),e("dl",[e("dd"),t._v(" "),e("dt",[e("router-link",{staticClass:"more",attrs:{to:t.moreArticle||"/archives/"}},[t._v("更多文章>")])],1)])],2)])}),[],!1,null,null,null);e.default=a.exports}}]); \ No newline at end of file diff --git a/assets/js/36.523cc6b8.js b/assets/js/36.523cc6b8.js new file mode 100644 index 0000000000..69570ea1e5 --- /dev/null +++ b/assets/js/36.523cc6b8.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[36],{362:function(t,e,r){"use strict";r.r(e);var o={props:{text:{type:String,required:!0},color:{type:String,default:"black"}},computed:{textColor(){return{red:"red",green:"green"}[this.color]||"black"}}},n=r(4),s=Object(n.a)(o,(function(){return(0,this._self._c)("span",{style:{color:this.textColor}},[this._v(this._s(this.text))])}),[],!1,null,"6e002b02",null);e.default=s.exports}}]); \ No newline at end of file diff --git a/assets/js/37.a3d1a0f1.js b/assets/js/37.a3d1a0f1.js new file mode 100644 index 0000000000..2c6fccf2ca --- /dev/null +++ b/assets/js/37.a3d1a0f1.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[37],{252:function(t,i,n){"use strict";n.r(i);var e=n(11),l={props:{item:{required:!0}},computed:{link(){return Object(e.c)(this.item.link)},exact(){return this.$site.locales?Object.keys(this.$site.locales).some(t=>t===this.link):"/"===this.link}},methods:{isExternal:e.g,isMailto:e.h,isTel:e.i,focusoutAction(){this.$emit("focusout")}}},s=n(4),o=Object(s.a)(l,(function(){var t=this,i=t._self._c;return t.isExternal(t.link)?i("a",{staticClass:"nav-link external",attrs:{href:t.link,target:t.isMailto(t.link)||t.isTel(t.link)?null:"_blank",rel:t.isMailto(t.link)||t.isTel(t.link)?null:"noopener noreferrer"},on:{focusout:t.focusoutAction}},[t._v("\n "+t._s(t.item.text)+"\n "),i("OutboundLink")],1):i("router-link",{staticClass:"nav-link",attrs:{to:t.link,exact:t.exact},nativeOn:{focusout:function(i){return t.focusoutAction.apply(null,arguments)}}},[t._v(t._s(t.item.text))])}),[],!1,null,null,null);i.default=o.exports}}]); \ No newline at end of file diff --git a/assets/js/38.d2f862be.js b/assets/js/38.d2f862be.js new file mode 100644 index 0000000000..5f477c9ad3 --- /dev/null +++ b/assets/js/38.d2f862be.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[38],{364:function(t,n,s){"use strict";s.r(n);var e=s(4),o=Object(e.a)({},(function(){return(0,this._self._c)("ContentSlotsDistributor",{attrs:{"slot-key":this.$parent.slotKey}})}),[],!1,null,null,null);n.default=o.exports}}]); \ No newline at end of file diff --git a/assets/js/39.add3f26d.js b/assets/js/39.add3f26d.js new file mode 100644 index 0000000000..3843b92363 --- /dev/null +++ b/assets/js/39.add3f26d.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[39],{365:function(t,n,s){"use strict";s.r(n);var e=s(4),o=Object(e.a)({},(function(){return(0,this._self._c)("ContentSlotsDistributor",{attrs:{"slot-key":this.$parent.slotKey}})}),[],!1,null,null,null);n.default=o.exports}}]); \ No newline at end of file diff --git a/assets/js/4.63f828c8.js b/assets/js/4.63f828c8.js new file mode 100644 index 0000000000..163249565d --- /dev/null +++ b/assets/js/4.63f828c8.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[4,25,32],{251:function(e,t,n){},254:function(e,t,n){"use strict";n.r(t);var i={name:"DropdownTransition",methods:{setHeight(e){e.style.height=e.scrollHeight+"px"},unsetHeight(e){e.style.height=""}}},s=(n(255),n(4)),r=Object(s.a)(i,(function(){return(0,this._self._c)("transition",{attrs:{name:"dropdown"},on:{enter:this.setHeight,"after-enter":this.unsetHeight,"before-leave":this.setHeight}},[this._t("default")],2)}),[],!1,null,null,null);t.default=r.exports},255:function(e,t,n){"use strict";n(251)},260:function(e,t,n){},266:function(e,t,n){},275:function(e,t,n){"use strict";n(260)},277:function(e,t,n){"use strict";n.r(t);var i=n(302),s=n(279),r=n(11);function a(e,t){return"group"===t.type&&t.children.some(t=>"group"===t.type?a(e,t):"page"===t.type&&Object(r.f)(e,t.path))}var o={name:"SidebarLinks",components:{SidebarGroup:i.default,SidebarLink:s.default},props:["items","depth","sidebarDepth","initialOpenGroupIndex"],data(){return{openGroupIndex:this.initialOpenGroupIndex||0}},created(){this.refreshIndex()},watch:{$route(){this.refreshIndex()}},methods:{refreshIndex(){const e=function(e,t){for(let n=0;n-1&&(this.openGroupIndex=e)},toggleGroup(e){this.openGroupIndex=e===this.openGroupIndex?-1:e},isActive(e){return Object(r.f)(this.$route,e.regularPath)}}},l=n(4),p=Object(l.a)(o,(function(){var e=this,t=e._self._c;return e.items.length?t("ul",{staticClass:"sidebar-links"},e._l(e.items,(function(n,i){return t("li",{key:i},["group"===n.type?t("SidebarGroup",{attrs:{item:n,open:i===e.openGroupIndex,collapsable:n.collapsable||n.collapsible,depth:e.depth},on:{toggle:function(t){return e.toggleGroup(i)}}}):t("SidebarLink",{attrs:{sidebarDepth:e.sidebarDepth,item:n}})],1)})),0):e._e()}),[],!1,null,null,null);t.default=p.exports},279:function(e,t,n){"use strict";n.r(t);var i=n(11);function s(e,t,n,i){return e("router-link",{props:{to:t,activeClass:"",exactActiveClass:""},class:{active:i,"sidebar-link":!0}},n)}function r(e,t,n,a,o,l=1){return!t||l>o?null:e("ul",{class:"sidebar-sub-headers"},t.map(t=>{const p=Object(i.f)(a,n+"#"+t.slug);return e("li",{class:"sidebar-sub-header level"+t.level},[s(e,n+"#"+t.slug,t.title,p),r(e,t.children,n,a,o,l+1)])}))}var a={functional:!0,props:["item","sidebarDepth"],render(e,{parent:{$page:t,$site:n,$route:a,$themeConfig:o,$themeLocaleConfig:l},props:{item:p,sidebarDepth:u}}){const c=Object(i.f)(a,p.path),d="auto"===p.type?c||p.children.some(e=>Object(i.f)(a,p.basePath+"#"+e.slug)):c,h="external"===p.type?function(e,t,n){return e("a",{attrs:{href:t,target:"_blank",rel:"noopener noreferrer"},class:{"sidebar-link":!0}},[n,e("OutboundLink")])}(e,p.path,p.title||p.path):s(e,p.path,p.title||p.path,d),b=[t.frontmatter.sidebarDepth,u,l.sidebarDepth,o.sidebarDepth,1].find(e=>void 0!==e),f=l.displayAllHeaders||o.displayAllHeaders;if("auto"===p.type)return[h,r(e,p.children,p.basePath,a,b)];if((d||f)&&p.headers&&!i.e.test(p.path)){return[h,r(e,Object(i.d)(p.headers),p.path,a,b)]}return h}},o=(n(275),n(4)),l=Object(o.a)(a,void 0,void 0,!1,null,null,null);t.default=l.exports},297:function(e,t,n){"use strict";n(266)},302:function(e,t,n){"use strict";n.r(t);var i=n(11),s={name:"SidebarGroup",props:["item","open","collapsable","depth"],components:{DropdownTransition:n(254).default},beforeCreate(){this.$options.components.SidebarLinks=n(277).default},methods:{isActive:i.f}},r=(n(297),n(4)),a=Object(r.a)(s,(function(){var e=this,t=e._self._c;return t("section",{staticClass:"sidebar-group",class:[{collapsable:e.collapsable,"is-sub-group":0!==e.depth},"depth-"+e.depth]},[e.item.path?t("router-link",{staticClass:"sidebar-heading clickable",class:{open:e.open,active:e.isActive(e.$route,e.item.path)},attrs:{to:e.item.path},nativeOn:{click:function(t){return e.$emit("toggle")}}},[t("span",[e._v(e._s(e.item.title))]),e._v(" "),e.collapsable?t("span",{staticClass:"arrow",class:e.open?"down":"right"}):e._e()]):t("p",{staticClass:"sidebar-heading",class:{open:e.open},on:{click:function(t){return e.$emit("toggle")}}},[t("span",[e._v(e._s(e.item.title))]),e._v(" "),e.collapsable?t("span",{staticClass:"arrow",class:e.open?"down":"right"}):e._e()]),e._v(" "),t("DropdownTransition",[e.open||!e.collapsable?t("SidebarLinks",{staticClass:"sidebar-group-items",attrs:{items:e.item.children,"sidebar-depth":e.item.sidebarDepth,"initial-open-group-index":e.item.initialOpenGroupIndex,depth:e.depth+1}}):e._e()],1)],1)}),[],!1,null,null,null);t.default=a.exports}}]); \ No newline at end of file diff --git a/assets/js/40.3c545622.js b/assets/js/40.3c545622.js new file mode 100644 index 0000000000..6c4fc7c325 --- /dev/null +++ b/assets/js/40.3c545622.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[40],{366:function(t,n,s){"use strict";s.r(n);var e=s(4),o=Object(e.a)({},(function(){return(0,this._self._c)("ContentSlotsDistributor",{attrs:{"slot-key":this.$parent.slotKey}})}),[],!1,null,null,null);n.default=o.exports}}]); \ No newline at end of file diff --git a/assets/js/41.aac1c8b8.js b/assets/js/41.aac1c8b8.js new file mode 100644 index 0000000000..abbad6df49 --- /dev/null +++ b/assets/js/41.aac1c8b8.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[41],{367:function(t,n,s){"use strict";s.r(n);var e=s(4),o=Object(e.a)({},(function(){return(0,this._self._c)("ContentSlotsDistributor",{attrs:{"slot-key":this.$parent.slotKey}})}),[],!1,null,null,null);n.default=o.exports}}]); \ No newline at end of file diff --git a/assets/js/42.9049242c.js b/assets/js/42.9049242c.js new file mode 100644 index 0000000000..4c870b654c --- /dev/null +++ b/assets/js/42.9049242c.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[42],{368:function(t,n,s){"use strict";s.r(n);var e=s(4),o=Object(e.a)({},(function(){return(0,this._self._c)("ContentSlotsDistributor",{attrs:{"slot-key":this.$parent.slotKey}})}),[],!1,null,null,null);n.default=o.exports}}]); \ No newline at end of file diff --git a/assets/js/43.95fe1066.js b/assets/js/43.95fe1066.js new file mode 100644 index 0000000000..c05a33d05b --- /dev/null +++ b/assets/js/43.95fe1066.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[43],{369:function(t,n,s){"use strict";s.r(n);var e=s(4),o=Object(e.a)({},(function(){return(0,this._self._c)("ContentSlotsDistributor",{attrs:{"slot-key":this.$parent.slotKey}})}),[],!1,null,null,null);n.default=o.exports}}]); \ No newline at end of file diff --git a/assets/js/44.234e85a1.js b/assets/js/44.234e85a1.js new file mode 100644 index 0000000000..ef0c467f45 --- /dev/null +++ b/assets/js/44.234e85a1.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[44],{370:function(t,n,s){"use strict";s.r(n);var e=s(4),o=Object(e.a)({},(function(){return(0,this._self._c)("ContentSlotsDistributor",{attrs:{"slot-key":this.$parent.slotKey}})}),[],!1,null,null,null);n.default=o.exports}}]); \ No newline at end of file diff --git a/assets/js/45.766c2ddd.js b/assets/js/45.766c2ddd.js new file mode 100644 index 0000000000..9fdc33bde7 --- /dev/null +++ b/assets/js/45.766c2ddd.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[45],{371:function(t,n,s){"use strict";s.r(n);var e=s(4),o=Object(e.a)({},(function(){return(0,this._self._c)("ContentSlotsDistributor",{attrs:{"slot-key":this.$parent.slotKey}})}),[],!1,null,null,null);n.default=o.exports}}]); \ No newline at end of file diff --git a/assets/js/46.baf712b6.js b/assets/js/46.baf712b6.js new file mode 100644 index 0000000000..72a739c6af --- /dev/null +++ b/assets/js/46.baf712b6.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[46],{372:function(t,n,s){"use strict";s.r(n);var e=s(4),o=Object(e.a)({},(function(){return(0,this._self._c)("ContentSlotsDistributor",{attrs:{"slot-key":this.$parent.slotKey}})}),[],!1,null,null,null);n.default=o.exports}}]); \ No newline at end of file diff --git a/assets/js/47.36f43ab8.js b/assets/js/47.36f43ab8.js new file mode 100644 index 0000000000..d7f999c1a5 --- /dev/null +++ b/assets/js/47.36f43ab8.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[47],{373:function(t,n,s){"use strict";s.r(n);var e=s(4),o=Object(e.a)({},(function(){return(0,this._self._c)("ContentSlotsDistributor",{attrs:{"slot-key":this.$parent.slotKey}})}),[],!1,null,null,null);n.default=o.exports}}]); \ No newline at end of file diff --git a/assets/js/48.566091e4.js b/assets/js/48.566091e4.js new file mode 100644 index 0000000000..fa2df1c56b --- /dev/null +++ b/assets/js/48.566091e4.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[48],{374:function(t,n,s){"use strict";s.r(n);var e=s(4),o=Object(e.a)({},(function(){return(0,this._self._c)("ContentSlotsDistributor",{attrs:{"slot-key":this.$parent.slotKey}})}),[],!1,null,null,null);n.default=o.exports}}]); \ No newline at end of file diff --git a/assets/js/49.fdd49479.js b/assets/js/49.fdd49479.js new file mode 100644 index 0000000000..5e50fba410 --- /dev/null +++ b/assets/js/49.fdd49479.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[49],{375:function(t,n,s){"use strict";s.r(n);var e=s(4),o=Object(e.a)({},(function(){return(0,this._self._c)("ContentSlotsDistributor",{attrs:{"slot-key":this.$parent.slotKey}})}),[],!1,null,null,null);n.default=o.exports}}]); \ No newline at end of file diff --git a/assets/js/5.b1b1df38.js b/assets/js/5.b1b1df38.js new file mode 100644 index 0000000000..fa149b883b --- /dev/null +++ b/assets/js/5.b1b1df38.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[5],{327:function(t,e,n){},351:function(t,e,n){"use strict";n(327)},363:function(t,e,n){"use strict";n.r(e);var i={functional:!0,props:{type:{type:String,default:"tip"},text:String,vertical:{type:String,default:"top"}},render:(t,{props:e,slots:n})=>t("span",{class:["badge",e.type],style:{verticalAlign:e.vertical}},e.text||n().default)},a=(n(351),n(4)),p=Object(a.a)(i,void 0,void 0,!1,null,"d5affa18",null);e.default=p.exports}}]); \ No newline at end of file diff --git a/assets/js/50.ecf93ba1.js b/assets/js/50.ecf93ba1.js new file mode 100644 index 0000000000..0a8391b413 --- /dev/null +++ b/assets/js/50.ecf93ba1.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[50],{376:function(t,n,s){"use strict";s.r(n);var e=s(4),o=Object(e.a)({},(function(){return(0,this._self._c)("ContentSlotsDistributor",{attrs:{"slot-key":this.$parent.slotKey}})}),[],!1,null,null,null);n.default=o.exports}}]); \ No newline at end of file diff --git a/assets/js/51.5ee9dbbb.js b/assets/js/51.5ee9dbbb.js new file mode 100644 index 0000000000..792bed64f7 --- /dev/null +++ b/assets/js/51.5ee9dbbb.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[51],{377:function(t,n,s){"use strict";s.r(n);var e=s(4),o=Object(e.a)({},(function(){return(0,this._self._c)("ContentSlotsDistributor",{attrs:{"slot-key":this.$parent.slotKey}})}),[],!1,null,null,null);n.default=o.exports}}]); \ No newline at end of file diff --git a/assets/js/52.eec69599.js b/assets/js/52.eec69599.js new file mode 100644 index 0000000000..fdc3248897 --- /dev/null +++ b/assets/js/52.eec69599.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[52],{378:function(s,a,t){"use strict";t.r(a);var e=t(4),n=Object(e.a)({},(function(){var s=this,a=s._self._c;return a("ContentSlotsDistributor",{attrs:{"slot-key":s.$parent.slotKey}},[a("div",{staticClass:"custom-block tip"},[a("p",{staticClass:"custom-block-title"},[s._v("提示")]),s._v(" "),a("p",[s._v("本篇整理了一些 shell 命令,更多的命令可见")]),s._v(" "),a("ul",[a("li",[a("a",{attrs:{href:"https://www.fly63.com/tool/linux/",target:"_blank",rel:"noopener noreferrer"}},[s._v("shell 常用命令查询"),a("OutboundLink")],1)])])]),s._v(" "),a("h2",{attrs:{id:"语法"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#语法"}},[s._v("#")]),s._v(" 语法")]),s._v(" "),a("div",{staticClass:"custom-block tip"},[a("p",{staticClass:"custom-block-title"},[s._v("提示")]),s._v(" "),a("p",[s._v("linux 语法参考学习网站:")]),s._v(" "),a("ol",[a("li",[a("a",{attrs:{href:"https://www.runoob.com/linux/linux-shell-variable.html",target:"_blank",rel:"noopener noreferrer"}},[s._v("https://www.runoob.com/linux/linux-shell-variable.html"),a("OutboundLink")],1),s._v(" RUNOOB.COM")])])]),s._v(" "),a("h3",{attrs:{id:"变量扩展语法"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#变量扩展语法"}},[s._v("#")]),s._v(" 变量扩展语法")]),s._v(" "),a("blockquote",[a("p",[s._v("解释 "),a("code",[s._v("${ZSH_CUSTOM:-~/.oh-my-zsh/custom}")])])]),s._v(" "),a("p",[a("code",[s._v("${ZSH_CUSTOM:-~/.oh-my-zsh/custom}")]),s._v(" 是一种 Shell 变量扩展语法,用于在命令中引用一个变量。在这个特定的命令中,"),a("code",[s._v("${ZSH_CUSTOM:-~/.oh-my-zsh/custom}")]),s._v(" 表示一个变量,它的值是 "),a("code",[s._v("$ZSH_CUSTOM")]),s._v(" 的值,如果 "),a("code",[s._v("$ZSH_CUSTOM")]),s._v(" 未定义,则使用默认值 "),a("code",[s._v("~/.oh-my-zsh/custom")]),s._v("。")]),s._v(" "),a("h3",{attrs:{id:"here-tag"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#here-tag"}},[s._v("#")]),s._v(" Here Tag")]),s._v(" "),a("blockquote",[a("p",[s._v("参考文档: "),a("a",{attrs:{href:"https://tldp.org/LDP/abs/html/here-docs.html",target:"_blank",rel:"noopener noreferrer"}},[s._v("Here Documents"),a("OutboundLink")],1)])]),s._v(" "),a("p",[s._v("在 Linux 中,"),a("code",[s._v("<<")]),s._v("(称为 Here Document 或 Here Tag)是一种用于输入多行文本的特殊语法。它允许将一段文本作为输入传递给命令或脚本,而无需使用外部文件。")]),s._v(" "),a("p",[s._v("具体来说,<<后面可以跟一个标识符(tag),用于标识输入的结束。输入文本的开始和结束都由这个标识符来界定。使用<<时,输入的文本会被 shell 进程处理,然后传递给相应的命令或脚本。")]),s._v(" "),a("p",[s._v("示例")]),s._v(" "),a("div",{staticClass:"language-shell line-numbers-mode"},[a("pre",{pre:!0,attrs:{class:"language-shell"}},[a("code",[a("span",{pre:!0,attrs:{class:"token function"}},[s._v("cat")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("<<")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[s._v("END\n这是一段\n多行文本输入,\n会被cat命令处理。\nEND")]),s._v("\n")])]),s._v(" "),a("div",{staticClass:"line-numbers-wrapper"},[a("span",{staticClass:"line-number"},[s._v("1")]),a("br"),a("span",{staticClass:"line-number"},[s._v("2")]),a("br"),a("span",{staticClass:"line-number"},[s._v("3")]),a("br"),a("span",{staticClass:"line-number"},[s._v("4")]),a("br"),a("span",{staticClass:"line-number"},[s._v("5")]),a("br")])]),a("p",[s._v("在上面的示例中,cat 命令接收"),a("code",[s._v("<< END")]),s._v(" 和 "),a("code",[s._v("END")]),s._v(" 之间的多行文本作为输入,并将其输出到标准输出。")]),s._v(" "),a("p",[s._v("Here Document 的用途包括但不限于:")]),s._v(" "),a("ul",[a("li",[a("p",[s._v("在脚本中嵌入大段的文本数据。")])]),s._v(" "),a("li",[a("p",[s._v("在命令行中直接输入多行文本,而无需创建临时文件。")])]),s._v(" "),a("li",[a("p",[s._v("在配置文件或模板中插入变量和文本。")]),s._v(" "),a("p",[s._v("需要注意的是,"),a("code",[s._v("tag")]),s._v(" 可以是用户自定义的标识符,只要它在输入文本中没有被使用即可。通常,"),a("code",[s._v("tag")]),s._v(" 以大写字母开头,但并不是强制要求。")])])]),s._v(" "),a("p",[s._v("二、 如果想把内容报错到文件如"),a("code",[s._v("config.pbtx")]),s._v("中可以使用如下方案")]),s._v(" "),a("div",{staticClass:"language-shell line-numbers-mode"},[a("pre",{pre:!0,attrs:{class:"language-shell"}},[a("code",[a("span",{pre:!0,attrs:{class:"token function"}},[s._v("cat")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("<<")]),s._v(" END"),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v(">")]),s._v("config.pbtx\n这是一段\n多行文本输入,\n会被 "),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("cat")]),s._v(" 命令处理。\nEND\n")])]),s._v(" "),a("div",{staticClass:"line-numbers-wrapper"},[a("span",{staticClass:"line-number"},[s._v("1")]),a("br"),a("span",{staticClass:"line-number"},[s._v("2")]),a("br"),a("span",{staticClass:"line-number"},[s._v("3")]),a("br"),a("span",{staticClass:"line-number"},[s._v("4")]),a("br"),a("span",{staticClass:"line-number"},[s._v("5")]),a("br")])]),a("p",[s._v("总结起来,<<标记在 Linux 中用于将多行文本作为输入传递给命令或脚本,提供了一种方便的方式来处理多行文本数据。")]),s._v(" "),a("p",[s._v("三、赋值多行字符串给变量")]),s._v(" "),a("div",{staticClass:"language-shell line-numbers-mode"},[a("pre",{pre:!0,attrs:{class:"language-shell"}},[a("code",[a("span",{pre:!0,attrs:{class:"token assign-left variable"}},[s._v("info")]),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),a("span",{pre:!0,attrs:{class:"token variable"}},[a("span",{pre:!0,attrs:{class:"token variable"}},[s._v("$(")]),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("cat")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("<<")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[s._v("'EOF'\n这是一段\n多行文本输入,\n会被cat命令处理。\nEOF")]),s._v("\n"),a("span",{pre:!0,attrs:{class:"token variable"}},[s._v(")")])]),s._v("\n\n"),a("span",{pre:!0,attrs:{class:"token builtin class-name"}},[s._v("echo")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[s._v('"'),a("span",{pre:!0,attrs:{class:"token variable"}},[s._v("$info")]),s._v('"')]),s._v("\n")])]),s._v(" "),a("div",{staticClass:"line-numbers-wrapper"},[a("span",{staticClass:"line-number"},[s._v("1")]),a("br"),a("span",{staticClass:"line-number"},[s._v("2")]),a("br"),a("span",{staticClass:"line-number"},[s._v("3")]),a("br"),a("span",{staticClass:"line-number"},[s._v("4")]),a("br"),a("span",{staticClass:"line-number"},[s._v("5")]),a("br"),a("span",{staticClass:"line-number"},[s._v("6")]),a("br"),a("span",{staticClass:"line-number"},[s._v("7")]),a("br"),a("span",{staticClass:"line-number"},[s._v("8")]),a("br")])]),a("h2",{attrs:{id:"安装相关"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#安装相关"}},[s._v("#")]),s._v(" 安装相关")]),s._v(" "),a("h3",{attrs:{id:"brew"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#brew"}},[s._v("#")]),s._v(" brew")]),s._v(" "),a("blockquote",[a("p",[s._v("name: The Missing Package Manager for macOS")])]),s._v(" "),a("p",[a("strong",[s._v("brew 的安装")])]),s._v(" "),a("ul",[a("li",[a("code",[s._v('/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"')]),s._v(": 安装 Homebrew")])]),s._v(" "),a("p",[s._v("以下是一些常用的安装软件的示例命令")]),s._v(" "),a("ul",[a("li",[a("code",[s._v("brew search package_name")]),s._v(": 查找软件包")]),s._v(" "),a("li",[a("code",[s._v("brew install package_name")])]),s._v(" "),a("li",[a("code",[s._v("brew update")]),s._v(": 更新 Homebrew 自身")]),s._v(" "),a("li",[a("code",[s._v("brew upgrade")]),s._v(": 升级所有已安装的软件包")]),s._v(" "),a("li",[a("code",[s._v("brew list")]),s._v(": 列出已经通过 Homebrew 安装的所有软件包")]),s._v(" "),a("li",[a("code",[s._v("brew info package_name")]),s._v(": 查看软件包信息")]),s._v(" "),a("li",[a("code",[s._v("brew uninstall package_name")]),s._v(": 卸载软件包")]),s._v(" "),a("li",[a("code",[s._v("brew deps package_name")]),s._v(": 查看已安装软件包的依赖关系")]),s._v(" "),a("li",[a("code",[s._v("brew config")]),s._v(": 查看 Homebrew 的配置信息")]),s._v(" "),a("li",[a("code",[s._v("brew cleanup")]),s._v(": 清理过期的版本和缓存文件")])]),s._v(" "),a("h3",{attrs:{id:"apt-get"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#apt-get"}},[s._v("#")]),s._v(" apt-get")]),s._v(" "),a("blockquote",[a("p",[s._v("要在 Ubuntu 上安装软件,可以使用 shell 命令 "),a("code",[s._v("apt-get")]),s._v(" 或 "),a("code",[s._v("apt")]),s._v("。以下是一些常用的安装软件的示例命令:")])]),s._v(" "),a("ul",[a("li",[a("code",[s._v("sudo apt-get install ")]),s._v(" 安装单个软件包")]),s._v(" "),a("li",[a("code",[s._v("sudo apt-get install ")]),s._v(" 安装多个软件包")]),s._v(" "),a("li",[a("code",[s._v("sudo apt-get update")]),s._v(" 更新软件包")]),s._v(" "),a("li",[a("code",[s._v("sudo apt-get upgrade")]),s._v(" 升级已安装的软件包")]),s._v(" "),a("li",[a("code",[s._v("apt list --installed")]),s._v(" 显示已在系统上安装的软件包列表 "),a("code",[s._v("dpkg --list")])])]),s._v(" "),a("h2",{attrs:{id:"文本-文件"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#文本-文件"}},[s._v("#")]),s._v(" 文本/文件")]),s._v(" "),a("h3",{attrs:{id:"lsof"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#lsof"}},[s._v("#")]),s._v(" lsof")]),s._v(" "),a("blockquote",[a("p",[a("code",[s._v('lsof("list open files")')]),s._v("是一个用于显示系统中打开文件的命令行工具。它在 Unix、Linux 和类 Unix 系统上可用,并提供了有关正在使用哪些文件和文件描述符的信息。lsof 可以显示当前打开的文件、网络连接、进程和其他资源的详细信息。")])]),s._v(" "),a("p",[s._v("lsof 的基本语法如下:")]),s._v(" "),a("div",{staticClass:"language-shell line-numbers-mode"},[a("pre",{pre:!0,attrs:{class:"language-shell"}},[a("code",[a("span",{pre:!0,attrs:{class:"token function"}},[s._v("lsof")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("[")]),s._v("options"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("]")]),s._v("\n")])]),s._v(" "),a("div",{staticClass:"line-numbers-wrapper"},[a("span",{staticClass:"line-number"},[s._v("1")]),a("br")])]),a("p",[s._v("以下是一些常用的 lsof 选项和用法示例:")]),s._v(" "),a("ul",[a("li",[a("code",[s._v("lsof")]),s._v(" 显示所有打开的文件")]),s._v(" "),a("li",[a("code",[s._v("lsof -p ")]),s._v(" 显示特定进程打开的文件")]),s._v(" "),a("li",[a("code",[s._v("lsof -u ")]),s._v(" 显示特定用户打开的文件")]),s._v(" "),a("li",[a("code",[s._v("lsof ")]),s._v(" 显示特定文件的打开者")]),s._v(" "),a("li",[a("code",[s._v("lsof -i :")]),s._v(" 显示特定端口号相关的网络连接")]),s._v(" "),a("li",[a("code",[s._v("lsof +L1")]),s._v(" 显示已删除但仍在使用的文件")]),s._v(" "),a("li",[a("code",[s._v("lsof -F [format]")]),s._v(" 以用户友好的格式显示输出结果")])]),s._v(" "),a("p",[s._v("这只是一些 lsof 命令的示例,lsof 支持许多其他选项和过滤器,可以根据具体需求进行定制。你可以通过查阅 "),a("code",[s._v("lsof")]),s._v(" 的手册页(man 页)来获取更详细的信息,使用命令 "),a("code",[s._v("man lsof")]),s._v(" 即可查看。")]),s._v(" "),a("h3",{attrs:{id:"ls"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#ls"}},[s._v("#")]),s._v(" ls")]),s._v(" "),a("p",[a("code",[s._v("ls")]),s._v(" 是一个常用的命令行工具,用于列出当前目录中的文件和子目录。它的功能包括显示文件属性、权限、时间戳等信息,以及对文件和目录进行排序和筛选。")]),s._v(" "),a("p",[s._v("常见选项:")]),s._v(" "),a("ul",[a("li",[a("code",[s._v("-l")]),s._v(":以长格式(long format)显示文件和目录的详细信息,包括权限、所有者、大小、时间戳等。")]),s._v(" "),a("li",[a("code",[s._v("-a")]),s._v(":显示所有文件和目录,包括隐藏文件(以点开头的文件名)。")]),s._v(" "),a("li",[a("code",[s._v("-h")]),s._v(":以人类可读的格式显示文件大小(例如,使用 KB、MB、GB 等单位)。")]),s._v(" "),a("li",[a("code",[s._v("-r")]),s._v(":以逆序(逆向)排序显示结果。")]),s._v(" "),a("li",[a("code",[s._v("-t")]),s._v(":按修改时间排序,最新的在前。")]),s._v(" "),a("li",[a("code",[s._v("-R")]),s._v(":递归地显示子目录中的文件和目录。")]),s._v(" "),a("li",[a("code",[s._v("-d")]),s._v(":仅显示目录本身,而不是其内容。")]),s._v(" "),a("li",[a("code",[s._v("-i")]),s._v(":显示文件和目录的索引号(inode)。")]),s._v(" "),a("li",[a("code",[s._v("-s")]),s._v(":显示文件和目录的大小(以块为单位)")])]),s._v(" "),a("p",[s._v("示例用法:")]),s._v(" "),a("ul",[a("li",[s._v("列出当前目录中的文件和目录:ls")]),s._v(" "),a("li",[s._v("列出当前目录中的所有文件和目录,包括隐藏文件:ls -a")]),s._v(" "),a("li",[s._v("以长格式显示当前目录中的文件和目录:ls -l")]),s._v(" "),a("li",[s._v("按修改时间排序,最新的在前:ls -lt")]),s._v(" "),a("li",[s._v("列出指定目录的内容:ls /path/to/directory")]),s._v(" "),a("li",[s._v("递归地列出指定目录及其子目录中的所有文件和目录:ls -R /path/to/directory")])]),s._v(" "),a("h3",{attrs:{id:"rg"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#rg"}},[s._v("#")]),s._v(" rg")]),s._v(" "),a("blockquote",[a("p",[s._v("rg(全称为 ripgrep)是一个高性能的文本搜索工具,用于在文件中进行快速且灵活的搜索。它支持正则表达式搜索,具有速度快、默认忽略版本控制文件、支持多种文件类型等特点。是个人日常使用比较多的文本搜索工具")])]),s._v(" "),a("p",[s._v("以下是 "),a("code",[s._v("rg")]),s._v(" 命令的基本语法:")]),s._v(" "),a("div",{staticClass:"language-shell line-numbers-mode"},[a("pre",{pre:!0,attrs:{class:"language-shell"}},[a("code",[s._v("rg "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("[")]),s._v("选项"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("]")]),s._v(" 搜索模式 "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("[")]),s._v("路径"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("]")]),s._v("\n")])]),s._v(" "),a("div",{staticClass:"line-numbers-wrapper"},[a("span",{staticClass:"line-number"},[s._v("1")]),a("br")])]),a("p",[s._v("其中,[选项] 可以是以下常用选项之一:")]),s._v(" "),a("ul",[a("li",[a("code",[s._v("-i")]),s._v(":忽略大小写进行搜索。")]),s._v(" "),a("li",[a("code",[s._v("-w")]),s._v(":只匹配完整的单词。")]),s._v(" "),a("li",[a("code",[s._v("-v")]),s._v(":反向匹配,即只显示不匹配的行。")]),s._v(" "),a("li",[a("code",[s._v("-c")]),s._v(":只显示匹配的行数而不显示具体内容。")]),s._v(" "),a("li",[a("code",[s._v("--hidden")]),s._v(":搜索包括隐藏文件。")]),s._v(" "),a("li",[a("code",[s._v("--no-ignore")]),s._v(":不忽略 .gitignore 或类似的忽略文件中指定的模式。")]),s._v(" "),a("li",[a("code",[s._v("--max-count ")]),s._v(": 表示只搜索 count 结果就返回。 如 "),a("code",[s._v("rg --max-count 1 uid")]),s._v(", 搜索一个 uid 结果即返回")]),s._v(" "),a("li",[a("code",[s._v("--glob '!' ")]),s._v(": 搜索 A 目录下所有文件及文件夹,除了文件夹 B")])]),s._v(" "),a("p",[a("code",[s._v("搜索模式")]),s._v(" 是要在文件中搜索的模式,可以是普通文本或正则表达式。你可以使用普通文本进行简单的字符串搜索,或使用正则表达式进行更复杂的模式匹配。\n"),a("code",[s._v("[路径]")]),s._v(" 是可选的,表示要搜索的文件或目录的路径。如果省略路径,则默认在当前目录及其子目录中进行搜索。")]),s._v(" "),a("h3",{attrs:{id:"fd"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#fd"}},[s._v("#")]),s._v(" fd")]),s._v(" "),a("blockquote",[a("p",[a("code",[s._v("fd")]),s._v(" 是一个用于在命令行中快速查找文件和目录的工具,而不需要使用复杂的正则表达式。它类似于 "),a("code",[s._v("find")]),s._v(" 命令,但具有更简洁的语法和更友好的用户界面。")]),s._v(" "),a("p",[a("code",[s._v("fd")]),s._v(" 工具可以与 shell 结合使用,通过在命令行中指定搜索模式和目录路径,来查找匹配的文件和目录。它支持递归搜索,并提供一些有用的选项来过滤和定制搜索结果。")])]),s._v(" "),a("p",[s._v("以下是 fd 命令的基本语法:")]),s._v(" "),a("div",{staticClass:"language-shell line-numbers-mode"},[a("pre",{pre:!0,attrs:{class:"language-shell"}},[a("code",[s._v("fd "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("[")]),s._v("选项"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("]")]),s._v(" 搜索模式 "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("[")]),s._v("目录"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("]")]),s._v("\n")])]),s._v(" "),a("div",{staticClass:"line-numbers-wrapper"},[a("span",{staticClass:"line-number"},[s._v("1")]),a("br")])]),a("p",[s._v("其中,搜索模式 是要查找的文件或目录的名称模式。目录 是要在其中进行搜索的起始目录路径。如果未指定目录路径,则默认从当前目录开始递归搜索。")]),s._v(" "),a("p",[s._v("以下是一些常用的 fd 命令选项:")]),s._v(" "),a("ul",[a("li",[a("code",[s._v("-i")]),s._v(":忽略大小写")]),s._v(" "),a("li",[a("code",[s._v("-a")]),s._v(":搜索隐藏文件和目录")]),s._v(" "),a("li",[a("code",[s._v("-t <类型>")]),s._v(":只搜索指定类型的文件或目录(例如,-t f 用于只搜索文件)")]),s._v(" "),a("li",[a("code",[s._v("-e <扩展名>")]),s._v(":只搜索具有指定扩展名的文件")]),s._v(" "),a("li",[a("code",[s._v("-x <文件系统>")]),s._v(":排除指定文件系统的搜索结果")]),s._v(" "),a("li",[a("code",[s._v("-s")]),s._v(":按文件大小进行排序")]),s._v(" "),a("li",[a("code",[s._v("-d <深度>")]),s._v(":指定递归搜索的最大深度")])]),s._v(" "),a("p",[s._v("这些选项可以根据你的搜索需求进行组合和调整。")]),s._v(" "),a("p",[s._v("fd 工具还支持其他高级功能,如正则表达式匹配、根据权限过滤搜索结果、自定义输出格式等。你可以通过运行 fd --help 或查阅 fd 的文档来了解更多选项和用法。")]),s._v(" "),a("p",[s._v("请注意,fd 是第三方工具,你可能需要先安装它,然后在 shell 中使用。")]),s._v(" "),a("h2",{attrs:{id:"网络"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#网络"}},[s._v("#")]),s._v(" 网络")]),s._v(" "),a("h3",{attrs:{id:"ifconfig"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#ifconfig"}},[s._v("#")]),s._v(" ifconfig")]),s._v(" "),a("div",{staticClass:"custom-block tip"},[a("p",{staticClass:"custom-block-title"},[s._v("提示")]),s._v(" "),a("p",[s._v("配置和显示 Linux 系统网卡的网络参数\nifconfig 命令 被用于配置和显示 Linux 内核中网络接口的网络参数。用 ifconfig 命令配置的网卡信息,在网卡重启后机器重启后,配置就不存在。要想将上述的配置信息永远的存的电脑里,那就要修改网卡的配置文件了。")])]),s._v(" "),a("p",[a("strong",[s._v("使用方法")])]),s._v(" "),a("ul",[a("li",[a("code",[s._v("ifconfig(参数)")])])]),s._v(" "),a("h3",{attrs:{id:"netstat"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#netstat"}},[s._v("#")]),s._v(" netstat")]),s._v(" "),a("blockquote",[a("p",[s._v("netstat:用于显示网络连接、路由表和网络接口统计信息。")])]),s._v(" "),a("ul",[a("li",[s._v("显示所有活动网络连接:netstat -a")]),s._v(" "),a("li",[s._v("显示 TCP 连接状态:netstat -t")]),s._v(" "),a("li",[s._v("显示监听的端口:netstat -l")]),s._v(" "),a("li",[s._v("显示路由表信息:netstat -r")])]),s._v(" "),a("h3",{attrs:{id:"dig"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#dig"}},[s._v("#")]),s._v(" dig")]),s._v(" "),a("p",[a("code",[s._v("dig")]),s._v("是一个常用的用于域名解析(DNS 查询)的命令行工具。它可以用于查询域名的 IP 地址、获取 DNS 记录以及执行其他与域名解析相关的操作。下面是 dig 命令的一些基本用法:")]),s._v(" "),a("ul",[a("li",[s._v("查询域名的 A 记录(IPv4 地址):dig example.com")]),s._v(" "),a("li",[s._v("查询域名的 AAAA 记录(IPv6 地址):dig AAAA example.com")]),s._v(" "),a("li",[s._v("查询域名的 CNAME 记录(别名):dig CNAME example.com")]),s._v(" "),a("li",[s._v("查询域名的 MX 记录(邮件交换服务器):dig MX example.com")]),s._v(" "),a("li",[s._v("查询域名的 TXT 记录(文本信息):dig TXT example.com")]),s._v(" "),a("li",[s._v("查询域名的 NS 记录(域名服务器):dig NS example.com")]),s._v(" "),a("li",[s._v("指定特定 DNS 服务器进行查询:dig @dns_server example.com")])]),s._v(" "),a("p",[s._v("dig 命令还支持其他参数和选项,可用于更详细和特定类型的查询。例如,你可以指定查询的 DNS 服务器、设置查询的超时时间、指定查询类型等。")]),s._v(" "),a("p",[s._v("一、比如查找 openai 的域名")]),s._v(" "),a("div",{staticClass:"language-shell line-numbers-mode"},[a("pre",{pre:!0,attrs:{class:"language-shell"}},[a("code",[a("span",{pre:!0,attrs:{class:"token function"}},[s._v("dig")]),s._v(" chat.openai.com\n")])]),s._v(" "),a("div",{staticClass:"line-numbers-wrapper"},[a("span",{staticClass:"line-number"},[s._v("1")]),a("br")])]),a("p",[s._v("输出如下:")]),s._v(" "),a("div",{staticClass:"language-shell line-numbers-mode"},[a("pre",{pre:!0,attrs:{class:"language-shell"}},[a("code",[a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("<<")]),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v(">>")]),s._v(" DiG "),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("9.10")]),s._v(".6 "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("<<")]),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v(">>")]),s._v(" chat.openai.com\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v(" global options: +cmd\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v(" Got answer:\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v(" -"),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v(">>")]),s._v("HEADER"),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("<<-")]),s._v(" opcode: QUERY, status: NOERROR, id: "),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("39096")]),s._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v(" flags: qr rd ra"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v(" QUERY: "),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("1")]),s._v(", ANSWER: "),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("3")]),s._v(", AUTHORITY: "),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("0")]),s._v(", ADDITIONAL: "),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("1")]),s._v("\n\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v(" OPT PSEUDOSECTION:\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v(" EDNS: version: "),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("0")]),s._v(", flags:"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v(" udp: "),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("1232")]),s._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v(" QUESTION SECTION:\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("chat.openai.com. IN A\n\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v(" ANSWER SECTION:\nchat.openai.com. "),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("152")]),s._v(" IN CNAME chat.openai.com.cdn.cloudflare.net.\nchat.openai.com.cdn.cloudflare.net. "),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("144")]),s._v(" IN A "),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("104.18")]),s._v(".2.161\nchat.openai.com.cdn.cloudflare.net. "),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("144")]),s._v(" IN A "),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("104.18")]),s._v(".3.161\n\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v(" Query time: "),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("1")]),s._v(" msec\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v(" SERVER: "),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("10.89")]),s._v(".54.2"),a("span",{pre:!0,attrs:{class:"token comment"}},[s._v("#53(10.89.54.2)")]),s._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v(" WHEN: Wed May "),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("24")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("21")]),s._v(":38:55 CST "),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("2023")]),s._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v(" MSG SIZE rcvd: "),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("124")]),s._v("\n")])]),s._v(" "),a("div",{staticClass:"line-numbers-wrapper"},[a("span",{staticClass:"line-number"},[s._v("1")]),a("br"),a("span",{staticClass:"line-number"},[s._v("2")]),a("br"),a("span",{staticClass:"line-number"},[s._v("3")]),a("br"),a("span",{staticClass:"line-number"},[s._v("4")]),a("br"),a("span",{staticClass:"line-number"},[s._v("5")]),a("br"),a("span",{staticClass:"line-number"},[s._v("6")]),a("br"),a("span",{staticClass:"line-number"},[s._v("7")]),a("br"),a("span",{staticClass:"line-number"},[s._v("8")]),a("br"),a("span",{staticClass:"line-number"},[s._v("9")]),a("br"),a("span",{staticClass:"line-number"},[s._v("10")]),a("br"),a("span",{staticClass:"line-number"},[s._v("11")]),a("br"),a("span",{staticClass:"line-number"},[s._v("12")]),a("br"),a("span",{staticClass:"line-number"},[s._v("13")]),a("br"),a("span",{staticClass:"line-number"},[s._v("14")]),a("br"),a("span",{staticClass:"line-number"},[s._v("15")]),a("br"),a("span",{staticClass:"line-number"},[s._v("16")]),a("br"),a("span",{staticClass:"line-number"},[s._v("17")]),a("br"),a("span",{staticClass:"line-number"},[s._v("18")]),a("br"),a("span",{staticClass:"line-number"},[s._v("19")]),a("br"),a("span",{staticClass:"line-number"},[s._v("20")]),a("br")])]),a("ul",[a("li",[a("code",[s._v("SERVER: 10.89.54.2#53")]),s._v(":这部分表示使用的 DNS 服务器的 IP 地址和端口号。在此示例中,DNS 服务器的 IP 地址是 10.89.54.2,端口号是 53,该端口通常用于 DNS 服务。")]),s._v(" "),a("li",[a("code",[s._v("(10.89.54.2)")]),s._v(":这部分是 DNS 服务器的可读性描述,显示为括在括号中的 IP 地址。")])]),s._v(" "),a("p",[a("code",[s._v(";; SERVER: 10.89.54.2#53(10.89.54.2)")]),s._v(" 行指示了查询过程中所使用的 DNS 服务器的信息。这对于调试和故障排除目的很有用,因为它告诉你查询是由哪个 DNS 服务器提供的响应。")]),s._v(" "),a("h3",{attrs:{id:"nslookup"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#nslookup"}},[s._v("#")]),s._v(" nslookup")]),s._v(" "),a("p",[a("code",[s._v("nslookup")]),s._v(":用于查询域名解析信息。")]),s._v(" "),a("p",[s._v("比如查询域名对应的 IP 地址:"),a("code",[s._v("nslookup example.com")]),s._v("\n查询特定 DNS 服务器上的域名解析:"),a("code",[s._v("nslookup example.com 8.8.8.8")])]),s._v(" "),a("p",[s._v("一、查询 "),a("code",[s._v("chat.openai.com")]),s._v(" 的 ip 地址")]),s._v(" "),a("div",{staticClass:"language-shell line-numbers-mode"},[a("pre",{pre:!0,attrs:{class:"language-shell"}},[a("code",[a("span",{pre:!0,attrs:{class:"token function"}},[s._v("nslookup")]),s._v(" chat.openai.com\n")])]),s._v(" "),a("div",{staticClass:"line-numbers-wrapper"},[a("span",{staticClass:"line-number"},[s._v("1")]),a("br")])]),a("p",[s._v("输出:")]),s._v(" "),a("div",{staticClass:"language-shell line-numbers-mode"},[a("pre",{pre:!0,attrs:{class:"language-shell"}},[a("code",[s._v("Server: "),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("10.89")]),s._v(".54.2\nAddress: "),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("10.89")]),s._v(".54.2"),a("span",{pre:!0,attrs:{class:"token comment"}},[s._v("#53")]),s._v("\n\nNon-authoritative answer:\nName: chat.openai.com\nAddress: "),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("192.133")]),s._v(".77.197\n")])]),s._v(" "),a("div",{staticClass:"line-numbers-wrapper"},[a("span",{staticClass:"line-number"},[s._v("1")]),a("br"),a("span",{staticClass:"line-number"},[s._v("2")]),a("br"),a("span",{staticClass:"line-number"},[s._v("3")]),a("br"),a("span",{staticClass:"line-number"},[s._v("4")]),a("br"),a("span",{staticClass:"line-number"},[s._v("5")]),a("br"),a("span",{staticClass:"line-number"},[s._v("6")]),a("br")])]),a("h3",{attrs:{id:"wget"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#wget"}},[s._v("#")]),s._v(" wget")]),s._v(" "),a("blockquote",[a("p",[s._v("这是 linux 下面的下载命令")])]),s._v(" "),a("ul",[a("li",[s._v("下载文件到当前目录:wget "),a("a",{attrs:{href:"http://example.com/file.txt",target:"_blank",rel:"noopener noreferrer"}},[s._v("http://example.com/file.txt"),a("OutboundLink")],1)]),s._v(" "),a("li",[s._v("下载文件并指定保存位置:wget -O /path/to/save/file.txt "),a("a",{attrs:{href:"http://example.com/file.txt",target:"_blank",rel:"noopener noreferrer"}},[s._v("http://example.com/file.txt"),a("OutboundLink")],1)])]),s._v(" "),a("h3",{attrs:{id:"curl"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#curl"}},[s._v("#")]),s._v(" curl")]),s._v(" "),a("ul",[a("li",[a("code",[s._v("man curl")]),s._v(" 帮助")]),s._v(" "),a("li",[a("code",[s._v("curl -I https://chat.openai.com")]),s._v(" 查看 header")]),s._v(" "),a("li",[a("code",[s._v("curl -OL ")]),s._v(" 下载文件, "),a("code",[s._v("-O")]),s._v(" 参数表示使用原始文件名保存下载的文. "),a("code",[s._v("-L")]),s._v(" 参数,用于开启重定向")]),s._v(" "),a("li",[a("code",[s._v("curl -v ")]),s._v(" 获取网站详细信息")])]),s._v(" "),a("h4",{attrs:{id:"下载-shell-并执行"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#下载-shell-并执行"}},[s._v("#")]),s._v(" 下载 shell 并执行")]),s._v(" "),a("div",{staticClass:"language-shell line-numbers-mode"},[a("pre",{pre:!0,attrs:{class:"language-shell"}},[a("code",[a("span",{pre:!0,attrs:{class:"token function"}},[s._v("curl")]),s._v(" -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.34.0/install.sh "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("|")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("bash")]),s._v("\n")])]),s._v(" "),a("div",{staticClass:"line-numbers-wrapper"},[a("span",{staticClass:"line-number"},[s._v("1")]),a("br")])]),a("ul",[a("li",[a("code",[s._v("-o-")]),s._v(": 表示将下载的文件输出到标准输出(stdout),而不是将其保存到文件中")]),s._v(" "),a("li",[a("code",[s._v("|")]),s._v(": 管道符号,将前一个命令的输出作为后一个命令的输入")]),s._v(" "),a("li",[a("code",[s._v("bash")]),s._v(": 执行传递给它的脚本。")])]),s._v(" "),a("h4",{attrs:{id:"保存到其他目录"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#保存到其他目录"}},[s._v("#")]),s._v(" 保存到其他目录")]),s._v(" "),a("blockquote",[a("p",[s._v("保存到其他目录,自动创建文件夹")])]),s._v(" "),a("div",{staticClass:"language-shell line-numbers-mode"},[a("pre",{pre:!0,attrs:{class:"language-shell"}},[a("code",[a("span",{pre:!0,attrs:{class:"token function"}},[s._v("curl")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token parameter variable"}},[s._v("-fLo")]),s._v(" ~/.vim/autoload/plug.vim --create-dirs "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("\\")]),s._v("\n https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim\n")])]),s._v(" "),a("div",{staticClass:"line-numbers-wrapper"},[a("span",{staticClass:"line-number"},[s._v("1")]),a("br"),a("span",{staticClass:"line-number"},[s._v("2")]),a("br")])]),a("p",[s._v("【解释】这个命令用于安装 Vim-Plug,这是一个流行的 Vim 插件管理器。以下是命令的解释和作用:")]),s._v(" "),a("ul",[a("li",[a("code",[s._v("curl")]),s._v(":这是一个用于在命令行中发出 HTTP 请求的命令行工具。它用于从 GitHub 上下载 Vim-Plug 插件管理器。")]),s._v(" "),a("li",[a("code",[s._v("-fLo")]),s._v(":这是 curl 命令的选项之一,它的作用是指定输出文件的路径。在这里,它将文件保存到 ~/.vim/autoload/plug.vim。")]),s._v(" "),a("li",[a("code",[s._v("~/.vim/autoload/plug.vim")]),s._v(":这是要保存下载文件的路径。在这里,它将下载的 plug.vim 文件保存到 Vim 的 autoload 目录中。autoload 目录通常用于存储 Vim 脚本和插件。")]),s._v(" "),a("li",[a("code",[s._v("--create-dirs")]),s._v(":这是 curl 命令的选项之一,它的作用是在保存文件之前创建目录。如果指定的目录不存在,它会自动创建 autoload 和 ~/.vim 这两个目录。")]),s._v(" "),a("li",[a("code",[s._v("https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim")]),s._v(":这是要下载的文件的 URL 地址。它指向 Vim-Plug 插件管理器的 GitHub 存储库中的 plug.vim 文件。")])]),s._v(" "),a("h4",{attrs:{id:"请求"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#请求"}},[s._v("#")]),s._v(" 请求")]),s._v(" "),a("ul",[a("li",[a("code",[s._v("curl -v http://localhost:888/demo/user/getAllUsers")]),s._v(": get 请求")]),s._v(" "),a("li",[a("code",[s._v('curl -X POST -H "Header1: Value1" -H "Header2: Value2" -d "key1=value1&key2=value2" https://example.com/api/endpoint')]),s._v(": post 请求")])]),s._v(" "),a("h3",{attrs:{id:"netcat-nc"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#netcat-nc"}},[s._v("#")]),s._v(" netcat/nc")]),s._v(" "),a("blockquote",[a("p",[s._v('nc 是一个常用的命令行工具,也被称为 "netcat",它在网络通信中起到了多种角色。nc 命令提供了一种简单的方式来建立 TCP 或 UDP 连接,发送和接收网络数据。')])]),s._v(" "),a("p",[a("code",[s._v("nc -lp 5000")]),s._v(" 是 nc 命令的一种使用方式,它的含义是在本地监听(-l 参数)端口号为 5000 的 TCP 连接。这意味着在运行该命令的终端窗口中,你可以接收到通过 5000 端口发送到本地的网络数据。")]),s._v(" "),a("p",[s._v("当你运行 "),a("code",[s._v("nc -lp 5000")]),s._v(" 后,它会在后台开始监听指定的端口。你可以在另一个终端窗口中执行其他操作,比如运行 "),a("code",[s._v("./client 127.0.0.1")]),s._v(",这会连接到本地主机的 5000 端口。当连接建立后,你可以通过连接发送数据,这些数据将会出现在运行 "),a("code",[s._v("nc -lp 5000")]),s._v(" 的终端窗口中。")]),s._v(" "),a("p",[s._v('在前面提到的代码示例中,程序会连接到服务器的 5000 端口,并通过网络发送字符串 "Hello there!" 进行自我介绍。通过在另一个终端窗口中运行 nc -lp 5000,你可以接收到该消息,并且还可以通过该连接向客户端发送回复消息。')]),s._v(" "),a("p",[s._v("这种使用方式使得 nc 命令成为一个有用的工具,用于调试和测试网络应用程序,或在不同主机之间进行简单的数据传输。")]),s._v(" "),a("h2",{attrs:{id:"解压缩"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#解压缩"}},[s._v("#")]),s._v(" 解压缩")]),s._v(" "),a("h3",{attrs:{id:"xz"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#xz"}},[s._v("#")]),s._v(" xz")]),s._v(" "),a("div",{staticClass:"custom-block tip"},[a("p",{staticClass:"custom-block-title"},[s._v("提示")]),s._v(" "),a("p",[s._v("xz 命令 XZ Utils 是为 POSIX 平台开发具有高压缩率的工具。它使用 "),a("code",[s._v("LZMA2")]),s._v(" 压缩算法,生成的压缩文件比 POSIX 平台传统使用的 gzip、bzip2 生成的压缩文件更小,而且解压缩速度也很快。最初 XZ Utils 的是基于 LZMA-SDK 开发,但是 LZMA-SDK 包含了一些 WINDOWS 平台的特性,所以 XZ Utils 为以适应 POSIX 平台作了大幅的修改。XZ Utils 的出现也是为了取代 POSIX 系统中旧的 LZMA Utils。")])]),s._v(" "),a("p",[a("strong",[s._v("常用命令")])]),s._v(" "),a("ul",[a("li",[a("code",[s._v("xz -h")])]),s._v(" "),a("li",[a("code",[s._v("xz test.txt")]),s._v(" 压缩一个文件 test.txt,压缩成功后生成 test.txt.xz, 原文件会被删除")]),s._v(" "),a("li",[a("code",[s._v("xz -d -k test.txt.xz")]),s._v(" 解压 test.txt.xz 文件,并使用参数 -k 保持原文件不被删除")])]),s._v(" "),a("h3",{attrs:{id:"tar"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#tar"}},[s._v("#")]),s._v(" tar")]),s._v(" "),a("ul",[a("li",[a("code",[s._v("tar xvf ")])])]),s._v(" "),a("h2",{attrs:{id:"其他"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#其他"}},[s._v("#")]),s._v(" 其他")]),s._v(" "),a("h3",{attrs:{id:"kill"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#kill"}},[s._v("#")]),s._v(" kill")]),s._v(" "),a("ul",[a("li",[a("code",[s._v("kill ")])]),s._v(" "),a("li",[a("code",[s._v("kill -9 ")]),s._v(" 强制终止一个进程")])]),s._v(" "),a("h3",{attrs:{id:"剪切板"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#剪切板"}},[s._v("#")]),s._v(" 剪切板")]),s._v(" "),a("blockquote",[a("p",[s._v("复制文件内容到剪切板")])]),s._v(" "),a("ul",[a("li",[a("code",[s._v("cat /path/to/source_file | pbcopy")]),s._v(" # macOS")]),s._v(" "),a("li",[a("code",[s._v("cat /path/to/source_file | xclip -selection clipboard")]),s._v(" # Linux with X11")]),s._v(" "),a("li",[a("code",[s._v("cat /path/to/source_file | xsel --clipboard")]),s._v(" # Alternative for Linux with X11")]),s._v(" "),a("li",[a("code",[s._v("type /path/to/source_file | clip")]),s._v(" #windows")])]),s._v(" "),a("h2",{attrs:{id:"案例"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#案例"}},[s._v("#")]),s._v(" 案例")]),s._v(" "),a("h3",{attrs:{id:"词频统计"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#词频统计"}},[s._v("#")]),s._v(" 词频统计")]),s._v(" "),a("blockquote",[a("p",[s._v("此示例来自 leetcode: "),a("a",{attrs:{href:"https://leetcode-cn.com/problems/word-frequency/",target:"_blank",rel:"noopener noreferrer"}},[s._v("https://leetcode-cn.com/problems/word-frequency/"),a("OutboundLink")],1)])]),s._v(" "),a("p",[s._v("word 内容如下")]),s._v(" "),a("div",{staticClass:"language-txt line-numbers-mode"},[a("pre",{pre:!0,attrs:{class:"language-txt"}},[a("code",[s._v("the day is sunny the the\nthe sunny is is\n")])]),s._v(" "),a("div",{staticClass:"line-numbers-wrapper"},[a("span",{staticClass:"line-number"},[s._v("1")]),a("br"),a("span",{staticClass:"line-number"},[s._v("2")]),a("br")])]),a("div",{staticClass:"language-shell line-numbers-mode"},[a("pre",{pre:!0,attrs:{class:"language-shell"}},[a("code",[a("span",{pre:!0,attrs:{class:"token function"}},[s._v("cat")]),s._v(" words.txt "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("|")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("tr")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token parameter variable"}},[s._v("-s")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[s._v("' '")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[s._v("'\\n'")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("|")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("sort")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("|")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("uniq")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token parameter variable"}},[s._v("-c")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("|")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("sort")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token parameter variable"}},[s._v("-r")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("|")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("awk")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[s._v("'{print $2,$1}'")]),s._v("\n")])]),s._v(" "),a("div",{staticClass:"line-numbers-wrapper"},[a("span",{staticClass:"line-number"},[s._v("1")]),a("br")])]),a("p",[s._v("解释如下:")]),s._v(" "),a("ul",[a("li",[a("code",[s._v("cat")]),s._v(" 命令查看 words.txt")]),s._v(" "),a("li",[a("code",[s._v("tr -s ' ' '\\n'")]),s._v("将空格都替换为换行 实现分词")]),s._v(" "),a("li",[a("code",[s._v("sort")]),s._v(" 排序将分好的词按照顺序排序")]),s._v(" "),a("li",[a("code",[s._v("uniq -c")]),s._v(" 统计重复次数(此步骤与上一步息息相关,-c 原理是字符串相同则加一,如果不进行先排序的话将无法统计数目)")]),s._v(" "),a("li",[a("code",[s._v("sort -r")]),s._v(" 将数目倒序排列")]),s._v(" "),a("li",[a("code",[s._v("awk '{print $2,$1}'")]),s._v(" 将词频和词语调换位置打印出来")])]),s._v(" "),a("h3",{attrs:{id:"转置文件"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#转置文件"}},[s._v("#")]),s._v(" 转置文件")]),s._v(" "),a("blockquote",[a("p",[s._v("给定一个文件 file.txt,转置它的内容。 你可以假设每行列数相同,并且每个字段由 ' ' 分隔。 "),a("a",{attrs:{href:"https://leetcode-cn.com/problems/transpose-file/",target:"_blank",rel:"noopener noreferrer"}},[s._v("https://leetcode-cn.com/problems/transpose-file/"),a("OutboundLink")],1)])]),s._v(" "),a("p",[s._v("假设 file.txt 文件为")]),s._v(" "),a("div",{staticClass:"language-txt line-numbers-mode"},[a("pre",{pre:!0,attrs:{class:"language-txt"}},[a("code",[s._v("name age\nalice 21\nryan 30\n")])]),s._v(" "),a("div",{staticClass:"line-numbers-wrapper"},[a("span",{staticClass:"line-number"},[s._v("1")]),a("br"),a("span",{staticClass:"line-number"},[s._v("2")]),a("br"),a("span",{staticClass:"line-number"},[s._v("3")]),a("br")])]),a("div",{staticClass:"language-bash line-numbers-mode"},[a("pre",{pre:!0,attrs:{class:"language-bash"}},[a("code",[a("span",{pre:!0,attrs:{class:"token shebang important"}},[s._v("#!/bin/bash")]),s._v("\n"),a("span",{pre:!0,attrs:{class:"token comment"}},[s._v("# Read from the file file.txt and print its transposed content to stdout.")]),s._v("\n"),a("span",{pre:!0,attrs:{class:"token comment"}},[s._v("# 获取第一行,然后用wc来获取列数")]),s._v("\n"),a("span",{pre:!0,attrs:{class:"token assign-left variable"}},[s._v("COLS")]),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),a("span",{pre:!0,attrs:{class:"token variable"}},[a("span",{pre:!0,attrs:{class:"token variable"}},[s._v("`")]),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("head")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token parameter variable"}},[s._v("-1")]),s._v(" file.txt "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("|")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("wc")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token parameter variable"}},[s._v("-w")]),a("span",{pre:!0,attrs:{class:"token variable"}},[s._v("`")])]),s._v("\n"),a("span",{pre:!0,attrs:{class:"token comment"}},[s._v("# 使用awk依次去输出文件的每一列的参数,然后用xargs做转置")]),s._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("for")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token variable"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("((")]),s._v(" i "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("1")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v(" i "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("<=")]),s._v(" $COLS"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v(" i"),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("++")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("))")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("do")]),s._v("\n "),a("span",{pre:!0,attrs:{class:"token comment"}},[s._v("# 这里col就是在代码里要替换的参数,而它等于$i")]),s._v("\n "),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("awk")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token parameter variable"}},[s._v("-v")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token assign-left variable"}},[s._v("col")]),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),a("span",{pre:!0,attrs:{class:"token variable"}},[s._v("$i")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[s._v("'{print $col}'")]),s._v(" file.txt "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("|")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("xargs")]),s._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("done")]),s._v("\n")])]),s._v(" "),a("div",{staticClass:"line-numbers-wrapper"},[a("span",{staticClass:"line-number"},[s._v("1")]),a("br"),a("span",{staticClass:"line-number"},[s._v("2")]),a("br"),a("span",{staticClass:"line-number"},[s._v("3")]),a("br"),a("span",{staticClass:"line-number"},[s._v("4")]),a("br"),a("span",{staticClass:"line-number"},[s._v("5")]),a("br"),a("span",{staticClass:"line-number"},[s._v("6")]),a("br"),a("span",{staticClass:"line-number"},[s._v("7")]),a("br"),a("span",{staticClass:"line-number"},[s._v("8")]),a("br"),a("span",{staticClass:"line-number"},[s._v("9")]),a("br")])]),a("p",[s._v("解释:")]),s._v(" "),a("ul",[a("li",[s._v("使用 head -1 file.txt 获取文件的第一行,然后使用 wc -w 命令来计算单词数,从而得到列数,并将结果存储在变量 $COLS 中。")]),s._v(" "),a("li",[s._v("使用一个循环,从第一列到第 $COLS 列,逐列处理文件。在每次循环中,通过 awk 命令来提取文件中的一列,然后使用 xargs 命令将这一列转置成行。\n"),a("ul",[a("li",[s._v("使用 "),a("code",[s._v("awk")]),s._v(' 来处理文件 "file.txt"。通过 '),a("code",[s._v("-v")]),s._v(" 选项,它将 shell 变量 col 设置为当前循环的列号 $i。然后,awk 脚本 {print $col} 用于打印当前列的内容。")]),s._v(" "),a("li",[a("code",[s._v("|")]),s._v(":这个管道符将 awk 命令的输出传递给下一个命令,也就是 xargs。")]),s._v(" "),a("li",[a("code",[s._v("xargs")]),s._v(":这个命令用于接收来自前一个命令(awk)的输出,并将其作为参数传递给指定的命令。在你的脚本中,没有指定要执行的特定命令,所以默认情况下,xargs 会将从 awk 获取的内容输出到终端。")])])]),s._v(" "),a("li",[s._v("在 awk 命令中,使用 -v 参数将 shell 变量 col 设置为当前列数 $i,然后通过 $col 来访问该列的内容。")])]),s._v(" "),a("h3",{attrs:{id:"提取-android-serial"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#提取-android-serial"}},[s._v("#")]),s._v(" 提取 ANDROID SERIAL")]),s._v(" "),a("p",[s._v("从如下的字符提取 99161FFBA00AZ2")]),s._v(" "),a("div",{staticClass:"language-shell line-numbers-mode"},[a("pre",{pre:!0,attrs:{class:"language-shell"}},[a("code",[s._v("List of devices attached\n99161FFBA00AZ2 device\n")])]),s._v(" "),a("div",{staticClass:"line-numbers-wrapper"},[a("span",{staticClass:"line-number"},[s._v("1")]),a("br"),a("span",{staticClass:"line-number"},[s._v("2")]),a("br")])]),a("p",[s._v("方法:")]),s._v(" "),a("div",{staticClass:"language-shell line-numbers-mode"},[a("pre",{pre:!0,attrs:{class:"language-shell"}},[a("code",[s._v("adb devices "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("|")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("awk")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[s._v("'NR==2{print $1}'")]),s._v("\n")])]),s._v(" "),a("div",{staticClass:"line-numbers-wrapper"},[a("span",{staticClass:"line-number"},[s._v("1")]),a("br")])]),a("p",[s._v("在这个命令中,"),a("code",[s._v("adb devices")]),s._v(" 用于获取设备列表。然后,"),a("code",[s._v("awk")]),s._v(" 命令会处理输出结果。"),a("code",[s._v("NR==")]),s._v("2 表示只处理第二行,"),a("code",[s._v("print $1")]),s._v(" 表示打印第一列的内容,即设备序列号。")])])}),[],!1,null,null,null);a.default=n.exports}}]); \ No newline at end of file diff --git a/assets/js/53.bf6b3f12.js b/assets/js/53.bf6b3f12.js new file mode 100644 index 0000000000..537d461c3f --- /dev/null +++ b/assets/js/53.bf6b3f12.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[53],{379:function(t,a,e){"use strict";e.r(a);var s=e(4),v=Object(s.a)({},(function(){var t=this,a=t._self._c;return a("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[a("h1",{attrs:{id:"git"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#git"}},[t._v("#")]),t._v(" GIT")]),t._v(" "),a("blockquote",[a("p",[t._v("如何学习 git 命令")])]),t._v(" "),a("ul",[a("li",[a("a",{attrs:{href:"https://learngitbranching.js.org/",target:"_blank",rel:"noopener noreferrer"}},[t._v("Learn Git Online"),a("OutboundLink")],1)])]),t._v(" "),a("h2",{attrs:{id:"实用操作"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#实用操作"}},[t._v("#")]),t._v(" 实用操作")]),t._v(" "),a("h3",{attrs:{id:"分离-header"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#分离-header"}},[t._v("#")]),t._v(" 分离 header")]),t._v(" "),a("p",[t._v("如何相对运动?")]),t._v(" "),a("blockquote",[a("p",[t._v("首先看看操作符 (^)。把这个符号加在引用名称的后面,表示让 Git 寻找指定提交记录的父提交。")])]),t._v(" "),a("ul",[a("li",[a("code",[t._v("master^")]),t._v(" 相当于 master 的父节点。")]),t._v(" "),a("li",[a("code",[t._v("master^^")]),t._v(" 是 master 的第二个父节点")]),t._v(" "),a("li",[a("code",[t._v("git checkout HEAD~4")]),t._v(" 向后移动 4 位")])]),t._v(" "),a("h2",{attrs:{id:"常用命令"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#常用命令"}},[t._v("#")]),t._v(" 常用命令")]),t._v(" "),a("ul",[a("li",[a("code",[t._v("git --help")]),t._v(" 查看帮助")]),t._v(" "),a("li",[a("code",[t._v("git log -p **/**pip3.md")]),t._v(" 该命令会显示出所有目录下以 pip3.md 结尾的文件每个提交的详细修改内容\n"),a("ul",[a("li",[a("code",[t._v("git log")]),t._v(" 查看提交历史记录")]),t._v(" "),a("li",[a("code",[t._v("-p")]),t._v("显示每个提交的详细修改内容(即补丁/差异)")]),t._v(" "),a("li",[a("code",[t._v("**")]),t._v(" ** 表示递归匹配任意目录")])])]),t._v(" "),a("li",[a("code",[t._v("git remote rm origin")])]),t._v(" "),a("li",[a("code",[t._v("git remote add origin xxx")])]),t._v(" "),a("li",[a("code",[t._v("git config --global --edit")]),t._v(" 编辑 global config")]),t._v(" "),a("li",[a("code",[t._v("git config --global core.ignorecase false")]),t._v(" 全局忽略大小写")]),t._v(" "),a("li",[a("code",[t._v("sparse checkout")]),t._v(" 可见"),a("a",{attrs:{href:"https://zhuanlan.zhihu.com/p/54581830",target:"_blank",rel:"noopener noreferrer"}},[t._v("链接"),a("OutboundLink")],1)]),t._v(" "),a("li",[a("code",[t._v("git checkout xxx")]),t._v(" reset single file")]),t._v(" "),a("li",[a("code",[t._v("git reset .")]),t._v(" 回退暂存区内容至工作区 "),a("code",[t._v("git add .")]),t._v(" 的反向操作")]),t._v(" "),a("li",[a("code",[t._v("git checkout .")]),t._v(" 清空工作区(放弃本地修改时使用,add 过的文件不会清空)")]),t._v(" "),a("li",[a("code",[t._v("git branch $branchName $commitId")]),t._v(" 基于"),a("code",[t._v("commitId")]),t._v("创建新的分支")]),t._v(" "),a("li",[a("code",[t._v("git checkout $branchName")]),t._v(" 切分支")]),t._v(" "),a("li",[a("code",[t._v("git push origin --delete ")]),t._v(" 强制删除远程分支")]),t._v(" "),a("li",[a("code",[t._v("git branch --delete --force")])]),t._v(" "),a("li",[a("code",[t._v("git branch --delete")])]),t._v(" "),a("li",[t._v("打 patch\n"),a("ul",[a("li",[a("code",[t._v("git format-patch ${since}")]),t._v(" 生成 patch 文件")]),t._v(" "),a("li",[a("code",[t._v("git apply ${patch-file}")]),t._v(" 应用 patch")])])]),t._v(" "),a("li",[a("code",[t._v("git merge --abort")]),t._v(" 取消当前的 merge 操作")]),t._v(" "),a("li",[a("code",[t._v("git diff ")]),t._v(" 查看 branch 之间的 diff")])]),t._v(" "),a("h2",{attrs:{id:"常用操作"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#常用操作"}},[t._v("#")]),t._v(" 常用操作")]),t._v(" "),a("h3",{attrs:{id:"撤销提交到-stage-的修改"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#撤销提交到-stage-的修改"}},[t._v("#")]),t._v(" 撤销提交到 stage 的修改")]),t._v(" "),a("ul",[a("li",[a("code",[t._v("git reset HEAD~")]),t._v(" 这将把最近的提交回退到暂存区,你可以再次提交修改")]),t._v(" "),a("li",[a("code",[t._v("git reset --hard HEAD~")]),t._v(" 这将删除最近的提交并重置工作目录和暂存区为上一个提交的状态")]),t._v(" "),a("li",[a("code",[t._v("git revert HEAD")]),t._v(" 将创建一个新的提交,撤销最近的提交所做的更改。这种方法不会删除之前的提交历史,而是创建一个新的提交来撤销之前的提交。")])]),t._v(" "),a("h3",{attrs:{id:"查看"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#查看"}},[t._v("#")]),t._v(" 查看")]),t._v(" "),a("ul",[a("li",[a("code",[t._v("git log --follow ")]),t._v(" 查看一个文件的提交记录,使用 "),a("code",[t._v("--follow")]),t._v(" 选项可以追踪文件的重命名或移动操作,以便在文件改名后仍然能够显示相关的提交记录。")])]),t._v(" "),a("h3",{attrs:{id:"stash"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#stash"}},[t._v("#")]),t._v(" stash")]),t._v(" "),a("p",[t._v("git stash 是 Git 版本控制系统中的一个命令,用于暂时保存当前工作目录的修改,并将其放入一个“存储堆栈”中。这样可以让您在不提交修改的情况下切换到其他分支或者进行其他操作。")]),t._v(" "),a("p",[t._v("当您在工作目录中有一些修改,但又不想立即提交这些修改时,可以使用 git stash 命令将这些修改保存起来。这将会清空当前工作目录,使其恢复到上一次提交的状态。")]),t._v(" "),a("p",[t._v("常用的命令:")]),t._v(" "),a("ul",[a("li",[a("code",[t._v("git stash")]),t._v(": 将当前工作目录的修改保存到一个临时的存储堆栈中。您可以继续在干净的工作目录上进行其他操作")]),t._v(" "),a("li",[a("code",[t._v("git stash list")])])]),t._v(" "),a("h3",{attrs:{id:"批量设置-git-config"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#批量设置-git-config"}},[t._v("#")]),t._v(" 批量设置 git config")]),t._v(" "),a("blockquote",[a("p",[t._v("使用 Git 的配置来实现在提交不同项目时使用不同的用户名")])]),t._v(" "),a("div",{staticClass:"language-shell line-numbers-mode"},[a("pre",{pre:!0,attrs:{class:"language-shell"}},[a("code",[a("span",{pre:!0,attrs:{class:"token function"}},[t._v("find")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v(".")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("-type")]),t._v(" d "),a("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("-name")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('".git"')]),t._v(" "),a("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("-execdir")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("git")]),t._v(" config user.name "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"xxx"')]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("\\")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("-execdir")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("git")]),t._v(" config user.email "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"xxxx@gmail.com"')]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("\\")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])]),t._v(" "),a("div",{staticClass:"line-numbers-wrapper"},[a("span",{staticClass:"line-number"},[t._v("1")]),a("br")])]),a("p",[t._v("解释:")]),t._v(" "),a("ul",[a("li",[a("code",[t._v("-execdir")]),t._v(" 是 find 命令的一个选项,用于在匹配的目录中执行指定的命令")])]),t._v(" "),a("h2",{attrs:{id:"术语"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#术语"}},[t._v("#")]),t._v(" 术语")]),t._v(" "),a("h3",{attrs:{id:"stage-changes-暂存区"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#stage-changes-暂存区"}},[t._v("#")]),t._v(" stage changes(暂存区)")]),t._v(" "),a("p",[t._v('在 Git 中,"stage changes"指的是将修改或新增的文件添加到暂存区(也称为索引)的过程。暂存区是在提交更改之前的一个中间区域,用于准备提交到版本控制系统中的文件。')]),t._v(" "),a("p",[t._v("当你在工作目录中修改或创建文件后,这些更改不会立即被记录到 Git 历史中。相反,你需要使用 git add 命令将这些更改添加到暂存区。通过将更改文件添加到暂存区,你告诉 Git 将这些更改包含在下一次提交中。")]),t._v(" "),a("p",[t._v("可以通过以下步骤将更改添加到暂存区:")]),t._v(" "),a("ol",[a("li",[t._v("使用"),a("code",[t._v("git add")]),t._v("命令加入要暂存的文件。例如,"),a("code",[t._v("git add myfile.tx")]),t._v("t 将"),a("code",[t._v("myfile.txt")]),t._v("文件添加到暂存区。")]),t._v(" "),a("li",[t._v("使用"),a("code",[t._v("git status")]),t._v('命令检查已暂存的更改。暂存的更改将显示在"Changes to be committed"部分中。\n一旦你将更改添加到暂存区,你可以使用'),a("code",[t._v("git commit")]),t._v("命令将其提交到 Git 历史记录中。提交后,暂存区中的更改将成为一个新的版本,并且可以在需要时回滚或查看历史记录。")])]),t._v(" "),a("p",[t._v("通过将更改分为工作目录、暂存区和历史记录这三个区域,Git 提供了一种灵活而强大的版本控制系统,使你能够精确控制文件的修改和提交过程。")]),t._v(" "),a("h2",{attrs:{id:"最佳实践"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#最佳实践"}},[t._v("#")]),t._v(" 最佳实践")]),t._v(" "),a("h3",{attrs:{id:"rebase-开发规范"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#rebase-开发规范"}},[t._v("#")]),t._v(" rebase 开发规范")]),t._v(" "),a("div",{staticClass:"custom-block tip"},[a("p",{staticClass:"custom-block-title"},[t._v("提示")]),t._v(" "),a("p",[t._v("开发分支 rebase master ,确保版本分支起点基于 master 最新节点")])]),t._v(" "),a("div",{staticClass:"language-bash line-numbers-mode"},[a("pre",{pre:!0,attrs:{class:"language-bash"}},[a("code",[a("span",{pre:!0,attrs:{class:"token function"}},[t._v("git")]),t._v(" checkout "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("版本分支"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("git")]),t._v(" pull --rebase/--no-rebase origin master\n"),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("git")]),t._v(" push "),a("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("-f")]),t._v("\n")])]),t._v(" "),a("div",{staticClass:"line-numbers-wrapper"},[a("span",{staticClass:"line-number"},[t._v("1")]),a("br"),a("span",{staticClass:"line-number"},[t._v("2")]),a("br"),a("span",{staticClass:"line-number"},[t._v("3")]),a("br")])]),a("h2",{attrs:{id:"hook"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#hook"}},[t._v("#")]),t._v(" hook")]),t._v(" "),a("blockquote",[a("p",[t._v("相关配置在 "),a("code",[t._v(".git/hooks/")]),t._v(" 后续进行完善")])])])}),[],!1,null,null,null);a.default=v.exports}}]); \ No newline at end of file diff --git a/assets/js/54.dbc23ce8.js b/assets/js/54.dbc23ce8.js new file mode 100644 index 0000000000..517e429aff --- /dev/null +++ b/assets/js/54.dbc23ce8.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[54],{380:function(t,n,a){"use strict";a.r(n);var e=a(4),p=Object(e.a)({},(function(){var t=this,n=t._self._c;return n("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[n("h2",{attrs:{id:"npm"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#npm"}},[t._v("#")]),t._v(" npm")]),t._v(" "),n("blockquote",[n("p",[n("RouterLink",{attrs:{to:"/pages/669dfc/"}},[t._v("链接")])],1)]),t._v(" "),n("h2",{attrs:{id:"npx"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#npx"}},[t._v("#")]),t._v(" npx")]),t._v(" "),n("blockquote",[n("p",[t._v("npx 是 npm v5.2.0 及更高版本中附带的一个工具。它用于执行一次性的命令行工具或安装的包。"),n("RText",{attrs:{text:"相比于全局安装包并在命令行中调用,npx 可以在不安装全局包的情况下直接运行包",color:"green"}}),t._v("。当你只需要临时使用一个工具或者尝试一个新的包时,npx 是一个很方便的选择。")],1)]),t._v(" "),n("p",[n("strong",[t._v("常用 npx 命令")])]),t._v(" "),n("ul",[n("li",[t._v("npx "),n("code",[t._v("")]),t._v(": 运行命令行工具或包,如果本地没有安装,则会自动下载和运行。")]),t._v(" "),n("li",[t._v("npx create-react-app my-app: 创建一个新的 React 应用程序。")]),t._v(" "),n("li",[t._v("npx -p "),n("code",[t._v("")]),t._v(" "),n("code",[t._v("")]),t._v(": 在运行命令之前,安装指定的包。")]),t._v(" "),n("li",[t._v("npx -c "),n("code",[t._v("")]),t._v(": 在命令行中执行 JavaScript 代码片段。")])])])}),[],!1,null,null,null);n.default=p.exports}}]); \ No newline at end of file diff --git a/assets/js/55.6b158b9e.js b/assets/js/55.6b158b9e.js new file mode 100644 index 0000000000..daa455b8b6 --- /dev/null +++ b/assets/js/55.6b158b9e.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[55],{381:function(e,v,a){"use strict";a.r(v);var _=a(4),n=Object(_.a)({},(function(){var e=this,v=e._self._c;return v("ContentSlotsDistributor",{attrs:{"slot-key":e.$parent.slotKey}},[v("div",{staticClass:"custom-block tip"},[v("p",{staticClass:"custom-block-title"},[e._v("提示")]),e._v(" "),v("p",[e._v("npm 是 Node.js 包管理器,提供了很多有用的命令来管理和维护项目中使用的包。 这里列举了一些常见的命令。 更多的命令请使用"),v("code",[e._v("npm help")]),e._v("查询")])]),e._v(" "),v("h2",{attrs:{id:"常用命令"}},[v("a",{staticClass:"header-anchor",attrs:{href:"#常用命令"}},[e._v("#")]),e._v(" 常用命令")]),e._v(" "),v("ul",[v("li",[v("code",[e._v("npm init")]),e._v(" 创建新的 package.json 文件,其中包含有关您的项目的信息和依赖项列表")]),e._v(" "),v("li",[e._v("install\n"),v("ul",[v("li",[v("code",[e._v("npm install")]),e._v(" 安装所需的包和依赖项。可以在命令行中指定包的名称,也可以将名称列入 package.json 文件中的依赖项列表")]),e._v(" "),v("li",[v("code",[e._v("npm install @latest")]),e._v(" 安装最新版本")]),e._v(" "),v("li",[v("code",[e._v("npm install --save ")]),e._v(" 将新的包添加到 package.json 文件的依赖项列表中,并安装它们")]),e._v(" "),v("li",[v("code",[e._v("npm install --save-dev ")]),e._v(" 将新的包添加到 package.json 文件的 devDependencies 列表中,并安装它们")]),e._v(" "),v("li",[v("code",[e._v("npm install --global")]),e._v(" 将包安装为全局包,使其在整个系统中可用")])])]),e._v(" "),v("li",[v("code",[e._v("npm uninstall ")]),e._v(" 卸载已安装的包和依赖项")]),e._v(" "),v("li",[v("code",[e._v("npm update")]),e._v(" 更新已安装的包和依赖项")]),e._v(" "),v("li",[v("code",[e._v("npm run")]),e._v(" 在 package.json 文件中定义的脚本中运行命令")]),e._v(" "),v("li",[v("code",[e._v("npm audit")]),e._v(" 检查项目中已安装的包是否存在已知的安全漏洞. audit 翻译成审计")]),e._v(" "),v("li",[v("code",[e._v("npm publish")]),e._v(" 将包发布到 npm 注册表中,以便其他人可以使用它")]),e._v(" "),v("li",[v("code",[e._v("npm view versions")]),e._v(" 查看一个 package 可用 version")]),e._v(" "),v("li",[v("code",[e._v("npm ls")]),e._v(" 查看项目的依赖树")]),e._v(" "),v("li",[v("code",[e._v("npm ls ")]),e._v(" 查看某个特定依赖的子树")])]),e._v(" "),v("h3",{attrs:{id:"查看子依赖"}},[v("a",{staticClass:"header-anchor",attrs:{href:"#查看子依赖"}},[e._v("#")]),e._v(" 查看子依赖")]),e._v(" "),v("blockquote",[v("p",[e._v("在有些时候需要查看 dependency 的子依赖")])]),e._v(" "),v("ul",[v("li",[e._v("查看 package-lock.json 文件")])]),e._v(" "),v("h3",{attrs:{id:"版本控制"}},[v("a",{staticClass:"header-anchor",attrs:{href:"#版本控制"}},[e._v("#")]),e._v(" 版本控制")]),e._v(" "),v("blockquote",[v("p",[e._v("package.json 文件是每个 Node.js 项目的核心配置文件,它不仅包含项目的元数据,还列出了项目的依赖项以及各个依赖项的版本。您可以在这个文件中使用"),v("a",{attrs:{href:"https://semver.org/",target:"_blank",rel:"noopener noreferrer"}},[e._v("语义化"),v("OutboundLink")],1),e._v("版本控制规范来控制依赖项的版本。版本号形式为: "),v("code",[e._v("MAJOR.MINOR.PATCH")])])]),e._v(" "),v("p",[e._v("规则:")]),e._v(" "),v("ul",[v("li",[e._v("使用波浪符号 (^) 表示锁定主版本号")]),e._v(" "),v("li",[e._v("使用波浪符号 (~) 表示锁定次要版本号")])]),e._v(" "),v("p",[e._v("举例,一个依赖项的版本可以指定为:")]),e._v(" "),v("ul",[v("li",[e._v('"^1.2.3": 包括了 1.2.0、1.2.1、1.2.2 等等,以及 1.3.0、1.4.0 等等。但不包括 2.0.0 或更高的版本,因为这涉及到主版本号的更改。')]),e._v(" "),v("li",[e._v('"~1.2.3": 允许安装 1.2.x 系列中的最新版本,但不包括 1.3.0 及其以上的版本')]),e._v(" "),v("li",[e._v('"1.2.3": 精确指定版本号为1.2.3。')])]),e._v(" "),v("h2",{attrs:{id:"其他"}},[v("a",{staticClass:"header-anchor",attrs:{href:"#其他"}},[e._v("#")]),e._v(" 其他")])])}),[],!1,null,null,null);v.default=n.exports}}]); \ No newline at end of file diff --git a/assets/js/56.2872159b.js b/assets/js/56.2872159b.js new file mode 100644 index 0000000000..9098299ad4 --- /dev/null +++ b/assets/js/56.2872159b.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[56],{382:function(a,e,s){"use strict";s.r(e);var t=s(4),l=Object(t.a)({},(function(){var a=this,e=a._self._c;return e("ContentSlotsDistributor",{attrs:{"slot-key":a.$parent.slotKey}},[e("div",{staticClass:"custom-block tip"},[e("p",{staticClass:"custom-block-title"},[a._v("提示")]),a._v(" "),e("p",[a._v("Android Debug Bridge (adb) is a versatile command-line tool that lets you communicate with a device. The adb command facilitates a variety of device actions, such as installing and debugging apps. adb provides access to a Unix shell that you can use to run a variety of commands on a device.")]),a._v(" "),e("p",[a._v("关于 adb 的更多介绍可见: "),e("a",{attrs:{href:"https://developer.android.com/tools/adb",target:"_blank",rel:"noopener noreferrer"}},[a._v("链接"),e("OutboundLink")],1)]),a._v(" "),e("ul",[e("li",[e("a",{attrs:{href:"https://github.com/mzlogin/awesome-adb",target:"_blank",rel:"noopener noreferrer"}},[a._v("awesome-adb"),e("OutboundLink")],1)]),a._v(" "),e("li",[e("a",{attrs:{href:"https://developer.android.com/studio/command-line",target:"_blank",rel:"noopener noreferrer"}},[a._v("官网"),e("OutboundLink")],1)])])]),a._v(" "),e("h2",{attrs:{id:"常用"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#常用"}},[a._v("#")]),a._v(" 常用")]),a._v(" "),e("h3",{attrs:{id:"dumpsys"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#dumpsys"}},[a._v("#")]),a._v(" dumpsys")]),a._v(" "),e("blockquote",[e("p",[a._v("dumpsys 同来用来 dumpsys 一些内存数据, 通过如下命令可以知道可以 dumpsys 哪些数据\nadb shell dumpsys -l")])]),a._v(" "),e("p",[a._v("常用的一些 dumpsys 相关的命令有:")]),a._v(" "),e("ul",[e("li",[e("code",[a._v("adb shell dumpsys activity activities")]),a._v(" 查看前台 Activity")]),a._v(" "),e("li",[e("code",[a._v("adb shell dumpsys activity top")])]),a._v(" "),e("li",[e("code",[a._v("adb shell dumpsys activity ")]),a._v(" 获取当前 Activity 中包含的 Fragment 信息, 如 "),e("code",[a._v("adb shell dumpsys activity com.example.app/.MainActivity")]),a._v(", 如下图:")]),a._v(" "),e("li",[e("code",[a._v("adb shell dumpsys activity broadcasts")])]),a._v(" "),e("li",[e("code",[a._v("adb shell dumpsys activity intents")])]),a._v(" "),e("li",[e("code",[a._v("adb shell dumpsys activity permissions")])]),a._v(" "),e("li",[e("code",[a._v("adb shell dumpsys activity processes")])]),a._v(" "),e("li",[e("code",[a._v("adb shell dumpsys activity providers")])]),a._v(" "),e("li",[e("code",[a._v("adb shell dumpsys activity recents")])]),a._v(" "),e("li",[e("code",[a._v("adb shell dumpsys activity services []")]),a._v(" 查看正在运行的 Services")]),a._v(" "),e("li",[e("code",[a._v("adb shell dumpsys meminfo <进程名称或进程ID>")]),a._v(" 内存信息")]),a._v(" "),e("li",[e("code",[a._v("adb shell dumpsys window | grep mCurrentFocus")]),a._v(" 获取设备的当前前台 Activity")]),a._v(" "),e("li",[e("code",[a._v("adb shell dumpsys SurfaceFlinger –latency")]),a._v(" 用于获取 Android 设备上 SurfaceFlinger 的延迟信息")]),a._v(" "),e("li",[e("code",[a._v("adb shell dumpsys gfxinfo $processName")]),a._v(" 用于获取特定应用程序进程的图形渲染信息")])]),a._v(" "),e("h3",{attrs:{id:"am"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#am"}},[a._v("#")]),a._v(" am")]),a._v(" "),e("blockquote",[e("p",[e("code",[a._v("adb shell am -h")])])]),a._v(" "),e("ul",[e("li",[e("code",[a._v("adb shell am crash")])]),a._v(" "),e("li",[e("code",[a._v("adb shell am kill")]),a._v(": 在安全模式下杀死进程,不影响用户体验")]),a._v(" "),e("li",[e("code",[a._v("adb shell am kill-all")]),a._v(": 杀掉所有后台程序")]),a._v(" "),e("li",[e("code",[a._v("adb shell am force-stop")]),a._v(": 应用在前台强制关闭,强制关闭指定的 package 包应用")]),a._v(" "),e("li",[e("code",[a._v("adb shell am start -D")])]),a._v(" "),e("li",[e("code",[a._v("adb shell am start -W")])]),a._v(" "),e("li",[e("code",[a._v("adb shell am set-debug-app -w $package")])]),a._v(" "),e("li",[e("code",[a._v("adb shell am set-debug-app -w --persistent $package")])]),a._v(" "),e("li",[e("code",[a._v("adb shell am clear-debug-app $package")]),a._v(" cancel debug with launch")]),a._v(" "),e("li",[e("code",[a._v("adb shell am broadcast -a $action")])]),a._v(" "),e("li",[e("code",[a._v("adb shell am broadcast -a $action -e x.command activity -e name jacky")]),a._v(" 通过 broadcast 传递参数")])]),a._v(" "),e("h3",{attrs:{id:"ps"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#ps"}},[a._v("#")]),a._v(" ps")]),a._v(" "),e("p",[e("code",[a._v("adb shell ps")]),a._v(" 命令提供了一些选项,可以用来过滤和显示特定的进程信息。以下是一些常用的选项:")]),a._v(" "),e("ul",[e("li",[e("code",[a._v("-A")]),a._v(":显示所有进程,包括系统进程和应用程序进程。")]),a._v(" "),e("li",[e("code",[a._v("-a")]),a._v(":显示除了无效的进程(已经被 init 启动的进程)之外的所有进程。")]),a._v(" "),e("li",[e("code",[a._v("-x")]),a._v(":显示所有进程,包括未运行的进程。")]),a._v(" "),e("li",[e("code",[a._v("-r")]),a._v(":按照内存使用量来排序进程。")]),a._v(" "),e("li",[e("code",[a._v("-n")]),a._v(":按照进程名字来排序进程。")]),a._v(" "),e("li",[e("code",[a._v("-s")]),a._v(":按照进程状态来排序进程。")]),a._v(" "),e("li",[e("code",[a._v("-p")]),a._v(":显示进程的 PID(进程标识符)。")]),a._v(" "),e("li",[e("code",[a._v("-c")]),a._v(":显示进程的 CPU 利用率。")]),a._v(" "),e("li",[e("code",[a._v("-u")]),a._v(":显示进程的用户名称和 UID(用户标识符)。")]),a._v(" "),e("li",[e("code",[a._v("-t")]),a._v(":显示进程的线程信息。")]),a._v(" "),e("li",[e("code",[a._v("-Z")]),a._v(":显示进程的安全上下文。")])]),a._v(" "),e("p",[a._v("您可以根据需要选择适当的选项来获取所需的进程信息。例如,使用命令 adb shell ps -p 可以显示进程的 PID,而使用命令 adb shell ps -t 可以显示进程的线程信息")]),a._v(" "),e("h3",{attrs:{id:"logcat"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#logcat"}},[a._v("#")]),a._v(" logcat")]),a._v(" "),e("ul",[e("li",[e("code",[a._v("adb logcat -G 16M")]),a._v(" 将缓冲区大小设置为 16MB")]),a._v(" "),e("li",[e("code",[a._v("adb logcat -c")]),a._v(" 清除设备日志缓存的 ADB 命令")]),a._v(" "),e("li",[e("code",[a._v("adb logcat -b crash")]),a._v(" 查看设备上的崩溃日志")]),a._v(" "),e("li",[a._v("日志过滤\n"),e("ul",[e("li",[e("code",[a._v("adb logcat *:V")])]),a._v(" "),e("li",[e("code",[a._v("adb logcat *:E")])]),a._v(" "),e("li",[e("code",[a._v('adb logcat -s "keyword"')])]),a._v(" "),e("li",[e("code",[a._v('adb logcat *:E -s "keyword"')])]),a._v(" "),e("li",[e("code",[a._v("adb logcat | grep -E 'regex'")])])])])]),a._v(" "),e("h3",{attrs:{id:"input"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#input"}},[a._v("#")]),a._v(" input")]),a._v(" "),e("blockquote",[e("p",[e("code",[a._v("adb shell input")]),a._v(" 是用于模拟输入事件的 ADB 命令,它可以在 Android 设备上执行各种输入操作,如按键、点击、滑动等。")])]),a._v(" "),e("p",[a._v("以下是 adb shell input 命令的一些常见用法:")]),a._v(" "),e("ul",[e("li",[e("p",[a._v("模拟点击事件:"),e("code",[a._v("adb shell input tap x y")]),a._v("\n这里的 x 和 y 分别是屏幕上的横纵坐标,用于指定点击的位置。")])]),a._v(" "),e("li",[e("p",[a._v("模拟按键事件:"),e("code",[a._v("adb shell input keyevent KEYCODE")]),a._v("\n这里的 KEYCODE 是表示按键码的整数值,用于模拟按下指定的按键。(KeyCode 查询"),e("a",{attrs:{href:"https://developer.android.com/reference/android/view/KeyEvent",target:"_blank",rel:"noopener noreferrer"}},[a._v("地址"),e("OutboundLink")],1),a._v(")")])]),a._v(" "),e("li",[e("p",[a._v("模拟滑动事件:"),e("code",[a._v("adb shell input swipe x1 y1 x2 y2 [duration]")]),a._v("\n这里的(x1, y1)和(x2, y2)是滑动起始点和终点的坐标,duration 表示滑动的持续时间。")])]),a._v(" "),e("li",[e("p",[a._v('模拟输入文本:adb shell input text "your_text"\n这里的 your_text 是要输入的文本内容,可以是任意字符串。')])]),a._v(" "),e("li",[e("p",[a._v("长按某个按键:adb shell input keyevent --longpress KEYCODE\n这里的 KEYCODE 是表示按键码的整数值,用于模拟长按指定的按键。")])])]),a._v(" "),e("p",[a._v("注意:使用 "),e("code",[a._v("adb shell input")]),a._v(' 命令需要连接到 Android 设备,并且设备必须具有开发者选项中的"USB 调试"选项已启用。此外,某些命令可能需要 Root 权限才能执行。')]),a._v(" "),e("h3",{attrs:{id:"其他"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#其他"}},[a._v("#")]),a._v(" 其他")]),a._v(" "),e("ul",[e("li",[e("code",[a._v("adb shell ip address show wlan0")]),a._v(" 查看 "),e("code",[a._v("wlan0")]),a._v(" 网络接口的 IP 地址信息")]),a._v(" "),e("li",[e("code",[a._v('adb shell ifconfig | grep "inet "')]),a._v(" 获取 Android 设备的 IP 地址")]),a._v(" "),e("li",[e("code",[a._v('adb shell "su -c ifconfig"')]),a._v(" 查看和配置网络接口信息的命令")]),a._v(" "),e("li",[e("code",[a._v("adb shell getprop -T")]),a._v(" Show property types instead of values")]),a._v(" "),e("li",[e("code",[a._v("adb shell getprop -Z")]),a._v(" Show property contexts instead of values")]),a._v(" "),e("li",[e("code",[a._v("adb shell getprop ro.product.cpu.abi")]),a._v(" 获取手机支持的 arm 架构")]),a._v(" "),e("li",[e("code",[a._v("adb bugreport crash.txt")]),a._v(' 生成一个完整的设备状态报告,并包括崩溃日志。它将崩溃日志保存到名为"crash.txt"的文件中')]),a._v(" "),e("li",[e("code",[a._v("adb kill-server")]),a._v(" 结束 adb 进程")]),a._v(" "),e("li",[e("code",[a._v("adb start-server")]),a._v(" 启动 adb 进程")]),a._v(" "),e("li",[e("code",[a._v("adb install -r ")])]),a._v(" "),e("li",[e("code",[a._v("adb uninstall ")])]),a._v(" "),e("li",[e("code",[a._v("adb reboot")])]),a._v(" "),e("li",[e("code",[a._v("adb shell run-as cat <私有路径文件> <输出到mac端的路径>")]),a._v(": 拉取应用私有目录到 pc 端, 需要应用 debugable")])]),a._v(" "),e("h2",{attrs:{id:"tricks"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#tricks"}},[a._v("#")]),a._v(" Tricks")]),a._v(" "),e("ul",[e("li",[a._v("dump anr info")])]),a._v(" "),e("div",{staticClass:"language-shell line-numbers-mode"},[e("pre",{pre:!0,attrs:{class:"language-shell"}},[e("code",[a._v("adb shell\nrun-as "),e("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$package")]),a._v(" // run app as root\n"),e("span",{pre:!0,attrs:{class:"token function"}},[a._v("kill")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-s")]),a._v(" SIGQUIT "),e("span",{pre:!0,attrs:{class:"token operator"}},[a._v("<")]),a._v("pid"),e("span",{pre:!0,attrs:{class:"token operator"}},[a._v(">")]),a._v("\n")])]),a._v(" "),e("div",{staticClass:"line-numbers-wrapper"},[e("span",{staticClass:"line-number"},[a._v("1")]),e("br"),e("span",{staticClass:"line-number"},[a._v("2")]),e("br"),e("span",{staticClass:"line-number"},[a._v("3")]),e("br")])]),e("h2",{attrs:{id:"实践"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#实践"}},[a._v("#")]),a._v(" 实践")]),a._v(" "),e("h3",{attrs:{id:"访问私有目录文件"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#访问私有目录文件"}},[a._v("#")]),a._v(" 访问私有目录文件")]),a._v(" "),e("blockquote",[e("p",[a._v("下面使用的常规方法获取私有目录权限,所以此方法需要 app 可调试")])]),a._v(" "),e("ol",[e("li",[e("code",[a._v("run-as $package")]),a._v(" 将指定目录压缩")])]),a._v(" "),e("div",{staticClass:"language-shell line-numbers-mode"},[e("pre",{pre:!0,attrs:{class:"language-shell"}},[e("code",[e("span",{pre:!0,attrs:{class:"token function"}},[a._v("tar")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-zcvf")]),a._v(" mojituo.tar.gz "),e("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$dir")]),a._v("\n")])]),a._v(" "),e("div",{staticClass:"line-numbers-wrapper"},[e("span",{staticClass:"line-number"},[a._v("1")]),e("br")])]),e("ol",{attrs:{start:"2"}},[e("li",[a._v("退出手机 shell,将数据流重定向到 mac 端")])]),a._v(" "),e("div",{staticClass:"language-shell line-numbers-mode"},[e("pre",{pre:!0,attrs:{class:"language-shell"}},[e("code",[a._v("adb shell run-as "),e("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$package")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token function"}},[a._v("cat")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),e("span",{pre:!0,attrs:{class:"token variable"}},[e("span",{pre:!0,attrs:{class:"token variable"}},[a._v("`")]),a._v("上述目录的打包成zip的路径"),e("span",{pre:!0,attrs:{class:"token variable"}},[a._v("`")])]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[a._v(">")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),e("span",{pre:!0,attrs:{class:"token variable"}},[e("span",{pre:!0,attrs:{class:"token variable"}},[a._v("`")]),a._v("输出到mac端的路径"),e("span",{pre:!0,attrs:{class:"token variable"}},[a._v("`")])]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),a._v("\n")])]),a._v(" "),e("div",{staticClass:"line-numbers-wrapper"},[e("span",{staticClass:"line-number"},[a._v("1")]),e("br")])]),e("p",[a._v("二、release 日志")]),a._v(" "),e("div",{staticClass:"language-sh line-numbers-mode"},[e("pre",{pre:!0,attrs:{class:"language-sh"}},[e("code",[a._v("private val DEBUG "),e("span",{pre:!0,attrs:{class:"token operator"}},[a._v("=")]),a._v(" Log.isLoggable"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[a._v('"MessageFragment"')]),a._v(", Log.DEBUG"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),a._v("\n\nadb shell setprop log.tag.Main D\nadb shell setprop log.tag.MessageFragment D\n")])]),a._v(" "),e("div",{staticClass:"line-numbers-wrapper"},[e("span",{staticClass:"line-number"},[a._v("1")]),e("br"),e("span",{staticClass:"line-number"},[a._v("2")]),e("br"),e("span",{staticClass:"line-number"},[a._v("3")]),e("br"),e("span",{staticClass:"line-number"},[a._v("4")]),e("br")])]),e("h3",{attrs:{id:"接口转发"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#接口转发"}},[a._v("#")]),a._v(" 接口转发")]),a._v(" "),e("p",[a._v("【背景】咨询一个网络的问题,我这里有两台设备,分别为 PC 和 Android A 设备,这两个设备处于同一个 wifi 下面,比如 wifi 名称为 wifiA。\n另外有一个设备 Android B, 处于一些原因没有连接到 wifiA。而是通过热点连接到 Android A 的热点上,从而 PC 和 Android B 也能互通私有的资源。\nAndroid B 的 ip 地址为: "),e("code",[a._v("192.168.254.193")]),a._v("。 另外 Android B 上面安装了 frida 服务,如果 PC 要访问 Android B 的服务,我这里通过如下命令进行连接:\n"),e("code",[a._v("objection -N --host 192.168.254.193 --port 1234 explore")])]),a._v(" "),e("p",[a._v("最终的结果是:")]),a._v(" "),e("div",{staticClass:"language-shell line-numbers-mode"},[e("pre",{pre:!0,attrs:{class:"language-shell"}},[e("code",[a._v("Unable to connect to the frida server: unable to connect to remote frida-server: Could not connect to "),e("span",{pre:!0,attrs:{class:"token number"}},[a._v("192.168")]),a._v(".254.193: Operation timed out\n")])]),a._v(" "),e("div",{staticClass:"line-numbers-wrapper"},[e("span",{staticClass:"line-number"},[a._v("1")]),e("br")])]),e("p",[e("strong",[a._v("以下的回答供参考 "),e("RText",{attrs:{text:"chatGPT",color:"green"}}),a._v(",并没有测试通过:")],1)]),a._v(" "),e("p",[a._v("根据您提供的信息,我们可以看到 Android B 连接到了 Android A 的热点上,这会导致 Android B 和 PC 处于不同的子网中,因此 PC 无法直接访问 Android B 的 IP 地址。为了解决这个问题,您可以尝试通过以下步骤进行操作:")]),a._v(" "),e("p",[a._v("一、在 Android A 上启用 IP 转发功能。 在 Android A 的终端上运行以下命令:")]),a._v(" "),e("div",{staticClass:"language-shell line-numbers-mode"},[e("pre",{pre:!0,attrs:{class:"language-shell"}},[e("code",[e("span",{pre:!0,attrs:{class:"token function"}},[a._v("su")]),a._v("\n"),e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v("echo")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[a._v("1")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[a._v(">")]),a._v(" /proc/sys/net/ipv4/ip_forward\n")])]),a._v(" "),e("div",{staticClass:"line-numbers-wrapper"},[e("span",{staticClass:"line-number"},[a._v("1")]),e("br"),e("span",{staticClass:"line-number"},[a._v("2")]),e("br")])]),e("p",[a._v("这将启用 Android A 上的 IP 转发功能,使其可以将来自 PC 的请求转发到 Android B。")]),a._v(" "),e("p",[a._v("二、设置 Android B 的默认网关。\n在 Android B 的终端上运行以下命令:")]),a._v(" "),e("div",{staticClass:"language-shell line-numbers-mode"},[e("pre",{pre:!0,attrs:{class:"language-shell"}},[e("code",[e("span",{pre:!0,attrs:{class:"token function"}},[a._v("su")]),a._v("\nroute "),e("span",{pre:!0,attrs:{class:"token function"}},[a._v("add")]),a._v(" default gw "),e("span",{pre:!0,attrs:{class:"token number"}},[a._v("192.168")]),a._v(".43.1\n")])]),a._v(" "),e("div",{staticClass:"line-numbers-wrapper"},[e("span",{staticClass:"line-number"},[a._v("1")]),e("br"),e("span",{staticClass:"line-number"},[a._v("2")]),e("br")])]),e("p",[a._v("其中,192.168.43.1 是 Android A 的 IP 地址,这将设置 Android B 的默认网关为 Android A 的 IP 地址。")]),a._v(" "),e("p",[a._v("三、在 PC 上设置路由规则。\n在 PC 上运行以下命令:\n"),e("code",[a._v("route add -net 192.168.254.0 netmask 255.255.255.0 gw 192.168.43.119")]),a._v("\n其中,192.168.43.119 是 Android A 的 IP 地址,这将设置 PC 的路由规则,使其可以将请求发送到 Android A。")])])}),[],!1,null,null,null);e.default=l.exports}}]); \ No newline at end of file diff --git a/assets/js/57.c84be887.js b/assets/js/57.c84be887.js new file mode 100644 index 0000000000..cfb6cdb253 --- /dev/null +++ b/assets/js/57.c84be887.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[57],{383:function(a,t,i){"use strict";i.r(t);var e=i(4),p=Object(e.a)({},(function(){var a=this,t=a._self._c;return t("ContentSlotsDistributor",{attrs:{"slot-key":a.$parent.slotKey}},[t("blockquote",[t("p",[a._v("aapt(Android Asset Packaging Tool)是一个用于打包和管理 Android 应用程序资源的命令行工具。它可以执行多种操作,包括编译资源、打包 APK 文件、解析 APK 文件等。以下是一些常用的")])]),a._v(" "),t("h2",{attrs:{id:"aapt-命令及其功能"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#aapt-命令及其功能"}},[a._v("#")]),a._v(" aapt 命令及其功能:")]),a._v(" "),t("ul",[t("li",[t("code",[a._v("aapt dump badging ")]),a._v(":显示 APK 文件的清单信息,包括应用程序包名、版本信息、启动 Activity、权限等。")]),a._v(" "),t("li",[t("code",[a._v("aapt list ")]),a._v(":列出 APK 文件中的所有文件和目录。")]),a._v(" "),t("li",[t("code",[a._v("aapt crunch -C ")]),a._v(":压缩和优化指定目录中的资源文件。")]),a._v(" "),t("li",[t("code",[a._v("aapt add [ ...]")]),a._v(":向 APK 文件中添加文件。")]),a._v(" "),t("li",[t("code",[a._v("aapt remove [ ...]")]),a._v(":从 APK 文件中删除文件。")]),a._v(" "),t("li",[t("code",[a._v("aapt package -f -M -I [ ...] -F -S -A ")]),a._v(":根据提供的清单文件、资源目录和资产目录等生成 APK 文件。")])]),a._v(" "),t("p",[a._v("这只是 aapt 工具的一些常见用法和命令示例。您可以通过运行 aapt 命令加上 --help 参数来获取更多详细的命令选项和用法说明。")]),a._v(" "),t("p",[a._v("注意:从 Android SDK 25 开始,aapt 已被 aapt2 替代为默认的资源编译和打包工具,但仍然可以使用 aapt 进行一些基本操作和与旧版本的 APK 兼容。")])])}),[],!1,null,null,null);t.default=p.exports}}]); \ No newline at end of file diff --git a/assets/js/58.c5576bf5.js b/assets/js/58.c5576bf5.js new file mode 100644 index 0000000000..77708747cf --- /dev/null +++ b/assets/js/58.c5576bf5.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[58],{384:function(_,t,c){"use strict";c.r(t);var e=c(4),i=Object(e.a)({},(function(){var _=this,t=_._self._c;return t("ContentSlotsDistributor",{attrs:{"slot-key":_.$parent.slotKey}},[t("h2",{attrs:{id:"编译工具-gcc"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#编译工具-gcc"}},[_._v("#")]),_._v(" 编译工具 gcc")]),_._v(" "),t("div",{staticClass:"custom-block tip"},[t("p",{staticClass:"custom-block-title"},[_._v("提示")]),_._v(" "),t("p",[t("code",[_._v("GCC")]),_._v("(GNU Compiler Collection)是一个广泛使用的开源编译器套件,其中包含了多种编程语言的编译器,其中包括 C++。GCC 是 C++开发者常用的编译工具之一,下面是 GCC 的一些通常用法:\nGCC 提供了丰富的选项和功能,可以根据需要进行更高级的编译配置和优化。可以通过 "),t("code",[_._v("man gcc")]),_._v(" 命令查看更多详细的文档和选项说明。")])]),_._v(" "),t("h3",{attrs:{id:"常用命令"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#常用命令"}},[_._v("#")]),_._v(" 常用命令")]),_._v(" "),t("ul",[t("li",[t("code",[_._v("gcc --help")])]),_._v(" "),t("li",[t("code",[_._v("gcc -Wall hi.c -o hi")]),_._v(" 编译 hi.c 文件,输出为 hi")]),_._v(" "),t("li",[t("code",[_._v("gcc -o output_file input_file.cpp")]),_._v(" 编译名为 input_file.cpp 的源文件,并将输出的可执行文件命名为 output_file")]),_._v(" "),t("li",[t("code",[_._v("gcc -o output_file input_file1.cpp input_file2.cpp")]),_._v(" 编译多个源文件,并将它们链接成一个可执行文件 output_file")]),_._v(" "),t("li",[t("code",[_._v("gcc -o output_file input_file.cpp -Wall -Wextra -O2")]),_._v(" 使用"),t("code",[_._v("-Wall")]),_._v(" 和"),t("code",[_._v("-Wextra")]),_._v(" 选项开启更多的警告信息,并使用-O2 选项开启优化")]),_._v(" "),t("li",[t("code",[_._v("gcc -o output_file input_file.cpp -m32")]),_._v(" 使用"),t("code",[_._v("-m32")]),_._v(" 选项将编译为 32 位目标,而不是默认的 64 位目标")]),_._v(" "),t("li",[t("code",[_._v("gcc -o output_file input_file.cpp -g")]),_._v(" 使用"),t("code",[_._v("-g")]),_._v(" 选项生成调试信息,以便在调试过程中使用")]),_._v(" "),t("li",[t("code",[_._v("gcc -o output_file input_file.cpp -l library_name")]),_._v(" 使用"),t("code",[_._v("-l")]),_._v(" 选项链接外部库,其中 library_name 是要链接的库名")]),_._v(" "),t("li",[t("code",[_._v("gcc -E input_file.cpp -o output_file.cpp")]),_._v(" 使用"),t("code",[_._v("-E")]),_._v(" 选项进行预处理,并将预处理结果输出到 output_file.cpp 中")]),_._v(" "),t("li",[t("code",[_._v("gcc -S input_file.cpp -o output_file.s")]),_._v(" 使用"),t("code",[_._v("-S")]),_._v(" 选项将源文件编译为汇编代码,并将汇编代码输出到 output_file.s 中")]),_._v(" "),t("li",[t("code",[_._v("gcc -o output_file input_file.cpp -target target_triplet")]),_._v(" 使用"),t("code",[_._v("-target")]),_._v(" 选项指定交叉编译的目标平台")])])])}),[],!1,null,null,null);t.default=i.exports}}]); \ No newline at end of file diff --git a/assets/js/59.5186dd10.js b/assets/js/59.5186dd10.js new file mode 100644 index 0000000000..6c0832e3ae --- /dev/null +++ b/assets/js/59.5186dd10.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[59],{385:function(e,t,s){"use strict";s.r(t);var a=s(4),i=Object(a.a)({},(function(){var e=this,t=e._self._c;return t("ContentSlotsDistributor",{attrs:{"slot-key":e.$parent.slotKey}},[t("blockquote",[t("p",[e._v("pip3 是 Python 的包管理器,用于安装、升级和管理 Python 包。它是 Python 的官方包管理工具,提供了便捷的方式来获取、安装和管理第三方库和工具。")])]),e._v(" "),t("h2",{attrs:{id:"pip3-的常见用法"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#pip3-的常见用法"}},[e._v("#")]),e._v(" pip3 的常见用法")]),e._v(" "),t("ul",[t("li",[t("code",[e._v("pip3 --help")])]),e._v(" "),t("li",[t("code",[e._v("pip3 install requests")]),e._v(" 安装名为 requests 的包")]),e._v(" "),t("li",[t("code",[e._v("pip3 install --upgrade requests")]),e._v(" 升级 requests 包")]),e._v(" "),t("li",[t("code",[e._v("pip3 install requests==$version")]),e._v(" 升级到指定版本")]),e._v(" "),t("li",[t("code",[e._v("pip3 uninstall requests")]),e._v(" 卸载 requests 包")]),e._v(" "),t("li",[t("code",[e._v("pip3 list")]),e._v(" 列出当前环境中已安装的所有包及其版本号")]),e._v(" "),t("li",[t("code",[e._v("pip3 freeze > requirements.txt")]),e._v(" 将包列表导出到 "),t("code",[e._v("requirements.txt")]),e._v(" 文件")]),e._v(" "),t("li",[t("code",[e._v("pip3 install -r requirements.txt")]),e._v(" 从 requirements.txt 文件中安装包")])]),e._v(" "),t("h2",{attrs:{id:"pip3-版本问题"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#pip3-版本问题"}},[e._v("#")]),e._v(" pip3 版本问题")]),e._v(" "),t("p",[e._v("在系统安装了多个 python3 编译器的场景下, 直接使用 pip3 安装到不同的编译器中,类似于下面这样的输出\n"),t("img",{attrs:{src:"https://cdn.jsdelivr.net/gh/jacky1234/picArchieve@master/uPic/20230917_203717_MfJuxi.png",alt:""}})]),e._v(" "),t("p",[e._v("方案一:全路径安装")]),e._v(" "),t("ul",[t("li",[t("code",[e._v("$PYTHON -m pip install lettuce")])])]),e._v(" "),t("p",[e._v("所以有的时候我们希望为指定的 python3 版本安装依赖。我是这样处理的.将如下路径添加进 path 路径\n"),t("img",{attrs:{src:"https://cdn.jsdelivr.net/gh/jacky1234/picArchieve@master/uPic/20230917_203908_kVdk86.png",alt:""}})]),e._v(" "),t("ul",[t("li",[e._v("如图如果给 python3.9 安装依赖则运行 pip3.9")]),e._v(" "),t("li",[e._v("如图如果给 python3.11 安装依赖则运行 pip3.11")])]),e._v(" "),t("h2",{attrs:{id:"package-模块版本控制"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#package-模块版本控制"}},[e._v("#")]),e._v(" package 模块版本控制")]),e._v(" "),t("blockquote",[t("p",[e._v("在通过"),t("code",[e._v("pip3")]),e._v("安装 package 通常会对版本进行限制。以下是两种常用的版本控制方式:")])]),e._v(" "),t("div",{staticClass:"custom-block warning"},[t("p",{staticClass:"custom-block-title"},[e._v("注意")]),e._v(" "),t("p",[e._v("使用引号将版本范围括起来。确保 < 等符号被正确解释为版本限制符号,而不是 shell 的输入重定向符号")])]),e._v(" "),t("ol",[t("li",[e._v("安装特定版本的包:\n如果要安装特定版本的包,可以使用 "),t("code",[e._v("package_name==version_number")]),e._v(" 的语法。例如,要安装 requests 包的 2.25.1 版本,可以运行以下命令:")])]),e._v(" "),t("div",{staticClass:"language-shell line-numbers-mode"},[t("pre",{pre:!0,attrs:{class:"language-shell"}},[t("code",[e._v("pip3 "),t("span",{pre:!0,attrs:{class:"token function"}},[e._v("install")]),e._v(" "),t("span",{pre:!0,attrs:{class:"token string"}},[e._v("'requests==2.25.1'")]),e._v("\n")])]),e._v(" "),t("div",{staticClass:"line-numbers-wrapper"},[t("span",{staticClass:"line-number"},[e._v("1")]),t("br")])]),t("ol",{attrs:{start:"2"}},[t("li",[e._v("安装符合指定版本范围的包:\n如果您希望安装符合特定版本范围的包,可以使用 "),t("code",[e._v("package_name>=min_version,<=max_version")]),e._v(" 的语法。例如,要安装 "),t("code",[e._v("numpy")]),e._v(" 包的版本在 1.18.0 到 1.19.0 之间(包括这两个版本),可以运行以下命令:")])]),e._v(" "),t("div",{staticClass:"language-shell line-numbers-mode"},[t("pre",{pre:!0,attrs:{class:"language-shell"}},[t("code",[e._v("pip3 "),t("span",{pre:!0,attrs:{class:"token function"}},[e._v("install")]),e._v(" "),t("span",{pre:!0,attrs:{class:"token string"}},[e._v("'numpy>=1.18.0,<=1.19.0'")]),e._v("\n")])]),e._v(" "),t("div",{staticClass:"line-numbers-wrapper"},[t("span",{staticClass:"line-number"},[e._v("1")]),t("br")])]),t("p",[e._v("通过指定特定版本或版本范围,您可以控制要安装的包的确切版本,以满足您的项目需求或依赖关系。")])])}),[],!1,null,null,null);t.default=i.exports}}]); \ No newline at end of file diff --git a/assets/js/6.d320717b.js b/assets/js/6.d320717b.js new file mode 100644 index 0000000000..17f8352531 --- /dev/null +++ b/assets/js/6.d320717b.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[6],{328:function(t,s,n){},352:function(t,s,n){"use strict";n(328)},360:function(t,s,n){"use strict";n.r(s);const i=["这里什么都没有。","我是谁?我在哪?","这是一个Four-Oh-Four.","看来我们的链接坏掉了~"];var o={methods:{getMsg:()=>i[Math.floor(Math.random()*i.length)]}},e=(n(352),n(4)),a=Object(e.a)(o,(function(){var t=this._self._c;return t("div",{staticClass:"theme-container"},[t("div",{staticClass:"theme-vdoing-content"},[t("span",[this._v("404")]),this._v(" "),t("blockquote",[this._v(this._s(this.getMsg()))]),this._v(" "),t("router-link",{attrs:{to:"/"}},[this._v("返回首页")])],1)])}),[],!1,null,"439bb2a8",null);s.default=a.exports}}]); \ No newline at end of file diff --git a/assets/js/60.965ec7df.js b/assets/js/60.965ec7df.js new file mode 100644 index 0000000000..b9e6dcd061 --- /dev/null +++ b/assets/js/60.965ec7df.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[60],{386:function(v,_,e){"use strict";e.r(_);var i=e(4),t=Object(i.a)({},(function(){var v=this,_=v._self._c;return _("ContentSlotsDistributor",{attrs:{"slot-key":v.$parent.slotKey}},[_("div",{staticClass:"custom-block tip"},[_("p",{staticClass:"custom-block-title"},[v._v("提示")]),v._v(" "),_("p",[v._v("vim linux 上使用较多的文本编辑器。 具有程序编辑的能力,可以主动的以字体颜色辨别语法的正确性,方便程序设计")]),v._v(" "),_("ol",[_("li",[v._v("vim 提供了交互式教程工具 "),_("a",{attrs:{href:"#vimtutor"}},[v._v("vimtutor")]),v._v(", 这对熟悉 vim 基础用法非常有用")]),v._v(" "),_("li",[v._v("另外你可以通过在文件 "),_("code",[v._v("~/.vimrc")]),v._v(" 为 vim 设置配置, 参考"),_("a",{attrs:{href:"https://www.freecodecamp.org/news/vimrc-configuration-guide-customize-your-vim-editor/",target:"_blank",rel:"noopener noreferrer"}},[v._v("链接"),_("OutboundLink")],1)])])]),v._v(" "),_("h2",{attrs:{id:"基础操作"}},[_("a",{staticClass:"header-anchor",attrs:{href:"#基础操作"}},[v._v("#")]),v._v(" 基础操作")]),v._v(" "),_("h3",{attrs:{id:"命令模式"}},[_("a",{staticClass:"header-anchor",attrs:{href:"#命令模式"}},[v._v("#")]),v._v(" 命令模式")]),v._v(" "),_("p",[v._v("在正常模式中,按下"),_("code",[v._v(":")]),v._v("(冒号)键或者 "),_("code",[v._v("/")]),v._v("(斜杠),会进入命令模式。在命令模式中可以执行一些输入并执行一些 VIM 或插件提供的指令,就像在 "),_("code",[v._v("shell")]),v._v(" 里一样。这些指令包括设置环境、文件操作、调用某个功能等等。")]),v._v(" "),_("ul",[_("li",[_("code",[v._v("set nu")]),v._v(" 显示行")]),v._v(" "),_("li",[_("code",[v._v("set nonu")])]),v._v(" "),_("li",[_("code",[v._v("set nu!")]),v._v(": 在行号与非显示行号切换")]),v._v(" "),_("li",[_("code",[v._v(":n")]),v._v(" , 定位指定行")]),v._v(" "),_("li",[_("code",[v._v(":set ic")]),v._v(" , 编辑器将不会区分大小写")]),v._v(" "),_("li",[_("code",[v._v(":set noic")])])]),v._v(" "),_("h3",{attrs:{id:"编辑模式"}},[_("a",{staticClass:"header-anchor",attrs:{href:"#编辑模式"}},[v._v("#")]),v._v(" 编辑模式")]),v._v(" "),_("p",[v._v('在 Vim 中,要从命令模式进入编辑模式,你可以按下 i 键(小写字母 "i")或其他一些按键来切换到插入模式,具体取决于你想要插入文本的位置和模式。以下是一些常见的进入编辑模式的方式:')]),v._v(" "),_("blockquote",[_("p",[v._v("常用的为: "),_("code",[v._v("i,I,a,A,o,O,s,S")])])]),v._v(" "),_("ul",[_("li",[_("p",[v._v("按下 "),_("code",[v._v("i")]),v._v(" 键: 这是最常见的方式,它允许你在当前光标位置之前插入文本。只需按下 i 键,然后你可以开始键入文本。")])]),v._v(" "),_("li",[_("p",[v._v("按下 "),_("code",[v._v("I")]),v._v(" 键: 与 i 键不同,按下 I 键会将光标移动到当前行的行首,然后进入插入模式,从行首开始插入文本。")])]),v._v(" "),_("li",[_("p",[v._v("按下 "),_("code",[v._v("a")]),v._v(" 键: 这个键将在当前光标位置之后进入插入模式,允许你在光标的右侧插入文本。")])]),v._v(" "),_("li",[_("p",[v._v("按下 "),_("code",[v._v("A")]),v._v(" 键: 与 a 键相反,按下 A 键会将光标移到当前行的行尾,然后进入插入模式,从行尾开始插入文本。")])]),v._v(" "),_("li",[_("p",[v._v("按下 "),_("code",[v._v("o")]),v._v(" 键: 这个键会在当前行的下面插入一个新的空白行,并进入插入模式,允许你在新行上插入文本。")])]),v._v(" "),_("li",[_("p",[v._v("按下 "),_("code",[v._v("O")]),v._v(" 键: 与 o 键相反,按下 O 键会在当前行的上面插入一个新的空白行,并进入插入模式,允许你在新行上插入文本。")])]),v._v(" "),_("li",[_("p",[_("code",[v._v("s")]),v._v(" , 删除光标所在处的字符然后插入需要录入的文本")])]),v._v(" "),_("li",[_("p",[_("code",[v._v("S")]),v._v(" , 删除光标所在行,在当前行的行首开始插入需要录入的文本")])]),v._v(" "),_("li",[_("p",[_("code",[v._v("cw")]),v._v(" , 删除从光标处开始到该单词结束的所有字符")])])]),v._v(" "),_("h3",{attrs:{id:"可视模式"}},[_("a",{staticClass:"header-anchor",attrs:{href:"#可视模式"}},[v._v("#")]),v._v(" 可视模式")]),v._v(" "),_("ul",[_("li",[_("code",[v._v("v")]),v._v(" , 字符可视化")]),v._v(" "),_("li",[_("code",[v._v("V")]),v._v(" , 行可视化")]),v._v(" "),_("li",[_("code",[v._v("Ctrl+v")]),v._v(" , 块状可视化")])]),v._v(" "),_("h3",{attrs:{id:"光标"}},[_("a",{staticClass:"header-anchor",attrs:{href:"#光标"}},[v._v("#")]),v._v(" 光标")]),v._v(" "),_("ul",[_("li",[v._v("h, j, k, l, 左下上右")]),v._v(" "),_("li",[v._v("0 , 移动到行头")]),v._v(" "),_("li",[v._v("^ , 移动到本行的第一个不是 blank 字符")]),v._v(" "),_("li",[v._v("$ , 移动到行尾")]),v._v(" "),_("li",[_("code",[v._v("CTRL-G")]),v._v(" 用于显示当前光标所在位置和文件状态信息")]),v._v(" "),_("li",[v._v("输入大写 G 可以使得当前光标直接跳转到文件最后一行")]),v._v(" "),_("li",[v._v("输入 gg 可以使得当前光标直接跳转到文件第一行。")])]),v._v(" "),_("h3",{attrs:{id:"查找"}},[_("a",{staticClass:"header-anchor",attrs:{href:"#查找"}},[v._v("#")]),v._v(" 查找")]),v._v(" "),_("ul",[_("li",[_("code",[v._v("/{目标字符串}")]),v._v(" , 当前所编辑的文档中正向查找该字符串. 搜索下一个位置只需要按 n 键。要向相反方向查找同上一次的字符串,请输入大写 N 即可")]),v._v(" "),_("li",[_("code",[v._v("?{目标字符串}")]),v._v(" 当前所编辑的文档中反向查找该字符串")]),v._v(" "),_("li",[_("code",[v._v("/\\/>")]),v._v(" , < 表示字符串开始,/> 表示字符串结束,中间的就是需要搜索的字符串表达式")]),v._v(" "),_("li",[_("code",[v._v(":%s/\\/&/gn")]),v._v(" , 查询匹配的次数 https://vimhelp.org/vim_faq.txt.html#faq-11.1")]),v._v(" "),_("li",[_("code",[v._v(":%s/\\a\\+/&/gn")]),v._v(" , To count the number of alphabetic words in a file")]),v._v(" "),_("li",[_("code",[v._v(":%s/\\S\\+/&/gn")]),v._v(" , To count the number of words made up of non-space characters")]),v._v(" "),_("li",[_("code",[v._v("%")]),v._v(" , 输入 % 可以查找配对的括号 )、]、}")])]),v._v(" "),_("h3",{attrs:{id:"替换"}},[_("a",{staticClass:"header-anchor",attrs:{href:"#替换"}},[v._v("#")]),v._v(" 替换")]),v._v(" "),_("ul",[_("li",[_("code",[v._v(":s/\\$1/\\$2")]),v._v(" , 从光标处开始查找替换,仅仅替换第一次匹配 $1 的地方为 $2")]),v._v(" "),_("li",[_("code",[v._v(":%s/\\$1/\\$2")]),v._v(" , 替换掉文件中所有行第一次出现 $1 的地方为 $2\n"),_("ul",[_("li",[_("code",[v._v(":%s/^\\s*//g")]),v._v(": 删除每一行的行首的空字符串")])])]),v._v(" "),_("li",[_("code",[v._v(":%s/\\$1/\\$2/i")]),v._v(" , i 表示大小写不敏感查找,I 表示大小写敏感")]),v._v(" "),_("li",[_("code",[v._v(":%s/\\$1/\\$2/gi")]),v._v(" , 替换掉所有行出现 $1 (不区分大小写) 为 $2")]),v._v(" "),_("li",[_("code",[v._v(":%s/old/new/gc")]),v._v(" , 替换掉所有行出现 old (不区分大小写) 为 new, 需要确认")]),v._v(" "),_("li",[_("code",[v._v(":.,+2s/foo/bar/g")]),v._v(" , 当前行 . 与接下来两行 +2")]),v._v(" "),_("li",[_("code",[v._v(":#,#s/old/new/g")]),v._v(" , 其中 #,# 代表的是替换操作的若干行中首尾两行的行号")])]),v._v(" "),_("h3",{attrs:{id:"删除"}},[_("a",{staticClass:"header-anchor",attrs:{href:"#删除"}},[v._v("#")]),v._v(" 删除")]),v._v(" "),_("ul",[_("li",[_("code",[v._v("dw")]),v._v(" , 删除一个单词")]),v._v(" "),_("li",[_("code",[v._v("dnw")]),v._v(" , 删除 n 个单词")]),v._v(" "),_("li",[_("code",[v._v("dd")]),v._v(" , 删除一整行")]),v._v(" "),_("li",[_("code",[v._v("ndd")]),v._v(" , 删除光标处开始的 n 行")]),v._v(" "),_("li",[_("code",[v._v("d$")]),v._v(" , 删除光标到本行的结尾")]),v._v(" "),_("li",[_("code",[v._v(",d")]),v._v(" , 删除 n 到 m 的行")]),v._v(" "),_("li",[_("code",[v._v(":%d")]),v._v(": 删除文件的所有内容")])]),v._v(" "),_("h3",{attrs:{id:"复制粘贴"}},[_("a",{staticClass:"header-anchor",attrs:{href:"#复制粘贴"}},[v._v("#")]),v._v(" 复制粘贴")]),v._v(" "),_("p",[v._v("一、复制, "),_("code",[v._v("y")])]),v._v(" "),_("ul",[_("li",[v._v("yw")]),v._v(" "),_("li",[v._v("yy")]),v._v(" "),_("li",[v._v("y$")]),v._v(" "),_("li",[_("code",[v._v("31,100y")]),v._v(": 复制从 31-100 行的内容到剪切板")])]),v._v(" "),_("p",[v._v("二、粘贴, "),_("code",[v._v("p")])]),v._v(" "),_("ul",[_("li",[v._v("p , 在光标后开始黏贴")]),v._v(" "),_("li",[v._v("P , 在光标前开始粘贴")])]),v._v(" "),_("h4",{attrs:{id:"复制多行"}},[_("a",{staticClass:"header-anchor",attrs:{href:"#复制多行"}},[v._v("#")]),v._v(" 复制多行")]),v._v(" "),_("blockquote",[_("p",[v._v("复制 100 行,比如从第一行复制到 100 行")])]),v._v(" "),_("p",[v._v("一、 复制到 vim 寄存器")]),v._v(" "),_("p",[v._v("在 Vim 中复制多行文本,可以通过以下步骤实现:")]),v._v(" "),_("ul",[_("li",[_("p",[v._v("进入普通模式(Normal Mode):按下 Esc 键,确保你在普通模式下。")])]),v._v(" "),_("li",[_("p",[v._v("移动光标到第一行:可以使用 gg 命令将光标移动到文件的第一行。")])]),v._v(" "),_("li",[_("p",[v._v("开始选择文本:按下 V 键(注意是大写的 V),进入可视行模式(Visual Line Mode)。这会选中当前光标所在的整行。")])]),v._v(" "),_("li",[_("p",[v._v("移动光标并选择多行:按下 100G 或者 100gg 命令,将光标移动到第 100 行。这样,Vim 将会选中从第一行到第 100 行的所有内容。")])]),v._v(" "),_("li",[_("p",[v._v("复制选中的文本:按下 y 键,将选中的文本复制到 Vim 的寄存器中。")])]),v._v(" "),_("li",[_("p",[v._v("粘贴文本:移动光标到你想要粘贴的位置,然后按下 p 键,在光标后粘贴文本;或者按下 P 键,在光标前粘贴文本。")])])]),v._v(" "),_("p",[v._v("总结:按下 V 进入可视行模式,移动光标到第 100 行,按下 y 复制选中的文本,按下 p 或 P 粘贴文本。")]),v._v(" "),_("p",[v._v("二、复制到 剪切板")]),v._v(" "),_("blockquote",[_("p",[v._v("如果你想把复制的内容放到剪切板,可以这样做。 我的思路是直接保存到文件中")])]),v._v(" "),_("ul",[_("li",[v._v("打开其他文件:使用 "),_("code",[v._v(":e <文件名>")]),v._v(" 命令打开你想要粘贴内容的其他文件。")]),v._v(" "),_("li",[v._v("移动光标到你想要粘贴的位置。")]),v._v(" "),_("li",[v._v("粘贴文本:按下 "),_("code",[v._v("p")]),v._v(" 键,在光标后粘贴文本;或按下 "),_("code",[v._v("P")]),v._v(" 键,在光标前粘贴文本。")])]),v._v(" "),_("p",[v._v("总结:在普通模式下,使用 "),_("code",[v._v(":e <文件名>")]),v._v(" 打开其他文件,移动光标到粘贴位置,然后按下 "),_("code",[v._v("p")]),v._v(" 或 "),_("code",[v._v("P")]),v._v(" 键,在光标后或光标前粘贴之前复制的文本。如果需要退出并不保存当前文件,请按下 "),_("code",[v._v(":q!")]),v._v("。")]),v._v(" "),_("h3",{attrs:{id:"退出"}},[_("a",{staticClass:"header-anchor",attrs:{href:"#退出"}},[v._v("#")]),v._v(" 退出")]),v._v(" "),_("ul",[_("li",[_("code",[v._v(":w")])]),v._v(" "),_("li",[_("code",[v._v(":w!")])]),v._v(" "),_("li",[_("code",[v._v(":w \\$file")])]),v._v(" "),_("li",[_("code",[v._v(":q!")])]),v._v(" "),_("li",[_("code",[v._v(":qa!")]),v._v(" ,退出所有的文件,对所有的文件修改都不做保存")]),v._v(" "),_("li",[_("code",[v._v(":wq")])]),v._v(" "),_("li",[_("code",[v._v(":x")]),v._v(" , 退出文件并保存对文件的修改")]),v._v(" "),_("li",[_("code",[v._v(":saveas file")]),v._v(" , 另存为")])]),v._v(" "),_("h3",{attrs:{id:"其他"}},[_("a",{staticClass:"header-anchor",attrs:{href:"#其他"}},[v._v("#")]),v._v(" 其他")]),v._v(" "),_("ul",[_("li",[_("code",[v._v("u")]),v._v(" , 撤销")]),v._v(" "),_("li",[_("code",[v._v("ctrl + r")]),v._v(" , 恢复撤销操作")]),v._v(" "),_("li",[_("code",[v._v("ctrl + f")]),v._v(" , 查看下一页内容")]),v._v(" "),_("li",[_("code",[v._v("ctrl + b")]),v._v(" , 查看上一页内容")]),v._v(" "),_("li",[_("code",[v._v(":e \\$file")]),v._v(" , 打开另一个文件")]),v._v(" "),_("li",[_("code",[v._v(":e!")]),v._v(", 放弃对文件的所有修改,恢复文件到上次保存的位置")]),v._v(" "),_("li",[_("code",[v._v(":!")]),v._v(" 然后紧接着输入一个外部命令可以执行该外部命令")]),v._v(" "),_("li",[_("code",[v._v(":help quickfix")]),v._v(": quickfix 帮助文档")])]),v._v(" "),_("h2",{attrs:{id:"vimtutor"}},[_("a",{staticClass:"header-anchor",attrs:{href:"#vimtutor"}},[v._v("#")]),v._v(" vimtutor")]),v._v(" "),_("p",[_("code",[v._v("vimtutor")]),v._v(" 是一个内置于 Vim 编辑器中的交互式教程,旨在帮助用户学习和掌握 Vim 编辑器的基本用法和功能。通过运行 vimtutor 命令,您可以在终端中启动这个教程并按照提示进行学习。")]),v._v(" "),_("p",[v._v("以下是使用 "),_("code",[v._v("vimtutor")]),v._v(" 的一般步骤:")]),v._v(" "),_("ul",[_("li",[v._v("打开终端(命令行界面)。")]),v._v(" "),_("li",[v._v("输入 vimtutor 命令并按下回车键。")]),v._v(" "),_("li",[v._v("Vim 将以教程模式启动,并在终端中显示教程的内容。")])]),v._v(" "),_("p",[v._v("教程内容会逐步引导您学习 Vim 的各种基本操作和编辑技巧,包括移动光标、插入和删除文本、保存和退出文件等。您可以按照屏幕上的指示进行练习和操作。教程中的练习文件会被保存在您当前的工作目录中,命名为 tutor。")]),v._v(" "),_("p",[v._v("请注意,vimtutor 教程相当详细,需要耐心和时间来完成。建议您安排足够的时间来完成教程,并根据需要进行实践和反复练习,以便更好地掌握 Vim 编辑器的使用技巧。")]),v._v(" "),_("h2",{attrs:{id:"vimgrep"}},[_("a",{staticClass:"header-anchor",attrs:{href:"#vimgrep"}},[v._v("#")]),v._v(" vimgrep")]),v._v(" "),_("div",{staticClass:"custom-block tip"},[_("p",{staticClass:"custom-block-title"},[v._v("提示")]),v._v(" "),_("p",[_("code",[v._v("vimgrep")]),v._v(" 是 Vim 中用于执行 "),_("RText",{attrs:{text:"全局搜索的命令",color:"red"}}),v._v(",它可以在整个文件或多个文件中搜索指定的模式并将匹配的结果保存在 Vim 的 quickfix 列表中.")],1),v._v(" "),_("p",[v._v("使用 "),_("code",[v._v("vimgrep")]),v._v(" 命令可以在 Vim 中执行全局搜索并轻松导航匹配的结果。它非常适用于处理包含大量文件的项目。")])]),v._v(" "),_("h3",{attrs:{id:"用法"}},[_("a",{staticClass:"header-anchor",attrs:{href:"#用法"}},[v._v("#")]),v._v(" 用法")]),v._v(" "),_("ol",[_("li",[v._v("进入 Vim 编辑器,打开一个文件。")]),v._v(" "),_("li",[v._v("进入命令行模式,按下冒号(:)键。")]),v._v(" "),_("li",[v._v("输入以下命令格式:"),_("code",[v._v(":vimgrep /模式/ 文件列表")])])]),v._v(" "),_("ul",[_("li",[v._v("/模式/:指定要搜索的模式,可以是简单的文本或正则表达式。")]),v._v(" "),_("li",[v._v('文件列表:指定要在其中搜索的文件列表, 其中"%"表示当前文件。你可以使用通配符来匹配多个文件,例如 '),_("code",[v._v("**/*.txt")]),v._v(" 表示当前目录包括子目录所有以 "),_("code",[v._v(".txt")]),v._v(" 结尾的文件。")])]),v._v(" "),_("ol",{attrs:{start:"4"}},[_("li",[v._v("按下回车键,Vim 将执行搜索并将匹配的结果保存在 quickfix 列表中。")]),v._v(" "),_("li",[v._v("要打开 quickfix 窗口并查看搜索结果,可以使用命令 "),_("code",[v._v(":copen")]),v._v("。")]),v._v(" "),_("li",[v._v("在 quickfix 窗口中,你可以使用 "),_("code",[v._v(":cn")]),v._v(" 命令跳转到下一个匹配项,使用 "),_("code",[v._v(":cp")]),v._v(" 命令跳转到上一个匹配项,使用 "),_("code",[v._v(":cc")]),v._v(" 命令跳转到指定的匹配项,使用 "),_("code",[v._v(":cnext")]),v._v(" 和 "),_("code",[v._v(":cprev")]),v._v(" 命令进行导航。")]),v._v(" "),_("li",[v._v("使用 "),_("code",[v._v(":cfilter {pattern}")]),v._v(":使用 {pattern} 进行过滤,只显示匹配 {pattern} 的行。这将更新 quickfix 列表为符合过滤条件的结果。")]),v._v(" "),_("li",[v._v("若要关闭 quickfix 窗口,可以使用命令 "),_("code",[v._v(":cclose")]),v._v("。")])]),v._v(" "),_("h2",{attrs:{id:"vimgrepadd"}},[_("a",{staticClass:"header-anchor",attrs:{href:"#vimgrepadd"}},[v._v("#")]),v._v(" vimgrepadd")]),v._v(" "),_("p",[_("code",[v._v("vimgrep")]),v._v(" 和 "),_("code",[v._v("vimgrepadd")]),v._v(" 是 Vim 中用于进行全局搜索的命令,但它们之间存在一些区别。")]),v._v(" "),_("ul",[_("li",[_("code",[v._v("vimgrep")]),v._v(" 命令执行全局搜索,并将搜索结果替换 quickfix 列表中的内容。这意味着每次执行 vimgrep 命令时,quickfix 列表将被新的搜索结果所覆盖。")]),v._v(" "),_("li",[_("code",[v._v("vimgrepadd")]),v._v(" 命令也执行全局搜索,但它会将搜索结果追加到 quickfix 列表中,而不是替换原有的内容。这样,你可以在多次搜索之间保留和比较不同的搜索结果。")])]),v._v(" "),_("p",[v._v("使用 "),_("code",[v._v("vimgrepadd")]),v._v(" 的语法与 "),_("code",[v._v("vimgrep")]),v._v(" 相同,例如 "),_("code",[v._v(":vimgrepadd PddVideoEngine xxx.log")]),v._v("。执行该命令后,搜索结果将被添加到 quickfix 列表中。")]),v._v(" "),_("p",[v._v("你可以使用 "),_("code",[v._v(":copen")]),v._v(" 命令打开 quickfix 窗口查看所有的搜索结果,并使用 "),_("code",[v._v(":cn")]),v._v(" 和 "),_("code",[v._v(":cp")]),v._v(" 命令分别跳转到下一个和上一个匹配项。")]),v._v(" "),_("p",[v._v("总结而言,"),_("code",[v._v("vimgrep")]),v._v(" 用于替换 quickfix 列表内容,而 "),_("code",[v._v("vimgrepadd")]),v._v(" 用于追加到 quickfix 列表中,保留多个搜索结果。你可以根据需要选择适合的命令来处理搜索结果。")]),v._v(" "),_("h2",{attrs:{id:"插件"}},[_("a",{staticClass:"header-anchor",attrs:{href:"#插件"}},[v._v("#")]),v._v(" 插件")]),v._v(" "),_("blockquote",[_("p",[_("a",{attrs:{href:"http://blog.fpliu.com/it/software/Vim/plugin/vim-plug",target:"_blank",rel:"noopener noreferrer"}},[v._v("http://blog.fpliu.com/it/software/Vim/plugin/vim-plug"),_("OutboundLink")],1)])]),v._v(" "),_("h3",{attrs:{id:"插件管理器-vim-plug"}},[_("a",{staticClass:"header-anchor",attrs:{href:"#插件管理器-vim-plug"}},[v._v("#")]),v._v(" 插件管理器 vim-plug")]),v._v(" "),_("blockquote",[_("p",[_("a",{attrs:{href:"https://github.com/junegunn/vim-plug",target:"_blank",rel:"noopener noreferrer"}},[v._v("vim-plug: Vim plugin manager"),_("OutboundLink")],1)])]),v._v(" "),_("p",[v._v("一、安装 vim-plug")]),v._v(" "),_("div",{staticClass:"language-shell line-numbers-mode"},[_("pre",{pre:!0,attrs:{class:"language-shell"}},[_("code",[_("span",{pre:!0,attrs:{class:"token function"}},[v._v("curl")]),v._v(" "),_("span",{pre:!0,attrs:{class:"token parameter variable"}},[v._v("-fLo")]),v._v(" ~/.vim/autoload/plug.vim --create-dirs "),_("span",{pre:!0,attrs:{class:"token punctuation"}},[v._v("\\")]),v._v("\n https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim\n")])]),v._v(" "),_("div",{staticClass:"line-numbers-wrapper"},[_("span",{staticClass:"line-number"},[v._v("1")]),_("br"),_("span",{staticClass:"line-number"},[v._v("2")]),_("br")])]),_("p",[v._v("【解释】这个命令用于安装 Vim-Plug,这是一个流行的 Vim 插件管理器。以下是命令的解释和作用:")]),v._v(" "),_("ul",[_("li",[_("code",[v._v("curl")]),v._v(":这是一个用于在命令行中发出 HTTP 请求的命令行工具。它用于从 GitHub 上下载 Vim-Plug 插件管理器。")]),v._v(" "),_("li",[_("code",[v._v("-fLo")]),v._v(":这是 curl 命令的选项之一,它的作用是指定输出文件的路径。在这里,它将文件保存到 ~/.vim/autoload/plug.vim。")]),v._v(" "),_("li",[_("code",[v._v("~/.vim/autoload/plug.vim")]),v._v(":这是要保存下载文件的路径。在这里,它将下载的 plug.vim 文件保存到 Vim 的 autoload 目录中。autoload 目录通常用于存储 Vim 脚本和插件。")]),v._v(" "),_("li",[_("code",[v._v("--create-dirs")]),v._v(":这是 curl 命令的选项之一,它的作用是在保存文件之前创建目录。如果指定的目录不存在,它会自动创建 autoload 和 ~/.vim 这两个目录。")]),v._v(" "),_("li",[_("code",[v._v("https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim")]),v._v(":这是要下载的文件的 URL 地址。它指向 Vim-Plug 插件管理器的 GitHub 存储库中的 plug.vim 文件。")])]),v._v(" "),_("p",[v._v("执行这个命令后,curl 将从 GitHub 下载 "),_("code",[v._v("plug.vim")]),v._v(" 文件并将其保存到 "),_("code",[v._v("~/.vim/autoload/plug.vim")]),v._v("。这样,你就可以在 Vim 中使用 Vim-Plug 插件管理器来管理和安装其他插件了。要使用 Vim-Plug 安装插件,你可以将插件列表添加到你的 .vimrc 文件中,并在 Vim 中运行 "),_("code",[v._v(":PlugInstall")]),v._v(" 命令来安装它们。")]),v._v(" "),_("h3",{attrs:{id:"常用-plugin"}},[_("a",{staticClass:"header-anchor",attrs:{href:"#常用-plugin"}},[v._v("#")]),v._v(" 常用 plugin")]),v._v(" "),_("ul",[_("li",[_("a",{attrs:{href:"https://github.com/vim-scripts/QFEnter",target:"_blank",rel:"noopener noreferrer"}},[v._v("QFEnter"),_("OutboundLink")],1),v._v(":")])]),v._v(" "),_("h2",{attrs:{id:"其他-2"}},[_("a",{staticClass:"header-anchor",attrs:{href:"#其他-2"}},[v._v("#")]),v._v(" 其他")]),v._v(" "),_("h3",{attrs:{id:"正则表达式技巧"}},[_("a",{staticClass:"header-anchor",attrs:{href:"#正则表达式技巧"}},[v._v("#")]),v._v(" 正则表达式技巧")]),v._v(" "),_("ul",[_("li",[_("code",[v._v(":vimgrep 'aaaa\\|bbbb' %")]),v._v(": 搜索列出包含 aaaa, 或者 bbbb 的行,"),_("RText",{attrs:{text:"注意:",color:"red"}}),v._v(" 这里的 "),_("code",[v._v("|")]),v._v(" 需要转义")],1),v._v(" "),_("li",[_("code",[v._v("\\[17474.*\\(Report\\.PMMReport\\]\\|PlayTimeHelper\\]\\)")]),v._v(": 包含 xx 且包含 aa 或者 bb(包含 "),_("code",[v._v("[17474")]),v._v("且包含"),_("code",[v._v("Report.PMMReport]")]),v._v("或者"),_("code",[v._v("PlayTimeHelper]")]),v._v("的所有行)")]),v._v(" "),_("li",[_("code",[v._v(".*onReallyStart\\n.*onReallyStart")]),v._v(": 搜索连续两行出现 onReallyStart 的行")])]),v._v(" "),_("h3",{attrs:{id:"vim-查看另外的文件"}},[_("a",{staticClass:"header-anchor",attrs:{href:"#vim-查看另外的文件"}},[v._v("#")]),v._v(" vim 查看另外的文件")]),v._v(" "),_("blockquote",[_("p",[v._v("vim 在查看过程中,打开另外一个文件")])]),v._v(" "),_("p",[v._v("在 Vim 中,你可以在查看一个文件的同时打开另一个文件。这通常通过以下方法实现:")]),v._v(" "),_("p",[v._v("1.分割窗口:Vim 支持分割窗口的功能,你可以在一个窗口中查看一个文件,同时在另一个窗口中打开并查看另一个文件。以下是一些相关命令:")]),v._v(" "),_("ul",[_("li",[_("p",[v._v("打开新文件并水平分割窗口:"),_("code",[v._v(":sp filename")])])]),v._v(" "),_("li",[_("p",[v._v("打开新文件并垂直分割窗口:"),_("code",[v._v(":vsp filename")])])]),v._v(" "),_("li",[_("p",[v._v("切换窗口:"),_("code",[v._v("Ctrl-w Ctrl-w")])])]),v._v(" "),_("li",[_("p",[v._v("关闭窗口:"),_("code",[v._v(":q")])]),v._v(" "),_("p",[v._v("2.标签页:另一种方法是使用标签页来查看多个文件。你可以使用以下命令:")])]),v._v(" "),_("li",[_("p",[v._v("打开新文件并将其放入新标签页:"),_("code",[v._v(":tabe filename")])])]),v._v(" "),_("li",[_("p",[v._v("切换标签页:"),_("code",[v._v(":tabn (下一个标签页) 或 :tabp (上一个标签页)")])])]),v._v(" "),_("li",[_("p",[v._v("关闭标签页:"),_("code",[v._v(":tabc")])]),v._v(" "),_("p",[v._v("3.缓冲区:Vim 也支持多个缓冲区,你可以使用以下命令在不同的缓冲区之间切换:")])]),v._v(" "),_("li",[_("p",[v._v("打开新文件并加载到缓冲区:"),_("code",[v._v(":e filename")])])]),v._v(" "),_("li",[_("p",[v._v("切换缓冲区:"),_("code",[v._v(":bnext (下一个缓冲区) 或 :bprev (上一个缓冲区)")])])]),v._v(" "),_("li",[_("p",[v._v("关闭缓冲区:"),_("code",[v._v(":bd")])])])]),v._v(" "),_("p",[v._v("这些方法中的选择取决于你的使用习惯和需求。你可以根据需要在不同的文件之间切换以提高编辑效率。")]),v._v(" "),_("h3",{attrs:{id:"quickfix"}},[_("a",{staticClass:"header-anchor",attrs:{href:"#quickfix"}},[v._v("#")]),v._v(" quickFix")]),v._v(" "),_("blockquote",[_("p",[v._v(":PlugInstall")])]),v._v(" "),_("h4",{attrs:{id:"多个-quickfix-窗口"}},[_("a",{staticClass:"header-anchor",attrs:{href:"#多个-quickfix-窗口"}},[v._v("#")]),v._v(" 多个 quickFix 窗口")]),v._v(" "),_("p",[v._v("在 Vim 中,你可以打开多个 Quickfix 窗口,但需要借助一些插件或者自定义脚本来实现。Quickfix 窗口通常用于显示编译错误、代码搜索结果或其他类型的快速查找结果。以下是一种实现多个 Quickfix 窗口的方法:")]),v._v(" "),_("p",[_("strong",[v._v("使用插件:")]),v._v("\n有一些 Vim 插件可以帮助你管理多个 Quickfix 窗口。一个常用的插件是 "),_("a",{attrs:{href:"https://github.com/vim-scripts/QFEnter",target:"_blank",rel:"noopener noreferrer"}},[v._v("qfenter"),_("OutboundLink")],1),v._v(",它允许你在 Vim 中打开多个 Quickfix 窗口。你可以按照以下步骤安装它:")]),v._v(" "),_("ol",[_("li",[v._v("使用 Vim 插件管理器(如 Vim-Plug)安装 "),_("code",[v._v("qfenter")]),v._v(" 插件。将以下行添加到你的"),_("code",[v._v(".vimrc")]),v._v(" 文件中:")])]),v._v(" "),_("div",{staticClass:"language-shell line-numbers-mode"},[_("pre",{pre:!0,attrs:{class:"language-shell"}},[_("code",[v._v("Plug "),_("span",{pre:!0,attrs:{class:"token string"}},[v._v("'yssl/QFEnter.vim'")]),v._v("\n")])]),v._v(" "),_("div",{staticClass:"line-numbers-wrapper"},[_("span",{staticClass:"line-number"},[v._v("1")]),_("br")])]),_("ol",{attrs:{start:"2"}},[_("li",[_("p",[v._v("运行 Vim 并执行:PlugInstall 来安装插件。")])]),v._v(" "),_("li",[_("p",[v._v("使用:QFEnter 命令来打开新的 Quickfix 窗口。你可以在不同的 Quickfix 窗口中加载不同的 Quickfix 列表。")])])]),v._v(" "),_("ul",[_("li",[v._v("打开新的 Quickfix 窗口: "),_("code",[v._v(":QFEnter")])]),v._v(" "),_("li",[v._v("切换到不同的 Quickfix 窗口: "),_("code",[v._v(":QFEnter ")])])]),v._v(" "),_("p",[v._v("这样,你就可以在同一 Vim 会话中管理多个 Quickfix 窗口了。")]),v._v(" "),_("p",[v._v("请注意,Vim 的基本功能中并没有直接支持打开多个 Quickfix 窗口,所以需要使用插件来扩展这个功能。")]),v._v(" "),_("h3",{attrs:{id:"visual-模式复制问题"}},[_("a",{staticClass:"header-anchor",attrs:{href:"#visual-模式复制问题"}},[v._v("#")]),v._v(" visual 模式复制问题")]),v._v(" "),_("blockquote",[_("p",[v._v("在使用 vim 的时候,如果显示行号,在 visual 模式下,复制可能会有空格")])]),v._v(" "),_("p",[v._v("在 Vim 中,在显示行号的情况下,复制文本可能会包括行号后面的空格。这是因为行号是显示在文本前面的,所以在 Visual 模式下选择文本时也会选择行号后的空格。")]),v._v(" "),_("p",[v._v("如果你希望在复制文本时不包括行号后的空格,可以考虑在 Visual 模式下使用一些技巧来排除行号。以下是一些方法:")]),v._v(" "),_("ol",[_("li",[_("p",[v._v("使用 set nu!命令切换行号显示:你可以使用命令:set nu!来切换行号的显示。这个命令会在显示和隐藏行号之间切换。在不显示行号的情况下,复制操作不会包括行号后的空格。当你需要查看行号时,再次执行:set nu!即可。")])]),v._v(" "),_("li",[_("p",[v._v("使用正则表达式来选择文本:在 Visual 模式下,你可以使用正则表达式来选择文本,以便排除行号。例如,假设你的行号是左对齐的,你可以使用正则表达式来选择非空格字符:")])])]),v._v(" "),_("ul",[_("li",[v._v("进入 Visual 模式:按 V 键。")]),v._v(" "),_("li",[v._v("使用正则表达式选择文本:/\\S.*,然后按 Enter。这将选择当前行中第一个非空格字符之后的文本。")])]),v._v(" "),_("ol",{attrs:{start:"3"}},[_("li",[v._v('使用 Vim 插件:有一些 Vim 插件可以帮助你更精确地选择文本,以排除行号。例如,"vim-textobj-line" 插件允许你选择文本行,而不包括行号。你可以使用插件管理器来安装这些插件。')])]),v._v(" "),_("p",[v._v("根据你的偏好和需求,选择适合你的方法来避免在 Visual 模式下复制行号后的空格。")]),v._v(" "),_("h2",{attrs:{id:"参考"}},[_("a",{staticClass:"header-anchor",attrs:{href:"#参考"}},[v._v("#")]),v._v(" 参考")]),v._v(" "),_("ul",[_("li",[_("a",{attrs:{href:"https://harttle.land/2016/08/08/vim-search-in-file.html",target:"_blank",rel:"noopener noreferrer"}},[v._v("vim-search-in-file"),_("OutboundLink")],1)]),v._v(" "),_("li",[_("a",{attrs:{href:"https://zhuanlan.zhihu.com/p/68111471",target:"_blank",rel:"noopener noreferrer"}},[v._v("知乎-精通 vim"),_("OutboundLink")],1)]),v._v(" "),_("li",[_("a",{attrs:{href:"https://vimhelp.org/pattern.txt.html",target:"_blank",rel:"noopener noreferrer"}},[v._v("vimhelp-pattern"),_("OutboundLink")],1)]),v._v(" "),_("li",[_("a",{attrs:{href:"https://vimhelp.org/vim_faq.txt.html",target:"_blank",rel:"noopener noreferrer"}},[v._v("vimhelp-faq"),_("OutboundLink")],1)]),v._v(" "),_("li",[_("a",{attrs:{href:"https://cloud.tencent.com/developer/article/1004716",target:"_blank",rel:"noopener noreferrer"}},[v._v("分享一些 vim 插件-Tencent"),_("OutboundLink")],1)]),v._v(" "),_("li",[_("a",{attrs:{href:"http://blog.fpliu.com/it/software/Vim/plugin/vim-plug",target:"_blank",rel:"noopener noreferrer"}},[v._v("vim-plug"),_("OutboundLink")],1)]),v._v(" "),_("li",[_("a",{attrs:{href:"https://freshman.tech/vim-quickfix-and-location-list/",target:"_blank",rel:"noopener noreferrer"}},[v._v("vim-quickfix-and-location-list"),_("OutboundLink")],1)])])])}),[],!1,null,null,null);_.default=t.exports}}]); \ No newline at end of file diff --git a/assets/js/61.26bdabb3.js b/assets/js/61.26bdabb3.js new file mode 100644 index 0000000000..13e67878a6 --- /dev/null +++ b/assets/js/61.26bdabb3.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[61],{387:function(e,r,o){"use strict";o.r(r);var _=o(4),v=Object(_.a)({},(function(){var e=this,r=e._self._c;return r("ContentSlotsDistributor",{attrs:{"slot-key":e.$parent.slotKey}},[r("h2",{attrs:{id:"环境"}},[r("a",{staticClass:"header-anchor",attrs:{href:"#环境"}},[e._v("#")]),e._v(" 环境")]),e._v(" "),r("blockquote",[r("p",[e._v("安装 docker 请直接点击查看: "),r("a",{attrs:{href:"https://docs.docker.com/desktop/install/mac-install/",target:"_blank",rel:"noopener noreferrer"}},[e._v("在 mac 上的安装"),r("OutboundLink")],1)])]),e._v(" "),r("h2",{attrs:{id:"常用命令"}},[r("a",{staticClass:"header-anchor",attrs:{href:"#常用命令"}},[e._v("#")]),e._v(" 常用命令")]),e._v(" "),r("div",{staticClass:"custom-block tip"},[r("p",{staticClass:"custom-block-title"},[e._v("提示")]),e._v(" "),r("p",[e._v("此模块列举了常见的一些命令,更多的用法可见:"),r("a",{attrs:{href:"https://docs.docker.com/engine/reference/commandline/cli/",target:"_blank",rel:"noopener noreferrer"}},[e._v("链接"),r("OutboundLink")],1)])]),e._v(" "),r("ul",[r("li",[r("p",[r("code",[e._v("docker run")]),e._v(": 运行一个容器(这个命令也创建了一个容器)。")]),e._v(" "),r("ul",[r("li",[r("code",[e._v("-d")]),e._v(": 表示以后台(守护进程)模式运行容器。容器将在后台运行,而不会占用你的终端")]),e._v(" "),r("li",[r("code",[e._v("-p")]),e._v(": 指定端口映射。")]),e._v(" "),r("li",[r("code",[e._v("--name")]),e._v(": 指定容器名称")]),e._v(" "),r("li",[r("code",[e._v("--user root")]),e._v(": 以 root 模式运行容器")]),e._v(" "),r("li",[r("code",[e._v("--user 1000:1000")]),e._v(": 其中 1000:1000 是一个具有普通权限的用户和用户组的标识。")])])]),e._v(" "),r("li",[r("p",[r("code",[e._v("docker build")]),e._v(": 构建一个镜像")]),e._v(" "),r("ul",[r("li",[r("code",[e._v("-t")]),e._v(": 指定镜像的名称和标签")]),e._v(" "),r("li",[r("code",[e._v("-f")]),e._v(": 指定 Dockerfile 的路径")])])]),e._v(" "),r("li",[r("p",[r("code",[e._v("docker pull ")]),e._v(": 下载一个镜像.")]),e._v(" "),r("ul",[r("li",[r("code",[e._v("docker pull elasticsearch:")]),e._v(" 下载 elasticsearch 镜像")]),e._v(" "),r("li",[r("code",[e._v("docker image pull elasticsearch")])])])]),e._v(" "),r("li",[r("p",[r("code",[e._v("docker push")]),e._v(": 将本地镜像推送到镜像仓库")])]),e._v(" "),r("li",[r("p",[r("code",[e._v("docker stop ")]),e._v(": 停止一个正在运行的容器")])]),e._v(" "),r("li",[r("p",[r("code",[e._v("docker start ")]),e._v(": 运行一个容器")])]),e._v(" "),r("li",[r("p",[r("code",[e._v("docker restart ")]),e._v(": 重启一个容器")])]),e._v(" "),r("li",[r("p",[r("code",[e._v("docker rm")]),e._v(": 删除一个容器")]),e._v(" "),r("ul",[r("li",[r("code",[e._v("-f")]),e._v(": 强制删除正在运行的容器")])])]),e._v(" "),r("li",[r("p",[r("code",[e._v("docker rmi")]),e._v(": 删除一个镜像")]),e._v(" "),r("ul",[r("li",[r("code",[e._v("-f")]),e._v(": 强制删除正在使用的镜像")])])]),e._v(" "),r("li",[r("p",[r("code",[e._v("docker ps")]),e._v(": 查看正在运行的容器")]),e._v(" "),r("ul",[r("li",[r("code",[e._v("-a")]),e._v(": 查看所有容器,包括已停止的")])])]),e._v(" "),r("li",[r("p",[r("code",[e._v("docker images")]),e._v(": 查看本地镜像列表")])]),e._v(" "),r("li",[r("p",[r("code",[e._v("docker exec")]),e._v(": 在正在运行的容器中执行命令")]),e._v(" "),r("ul",[r("li",[r("code",[e._v("docker exec -u root -it /bin/bash")]),e._v(": 以 root 进入 Docker 容器的 shell")]),e._v(" "),r("li",[r("code",[e._v("-u root")]),e._v(": 你可能需要以此身份运行 docker container,否则有些命令无权限")])])]),e._v(" "),r("li",[r("p",[r("code",[e._v("docker logs ")]),e._v(": 查看容器的日志输出")])]),e._v(" "),r("li",[r("p",[r("code",[e._v("docker inspect")]),e._v(": 检查容器或镜像的详细信息")])]),e._v(" "),r("li",[r("p",[r("code",[e._v("docker export")]),e._v(": Export a container’s filesystem as a tar archive")])]),e._v(" "),r("li",[r("p",[r("code",[e._v("docker image prune")]),e._v(" 清理无用镜像,释放磁盘空间")])]),e._v(" "),r("li",[r("p",[r("code",[e._v("docker container")]),e._v(": container help")]),e._v(" "),r("ul",[r("li",[r("code",[e._v("docker container prune")]),e._v(": 清理无用的容器,释放磁盘空间")]),e._v(" "),r("li",[r("code",[e._v("docker container ls -a")])])])]),e._v(" "),r("li",[r("p",[r("code",[e._v("docker cp")])]),e._v(" "),r("ul",[r("li",[r("code",[e._v("docker cp :")]),e._v(": 将主机的文件拷贝到 docker 容器中")])])])]),e._v(" "),r("h2",{attrs:{id:"技巧"}},[r("a",{staticClass:"header-anchor",attrs:{href:"#技巧"}},[e._v("#")]),e._v(" 技巧")]),e._v(" "),r("blockquote",[r("p",[e._v("为 Docker for Mac 配置 HTTP 代理: "),r("a",{attrs:{href:"https://zhuanlan.zhihu.com/p/26033249",target:"_blank",rel:"noopener noreferrer"}},[e._v("https://zhuanlan.zhihu.com/p/26033249"),r("OutboundLink")],1)])]),e._v(" "),r("ul",[r("li",[e._v("使用 Dockerfile:编写一个 Dockerfile,定义容器的构建过程,并使用 "),r("code",[e._v("docker build")]),e._v(" 命令构建镜像。")]),e._v(" "),r("li",[e._v("镜像标签管理:给镜像打上标签,可以方便地区分不同版本或不同环境的镜像。")]),e._v(" "),r("li",[e._v("数据卷挂载:使用数据卷挂载容器内的目录到主机上,实现数据持久化,并方便对数据进行备份和恢复。")]),e._v(" "),r("li",[e._v("使用 Docker Compose:使用 Docker Compose 工具,可以通过一个 YAML 文件定义和管理多个相关容器的配置,方便地进行多容器应用的部署和管理。")]),e._v(" "),r("li",[e._v("多阶段构建:在 Dockerfile 中使用多个构建阶段,可以减小最终镜像的体积,提高构建速度。")]),e._v(" "),r("li",[e._v("使用官方镜像:尽可能使用官方提供的镜像,它们经过了广泛测试和验证,可信度较高。")]),e._v(" "),r("li",[e._v("容器互联:通过设置网络连接,可以实现容器之间的通信和数据共享。")]),e._v(" "),r("li",[e._v("Docker Registry:搭建私有的 Docker Registry,可以方便地存储和分享自己的镜像。")]),e._v(" "),r("li",[e._v("监控和日志:使用监控工具和日志管理工具,对 Docker 容器和集群进行监控和日志收集,方便故障排查和性能优化。")]),e._v(" "),r("li",[e._v("自动化构建和部署:结合持续集成和持续部署工具")])]),e._v(" "),r("h2",{attrs:{id:"原理"}},[r("a",{staticClass:"header-anchor",attrs:{href:"#原理"}},[e._v("#")]),e._v(" 原理")]),e._v(" "),r("p",[e._v("以下是 Docker 的工作原理的关键要点:")]),e._v(" "),r("ul",[r("li",[r("p",[r("strong",[e._v("容器化技术")]),e._v(": Docker 使用容器化技术来封装应用程序和其依赖项,以便它们可以在不同的环境中运行一致,而无需考虑底层操作系统的差异。这是通过使用 Linux 容器技术(如 cgroups 和 namespace)来实现的。")])]),e._v(" "),r("li",[r("p",[r("strong",[e._v("镜像")]),e._v(": Docker 镜像是容器的构建模块。镜像是一个只读文件,包含了应用程序代码、运行时环境、依赖项等。镜像是不可更改的,这意味着一旦创建,它们就不会被更改。镜像是容器的基础,可以用来启动多个容器实例。")])]),e._v(" "),r("li",[r("p",[r("strong",[e._v("容器")]),e._v(": 容器是从镜像创建的运行时实体。容器包括一个独立的文件系统、运行时环境和应用程序代码。容器是可移植的,可以在不同的主机上运行,只要这些主机支持 Docker。")])]),e._v(" "),r("li",[r("p",[r("strong",[e._v("Docker Daemon")]),e._v(": Docker 守护进程(Docker Daemon)是一个在后台运行的服务,负责管理 Docker 容器的生命周期、镜像的构建和存储、网络设置等。Docker 守护进程监听 Docker CLI 的命令,并执行相应的操作。")])]),e._v(" "),r("li",[r("p",[r("strong",[e._v("Docker CLI")]),e._v(": Docker 命令行界面(Docker CLI)是与 Docker 守护进程通信的主要方式。用户可以使用 Docker CLI 来创建、管理和监视容器、镜像以及其他 Docker 资源。")])]),e._v(" "),r("li",[r("p",[r("strong",[e._v("Docker Compose")]),e._v(": Docker Compose 是一个用于定义和运行多个 Docker 容器的工具。它允许你使用一个 YAML 文件来描述应用程序的各个组件和它们之间的关系,然后可以一键启动整个应用程序栈。")])]),e._v(" "),r("li",[r("p",[r("strong",[e._v("Docker Registry")]),e._v(": Docker Registry 是用于存储和分享 Docker 镜像的中央存储库。Docker Hub 是 Docker 的官方 Registry,用户可以在其中找到许多常见的公共镜像。企业也可以搭建自己的私有 Docker Registry 来管理和分享镜像。")])])]),e._v(" "),r("p",[e._v("Docker 的工作原理可以简单总结为:通过将应用程序及其依赖项打包到容器中,使其可移植性极高,然后使用 Docker 守护进程管理容器的生命周期和资源。这种容器化方法大大简化了应用程序的部署和管理,提高了开发、测试和生产环境之间的一致性。")]),e._v(" "),r("h2",{attrs:{id:"其他"}},[r("a",{staticClass:"header-anchor",attrs:{href:"#其他"}},[e._v("#")]),e._v(" 其他")]),e._v(" "),r("h3",{attrs:{id:"容器中-mysql-链接主机"}},[r("a",{staticClass:"header-anchor",attrs:{href:"#容器中-mysql-链接主机"}},[e._v("#")]),e._v(" 容器中 mysql 链接主机")]),e._v(" "),r("p",[e._v("TODO")]),e._v(" "),r("h2",{attrs:{id:"链接"}},[r("a",{staticClass:"header-anchor",attrs:{href:"#链接"}},[e._v("#")]),e._v(" 链接")]),e._v(" "),r("ul",[r("li",[r("a",{attrs:{href:"https://docs.docker.com/",target:"_blank",rel:"noopener noreferrer"}},[e._v("docker 官方文档"),r("OutboundLink")],1)]),e._v(" "),r("li",[r("a",{attrs:{href:"https://docs.docker.com/engine/reference/builder/",target:"_blank",rel:"noopener noreferrer"}},[e._v("Dockerfile 命令,参考文档"),r("OutboundLink")],1)]),e._v(" "),r("li",[r("a",{attrs:{href:"https://jozala.com/posts/2019-11-21-docker-image-with-gradle/",target:"_blank",rel:"noopener noreferrer"}},[e._v("Building Docker image with Gradle"),r("OutboundLink")],1)]),e._v(" "),r("li",[r("a",{attrs:{href:"https://hub.docker.com/",target:"_blank",rel:"noopener noreferrer"}},[e._v("Docker Hub"),r("OutboundLink")],1),e._v(" :Docker Hub is the world's largest\nlibrary and community for container images")]),e._v(" "),r("li",[r("a",{attrs:{href:"https://labs.play-with-docker.com/",target:"_blank",rel:"noopener noreferrer"}},[e._v("play-with-docker"),r("OutboundLink")],1),e._v(" 在线 play docker")])])])}),[],!1,null,null,null);r.default=v.exports}}]); \ No newline at end of file diff --git a/assets/js/62.c48ad769.js b/assets/js/62.c48ad769.js new file mode 100644 index 0000000000..63ae10f997 --- /dev/null +++ b/assets/js/62.c48ad769.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[62],{388:function(n,u,t){"use strict";t.r(u);var o=t(4),i=Object(o.a)({},(function(){var n=this,u=n._self._c;return u("ContentSlotsDistributor",{attrs:{"slot-key":n.$parent.slotKey}},[u("h2",{attrs:{id:"ubuntu-on-windows"}},[u("a",{staticClass:"header-anchor",attrs:{href:"#ubuntu-on-windows"}},[n._v("#")]),n._v(" Ubuntu on Windows")]),n._v(" "),u("p",[n._v("Ubuntu on Windows 是一种特殊的操作系统环境,允许用户在基于 Windows 操作系统的计算机上运行 Ubuntu。它是通过一个名为 Windows Subsystem for Linux (WSL) 的功能实现的。WSL 是由 Microsoft 开发的一项技术,旨在为 Windows 用户提供原生的 Linux 兼容性。")]),n._v(" "),u("p",[n._v("通过 WSL,用户可以在 Windows 上运行 Ubuntu 的命令行工具和应用程序,而无需在计算机上安装另一个完整的操作系统。WSL 实际上是在 Windows 内核上运行一个轻量级的虚拟机,其中包含了 Ubuntu 的用户模式组件。这种方式使得 Ubuntu 在 Windows 上运行时能够直接访问系统资源,并且具有良好的性能。")]),n._v(" "),u("p",[n._v("安装 Ubuntu on Windows 非常简单。首先,确保你的 Windows 版本支持 WSL。从 Windows 10 版本 1607 开始,WSL 就成为了 Windows 的一部分。然后,你可以通过 Microsoft Store 下载和安装所需的 Ubuntu 版本。目前,常用的 Ubuntu 版本有 Ubuntu 20.04 LTS 和 Ubuntu 18.04 LTS。")]),n._v(" "),u("p",[n._v("安装完成后,你可以通过启动菜单中的 Ubuntu 应用程序来打开 Ubuntu on Windows。这将打开一个命令行界面,你可以在其中执行各种 Linux 命令和使用 Ubuntu 的软件包管理工具,如apt。")]),n._v(" "),u("p",[n._v("使用 Ubuntu on Windows,你可以运行大部分的 Ubuntu 命令行工具和应用程序,并且能够访问文件系统、运行脚本、开发和调试代码等。这为开发人员和系统管理员提供了一个便捷的方式,在 Windows 环境中同时享受到 Windows 和 Linux 的优势。")]),n._v(" "),u("p",[n._v("总结来说,Ubuntu on Windows(通过 Windows Subsystem for Linux)提供了一个在 Windows 操作系统上运行 Ubuntu 的解决方案,使用户能够同时享受到 Windows 和 Linux 的功能和便利。这为开发者和技术爱好者提供了更多的灵活性和选择,以满足他们的工作和学习需求。")]),n._v(" "),u("h2",{attrs:{id:"设置环境"}},[u("a",{staticClass:"header-anchor",attrs:{href:"#设置环境"}},[n._v("#")]),n._v(" 设置环境")]),n._v(" "),u("h3",{attrs:{id:"vscode-terminal"}},[u("a",{staticClass:"header-anchor",attrs:{href:"#vscode-terminal"}},[n._v("#")]),n._v(" vscode terminal")]),n._v(" "),u("blockquote",[u("p",[n._v("【背景】在 windows 下,打开 vscode,默认的 terminal 环境是 windows bash。 不能使用 zsh 带来的各种方便的操作")])]),n._v(" "),u("p",[n._v("要在 Windows 下的 Visual Studio Code 中将默认终端设置为 Ubuntu 命令行,你可以按照以下步骤进行操作:")]),n._v(" "),u("ol",[u("li",[n._v("打开 Visual Studio Code。")]),n._v(" "),u("li",[n._v("点击左侧的「查看」(View) 选项卡。")]),n._v(" "),u("li",[n._v("选择「终端」(Terminal)。")]),n._v(" "),u("li",[n._v("在终端菜单中,点击「新终端」(New Terminal)。")]),n._v(" "),u("li",[n._v("在打开的终端窗口中,点击终端窗口右上角的下拉菜单图标(默认为 PowerShell)。")]),n._v(" "),u("li",[n._v("在下拉菜单中,选择「选择默认终端」(Select Default Profile)。")]),n._v(" "),u("li",[n._v("在弹出的列表中,选择「WSL: Ubuntu」。如果你之前已经安装了多个 WSL 发行版,你可能会看到其他的选项,选择你想要的 Ubuntu 发行版。")])]),n._v(" "),u("p",[n._v("现在,你的默认终端将设置为 Ubuntu 命令行。")]),n._v(" "),u("p",[n._v("下次打开终端时,Visual Studio Code 将自动打开 Ubuntu 命令行终端。你可以在该终端中运行 Ubuntu 的命令和工具。注意,你可以随时从终端下拉菜单中切换终端类型,以便使用其他终端,如 PowerShell 或 CMD。")])])}),[],!1,null,null,null);u.default=i.exports}}]); \ No newline at end of file diff --git a/assets/js/63.07a9a7ed.js b/assets/js/63.07a9a7ed.js new file mode 100644 index 0000000000..e394b67b47 --- /dev/null +++ b/assets/js/63.07a9a7ed.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[63],{389:function(t,v,_){"use strict";_.r(v);var a=_(4),s=Object(a.a)({},(function(){var t=this,v=t._self._c;return v("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[v("blockquote",[v("p",[t._v("各种 "),v("code",[t._v("IDE")]),t._v(" 小技巧记录")])]),t._v(" "),v("h2",{attrs:{id:"android-studio"}},[v("a",{staticClass:"header-anchor",attrs:{href:"#android-studio"}},[t._v("#")]),t._v(" Android studio")]),t._v(" "),v("p",[t._v("TODO")]),t._v(" "),v("h2",{attrs:{id:"vscode"}},[v("a",{staticClass:"header-anchor",attrs:{href:"#vscode"}},[t._v("#")]),t._v(" vscode")]),t._v(" "),v("h3",{attrs:{id:"插件"}},[v("a",{staticClass:"header-anchor",attrs:{href:"#插件"}},[t._v("#")]),t._v(" 插件")]),t._v(" "),v("ul",[v("li",[v("code",[t._v("GitLens — Git supercharged")]),t._v(" 可视化 git blame 工具、浏览 git 仓库")])]),t._v(" "),v("h3",{attrs:{id:"替换技巧"}},[v("a",{staticClass:"header-anchor",attrs:{href:"#替换技巧"}},[t._v("#")]),t._v(" 替换技巧")]),t._v(" "),v("p",[t._v("【问】vscode中找到所有字母开头,且截止到: 的行,并将内容替换成如下格式:\n如:"),v("code",[t._v("abc: hhhh")]),t._v("\n替换后的格式为 "),v("code",[t._v("- **abc**: hhhh")])]),t._v(" "),v("ol",[v("li",[v("p",[t._v("打开要搜索的文件。")])]),t._v(" "),v("li",[v("p",[t._v("使用快捷键 Ctrl + H(或者在菜单中选择“编辑” > “查找” > “替换”)来打开替换面板。")])]),t._v(" "),v("li",[v("p",[t._v("确保在替换面板上启用正则表达式搜索功能,可以点击替换面板上的 "),v("code",[t._v(".*")]),t._v(" 按钮来切换到正则表达式模式。")])]),t._v(" "),v("li",[v("p",[t._v("在查找框中输入正则表达式 "),v("code",[t._v("^([^\\s]+.*):")]),t._v(",这将匹配以非空字符串开头并以冒号结束的行。")])]),t._v(" "),v("li",[v("p",[t._v("在替换框中输入替换的格式:- "),v("strong",[t._v("$1")]),t._v(": ,其中 "),v("code",[t._v("$1")]),t._v(" 表示匹配到的内容,并在冒号后加入空格。")])]),t._v(" "),v("li",[v("p",[t._v("点击替换按钮(或者按下 Alt + Enter),Visual Studio Code会查找并替换匹配的文本。")])])]),t._v(" "),v("p",[t._v("如果您希望一次性替换所有匹配,可以点击“全部替换”按钮。")]),t._v(" "),v("h2",{attrs:{id:"python"}},[v("a",{staticClass:"header-anchor",attrs:{href:"#python"}},[t._v("#")]),t._v(" python")]),t._v(" "),v("p",[t._v("TODO")])])}),[],!1,null,null,null);v.default=s.exports}}]); \ No newline at end of file diff --git a/assets/js/64.e0ad93a0.js b/assets/js/64.e0ad93a0.js new file mode 100644 index 0000000000..c6cb2124b0 --- /dev/null +++ b/assets/js/64.e0ad93a0.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[64],{390:function(s,t,a){"use strict";a.r(t);var e=a(4),r=Object(e.a)({},(function(){var s=this,t=s._self._c;return t("ContentSlotsDistributor",{attrs:{"slot-key":s.$parent.slotKey}},[t("blockquote",[t("p",[s._v("Zsh 是一款功能强大且高度可定制的 Shell,通过提供更多的便利功能和扩展,使命令行操作更加高效和愉快。它是许多开发人员和系统管理员喜爱的命令行工具之一")])]),s._v(" "),t("h2",{attrs:{id:"常用"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#常用"}},[s._v("#")]),s._v(" 常用")]),s._v(" "),t("ul",[t("li",[t("code",[s._v("upgrade_oh_my_zsh")]),s._v(" Run the command to update Oh My Zsh")])]),s._v(" "),t("h2",{attrs:{id:"配置"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#配置"}},[s._v("#")]),s._v(" 配置")]),s._v(" "),t("ol",[t("li",[t("code",[s._v("~/.oh-my-zsh/custom/plugins")]),s._v(" 这个目录是用来存放自定义的插件的。当你需要创建自己的 Zsh 插件时,可以将插件文件放在这个目录下。这样,你可以根据自己的需要定制和扩展 Zsh 的功能。")]),s._v(" "),t("li",[t("code",[s._v("~/.oh-my-zsh/plugins")]),s._v(" 这个目录是 Oh My Zsh 框架自带的插件存放的地方。当你安装 Oh My Zsh 时,默认情况下会包含一些常用的插件,例如 git、npm、syntax-highlighting 等。这些插件可以提供丰富的功能和命令补全,以增强你的命令行体验。这些插件由 Oh My Zsh 负责管理和更新,你可以通过编辑 ~/.zshrc 文件中的 plugins 行来启用或禁用这些插件。")]),s._v(" "),t("li",[t("code",[s._v("~/.zshrc")]),s._v(" zsh 的配置文件")])]),s._v(" "),t("h2",{attrs:{id:"常用插件"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#常用插件"}},[s._v("#")]),s._v(" 常用插件")]),s._v(" "),t("ul",[t("li",[t("code",[s._v("git")]),s._v(" 这个是装好 oh-my-zsh 就默认已经开启的")]),s._v(" "),t("li",[t("code",[s._v("sublime")]),s._v(" 一个自带的插件,同样需要自己开启,针对喜欢用 sublime 的小伙伴")]),s._v(" "),t("li",[t("code",[s._v("vscode")])])]),s._v(" "),t("h2",{attrs:{id:"zsh-autosuggestions"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#zsh-autosuggestions"}},[s._v("#")]),s._v(" "),t("code",[s._v("zsh-autosuggestions")])]),s._v(" "),t("blockquote",[t("p",[s._v("非常好用的一个插件,会记录你之前输入过的所有命令,并且自动匹配你可能想要输入命令,然后按 → 补全. 官网地址为: "),t("a",{attrs:{href:"https://github.com/zsh-users/zsh-autosuggestions",target:"_blank",rel:"noopener noreferrer"}},[s._v("https://github.com/zsh-users/zsh-autosuggestions"),t("OutboundLink")],1)])]),s._v(" "),t("div",{staticClass:"language-shell line-numbers-mode"},[t("pre",{pre:!0,attrs:{class:"language-shell"}},[t("code",[t("span",{pre:!0,attrs:{class:"token function"}},[s._v("git")]),s._v(" clone https://github.com/zsh-users/zsh-autosuggestions "),t("span",{pre:!0,attrs:{class:"token variable"}},[s._v("${ZSH_CUSTOM"),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v(":-")]),s._v("~"),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("/")]),s._v(".oh-my-zsh"),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("/")]),s._v("custom}")]),s._v("/plugins/zsh-autosuggestions\n")])]),s._v(" "),t("div",{staticClass:"line-numbers-wrapper"},[t("span",{staticClass:"line-number"},[s._v("1")]),t("br")])]),t("h2",{attrs:{id:"zsh-syntax-highlighting"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#zsh-syntax-highlighting"}},[s._v("#")]),s._v(" "),t("code",[s._v("zsh-syntax-highlighting")])]),s._v(" "),t("blockquote",[t("p",[s._v("命令太多,有时候记不住,等输入完了才知道命令输错了,这个插件直接在输入过程中就会提示你,当前命令是否正确,错误红色,正确绿色. 官网地址为: "),t("a",{attrs:{href:"https://github.com/zsh-users/zsh-syntax-highlighting",target:"_blank",rel:"noopener noreferrer"}},[s._v("https://github.com/zsh-users/zsh-syntax-highlighting"),t("OutboundLink")],1)])]),s._v(" "),t("div",{staticClass:"language-shell line-numbers-mode"},[t("pre",{pre:!0,attrs:{class:"language-shell"}},[t("code",[t("span",{pre:!0,attrs:{class:"token function"}},[s._v("git")]),s._v(" clone https://github.com/zsh-users/zsh-syntax-highlighting.git "),t("span",{pre:!0,attrs:{class:"token variable"}},[s._v("${ZSH_CUSTOM"),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v(":-")]),s._v("~"),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("/")]),s._v(".oh-my-zsh"),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("/")]),s._v("custom}")]),s._v("/plugins/zsh-syntax-highlighting\n")])]),s._v(" "),t("div",{staticClass:"line-numbers-wrapper"},[t("span",{staticClass:"line-number"},[s._v("1")]),t("br")])])])}),[],!1,null,null,null);t.default=r.exports}}]); \ No newline at end of file diff --git a/assets/js/65.bb2c89ab.js b/assets/js/65.bb2c89ab.js new file mode 100644 index 0000000000..9c9275b516 --- /dev/null +++ b/assets/js/65.bb2c89ab.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[65],{391:function(s,t,a){"use strict";a.r(t);var e=a(4),r=Object(e.a)({},(function(){var s=this,t=s._self._c;return t("ContentSlotsDistributor",{attrs:{"slot-key":s.$parent.slotKey}},[t("h2",{attrs:{id:"workflows"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#workflows"}},[s._v("#")]),s._v(" workflows")]),s._v(" "),t("h3",{attrs:{id:"trigger-workflow"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#trigger-workflow"}},[s._v("#")]),s._v(" trigger workflow")]),s._v(" "),t("blockquote",[t("p",[s._v("官网是最全面的,建议直接查看 "),t("code",[s._v("https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows")])])]),s._v(" "),t("h4",{attrs:{id:"schedule"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#schedule"}},[s._v("#")]),s._v(" schedule")]),s._v(" "),t("blockquote",[t("p",[s._v("通过 schedule 出发 workflow,更多内容可见"),t("a",{attrs:{href:"https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#schedule",target:"_blank",rel:"noopener noreferrer"}},[s._v("trigger a workflow by schedule"),t("OutboundLink")],1)])]),s._v(" "),t("p",[t("strong",[s._v("POSIX cron 语法")])]),s._v(" "),t("blockquote",[t("p",[s._v("POSIX cron 是一种用于调度任务的时间表达式语法,它由五个字段组成,分别表示分钟、小时、日期、月份和星期几。")])]),s._v(" "),t("p",[s._v("下面是每个字段的取值范围及其对应的含义:")]),s._v(" "),t("ol",[t("li",[s._v("分钟(0-59):表示一小时中的哪一分钟触发任务。")]),s._v(" "),t("li",[s._v("小时(0-23):表示一天中的哪个小时触发任务。")]),s._v(" "),t("li",[s._v("日期(1-31):表示一个月中的哪一天触发任务。")]),s._v(" "),t("li",[s._v("月份(1-12):表示一年中的哪个月触发任务。")]),s._v(" "),t("li",[s._v("星期几(0-7,其中 0 和 7 都表示周日):表示一周中的哪一天触发任务。")])]),s._v(" "),t("p",[s._v("使用这五个字段的组合,我们可以创建出各种不同的时间表达式来调度任务。下面是一些示例:")]),s._v(" "),t("ul",[t("li",[t("code",[s._v("* * * * *")]),s._v(":每分钟触发一次任务。")]),s._v(" "),t("li",[t("code",[s._v("0 * * * *")]),s._v(":每小时的 0 分钟触发一次任务。")]),s._v(" "),t("li",[t("code",[s._v("0 0 * * *")]),s._v(":每天的 0 点整触发一次任务。")]),s._v(" "),t("li",[t("code",[s._v("0 0 * * 1")]),s._v(":每周一的 0 点整触发一次任务。")]),s._v(" "),t("li",[t("code",[s._v("0 0 1 1 *")]),s._v(":每年的 1 月 1 日的 0 点整触发一次任务。")])]),s._v(" "),t("p",[s._v("通过指定这些时间表达式,你可以在 GitHub Actions 中使用 POSIX cron 来定时执行你的工作流程。")]),s._v(" "),t("h3",{attrs:{id:"reuse-workflows"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#reuse-workflows"}},[s._v("#")]),s._v(" Reuse workflows")]),s._v(" "),t("p",[s._v("coming soon")]),s._v(" "),t("h3",{attrs:{id:"workflow-commands"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#workflow-commands"}},[s._v("#")]),s._v(" workflow commands")]),s._v(" "),t("h4",{attrs:{id:"multiline-strings"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#multiline-strings"}},[s._v("#")]),s._v(" multiline strings*")]),s._v(" "),t("blockquote",[t("p",[t("a",{attrs:{href:"https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions#environment-files",target:"_blank",rel:"noopener noreferrer"}},[s._v("multiline strings"),t("OutboundLink")],1)])]),s._v(" "),t("p",[s._v("使用方式:")]),s._v(" "),t("div",{staticClass:"language-shell line-numbers-mode"},[t("pre",{pre:!0,attrs:{class:"language-shell"}},[t("code",[t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("name"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("<<")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("delimiter"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("value"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("delimiter"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n")])]),s._v(" "),t("div",{staticClass:"line-numbers-wrapper"},[t("span",{staticClass:"line-number"},[s._v("1")]),t("br"),t("span",{staticClass:"line-number"},[s._v("2")]),t("br"),t("span",{staticClass:"line-number"},[s._v("3")]),t("br")])]),t("p",[s._v("示例:")]),s._v(" "),t("div",{staticClass:"language-shell line-numbers-mode"},[t("pre",{pre:!0,attrs:{class:"language-shell"}},[t("code",[s._v("steps:\n - name: Set the value "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("in")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("bash")]),s._v("\n id: step_one\n run: "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("|")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token assign-left variable"}},[s._v("EOF")]),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),t("span",{pre:!0,attrs:{class:"token variable"}},[t("span",{pre:!0,attrs:{class:"token variable"}},[s._v("$(")]),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("dd")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token assign-left variable"}},[s._v("if")]),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v("/dev/urandom "),t("span",{pre:!0,attrs:{class:"token assign-left variable"}},[s._v("bs")]),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("15")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token assign-left variable"}},[s._v("count")]),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("1")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token assign-left variable"}},[s._v("status")]),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v("none "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("|")]),s._v(" base64"),t("span",{pre:!0,attrs:{class:"token variable"}},[s._v(")")])]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token builtin class-name"}},[s._v("echo")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token string"}},[s._v('"JSON_RESPONSE<<'),t("span",{pre:!0,attrs:{class:"token variable"}},[s._v("$EOF")]),s._v('"')]),s._v(" "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v(">>")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token string"}},[s._v('"'),t("span",{pre:!0,attrs:{class:"token variable"}},[s._v("$GITHUB_ENV")]),s._v('"')]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("curl")]),s._v(" https://example.com "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v(">>")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token string"}},[s._v('"'),t("span",{pre:!0,attrs:{class:"token variable"}},[s._v("$GITHUB_ENV")]),s._v('"')]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token builtin class-name"}},[s._v("echo")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token string"}},[s._v('"'),t("span",{pre:!0,attrs:{class:"token variable"}},[s._v("$EOF")]),s._v('"')]),s._v(" "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v(">>")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token string"}},[s._v('"'),t("span",{pre:!0,attrs:{class:"token variable"}},[s._v("$GITHUB_ENV")]),s._v('"')]),s._v("\n")])]),s._v(" "),t("div",{staticClass:"line-numbers-wrapper"},[t("span",{staticClass:"line-number"},[s._v("1")]),t("br"),t("span",{staticClass:"line-number"},[s._v("2")]),t("br"),t("span",{staticClass:"line-number"},[s._v("3")]),t("br"),t("span",{staticClass:"line-number"},[s._v("4")]),t("br"),t("span",{staticClass:"line-number"},[s._v("5")]),t("br"),t("span",{staticClass:"line-number"},[s._v("6")]),t("br"),t("span",{staticClass:"line-number"},[s._v("7")]),t("br"),t("span",{staticClass:"line-number"},[s._v("8")]),t("br")])]),t("h2",{attrs:{id:"授权"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#授权"}},[s._v("#")]),s._v(" 授权")]),s._v(" "),t("h3",{attrs:{id:"qq-邮箱"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#qq-邮箱"}},[s._v("#")]),s._v(" QQ 邮箱")]),s._v(" "),t("blockquote",[t("p",[s._v("qq 邮箱的授权码更多内容可见链接: "),t("a",{attrs:{href:"https://wx.mail.qq.com/list/readtemplate?name=app_intro.html#/agreement/authorizationCode",target:"_blank",rel:"noopener noreferrer"}},[s._v("SMTP/IMAP 服务"),t("OutboundLink")],1)])]),s._v(" "),t("p",[s._v(":::\nIMAP/SMTP 设置方法\n用户名/帐户: 你的 QQ 邮箱完整的地址")]),s._v(" "),t("p",[s._v("密码: 生成的授权码")]),s._v(" "),t("p",[s._v("电子邮件地址: 你的 QQ 邮箱的完整邮件地址")]),s._v(" "),t("p",[s._v("接收邮件服务器: imap.qq.com,使用 SSL,端口号 993")]),s._v(" "),t("p",[s._v("发送邮件服务器: smtp.qq.com,使用 SSL,端口号 465 或 587\n:::")]),s._v(" "),t("h2",{attrs:{id:"链接"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#链接"}},[s._v("#")]),s._v(" 链接")]),s._v(" "),t("ul",[t("li",[t("a",{attrs:{href:"https://xugaoyi.com/pages/f44d2f9ad04ab8d3/",target:"_blank",rel:"noopener noreferrer"}},[s._v("《GitHub Actions 定时运行代码:每天定时百度链接推送》"),t("OutboundLink")],1)]),s._v(" "),t("li",[t("a",{attrs:{href:"https://docs.github.com/en/actions",target:"_blank",rel:"noopener noreferrer"}},[s._v("github-actions-en"),t("OutboundLink")],1)]),s._v(" "),t("li",[t("a",{attrs:{href:"https://docs.github.com/zh/actions",target:"_blank",rel:"noopener noreferrer"}},[s._v("github-actions-cn"),t("OutboundLink")],1)]),s._v(" "),t("li",[t("a",{attrs:{href:"https://docs.github.com/en/actions/security-guides/encrypted-secrets",target:"_blank",rel:"noopener noreferrer"}},[s._v("security-guides"),t("OutboundLink")],1)])])])}),[],!1,null,null,null);t.default=r.exports}}]); \ No newline at end of file diff --git a/assets/js/66.f21ab691.js b/assets/js/66.f21ab691.js new file mode 100644 index 0000000000..50d4516ad8 --- /dev/null +++ b/assets/js/66.f21ab691.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[66],{392:function(a,e,t){"use strict";t.r(e);var s=t(4),r=Object(s.a)({},(function(){var a=this,e=a._self._c;return e("ContentSlotsDistributor",{attrs:{"slot-key":a.$parent.slotKey}},[e("h1",{attrs:{id:"介绍"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#介绍"}},[a._v("#")]),a._v(" 介绍")]),a._v(" "),e("div",{staticClass:"custom-block tip"},[e("p",{staticClass:"custom-block-title"},[a._v("提示")]),a._v(" "),e("p",[a._v("Gradle is an open-source build automation tool flexible enough to build almost any type of software. Gradle makes few assumptions about what you’re trying to build or how to build it. This makes Gradle particularly flexible.\n"),e("a",{attrs:{href:"https://gradle.org/",target:"_blank",rel:"noopener noreferrer"}},[a._v("官网"),e("OutboundLink")],1)])]),a._v(" "),e("h2",{attrs:{id:"常用"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#常用"}},[a._v("#")]),a._v(" 常用")]),a._v(" "),e("ul",[e("li",[e("code",[a._v("./gradlew ::dependencies")]),a._v(": 打印依赖\n"),e("ul",[e("li",[e("code",[a._v("./gradlew ::dependencies --configuration releaseCompileClasspath")]),a._v(": 打印指定变体 releaseCompileClasspath 依赖")])])])]),a._v(" "),e("h2",{attrs:{id:"agp"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#agp"}},[a._v("#")]),a._v(" AGP")]),a._v(" "),e("h3",{attrs:{id:"agp-升级"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#agp-升级"}},[a._v("#")]),a._v(" AGP 升级")]),a._v(" "),e("h3",{attrs:{id:"prefab"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#prefab"}},[a._v("#")]),a._v(" prefab")]),a._v(" "),e("p",[a._v("在过去进行 "),e("code",[a._v("native")]),a._v(" 开发的时候,如果想要依赖其他的 "),e("code",[a._v("native")]),a._v(" 库时一般需要将头文件和.so/.a 拷贝一份到当前仓库内。这种方式不仅更新 native 库版本不容易,还会因为存放二进制文件导致仓库变大。Google 为了解决这个问题,提出了一个格式叫做 "),e("code",[a._v("Prefab | prefab (google.github.io)")]),a._v("。简单来说,"),e("code",[a._v("Prefab")]),a._v(" 是一种为预构建 "),e("code",[a._v("C/C++")]),a._v(" 库生成构建系统集成的工具,"),e("code",[a._v("Prefab")]),a._v(" 包由少量元数据和它所描述的预构建库组成。\nGoogle 在新版本的安卓打包插件(AGP)内会识别和生成 "),e("code",[a._v("prefab")]),a._v(",现在可以从应用的 AAR 依赖项导入 C/C++ 库头文件,也可以在发布 AAR 时携带自己的头文件:")]),a._v(" "),e("ul",[e("li",[a._v("AGP4.0 时提供了识别 prefab 功能:"),e("a",{attrs:{href:"https://developer.android.com/studio/releases/gradle-plugin?buildsystem=cmake#native-dependencies",target:"_blank",rel:"noopener noreferrer"}},[a._v("https://developer.android.com/studio/releases/gradle-plugin?buildsystem=cmake#native-dependencies"),e("OutboundLink")],1)]),a._v(" "),e("li",[a._v("AGP4.1 时提供了发布 prefab 功能:"),e("a",{attrs:{href:"https://developer.android.com/studio/releases/gradle-plugin?buildsystem=cmake#4.1-prefab-publish",target:"_blank",rel:"noopener noreferrer"}},[a._v("https://developer.android.com/studio/releases/gradle-plugin?buildsystem=cmake#4.1-prefab-publish"),e("OutboundLink")],1)])]),a._v(" "),e("h2",{attrs:{id:"controlling-transitives"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#controlling-transitives"}},[a._v("#")]),a._v(" Controlling Transitives")]),a._v(" "),e("h3",{attrs:{id:"share-versions"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#share-versions"}},[a._v("#")]),a._v(" share versions")]),a._v(" "),e("blockquote",[e("p",[a._v("在 Gradle 构建中,有两种常见的方式来管理依赖的共享版本:平台(platform)方式和目录(catalog)方式。\n要知道更多详情可见官网 "),e("a",{attrs:{href:"https://docs.gradle.org/current/userguide/platforms.html#sub:bom_import",target:"_blank",rel:"noopener noreferrer"}},[a._v("share version"),e("OutboundLink")],1)])]),a._v(" "),e("ol",[e("li",[e("p",[a._v("平台方式(Platform-based Approach):")]),a._v(" "),e("ul",[e("li",[a._v('平台方式通过定义一个称为"平台"(platform)的依赖项来管理共享版本。')]),a._v(" "),e("li",[a._v("平台定义了一个版本,而不是具体的依赖项。它充当一个版本约束,可以在多个子项目中共享。")]),a._v(" "),e("li",[a._v("平台可以包含多个相关联的依赖项,并确保它们使用相同的版本。")]),a._v(" "),e("li",[a._v("子项目可以声明对平台的依赖,而不需要指定具体的版本号。")]),a._v(" "),e("li",[a._v("平台方式适用于具有多个子项目,并且需要确保这些子项目使用相同版本的依赖项。")])])]),a._v(" "),e("li",[e("p",[a._v("目录方式(Catalog-based Approach):")]),a._v(" "),e("ul",[e("li",[a._v('目录方式通过定义一个称为"目录"(catalog)的依赖项来管理共享版本。')]),a._v(" "),e("li",[a._v("目录是一个定义了多个依赖项及其相应版本的集合。")]),a._v(" "),e("li",[a._v("目录中的依赖项可以按组织结构或其他自定义规则进行组织。")]),a._v(" "),e("li",[a._v("子项目可以引用目录中的依赖项,并指定相应的版本号。")]),a._v(" "),e("li",[a._v("目录方式适用于需要在一个中心位置管理多个依赖项及其版本的场景。")])])])]),a._v(" "),e("p",[a._v("选择使用平台方式还是目录方式取决于项目的需求和组织结构。以下是一些考虑因素:")]),a._v(" "),e("ul",[e("li",[a._v("如果您的项目有多个子项目,并且您希望确保它们使用相同版本的依赖项,那么平台方式是一个不错的选择。")]),a._v(" "),e("li",[a._v("如果您希望在一个中心位置定义和管理依赖项及其版本,以便供多个项目使用,那么目录方式可能更适合。")]),a._v(" "),e("li",[a._v("平台方式更适合于管理大型项目的版本依赖关系,而目录方式则更适合于组织结构较简单的项目。")])]),a._v(" "),e("p",[a._v("要在 Gradle 项目中选择使用平台方式还是目录方式,您需要根据项目的具体需求进行评估,并在构建脚本中进行相应的配置。您可以使用 Gradle 的相关插件或功能来定义和管理平台或目录。")]),a._v(" "),e("h3",{attrs:{id:"解决版本号冲突"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#解决版本号冲突"}},[a._v("#")]),a._v(" 解决版本号冲突")]),a._v(" "),e("blockquote",[e("p",[e("a",{attrs:{href:"https://docs.gradle.org/current/userguide/resolution_rules.html",target:"_blank",rel:"noopener noreferrer"}},[a._v("Customizing resolution of a dependency directly"),e("OutboundLink")],1)])]),a._v(" "),e("p",[a._v("示例")]),a._v(" "),e("div",{staticClass:"language-groovy line-numbers-mode"},[e("pre",{pre:!0,attrs:{class:"language-groovy"}},[e("code",[a._v("subprojects "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("{")]),a._v("\n group "),e("span",{pre:!0,attrs:{class:"token operator"}},[a._v("=")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[a._v("'xxx'")]),a._v("\n configurations"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(".")]),a._v("all "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("{")]),a._v(" Configuration configuration "),e("span",{pre:!0,attrs:{class:"token operator"}},[a._v("->")]),a._v("\n configuration"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(".")]),a._v("resolutionStrategy "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("{")]),a._v("\n "),e("span",{pre:!0,attrs:{class:"token function"}},[a._v("preferProjectModules")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),a._v("\n "),e("span",{pre:!0,attrs:{class:"token function"}},[a._v("force")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[a._v("'::'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),a._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("}")]),a._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("}")]),a._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("}")]),a._v("\n")])]),a._v(" "),e("div",{staticClass:"line-numbers-wrapper"},[e("span",{staticClass:"line-number"},[a._v("1")]),e("br"),e("span",{staticClass:"line-number"},[a._v("2")]),e("br"),e("span",{staticClass:"line-number"},[a._v("3")]),e("br"),e("span",{staticClass:"line-number"},[a._v("4")]),e("br"),e("span",{staticClass:"line-number"},[a._v("5")]),e("br"),e("span",{staticClass:"line-number"},[a._v("6")]),e("br"),e("span",{staticClass:"line-number"},[a._v("7")]),e("br"),e("span",{staticClass:"line-number"},[a._v("8")]),e("br"),e("span",{staticClass:"line-number"},[a._v("9")]),e("br")])]),e("p",[a._v("【注】发布到 maven 的话不要用 force 关键字,会导致其他依赖你的库 也锁死了相关库的版本号")]),a._v(" "),e("h2",{attrs:{id:"其他"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#其他"}},[a._v("#")]),a._v(" 其他")]),a._v(" "),e("h3",{attrs:{id:"调试"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#调试"}},[a._v("#")]),a._v(" 调试")]),a._v(" "),e("p",[a._v("方案一: 利用 gradle 的参数让其等待我们的调试进程 attach 上去")]),a._v(" "),e("div",{staticClass:"language-shell line-numbers-mode"},[e("pre",{pre:!0,attrs:{class:"language-shell"}},[e("code",[a._v("gradle :app:clean "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-Dorg.gradle.debug")]),e("span",{pre:!0,attrs:{class:"token operator"}},[a._v("=")]),a._v("true --no-daemon\n")])]),a._v(" "),e("div",{staticClass:"line-numbers-wrapper"},[e("span",{staticClass:"line-number"},[a._v("1")]),e("br")])]),e("p",[a._v("后续操作可以参考: "),e("a",{attrs:{href:"https://fucknmb.com/2017/07/05/%E5%8F%88%E6%8E%8C%E6%8F%A1%E4%BA%86%E4%B8%80%E9%A1%B9%E6%96%B0%E6%8A%80%E8%83%BD-%E6%96%AD%E7%82%B9%E8%B0%83%E8%AF%95Gradle%E6%8F%92%E4%BB%B6/",target:"_blank",rel:"noopener noreferrer"}},[a._v("断点调试"),e("OutboundLink")],1)]),a._v(" "),e("p",[a._v("方案二:用环境变量")]),a._v(" "),e("div",{staticClass:"language-shell line-numbers-mode"},[e("pre",{pre:!0,attrs:{class:"language-shell"}},[e("code",[e("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v("export")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token assign-left variable"}},[a._v("GRADLE_OPTS")]),e("span",{pre:!0,attrs:{class:"token operator"}},[a._v("=")]),e("span",{pre:!0,attrs:{class:"token string"}},[a._v('"-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=5005"')]),a._v("\n")])]),a._v(" "),e("div",{staticClass:"line-numbers-wrapper"},[e("span",{staticClass:"line-number"},[a._v("1")]),e("br")])]),e("p",[a._v("而后执行跟正常的命令是一样的")])])}),[],!1,null,null,null);e.default=r.exports}}]); \ No newline at end of file diff --git a/assets/js/67.ae34006f.js b/assets/js/67.ae34006f.js new file mode 100644 index 0000000000..258d4634a3 --- /dev/null +++ b/assets/js/67.ae34006f.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[67],{393:function(v,e,n){"use strict";n.r(e);var _=n(4),l=Object(_.a)({},(function(){var v=this,e=v._self._c;return e("ContentSlotsDistributor",{attrs:{"slot-key":v.$parent.slotKey}},[e("p",[v._v("Apache Maven 是一个强大的项目构建和依赖管理工具,它使用 mvn 命令行工具来执行各种构建任务。以下是一些常用的 mvn 命令:")]),v._v(" "),e("ul",[e("li",[e("code",[v._v("mvn clean")]),v._v(":清除项目的目标目录(通常是 target 目录),删除之前构建生成的文件。这通常用于在重新构建项目之前进行清理。")]),v._v(" "),e("li",[e("code",[v._v("mvn compile")]),v._v(":编译项目的源代码,将编译后的类文件存储在 target/classes 目录中。")]),v._v(" "),e("li",[e("code",[v._v("mvn test")]),v._v(":运行项目的单元测试。Maven 将查找并执行项目中的测试类,并生成测试报告。")]),v._v(" "),e("li",[e("code",[v._v("mvn package")]),v._v(":打包项目,通常将项目的编译输出打包成 JAR、WAR 或其他格式的归档文件,存储在 target 目录中。")]),v._v(" "),e("li",[e("code",[v._v("mvn install")]),v._v(":将项目构建结果安装到本地 Maven 仓库,以便其他项目可以引用它。这对于多模块项目非常有用。")]),v._v(" "),e("li",[e("code",[v._v("mvn deploy")]),v._v(":将项目构建结果发布到远程 Maven 仓库,以供其他开发人员和项目使用。通常需要配置远程仓库的详细信息。")]),v._v(" "),e("li",[e("code",[v._v("mvn clean install")]),v._v(":清理项目、编译代码并将构建结果安装到本地仓库。这是常用的组合命令,用于构建并安装项目。")]),v._v(" "),e("li",[e("code",[v._v("mvn clean test")]),v._v(":清理项目并运行单元测试。")]),v._v(" "),e("li",[e("code",[v._v("mvn clean package")]),v._v(":清理项目并打包项目。通常用于生成可部署的构建文件。")]),v._v(" "),e("li",[e("code",[v._v("mvn clean install -DskipTests")]),v._v(":清理项目、编译代码并将构建结果安装到本地仓库,但跳过运行单元测试。")]),v._v(" "),e("li",[e("code",[v._v("mvn dependency:tree")]),v._v(":显示项目的依赖树,包括所有直接和间接依赖项。这对于解决依赖冲突问题非常有用。")]),v._v(" "),e("li",[e("code",[v._v("mvn archetype:generate")]),v._v(":使用 Maven Archetype 插件创建新项目的模板。你可以选择不同类型的模板来创建不同类型的项目。")]),v._v(" "),e("li",[e("code",[v._v("mvn help:effective-pom")]),v._v(":显示项目的有效 POM(合并了所有继承和配置的 POM 部分),这对于了解项目的实际配置非常有用。")])]),v._v(" "),e("p",[v._v("这些是一些常用的 mvn 命令,你可以根据项目的需求和构建过程使用不同的命令。要了解更多关于 Maven 命令的详细信息,你可以运行 mvn --help 或查阅 Maven 文档")])])}),[],!1,null,null,null);e.default=l.exports}}]); \ No newline at end of file diff --git a/assets/js/68.325d6318.js b/assets/js/68.325d6318.js new file mode 100644 index 0000000000..bc4325ff33 --- /dev/null +++ b/assets/js/68.325d6318.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[68],{394:function(t,a,i){"use strict";i.r(a);var v=i(4),d=Object(v.a)({},(function(){var t=this,a=t._self._c;return a("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[a("div",{staticClass:"custom-block tip"},[a("p",{staticClass:"custom-block-title"},[t._v("提示")]),t._v(" "),a("p",[a("a",{attrs:{href:"https://github.com/skylot/jadx",target:"_blank",rel:"noopener noreferrer"}},[t._v("github 链接"),a("OutboundLink")],1)])]),t._v(" "),a("h2",{attrs:{id:"介绍"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#介绍"}},[t._v("#")]),t._v(" 介绍")]),t._v(" "),a("p",[t._v("jadx 是一款用于将 Android APK 文件反编译为可读的 Java 源代码的开源工具。它可以帮助开发人员和安全研究人员分析和理解 Android 应用程序的内部结构、逻辑和实现细节。")]),t._v(" "),a("p",[t._v("以下是 jadx 工具的一些主要特点和功能:")]),t._v(" "),a("ul",[a("li",[a("p",[t._v("反编译 APK 文件:jadx 可以将 Android APK 文件转换为可读的 Java 源代码,并提取出应用程序中的类、方法、字段等信息。")])]),t._v(" "),a("li",[a("p",[t._v("可视化展示:jadx 提供了一个用户友好的图形界面,可以以树状结构形式展示应用程序的包、类、方法等元素,使得代码浏览和分析更加方便。")])]),t._v(" "),a("li",[a("p",[t._v("跨平台支持:jadx 支持在多个操作系统上运行,包括 Windows、Linux 和 macOS,可以在不同环境中使用。")])]),t._v(" "),a("li",[a("p",[t._v("支持最新的 Android 版本:jadx 对 Android 的最新版本和特性提供了支持,可以处理使用较新 API 级别构建的应用程序。")])]),t._v(" "),a("li",[a("p",[t._v("反混淆支持:对于已经进行了代码混淆的应用程序,jadx 可以尝试还原原始的类、方法和字段名称,以便更好地理解代码。")])]),t._v(" "),a("li",[a("p",[t._v("代码导航和搜索:jadx 提供了代码导航和搜索功能,可以快速定位特定的类、方法、字段或关键字,便于快速浏览和分析代码。")])]),t._v(" "),a("li",[a("p",[t._v("导出功能:jadx 允许将反编译的代码导出为 Java 源代码或 Smali 格式,方便进一步的分析和处理。")])])]),t._v(" "),a("p",[t._v("总体而言,jadx 是一个功能强大且易于使用的工具,可以帮助开发人员和安全研究人员对 Android 应用程序进行逆向工程和代码分析。它可以提供有关应用程序内部实现的深入洞察,并帮助解决问题、修复错误或进行安全评估。")])])}),[],!1,null,null,null);a.default=d.exports}}]); \ No newline at end of file diff --git a/assets/js/69.a00d1e3f.js b/assets/js/69.a00d1e3f.js new file mode 100644 index 0000000000..ba6ae0a123 --- /dev/null +++ b/assets/js/69.a00d1e3f.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[69],{395:function(t,v,o){"use strict";o.r(v);var s=o(4),_=Object(s.a)({},(function(){var t=this,v=t._self._c;return v("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[v("blockquote",[v("p",[t._v("http 相关的内容 blog 可以查看,小林 coding 对网络的总结,链接为:https://xiaolincoding.com/network")])]),t._v(" "),v("h2",{attrs:{id:"ipv4-地址的表示"}},[v("a",{staticClass:"header-anchor",attrs:{href:"#ipv4-地址的表示"}},[t._v("#")]),t._v(" IPv4 地址的表示")]),t._v(" "),v("div",{staticClass:"custom-block tip"},[v("p",{staticClass:"custom-block-title"},[t._v("提示")]),t._v(" "),v("p",[t._v("一个 IPv4 地址,可以使用 16 进制的输出代表.\n这里分析下 16 进制各子节代表的意义,以: 00 02 13 88 7f 00 00 01 00 00 00 00 00 00 00 00 为例")])]),t._v(" "),v("p",[t._v("这个 16 进制的输出代表一个 IPv4 地址。让我们一起分析它:")]),t._v(" "),v("ul",[v("li",[v("code",[t._v("00 02")]),t._v(":这是表示地址族(Address Family)的字段,其中 00 02 对应 AF_INET,表示 IPv4 地址族。")]),t._v(" "),v("li",[v("code",[t._v("13 88")]),t._v(":这是表示端口号的字段,其中 13 88 对应 5000,表示目标主机的端口号为 5000。")]),t._v(" "),v("li",[v("code",[t._v("7f 00 00 01")]),t._v(":这是表示 IP 地址的字段,其中 7f 00 00 01 对应 127.0.0.1,表示目标主机的 IP 地址为 127.0.0.1,即本地回环地址。")])]),t._v(" "),v("p",[t._v("所以,这个 16 进制输出表示将连接目标主机的 IP 地址和端口号设置为 127.0.0.1:5000。")]),t._v(" "),v("p",[t._v("在代码中,这个地址被用作 inet_pton 函数的参数,将字符串形式的 IP 地址转换为二进制表示。这样就将目标主机的地址设置为 127.0.0.1,以便与其建立连接。")])])}),[],!1,null,null,null);v.default=_.exports}}]); \ No newline at end of file diff --git a/assets/js/70.c347c4c6.js b/assets/js/70.c347c4c6.js new file mode 100644 index 0000000000..a362076b7c --- /dev/null +++ b/assets/js/70.c347c4c6.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[70],{396:function(o,s,e){"use strict";e.r(s);var i=e(4),t=Object(i.a)({},(function(){var o=this,s=o._self._c;return s("ContentSlotsDistributor",{attrs:{"slot-key":o.$parent.slotKey}},[s("h2",{attrs:{id:"session-和-cookie"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#session-和-cookie"}},[o._v("#")]),o._v(" SESSION 和 COOKIE")]),o._v(" "),s("p",[o._v("由于 HTTP 协议是无状态的协议,所以服务端需要记录用户的状态时,就需要用某种机制来识具体的用户,这个机制就是 Session.")]),o._v(" "),s("blockquote",[s("ul",[s("li",[o._v("Session 是在服务端保存的一个数据结构,用来跟踪用户的状态,这个数据可以保存在集群、数据库、文件中。")]),o._v(" "),s("li",[o._v("Cookie 是客户端保存用户信息的一种机制,也是实现 Session 的一种方式。可以理解为一个文件,不会因为浏览器的关闭而消失。")])])]),o._v(" "),s("p",[s("strong",[o._v("思考一下服务端如何识别特定的客户?")])]),o._v(" "),s("p",[o._v("每次 HTTP 请求的时候,客户端都会发送相应的 Cookie 信息到服务端。"),s("strong",[o._v("实际上大多数的应用都是用 Cookie 来实现 Session 跟踪的")]),o._v(",第一次创建 Session 的时候,服务端会在 HTTP 协议中告诉客户端,需要在 Cookie 里面记录一个 Session ID,以后每次请求把这个会话 ID 发送到服务器,服务器就知道你是谁了。")]),o._v(" "),s("p",[s("strong",[o._v("Cookie 常见的应用场景")])]),o._v(" "),s("p",[o._v("Cookie 是浏览器保存信息的一种方式,可以理解为一个文件,保存到客户端了啊,服务器可以通过响应浏览器的 set-cookie 的标头,得到 Cookie 的信息。你可以给这个文件设置一个期限,这个期限呢,不会因为浏览器的关闭而消失啊。其实大家应该对这个效果不陌生,很多购物网站都是这个做的,即使你没有买东西,他也记住了你的喜好,现在回来,会优先给你提交你喜欢的东西啊,他们也真是煞费苦心了啊。")])])}),[],!1,null,null,null);s.default=t.exports}}]); \ No newline at end of file diff --git a/assets/js/71.c52e0f63.js b/assets/js/71.c52e0f63.js new file mode 100644 index 0000000000..a7a97a2276 --- /dev/null +++ b/assets/js/71.c52e0f63.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[71],{397:function(t,s,a){"use strict";a.r(s);var n=a(4),e=Object(n.a)({},(function(){var t=this,s=t._self._c;return s("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[s("h2",{attrs:{id:"网络基础"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#网络基础"}},[t._v("#")]),t._v(" 网络基础")]),t._v(" "),s("h3",{attrs:{id:"osi-7-层模型"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#osi-7-层模型"}},[t._v("#")]),t._v(" OSI 7 层模型")]),t._v(" "),s("p",[s("img",{attrs:{src:"https://raw.githubusercontent.com/jacky1234/picArchieve/master/uPic/687474703a2f2f68692e6373646e2e6e65742f6174746163686d656e742f3230313230312f352f305f31333235373434353937574d33322e676966.gif",alt:""}})]),t._v(" "),s("h3",{attrs:{id:"公钥与私钥"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#公钥与私钥"}},[t._v("#")]),t._v(" "),s("a",{attrs:{href:"https://songlee24.github.io/2015/05/03/public-key-and-private-key/",target:"_blank",rel:"noopener noreferrer"}},[t._v("公钥与私钥"),s("OutboundLink")],1)]),t._v(" "),s("p",[t._v("公钥算法与私钥算法\n私钥加密算法,又称 对称加密算法,因为这种算法解密密钥和加密密钥是相同的。也正因为同一密钥既用于加密又用于解密,所以这个密钥是不能公开的。常见的有**《DES 加密算法》、《AES 加密算法》**。")]),t._v(" "),s("h3",{attrs:{id:"证书"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#证书"}},[t._v("#")]),t._v(" 证书")]),t._v(" "),s("p",[t._v("这种由权威部门颁发的称为证书。有权威机构去认证,"),s("strong",[t._v("这个机构叫 CA(Certificate Authority)")])]),t._v(" "),s("p",[t._v("证书里面有什么:")]),t._v(" "),s("ul",[s("li",[t._v("公钥")]),t._v(" "),s("li",[t._v("所有者")]),t._v(" "),s("li",[t._v("发布机构和证书有效期")])]),t._v(" "),s("p",[t._v("创建私钥\n"),s("code",[t._v("openssl genrsa -out cliu8siteprivate.key 1024")])]),t._v(" "),s("p",[t._v("根据这个私钥创建公钥\n"),s("code",[t._v("openssl rsa -in cliu8siteprivate.key -pubout -out cliu8sitepublic.pem")])]),t._v(" "),s("p",[t._v("证书请求\n问题: 公钥如何传输呢?如何证明别人给你的证书是正确的?\n"),s("code",[t._v("openssl req -key cliu8siteprivate.key -new -out cliu8sitecertifiacte.req")])]),t._v(" "),s("p",[t._v("将这个请求发给权威机构,权威机构会给这个证书卡一个章(签名)\n权威机构给证书签名是这样的:\n"),s("code",[t._v("openssl x509 -req -in cliu8sitecertificate.req -CA cacertificate.pem -CAkey caprivate.key -out cliu8sitecertificate.pem")]),t._v("\n这个命令返回 Signature ok,而 cliu8sitecertificate.pem 就是签过名的证书。")]),t._v(" "),s("p",[t._v("查看这个证书内容:\n"),s("code",[t._v("openssl x509 -in cliu8sitecertificate.pem -noout -text")])]),t._v(" "),s("p",[t._v("==>\n你不会从一个外卖网站上得到一个公钥,而是会得到一个证书,这个证书有颁发的 CA,只要得到这个 CA 的公钥,去解密外卖网站证书的签名,如果解密成功,Hash 也对上,就说明这个外卖网站的公钥没有问题。")]),t._v(" "),s("hr"),t._v(" "),s("p",[t._v("为了同时兼顾安全和效率,我们通常结合使用公钥算法和私钥算法:")]),t._v(" "),s("ul",[s("li",[t._v("首先,发送方使用对称算法对原始信息进行加密。")]),t._v(" "),s("li",[t._v("接收方通过公钥机制生成一对密钥,一个公钥,一个私钥。")]),t._v(" "),s("li",[t._v("接收方 将公钥发送给 发送方。")]),t._v(" "),s("li",[t._v("发送方用公钥对对称算法的密钥进行加密,并发送给接收方。")]),t._v(" "),s("li",[t._v("接收方用私钥进行解密得到对称算法的密钥。")]),t._v(" "),s("li",[t._v("发送方再把已加密的原始信息发送给接收方。")]),t._v(" "),s("li",[t._v("接收方使用对称算法的密钥进行解密。")])]),t._v(" "),s("hr"),t._v(" "),s("h2",{attrs:{id:"https-协议的总体思路"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#https-协议的总体思路"}},[t._v("#")]),t._v(" HTTPS 协议的总体思路")]),t._v(" "),s("p",[s("img",{attrs:{src:"https://raw.githubusercontent.com/jacky1234/picArchieve/master/uPic/x2ccL5.jpg",alt:"img"}})]),t._v(" "),s("ol",[s("li",[t._v("Client 会发送 Client Hello 到服务器,以明文传输 TLS 版本信息,加密套件候选列表,压缩算法候选列表等信息。还有个随机数,在协商密钥的时候使用。")]),t._v(" "),s("li",[t._v("Server 返回 Server Hello 信息,告诉客户端,服务器选择用的协议版本,加密套件,压缩算法等,还有一个随机数,用于后续协商密钥。")]),t._v(" "),s("li",[t._v('Server 返回服务器证书,然后说 "Server Hello Done"')]),t._v(" "),s("li",[t._v("Client 从自己信任的 CA 仓库中,那 CA 的证书公钥去解密外卖网站的证书。如果解密成功,则说明外卖证书可信。这个过程可能会不断线上追溯 CA,CA 的 CA,CA 的 CA 的 CA,反正知道一个授信的 CA,就可以了。")]),t._v(" "),s("li",[t._v("客户端计算 pre-master 随机数,发送 Client key exchange,用证书中的公钥加密,发给服务器。服务器通过私钥解密 pre-master 随机数")]),t._v(" "),s("li",[t._v("目前有 3 个随机数,分别是:自己的,对端的,以及刚刚生成的 pre-master 随机数.通过这 3 个随机数,在 Clent 和 Server 端产生相同的对称密钥 "),s("em",[t._v("master secret")])]),t._v(" "),s("li",[t._v('Client 可以说 "Change Clipher Spec" 。以后采用协商的通信密钥和加密算法进行通信, 对称密钥通信。')]),t._v(" "),s("li",[t._v("Client 发送一个 Encrypted Handshake Message,将协商好的参数,采用协商密钥加密,发送给 Server 用于数据与握手验证。\n...")])]),t._v(" "),s("p",[t._v("补充:")]),t._v(" "),s("ol",[s("li",[t._v("Change Clipher Spec Protocol: "),s("a",{attrs:{href:"https://www.cnblogs.com/bonelee/p/10404733.html",target:"_blank",rel:"noopener noreferrer"}},[t._v("TLS 改变密码标准协议(Change Cipher Spec Protocol) 就是加密传输中每隔一段时间必须改变其加解密参数的协议"),s("OutboundLink")],1)]),t._v(" "),s("li",[t._v("Encrypted Handshake Message: 这个报文的目的就是告诉对端自己在整个握手过程中收到了什么数据,发送了什么数据。来保证中间没人篡改报文。")])]),t._v(" "),s("p",[s("strong",[t._v("问题:为什么不能只用一个 pre-master 作为之后加密的对称密钥?")])]),t._v(" "),s("p",[t._v("虽然只有服务器有私钥,能够解密 pre-master 呀,但仅用它作为 master secret 是不够安全的,这是因为要以防客户端的 pre-master 并不是随机数的情况。\n加上另外两个随机数 client-random 以及 server-random(而这两个随机数和时间有相关性),这样就能保证最后生成的 master secret 一定是随机数。")]),t._v(" "),s("hr"),t._v(" "),s("h2",{attrs:{id:"实战"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#实战"}},[t._v("#")]),t._v(" 实战")]),t._v(" "),s("h3",{attrs:{id:"http-安全实践"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#http-安全实践"}},[t._v("#")]),t._v(" http 安全实践")]),t._v(" "),s("ol",[s("li",[t._v("client 启动的时候生成随机数 key (仅启动时生成一次)")]),t._v(" "),s("li",[t._v("将 version;type;key(上述随机数);time 信息用公钥加密; 这个信息是直接可以通过服务器私钥解密的")]),t._v(" "),s("li",[t._v("对请求的 body 等信息使用第一步的 key 进行 hmac 计算(服务器采用相同算法计算与这个信息做比较,为了保证数据完整性)")]),t._v(" "),s("li",[t._v("...")])]),t._v(" "),s("p",[t._v("代码如下:")]),t._v(" "),s("div",{staticClass:"language-java line-numbers-mode"},[s("pre",{pre:!0,attrs:{class:"language-java"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("static")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("sign")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),t._v(" urlString"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("HttpRequestClient"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("Method")]),t._v(" method"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("byte")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" body"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Map"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("Entry")]),s("span",{pre:!0,attrs:{class:"token generics"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" randomValue "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" pubicKeyEntries"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("get")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("generator"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("nextInt")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("pubicKeyEntries"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("size")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),t._v(" time "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("valueOf")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("System")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("currentTimeMillis")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("InnerLogicManager")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("get")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("getServerTimestampDelta")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1000")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("final")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("List")]),s("span",{pre:!0,attrs:{class:"token generics"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" contentOfSign "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ArrayList")]),s("span",{pre:!0,attrs:{class:"token generics"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("6")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n contentOfSign"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("add")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("time"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n contentOfSign"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("add")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("method"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("name")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("try")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("URL")]),t._v(" url "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("URL")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("urlString"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),t._v(" path "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" url"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("getPath")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("path "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("null")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n contentOfSign"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("add")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('""')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("else")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n contentOfSign"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("add")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("path"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),t._v(" query "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" url"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("getQuery")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("query "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("null")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n contentOfSign"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("add")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('""')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("else")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n contentOfSign"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("add")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("query"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("catch")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("MalformedURLException")]),t._v(" e"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Logger")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("e")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("e"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("try")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("MessageDigest")]),t._v(" digest "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("MessageDigest")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("getInstance")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"SHA-256"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("byte")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" hash "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" digest"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("digest")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("body"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),t._v(" bodySign "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("bytesToHex")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("hash"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n contentOfSign"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("add")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("bodySign"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("catch")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("NoSuchAlgorithmException")]),t._v(" e"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Logger")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("e")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("e"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),t._v(" sign "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("DeviceDependence")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("current"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("getDeviceInject")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("hmac")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("key"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Strings")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("joinStrings")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("contentOfSign"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token char"}},[t._v("'\\n'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("final")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("List")]),s("span",{pre:!0,attrs:{class:"token generics"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" content "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ArrayList")]),s("span",{pre:!0,attrs:{class:"token generics"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n content"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("add")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"version="')]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" version"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n content"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("add")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"type=0"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// type = 0 ,只签名不加密,防止非法调用接口")]),t._v("\n content"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("add")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"key="')]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Base64")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("encodeToString")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("key"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("getBytes")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Base64")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("DEFAULT")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n content"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("add")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"time="')]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" time"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),t._v(" encryptedContent "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("DeviceDependence")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("current"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("getDeviceInject")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("rsaEncode")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Strings")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("joinStrings")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("content"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token char"}},[t._v("';'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" randomValue"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("getValue")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"key="')]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" randomValue"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("getKey")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('";secret="')]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" encryptedContent "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('";signature="')]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" sign"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])]),t._v(" "),s("div",{staticClass:"line-numbers-wrapper"},[s("span",{staticClass:"line-number"},[t._v("1")]),s("br"),s("span",{staticClass:"line-number"},[t._v("2")]),s("br"),s("span",{staticClass:"line-number"},[t._v("3")]),s("br"),s("span",{staticClass:"line-number"},[t._v("4")]),s("br"),s("span",{staticClass:"line-number"},[t._v("5")]),s("br"),s("span",{staticClass:"line-number"},[t._v("6")]),s("br"),s("span",{staticClass:"line-number"},[t._v("7")]),s("br"),s("span",{staticClass:"line-number"},[t._v("8")]),s("br"),s("span",{staticClass:"line-number"},[t._v("9")]),s("br"),s("span",{staticClass:"line-number"},[t._v("10")]),s("br"),s("span",{staticClass:"line-number"},[t._v("11")]),s("br"),s("span",{staticClass:"line-number"},[t._v("12")]),s("br"),s("span",{staticClass:"line-number"},[t._v("13")]),s("br"),s("span",{staticClass:"line-number"},[t._v("14")]),s("br"),s("span",{staticClass:"line-number"},[t._v("15")]),s("br"),s("span",{staticClass:"line-number"},[t._v("16")]),s("br"),s("span",{staticClass:"line-number"},[t._v("17")]),s("br"),s("span",{staticClass:"line-number"},[t._v("18")]),s("br"),s("span",{staticClass:"line-number"},[t._v("19")]),s("br"),s("span",{staticClass:"line-number"},[t._v("20")]),s("br"),s("span",{staticClass:"line-number"},[t._v("21")]),s("br"),s("span",{staticClass:"line-number"},[t._v("22")]),s("br"),s("span",{staticClass:"line-number"},[t._v("23")]),s("br"),s("span",{staticClass:"line-number"},[t._v("24")]),s("br"),s("span",{staticClass:"line-number"},[t._v("25")]),s("br"),s("span",{staticClass:"line-number"},[t._v("26")]),s("br"),s("span",{staticClass:"line-number"},[t._v("27")]),s("br"),s("span",{staticClass:"line-number"},[t._v("28")]),s("br"),s("span",{staticClass:"line-number"},[t._v("29")]),s("br"),s("span",{staticClass:"line-number"},[t._v("30")]),s("br"),s("span",{staticClass:"line-number"},[t._v("31")]),s("br"),s("span",{staticClass:"line-number"},[t._v("32")]),s("br"),s("span",{staticClass:"line-number"},[t._v("33")]),s("br"),s("span",{staticClass:"line-number"},[t._v("34")]),s("br"),s("span",{staticClass:"line-number"},[t._v("35")]),s("br"),s("span",{staticClass:"line-number"},[t._v("36")]),s("br"),s("span",{staticClass:"line-number"},[t._v("37")]),s("br"),s("span",{staticClass:"line-number"},[t._v("38")]),s("br"),s("span",{staticClass:"line-number"},[t._v("39")]),s("br"),s("span",{staticClass:"line-number"},[t._v("40")]),s("br"),s("span",{staticClass:"line-number"},[t._v("41")]),s("br"),s("span",{staticClass:"line-number"},[t._v("42")]),s("br"),s("span",{staticClass:"line-number"},[t._v("43")]),s("br"),s("span",{staticClass:"line-number"},[t._v("44")]),s("br"),s("span",{staticClass:"line-number"},[t._v("45")]),s("br"),s("span",{staticClass:"line-number"},[t._v("46")]),s("br")])]),s("hr"),t._v(" "),s("h2",{attrs:{id:"附录"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#附录"}},[t._v("#")]),t._v(" 附录")]),t._v(" "),s("ul",[s("li",[t._v("刘超《趣谈网络协议-15》")])])])}),[],!1,null,null,null);s.default=e.exports}}]); \ No newline at end of file diff --git a/assets/js/72.9c3acff8.js b/assets/js/72.9c3acff8.js new file mode 100644 index 0000000000..dee1e9aa91 --- /dev/null +++ b/assets/js/72.9c3acff8.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[72],{398:function(t,r,e){"use strict";e.r(r);var a=e(4),n=Object(a.a)({},(function(){var t=this,r=t._self._c;return r("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[r("p",[r("strong",[t._v("参考内容")])]),t._v(" "),r("ul",[r("li",[r("a",{attrs:{href:"https://cloud.tencent.com/developer/article/1367850",target:"_blank",rel:"noopener noreferrer"}},[t._v("腾讯社区-全面了解移动端DNS域名劫持等杂症:原理、根源、HttpDNS解决方案等"),r("OutboundLink")],1)]),t._v(" "),r("li",[r("a",{attrs:{href:"https://time.geekbang.org/column/article/9938",target:"_blank",rel:"noopener noreferrer"}},[t._v("极客时间-HttpDNS:网络世界的地址簿也会指错路"),r("OutboundLink")],1)]),t._v(" "),r("li",[r("a",{attrs:{href:"https://juejin.cn/post/6844904190913822727",target:"_blank",rel:"noopener noreferrer"}},[t._v("CDN 的工作原理介绍"),r("OutboundLink")],1)]),t._v(" "),r("li",[r("a",{attrs:{href:"https://www.dns.com/supports/710.html",target:"_blank",rel:"noopener noreferrer"}},[t._v("DNS和CDN的区别与联系"),r("OutboundLink")],1)]),t._v(" "),r("li",[r("a",{attrs:{href:"https://zhuanlan.zhihu.com/p/156888470",target:"_blank",rel:"noopener noreferrer"}},[t._v("DNS、HttpDNS和Okhttp"),r("OutboundLink")],1)]),t._v(" "),r("li",[r("a",{attrs:{href:"https://blog.sprov.xyz/2019/03/11/cdn-v2ray-safe-proxy/",target:"_blank",rel:"noopener noreferrer"}},[t._v("拯救被墙的IP,CDN + v2ray,安全的科学上网方法"),r("OutboundLink")],1)])]),t._v(" "),r("hr"),t._v(" "),r("p",[r("strong",[t._v("工具")])]),t._v(" "),r("ul",[r("li",[t._v("​\tdig")]),t._v(" "),r("li",[t._v("​\tnslookup")])]),t._v(" "),r("hr"),t._v(" "),r("h2",{attrs:{id:"dns"}},[r("a",{staticClass:"header-anchor",attrs:{href:"#dns"}},[t._v("#")]),t._v(" DNS")]),t._v(" "),r("blockquote",[r("p",[t._v("DNS ("),r("em",[t._v("Domain Name System")]),t._v(")域名解析系统,其作用是根据域名查找出对应的 IP 地址。比如访问 "),r("a",{attrs:{href:"https://link.zhihu.com/?target=http%3A//www.baidu.com",target:"_blank",rel:"noopener noreferrer"}},[t._v("http://www.baidu.com"),r("OutboundLink")],1),t._v(" 的时候,需要通过 DNS 查处 IP 地址是 14.215.177.39")])]),t._v(" "),r("h4",{attrs:{id:"域名解析过程"}},[r("a",{staticClass:"header-anchor",attrs:{href:"#域名解析过程"}},[t._v("#")]),t._v(" 域名解析过程")]),t._v(" "),r("p",[r("img",{attrs:{src:"https://pic4.zhimg.com/80/v2-fd660e4769ac4ce59b0ef86e79c508c3_1440w.jpg",alt:"img"}})]),t._v(" "),r("p",[t._v("假设访问 "),r("a",{attrs:{href:"https://link.zhihu.com/?target=http%3A//www.baidu.com",target:"_blank",rel:"noopener noreferrer"}},[t._v("http://www.baidu.com"),r("OutboundLink")],1),t._v(" 域名解析过程如下:")]),t._v(" "),r("ul",[r("li",[t._v("1.查找本地 DNS 缓存(即系统缓存),如没有则进行下一步")]),t._v(" "),r("li",[t._v("2.向 "),r("strong",[t._v("localDNS")]),t._v(" (本地 DNS 服务器,一般是由 ISP 互联网服务提供商,例如联通、电信和移动提供)发起查询请求,如没有则 localDNS 会向根域名服务器发起查询请求。")]),t._v(" "),r("li",[t._v("3.根域名服务器会返回 .com 的顶级域名服务器地址")]),t._v(" "),r("li",[t._v("4.localDNS 向顶级域名服务器发起查询,顶级域名服务器返回 ."),r("a",{attrs:{href:"https://link.zhihu.com/?target=http%3A//baidu.com",target:"_blank",rel:"noopener noreferrer"}},[t._v("http://baidu.com"),r("OutboundLink")],1),t._v(" 的次级域名服务器地址")]),t._v(" "),r("li",[t._v("5.localDNS 向次级域名服务器发起查询,次级域名服务器返回 "),r("a",{attrs:{href:"https://link.zhihu.com/?target=http%3A//www.baidu.com",target:"_blank",rel:"noopener noreferrer"}},[t._v("http://www.baidu.com"),r("OutboundLink")],1),t._v(" 的 IP 地址")]),t._v(" "),r("li",[t._v("6.localDNS 记录缓存,并返回给客户端。")])]),t._v(" "),r("hr"),t._v(" "),r("h5",{attrs:{id:"国内-isp-localdns-问题"}},[r("a",{staticClass:"header-anchor",attrs:{href:"#国内-isp-localdns-问题"}},[t._v("#")]),t._v(" "),r("a",{attrs:{href:"https://cloud.tencent.com/developer/article/1367850",target:"_blank",rel:"noopener noreferrer"}},[t._v("国内 ISP LocalDNS 问题"),r("OutboundLink")],1)]),t._v(" "),r("ul",[r("li",[t._v("缓存问题\n"),r("ul",[r("li",[t._v("仅对 80 端口的http服务做了缓存")])])]),t._v(" "),r("li",[t._v("解析转发")]),t._v(" "),r("li",[t._v("出口 NAT 问题\n"),r("ol",[r("li",[t._v("network address transmit")])])]),t._v(" "),r("li",[t._v("域名更新问题")]),t._v(" "),r("li",[t._v("解析延迟问题\n"),r("ul",[r("li",[t._v("DNS 的查询过程需要递归遍历多个 DNS 服务器,才能获得最终的解析结果,这会带来一定的时延,甚至会解析超时。")])])])]),t._v(" "),r("h4",{attrs:{id:"dns-ttl"}},[r("a",{staticClass:"header-anchor",attrs:{href:"#dns-ttl"}},[t._v("#")]),t._v(" DNS TTL")]),t._v(" "),r("p",[t._v("TTL( Time-To-Live 生存时间),表示"),r("strong",[t._v("一条域名解析记录在 DNS 服务器上缓存时间")]),t._v("。当 DNS 服务器获得一条 DNS 解析记录后,会在 DNS 服务器中保存一段时间,这段时间内如果再接到这个域名的解析请求,DNS 服务器将不再发出解析请求,而是直接返回缓存的记录。")]),t._v(" "),r("hr"),t._v(" "),r("h4",{attrs:{id:"httpdns"}},[r("a",{staticClass:"header-anchor",attrs:{href:"#httpdns"}},[t._v("#")]),t._v(" HttpDNS")]),t._v(" "),r("p",[t._v("HttpDNS 原理只是将域名解析过程中向 localDNS 请求替换成了使用 Http 协议,向某个厂商的 HttpDNS 服务器发送请求,HttpDNS服务器返回 IP 地址,客户端将 ip 地址替换域名发送请求。目前腾讯、阿里等都有提供 HttpDNS 解析服务。")]),t._v(" "),r("p",[t._v("请求的方式是这样的。")]),t._v(" "),r("blockquote",[r("p",[t._v('curl http://106.2.xxx.xxx/d?dn=c.m.163.com\n{"dns":[{"host":"c.m.163.com","ips":["223.252.199.12"],"ttl":300,"http2":0}],"client":{"ip":"106.2.81.50","line":269692944}}')])]),t._v(" "),r("p",[t._v("手机客户端自然知道手机在哪个运营商、哪个地址。由于是直接的 HTTP 通信,HttpDNS 服务器能够准确知道这些信息,因而可以做精准的全局负载均衡。")]),t._v(" "),r("p",[r("img",{attrs:{src:"https://raw.githubusercontent.com/jacky1234/picArchieve/master/uPic/aa45cf8a07b563ccea376f712b2e8975-20210515183350636.jpg",alt:"img"}})]),t._v(" "),r("h5",{attrs:{id:"httpdns-的缓存设计"}},[r("a",{staticClass:"header-anchor",attrs:{href:"#httpdns-的缓存设计"}},[t._v("#")]),t._v(" HttpDNS 的缓存设计")]),t._v(" "),r("h5",{attrs:{id:"httpdns-的调度设计"}},[r("a",{staticClass:"header-anchor",attrs:{href:"#httpdns-的调度设计"}},[t._v("#")]),t._v(" HttpDNS 的调度设计")]),t._v(" "),r("hr"),t._v(" "),r("h2",{attrs:{id:"cdn"}},[r("a",{staticClass:"header-anchor",attrs:{href:"#cdn"}},[t._v("#")]),t._v(" CDN")]),t._v(" "),r("h4",{attrs:{id:"cname解析"}},[r("a",{staticClass:"header-anchor",attrs:{href:"#cname解析"}},[t._v("#")]),t._v(" CNAME解析")]),t._v(" "),r("p",[t._v("解析过程")]),t._v(" "),r("p",[r("img",{attrs:{src:"https://raw.githubusercontent.com/jacky1234/picArchieve/master/uPic/image-20210513145733309.png",alt:"image-20210513145733309"}})]),t._v(" "),r("h4",{attrs:{id:"cdn分发系统"}},[r("a",{staticClass:"header-anchor",attrs:{href:"#cdn分发系统"}},[t._v("#")]),t._v(" CDN分发系统")]),t._v(" "),r("p",[r("img",{attrs:{src:"https://static001.geekbang.org/resource/image/5f/25/5fbe602d9b85966d9a1748d2e6aa6425.jpeg",alt:"img"}})]),t._v(" "),r("h5",{attrs:{id:"客户端如何找到相应的边缘节点进行访问呢"}},[r("a",{staticClass:"header-anchor",attrs:{href:"#客户端如何找到相应的边缘节点进行访问呢"}},[t._v("#")]),t._v(" 客户端如何找到相应的边缘节点进行访问呢?")]),t._v(" "),r("p",[r("img",{attrs:{src:"https://raw.githubusercontent.com/jacky1234/picArchieve/master/uPic/c4d826188e664605d6f8dfb82e348824.jpeg",alt:"img"}})]),t._v(" "),r("p",[r("em",[t._v("详情见: 极客时间")])])])}),[],!1,null,null,null);r.default=n.exports}}]); \ No newline at end of file diff --git a/assets/js/73.c224c877.js b/assets/js/73.c224c877.js new file mode 100644 index 0000000000..d2b8882af7 --- /dev/null +++ b/assets/js/73.c224c877.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[73],{399:function(t,r,e){"use strict";e.r(r);var n=e(4),o=Object(n.a)({},(function(){var t=this,r=t._self._c;return r("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[r("h1",{attrs:{id:"okhttp"}},[r("a",{staticClass:"header-anchor",attrs:{href:"#okhttp"}},[t._v("#")]),t._v(" OkHttp")]),t._v(" "),r("p",[t._v("链接")]),t._v(" "),r("p",[t._v("​\t1. "),r("a",{attrs:{href:"https://github.com/ad-ppp/OkHttpStudy",target:"_blank",rel:"noopener noreferrer"}},[t._v("OkHttpStudyDemo"),r("OutboundLink")],1)]),t._v(" "),r("hr")])}),[],!1,null,null,null);r.default=o.exports}}]); \ No newline at end of file diff --git a/assets/js/74.677ebc29.js b/assets/js/74.677ebc29.js new file mode 100644 index 0000000000..885ca03225 --- /dev/null +++ b/assets/js/74.677ebc29.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[74],{400:function(t,r,e){"use strict";e.r(r);var l=e(4),n=Object(l.a)({},(function(){var t=this,r=t._self._c;return r("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[r("h3",{attrs:{id:"请求速度优化"}},[r("a",{staticClass:"header-anchor",attrs:{href:"#请求速度优化"}},[t._v("#")]),t._v(" 请求速度优化")]),t._v(" "),r("ul",[r("li",[t._v("DNS 优化")]),t._v(" "),r("li",[t._v("连接优化\n"),r("ul",[r("li",[t._v("复用连接。keep-alive")]),t._v(" "),r("li",[t._v("多路复用。Http1.1 VS Http2")]),t._v(" "),r("li",[t._v("TCP 对头阻塞")])])]),t._v(" "),r("li",[t._v("数据压缩\n"),r("ul",[r("li",[r("a",{attrs:{href:"http://www.52im.net/thread-323-1-1.html",target:"_blank",rel:"noopener noreferrer"}},[t._v("Protobuf vs Json"),r("OutboundLink")],1),t._v(" "),r("ul",[r("li",[t._v("Protobuf 采用 varint 编码")]),t._v(" "),r("li",[t._v("解封包速度")])])])])])]),t._v(" "),r("h2",{attrs:{id:"参考"}},[r("a",{staticClass:"header-anchor",attrs:{href:"#参考"}},[t._v("#")]),t._v(" 参考")]),t._v(" "),r("ul",[r("li",[r("a",{attrs:{href:"http://www.52im.net/thread-1413-1-1.html",target:"_blank",rel:"noopener noreferrer"}},[t._v("现代移动端网络短连接的优化手段总结:请求速度、弱网适应、安全保障"),r("OutboundLink")],1)])])])}),[],!1,null,null,null);r.default=n.exports}}]); \ No newline at end of file diff --git a/assets/js/75.c11411fc.js b/assets/js/75.c11411fc.js new file mode 100644 index 0000000000..4f4cea6bd2 --- /dev/null +++ b/assets/js/75.c11411fc.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[75],{401:function(t,e,a){"use strict";a.r(e);var r=a(4),s=Object(r.a)({},(function(){var t=this,e=t._self._c;return e("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[e("h2",{attrs:{id:"websocket"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#websocket"}},[t._v("#")]),t._v(" WebSocket")]),t._v(" "),e("blockquote",[e("p",[t._v("WebSocket,下层和 HTTP 一样也是基于 TCP 协议,是一种轻量级网络通信协议,也属于应用层协议。")]),t._v(" "),e("p",[t._v('WebSocket 与 HTTP/2 一样,其实都是为了解决 HTTP/1.1 的一些缺陷而诞生的,而 WebSocket 针对的就是「请求-应答」这种"半双工"的模式的通信缺陷。')])]),t._v(" "),e("h3",{attrs:{id:"附件"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#附件"}},[t._v("#")]),t._v(" 附件")]),t._v(" "),e("ul",[e("li",[e("a",{attrs:{href:"https://github.com/ad-ppp/WsManager",target:"_blank",rel:"noopener noreferrer"}},[t._v("基于Okhttp的WebSocket示例-WsManager"),e("OutboundLink")],1)]),t._v(" "),e("li",[e("a",{attrs:{href:"https://cloud.tencent.com/developer/article/1719385",target:"_blank",rel:"noopener noreferrer"}},[t._v("使用Android WebSocket实现即时通讯功能"),e("OutboundLink")],1)])]),t._v(" "),e("h2",{attrs:{id:"socket"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#socket"}},[t._v("#")]),t._v(" Socket")]),t._v(" "),e("blockquote",[e("p",[t._v("网络中的 Socket 并不是什么协议,而是为了使用 TCP,UDP 而抽象出来的一层 API,它是位于应用层和传输层之间的一个抽象层。")])]),t._v(" "),e("hr"),t._v(" "),e("h3",{attrs:{id:"常见问题汇总"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#常见问题汇总"}},[t._v("#")]),t._v(" 常见问题汇总")]),t._v(" "),e("h4",{attrs:{id:"半包-粘包与分包"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#半包-粘包与分包"}},[t._v("#")]),t._v(" 半包,粘包与分包")]),t._v(" "),e("p",[t._v("一个包没有固定长度,以太网限制在46-1500字节,1500就是以太网的MTU,超过这个量,TCP会为IP数据报设置偏移量进行分片传输,现在一般可允许应用层设置8k(NTFS系)的缓冲区,8k的数据由底层分片,而应用看来只是一次发送。windows的缓冲区经验值是4k,Socket本身分为两种,流(TCP)和数据报(UDP),你的问题针对这两种不同使用而结论不一样。甚至还和你是用阻塞、还是非阻塞Socket来编程有关.\n注意一点,你无论发多大的包,IP层和链路层都会把你的包进行分片发送,一般局域网就是1500左右")]),t._v(" "),e("h4",{attrs:{id:"tcp的三次握手与四次挥手"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#tcp的三次握手与四次挥手"}},[t._v("#")]),t._v(" TCP的三次握手与四次挥手")]),t._v(" "),e("p",[e("a",{attrs:{href:"https://www.huaweicloud.com/articles/eedcc3d1fe20c890bfa0c960781f0ab1.html",target:"_blank",rel:"noopener noreferrer"}},[t._v("内容来自华为云分析"),e("OutboundLink")],1)]),t._v(" "),e("p",[e("img",{attrs:{src:"https://raw.githubusercontent.com/jacky1234/picArchieve/master/uPic/0c6f5dc04e337b1c6deb57e82a9210d71603427626959.jpeg",alt:"TCP协议:三次握手、四次挥手过程详解1"}})]),t._v(" "),e("h5",{attrs:{id:"三次握手建立连接"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#三次握手建立连接"}},[t._v("#")]),t._v(" 三次握手建立连接")]),t._v(" "),e("p",[t._v("第一次握手:客户端发送syn包(seq=x)到服务器,并进入SYN_SEND状态,等待服务器确认;")]),t._v(" "),e("p",[t._v("第二次握手:服务器收到syn包,必须确认客户的SYN(ack=x+1),同时自己也发送一个SYN包(seq=y),即SYN+ACK包,此时服务器进入SYN_RECV状态;")]),t._v(" "),e("p",[t._v("第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=y+1),此包发送完毕,客户端和服务器进入ESTABLISHED状态,完成三次握手。")]),t._v(" "),e("p",[t._v("握手过程中传送的包里不包含数据,三次握手完毕后,客户端与服务器才正式开始传送数据。理想状态下,TCP连接一旦建立,在通信双方中的任何一方主动关闭连接之前,TCP 连接都将被一直保持下去。")]),t._v(" "),e("p",[e("strong",[t._v("传输数据过程:")])]),t._v(" "),e("p",[t._v("a.超时重传超时重传机制用来保证TCP传输的可靠性。每次发送数据包时,发送的数据报都有seq号,接收端收到数据后,会回复ack进行确认,表示某一seq 号数据已经收到。发送方在发送了某个seq包后,等待一段时间,如果没有收到对应的ack回复,就会认为报文丢失,会重传这个数据包。")]),t._v(" "),e("p",[t._v("b."),e("strong",[t._v("快速重传")]),t._v("接受数据一方发现有数据包丢掉了。就会发送ack报文告诉发送端重传丢失的报文。如果发送端连续收到标号相同的ack包,则会触发客户端的快速重 传。比较超时重传和快速重传,可以发现超时重传是发送端在傻等超时,然后触发重传;而快速重传则是接收端主动告诉发送端数据没收到,然后触发发送端重传。")]),t._v(" "),e("p",[t._v("c.流量控制这里主要说"),e("strong",[t._v("TCP滑动窗流量控制")]),t._v("。TCP头里有一个字段叫Window,又叫Advertised-Window,这个字段是接收端告诉发送端自己 还有多少缓冲区可以接收数据。于是发送端就可以根据这个接收端的处理能力来发送数据,而不会导致接收端处理不过来。 滑动窗可以是提高TCP传输效率的一种机制。")]),t._v(" "),e("p",[t._v("d.拥塞控制滑动窗用来做流量控制。流量控制只关注发送端和接受端自身的状况,而没有考虑整个网络的通信情况。拥塞控制,则是基于整个网络来考虑的。考虑一下这 样的场景:某一时刻网络上的延时突然增加,那么,TCP对这个事做出的应对只有重传数据,但是,重传会导致网络的负担更重,于是会导致更大的延迟以及更多 的丢包,于是,这个情况就会进入恶性循环被不断地放大。试想一下,如果一个网络内有成千上万的TCP连接都这么行事,那么马上就会形成“网络风 暴”,TCP这个协议就会拖垮整个网络。为此,"),e("strong",[t._v("TCP引入了拥塞控制策略")]),t._v("。拥塞策略算法主要包括:慢启动,拥塞避免,拥塞发生,快速恢复。")]),t._v(" "),e("h5",{attrs:{id:"四次握手断开连接"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#四次握手断开连接"}},[t._v("#")]),t._v(" 四次握手断开连接")]),t._v(" "),e("p",[t._v("第一次挥手:主动关闭方发送一个FIN,用来关闭主动方到被动关闭方的数据传送,也就是主动关闭方告诉被动关闭方:我已经不会再给你发数据了(当 然,在fin包之前发送出去的数据,如果没有收到对应的ack确认报文,主动关闭方依然会重发这些数据),但此时主动关闭方还可以接受数据。")]),t._v(" "),e("p",[t._v("第二次挥手:被动关闭方收到FIN包后,发送一个ACK给对方,确认序号为收到序号+1(与SYN相同,一个FIN占用一个序号)。")]),t._v(" "),e("p",[t._v("第三次挥手:被动关闭方发送一个FIN,用来关闭被动关闭方到主动关闭方的数据传送,也就是告诉主动关闭方,我的数据也发送完了,不会再给你发数据了。")]),t._v(" "),e("p",[t._v("第四次挥手:主动关闭方收到FIN后,发送一个ACK给被动关闭方,确认序号为收到序号+1,至此,完成四次挥手。")]),t._v(" "),e("hr"),t._v(" "),e("h2",{attrs:{id:"websocket-与-socket-区别"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#websocket-与-socket-区别"}},[t._v("#")]),t._v(" WebSocket 与 Socket 区别")]),t._v(" "),e("ol",[e("li",[t._v("Socket 是传输控制层的接口。用户可以通过 Socket 来操作底层 TCP/IP 协议族通信。")]),t._v(" "),e("li",[t._v("WebSocket 是一个完整应用层协议。")]),t._v(" "),e("li",[t._v("Socket 更灵活,WebSocket 更易用。")]),t._v(" "),e("li",[t._v("两者都能做即时通讯")])])])}),[],!1,null,null,null);e.default=s.exports}}]); \ No newline at end of file diff --git a/assets/js/76.60639833.js b/assets/js/76.60639833.js new file mode 100644 index 0000000000..de33e4f670 --- /dev/null +++ b/assets/js/76.60639833.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[76],{402:function(t,n,r){"use strict";r.r(n);var e=r(4),s=Object(e.a)({},(function(){var t=this._self._c;return t("ContentSlotsDistributor",{attrs:{"slot-key":this.$parent.slotKey}},[t("h2",{attrs:{id:"link"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#link"}},[this._v("#")]),this._v(" link")]),this._v(" "),t("ul",[t("li",[t("a",{attrs:{href:"https://github.com/jacky1234/learnC",target:"_blank",rel:"noopener noreferrer"}},[this._v("learnC"),t("OutboundLink")],1)])])])}),[],!1,null,null,null);n.default=s.exports}}]); \ No newline at end of file diff --git a/assets/js/77.406dc39c.js b/assets/js/77.406dc39c.js new file mode 100644 index 0000000000..fa9b281432 --- /dev/null +++ b/assets/js/77.406dc39c.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[77],{403:function(s,n,a){"use strict";a.r(n);var e=a(4),t=Object(e.a)({},(function(){var s=this,n=s._self._c;return n("ContentSlotsDistributor",{attrs:{"slot-key":s.$parent.slotKey}},[n("h1",{attrs:{id:"编译和内存相关"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#编译和内存相关"}},[s._v("#")]),s._v(" 编译和内存相关")]),s._v(" "),n("p",[s._v("本章是 C++ 面经的开章之作,其中涉及 C++ 程序的编译过程、内存以及头文件的一些知识点,重点在内存方面进行展开,包括内存的分区、内存对齐、内存泄漏、内存泄漏的防止方法、现有的检测内存泄漏的工具等等。由于问题之间的关联性,可能有些问题并非是本章相关的知识点,例如一些问题涉及到了类中的虚函数、创建类的对象的底层原理等等,但为了保持问题上下的连贯性,也放在了本章,便于问题的理解。")]),s._v(" "),n("h2",{attrs:{id:"c-程序编译过程"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#c-程序编译过程"}},[s._v("#")]),s._v(" C++ 程序编译过程")]),s._v(" "),n("p",[n("strong",[s._v("面试高频指数:★★★★☆")]),s._v(" "),n("strong",[s._v("编译过程分为四个过程:编译(编译预处理、编译、优化),汇编,链接。")])]),s._v(" "),n("ul",[n("li",[n("strong",[s._v("编译预处理")]),s._v(":处理以 # 开头的指令;")]),s._v(" "),n("li",[n("strong",[s._v("编译、优化")]),s._v(":将源码 .cpp 文件翻译成 .s 汇编代码;")]),s._v(" "),n("li",[n("strong",[s._v("汇编")]),s._v(":将汇编代码 .s 翻译成机器指令 .o 文件;")]),s._v(" "),n("li",[n("strong",[s._v("链接")]),s._v(":汇编程序生成的目标文件,即 .o 文件,并不会立即执行,因为可能会出现:.cpp 文件中的函数引用了另一个 .cpp 文件中定义的符号或者调用了某个库文件中的函数。那链接的目的就是将这些文件对应的目标文件连接成一个整体,从而生成可执行的程序 .exe 文件。")])]),s._v(" "),n("p",[n("img",{attrs:{src:"https://cdn.jsdelivr.net/gh/jacky1234/picArchieve@master/uPic/20230522_135119_rGgam9.png",alt:"image.png"}})]),s._v(" "),n("p",[n("strong",[s._v("链接分为两种:")])]),s._v(" "),n("ul",[n("li",[n("strong",[s._v("静态链接")]),s._v(":代码从其所在的静态链接库中拷贝到最终的可执行程序中,在该程序被执行时,这些代码会被装入到该进程的虚拟地址空间中。")]),s._v(" "),n("li",[n("strong",[s._v("动态链接")]),s._v(":代码被放到动态链接库或共享对象的某个目标文件中,链接程序只是在最终的可执行程序中记录了共享对象的名字等一些信息。在程序执行时,动态链接库的全部内容会被映射到运行时相应进行的虚拟地址的空间。")])]),s._v(" "),n("p",[n("strong",[s._v("二者的优缺点:")])]),s._v(" "),n("ul",[n("li",[n("strong",[s._v("静态链接")]),s._v(":浪费空间,每个可执行程序都会有目标文件的一个副本,这样如果目标文件进行了更新操作,就需要重新进行编译链接生成可执行程序(更新困难);优点就是执行的时候运行速度快,因为可执行程序具备了程序运行的所有内容。")]),s._v(" "),n("li",[n("strong",[s._v("动态链接")]),s._v(":节省内存、更新方便,但是动态链接是在程序运行时,每次执行都需要链接,相比静态链接会有一定的性能损失。")])]),s._v(" "),n("h2",{attrs:{id:"c-内存管理"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#c-内存管理"}},[s._v("#")]),s._v(" C++ 内存管理")]),s._v(" "),n("p",[n("strong",[s._v("面试高频指数:★★★★★")]),s._v(" "),n("strong",[s._v("C++ 内存分区:栈、堆、全局/静态存储区、常量存储区、代码区。")])]),s._v(" "),n("ul",[n("li",[n("strong",[s._v("栈")]),s._v(":存放函数的局部变量、函数参数、返回地址等,由编译器自动分配和释放。")]),s._v(" "),n("li",[n("strong",[s._v("堆")]),s._v(":动态申请的内存空间,就是由 malloc 分配的内存块,由程序员控制它的分配和释放,如果程序执行结束还没有释放,操作系统会自动回收。")]),s._v(" "),n("li",[n("strong",[s._v("全局区/静态存储区(.bss 段和 .data 段")]),s._v("):存放全局变量和静态变量,程序运行结束操作系统自动释放,在 C 语言中,未初始化的放在 .bss 段中,初始化的放在 .data 段中,C++ 中不再区分了。")]),s._v(" "),n("li",[n("strong",[s._v("常量存储区(.data 段)")]),s._v(":存放的是常量,不允许修改,程序运行结束自动释放。")]),s._v(" "),n("li",[n("strong",[s._v("代码区(.text 段)")]),s._v(":存放代码,不允许修改,但可以执行。编译后的二进制文件存放在这里。")])]),s._v(" "),n("p",[s._v("**说明:**从操作系统的本身来讲,以上存储区在内存中的分布是如下形式(从低地址到高地址):.text 段 --\x3e .data 段 --\x3e .bss 段 --\x3e 堆 --\x3e unused --\x3e 栈 --\x3e env\n程序实例:")]),s._v(" "),n("div",{staticClass:"language-c++ line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v('#include \nusing namespace std;\n\n/*\n说明:C++ 中不再区分初始化和未初始化的全局变量、静态变量的存储区,如果非要区分下述程序标注在了括号中\n*/\n\nint g_var = 0; // g_var 在全局区(.data 段)\nchar *gp_var; // gp_var 在全局区(.bss 段)\n\nint main()\n{\n int var; // var 在栈区\n char *p_var; // p_var 在栈区\n char arr[] = "abc"; // arr 为数组变量,存储在栈区;"abc"为字符串常量,存储在常量区\n char *p_var1 = "123456"; // p_var1 在栈区;"123456"为字符串常量,存储在常量区\n static int s_var = 0; // s_var 为静态变量,存在静态存储区(.data 段)\n p_var = (char *)malloc(10); // 分配得来的 10 个字节的区域在堆区\n free(p_var);\n return 0;\n}\n')])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br"),n("span",{staticClass:"line-number"},[s._v("8")]),n("br"),n("span",{staticClass:"line-number"},[s._v("9")]),n("br"),n("span",{staticClass:"line-number"},[s._v("10")]),n("br"),n("span",{staticClass:"line-number"},[s._v("11")]),n("br"),n("span",{staticClass:"line-number"},[s._v("12")]),n("br"),n("span",{staticClass:"line-number"},[s._v("13")]),n("br"),n("span",{staticClass:"line-number"},[s._v("14")]),n("br"),n("span",{staticClass:"line-number"},[s._v("15")]),n("br"),n("span",{staticClass:"line-number"},[s._v("16")]),n("br"),n("span",{staticClass:"line-number"},[s._v("17")]),n("br"),n("span",{staticClass:"line-number"},[s._v("18")]),n("br"),n("span",{staticClass:"line-number"},[s._v("19")]),n("br"),n("span",{staticClass:"line-number"},[s._v("20")]),n("br"),n("span",{staticClass:"line-number"},[s._v("21")]),n("br")])]),n("h2",{attrs:{id:"栈和堆的区别"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#栈和堆的区别"}},[s._v("#")]),s._v(" 栈和堆的区别")]),s._v(" "),n("p",[n("strong",[s._v("面试高频指数:★★★★★")])]),s._v(" "),n("ul",[n("li",[s._v("**申请方式:**栈是系统自动分配,堆是程序员主动申请。")]),s._v(" "),n("li",[s._v("**申请后系统响应:**分配栈空间,如果剩余空间大于申请空间则分配成功,否则分配失败栈溢出;申请堆空间,堆在内存中呈现的方式类似于链表(记录空闲地址空间的链表),在链表上寻找第一个大于申请空间的节点分配给程序,将该节点从链表中删除,大多数系统中该块空间的首地址存放的是本次分配空间的大小,便于释放,将该块空间上的剩余空间再次连接在空闲链表上。")]),s._v(" "),n("li",[n("strong",[s._v("栈在内存中是连续的一块空间")]),s._v("(向低地址扩展)最大容量是系统预定好的,堆在内存中的空间(向高地址扩展)是不连续的。")]),s._v(" "),n("li",[s._v("**申请效率:**栈是有系统自动分配,申请效率高,但程序员无法控制;堆是由程序员主动申请,效率低,使用起来方便但是容易产生碎片。")]),s._v(" "),n("li",[s._v("**存放的内容:**栈中存放的是局部变量,函数的参数;堆中存放的内容由程序员控制。")])]),s._v(" "),n("h2",{attrs:{id:"变量的区别"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#变量的区别"}},[s._v("#")]),s._v(" 变量的区别")]),s._v(" "),n("p",[n("strong",[s._v("面试高频指数:★★★☆☆")])]),s._v(" "),n("p",[n("strong",[s._v("全局变量、局部变量、静态全局变量、静态局部变量的区别")])]),s._v(" "),n("p",[s._v("C++ 变量根据定义的位置的不同的生命周期,具有不同的作用域,作用域可分为 6 种:全局作用域,局部作用域,语句作用域,类作用域,命名空间作用域和文件作用域。")]),s._v(" "),n("p",[s._v("从作用域看:")]),s._v(" "),n("ul",[n("li",[s._v("**全局变量:**具有全局作用域。全局变量只需在一个源文件中定义,就可以作用于所有的源文件。当然,其他不包含全局变量定义的源文件需要用 extern 关键字再次声明这个全局变量。")]),s._v(" "),n("li",[s._v("**静态全局变量:**具有文件作用域。它与全局变量的区别在于如果程序包含多个文件的话,它作用于定义它的文件里,不能作用到其它文件里,即被 static 关键字修饰过的变量具有文件作用域。这样即使两个不同的源文件都定义了相同名字的静态全局变量,它们也是不同的变量。")]),s._v(" "),n("li",[s._v("**局部变量:**具有局部作用域。它是自动对象(auto),在程序运行期间不是一直存在,而是只在函数执行期间存在,函数的一次调用执行结束后,变量被撤销,其所占用的内存也被收回。")]),s._v(" "),n("li",[s._v("**静态局部变量:**具有局部作用域。它只被初始化一次,自从第一次被初始化直到程序运行结束都一直存在,它和全局变量的区别在于全局变量对所有的函数都是可见的,而静态局部变量只对定义自己的函数体始终可见。")])]),s._v(" "),n("p",[s._v("从分配内存空间看:")]),s._v(" "),n("ul",[n("li",[s._v("静态存储区:全局变量,静态局部变量,静态全局变量。")]),s._v(" "),n("li",[s._v("栈:局部变量。")])]),s._v(" "),n("p",[s._v("说明:")]),s._v(" "),n("ul",[n("li",[s._v("静态变量和栈变量(存储在栈中的变量)、堆变量(存储在堆中的变量)的区别:静态变量会被放在程序的静态数据存储区(.data 段)中(静态变量会自动初始化),这样可以在下一次调用的时候还可以保持原来的赋值。而栈变量或堆变量不能保证在下一次调用的时候依然保持原来的值。")]),s._v(" "),n("li",[s._v("静态变量和全局变量的区别:静态变量用 static 告知编译器,自己仅仅在变量的作用范围内可见。")])]),s._v(" "),n("h2",{attrs:{id:"全局变量定义在头文件中有什么问题"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#全局变量定义在头文件中有什么问题"}},[s._v("#")]),s._v(" 全局变量定义在头文件中有什么问题?")]),s._v(" "),n("p",[n("strong",[s._v("面试高频指数:★☆☆☆☆")]),s._v("\n如果在头文件中定义全局变量,当该头文件被多个文件 include 时,该头文件中的全局变量就会被定义多次,导致重复定义,因此不能再头文件中定义全局变量。")]),s._v(" "),n("h2",{attrs:{id:"对象创建限制在堆或栈"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#对象创建限制在堆或栈"}},[s._v("#")]),s._v(" 对象创建限制在堆或栈")]),s._v(" "),n("p",[n("strong",[s._v("面试高频指数:★★★☆☆")])]),s._v(" "),n("p",[n("strong",[s._v("如何限制类的对象只能在堆上创建?如何限制对象只能在栈上创建?")]),s._v("\n说明:C++ 中的类的对象的建立分为两种:静态建立、动态建立。")]),s._v(" "),n("ul",[n("li",[s._v("**静态建立:**由编译器为对象在栈空间上分配内存,直接调用类的构造函数创建对象。例如:A a;")]),s._v(" "),n("li",[s._v("**动态建立:**使用 new 关键字在堆空间上创建对象,底层首先调用 operator new() 函数,在堆空间上寻找合适的内存并分配;然后,调用类的构造函数创建对象。例如:A *p = new A();")])]),s._v(" "),n("p",[n("strong",[s._v("限制对象只能建立在堆上:")])]),s._v(" "),n("ul",[n("li",[n("p",[s._v("最直观的思想:避免直接调用类的构造函数,因为对象静态建立时,会调用类的构造函数创建对象。但是直接将类的构造函数设为私有并不可行,因为当构造函数设置为私有后,不能在类的外部调用构造函数来构造对象,只能用 new 来建立对象。但是由于 new 创建对象时,底层也会调用类的构造函数,将构造函数设置为私有后,那就无法在类的外部使用 new 创建对象了。因此,这种方法不可行。")])]),s._v(" "),n("li",[n("p",[s._v("解决方法 1:")]),s._v(" "),n("ul",[n("li",[n("p",[s._v("将析构函数设置为私有。原因:静态对象建立在栈上,是由编译器分配和释放内存空间,编译器为对象分配内存空间时,会对类的非静态函数进行检查,即编译器会检查析构函数的访问性。当析构函数设为私有时,编译器创建的对象就无法通过访问析构函数来释放对象的内存空间,因此,编译器不会在栈上为对象分配内存。")]),s._v(" "),n("div",{staticClass:"language-c++ line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v("class A\n{\npublic:\n A() {}\n void destory()\n {\n delete this;\n }\n\nprivate:\n ~A()\n {\n }\n};\n")])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br"),n("span",{staticClass:"line-number"},[s._v("8")]),n("br"),n("span",{staticClass:"line-number"},[s._v("9")]),n("br"),n("span",{staticClass:"line-number"},[s._v("10")]),n("br"),n("span",{staticClass:"line-number"},[s._v("11")]),n("br"),n("span",{staticClass:"line-number"},[s._v("12")]),n("br"),n("span",{staticClass:"line-number"},[s._v("13")]),n("br"),n("span",{staticClass:"line-number"},[s._v("14")]),n("br")])])]),s._v(" "),n("li",[n("p",[s._v("用 new 创建的对象,通常会使用 delete 释放该对象的内存空间,但此时类的外部无法调用析构函数,因此类内必须定义一个 destory() 函数,用来释放 new 创建的对象。")])]),s._v(" "),n("li",[n("p",[s._v("无法解决继承问题,因为如果这个类作为基类,析构函数要设置成 virtual,然后在派生类中重写该函数,来实现多态。但此时,析构函数是私有的,派生类中无法访问。")])])])]),s._v(" "),n("li",[n("p",[s._v("解决方法 2:")]),s._v(" "),n("ul",[n("li",[n("p",[s._v("构造函数设置为 protected,并提供一个 public 的静态函数来完成构造,而不是在类的外部使用 new 构造;将析构函数设置为 protected。原因:类似于单例模式,也保证了在派生类中能够访问析构函数。通过调用 create() 函数在堆上创建对象。")]),s._v(" "),n("div",{staticClass:"language-c++ line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v("class A\n{\nprotected:\n A() {}\n ~A() {}\n\npublic:\n static A *create()\n {\n return new A();\n }\n void destory()\n {\n delete this;\n }\n};\n")])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br"),n("span",{staticClass:"line-number"},[s._v("8")]),n("br"),n("span",{staticClass:"line-number"},[s._v("9")]),n("br"),n("span",{staticClass:"line-number"},[s._v("10")]),n("br"),n("span",{staticClass:"line-number"},[s._v("11")]),n("br"),n("span",{staticClass:"line-number"},[s._v("12")]),n("br"),n("span",{staticClass:"line-number"},[s._v("13")]),n("br"),n("span",{staticClass:"line-number"},[s._v("14")]),n("br"),n("span",{staticClass:"line-number"},[s._v("15")]),n("br"),n("span",{staticClass:"line-number"},[s._v("16")]),n("br")])])])])])]),s._v(" "),n("p",[n("strong",[s._v("限制对象只能建立在栈上:")])]),s._v(" "),n("ul",[n("li",[n("p",[s._v("解决方法:将 operator new() 设置为私有。原因:当对象建立在堆上时,是采用 new 的方式进行建立,其底层会调用 operator new() 函数,因此只要对该函数加以限制,就能够防止对象建立在堆上。")]),s._v(" "),n("div",{staticClass:"language-c++ line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v("class A\n{\nprivate:\n void *operator new(size_t t) {} // 注意函数的第一个参数和返回值都是固定的\n void operator delete(void *ptr) {} // 重载了 new 就需要重载 delete\npublic:\n A() {}\n ~A() {}\n};\n")])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br"),n("span",{staticClass:"line-number"},[s._v("8")]),n("br"),n("span",{staticClass:"line-number"},[s._v("9")]),n("br")])])])]),s._v(" "),n("h2",{attrs:{id:"内存对齐"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#内存对齐"}},[s._v("#")]),s._v(" 内存对齐")]),s._v(" "),n("p",[n("strong",[s._v("面试高频指数:★★☆☆☆")]),s._v(" "),n("strong",[s._v("什么是内存对齐?内存对齐的原则?为什么要进行内存对齐,有什么优点?")])]),s._v(" "),n("p",[s._v("内存对齐:编译器将程序中的每个“数据单元”安排在字的整数倍的地址指向的内存之中\n内存对齐的原则:")]),s._v(" "),n("ol",[n("li",[n("p",[s._v("结构体变量的首地址能够被其最宽基本类型成员大小与对齐基数中的较小者所整除;")])]),s._v(" "),n("li",[n("p",[s._v("结构体每个成员相对于结构体首地址的偏移量 (offset) 都是该成员大小与对齐基数中的较小者的整数倍,如有需要编译器会在成员之间加上填充字节 (internal padding);")])]),s._v(" "),n("li",[n("p",[s._v("结构体的总大小为结构体最宽基本类型成员大小与对齐基数中的较小者的整数倍,如有需要编译器会在最末一个成员之后加上填充字节 (trailing padding)。")])])]),s._v(" "),n("p",[s._v("实例:")]),s._v(" "),n("div",{staticClass:"language-c++ line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v("/*\n说明:程序是在 64 位编译器下测试的\n*/\n#include \n\nusing namespace std;\n\nstruct A\n{\n short var; // 2 字节\n int var1; // 8 字节 (内存对齐原则:填充 2 个字节) 2 (short) + 2 (填充) + 4 (int)= 8\n long var2; // 12 字节 8 + 4 (long) = 12\n char var3; // 16 字节 (内存对齐原则:填充 3 个字节)12 + 1 (char) + 3 (填充) = 16\n string s; // 48 字节 16 + 32 (string) = 48\n};\n\nint main()\n{\n short var;\n int var1;\n long var2;\n char var3;\n string s;\n A ex1;\n cout << sizeof(var) << endl; // 2 short\n cout << sizeof(var1) << endl; // 4 int\n cout << sizeof(var2) << endl; // 4 long\n cout << sizeof(var3) << endl; // 1 char\n cout << sizeof(s) << endl; // 32 string\n cout << sizeof(ex1) << endl; // 48 struct\n return 0;\n}\n")])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br"),n("span",{staticClass:"line-number"},[s._v("8")]),n("br"),n("span",{staticClass:"line-number"},[s._v("9")]),n("br"),n("span",{staticClass:"line-number"},[s._v("10")]),n("br"),n("span",{staticClass:"line-number"},[s._v("11")]),n("br"),n("span",{staticClass:"line-number"},[s._v("12")]),n("br"),n("span",{staticClass:"line-number"},[s._v("13")]),n("br"),n("span",{staticClass:"line-number"},[s._v("14")]),n("br"),n("span",{staticClass:"line-number"},[s._v("15")]),n("br"),n("span",{staticClass:"line-number"},[s._v("16")]),n("br"),n("span",{staticClass:"line-number"},[s._v("17")]),n("br"),n("span",{staticClass:"line-number"},[s._v("18")]),n("br"),n("span",{staticClass:"line-number"},[s._v("19")]),n("br"),n("span",{staticClass:"line-number"},[s._v("20")]),n("br"),n("span",{staticClass:"line-number"},[s._v("21")]),n("br"),n("span",{staticClass:"line-number"},[s._v("22")]),n("br"),n("span",{staticClass:"line-number"},[s._v("23")]),n("br"),n("span",{staticClass:"line-number"},[s._v("24")]),n("br"),n("span",{staticClass:"line-number"},[s._v("25")]),n("br"),n("span",{staticClass:"line-number"},[s._v("26")]),n("br"),n("span",{staticClass:"line-number"},[s._v("27")]),n("br"),n("span",{staticClass:"line-number"},[s._v("28")]),n("br"),n("span",{staticClass:"line-number"},[s._v("29")]),n("br"),n("span",{staticClass:"line-number"},[s._v("30")]),n("br"),n("span",{staticClass:"line-number"},[s._v("31")]),n("br"),n("span",{staticClass:"line-number"},[s._v("32")]),n("br")])]),n("p",[s._v("进行内存对齐的原因:(主要是硬件设备方面的问题)")]),s._v(" "),n("ol",[n("li",[n("p",[s._v("某些硬件设备只能存取对齐数据,存取非对齐的数据可能会引发异常;")])]),s._v(" "),n("li",[n("p",[s._v("某些硬件设备不能保证在存取非对齐数据的时候的操作是原子操作;")])]),s._v(" "),n("li",[n("p",[s._v("相比于存取对齐的数据,存取非对齐的数据需要花费更多的时间;")])]),s._v(" "),n("li",[n("p",[s._v("某些处理器虽然支持非对齐数据的访问,但会引发对齐陷阱(alignment trap);")])]),s._v(" "),n("li",[n("p",[s._v("某些硬件设备只支持简单数据指令非对齐存取,不支持复杂数据指令的非对齐存取。")])])]),s._v(" "),n("p",[s._v("内存对齐的优点:")]),s._v(" "),n("ol",[n("li",[n("p",[s._v("便于在不同的平台之间进行移植,因为有些硬件平台不能够支持任意地址的数据访问,只能在某些地址处取某些特定的数据,否则会抛出异常;")])]),s._v(" "),n("li",[n("p",[s._v("提高内存的访问效率,因为 CPU 在读取内存时,是一块一块的读取。")])])]),s._v(" "),n("h2",{attrs:{id:"类的大小"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#类的大小"}},[s._v("#")]),s._v(" 类的大小")]),s._v(" "),n("p",[n("strong",[s._v("面试高频指数:★★☆☆☆")]),s._v(" "),n("strong",[s._v("类大小的计算")]),s._v("\n说明:类的大小是指类的实例化对象的大小,用 sizeof 对类型名操作时,结果是该类型的对象的大小。\n计算原则:")]),s._v(" "),n("ul",[n("li",[n("p",[s._v("遵循结构体的对齐原则。")])]),s._v(" "),n("li",[n("p",[s._v("与普通成员变量有关,与成员函数和静态成员无关。即普通成员函数,静态成员函数,静态数据成员,静态常量数据成员均对类的大小无影响。因为静态数据成员被类的对象共享,并不属于哪个具体的对象。")])]),s._v(" "),n("li",[n("p",[s._v("虚函数对类的大小有影响,是因为虚函数表指针的影响。")])]),s._v(" "),n("li",[n("p",[s._v("虚继承对类的大小有影响,是因为虚基表指针带来的影响。")])]),s._v(" "),n("li",[n("p",[s._v("空类的大小是一个特殊情况,空类的大小为 1,当用 new 来创建一个空类的对象时,为了保证不同对象的地址不同,空类也占用存储空间。")])])]),s._v(" "),n("p",[n("strong",[s._v("实例")]),s._v(":\n简单情况和空类情况")]),s._v(" "),n("div",{staticClass:"language-c++ line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v("/*\n说明:程序是在 64 位编译器下测试的\n*/\n#include \n\nusing namespace std;\n\nclass A\n{\nprivate:\n static int s_var; // 不影响类的大小\n const int c_var; // 4 字节\n int var; // 8 字节 4 + 4 (int) = 8\n char var1; // 12 字节 8 + 1 (char) + 3 (填充) = 12\npublic:\n A(int temp) : c_var(temp) {} // 不影响类的大小\n ~A() {} // 不影响类的大小\n};\n\nclass B\n{\n};\nint main()\n{\n A ex1(4);\n B ex2;\n cout << sizeof(ex1) << endl; // 12 字节\n cout << sizeof(ex2) << endl; // 1 字节\n return 0;\n}\n")])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br"),n("span",{staticClass:"line-number"},[s._v("8")]),n("br"),n("span",{staticClass:"line-number"},[s._v("9")]),n("br"),n("span",{staticClass:"line-number"},[s._v("10")]),n("br"),n("span",{staticClass:"line-number"},[s._v("11")]),n("br"),n("span",{staticClass:"line-number"},[s._v("12")]),n("br"),n("span",{staticClass:"line-number"},[s._v("13")]),n("br"),n("span",{staticClass:"line-number"},[s._v("14")]),n("br"),n("span",{staticClass:"line-number"},[s._v("15")]),n("br"),n("span",{staticClass:"line-number"},[s._v("16")]),n("br"),n("span",{staticClass:"line-number"},[s._v("17")]),n("br"),n("span",{staticClass:"line-number"},[s._v("18")]),n("br"),n("span",{staticClass:"line-number"},[s._v("19")]),n("br"),n("span",{staticClass:"line-number"},[s._v("20")]),n("br"),n("span",{staticClass:"line-number"},[s._v("21")]),n("br"),n("span",{staticClass:"line-number"},[s._v("22")]),n("br"),n("span",{staticClass:"line-number"},[s._v("23")]),n("br"),n("span",{staticClass:"line-number"},[s._v("24")]),n("br"),n("span",{staticClass:"line-number"},[s._v("25")]),n("br"),n("span",{staticClass:"line-number"},[s._v("26")]),n("br"),n("span",{staticClass:"line-number"},[s._v("27")]),n("br"),n("span",{staticClass:"line-number"},[s._v("28")]),n("br"),n("span",{staticClass:"line-number"},[s._v("29")]),n("br"),n("span",{staticClass:"line-number"},[s._v("30")]),n("br")])]),n("p",[s._v("带有虚函数的情况:(注意:虚函数的个数并不影响所占内存的大小,因为类对象的内存中只保存了指向虚函数表的指针。)")]),s._v(" "),n("div",{staticClass:"language-c++ line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v('/*\n说明:程序是在 64 位编译器下测试的\n*/\n#include \n\nusing namespace std;\n\nclass A\n{\nprivate:\n static int s_var; // 不影响类的大小\n const int c_var; // 4 字节\n int var; // 8 字节 4 + 4 (int) = 8\n char var1; // 12 字节 8 + 1 (char) + 3 (填充) = 12\npublic:\n A(int temp) : c_var(temp) {} // 不影响类的大小\n ~A() {} // 不影响类的大小\n virtual void f() { cout << "A::f" << endl; }\n\n virtual void g() { cout << "A::g" << endl; }\n\n virtual void h() { cout << "A::h" << endl; } // 24 字节 12 + 4 (填充) + 8 (指向虚函数的指针) = 24\n};\n\nint main()\n{\n A ex1(4);\n A *p;\n cout << sizeof(p) << endl; // 8 字节 注意:指针所占的空间和指针指向的数据类型无关\n cout << sizeof(ex1) << endl; // 24 字节\n return 0;\n}\n')])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br"),n("span",{staticClass:"line-number"},[s._v("8")]),n("br"),n("span",{staticClass:"line-number"},[s._v("9")]),n("br"),n("span",{staticClass:"line-number"},[s._v("10")]),n("br"),n("span",{staticClass:"line-number"},[s._v("11")]),n("br"),n("span",{staticClass:"line-number"},[s._v("12")]),n("br"),n("span",{staticClass:"line-number"},[s._v("13")]),n("br"),n("span",{staticClass:"line-number"},[s._v("14")]),n("br"),n("span",{staticClass:"line-number"},[s._v("15")]),n("br"),n("span",{staticClass:"line-number"},[s._v("16")]),n("br"),n("span",{staticClass:"line-number"},[s._v("17")]),n("br"),n("span",{staticClass:"line-number"},[s._v("18")]),n("br"),n("span",{staticClass:"line-number"},[s._v("19")]),n("br"),n("span",{staticClass:"line-number"},[s._v("20")]),n("br"),n("span",{staticClass:"line-number"},[s._v("21")]),n("br"),n("span",{staticClass:"line-number"},[s._v("22")]),n("br"),n("span",{staticClass:"line-number"},[s._v("23")]),n("br"),n("span",{staticClass:"line-number"},[s._v("24")]),n("br"),n("span",{staticClass:"line-number"},[s._v("25")]),n("br"),n("span",{staticClass:"line-number"},[s._v("26")]),n("br"),n("span",{staticClass:"line-number"},[s._v("27")]),n("br"),n("span",{staticClass:"line-number"},[s._v("28")]),n("br"),n("span",{staticClass:"line-number"},[s._v("29")]),n("br"),n("span",{staticClass:"line-number"},[s._v("30")]),n("br"),n("span",{staticClass:"line-number"},[s._v("31")]),n("br"),n("span",{staticClass:"line-number"},[s._v("32")]),n("br")])]),n("h2",{attrs:{id:"什么是内存泄露"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#什么是内存泄露"}},[s._v("#")]),s._v(" 什么是内存泄露")]),s._v(" "),n("p",[n("strong",[s._v("面试高频指数:★★★★☆")])]),s._v(" "),n("p",[n("strong",[s._v("内存泄漏")]),s._v(":由于疏忽或错误导致的程序未能释放已经不再使用的内存。\n进一步解释:")]),s._v(" "),n("ul",[n("li",[n("p",[s._v("并非指内存从物理上消失,而是指程序在运行过程中,由于疏忽或错误而失去了对该内存的控制,从而造成了内存的浪费。")])]),s._v(" "),n("li",[n("p",[s._v("常指堆内存泄漏,因为堆是动态分配的,而且是用户来控制的,如果使用不当,会产生内存泄漏。")])]),s._v(" "),n("li",[n("p",[s._v("使用 malloc、calloc、realloc、new 等分配内存时,使用完后要调用相应的 free 或 delete 释放内存,否则这块内存就会造成内存泄漏。")])]),s._v(" "),n("li",[n("p",[s._v("指针重新赋值")]),s._v(" "),n("div",{staticClass:"language-c++ line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v("char *p = (char *)malloc(10);\nchar *p1 = (char *)malloc(10);\np = np;\n")])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br")])]),n("p",[s._v("开始时,指针 "),n("code",[s._v("p")]),s._v(" 和 "),n("code",[s._v("p1")]),s._v(" 分别指向一块内存空间,但指针 "),n("code",[s._v("p")]),s._v(" 被重新赋值,导致 "),n("code",[s._v("p")]),s._v(" 初始时指向的那块内存空间无法找到,从而发生了内存泄漏。")])])]),s._v(" "),n("h2",{attrs:{id:"怎么防止内存泄漏-内存泄漏检测工具的原理"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#怎么防止内存泄漏-内存泄漏检测工具的原理"}},[s._v("#")]),s._v(" 怎么防止内存泄漏?内存泄漏检测工具的原理?")]),s._v(" "),n("p",[n("strong",[s._v("面试高频指数:★★★☆☆")])]),s._v(" "),n("p",[n("strong",[s._v("防止内存泄漏的方法:")])]),s._v(" "),n("ol",[n("li",[n("p",[s._v("**内部封装:**将内存的分配和释放封装到类中,在构造的时候申请内存,析构的时候释放内存。")]),s._v(" "),n("div",{staticClass:"language-c++ line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v('#include \n#include \n\nusing namespace std;\n\nclass A\n{\nprivate:\n char *p;\n unsigned int p_size;\n\npublic:\n A(unsigned int n = 1) // 构造函数中分配内存空间\n {\n p = new char[n];\n p_size = n;\n };\n ~A() // 析构函数中释放内存空间\n {\n if (p != NULL)\n {\n delete[] p; // 删除字符数组\n p = NULL; // 防止出现野指针\n }\n };\n char *GetPointer()\n {\n return p;\n };\n};\nvoid fun()\n{\n A ex(100);\n char *p = ex.GetPointer();\n strcpy(p, "Test");\n cout << p << endl;\n}\nint main()\n{\n fun();\n return 0;\n}\n')])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br"),n("span",{staticClass:"line-number"},[s._v("8")]),n("br"),n("span",{staticClass:"line-number"},[s._v("9")]),n("br"),n("span",{staticClass:"line-number"},[s._v("10")]),n("br"),n("span",{staticClass:"line-number"},[s._v("11")]),n("br"),n("span",{staticClass:"line-number"},[s._v("12")]),n("br"),n("span",{staticClass:"line-number"},[s._v("13")]),n("br"),n("span",{staticClass:"line-number"},[s._v("14")]),n("br"),n("span",{staticClass:"line-number"},[s._v("15")]),n("br"),n("span",{staticClass:"line-number"},[s._v("16")]),n("br"),n("span",{staticClass:"line-number"},[s._v("17")]),n("br"),n("span",{staticClass:"line-number"},[s._v("18")]),n("br"),n("span",{staticClass:"line-number"},[s._v("19")]),n("br"),n("span",{staticClass:"line-number"},[s._v("20")]),n("br"),n("span",{staticClass:"line-number"},[s._v("21")]),n("br"),n("span",{staticClass:"line-number"},[s._v("22")]),n("br"),n("span",{staticClass:"line-number"},[s._v("23")]),n("br"),n("span",{staticClass:"line-number"},[s._v("24")]),n("br"),n("span",{staticClass:"line-number"},[s._v("25")]),n("br"),n("span",{staticClass:"line-number"},[s._v("26")]),n("br"),n("span",{staticClass:"line-number"},[s._v("27")]),n("br"),n("span",{staticClass:"line-number"},[s._v("28")]),n("br"),n("span",{staticClass:"line-number"},[s._v("29")]),n("br"),n("span",{staticClass:"line-number"},[s._v("30")]),n("br"),n("span",{staticClass:"line-number"},[s._v("31")]),n("br"),n("span",{staticClass:"line-number"},[s._v("32")]),n("br"),n("span",{staticClass:"line-number"},[s._v("33")]),n("br"),n("span",{staticClass:"line-number"},[s._v("34")]),n("br"),n("span",{staticClass:"line-number"},[s._v("35")]),n("br"),n("span",{staticClass:"line-number"},[s._v("36")]),n("br"),n("span",{staticClass:"line-number"},[s._v("37")]),n("br"),n("span",{staticClass:"line-number"},[s._v("38")]),n("br"),n("span",{staticClass:"line-number"},[s._v("39")]),n("br"),n("span",{staticClass:"line-number"},[s._v("40")]),n("br"),n("span",{staticClass:"line-number"},[s._v("41")]),n("br"),n("span",{staticClass:"line-number"},[s._v("42")]),n("br")])]),n("p",[s._v("说明:但这样做并不是最佳的做法,在类的对象复制时,程序会出现同一块内存空间释放两次的情况,请看如下程序:")]),s._v(" "),n("div",{staticClass:"language-c++ line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v('void fun1()\n{\n A ex(100);\n A ex1 = ex;\n char *p = ex.GetPointer();\n strcpy(p, "Test");\n cout << p << endl;\n}\n')])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br"),n("span",{staticClass:"line-number"},[s._v("8")]),n("br")])]),n("p",[s._v("简单解释:对于 fun1 这个函数中定义的两个类的对象而言,在离开该函数的作用域时,会两次调用析构函数来释放空间,但是这两个对象指向的是同一块内存空间,所以导致同一块内存空间被释放两次,可以通过增加计数机制来避免这种情况,看如下程序:")]),s._v(" "),n("div",{staticClass:"language-c++ line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v('#include \n #include \n\n using namespace std;\n class A\n {\n private:\n char *p;\n unsigned int p_size;\n int *p_count; // 计数变量\n public:\n A(unsigned int n = 1) // 在构造函数中申请内存\n {\n p = new char[n];\n p_size = n;\n p_count = new int;\n *p_count = 1;\n cout << "count is : " << *p_count << endl;\n };\n A(const A &temp)\n {\n p = temp.p;\n p_size = temp.p_size;\n p_count = temp.p_count;\n (*p_count)++; // 复制时,计数变量 +1\n cout << "count is : " << *p_count << endl;\n }\n ~A()\n {\n (*p_count)--; // 析构时,计数变量 -1\n cout << "count is : " << *p_count << endl;\n\n if (*p_count == 0) // 只有当计数变量为 0 的时候才会释放该块内存空间\n {\n cout << "buf is deleted" << endl;\n if (p != NULL)\n {\n delete[] p; // 删除字符数组\n p = NULL; // 防止出现野指针\n if (p_count != NULL)\n {\n delete p_count;\n p_count = NULL;\n }\n }\n }\n };\n char *GetPointer()\n {\n return p;\n };\n };\n void fun()\n {\n A ex(100);\n char *p = ex.GetPointer();\n strcpy(p, "Test");\n cout << p << endl;\n\n A ex1 = ex; // 此时计数变量会 +1\n cout << "ex1.p = " << ex1.GetPointer() << endl;\n }\n int main()\n {\n fun();\n return 0;\n }\n')])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br"),n("span",{staticClass:"line-number"},[s._v("8")]),n("br"),n("span",{staticClass:"line-number"},[s._v("9")]),n("br"),n("span",{staticClass:"line-number"},[s._v("10")]),n("br"),n("span",{staticClass:"line-number"},[s._v("11")]),n("br"),n("span",{staticClass:"line-number"},[s._v("12")]),n("br"),n("span",{staticClass:"line-number"},[s._v("13")]),n("br"),n("span",{staticClass:"line-number"},[s._v("14")]),n("br"),n("span",{staticClass:"line-number"},[s._v("15")]),n("br"),n("span",{staticClass:"line-number"},[s._v("16")]),n("br"),n("span",{staticClass:"line-number"},[s._v("17")]),n("br"),n("span",{staticClass:"line-number"},[s._v("18")]),n("br"),n("span",{staticClass:"line-number"},[s._v("19")]),n("br"),n("span",{staticClass:"line-number"},[s._v("20")]),n("br"),n("span",{staticClass:"line-number"},[s._v("21")]),n("br"),n("span",{staticClass:"line-number"},[s._v("22")]),n("br"),n("span",{staticClass:"line-number"},[s._v("23")]),n("br"),n("span",{staticClass:"line-number"},[s._v("24")]),n("br"),n("span",{staticClass:"line-number"},[s._v("25")]),n("br"),n("span",{staticClass:"line-number"},[s._v("26")]),n("br"),n("span",{staticClass:"line-number"},[s._v("27")]),n("br"),n("span",{staticClass:"line-number"},[s._v("28")]),n("br"),n("span",{staticClass:"line-number"},[s._v("29")]),n("br"),n("span",{staticClass:"line-number"},[s._v("30")]),n("br"),n("span",{staticClass:"line-number"},[s._v("31")]),n("br"),n("span",{staticClass:"line-number"},[s._v("32")]),n("br"),n("span",{staticClass:"line-number"},[s._v("33")]),n("br"),n("span",{staticClass:"line-number"},[s._v("34")]),n("br"),n("span",{staticClass:"line-number"},[s._v("35")]),n("br"),n("span",{staticClass:"line-number"},[s._v("36")]),n("br"),n("span",{staticClass:"line-number"},[s._v("37")]),n("br"),n("span",{staticClass:"line-number"},[s._v("38")]),n("br"),n("span",{staticClass:"line-number"},[s._v("39")]),n("br"),n("span",{staticClass:"line-number"},[s._v("40")]),n("br"),n("span",{staticClass:"line-number"},[s._v("41")]),n("br"),n("span",{staticClass:"line-number"},[s._v("42")]),n("br"),n("span",{staticClass:"line-number"},[s._v("43")]),n("br"),n("span",{staticClass:"line-number"},[s._v("44")]),n("br"),n("span",{staticClass:"line-number"},[s._v("45")]),n("br"),n("span",{staticClass:"line-number"},[s._v("46")]),n("br"),n("span",{staticClass:"line-number"},[s._v("47")]),n("br"),n("span",{staticClass:"line-number"},[s._v("48")]),n("br"),n("span",{staticClass:"line-number"},[s._v("49")]),n("br"),n("span",{staticClass:"line-number"},[s._v("50")]),n("br"),n("span",{staticClass:"line-number"},[s._v("51")]),n("br"),n("span",{staticClass:"line-number"},[s._v("52")]),n("br"),n("span",{staticClass:"line-number"},[s._v("53")]),n("br"),n("span",{staticClass:"line-number"},[s._v("54")]),n("br"),n("span",{staticClass:"line-number"},[s._v("55")]),n("br"),n("span",{staticClass:"line-number"},[s._v("56")]),n("br"),n("span",{staticClass:"line-number"},[s._v("57")]),n("br"),n("span",{staticClass:"line-number"},[s._v("58")]),n("br"),n("span",{staticClass:"line-number"},[s._v("59")]),n("br"),n("span",{staticClass:"line-number"},[s._v("60")]),n("br"),n("span",{staticClass:"line-number"},[s._v("61")]),n("br"),n("span",{staticClass:"line-number"},[s._v("62")]),n("br"),n("span",{staticClass:"line-number"},[s._v("63")]),n("br"),n("span",{staticClass:"line-number"},[s._v("64")]),n("br"),n("span",{staticClass:"line-number"},[s._v("65")]),n("br"),n("span",{staticClass:"line-number"},[s._v("66")]),n("br"),n("span",{staticClass:"line-number"},[s._v("67")]),n("br")])]),n("p",[s._v("程序运行结果:")]),s._v(" "),n("div",{staticClass:"language-c++ line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v("count is : 1\nTest\ncount is : 2\nex1.p = Test\ncount is : 1\ncount is : 0\nbuf is deleted\n")])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br")])])])]),s._v(" "),n("p",[s._v("解释下:程序运行结果的倒数 2、3 行是调用两次析构函数时进行的操作,在第二次调用析构函数时,进行内存空间的释放,从而会有倒数第 1 行的输出结果。")]),s._v(" "),n("ol",{attrs:{start:"2"}},[n("li",[n("p",[n("strong",[s._v("智能指针")])]),s._v(" "),n("p",[s._v("智能指针是 C++ 中已经对内存泄漏封装好了一个工具,可以直接拿来使用,将在下一个问题中对智能指针进行详细的解释。")])])]),s._v(" "),n("p",[n("strong",[s._v("内存泄漏检测工具的实现原理:")]),s._v("\n内存检测工具有很多,这里重点介绍下 valgrind 。")]),s._v(" "),n("p",[n("img",{attrs:{src:"https://cdn.jsdelivr.net/gh/jacky1234/picArchieve@master/uPic/20230522_135513_6SuS1v.png",alt:"20230522_135513_6SuS1v"}})]),s._v(" "),n("p",[s._v("valgrind 是一套 Linux 下,开放源代码(GPL V2)的仿真调试工具的集合,包括以下工具:")]),s._v(" "),n("ul",[n("li",[s._v("Memcheck:内存检查器(valgrind 应用最广泛的工具),能够发现开发中绝大多数内存错误的使用情况,比如:使用未初始化的内存,使用已经释放了的内存,内存访问越界等。")]),s._v(" "),n("li",[s._v("Callgrind:检查程序中函数调用过程中出现的问题。")]),s._v(" "),n("li",[s._v("Cachegrind:检查程序中缓存使用出现的问题。")]),s._v(" "),n("li",[s._v("Helgrind:检查多线程程序中出现的竞争问题。")]),s._v(" "),n("li",[s._v("Massif:检查程序中堆栈使用中出现的问题。")]),s._v(" "),n("li",[s._v("Extension:可以利用 core 提供的功能,自己编写特定的内存调试工具。")])]),s._v(" "),n("p",[s._v("Memcheck 能够检测出内存问题,关键在于其建立了两个全局表:")]),s._v(" "),n("ul",[n("li",[s._v("Valid-Value 表:对于进程的整个地址空间中的每一个字节(byte),都有与之对应的 8 个 bits ;对于 CPU 的每个寄存器,也有一个与之对应的 bit 向量。这些 bits 负责记录该字节或者寄存器值是否具有有效的、已初始化的值。")]),s._v(" "),n("li",[s._v("Valid-Address 表:对于进程整个地址空间中的每一个字节(byte),还有与之对应的 1 个 bit,负责记录该地址是否能够被读写。")])]),s._v(" "),n("p",[s._v("检测原理:")]),s._v(" "),n("ul",[n("li",[s._v("当要读写内存中某个字节时,首先检查这个字节对应的 Valid-Address 表中对应的 bit。如果该 bit 显示该位置是无效位置,Memcheck 则报告读写错误。")]),s._v(" "),n("li",[s._v("内核(core)类似于一个虚拟的 CPU 环境,这样当内存中的某个字节被加载到真实的 CPU 中时,该字节在 Valid-Value 表对应的 bits 也被加载到虚拟的 CPU 环境中。一旦寄存器中的值,被用来产生内存地址,或者该值能够影响程序输出,则 Memcheck 会检查 Valid-Value 表对应的 bits,如果该值尚未初始化,则会报告使用未初始化内存错误。")])]),s._v(" "),n("h2",{attrs:{id:"智能指针的实现原理"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#智能指针的实现原理"}},[s._v("#")]),s._v(" 智能指针的实现原理")]),s._v(" "),n("div",{staticClass:"custom-block tip"},[n("p",{staticClass:"custom-block-title"},[s._v("提示")]),s._v(" "),n("p",[s._v("面试高频指数:★★★★★\n智能指针是为了解决动态内存分配时带来的内存泄漏以及多次释放同一块内存空间而提出的。C++11 中封装在了 "),n("code",[s._v("memory")]),s._v(" 头文件中。")])]),s._v(" "),n("p",[s._v("C++11 中智能指针包括以下三种:")]),s._v(" "),n("ul",[n("li",[s._v("**共享指针(shared_ptr):**资源可以被多个指针共享,使用计数机制表明资源被几个指针共享。通过 use_count() 查看资源的所有者的个数,可以通过 unique_ptr、weak_ptr 来构造,调用 release() 释放资源的所有权,计数减一,当计数减为 0 时,会自动释放内存空间,从而避免了内存泄漏。")]),s._v(" "),n("li",[s._v("**独占指针(unique_ptr):**独享所有权的智能指针,资源只能被一个指针占有,该指针不能拷贝构造和赋值。但可以进行移动构造和移动赋值构造(调用 move() 函数),即一个 unique_ptr 对象赋值给另一个 unique_ptr 对象,可以通过该方法进行赋值。")]),s._v(" "),n("li",[s._v("**弱指针(weak_ptr):**指向 share_ptr 指向的对象,能够解决由 shared_ptr 带来的循环引用问题。")])]),s._v(" "),n("p",[s._v("智能指针的实现原理:计数原理。")]),s._v(" "),n("div",{staticClass:"language-c++ line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v("#include \n#include \n\ntemplate \nclass SmartPtr\n{\nprivate :\n T *_ptr;\n size_t *_count;\n\npublic:\n SmartPtr(T *ptr = nullptr) : _ptr(ptr)\n {\n if (_ptr)\n {\n _count = new size_t(1);\n }\n else\n {\n _count = new size_t(0);\n }\n }\n\n ~SmartPtr()\n {\n (*this->_count)--;\n if (*this->_count == 0)\n {\n delete this->_ptr;\n delete this->_count;\n }\n }\n\n SmartPtr(const SmartPtr &ptr) // 拷贝构造:计数 +1\n {\n if (this != &ptr)\n {\n this->_ptr = ptr._ptr;\n this->_count = ptr._count;\n (*this->_count)++;\n }\n }\n\n SmartPtr &operator=(const SmartPtr &ptr) // 赋值运算符重载\n {\n if (this->_ptr == ptr._ptr)\n {\n return *this;\n }\n if (this->_ptr) // 将当前的 ptr 指向的原来的空间的计数 -1\n {\n (*this->_count)--;\n if (this->_count == 0)\n {\n delete this->_ptr;\n delete this->_count;\n }\n }\n this->_ptr = ptr._ptr;\n this->_count = ptr._count;\n (*this->_count)++; // 此时 ptr 指向了新赋值的空间,该空间的计数 +1\n return *this;\n }\n\n T &operator*()\n {\n assert(this->_ptr == nullptr);\n return *(this->_ptr);\n }\n\n T *operator->()\n {\n assert(this->_ptr == nullptr);\n return this->_ptr;\n }\n\n size_t use_count()\n {\n return *this->count;\n }\n};\n")])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br"),n("span",{staticClass:"line-number"},[s._v("8")]),n("br"),n("span",{staticClass:"line-number"},[s._v("9")]),n("br"),n("span",{staticClass:"line-number"},[s._v("10")]),n("br"),n("span",{staticClass:"line-number"},[s._v("11")]),n("br"),n("span",{staticClass:"line-number"},[s._v("12")]),n("br"),n("span",{staticClass:"line-number"},[s._v("13")]),n("br"),n("span",{staticClass:"line-number"},[s._v("14")]),n("br"),n("span",{staticClass:"line-number"},[s._v("15")]),n("br"),n("span",{staticClass:"line-number"},[s._v("16")]),n("br"),n("span",{staticClass:"line-number"},[s._v("17")]),n("br"),n("span",{staticClass:"line-number"},[s._v("18")]),n("br"),n("span",{staticClass:"line-number"},[s._v("19")]),n("br"),n("span",{staticClass:"line-number"},[s._v("20")]),n("br"),n("span",{staticClass:"line-number"},[s._v("21")]),n("br"),n("span",{staticClass:"line-number"},[s._v("22")]),n("br"),n("span",{staticClass:"line-number"},[s._v("23")]),n("br"),n("span",{staticClass:"line-number"},[s._v("24")]),n("br"),n("span",{staticClass:"line-number"},[s._v("25")]),n("br"),n("span",{staticClass:"line-number"},[s._v("26")]),n("br"),n("span",{staticClass:"line-number"},[s._v("27")]),n("br"),n("span",{staticClass:"line-number"},[s._v("28")]),n("br"),n("span",{staticClass:"line-number"},[s._v("29")]),n("br"),n("span",{staticClass:"line-number"},[s._v("30")]),n("br"),n("span",{staticClass:"line-number"},[s._v("31")]),n("br"),n("span",{staticClass:"line-number"},[s._v("32")]),n("br"),n("span",{staticClass:"line-number"},[s._v("33")]),n("br"),n("span",{staticClass:"line-number"},[s._v("34")]),n("br"),n("span",{staticClass:"line-number"},[s._v("35")]),n("br"),n("span",{staticClass:"line-number"},[s._v("36")]),n("br"),n("span",{staticClass:"line-number"},[s._v("37")]),n("br"),n("span",{staticClass:"line-number"},[s._v("38")]),n("br"),n("span",{staticClass:"line-number"},[s._v("39")]),n("br"),n("span",{staticClass:"line-number"},[s._v("40")]),n("br"),n("span",{staticClass:"line-number"},[s._v("41")]),n("br"),n("span",{staticClass:"line-number"},[s._v("42")]),n("br"),n("span",{staticClass:"line-number"},[s._v("43")]),n("br"),n("span",{staticClass:"line-number"},[s._v("44")]),n("br"),n("span",{staticClass:"line-number"},[s._v("45")]),n("br"),n("span",{staticClass:"line-number"},[s._v("46")]),n("br"),n("span",{staticClass:"line-number"},[s._v("47")]),n("br"),n("span",{staticClass:"line-number"},[s._v("48")]),n("br"),n("span",{staticClass:"line-number"},[s._v("49")]),n("br"),n("span",{staticClass:"line-number"},[s._v("50")]),n("br"),n("span",{staticClass:"line-number"},[s._v("51")]),n("br"),n("span",{staticClass:"line-number"},[s._v("52")]),n("br"),n("span",{staticClass:"line-number"},[s._v("53")]),n("br"),n("span",{staticClass:"line-number"},[s._v("54")]),n("br"),n("span",{staticClass:"line-number"},[s._v("55")]),n("br"),n("span",{staticClass:"line-number"},[s._v("56")]),n("br"),n("span",{staticClass:"line-number"},[s._v("57")]),n("br"),n("span",{staticClass:"line-number"},[s._v("58")]),n("br"),n("span",{staticClass:"line-number"},[s._v("59")]),n("br"),n("span",{staticClass:"line-number"},[s._v("60")]),n("br"),n("span",{staticClass:"line-number"},[s._v("61")]),n("br"),n("span",{staticClass:"line-number"},[s._v("62")]),n("br"),n("span",{staticClass:"line-number"},[s._v("63")]),n("br"),n("span",{staticClass:"line-number"},[s._v("64")]),n("br"),n("span",{staticClass:"line-number"},[s._v("65")]),n("br"),n("span",{staticClass:"line-number"},[s._v("66")]),n("br"),n("span",{staticClass:"line-number"},[s._v("67")]),n("br"),n("span",{staticClass:"line-number"},[s._v("68")]),n("br"),n("span",{staticClass:"line-number"},[s._v("69")]),n("br"),n("span",{staticClass:"line-number"},[s._v("70")]),n("br"),n("span",{staticClass:"line-number"},[s._v("71")]),n("br"),n("span",{staticClass:"line-number"},[s._v("72")]),n("br"),n("span",{staticClass:"line-number"},[s._v("73")]),n("br"),n("span",{staticClass:"line-number"},[s._v("74")]),n("br"),n("span",{staticClass:"line-number"},[s._v("75")]),n("br"),n("span",{staticClass:"line-number"},[s._v("76")]),n("br"),n("span",{staticClass:"line-number"},[s._v("77")]),n("br"),n("span",{staticClass:"line-number"},[s._v("78")]),n("br"),n("span",{staticClass:"line-number"},[s._v("79")]),n("br"),n("span",{staticClass:"line-number"},[s._v("80")]),n("br"),n("span",{staticClass:"line-number"},[s._v("81")]),n("br")])]),n("h2",{attrs:{id:"一个-unique-ptr-怎么赋值给另一个-unique-ptr-对象"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#一个-unique-ptr-怎么赋值给另一个-unique-ptr-对象"}},[s._v("#")]),s._v(" 一个 unique_ptr 怎么赋值给另一个 unique_ptr 对象?")]),s._v(" "),n("p",[n("strong",[s._v("面试高频指数:★★☆☆☆")]),s._v(" "),n("strong",[s._v("借助 std::move() 可以实现将一个 unique_ptr 对象赋值给另一个 unique_ptr 对象,其目的是实现所有权的转移。")])]),s._v(" "),n("div",{staticClass:"language-c++ line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v("// A 作为一个类\nstd::unique_ptr ptr1(new A());\nstd::unique_ptr ptr2 = std::move(ptr1);\n")])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br")])]),n("h2",{attrs:{id:"使用智能指针会出现什么问题-怎么解决"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#使用智能指针会出现什么问题-怎么解决"}},[s._v("#")]),s._v(" 使用智能指针会出现什么问题?怎么解决?")]),s._v(" "),n("p",[n("strong",[s._v("面试高频指数:★★★★★")]),s._v(" "),n("strong",[s._v("智能指针可能出现的问题:循环引用")]),s._v("\n在如下例子中定义了两个类 Parent、Child,在两个类中分别定义另一个类的对象的共享指针,由于在程序结束后,两个指针相互指向对方的内存空间,导致内存无法释放。")]),s._v(" "),n("div",{staticClass:"language-c++ line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v("#include \n#include \n\nusing namespace std;\n\nclass Child;\nclass Parent;\n\nclass Parent {\nprivate:\n shared_ptr ChildPtr;\npublic:\n void setChild(shared_ptr child) {\n this->ChildPtr = child;\n }\n\n void doSomething() {\n if (this->ChildPtr.use_count()) {\n\n }\n }\n\n ~Parent() {\n }\n};\n\nclass Child {\nprivate:\n shared_ptr ParentPtr;\npublic:\n void setPartent(shared_ptr parent) {\n this->ParentPtr = parent;\n }\n void doSomething() {\n if (this->ParentPtr.use_count()) {\n\n }\n }\n ~Child() {\n }\n};\n\nint main() {\n weak_ptr wpp;\n weak_ptr wpc;\n {\n shared_ptr p(new Parent);\n shared_ptr c(new Child);\n p->setChild(c);\n c->setPartent(p);\n wpp = p;\n wpc = c;\n cout << p.use_count() << endl; // 2\n cout << c.use_count() << endl; // 2\n }\n cout << wpp.use_count() << endl; // 1\n cout << wpc.use_count() << endl; // 1\n return 0;\n}\n")])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br"),n("span",{staticClass:"line-number"},[s._v("8")]),n("br"),n("span",{staticClass:"line-number"},[s._v("9")]),n("br"),n("span",{staticClass:"line-number"},[s._v("10")]),n("br"),n("span",{staticClass:"line-number"},[s._v("11")]),n("br"),n("span",{staticClass:"line-number"},[s._v("12")]),n("br"),n("span",{staticClass:"line-number"},[s._v("13")]),n("br"),n("span",{staticClass:"line-number"},[s._v("14")]),n("br"),n("span",{staticClass:"line-number"},[s._v("15")]),n("br"),n("span",{staticClass:"line-number"},[s._v("16")]),n("br"),n("span",{staticClass:"line-number"},[s._v("17")]),n("br"),n("span",{staticClass:"line-number"},[s._v("18")]),n("br"),n("span",{staticClass:"line-number"},[s._v("19")]),n("br"),n("span",{staticClass:"line-number"},[s._v("20")]),n("br"),n("span",{staticClass:"line-number"},[s._v("21")]),n("br"),n("span",{staticClass:"line-number"},[s._v("22")]),n("br"),n("span",{staticClass:"line-number"},[s._v("23")]),n("br"),n("span",{staticClass:"line-number"},[s._v("24")]),n("br"),n("span",{staticClass:"line-number"},[s._v("25")]),n("br"),n("span",{staticClass:"line-number"},[s._v("26")]),n("br"),n("span",{staticClass:"line-number"},[s._v("27")]),n("br"),n("span",{staticClass:"line-number"},[s._v("28")]),n("br"),n("span",{staticClass:"line-number"},[s._v("29")]),n("br"),n("span",{staticClass:"line-number"},[s._v("30")]),n("br"),n("span",{staticClass:"line-number"},[s._v("31")]),n("br"),n("span",{staticClass:"line-number"},[s._v("32")]),n("br"),n("span",{staticClass:"line-number"},[s._v("33")]),n("br"),n("span",{staticClass:"line-number"},[s._v("34")]),n("br"),n("span",{staticClass:"line-number"},[s._v("35")]),n("br"),n("span",{staticClass:"line-number"},[s._v("36")]),n("br"),n("span",{staticClass:"line-number"},[s._v("37")]),n("br"),n("span",{staticClass:"line-number"},[s._v("38")]),n("br"),n("span",{staticClass:"line-number"},[s._v("39")]),n("br"),n("span",{staticClass:"line-number"},[s._v("40")]),n("br"),n("span",{staticClass:"line-number"},[s._v("41")]),n("br"),n("span",{staticClass:"line-number"},[s._v("42")]),n("br"),n("span",{staticClass:"line-number"},[s._v("43")]),n("br"),n("span",{staticClass:"line-number"},[s._v("44")]),n("br"),n("span",{staticClass:"line-number"},[s._v("45")]),n("br"),n("span",{staticClass:"line-number"},[s._v("46")]),n("br"),n("span",{staticClass:"line-number"},[s._v("47")]),n("br"),n("span",{staticClass:"line-number"},[s._v("48")]),n("br"),n("span",{staticClass:"line-number"},[s._v("49")]),n("br"),n("span",{staticClass:"line-number"},[s._v("50")]),n("br"),n("span",{staticClass:"line-number"},[s._v("51")]),n("br"),n("span",{staticClass:"line-number"},[s._v("52")]),n("br"),n("span",{staticClass:"line-number"},[s._v("53")]),n("br"),n("span",{staticClass:"line-number"},[s._v("54")]),n("br"),n("span",{staticClass:"line-number"},[s._v("55")]),n("br"),n("span",{staticClass:"line-number"},[s._v("56")]),n("br"),n("span",{staticClass:"line-number"},[s._v("57")]),n("br"),n("span",{staticClass:"line-number"},[s._v("58")]),n("br"),n("span",{staticClass:"line-number"},[s._v("59")]),n("br")])]),n("p",[n("strong",[s._v("循环引用的解决方法:")]),s._v(" "),n("code",[s._v("weak_ptr")])]),s._v(" "),n("p",[s._v("循环引用:该被调用的析构函数没有被调用,从而出现了内存泄漏。")]),s._v(" "),n("ul",[n("li",[n("p",[s._v("weak_ptr 对被 shared_ptr 管理的对象存在 非拥有性(弱)引用,在访问所引用的对象前必须先转化为 shared_ptr;")])]),s._v(" "),n("li",[n("p",[s._v("weak_ptr 用来打断 shared_ptr 所管理对象的循环引用问题,若这种环被孤立(没有指向环中的外部共享指针),shared_ptr 引用计数无法抵达 0,内存被泄露;令环中的指针之一为弱指针可以避免该情况;")])]),s._v(" "),n("li",[n("p",[s._v("weak_ptr 用来表达临时所有权的概念,当某个对象只有存在时才需要被访问,而且随时可能被他人删除,可以用 weak_ptr 跟踪该对象;需要获得所有权时将其转化为 shared_ptr,此时如果原来的 shared_ptr 被销毁,则该对象的生命期被延长至这个临时的 shared_ptr 同样被销毁。")])])]),s._v(" "),n("div",{staticClass:"language-c++ line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v("#include \n#include \n\nusing namespace std;\n\nclass Child;\nclass Parent;\n\nclass Parent {\nprivate:\n //shared_ptr ChildPtr;\n weak_ptr ChildPtr;\npublic:\n void setChild(shared_ptr child) {\n this->ChildPtr = child;\n }\n\n void doSomething() {\n //new shared_ptr\n if (this->ChildPtr.lock()) {\n\n }\n }\n\n ~Parent() {\n }\n};\n\nclass Child {\nprivate:\n shared_ptr ParentPtr;\npublic:\n void setPartent(shared_ptr parent) {\n this->ParentPtr = parent;\n }\n void doSomething() {\n if (this->ParentPtr.use_count()) {\n\n }\n }\n ~Child() {\n }\n};\n\nint main() {\n weak_ptr wpp;\n weak_ptr wpc;\n {\n shared_ptr p(new Parent);\n shared_ptr c(new Child);\n p->setChild(c);\n c->setPartent(p);\n wpp = p;\n wpc = c;\n cout << p.use_count() << endl; // 2\n cout << c.use_count() << endl; // 1\n }\n cout << wpp.use_count() << endl; // 0\n cout << wpc.use_count() << endl; // 0\n return 0;\n}\n")])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br"),n("span",{staticClass:"line-number"},[s._v("8")]),n("br"),n("span",{staticClass:"line-number"},[s._v("9")]),n("br"),n("span",{staticClass:"line-number"},[s._v("10")]),n("br"),n("span",{staticClass:"line-number"},[s._v("11")]),n("br"),n("span",{staticClass:"line-number"},[s._v("12")]),n("br"),n("span",{staticClass:"line-number"},[s._v("13")]),n("br"),n("span",{staticClass:"line-number"},[s._v("14")]),n("br"),n("span",{staticClass:"line-number"},[s._v("15")]),n("br"),n("span",{staticClass:"line-number"},[s._v("16")]),n("br"),n("span",{staticClass:"line-number"},[s._v("17")]),n("br"),n("span",{staticClass:"line-number"},[s._v("18")]),n("br"),n("span",{staticClass:"line-number"},[s._v("19")]),n("br"),n("span",{staticClass:"line-number"},[s._v("20")]),n("br"),n("span",{staticClass:"line-number"},[s._v("21")]),n("br"),n("span",{staticClass:"line-number"},[s._v("22")]),n("br"),n("span",{staticClass:"line-number"},[s._v("23")]),n("br"),n("span",{staticClass:"line-number"},[s._v("24")]),n("br"),n("span",{staticClass:"line-number"},[s._v("25")]),n("br"),n("span",{staticClass:"line-number"},[s._v("26")]),n("br"),n("span",{staticClass:"line-number"},[s._v("27")]),n("br"),n("span",{staticClass:"line-number"},[s._v("28")]),n("br"),n("span",{staticClass:"line-number"},[s._v("29")]),n("br"),n("span",{staticClass:"line-number"},[s._v("30")]),n("br"),n("span",{staticClass:"line-number"},[s._v("31")]),n("br"),n("span",{staticClass:"line-number"},[s._v("32")]),n("br"),n("span",{staticClass:"line-number"},[s._v("33")]),n("br"),n("span",{staticClass:"line-number"},[s._v("34")]),n("br"),n("span",{staticClass:"line-number"},[s._v("35")]),n("br"),n("span",{staticClass:"line-number"},[s._v("36")]),n("br"),n("span",{staticClass:"line-number"},[s._v("37")]),n("br"),n("span",{staticClass:"line-number"},[s._v("38")]),n("br"),n("span",{staticClass:"line-number"},[s._v("39")]),n("br"),n("span",{staticClass:"line-number"},[s._v("40")]),n("br"),n("span",{staticClass:"line-number"},[s._v("41")]),n("br"),n("span",{staticClass:"line-number"},[s._v("42")]),n("br"),n("span",{staticClass:"line-number"},[s._v("43")]),n("br"),n("span",{staticClass:"line-number"},[s._v("44")]),n("br"),n("span",{staticClass:"line-number"},[s._v("45")]),n("br"),n("span",{staticClass:"line-number"},[s._v("46")]),n("br"),n("span",{staticClass:"line-number"},[s._v("47")]),n("br"),n("span",{staticClass:"line-number"},[s._v("48")]),n("br"),n("span",{staticClass:"line-number"},[s._v("49")]),n("br"),n("span",{staticClass:"line-number"},[s._v("50")]),n("br"),n("span",{staticClass:"line-number"},[s._v("51")]),n("br"),n("span",{staticClass:"line-number"},[s._v("52")]),n("br"),n("span",{staticClass:"line-number"},[s._v("53")]),n("br"),n("span",{staticClass:"line-number"},[s._v("54")]),n("br"),n("span",{staticClass:"line-number"},[s._v("55")]),n("br"),n("span",{staticClass:"line-number"},[s._v("56")]),n("br"),n("span",{staticClass:"line-number"},[s._v("57")]),n("br"),n("span",{staticClass:"line-number"},[s._v("58")]),n("br"),n("span",{staticClass:"line-number"},[s._v("59")]),n("br"),n("span",{staticClass:"line-number"},[s._v("60")]),n("br"),n("span",{staticClass:"line-number"},[s._v("61")]),n("br")])]),n("h1",{attrs:{id:"语言对比"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#语言对比"}},[s._v("#")]),s._v(" 语言对比")]),s._v(" "),n("p",[s._v("本章主要介绍下编程语言之间的区别,涉及到 C++、Python、Java,并对 C++ 11 的新特性进行了总结。主要考虑到面试时,面试者熟悉 C++ 的同时,或许会对其他语言有一定的了解,那面试官就不可避免的会问到不同语言之间的区别。")]),s._v(" "),n("h2",{attrs:{id:"c-11-新特性"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#c-11-新特性"}},[s._v("#")]),s._v(" C++ 11 新特性")]),s._v(" "),n("p",[n("strong",[s._v("面试高频指数:★★★★☆")]),s._v("\n说明:C++11 的新特性有很多,从面试的角度来讲,如果面试官问到该问题,常以该问题作为引子,对面试者提到的知识点进行深入展开提问。面试者尽可能的列举常用的并且熟悉的特性,尽可能的掌握相关原理,下文只是对相关知识点进行了简单的阐述,有关细节还需要结合相关知识点的相关问题。")]),s._v(" "),n("p",[s._v("下面对常用的做一下总结:")]),s._v(" "),n("ol",[n("li",[n("p",[n("strong",[s._v("auto 类型推导")])]),s._v(" "),n("p",[s._v("auto 关键字:自动类型推导,编译器会在 编译期间 通过初始值推导出变量的类型,通过 auto 定义的变量必须有初始值。auto 关键字基本的使用语法如下:")]),s._v(" "),n("div",{staticClass:"language-c++ line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v("auto var = val1 + val2; // 根据 val1 和 val2 相加的结果推断出 var 的类型,\n")])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br")])]),n("p",[s._v("注意:编译器推导出来的类型和初始值的类型并不完全一样,编译器会适当地改变结果类型使其更符合初始化规则。")])]),s._v(" "),n("li",[n("p",[n("strong",[s._v("decltype 类型推导")]),s._v("\ndecltype 关键字:decltype 是“declare type”的缩写,译为“声明类型”。和 auto 的功能一样,都用来在编译时期进行自动类型推导。如果希望从表达式中推断出要定义的变量的类型,但是不想用该表达式的值初始化变量,这时就不能再用 auto。decltype 作用是选择并返回操作数的数据类型。")]),s._v(" "),n("p",[s._v("区别:")]),s._v(" "),n("div",{staticClass:"language-c++ line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v("auto var = val1 + val2;\ndecltype(val1 + val2) var1 = 0;\n")])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br")])]),n("ul",[n("li",[n("p",[s._v("auto 根据 = 右边的初始值 val1 + val2 推导出变量的类型,并将该初始值赋值给变量 var;decltype 根据 val1 + val2 表达式推导出变量的类型,变量的初始值和与表达式的值无关。")])]),s._v(" "),n("li",[n("p",[s._v("auto 要求变量必须初始化,因为它是根据初始化的值推导出变量的类型,而 decltype 不要求,定义变量的时候可初始化也可以不初始化。")])])])]),s._v(" "),n("li",[n("p",[n("strong",[n("code",[s._v("lambda")]),s._v(" 表达式")]),s._v(" "),n("code",[s._v("lambda")]),s._v(" 表达式,又被称为 "),n("code",[s._v("lambda")]),s._v(" 函数或者 "),n("code",[s._v("lambda")]),s._v(" 匿名函数。")]),s._v(" "),n("div",{staticClass:"language-c++ line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v("[capture list] (parameter list) -> return type\n{\n function body;\n};\n")])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br")])]),n("p",[s._v("其中:")]),s._v(" "),n("ul",[n("li",[s._v("capture list:捕获列表,指 lambda 所在函数中定义的局部变量的列表,通常为空。")]),s._v(" "),n("li",[s._v("return type、parameter list、function body:分别表示返回值类型、参数列表、函数体,和普通函数一样。")])]),s._v(" "),n("p",[s._v("举例:")]),s._v(" "),n("div",{staticClass:"language-c++ line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v('#include \n#include \nusing namespace std;\n\nint main()\n{\n int arr[4] = {4, 2, 3, 1};\n //对 a 数组中的元素进行升序排序\n sort(arr, arr+4, [=](int x, int y) -> bool{ return x < y; } );\n for(int n : arr){\n cout << n << " ";\n }\n return 0;\n}\n')])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br"),n("span",{staticClass:"line-number"},[s._v("8")]),n("br"),n("span",{staticClass:"line-number"},[s._v("9")]),n("br"),n("span",{staticClass:"line-number"},[s._v("10")]),n("br"),n("span",{staticClass:"line-number"},[s._v("11")]),n("br"),n("span",{staticClass:"line-number"},[s._v("12")]),n("br"),n("span",{staticClass:"line-number"},[s._v("13")]),n("br"),n("span",{staticClass:"line-number"},[s._v("14")]),n("br")])])]),s._v(" "),n("li",[n("p",[n("strong",[s._v("范围 "),n("code",[s._v("for")]),s._v(" 语句")]),s._v("\n语法格式:")]),s._v(" "),n("div",{staticClass:"language-c++ line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v("for (declaration : expression){\n statement\n}\n")])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br")])]),n("p",[s._v("参数的含义:")]),s._v(" "),n("ul",[n("li",[n("p",[s._v("expression:必须是一个序列,例如用花括号括起来的初始值列表、数组、vector ,string 等,这些类型的共同特点是拥有能返回迭代器的 beign、end 成员。")])]),s._v(" "),n("li",[n("p",[s._v("declaration:此处定义一个变量,序列中的每一个元素都能转化成该变量的类型,常用 auto 类型说明符。")])])]),s._v(" "),n("p",[s._v("实例:")]),s._v(" "),n("div",{staticClass:"language-c++ line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v('#include \n#include \nusing namespace std;\nint main() {\n char arr[] = "hello world!";\n for (char c : arr) {\n cout << c;\n }\n return 0;\n}\n/*\n程序执行结果为:\nhello world!\n*/\n')])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br"),n("span",{staticClass:"line-number"},[s._v("8")]),n("br"),n("span",{staticClass:"line-number"},[s._v("9")]),n("br"),n("span",{staticClass:"line-number"},[s._v("10")]),n("br"),n("span",{staticClass:"line-number"},[s._v("11")]),n("br"),n("span",{staticClass:"line-number"},[s._v("12")]),n("br"),n("span",{staticClass:"line-number"},[s._v("13")]),n("br"),n("span",{staticClass:"line-number"},[s._v("14")]),n("br")])])]),s._v(" "),n("li",[n("p",[n("strong",[s._v("右值引用")]),s._v("\n右值引用:绑定到右值的引用,用 "),n("code",[s._v("&&")]),s._v(" 来获得右值引用,右值引用只能绑定到要销毁的对象。为了和右值引用区分开,常规的引用称为左值引用。\n举例:")]),s._v(" "),n("div",{staticClass:"language-c++ line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v("#include \n#include \nusing namespace std;\nint main()\n{\n int var = 42;\n int &l_var = var;\n int &&r_var = var; // error: cannot bind rvalue reference of type 'int&&' to lvalue of type 'int' 错误:不能将右值引用绑定到左值上\n\n int &&r_var2 = var + 40; // 正确:将 r_var2 绑定到求和结果上\n return 0;\n}\n")])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br"),n("span",{staticClass:"line-number"},[s._v("8")]),n("br"),n("span",{staticClass:"line-number"},[s._v("9")]),n("br"),n("span",{staticClass:"line-number"},[s._v("10")]),n("br"),n("span",{staticClass:"line-number"},[s._v("11")]),n("br"),n("span",{staticClass:"line-number"},[s._v("12")]),n("br")])])]),s._v(" "),n("li",[n("p",[n("strong",[s._v("标准库 move() 函数")]),s._v("\nmove() 函数:通过该函数可获得绑定到左值上的右值引用,该函数包括在 utility 头文件中。该知识点会在后续的章节中做详细的说明。")])]),s._v(" "),n("li",[n("p",[n("strong",[s._v("智能指针")]),s._v("\n相关知识已在第一章中进行了详细的说明,这里不再重复。")])]),s._v(" "),n("li",[n("p",[n("strong",[s._v("delete 函数和 default 函数")])]),s._v(" "),n("ul",[n("li",[n("p",[s._v("delete 函数:= delete 表示该函数不能被调用。")])]),s._v(" "),n("li",[n("p",[s._v("default 函数:= default 表示编译器生成默认的函数,例如:生成默认的构造函数。")]),s._v(" "),n("div",{staticClass:"language-c++ line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v("#include \nusing namespace std;\n\nclass A\n{\npublic:\n A() = default; // 表示使用默认的构造函数\n ~A() = default; // 表示使用默认的析构函数\n A(const A &) = delete; // 表示类的对象禁止拷贝构造\n A &operator=(const A &) = delete; // 表示类的对象禁止拷贝赋值\n};\nint main()\n{\n A ex1;\n A ex2 = ex1; // error: use of deleted function 'A::A(const A&)'\n A ex3;\n ex3 = ex1; // error: use of deleted function 'A& A::operator=(const A&)'\n return 0;\n}\n")])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br"),n("span",{staticClass:"line-number"},[s._v("8")]),n("br"),n("span",{staticClass:"line-number"},[s._v("9")]),n("br"),n("span",{staticClass:"line-number"},[s._v("10")]),n("br"),n("span",{staticClass:"line-number"},[s._v("11")]),n("br"),n("span",{staticClass:"line-number"},[s._v("12")]),n("br"),n("span",{staticClass:"line-number"},[s._v("13")]),n("br"),n("span",{staticClass:"line-number"},[s._v("14")]),n("br"),n("span",{staticClass:"line-number"},[s._v("15")]),n("br"),n("span",{staticClass:"line-number"},[s._v("16")]),n("br"),n("span",{staticClass:"line-number"},[s._v("17")]),n("br"),n("span",{staticClass:"line-number"},[s._v("18")]),n("br"),n("span",{staticClass:"line-number"},[s._v("19")]),n("br")])])])])])]),s._v(" "),n("h2",{attrs:{id:"c-和-c-的区别"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#c-和-c-的区别"}},[s._v("#")]),s._v(" C 和 C++ 的区别")]),s._v(" "),n("p",[n("strong",[s._v("面试高频指数:★★★☆☆")])]),s._v(" "),n("p",[s._v("首先说一下面向对象和面向过程:")]),s._v(" "),n("ul",[n("li",[n("p",[s._v("面向过程的思路:分析解决问题所需的步骤,用函数把这些步骤依次实现。")])]),s._v(" "),n("li",[n("p",[s._v("面向对象的思路:把构成问题的事务分解为各个对象,建立对象的目的,不是完成一个步骤,而是描述某个事务在解决整个问题步骤中的行为。")])])]),s._v(" "),n("p",[s._v("区别和联系:")]),s._v(" "),n("ul",[n("li",[n("p",[s._v("语言自身:C 语言是面向过程的编程,它最重要的特点是函数,通过 main 函数来调用各个子函数。程序运行的顺序都是程序员事先决定好的。C++ 是面向对象的编程,类是它的主要特点,在程序执行过程中,先由主 main 函数进入,定义一些类,根据需要执行类的成员函数,过程的概念被淡化了(实际上过程还是有的,就是主函数的那些语句。),以类驱动程序运行,类就是对象,所以我们称之为面向对象程序设计。面向对象在分析和解决问题的时候,将涉及到的数据和数据的操作封装在类中,通过类可以创建对象,以事件或消息来驱动对象执行处理。")])]),s._v(" "),n("li",[n("p",[s._v("应用领域:C 语言主要用于嵌入式领域,驱动开发等与硬件直接打交道的领域,C++ 可以用于应用层开发,用户界面开发等与操作系统打交道的领域。")])]),s._v(" "),n("li",[n("p",[s._v("C++ 既继承了 C 强大的底层操作特性,又被赋予了面向对象机制。它特性繁多,面向对象语言的多继承,对值传递与引用传递的区分以及 const 关键字,等等。")])]),s._v(" "),n("li",[n("p",[s._v("C++ 对 C 的“增强”,表现在以下几个方面:类型检查更为严格。增加了面向对象的机制、泛型编程的机制(Template)、异常处理、运算符重载、标准模板库(STL)、命名空间(避免全局命名冲突)。")])])]),s._v(" "),n("h2",{attrs:{id:"java-和-c-的区别"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#java-和-c-的区别"}},[s._v("#")]),s._v(" Java 和 C++ 的区别")]),s._v(" "),n("p",[n("strong",[s._v("面试高频指数:★★★☆☆")])]),s._v(" "),n("p",[s._v("二者在语言特性上有很大的区别:")]),s._v(" "),n("ul",[n("li",[n("p",[s._v("指针:C++ 可以直接操作指针,容易产生内存泄漏以及非法指针引用的问题;Java 并不是没有指针,虚拟机(JVM)内部还是使用了指针,只是编程人员不能直接使用指针,不能通过指针来直接访问内存,并且 Java 增加了内存管理机制。")])]),s._v(" "),n("li",[n("p",[s._v("多重继承:C++ 支持多重继承,允许多个父类派生一个类,虽然功能很强大,但是如果使用的不当会造成很多问题,例如:菱形继承;Java 不支持多重继承,但允许一个类可以继承多个接口,可以实现 C++ 多重继承的功能,但又避免了多重继承带来的许多不便。")])]),s._v(" "),n("li",[n("p",[s._v("数据类型和类:Java 是完全面向对象的语言,所有函数和变量部必须是类的一部分。除了基本数据类型之外,其余的都作为类对象,包括数组。对象将数据和方法结合起来,把它们封装在类中,这样每个对象都可实现自己的特点和行为。而 C++ 允许将函数和变量定义为全局的。")])])]),s._v(" "),n("p",[s._v("垃圾回收:")]),s._v(" "),n("ul",[n("li",[n("p",[s._v("Java 语言一个显著的特点就是垃圾回收机制,编程人员无需考虑内存管理的问题,可以有效的防止内存泄漏,有效的使用空闲的内存。")])]),s._v(" "),n("li",[n("p",[s._v("Java 所有的对象都是用 new 操作符建立在内存堆栈上,类似于 C++ 中的 new 操作符,但是当要释放该申请的内存空间时,Java 自动进行内存回收操作,C++ 需要程序员自己释放内存空间,并且 Java 中的内存回收是以线程的方式在后台运行的,利用空闲时间。")])])]),s._v(" "),n("p",[s._v("应用场景:")]),s._v(" "),n("ul",[n("li",[n("p",[s._v("Java 运行在虚拟机上,和开发平台无关,C++ 直接编译成可执行文件,是否跨平台在于用到的编译器的特性是否有多平台的支持。")])]),s._v(" "),n("li",[n("p",[s._v("C++ 可以直接编译成可执行文件,运行效率比 Java 高。")])]),s._v(" "),n("li",[n("p",[s._v("Java 主要用来开发 Web 应用。")])]),s._v(" "),n("li",[n("p",[s._v("C++ 主要用在嵌入式开发、网络、并发编程的方面。")])])]),s._v(" "),n("h2",{attrs:{id:"python-和-c-的区别"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#python-和-c-的区别"}},[s._v("#")]),s._v(" Python 和 C++ 的区别")]),s._v(" "),n("p",[n("strong",[s._v("面试高频指数:★★★☆☆")])]),s._v(" "),n("p",[s._v("区别:")]),s._v(" "),n("ul",[n("li",[n("p",[s._v("**语言自身:**Python 为脚本语言,解释执行,不需要经过编译;C++ 是一种需要编译后才能运行的语言,在特定的机器上编译后运行。")])]),s._v(" "),n("li",[n("p",[s._v("**运行效率:**C++ 运行效率高,安全稳定。原因:Python 代码和 C++ 最终都会变成 CPU 指令来跑,但一般情况下,比如反转和合并两个字符串,Python 最终转换出来的 CPU 指令会比 C++ 多很多。首先,Python 中涉及的内容比 C++ 多,经过了更多层,Python 中甚至连数字都是 object ;其次,Python 是解释执行的,和物理机 CPU 之间多了解释器这层,而 C++ 是编译执行的,直接就是机器码,编译的时候编译器又可以进行一些优化。")])]),s._v(" "),n("li",[n("p",[s._v("**开发效率:**Python 开发效率高。原因:Python 一两句代码就能实现的功能,C++ 往往需要更多的代码才能实现。")])]),s._v(" "),n("li",[n("p",[s._v("**书写格式和语法不同:**Python 的语法格式不同于其 C++ 定义声明才能使用,而且极其灵活,完全面向更上层的开发者。")])])]),s._v(" "),n("h1",{attrs:{id:"面向对象"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#面向对象"}},[s._v("#")]),s._v(" 面向对象")]),s._v(" "),n("p",[s._v("第三章主要针对 C++ 面向对象展开相关的知识点,主要涉及对面向对象的理解、三大特性、多态等知识点。本章中涉及的几个问题面试者在回答的时候,可以了灵活的来回答,例如:结合自己的项目经历进行展开的讲解,说一下在自己的项目中哪里用到了多态、多态是怎么实现的。但是,一定要在准确表述其基本含义后再结合实战经验进行展开。")]),s._v(" "),n("h2",{attrs:{id:"什么是面向对象-面向对象的三大特性"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#什么是面向对象-面向对象的三大特性"}},[s._v("#")]),s._v(" 什么是面向对象?面向对象的三大特性")]),s._v(" "),n("p",[n("strong",[s._v("面试高频指数:★★★★★")])]),s._v(" "),n("p",[s._v("面向对象:对象是指具体的某一个事物,这些事物的抽象就是类,类中包含数据(成员变量)和动作(成员方法)。")]),s._v(" "),n("p",[s._v("面向对象的三大特性:")]),s._v(" "),n("ul",[n("li",[n("p",[s._v("封装:将具体的实现过程和数据封装成一个函数,只能通过接口进行访问,降低耦合性。")])]),s._v(" "),n("li",[n("p",[s._v("继承:子类继承父类的特征和行为,子类有父类的非 private 方法或成员变量,子类可以对父类的方法进行重写,增强了类之间的耦合性,但是当父类中的成员变量、成员函数或者类本身被 final 关键字修饰时,修饰的类不能继承,修饰的成员不能重写或修改。")])]),s._v(" "),n("li",[n("p",[s._v("多态:多态就是不同继承类的对象,对同一消息做出不同的响应,基类的指针指向或绑定到派生类的对象,使得基类指针呈现不同的表现方式。")])])]),s._v(" "),n("h2",{attrs:{id:"重载、重写、隐藏的区别"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#重载、重写、隐藏的区别"}},[s._v("#")]),s._v(" 重载、重写、隐藏的区别")]),s._v(" "),n("p",[n("strong",[s._v("面试高频指数:★★★★★")])]),s._v(" "),n("p",[s._v("概念解释:")]),s._v(" "),n("ul",[n("li",[n("p",[s._v("重载:是指同一可访问区内被声明几个具有不同参数列(参数的类型、个数、顺序)的同名函数,根据参数列表确定调用哪个函数,重载不关心函数返回类型。")]),s._v(" "),n("div",{staticClass:"language-c++ line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v("class A\n{\npublic:\n void fun(int tmp);\n void fun(float tmp); // 重载 参数类型不同(相对于上一个函数)\n void fun(int tmp, float tmp1); // 重载 参数个数不同(相对于上一个函数)\n void fun(float tmp, int tmp1); // 重载 参数顺序不同(相对于上一个函数)\n int fun(int tmp); // error: 'int A::fun(int)' cannot be overloaded 错误:注意重载不关心函数返回类型\n};\n")])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br"),n("span",{staticClass:"line-number"},[s._v("8")]),n("br"),n("span",{staticClass:"line-number"},[s._v("9")]),n("br")])])]),s._v(" "),n("li",[n("p",[s._v("隐藏:是指派生类的函数屏蔽了与其同名的基类函数,主要只要同名函数,不管参数列表是否相同,基类函数都会被隐藏。")]),s._v(" "),n("div",{staticClass:"language-c++ line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v('#include \nusing namespace std;\n\nclass Base\n{\npublic:\n void fun(int tmp, float tmp1) { cout << "Base::fun(int tmp, float tmp1)" << endl; }\n};\n\nclass Derive : public Base\n{\npublic:\n void fun(int tmp) { cout << "Derive::fun(int tmp)" << endl; } // 隐藏基类中的同名函数\n};\n\nint main()\n{\n Derive ex;\n ex.fun(1); // Derive::fun(int tmp)\n ex.fun(1, 0.01); // error: candidate expects 1 argument, 2 provided\n return 0;\n}\n')])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br"),n("span",{staticClass:"line-number"},[s._v("8")]),n("br"),n("span",{staticClass:"line-number"},[s._v("9")]),n("br"),n("span",{staticClass:"line-number"},[s._v("10")]),n("br"),n("span",{staticClass:"line-number"},[s._v("11")]),n("br"),n("span",{staticClass:"line-number"},[s._v("12")]),n("br"),n("span",{staticClass:"line-number"},[s._v("13")]),n("br"),n("span",{staticClass:"line-number"},[s._v("14")]),n("br"),n("span",{staticClass:"line-number"},[s._v("15")]),n("br"),n("span",{staticClass:"line-number"},[s._v("16")]),n("br"),n("span",{staticClass:"line-number"},[s._v("17")]),n("br"),n("span",{staticClass:"line-number"},[s._v("18")]),n("br"),n("span",{staticClass:"line-number"},[s._v("19")]),n("br"),n("span",{staticClass:"line-number"},[s._v("20")]),n("br"),n("span",{staticClass:"line-number"},[s._v("21")]),n("br"),n("span",{staticClass:"line-number"},[s._v("22")]),n("br")])]),n("p",[s._v("说明:上述代码中 ex.fun(1, 0.01); 出现错误,说明派生类中将基类的同名函数隐藏了。若是想调用基类中的同名函数,可以加上类型名指明 ex.Base::fun(1, 0.01);,这样就可以调用基类中的同名函数。")])]),s._v(" "),n("li",[n("p",[s._v("重写(覆盖):是指派生类中存在重新定义的函数。函数名、参数列表、返回值类型都必须同基类中被重写的函数一致,只有函数体不同。派生类调用时会调用派生类的重写函数,不会调用被重写函数。重写的基类中被重写的函数必须有 virtual 修饰。")]),s._v(" "),n("div",{staticClass:"language-c++ line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v('#include \nusing namespace std;\n\nclass Base\n{\npublic:\n virtual void fun(int tmp) { cout << "Base::fun(int tmp) : " << tmp << endl; }\n};\n\nclass Derived : public Base\n{\npublic:\n virtual void fun(int tmp) { cout << "Derived::fun(int tmp) : " << tmp << endl; } // 重写基类中的 fun 函数\n};\nint main()\n{\n Base *p = new Derived();\n p->fun(3); // Derived::fun(int) : 3\n return 0;\n}\n')])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br"),n("span",{staticClass:"line-number"},[s._v("8")]),n("br"),n("span",{staticClass:"line-number"},[s._v("9")]),n("br"),n("span",{staticClass:"line-number"},[s._v("10")]),n("br"),n("span",{staticClass:"line-number"},[s._v("11")]),n("br"),n("span",{staticClass:"line-number"},[s._v("12")]),n("br"),n("span",{staticClass:"line-number"},[s._v("13")]),n("br"),n("span",{staticClass:"line-number"},[s._v("14")]),n("br"),n("span",{staticClass:"line-number"},[s._v("15")]),n("br"),n("span",{staticClass:"line-number"},[s._v("16")]),n("br"),n("span",{staticClass:"line-number"},[s._v("17")]),n("br"),n("span",{staticClass:"line-number"},[s._v("18")]),n("br"),n("span",{staticClass:"line-number"},[s._v("19")]),n("br"),n("span",{staticClass:"line-number"},[s._v("20")]),n("br")])])])]),s._v(" "),n("p",[n("strong",[s._v("重写和重载的区别:")])]),s._v(" "),n("ul",[n("li",[s._v("范围区别:对于类中函数的重载或者重写而言,重载发生在同一个类的内部,重写发生在不同的类之间(子类和父类之间)。")]),s._v(" "),n("li",[s._v("参数区别:重载的函数需要与原函数有相同的函数名、不同的参数列表,不关注函数的返回值类型;重写的函数的函数名、参数列表和返回值类型都需要和原函数相同,父类中被重写的函数需要有 virtual 修饰。")]),s._v(" "),n("li",[s._v("virtual 关键字:重写的函数基类中必须有 virtual 关键字的修饰,重载的函数可以有 virtual 关键字的修饰也可以没有。")])]),s._v(" "),n("p",[n("strong",[s._v("隐藏和重写,重载的区别:")])]),s._v(" "),n("ul",[n("li",[n("p",[s._v("范围区别:隐藏与重载范围不同,隐藏发生在不同类中。")])]),s._v(" "),n("li",[n("p",[s._v("参数区别:隐藏函数和被隐藏函数参数列表可以相同,也可以不同,但函数名一定相同;当参数不同时,无论基类中的函数是否被 virtual 修饰,基类函数都是被隐藏,而不是重写。")])])]),s._v(" "),n("h2",{attrs:{id:"如何理解-c-是面向对象编程"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#如何理解-c-是面向对象编程"}},[s._v("#")]),s._v(" 如何理解 C++ 是面向对象编程")]),s._v(" "),n("p",[n("strong",[s._v("面试高频指数:★★★☆☆")])]),s._v(" "),n("p",[s._v("说明:该问题最好结合自己的项目经历进行展开解释,或举一些恰当的例子,同时对比下面向过程编程。")]),s._v(" "),n("ul",[n("li",[n("p",[s._v("面向过程编程:一种以执行程序操作的过程或函数为中心编写软件的方法。程序的数据通常存储在变量中,与这些过程是分开的。所以必须将变量传递给需要使用它们的函数。缺点:随着程序变得越来越复杂,程序数据与运行代码的分离可能会导致问题。例如,程序的规范经常会发生变化,从而需要更改数据的格式或数据结构的设计。当数据结构发生变化时,对数据进行操作的代码也必须更改为接受新的格式。查找需要更改的所有代码会为程序员带来额外的工作,并增加了使代码出现错误的机会。")])]),s._v(" "),n("li",[n("p",[s._v("面向对象编程(Object-Oriented Programming, OOP):以创建和使用对象为中心。一个对象(Object)就是一个软件实体,它将数据和程序在一个单元中组合起来。对象的数据项,也称为其属性,存储在成员变量中。对象执行的过程被称为其成员函数。将对象的数据和过程绑定在一起则被称为封装。")])])]),s._v(" "),n("p",[n("strong",[s._v("面向对象编程进一步说明:")])]),s._v(" "),n("p",[s._v("面向对象编程将数据成员和成员函数封装到一个类中,并声明数据成员和成员函数的访问级别(public、private、protected),以便控制类对象对数据成员和函数的访问,对数据成员起到一定的保护作用。而且在类的对象调用成员函数时,只需知道成员函数的名、参数列表以及返回值类型即可,无需了解其函数的实现原理。当类内部的数据成员或者成员函数发生改变时,不影响类外部的代码。")]),s._v(" "),n("h2",{attrs:{id:"什么是多态-多态如何实现"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#什么是多态-多态如何实现"}},[s._v("#")]),s._v(" 什么是多态?多态如何实现?")]),s._v(" "),n("p",[n("strong",[s._v("面试高频指数:★★★★★")])]),s._v(" "),n("p",[s._v("**多态:**多态就是不同继承类的对象,对同一消息做出不同的响应,基类的指针指向或绑定到派生类的对象,使得基类指针呈现不同的表现方式。在基类的函数前加上 virtual 关键字,在派生类中重写该函数,运行时将会根据对象的实际类型来调用相应的函数。如果对象类型是派生类,就调用派生类的函数;如果对象类型是基类,就调用基类的函数。")]),s._v(" "),n("p",[s._v("**实现方法:**多态是通过虚函数实现的,虚函数的地址保存在虚函数表中,虚函数表的地址保存在含有虚函数的类的实例对象的内存空间中。")]),s._v(" "),n("p",[n("strong",[s._v("实现过程:")])]),s._v(" "),n("ul",[n("li",[s._v("在类中用 virtual 关键字声明的函数叫做虚函数;")]),s._v(" "),n("li",[s._v("存在虚函数的类都有一个虚函数表,当创建一个该类的对象时,该对象有一个指向虚函数表的虚表指针(虚函数表和类对应的,虚表指针是和对象对应);")]),s._v(" "),n("li",[s._v("当基类指针指向派生类对象,基类指针调用虚函数时,基类指针指向派生类的虚表指针,由于该虚表指针指向派生类虚函数表,通过遍历虚表,寻找相应的虚函数。")])]),s._v(" "),n("p",[s._v("举例:")]),s._v(" "),n("div",{staticClass:"language-c++ line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v('#include \nusing namespace std;\n\nclass Base\n{\npublic:\n virtual void fun() { cout << "Base::fun()" << endl; }\n\n virtual void fun1() { cout << "Base::fun1()" << endl; }\n\n virtual void fun2() { cout << "Base::fun2()" << endl; }\n};\nclass Derive : public Base\n{\npublic:\n void fun() { cout << "Derive::fun()" << endl; }\n\n virtual void D_fun1() { cout << "Derive::D_fun1()" << endl; }\n\n virtual void D_fun2() { cout << "Derive::D_fun2()" << endl; }\n};\nint main()\n{\n Base *p = new Derive();\n p->fun(); // Derive::fun() 调用派生类中的虚函数\n return 0;\n}\n')])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br"),n("span",{staticClass:"line-number"},[s._v("8")]),n("br"),n("span",{staticClass:"line-number"},[s._v("9")]),n("br"),n("span",{staticClass:"line-number"},[s._v("10")]),n("br"),n("span",{staticClass:"line-number"},[s._v("11")]),n("br"),n("span",{staticClass:"line-number"},[s._v("12")]),n("br"),n("span",{staticClass:"line-number"},[s._v("13")]),n("br"),n("span",{staticClass:"line-number"},[s._v("14")]),n("br"),n("span",{staticClass:"line-number"},[s._v("15")]),n("br"),n("span",{staticClass:"line-number"},[s._v("16")]),n("br"),n("span",{staticClass:"line-number"},[s._v("17")]),n("br"),n("span",{staticClass:"line-number"},[s._v("18")]),n("br"),n("span",{staticClass:"line-number"},[s._v("19")]),n("br"),n("span",{staticClass:"line-number"},[s._v("20")]),n("br"),n("span",{staticClass:"line-number"},[s._v("21")]),n("br"),n("span",{staticClass:"line-number"},[s._v("22")]),n("br"),n("span",{staticClass:"line-number"},[s._v("23")]),n("br"),n("span",{staticClass:"line-number"},[s._v("24")]),n("br"),n("span",{staticClass:"line-number"},[s._v("25")]),n("br"),n("span",{staticClass:"line-number"},[s._v("26")]),n("br"),n("span",{staticClass:"line-number"},[s._v("27")]),n("br")])]),n("h1",{attrs:{id:"关键字库函数"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#关键字库函数"}},[s._v("#")]),s._v(" 关键字库函数")]),s._v(" "),n("p",[s._v("第四章主要讲解关键字和库函数相关的内容,重点是对比功能上相似的一些关键字、库函数的区别,或者是名称上相似的关键字、库函数的区别,还对对一些关键字的用法进行讲解。")]),s._v(" "),n("h2",{attrs:{id:"sizeof-和-strlen-的区别"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#sizeof-和-strlen-的区别"}},[s._v("#")]),s._v(" sizeof 和 strlen 的区别")]),s._v(" "),n("p",[n("strong",[s._v("面试高频指数:★★★☆☆")])]),s._v(" "),n("ol",[n("li",[n("p",[s._v("strlen 是头文件 "),n("code",[s._v("")]),s._v(" 中的函数,sizeof 是 C++ 中的运算符。")])]),s._v(" "),n("li",[n("p",[s._v("strlen 测量的是字符串的实际长度(其源代码如下),以 \\0 结束。而 sizeof 测量的是字符数组的分配大小。")]),s._v(" "),n("p",[s._v("strlen 源代码:")]),s._v(" "),n("div",{staticClass:"language-c++ line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v("size_t strlen(const char *str) {\n size_t length = 0;\n while (*str++)\n ++length;\n return length;\n}\n")])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br")])]),n("p",[s._v("举例:")]),s._v(" "),n("div",{staticClass:"language-c++ line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v('#include \n#include \n\nusing namespace std;\n\nint main()\n{\n char arr[10] = "hello";\n cout << strlen(arr) << endl; // 5\n cout << sizeof(arr) << endl; // 10\n return 0;\n}\n')])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br"),n("span",{staticClass:"line-number"},[s._v("8")]),n("br"),n("span",{staticClass:"line-number"},[s._v("9")]),n("br"),n("span",{staticClass:"line-number"},[s._v("10")]),n("br"),n("span",{staticClass:"line-number"},[s._v("11")]),n("br"),n("span",{staticClass:"line-number"},[s._v("12")]),n("br")])])]),s._v(" "),n("li",[n("p",[s._v("若字符数组 arr 作为函数的形参,sizeof(arr) 中 arr 被当作字符指针来处理,strlen(arr) 中 arr 依然是字符数组,从下述程序的运行结果中就可以看出。")]),s._v(" "),n("div",{staticClass:"language-c++ line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v("#include \n#include \n\nusing namespace std;\n\nvoid size_of(char arr[])\n{\n cout << sizeof(arr) << endl; // warning: 'sizeof' on array function parameter 'arr' will return size of 'char*' .\n cout << strlen(arr) << endl;\n}\n\nint main()\n{\n char arr[20] = \"hello\";\n size_of(arr);\n return 0;\n}\n/*\n输出结果:\n8\n5\n*/\n")])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br"),n("span",{staticClass:"line-number"},[s._v("8")]),n("br"),n("span",{staticClass:"line-number"},[s._v("9")]),n("br"),n("span",{staticClass:"line-number"},[s._v("10")]),n("br"),n("span",{staticClass:"line-number"},[s._v("11")]),n("br"),n("span",{staticClass:"line-number"},[s._v("12")]),n("br"),n("span",{staticClass:"line-number"},[s._v("13")]),n("br"),n("span",{staticClass:"line-number"},[s._v("14")]),n("br"),n("span",{staticClass:"line-number"},[s._v("15")]),n("br"),n("span",{staticClass:"line-number"},[s._v("16")]),n("br"),n("span",{staticClass:"line-number"},[s._v("17")]),n("br"),n("span",{staticClass:"line-number"},[s._v("18")]),n("br"),n("span",{staticClass:"line-number"},[s._v("19")]),n("br"),n("span",{staticClass:"line-number"},[s._v("20")]),n("br"),n("span",{staticClass:"line-number"},[s._v("21")]),n("br"),n("span",{staticClass:"line-number"},[s._v("22")]),n("br")])])]),s._v(" "),n("li",[n("p",[s._v("strlen 本身是库函数,因此在程序运行过程中,计算长度;而 sizeof 在编译时,计算长度;")])]),s._v(" "),n("li",[n("p",[s._v("sizeof 的参数可以是类型,也可以是变量;strlen 的参数必须是 char* 类型的变量。")])])]),s._v(" "),n("h2",{attrs:{id:"lambda-表达式-匿名函数-的具体应用和使用场景"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#lambda-表达式-匿名函数-的具体应用和使用场景"}},[s._v("#")]),s._v(" lambda 表达式(匿名函数)的具体应用和使用场景")]),s._v(" "),n("p",[n("strong",[s._v("面试高频指数:★★★☆☆")])]),s._v(" "),n("p",[n("code",[s._v("lambda")]),s._v(" 表达式的定义形式如下:")]),s._v(" "),n("div",{staticClass:"language-c++ line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v("[capture list] (parameter list) -> reurn type\n{\n function body\n}\n")])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br")])]),n("p",[s._v("其中:")]),s._v(" "),n("ul",[n("li",[n("p",[s._v("capture list:捕获列表,指 lambda 表达式所在函数中定义的局部变量的列表,通常为空,但如果函数体中用到了 lambda 表达式所在函数的局部变量,必须捕获该变量,即将此变量写在捕获列表中。捕获方式分为:引用捕获方式 [&]、值捕获方式 [=]。")])]),s._v(" "),n("li",[n("p",[s._v("return type、parameter list、function body:分别表示返回值类型、参数列表、函数体,和普通函数一样。")])])]),s._v(" "),n("p",[s._v("举例:\nlambda 表达式常搭配排序算法使用。")]),s._v(" "),n("div",{staticClass:"language-c++ line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v('#include \n#include \n#include \nusing namespace std;\n\nint main()\n{\n vector arr = {3, 4, 76, 12, 54, 90, 34};\n sort(arr.begin(), arr.end(), [](int a, int b) { return a > b; }); // 降序排序\n for (auto a : arr)\n {\n cout << a << " ";\n }\n return 0;\n}\n/*\n运行结果:90 76 54 34 12 4 3\n*/\n')])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br"),n("span",{staticClass:"line-number"},[s._v("8")]),n("br"),n("span",{staticClass:"line-number"},[s._v("9")]),n("br"),n("span",{staticClass:"line-number"},[s._v("10")]),n("br"),n("span",{staticClass:"line-number"},[s._v("11")]),n("br"),n("span",{staticClass:"line-number"},[s._v("12")]),n("br"),n("span",{staticClass:"line-number"},[s._v("13")]),n("br"),n("span",{staticClass:"line-number"},[s._v("14")]),n("br"),n("span",{staticClass:"line-number"},[s._v("15")]),n("br"),n("span",{staticClass:"line-number"},[s._v("16")]),n("br"),n("span",{staticClass:"line-number"},[s._v("17")]),n("br"),n("span",{staticClass:"line-number"},[s._v("18")]),n("br")])]),n("h2",{attrs:{id:"explicit-的作用-如何避免编译器进行隐式类型转换"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#explicit-的作用-如何避免编译器进行隐式类型转换"}},[s._v("#")]),s._v(" explicit 的作用(如何避免编译器进行隐式类型转换)")]),s._v(" "),n("p",[n("strong",[s._v("面试高频指数:★★★☆☆")])]),s._v(" "),n("p",[s._v("作用:用来声明类构造函数是显示调用的,而非隐式调用,可以阻止调用构造函数时进行隐式转换。只可用于修饰单参构造函数,因为无参构造函数和多参构造函数本身就是显示调用的,再加上 explicit 关键字也没有什么意义。")]),s._v(" "),n("p",[s._v("隐式转换:")]),s._v(" "),n("div",{staticClass:"language-c++ line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v("#include \n#include \nusing namespace std;\n\nclass A\n{\npublic:\n int var;\n A(int tmp)\n {\n var = tmp;\n }\n};\nint main()\n{\n A ex = 10; // 发生了隐式转换\n return 0;\n}\n")])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br"),n("span",{staticClass:"line-number"},[s._v("8")]),n("br"),n("span",{staticClass:"line-number"},[s._v("9")]),n("br"),n("span",{staticClass:"line-number"},[s._v("10")]),n("br"),n("span",{staticClass:"line-number"},[s._v("11")]),n("br"),n("span",{staticClass:"line-number"},[s._v("12")]),n("br"),n("span",{staticClass:"line-number"},[s._v("13")]),n("br"),n("span",{staticClass:"line-number"},[s._v("14")]),n("br"),n("span",{staticClass:"line-number"},[s._v("15")]),n("br"),n("span",{staticClass:"line-number"},[s._v("16")]),n("br"),n("span",{staticClass:"line-number"},[s._v("17")]),n("br"),n("span",{staticClass:"line-number"},[s._v("18")]),n("br")])]),n("p",[s._v("上述代码中,A ex = 10; 在编译时,进行了隐式转换,将 10 转换成 A 类型的对象,然后将该对象赋值给 ex,等同于如下操作:")]),s._v(" "),n("p",[s._v("为了避免隐式转换,可用 explicit 关键字进行声明:")]),s._v(" "),n("div",{staticClass:"language-c++ line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v("#include \n#include \nusing namespace std;\n\nclass A\n{\npublic:\n int var;\n explicit A(int tmp)\n {\n var = tmp;\n cout << var << endl;\n }\n};\nint main()\n{\n A ex(100);\n A ex1 = 10; // error: conversion from 'int' to non-scalar type 'A' requested\n return 0;\n}\n")])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br"),n("span",{staticClass:"line-number"},[s._v("8")]),n("br"),n("span",{staticClass:"line-number"},[s._v("9")]),n("br"),n("span",{staticClass:"line-number"},[s._v("10")]),n("br"),n("span",{staticClass:"line-number"},[s._v("11")]),n("br"),n("span",{staticClass:"line-number"},[s._v("12")]),n("br"),n("span",{staticClass:"line-number"},[s._v("13")]),n("br"),n("span",{staticClass:"line-number"},[s._v("14")]),n("br"),n("span",{staticClass:"line-number"},[s._v("15")]),n("br"),n("span",{staticClass:"line-number"},[s._v("16")]),n("br"),n("span",{staticClass:"line-number"},[s._v("17")]),n("br"),n("span",{staticClass:"line-number"},[s._v("18")]),n("br"),n("span",{staticClass:"line-number"},[s._v("19")]),n("br"),n("span",{staticClass:"line-number"},[s._v("20")]),n("br")])]),n("h2",{attrs:{id:"c-和-c-static-的区别"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#c-和-c-static-的区别"}},[s._v("#")]),s._v(" C 和 C++ static 的区别")]),s._v(" "),n("p",[n("strong",[s._v("面试高频指数:★☆☆☆☆")])]),s._v(" "),n("ul",[n("li",[s._v("在 C 语言中,使用 static 可以定义局部静态变量、外部静态变量、静态函数")]),s._v(" "),n("li",[s._v("在 C++ 中,使用 static 可以定义局部静态变量、外部静态变量、静态函数、静态成员变量和静态成员函数。因为 C++ 中有类的概念,静态成员变量、静态成员函数都是与类有关的概念。")])]),s._v(" "),n("h2",{attrs:{id:"static-的作用"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#static-的作用"}},[s._v("#")]),s._v(" static 的作用")]),s._v(" "),n("p",[n("strong",[s._v("面试高频指数:★★★★☆")]),s._v("\n作用:\nstatic 定义静态变量,静态函数。")]),s._v(" "),n("ul",[n("li",[n("p",[s._v("保持变量内容持久:static 作用于局部变量,改变了局部变量的生存周期,使得该变量存在于定义后直到程序运行结束的这段时间。")]),s._v(" "),n("div",{staticClass:"language-c++ line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v('#include \nusing namespace std;\n\nint fun(){\n static int var = 1; // var 只在第一次进入这个函数的时初始化\n var += 1;\n return var;\n}\n\nint main()\n{\n for(int i = 0; i < 10; ++i)\n cout << fun() << " "; // 2 3 4 5 6 7 8 9 10 11\n return 0;\n}\n')])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br"),n("span",{staticClass:"line-number"},[s._v("8")]),n("br"),n("span",{staticClass:"line-number"},[s._v("9")]),n("br"),n("span",{staticClass:"line-number"},[s._v("10")]),n("br"),n("span",{staticClass:"line-number"},[s._v("11")]),n("br"),n("span",{staticClass:"line-number"},[s._v("12")]),n("br"),n("span",{staticClass:"line-number"},[s._v("13")]),n("br"),n("span",{staticClass:"line-number"},[s._v("14")]),n("br"),n("span",{staticClass:"line-number"},[s._v("15")]),n("br")])])]),s._v(" "),n("li",[n("p",[s._v("隐藏:static 作用于全局变量和函数,改变了全局变量和函数的作用域,使得全局变量和函数只能在定义它的文件中使用,在源文件中不具有全局可见性。(注:普通全局变量和函数具有全局可见性,即其他的源文件也可以使用。)")])]),s._v(" "),n("li",[n("p",[s._v("static 作用于类的成员变量和类的成员函数,使得类变量或者类成员函数和类有关,也就是说可以不定义类的对象就可以通过类访问这些静态成员。注意:类的静态成员函数中只能访问静态成员变量或者静态成员函数,不能将静态成员函数定义成虚函数。")]),s._v(" "),n("div",{staticClass:"language-c++ line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v("#include\nusing namespace std;\n\nclass A\n{\nprivate:\n int var;\n static int s_var; // 静态成员变量\npublic:\n void show()\n {\n cout << s_var++ << endl;\n }\n static void s_show()\n {\n cout << s_var << endl;\n // cout << var << endl; // error: invalid use of member 'A::a' in static member function. 静态成员函数不能调用非静态成员变量。无法使用 this.var\n // show(); // error: cannot call member function 'void A::show()' without object. 静态成员函数不能调用非静态成员函数。无法使用 this.show()\n }\n};\nint A::s_var = 1; // 静态成员变量在类外进行初始化赋值,默认初始化为 0\n\nint main()\n{\n\n // cout << A::sa << endl; // error: 'int A::sa' is private within this context\n A ex;\n ex.show();\n A::s_show();\n}\n")])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br"),n("span",{staticClass:"line-number"},[s._v("8")]),n("br"),n("span",{staticClass:"line-number"},[s._v("9")]),n("br"),n("span",{staticClass:"line-number"},[s._v("10")]),n("br"),n("span",{staticClass:"line-number"},[s._v("11")]),n("br"),n("span",{staticClass:"line-number"},[s._v("12")]),n("br"),n("span",{staticClass:"line-number"},[s._v("13")]),n("br"),n("span",{staticClass:"line-number"},[s._v("14")]),n("br"),n("span",{staticClass:"line-number"},[s._v("15")]),n("br"),n("span",{staticClass:"line-number"},[s._v("16")]),n("br"),n("span",{staticClass:"line-number"},[s._v("17")]),n("br"),n("span",{staticClass:"line-number"},[s._v("18")]),n("br"),n("span",{staticClass:"line-number"},[s._v("19")]),n("br"),n("span",{staticClass:"line-number"},[s._v("20")]),n("br"),n("span",{staticClass:"line-number"},[s._v("21")]),n("br"),n("span",{staticClass:"line-number"},[s._v("22")]),n("br"),n("span",{staticClass:"line-number"},[s._v("23")]),n("br"),n("span",{staticClass:"line-number"},[s._v("24")]),n("br"),n("span",{staticClass:"line-number"},[s._v("25")]),n("br"),n("span",{staticClass:"line-number"},[s._v("26")]),n("br"),n("span",{staticClass:"line-number"},[s._v("27")]),n("br"),n("span",{staticClass:"line-number"},[s._v("28")]),n("br"),n("span",{staticClass:"line-number"},[s._v("29")]),n("br"),n("span",{staticClass:"line-number"},[s._v("30")]),n("br")])])])]),s._v(" "),n("h2",{attrs:{id:"static-在类中使用的注意事项-定义、初始化和使用"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#static-在类中使用的注意事项-定义、初始化和使用"}},[s._v("#")]),s._v(" static 在类中使用的注意事项(定义、初始化和使用)")]),s._v(" "),n("p",[n("strong",[s._v("面试高频指数:★★★★★")])]),s._v(" "),n("p",[n("strong",[s._v("static 静态成员变量:")])]),s._v(" "),n("ol",[n("li",[n("p",[s._v("静态成员变量是在类内进行声明,在类外进行定义和初始化,在类外进行定义和初始化的时候不要出现 static 关键字和 private、public、protected 访问规则。")])]),s._v(" "),n("li",[n("p",[s._v("静态成员变量相当于类域中的全局变量,被类的所有对象所共享,包括派生类的对象。")])]),s._v(" "),n("li",[n("p",[s._v("静态成员变量可以作为成员函数的参数,而普通成员变量不可以。")]),s._v(" "),n("div",{staticClass:"language-c++ line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v("#include \nusing namespace std;\n\nclass A\n{\npublic:\n static int s_var;\n int var;\n void fun1(int i = s_var); // 正确,静态成员变量可以作为成员函数的参数\n void fun2(int i = var); // error: invalid use of non-static data member 'A::var'\n};\nint main()\n{\n return 0;\n}\n")])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br"),n("span",{staticClass:"line-number"},[s._v("8")]),n("br"),n("span",{staticClass:"line-number"},[s._v("9")]),n("br"),n("span",{staticClass:"line-number"},[s._v("10")]),n("br"),n("span",{staticClass:"line-number"},[s._v("11")]),n("br"),n("span",{staticClass:"line-number"},[s._v("12")]),n("br"),n("span",{staticClass:"line-number"},[s._v("13")]),n("br"),n("span",{staticClass:"line-number"},[s._v("14")]),n("br"),n("span",{staticClass:"line-number"},[s._v("15")]),n("br")])])]),s._v(" "),n("li",[n("p",[s._v("静态数据成员的类型可以是所属类的类型,而普通数据成员的类型只能是该类类型的指针或引用。")]),s._v(" "),n("div",{staticClass:"language-c++ line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v("#include \nusing namespace std;\n\nclass A\n{\npublic:\n static A s_var; // 正确,静态数据成员\n A var; // error: field 'var' has incomplete type 'A'\n A *p; // 正确,指针\n A &var1; // 正确,引用\n};\n\nint main()\n{\n return 0;\n}\n")])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br"),n("span",{staticClass:"line-number"},[s._v("8")]),n("br"),n("span",{staticClass:"line-number"},[s._v("9")]),n("br"),n("span",{staticClass:"line-number"},[s._v("10")]),n("br"),n("span",{staticClass:"line-number"},[s._v("11")]),n("br"),n("span",{staticClass:"line-number"},[s._v("12")]),n("br"),n("span",{staticClass:"line-number"},[s._v("13")]),n("br"),n("span",{staticClass:"line-number"},[s._v("14")]),n("br"),n("span",{staticClass:"line-number"},[s._v("15")]),n("br"),n("span",{staticClass:"line-number"},[s._v("16")]),n("br")])])])]),s._v(" "),n("p",[n("strong",[s._v("static 静态成员函数:")])]),s._v(" "),n("ol",[n("li",[n("p",[s._v("静态成员函数不能调用非静态成员变量或者非静态成员函数,因为静态成员函数没有 this 指针。静态成员函数做为类作用域的全局函数。")])]),s._v(" "),n("li",[n("p",[s._v("静态成员函数不能声明成虚函数(virtual)、const 函数和 volatile 函数。")])])]),s._v(" "),n("h2",{attrs:{id:"static-全局变量和普通全局变量的异同"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#static-全局变量和普通全局变量的异同"}},[s._v("#")]),s._v(" static 全局变量和普通全局变量的异同")]),s._v(" "),n("p",[n("strong",[s._v("面试高频指数:★★★☆☆")])]),s._v(" "),n("p",[s._v("相同点:")]),s._v(" "),n("ul",[n("li",[s._v("存储方式:普通全局变量和 static 全局变量都是静态存储方式。")])]),s._v(" "),n("p",[s._v("不同点:")]),s._v(" "),n("ul",[n("li",[n("p",[s._v("作用域:普通全局变量的作用域是整个源程序,当一个源程序由多个源文件组成时,普通全局变量在各个源文件中都是有效的;静态全局变量则限制了其作用域,即只在定义该变量的源文件内有效,在同一源程序的其它源文件中不能使用它。由于静态全局变量的作用域限于一个源文件内,只能为该源文件内的函数公用,因此可以避免在其他源文件中引起错误。")])]),s._v(" "),n("li",[n("p",[s._v("初始化:静态全局变量只初始化一次,防止在其他文件中使用。")])])]),s._v(" "),n("h2",{attrs:{id:"const-作用及用法"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#const-作用及用法"}},[s._v("#")]),s._v(" const 作用及用法")]),s._v(" "),n("p",[n("strong",[s._v("面试高频指数:★★★☆☆")])]),s._v(" "),n("p",[n("strong",[s._v("作用:")])]),s._v(" "),n("ul",[n("li",[s._v("const 修饰成员变量,定义成 const 常量,相较于宏常量,可进行类型检查,节省内存空间,提高了效率。")]),s._v(" "),n("li",[s._v("const 修饰函数参数,使得传递过来的函数参数的值不能改变。")]),s._v(" "),n("li",[s._v("const 修饰成员函数,使得成员函数不能修改任何类型的成员变量(mutable 修饰的变量除外),也不能调用非 const 成员函数,因为非 const 成员函数可能会修改成员变量。")])]),s._v(" "),n("p",[n("strong",[s._v("在类中的用法:")])]),s._v(" "),n("p",[s._v("const 成员变量:")]),s._v(" "),n("ol",[n("li",[n("p",[s._v("const 成员变量只能在类内声明、定义,在构造函数初始化列表中初始化。")])]),s._v(" "),n("li",[n("p",[s._v("const 成员变量只在某个对象的生存周期内是常量,对于整个类而言却是可变的,因为类可以创建多个对象,不同类的 const 成员变量的值是不同的。因此不能在类的声明中初始化 const 成员变量,类的对象还没有创建,编译器不知道他的值。")])])]),s._v(" "),n("p",[s._v("const 成员函数:")]),s._v(" "),n("ol",[n("li",[n("p",[s._v("不能修改成员变量的值,除非有 mutable 修饰;只能访问成员变量。")])]),s._v(" "),n("li",[n("p",[s._v("不能调用非常量成员函数,以防修改成员变量的值。")])])]),s._v(" "),n("div",{staticClass:"language-c++ line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v("#include \nusing namespace std;\n\nclass A\n{\npublic:\n int var;\n A(int tmp) : var(tmp) {}\n void c_fun(int tmp) const // const 成员函数\n {\n var = tmp; // error: assignment of member 'A::var' in read-only object. 在 const 成员函数中,不能修改任何类成员变量。\n fun(tmp); // error: passing 'const A' as 'this' argument discards qualifiers. const 成员函数不能调用非 const 成员函数,因为非 const 成员函数可能会修改成员变量。\n }\n\n void fun(int tmp)\n {\n var = tmp;\n }\n};\n\nint main()\n{\n return 0;\n}\n")])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br"),n("span",{staticClass:"line-number"},[s._v("8")]),n("br"),n("span",{staticClass:"line-number"},[s._v("9")]),n("br"),n("span",{staticClass:"line-number"},[s._v("10")]),n("br"),n("span",{staticClass:"line-number"},[s._v("11")]),n("br"),n("span",{staticClass:"line-number"},[s._v("12")]),n("br"),n("span",{staticClass:"line-number"},[s._v("13")]),n("br"),n("span",{staticClass:"line-number"},[s._v("14")]),n("br"),n("span",{staticClass:"line-number"},[s._v("15")]),n("br"),n("span",{staticClass:"line-number"},[s._v("16")]),n("br"),n("span",{staticClass:"line-number"},[s._v("17")]),n("br"),n("span",{staticClass:"line-number"},[s._v("18")]),n("br"),n("span",{staticClass:"line-number"},[s._v("19")]),n("br"),n("span",{staticClass:"line-number"},[s._v("20")]),n("br"),n("span",{staticClass:"line-number"},[s._v("21")]),n("br"),n("span",{staticClass:"line-number"},[s._v("22")]),n("br"),n("span",{staticClass:"line-number"},[s._v("23")]),n("br"),n("span",{staticClass:"line-number"},[s._v("24")]),n("br")])]),n("h2",{attrs:{id:"define-和-const-的区别"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#define-和-const-的区别"}},[s._v("#")]),s._v(" define 和 const 的区别")]),s._v(" "),n("p",[n("strong",[s._v("面试高频指数:★★★☆☆")]),s._v("\n区别:")]),s._v(" "),n("ul",[n("li",[s._v("编译阶段:define 是在编译预处理阶段进行替换,const 是在编译阶段确定其值。")]),s._v(" "),n("li",[s._v("安全性:define 定义的宏常量没有数据类型,只是进行简单的替换,不会进行类型安全的检查;const 定义的常量是有类型的,是要进行判断的,可以避免一些低级的错误。")]),s._v(" "),n("li",[s._v("内存占用:define 定义的宏常量,在程序中使用多少次就会进行多少次替换,内存中有多个备份,占用的是代码段的空间;const 定义的常量占用静态存储区的空间,程序运行过程中只有一份。")]),s._v(" "),n("li",[s._v("调试:define 定义的宏常量不能调试,因为在预编译阶段就已经进行替换了;const 定义的常量可以进行调试。")])]),s._v(" "),n("p",[s._v("const 的优点:")]),s._v(" "),n("ul",[n("li",[n("p",[s._v("有数据类型,在定义式可进行安全性检查。")])]),s._v(" "),n("li",[n("p",[s._v("可调式。")])]),s._v(" "),n("li",[n("p",[s._v("占用较少的空间。")])])]),s._v(" "),n("h2",{attrs:{id:"define-和-typedef-的区别"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#define-和-typedef-的区别"}},[s._v("#")]),s._v(" define 和 typedef 的区别")]),s._v(" "),n("p",[n("strong",[s._v("面试高频指数:★★☆☆☆")])]),s._v(" "),n("ul",[n("li",[n("p",[s._v("原理:#define 作为预处理指令,在编译预处理时进行替换操作,不作正确性检查,只有在编译已被展开的源程序时才会发现可能的错误并报错。typedef 是关键字,在编译时处理,有类型检查功能,用来给一个已经存在的类型一个别名,但不能在一个函数定义里面使用 typedef 。")])]),s._v(" "),n("li",[n("p",[s._v("功能:typedef 用来定义类型的别名,方便使用。#define 不仅可以为类型取别名,还可以定义常量、变量、编译开关等。")])]),s._v(" "),n("li",[n("p",[s._v("作用域:#define 没有作用域的限制,只要是之前预定义过的宏,在以后的程序中都可以使用,而 typedef 有自己的作用域。")])]),s._v(" "),n("li",[n("p",[s._v("指针的操作:typedef 和 #define 在处理指针时不完全一样")])])]),s._v(" "),n("div",{staticClass:"language-c++ line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v("#include \n#define INTPTR1 int *\ntypedef int * INTPTR2;\n\nusing namespace std;\n\nint main()\n{\n INTPTR1 p1, p2; // p1: int *; p2: int\n INTPTR2 p3, p4; // p3: int *; p4: int *\n\n int var = 1;\n const INTPTR1 p5 = &var; // 相当于 const int * p5; 常量指针,即不可以通过 p5 去修改 p5 指向的内容,但是 p5 可以指向其他内容。\n const INTPTR2 p6 = &var; // 相当于 int * const p6; 指针常量,不可使 p6 再指向其他内容。\n\n return 0;\n}\n")])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br"),n("span",{staticClass:"line-number"},[s._v("8")]),n("br"),n("span",{staticClass:"line-number"},[s._v("9")]),n("br"),n("span",{staticClass:"line-number"},[s._v("10")]),n("br"),n("span",{staticClass:"line-number"},[s._v("11")]),n("br"),n("span",{staticClass:"line-number"},[s._v("12")]),n("br"),n("span",{staticClass:"line-number"},[s._v("13")]),n("br"),n("span",{staticClass:"line-number"},[s._v("14")]),n("br"),n("span",{staticClass:"line-number"},[s._v("15")]),n("br"),n("span",{staticClass:"line-number"},[s._v("16")]),n("br"),n("span",{staticClass:"line-number"},[s._v("17")]),n("br")])]),n("p",[s._v("注:对于指针常量和常量指针的区别,可查阅第六章。")]),s._v(" "),n("h2",{attrs:{id:"用宏实现比较大小-以及两个数中的最小值"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#用宏实现比较大小-以及两个数中的最小值"}},[s._v("#")]),s._v(" 用宏实现比较大小,以及两个数中的最小值")]),s._v(" "),n("p",[n("strong",[s._v("面试高频指数:★☆☆☆☆")])]),s._v(" "),n("p",[s._v("具体代码如下:")]),s._v(" "),n("div",{staticClass:"language-c++ line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v("#include \n#define MAX(X, Y) ((X)>(Y)?(X):(Y))\n#define MIN(X, Y) ((X)<(Y)?(X):(Y))\nusing namespace std;\n\nint main ()\n{\n int var1 = 10, var2 = 100;\n cout << MAX(var1, var2) << endl;\n cout << MIN(var1, var2) << endl;\n return 0;\n}\n/*\n程序运行结果:\n100\n10\n*/\n")])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br"),n("span",{staticClass:"line-number"},[s._v("8")]),n("br"),n("span",{staticClass:"line-number"},[s._v("9")]),n("br"),n("span",{staticClass:"line-number"},[s._v("10")]),n("br"),n("span",{staticClass:"line-number"},[s._v("11")]),n("br"),n("span",{staticClass:"line-number"},[s._v("12")]),n("br"),n("span",{staticClass:"line-number"},[s._v("13")]),n("br"),n("span",{staticClass:"line-number"},[s._v("14")]),n("br"),n("span",{staticClass:"line-number"},[s._v("15")]),n("br"),n("span",{staticClass:"line-number"},[s._v("16")]),n("br"),n("span",{staticClass:"line-number"},[s._v("17")]),n("br")])]),n("h2",{attrs:{id:"inline-作用及使用方法"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#inline-作用及使用方法"}},[s._v("#")]),s._v(" inline 作用及使用方法")]),s._v(" "),n("p",[n("strong",[s._v("面试高频指数:★★★☆☆")])]),s._v(" "),n("p",[n("strong",[s._v("作用:")]),s._v("\ninline 是一个关键字,可以用于定义内联函数。内联函数,像普通函数一样被调用,但是在调用时并不通过函数调用的机制而是直接在调用点处展开,这样可以大大减少由函数调用带来的开销,从而提高程序的运行效率。")]),s._v(" "),n("p",[n("strong",[s._v("使用方法:")])]),s._v(" "),n("ol",[n("li",[n("p",[s._v("类内定义成员函数默认是内联函数")]),s._v(" "),n("p",[s._v("在类内定义成员函数,可以不用在函数头部加 inline 关键字,因为编译器会自动将类内定义的函数(构造函数、析构函数、普通成员函数等)声明为内联函数,代码如下:")]),s._v(" "),n("div",{staticClass:"language-c++ line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v("#include \nusing namespace std;\n\nclass A{\npublic:\n int var;\n A(int tmp){\n var = tmp;\n }\n void fun(){\n cout << var << endl;\n }\n};\n\nint main()\n{\n return 0;\n}\n")])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br"),n("span",{staticClass:"line-number"},[s._v("8")]),n("br"),n("span",{staticClass:"line-number"},[s._v("9")]),n("br"),n("span",{staticClass:"line-number"},[s._v("10")]),n("br"),n("span",{staticClass:"line-number"},[s._v("11")]),n("br"),n("span",{staticClass:"line-number"},[s._v("12")]),n("br"),n("span",{staticClass:"line-number"},[s._v("13")]),n("br"),n("span",{staticClass:"line-number"},[s._v("14")]),n("br"),n("span",{staticClass:"line-number"},[s._v("15")]),n("br"),n("span",{staticClass:"line-number"},[s._v("16")]),n("br"),n("span",{staticClass:"line-number"},[s._v("17")]),n("br"),n("span",{staticClass:"line-number"},[s._v("18")]),n("br")])])]),s._v(" "),n("li",[n("p",[s._v("类外定义成员函数,若想定义为内联函数,需用关键字声明\n当在类内声明函数,在类外定义函数时,如果想将该函数定义为内联函数,则可以在类内声明时不加 inline 关键字,而在类外定义函数时加上 inline 关键字。")]),s._v(" "),n("div",{staticClass:"language-c++ line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v("#include \nusing namespace std;\n\nclass A{\npublic:\n int var;\n A(int tmp){\n var = tmp;\n }\n void fun();\n};\n\ninline void A::fun(){\n cout << var << endl;\n}\n\nint main()\n{\n return 0;\n}\n")])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br"),n("span",{staticClass:"line-number"},[s._v("8")]),n("br"),n("span",{staticClass:"line-number"},[s._v("9")]),n("br"),n("span",{staticClass:"line-number"},[s._v("10")]),n("br"),n("span",{staticClass:"line-number"},[s._v("11")]),n("br"),n("span",{staticClass:"line-number"},[s._v("12")]),n("br"),n("span",{staticClass:"line-number"},[s._v("13")]),n("br"),n("span",{staticClass:"line-number"},[s._v("14")]),n("br"),n("span",{staticClass:"line-number"},[s._v("15")]),n("br"),n("span",{staticClass:"line-number"},[s._v("16")]),n("br"),n("span",{staticClass:"line-number"},[s._v("17")]),n("br"),n("span",{staticClass:"line-number"},[s._v("18")]),n("br"),n("span",{staticClass:"line-number"},[s._v("19")]),n("br"),n("span",{staticClass:"line-number"},[s._v("20")]),n("br")])])])]),s._v(" "),n("p",[s._v("另外,可以在声明函数和定义函数的同时加上 inline;也可以只在函数声明时加 inline,而定义函数时不加 inline。只要确保在调用该函数之前把 inline 的信息告知编译器即可。")]),s._v(" "),n("h2",{attrs:{id:"inline-函数工作原理"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#inline-函数工作原理"}},[s._v("#")]),s._v(" inline 函数工作原理")]),s._v(" "),n("p",[n("strong",[s._v("面试高频指数:★★☆☆☆")])]),s._v(" "),n("ul",[n("li",[n("p",[s._v("内联函数不是在调用时发生控制转移关系,而是在编译阶段将函数体嵌入到每一个调用该函数的语句块中,编译器会将程序中出现内联函数的调用表达式用内联函数的函数体来替换。")])]),s._v(" "),n("li",[n("p",[s._v("普通函数是将程序执行转移到被调用函数所存放的内存地址,当函数执行完后,返回到执行此函数前的地方。转移操作需要保护现场,被调函数执行完后,再恢复现场,该过程需要较大的资源开销。")])])]),s._v(" "),n("h2",{attrs:{id:"宏定义-define-和内联函数-inline-的区别"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#宏定义-define-和内联函数-inline-的区别"}},[s._v("#")]),s._v(" 宏定义(define)和内联函数(inline)的区别")]),s._v(" "),n("p",[n("strong",[s._v("面试高频指数:★★☆☆☆")])]),s._v(" "),n("ul",[n("li",[s._v("内联函数是在编译时展开,而宏在编译预处理时展开;在编译的时候,内联函数直接被嵌入到目标代码中去,而宏只是一个简单的文本替换。")]),s._v(" "),n("li",[s._v("内联函数是真正的函数,和普通函数调用的方法一样,在调用点处直接展开,避免了函数的参数压栈操作,减少了调用的开销。而宏定义编写较为复杂,常需要增加一些括号来避免歧义。")]),s._v(" "),n("li",[s._v("宏定义只进行文本替换,不会对参数的类型、语句能否正常编译等进行检查。而内联函数是真正的函数,会对参数的类型、函数体内的语句编写是否正确等进行检查。")])]),s._v(" "),n("p",[s._v("使用举例:")]),s._v(" "),n("div",{staticClass:"language-c++ line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v("#include \n\n#define MAX(a, b) ((a) > (b) ? (a) : (b))\n\nusing namespace std;\n\ninline int fun_max(int a, int b)\n{\n return a > b ? a : b;\n}\n\nint main()\n{\n int var = 1;\n cout << MAX(var, 5) << endl;\n cout << fun_max(var, 0) << endl;\n return 0;\n}\n/*\n程序运行结果:\n5\n1\n\n*/\n")])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br"),n("span",{staticClass:"line-number"},[s._v("8")]),n("br"),n("span",{staticClass:"line-number"},[s._v("9")]),n("br"),n("span",{staticClass:"line-number"},[s._v("10")]),n("br"),n("span",{staticClass:"line-number"},[s._v("11")]),n("br"),n("span",{staticClass:"line-number"},[s._v("12")]),n("br"),n("span",{staticClass:"line-number"},[s._v("13")]),n("br"),n("span",{staticClass:"line-number"},[s._v("14")]),n("br"),n("span",{staticClass:"line-number"},[s._v("15")]),n("br"),n("span",{staticClass:"line-number"},[s._v("16")]),n("br"),n("span",{staticClass:"line-number"},[s._v("17")]),n("br"),n("span",{staticClass:"line-number"},[s._v("18")]),n("br"),n("span",{staticClass:"line-number"},[s._v("19")]),n("br"),n("span",{staticClass:"line-number"},[s._v("20")]),n("br"),n("span",{staticClass:"line-number"},[s._v("21")]),n("br"),n("span",{staticClass:"line-number"},[s._v("22")]),n("br"),n("span",{staticClass:"line-number"},[s._v("23")]),n("br"),n("span",{staticClass:"line-number"},[s._v("24")]),n("br")])]),n("h2",{attrs:{id:"new-的作用"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#new-的作用"}},[s._v("#")]),s._v(" new 的作用?")]),s._v(" "),n("p",[n("strong",[s._v("面试高频指数:★★☆☆☆")])]),s._v(" "),n("p",[n("code",[s._v("new")]),s._v(" 是 C++ 中的关键字,用来动态分配内存空间,实现方式如下:")]),s._v(" "),n("div",{staticClass:"language-c++ line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v("int *p = new int[5];\n")])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br")])]),n("h2",{attrs:{id:"new-和-malloc-如何判断是否申请到内存"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#new-和-malloc-如何判断是否申请到内存"}},[s._v("#")]),s._v(" new 和 malloc 如何判断是否申请到内存?")]),s._v(" "),n("p",[n("strong",[s._v("面试高频指数:★★☆☆☆")])]),s._v(" "),n("ul",[n("li",[s._v("malloc :成功申请到内存,返回指向该内存的指针;分配失败,返回 NULL 指针。")]),s._v(" "),n("li",[s._v("new :内存分配成功,返回该对象类型的指针;分配失败,抛出 bac_alloc 异常。")])]),s._v(" "),n("h2",{attrs:{id:"delete-实现原理-delete-和-delete-的区别"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#delete-实现原理-delete-和-delete-的区别"}},[s._v("#")]),s._v(" delete 实现原理?delete 和 delete[] 的区别?")]),s._v(" "),n("p",[n("strong",[s._v("面试高频指数:★★★☆☆")])]),s._v(" "),n("p",[s._v("delete 的实现原理:")]),s._v(" "),n("ul",[n("li",[s._v("首先执行该对象所属类的析构函数;")]),s._v(" "),n("li",[s._v("进而通过调用 operator delete 的标准库函数来释放所占的内存空间。")])]),s._v(" "),n("p",[s._v("delete 和 delete [] 的区别:")]),s._v(" "),n("ul",[n("li",[n("p",[s._v("delete 用来释放单个对象所占的空间,只会调用一次析构函数;")])]),s._v(" "),n("li",[n("p",[s._v("delete [] 用来释放数组空间,会对数组中的每个成员都调用一次析构函数。")])])]),s._v(" "),n("h2",{attrs:{id:"new-和-malloc-的区别-delete-和-free-的区别"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#new-和-malloc-的区别-delete-和-free-的区别"}},[s._v("#")]),s._v(" new 和 malloc 的区别,delete 和 free 的区别")]),s._v(" "),n("p",[n("strong",[s._v("面试高频指数:★★★★☆")]),s._v("\n在使用的时候 new、delete 搭配使用,malloc、free 搭配使用。")]),s._v(" "),n("ul",[n("li",[s._v("malloc、free 是库函数,而 new、delete 是关键字。")]),s._v(" "),n("li",[s._v("-new 申请空间时,无需指定分配空间的大小,编译器会根据类型自行计算;malloc 在申请空间时,需要确定所申请空间的大小。")]),s._v(" "),n("li",[s._v("new 申请空间时,返回的类型是对象的指针类型,无需强制类型转换,是类型安全的操作符;malloc 申请空间时,返回的是 void* 类型,需要进行强制类型的转换,转换为对象类型的指针。")]),s._v(" "),n("li",[s._v("new 分配失败时,会抛出 bad_alloc 异常,malloc 分配失败时返回空指针。")]),s._v(" "),n("li",[s._v("对于自定义的类型,new 首先调用 operator new() 函数申请空间(底层通过 malloc 实现),然后调用构造函数进行初始化,最后返回自定义类型的指针;delete 首先调用析构函数,然后调用 operator delete() 释放空间(底层通过 free 实现)。malloc、free 无法进行自定义类型的对象的构造和析构。")]),s._v(" "),n("li",[s._v("new 操作符从自由存储区上为对象动态分配内存,而 malloc 函数从堆上动态分配内存。(自由存储区不等于堆)")])]),s._v(" "),n("h2",{attrs:{id:"malloc-的原理-malloc-的底层实现"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#malloc-的原理-malloc-的底层实现"}},[s._v("#")]),s._v(" malloc 的原理?malloc 的底层实现?")]),s._v(" "),n("p",[n("strong",[s._v("面试高频指数:★★☆☆☆")]),s._v("\nmalloc 的原理:")]),s._v(" "),n("ul",[n("li",[n("p",[s._v("当开辟的空间小于 128K 时,调用 brk() 函数,通过移动 _enddata 来实现;")])]),s._v(" "),n("li",[n("p",[s._v("当开辟空间大于 128K 时,调用 mmap() 函数,通过在虚拟地址空间中开辟一块内存空间来实现。")])])]),s._v(" "),n("p",[s._v("malloc 的底层实现:")]),s._v(" "),n("ul",[n("li",[n("p",[s._v("brk() 函数实现原理:向高地址的方向移动指向数据段的高地址的指针 _enddata。")])]),s._v(" "),n("li",[n("p",[s._v("mmap 内存映射原理:")]),s._v(" "),n("ol",[n("li",[s._v("进程启动映射过程,并在虚拟地址空间中为映射创建虚拟映射区域;")]),s._v(" "),n("li",[s._v("调用内核空间的系统调用函数 mmap(),实现文件物理地址和进程虚拟地址的一一映射关系;")]),s._v(" "),n("li",[s._v("进程发起对这片映射空间的访问,引发缺页异常,实现文件内容到物理内存(主存)的拷贝。")])])])]),s._v(" "),n("h2",{attrs:{id:"c-和-c-struct-的区别"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#c-和-c-struct-的区别"}},[s._v("#")]),s._v(" C 和 C++ struct 的区别?")]),s._v(" "),n("p",[n("strong",[s._v("面试高频指数:★★☆☆☆")])]),s._v(" "),n("ul",[n("li",[s._v("在 C 语言中 struct 是用户自定义数据类型;在 C++ 中 struct 是抽象数据类型,支持成员函数的定义。")]),s._v(" "),n("li",[s._v("C 语言中 struct 没有访问权限的设置,是一些变量的集合体,不能定义成员函数;C++ 中 struct 可以和类一样,有访问权限,并可以定义成员函数。")]),s._v(" "),n("li",[s._v("C 语言中 struct 定义的自定义数据类型,在定义该类型的变量时,需要加上 struct 关键字,例如:struct A var;,定义 A 类型的变量;而 C++ 中,不用加该关键字,例如:A var;")])]),s._v(" "),n("h2",{attrs:{id:"为什么有了-class-还保留-struct"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#为什么有了-class-还保留-struct"}},[s._v("#")]),s._v(" 为什么有了 class 还保留 struct?")]),s._v(" "),n("p",[n("strong",[s._v("面试高频指数:★★☆☆☆")]),s._v("\nC++ 是在 C 语言的基础上发展起来的,为了与 C 语言兼容,C++ 中保留了 struct。")]),s._v(" "),n("h2",{attrs:{id:"struct-和-union-的区别"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#struct-和-union-的区别"}},[s._v("#")]),s._v(" struct 和 union 的区别")]),s._v(" "),n("p",[n("strong",[s._v("面试高频指数:★★☆☆☆")]),s._v("\n说明:union 是联合体,struct 是结构体。")]),s._v(" "),n("p",[s._v("区别:")]),s._v(" "),n("ol",[n("li",[n("p",[s._v("联合体和结构体都是由若干个数据类型不同的数据成员组成。使用时,联合体只有一个有效的成员;而结构体所有的成员都有效。")])]),s._v(" "),n("li",[n("p",[s._v("对联合体的不同成员赋值,将会对覆盖其他成员的值,而对于结构体的对不同成员赋值时,相互不影响。")])]),s._v(" "),n("li",[n("p",[s._v("联合体的大小为其内部所有变量的最大值,按照最大类型的倍数进行分配大小;结构体分配内存的大小遵循内存对齐原则。")])])]),s._v(" "),n("div",{staticClass:"language-c++ line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v("#include \nusing namespace std;\n\ntypedef union\n{\n char c[10];\n char cc1; // char 1 字节,按该类型的倍数分配大小\n} u11;\n\ntypedef union\n{\n char c[10];\n int i; // int 4 字节,按该类型的倍数分配大小\n} u22;\n\ntypedef union\n{\n char c[10];\n double d; // double 8 字节,按该类型的倍数分配大小\n} u33;\n\ntypedef struct s1\n{\n char c; // 1 字节\n double d; // 1(char)+ 7(内存对齐)+ 8(double)= 16 字节\n} s11;\n\ntypedef struct s2\n{\n char c; // 1 字节\n char cc; // 1(char)+ 1(char)= 2 字节\n double d; // 2 + 6(内存对齐)+ 8(double)= 16 字节\n} s22;\n\ntypedef struct s3\n{\n char c; // 1 字节\n double d; // 1(char)+ 7(内存对齐)+ 8(double)= 16 字节\n char cc; // 16 + 1(char)+ 7(内存对齐)= 24 字节\n} s33;\n\nint main()\n{\n cout << sizeof(u11) << endl; // 10\n cout << sizeof(u22) << endl; // 12\n cout << sizeof(u33) << endl; // 16\n cout << sizeof(s11) << endl; // 16\n cout << sizeof(s22) << endl; // 16\n cout << sizeof(s33) << endl; // 24\n\n cout << sizeof(int) << endl; // 4\n cout << sizeof(double) << endl; // 8\n return 0;\n}\n")])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br"),n("span",{staticClass:"line-number"},[s._v("8")]),n("br"),n("span",{staticClass:"line-number"},[s._v("9")]),n("br"),n("span",{staticClass:"line-number"},[s._v("10")]),n("br"),n("span",{staticClass:"line-number"},[s._v("11")]),n("br"),n("span",{staticClass:"line-number"},[s._v("12")]),n("br"),n("span",{staticClass:"line-number"},[s._v("13")]),n("br"),n("span",{staticClass:"line-number"},[s._v("14")]),n("br"),n("span",{staticClass:"line-number"},[s._v("15")]),n("br"),n("span",{staticClass:"line-number"},[s._v("16")]),n("br"),n("span",{staticClass:"line-number"},[s._v("17")]),n("br"),n("span",{staticClass:"line-number"},[s._v("18")]),n("br"),n("span",{staticClass:"line-number"},[s._v("19")]),n("br"),n("span",{staticClass:"line-number"},[s._v("20")]),n("br"),n("span",{staticClass:"line-number"},[s._v("21")]),n("br"),n("span",{staticClass:"line-number"},[s._v("22")]),n("br"),n("span",{staticClass:"line-number"},[s._v("23")]),n("br"),n("span",{staticClass:"line-number"},[s._v("24")]),n("br"),n("span",{staticClass:"line-number"},[s._v("25")]),n("br"),n("span",{staticClass:"line-number"},[s._v("26")]),n("br"),n("span",{staticClass:"line-number"},[s._v("27")]),n("br"),n("span",{staticClass:"line-number"},[s._v("28")]),n("br"),n("span",{staticClass:"line-number"},[s._v("29")]),n("br"),n("span",{staticClass:"line-number"},[s._v("30")]),n("br"),n("span",{staticClass:"line-number"},[s._v("31")]),n("br"),n("span",{staticClass:"line-number"},[s._v("32")]),n("br"),n("span",{staticClass:"line-number"},[s._v("33")]),n("br"),n("span",{staticClass:"line-number"},[s._v("34")]),n("br"),n("span",{staticClass:"line-number"},[s._v("35")]),n("br"),n("span",{staticClass:"line-number"},[s._v("36")]),n("br"),n("span",{staticClass:"line-number"},[s._v("37")]),n("br"),n("span",{staticClass:"line-number"},[s._v("38")]),n("br"),n("span",{staticClass:"line-number"},[s._v("39")]),n("br"),n("span",{staticClass:"line-number"},[s._v("40")]),n("br"),n("span",{staticClass:"line-number"},[s._v("41")]),n("br"),n("span",{staticClass:"line-number"},[s._v("42")]),n("br"),n("span",{staticClass:"line-number"},[s._v("43")]),n("br"),n("span",{staticClass:"line-number"},[s._v("44")]),n("br"),n("span",{staticClass:"line-number"},[s._v("45")]),n("br"),n("span",{staticClass:"line-number"},[s._v("46")]),n("br"),n("span",{staticClass:"line-number"},[s._v("47")]),n("br"),n("span",{staticClass:"line-number"},[s._v("48")]),n("br"),n("span",{staticClass:"line-number"},[s._v("49")]),n("br"),n("span",{staticClass:"line-number"},[s._v("50")]),n("br"),n("span",{staticClass:"line-number"},[s._v("51")]),n("br"),n("span",{staticClass:"line-number"},[s._v("52")]),n("br"),n("span",{staticClass:"line-number"},[s._v("53")]),n("br"),n("span",{staticClass:"line-number"},[s._v("54")]),n("br")])]),n("h2",{attrs:{id:"class-和-struct-的异同"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#class-和-struct-的异同"}},[s._v("#")]),s._v(" class 和 struct 的异同")]),s._v(" "),n("p",[n("strong",[s._v("面试高频指数:★★☆☆☆")])]),s._v(" "),n("ul",[n("li",[n("p",[s._v("struct 和 class 都可以自定义数据类型,也支持继承操作。")])]),s._v(" "),n("li",[n("p",[s._v("struct 中默认的访问级别是 public,默认的继承级别也是 public;class 中默认的访问级别是 private,默认的继承级别也是 private。")])]),s._v(" "),n("li",[n("p",[s._v("当 class 继承 struct 或者 struct 继承 class 时,默认的继承级别取决于 class 或 struct 本身, class(private 继承),struct(public 继承),即取决于派生类的默认继承级别。")]),s._v(" "),n("div",{staticClass:"language-c++ line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v("struct A{};\nclass B : A{}; // private 继承\nstruct C : B{}; // public 继承\n")])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br")])]),n("p",[s._v("举例:")]),s._v(" "),n("div",{staticClass:"language-c++ line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v("#include\n\nusing namespace std;\n\nclass A{\npublic:\n void funA(){\n cout << \"class A\" << endl;\n }\n};\n\nstruct B: A{ // 由于 B 是 struct,A 的默认继承级别为 public\npublic:\n void funB(){\n cout << \"class B\" << endl;\n }\n};\n\nclass C: B{ // 由于 C 是 class,B 的默认继承级别为 private,所以无法访问基类 B 中的 printB 函数\n\n};\n\nint main(){\n A ex1;\n ex1.funA(); // class A\n\n B ex2;\n ex2.funA(); // class A\n ex2.funB(); // class B\n\n C ex3;\n ex3.funB(); // error: 'B' is not an accessible base of 'C'.\n return 0;\n}\n")])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br"),n("span",{staticClass:"line-number"},[s._v("8")]),n("br"),n("span",{staticClass:"line-number"},[s._v("9")]),n("br"),n("span",{staticClass:"line-number"},[s._v("10")]),n("br"),n("span",{staticClass:"line-number"},[s._v("11")]),n("br"),n("span",{staticClass:"line-number"},[s._v("12")]),n("br"),n("span",{staticClass:"line-number"},[s._v("13")]),n("br"),n("span",{staticClass:"line-number"},[s._v("14")]),n("br"),n("span",{staticClass:"line-number"},[s._v("15")]),n("br"),n("span",{staticClass:"line-number"},[s._v("16")]),n("br"),n("span",{staticClass:"line-number"},[s._v("17")]),n("br"),n("span",{staticClass:"line-number"},[s._v("18")]),n("br"),n("span",{staticClass:"line-number"},[s._v("19")]),n("br"),n("span",{staticClass:"line-number"},[s._v("20")]),n("br"),n("span",{staticClass:"line-number"},[s._v("21")]),n("br"),n("span",{staticClass:"line-number"},[s._v("22")]),n("br"),n("span",{staticClass:"line-number"},[s._v("23")]),n("br"),n("span",{staticClass:"line-number"},[s._v("24")]),n("br"),n("span",{staticClass:"line-number"},[s._v("25")]),n("br"),n("span",{staticClass:"line-number"},[s._v("26")]),n("br"),n("span",{staticClass:"line-number"},[s._v("27")]),n("br"),n("span",{staticClass:"line-number"},[s._v("28")]),n("br"),n("span",{staticClass:"line-number"},[s._v("29")]),n("br"),n("span",{staticClass:"line-number"},[s._v("30")]),n("br"),n("span",{staticClass:"line-number"},[s._v("31")]),n("br"),n("span",{staticClass:"line-number"},[s._v("32")]),n("br"),n("span",{staticClass:"line-number"},[s._v("33")]),n("br"),n("span",{staticClass:"line-number"},[s._v("34")]),n("br")])])]),s._v(" "),n("li",[n("p",[n("code",[s._v("class")]),s._v(" 可以用于定义模板参数,"),n("code",[s._v("struct")]),s._v(" 不能用于定义模板参数。")])])]),s._v(" "),n("h2",{attrs:{id:"volatile-的作用-是否具有原子性-对编译器有什么影响"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#volatile-的作用-是否具有原子性-对编译器有什么影响"}},[s._v("#")]),s._v(" volatile 的作用?是否具有原子性,对编译器有什么影响?")]),s._v(" "),n("p",[n("strong",[s._v("面试高频指数:★★☆☆☆")]),s._v("\nvolatile 的作用:当对象的值可能在程序的控制或检测之外被改变时,应该将该对象声明为 volatile,告知编译器不应对这样的对象进行优化。")]),s._v(" "),n("p",[s._v("volatile 不具有原子性。")]),s._v(" "),n("p",[s._v("volatile 对编译器的影响:使用该关键字后,编译器不会对相应的对象进行优化,即不会将变量从内存缓存到寄存器中,防止多个线程有可能使用内存中的变量,有可能使用寄存器中的变量,从而导致程序错误。")]),s._v(" "),n("h2",{attrs:{id:"什么情况下一定要用-volatile-能否和-const-一起使用"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#什么情况下一定要用-volatile-能否和-const-一起使用"}},[s._v("#")]),s._v(" 什么情况下一定要用 volatile, 能否和 const 一起使用?")]),s._v(" "),n("p",[n("strong",[s._v("面试高频指数:★★☆☆☆")]),s._v("\n使用 volatile 关键字的场景:")]),s._v(" "),n("ul",[n("li",[s._v("当多个线程都会用到某一变量,并且该变量的值有可能发生改变时,需要用 volatile 关键字对该变量进行修饰;")]),s._v(" "),n("li",[s._v("中断服务程序中访问的变量或并行设备的硬件寄存器的变量,最好用 volatile 关键字修饰。")])]),s._v(" "),n("p",[s._v("volatile 关键字和 const 关键字可以同时使用,某种类型可以既是 volatile 又是 const ,同时具有二者的属性。")]),s._v(" "),n("h2",{attrs:{id:"返回函数中静态变量的地址会发生什么"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#返回函数中静态变量的地址会发生什么"}},[s._v("#")]),s._v(" 返回函数中静态变量的地址会发生什么?")]),s._v(" "),n("p",[n("strong",[s._v("面试高频指数:★★☆☆☆")])]),s._v(" "),n("div",{staticClass:"language-c++ line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v("#include \nusing namespace std;\n\nint * fun(int tmp){\n static int var = 10;\n var *= tmp;\n return &var;\n}\n\nint main() {\n cout << *fun(5) << endl;\n return 0;\n}\n\n/*\n运行结果:\n50\n*/\n")])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br"),n("span",{staticClass:"line-number"},[s._v("8")]),n("br"),n("span",{staticClass:"line-number"},[s._v("9")]),n("br"),n("span",{staticClass:"line-number"},[s._v("10")]),n("br"),n("span",{staticClass:"line-number"},[s._v("11")]),n("br"),n("span",{staticClass:"line-number"},[s._v("12")]),n("br"),n("span",{staticClass:"line-number"},[s._v("13")]),n("br"),n("span",{staticClass:"line-number"},[s._v("14")]),n("br"),n("span",{staticClass:"line-number"},[s._v("15")]),n("br"),n("span",{staticClass:"line-number"},[s._v("16")]),n("br"),n("span",{staticClass:"line-number"},[s._v("17")]),n("br"),n("span",{staticClass:"line-number"},[s._v("18")]),n("br")])]),n("p",[s._v("说明:上述代码中在函数 fun 中定义了静态局部变量 var,使得离开该函数的作用域后,该变量不会销毁,返回到主函数中,该变量依然存在,从而使程序得到正确的运行结果。但是,该静态局部变量直到程序运行结束后才销毁,浪费内存空间。")]),s._v(" "),n("h2",{attrs:{id:"extern-c-的作用"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#extern-c-的作用"}},[s._v("#")]),s._v(" extern C 的作用?")]),s._v(" "),n("p",[n("strong",[s._v("面试高频指数:★★☆☆☆")]),s._v('\n当 C++ 程序 需要调用 C 语言编写的函数,C++ 使用链接指示,即 extern "C" 指出任意非 C++ 函数所用的语言。')]),s._v(" "),n("p",[s._v("举例:")]),s._v(" "),n("div",{staticClass:"language-c++ line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v('// 可能出现在 C++ 头文件中的链接指示\nextern "C"{\n int strcmp(const char*, const char*);\n}\n')])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br")])]),n("h2",{attrs:{id:"sizeof-1-1-在-c-和-c-中分别是什么结果"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#sizeof-1-1-在-c-和-c-中分别是什么结果"}},[s._v("#")]),s._v(" sizeof(1==1) 在 C 和 C++ 中分别是什么结果?")]),s._v(" "),n("p",[n("strong",[s._v("面试高频指数:★☆☆☆☆")])]),s._v(" "),n("p",[s._v("C 语言代码:")]),s._v(" "),n("div",{staticClass:"language-c++ line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v('#include\n\nvoid main(){\n printf("%d\\n", sizeof(1==1));\n}\n\n/*\n运行结果:\n4\n*/\n')])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br"),n("span",{staticClass:"line-number"},[s._v("8")]),n("br"),n("span",{staticClass:"line-number"},[s._v("9")]),n("br"),n("span",{staticClass:"line-number"},[s._v("10")]),n("br")])]),n("p",[s._v("C++ 代码:")]),s._v(" "),n("div",{staticClass:"language-c++ line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v("#include \nusing namespace std;\n\nint main() {\n cout << sizeof(1==1) << endl;\n return 0;\n}\n\n/*\n1\n*/\n")])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br"),n("span",{staticClass:"line-number"},[s._v("8")]),n("br"),n("span",{staticClass:"line-number"},[s._v("9")]),n("br"),n("span",{staticClass:"line-number"},[s._v("10")]),n("br"),n("span",{staticClass:"line-number"},[s._v("11")]),n("br")])]),n("h2",{attrs:{id:"memcpy-函数的底层原理"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#memcpy-函数的底层原理"}},[s._v("#")]),s._v(" memcpy 函数的底层原理?")]),s._v(" "),n("p",[n("strong",[s._v("面试高频指数:★★★☆☆")])]),s._v(" "),n("div",{staticClass:"language-c++ line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v("void *memcpy(void *dst, const void *src, size_t size)\n{\n char *psrc;\n char *pdst;\n\n if (NULL == dst || NULL == src)\n {\n return NULL;\n }\n\n if ((src < dst) && (char *)src + size > (char *)dst) // 出现地址重叠的情况,自后向前拷贝\n {\n psrc = (char *)src + size - 1;\n pdst = (char *)dst + size - 1;\n while (size--)\n {\n *pdst-- = *psrc--;\n }\n }\n else\n {\n psrc = (char *)src;\n pdst = (char *)dst;\n while (size--)\n {\n *pdst++ = *psrc++;\n }\n }\n\n return dst;\n}\n")])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br"),n("span",{staticClass:"line-number"},[s._v("8")]),n("br"),n("span",{staticClass:"line-number"},[s._v("9")]),n("br"),n("span",{staticClass:"line-number"},[s._v("10")]),n("br"),n("span",{staticClass:"line-number"},[s._v("11")]),n("br"),n("span",{staticClass:"line-number"},[s._v("12")]),n("br"),n("span",{staticClass:"line-number"},[s._v("13")]),n("br"),n("span",{staticClass:"line-number"},[s._v("14")]),n("br"),n("span",{staticClass:"line-number"},[s._v("15")]),n("br"),n("span",{staticClass:"line-number"},[s._v("16")]),n("br"),n("span",{staticClass:"line-number"},[s._v("17")]),n("br"),n("span",{staticClass:"line-number"},[s._v("18")]),n("br"),n("span",{staticClass:"line-number"},[s._v("19")]),n("br"),n("span",{staticClass:"line-number"},[s._v("20")]),n("br"),n("span",{staticClass:"line-number"},[s._v("21")]),n("br"),n("span",{staticClass:"line-number"},[s._v("22")]),n("br"),n("span",{staticClass:"line-number"},[s._v("23")]),n("br"),n("span",{staticClass:"line-number"},[s._v("24")]),n("br"),n("span",{staticClass:"line-number"},[s._v("25")]),n("br"),n("span",{staticClass:"line-number"},[s._v("26")]),n("br"),n("span",{staticClass:"line-number"},[s._v("27")]),n("br"),n("span",{staticClass:"line-number"},[s._v("28")]),n("br"),n("span",{staticClass:"line-number"},[s._v("29")]),n("br"),n("span",{staticClass:"line-number"},[s._v("30")]),n("br"),n("span",{staticClass:"line-number"},[s._v("31")]),n("br")])]),n("h2",{attrs:{id:"strcpy-函数有什么缺陷"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#strcpy-函数有什么缺陷"}},[s._v("#")]),s._v(" strcpy 函数有什么缺陷?")]),s._v(" "),n("p",[n("strong",[s._v("面试高频指数:★★☆☆☆")])]),s._v(" "),n("p",[s._v("strcpy 函数的缺陷:strcpy 函数不检查目的缓冲区的大小边界,而是将源字符串逐一的全部赋值给目的字符串地址起始的一块连续的内存空间,同时加上字符串终止符,会导致其他变量被覆盖。")]),s._v(" "),n("div",{staticClass:"language-c++ line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v('#include \n#include \nusing namespace std;\n\nint main()\n{\n int var = 0x11112222;\n char arr[10];\n cout << "Address : var " << &var << endl;\n cout << "Address : arr " << &arr << endl;\n strcpy(arr, "hello world!");\n cout << "var:" << hex << var << endl; // 将变量 var 以 16 进制输出\n cout << "arr:" << arr << endl;\n return 0;\n}\n\n/*\nAddress : var 0x23fe4c\nAddress : arr 0x23fe42\nvar:11002164\narr:hello world!\n*/\n')])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br"),n("span",{staticClass:"line-number"},[s._v("8")]),n("br"),n("span",{staticClass:"line-number"},[s._v("9")]),n("br"),n("span",{staticClass:"line-number"},[s._v("10")]),n("br"),n("span",{staticClass:"line-number"},[s._v("11")]),n("br"),n("span",{staticClass:"line-number"},[s._v("12")]),n("br"),n("span",{staticClass:"line-number"},[s._v("13")]),n("br"),n("span",{staticClass:"line-number"},[s._v("14")]),n("br"),n("span",{staticClass:"line-number"},[s._v("15")]),n("br"),n("span",{staticClass:"line-number"},[s._v("16")]),n("br"),n("span",{staticClass:"line-number"},[s._v("17")]),n("br"),n("span",{staticClass:"line-number"},[s._v("18")]),n("br"),n("span",{staticClass:"line-number"},[s._v("19")]),n("br"),n("span",{staticClass:"line-number"},[s._v("20")]),n("br"),n("span",{staticClass:"line-number"},[s._v("21")]),n("br"),n("span",{staticClass:"line-number"},[s._v("22")]),n("br")])]),n("p",[s._v('说明:从上述代码中可以看出,变量 var 的后六位被字符串 "hello world!" 的 "d!\\0" 这三个字符改变,这三个字符对应的 ascii 码的十六进制为:\\0(0x00),!(0x21),d(0x64)。\n原因:变量 arr 只分配的 10 个内存空间,通过上述程序中的地址可以看出 arr 和 var 在内存中是连续存放的,但是在调用 strcpy 函数进行拷贝时,源字符串 "hello world!" 所占的内存空间为 13,因此在拷贝的过程中会占用 var 的内存空间,导致 var 的后六位被覆盖。')]),s._v(" "),n("h2",{attrs:{id:"auto-类型推导的原理"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#auto-类型推导的原理"}},[s._v("#")]),s._v(" auto 类型推导的原理")]),s._v(" "),n("p",[n("strong",[s._v("面试高频指数:★★☆☆☆")]),s._v("\nauto 类型推导的原理:\n编译器根据初始值来推算变量的类型,要求用 auto 定义变量时必须有初始值。编译器推断出来的 auto 类型有时和初始值类型并不完全一样,编译器会适当改变结果类型使其更符合初始化规则。")]),s._v(" "),n("h1",{attrs:{id:"类相关"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#类相关"}},[s._v("#")]),s._v(" 类相关")]),s._v(" "),n("p",[s._v("第五章主要讲解类相关的知识点,涉及到虚函数、继承、构造函数、析构函数、深拷贝、浅拷贝等知识点,本章的内容十分重要,同时也是面试过程中的高频问题。")]),s._v(" "),n("h2",{attrs:{id:"什么是虚函数-什么是纯虚函数"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#什么是虚函数-什么是纯虚函数"}},[s._v("#")]),s._v(" 什么是虚函数?什么是纯虚函数?")]),s._v(" "),n("p",[n("strong",[s._v("面试高频指数:★★★★★")])]),s._v(" "),n("p",[n("strong",[s._v("虚函数")]),s._v(":被 "),n("code",[s._v("virtual")]),s._v(" 关键字修饰的成员函数,就是虚函数。")]),s._v(" "),n("div",{staticClass:"language-c++ line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v('#include \nusing namespace std;\n\nclass A\n{\npublic:\n virtual void v_fun() // 虚函数\n {\n cout << "A::v_fun()" << endl;\n }\n};\nclass B : public A\n{\npublic:\n void v_fun()\n {\n cout << "B::v_fun()" << endl;\n }\n};\nint main()\n{\n A *p = new B();\n p->v_fun(); // B::v_fun()\n return 0;\n}\n')])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br"),n("span",{staticClass:"line-number"},[s._v("8")]),n("br"),n("span",{staticClass:"line-number"},[s._v("9")]),n("br"),n("span",{staticClass:"line-number"},[s._v("10")]),n("br"),n("span",{staticClass:"line-number"},[s._v("11")]),n("br"),n("span",{staticClass:"line-number"},[s._v("12")]),n("br"),n("span",{staticClass:"line-number"},[s._v("13")]),n("br"),n("span",{staticClass:"line-number"},[s._v("14")]),n("br"),n("span",{staticClass:"line-number"},[s._v("15")]),n("br"),n("span",{staticClass:"line-number"},[s._v("16")]),n("br"),n("span",{staticClass:"line-number"},[s._v("17")]),n("br"),n("span",{staticClass:"line-number"},[s._v("18")]),n("br"),n("span",{staticClass:"line-number"},[s._v("19")]),n("br"),n("span",{staticClass:"line-number"},[s._v("20")]),n("br"),n("span",{staticClass:"line-number"},[s._v("21")]),n("br"),n("span",{staticClass:"line-number"},[s._v("22")]),n("br"),n("span",{staticClass:"line-number"},[s._v("23")]),n("br"),n("span",{staticClass:"line-number"},[s._v("24")]),n("br"),n("span",{staticClass:"line-number"},[s._v("25")]),n("br")])]),n("p",[n("strong",[s._v("纯虚函数:")])]),s._v(" "),n("ul",[n("li",[n("p",[s._v("纯虚函数在类中声明时,加上 =0;")])]),s._v(" "),n("li",[n("p",[s._v("含有纯虚函数的类称为抽象类(只要含有纯虚函数这个类就是抽象类),类中只有接口,没有具体的实现方法;")])]),s._v(" "),n("li",[n("p",[s._v("继承纯虚函数的派生类,如果没有完全实现基类纯虚函数,依然是抽象类,不能实例化对象。")])])]),s._v(" "),n("p",[s._v("说明:")]),s._v(" "),n("ul",[n("li",[n("p",[s._v("抽象类对象不能作为函数的参数,不能创建对象,不能作为函数返回类型;")])]),s._v(" "),n("li",[n("p",[s._v("可以声明抽象类指针,可以声明抽象类的引用;")])]),s._v(" "),n("li",[n("p",[s._v("子类必须继承父类的纯虚函数,并全部实现后,才能创建子类的对象。")])])]),s._v(" "),n("h2",{attrs:{id:"虚函数和纯虚函数的区别"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#虚函数和纯虚函数的区别"}},[s._v("#")]),s._v(" 虚函数和纯虚函数的区别?")]),s._v(" "),n("p",[n("strong",[s._v("面试高频指数:★★★☆☆")])]),s._v(" "),n("ul",[n("li",[s._v("虚函数和纯虚函数可以出现在同一个类中,该类称为抽象基类。(含有纯虚函数的类称为抽象基类)")]),s._v(" "),n("li",[s._v("使用方式不同:虚函数可以直接使用,纯虚函数必须在派生类中实现后才能使用;")]),s._v(" "),n("li",[s._v("定义形式不同:虚函数在定义时在普通函数的基础上加上 virtual 关键字,纯虚函数定义时除了加上 virtual 关键字还需要加上 =0;")]),s._v(" "),n("li",[s._v("虚函数必须实现,否则编译器会报错;")]),s._v(" "),n("li",[s._v("对于实现纯虚函数的派生类,该纯虚函数在派生类中被称为虚函数,虚函数和纯虚函数都可以在派生类中重写;")]),s._v(" "),n("li",[s._v("析构函数最好定义为虚函数,特别是对于含有继承关系的类;析构函数可以定义为纯虚函数,此时,其所在的类为抽象基类,不能创建实例化对象。")])]),s._v(" "),n("h2",{attrs:{id:"虚函数的实现机制"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#虚函数的实现机制"}},[s._v("#")]),s._v(" 虚函数的实现机制")]),s._v(" "),n("p",[n("strong",[s._v("面试高频指数:★★★★★")])]),s._v(" "),n("p",[s._v("**实现机制:**虚函数通过虚函数表来实现。虚函数的地址保存在虚函数表中,在类的对象所在的内存空间中,保存了指向虚函数表的指针(称为“虚表指针”),通过虚表指针可以找到类对应的虚函数表。虚函数表解决了基类和派生类的继承问题和类中成员函数的覆盖问题,当用基类的指针来操作一个派生类的时候,这张虚函数表就指明了实际应该调用的函数。")]),s._v(" "),n("p",[n("strong",[s._v("虚函数表相关知识点:")])]),s._v(" "),n("ul",[n("li",[s._v("虚函数表存放的内容:类的虚函数的地址。")]),s._v(" "),n("li",[s._v("虚函数表建立的时间:编译阶段,即程序的编译过程中会将虚函数的地址放在虚函数表中。")]),s._v(" "),n("li",[s._v("虚表指针保存的位置:虚表指针存放在对象的内存空间中最前面的位置,这是为了保证正确取到虚函数的偏移量。")])]),s._v(" "),n("p",[s._v("注:虚函数表和类绑定,虚表指针和对象绑定。即类的不同的对象的虚函数表是一样的,但是每个对象都有自己的虚表指针,来指向类的虚函数表。")]),s._v(" "),n("p",[n("strong",[s._v("实例:")])]),s._v(" "),n("p",[s._v("无虚函数覆盖的情况:")]),s._v(" "),n("div",{staticClass:"language-c++ line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v('#include \nusing namespace std;\n\nclass Base\n{\npublic:\n virtual void B_fun1() { cout << "Base::B_fun1()" << endl; }\n virtual void B_fun2() { cout << "Base::B_fun2()" << endl; }\n virtual void B_fun3() { cout << "Base::B_fun3()" << endl; }\n};\n\nclass Derive : public Base\n{\npublic:\n virtual void D_fun1() { cout << "Derive::D_fun1()" << endl; }\n virtual void D_fun2() { cout << "Derive::D_fun2()" << endl; }\n virtual void D_fun3() { cout << "Derive::D_fun3()" << endl; }\n};\nint main()\n{\n Base *p = new Derive();\n p->B_fun1(); // Base::B_fun1()\n return 0;\n}\n')])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br"),n("span",{staticClass:"line-number"},[s._v("8")]),n("br"),n("span",{staticClass:"line-number"},[s._v("9")]),n("br"),n("span",{staticClass:"line-number"},[s._v("10")]),n("br"),n("span",{staticClass:"line-number"},[s._v("11")]),n("br"),n("span",{staticClass:"line-number"},[s._v("12")]),n("br"),n("span",{staticClass:"line-number"},[s._v("13")]),n("br"),n("span",{staticClass:"line-number"},[s._v("14")]),n("br"),n("span",{staticClass:"line-number"},[s._v("15")]),n("br"),n("span",{staticClass:"line-number"},[s._v("16")]),n("br"),n("span",{staticClass:"line-number"},[s._v("17")]),n("br"),n("span",{staticClass:"line-number"},[s._v("18")]),n("br"),n("span",{staticClass:"line-number"},[s._v("19")]),n("br"),n("span",{staticClass:"line-number"},[s._v("20")]),n("br"),n("span",{staticClass:"line-number"},[s._v("21")]),n("br"),n("span",{staticClass:"line-number"},[s._v("22")]),n("br"),n("span",{staticClass:"line-number"},[s._v("23")]),n("br"),n("span",{staticClass:"line-number"},[s._v("24")]),n("br")])]),n("p",[s._v("基类和派生类的继承关系:")]),s._v(" "),n("img",{staticStyle:{zoom:"80%"},attrs:{src:"https://cdn.jsdelivr.net/gh/jacky1234/picArchieve@master/uPic/20230522_135412_pIKwGE.png",alt:"20230522_135412_pIKwGE"}}),s._v(" "),n("p",[s._v("基类的虚函数表:")]),s._v(" "),n("img",{staticStyle:{zoom:"80%"},attrs:{src:"https://cdn.jsdelivr.net/gh/jacky1234/picArchieve@master/uPic/20230522_135155_4LwCrT.png",alt:"20230522_135155_4LwCrT"}}),s._v(" "),n("p",[s._v("主函数中基类的指针 "),n("code",[s._v("p")]),s._v(" 指向了派生类的对象,当调用函数 "),n("code",[s._v("B_fun1()")]),s._v(" 时,通过派生类的虚函数表找到该函数的地址,从而完成调用。")]),s._v(" "),n("h2",{attrs:{id:"单继承和多继承的虚函数表结构"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#单继承和多继承的虚函数表结构"}},[s._v("#")]),s._v(" 单继承和多继承的虚函数表结构")]),s._v(" "),n("p",[n("strong",[s._v("面试高频指数:★★★★☆")])]),s._v(" "),n("p",[n("strong",[s._v("编译器处理虚函数表:")])]),s._v(" "),n("ul",[n("li",[s._v("编译器将虚函数表的指针放在类的实例对象的内存空间中,该对象调用该类的虚函数时,通过指针找到虚函数表,根据虚函数表中存放的虚函数的地址找到对应的虚函数。")]),s._v(" "),n("li",[s._v("如果派生类没有重新定义基类的虚函数 A,则派生类的虚函数表中保存的是基类的虚函数 A 的地址,也就是说基类和派生类的虚函数 A 的地址是一样的。")]),s._v(" "),n("li",[s._v("如果派生类重写了基类的某个虚函数 B,则派生的虚函数表中保存的是重写后的虚函数 B 的地址,也就是说虚函数 B 有两个版本,分别存放在基类和派生类的虚函数表中。")]),s._v(" "),n("li",[s._v("如果派生类重新定义了新的虚函数 C,派生类的虚函数表保存新的虚函数 C 的地址。")])]),s._v(" "),n("ol",[n("li",[n("p",[s._v("单继承无虚函数覆盖的情况:")]),s._v(" "),n("div",{staticClass:"language-c++ line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v('#include \nusing namespace std;\n\nclass Base\n{\npublic:\n virtual void B_fun1() { cout << "Base::B_fun1()" << endl; }\n virtual void B_fun2() { cout << "Base::B_fun2()" << endl; }\n virtual void B_fun3() { cout << "Base::B_fun3()" << endl; }\n};\n\nclass Derive : public Base\n{\npublic:\n virtual void D_fun1() { cout << "Derive::D_fun1()" << endl; }\n virtual void D_fun2() { cout << "Derive::D_fun2()" << endl; }\n virtual void D_fun3() { cout << "Derive::D_fun3()" << endl; }\n};\nint main()\n{\n Base *p = new Derive();\n p->B_fun1(); // Base::B_fun1()\n return 0;\n}\n')])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br"),n("span",{staticClass:"line-number"},[s._v("8")]),n("br"),n("span",{staticClass:"line-number"},[s._v("9")]),n("br"),n("span",{staticClass:"line-number"},[s._v("10")]),n("br"),n("span",{staticClass:"line-number"},[s._v("11")]),n("br"),n("span",{staticClass:"line-number"},[s._v("12")]),n("br"),n("span",{staticClass:"line-number"},[s._v("13")]),n("br"),n("span",{staticClass:"line-number"},[s._v("14")]),n("br"),n("span",{staticClass:"line-number"},[s._v("15")]),n("br"),n("span",{staticClass:"line-number"},[s._v("16")]),n("br"),n("span",{staticClass:"line-number"},[s._v("17")]),n("br"),n("span",{staticClass:"line-number"},[s._v("18")]),n("br"),n("span",{staticClass:"line-number"},[s._v("19")]),n("br"),n("span",{staticClass:"line-number"},[s._v("20")]),n("br"),n("span",{staticClass:"line-number"},[s._v("21")]),n("br"),n("span",{staticClass:"line-number"},[s._v("22")]),n("br"),n("span",{staticClass:"line-number"},[s._v("23")]),n("br"),n("span",{staticClass:"line-number"},[s._v("24")]),n("br")])]),n("p",[s._v("基类和派生类的继承关系:")]),s._v(" "),n("img",{staticStyle:{zoom:"80%"},attrs:{src:"https://cdn.jsdelivr.net/gh/jacky1234/picArchieve@master/uPic/20230522_135412_pIKwGE.png",alt:"20230522_135412_pIKwGE"}}),s._v(" "),n("div",{staticClass:"language-c++ line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v('#include \nusing namespace std;\n\nclass Base\n{\npublic:\n virtual void fun1() { cout << "Base::fun1()" << endl; }\n virtual void B_fun2() { cout << "Base::B_fun2()" << endl; }\n virtual void B_fun3() { cout << "Base::B_fun3()" << endl; }\n};\n\nclass Derive : public Base\n{\npublic:\n virtual void fun1() { cout << "Derive::fun1()" << endl; }\n virtual void D_fun2() { cout << "Derive::D_fun2()" << endl; }\n virtual void D_fun3() { cout << "Derive::D_fun3()" << endl; }\n};\nint main()\n{\n Base *p = new Derive();\n p->fun1(); // Derive::fun1()\n return 0;\n}\n')])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br"),n("span",{staticClass:"line-number"},[s._v("8")]),n("br"),n("span",{staticClass:"line-number"},[s._v("9")]),n("br"),n("span",{staticClass:"line-number"},[s._v("10")]),n("br"),n("span",{staticClass:"line-number"},[s._v("11")]),n("br"),n("span",{staticClass:"line-number"},[s._v("12")]),n("br"),n("span",{staticClass:"line-number"},[s._v("13")]),n("br"),n("span",{staticClass:"line-number"},[s._v("14")]),n("br"),n("span",{staticClass:"line-number"},[s._v("15")]),n("br"),n("span",{staticClass:"line-number"},[s._v("16")]),n("br"),n("span",{staticClass:"line-number"},[s._v("17")]),n("br"),n("span",{staticClass:"line-number"},[s._v("18")]),n("br"),n("span",{staticClass:"line-number"},[s._v("19")]),n("br"),n("span",{staticClass:"line-number"},[s._v("20")]),n("br"),n("span",{staticClass:"line-number"},[s._v("21")]),n("br"),n("span",{staticClass:"line-number"},[s._v("22")]),n("br"),n("span",{staticClass:"line-number"},[s._v("23")]),n("br"),n("span",{staticClass:"line-number"},[s._v("24")]),n("br")])]),n("p",[s._v("派生类的虚函数表:")]),s._v(" "),n("p",[n("img",{attrs:{src:"https://cdn.jsdelivr.net/gh/jacky1234/picArchieve@master/uPic/20230522_134819_ymDbht.png",alt:""}})])]),s._v(" "),n("li",[n("p",[s._v("多继承无虚函数覆盖的情况:")])])]),s._v(" "),n("div",{staticClass:"language-c++ line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v('#include \nusing namespace std;\n\nclass Base1\n{\npublic:\n virtual void B1_fun1() { cout << "Base1::B1_fun1()" << endl; }\n virtual void B1_fun2() { cout << "Base1::B1_fun2()" << endl; }\n virtual void B1_fun3() { cout << "Base1::B1_fun3()" << endl; }\n};\nclass Base2\n{\npublic:\n virtual void B2_fun1() { cout << "Base2::B2_fun1()" << endl; }\n virtual void B2_fun2() { cout << "Base2::B2_fun2()" << endl; }\n virtual void B2_fun3() { cout << "Base2::B2_fun3()" << endl; }\n};\nclass Base3\n{\npublic:\n virtual void B3_fun1() { cout << "Base3::B3_fun1()" << endl; }\n virtual void B3_fun2() { cout << "Base3::B3_fun2()" << endl; }\n virtual void B3_fun3() { cout << "Base3::B3_fun3()" << endl; }\n};\n\nclass Derive : public Base1, public Base2, public Base3\n{\npublic:\n virtual void D_fun1() { cout << "Derive::D_fun1()" << endl; }\n virtual void D_fun2() { cout << "Derive::D_fun2()" << endl; }\n virtual void D_fun3() { cout << "Derive::D_fun3()" << endl; }\n};\n\nint main(){\n Base1 *p = new Derive();\n p->B1_fun1(); // Base1::B1_fun1()\n return 0;\n}\n')])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br"),n("span",{staticClass:"line-number"},[s._v("8")]),n("br"),n("span",{staticClass:"line-number"},[s._v("9")]),n("br"),n("span",{staticClass:"line-number"},[s._v("10")]),n("br"),n("span",{staticClass:"line-number"},[s._v("11")]),n("br"),n("span",{staticClass:"line-number"},[s._v("12")]),n("br"),n("span",{staticClass:"line-number"},[s._v("13")]),n("br"),n("span",{staticClass:"line-number"},[s._v("14")]),n("br"),n("span",{staticClass:"line-number"},[s._v("15")]),n("br"),n("span",{staticClass:"line-number"},[s._v("16")]),n("br"),n("span",{staticClass:"line-number"},[s._v("17")]),n("br"),n("span",{staticClass:"line-number"},[s._v("18")]),n("br"),n("span",{staticClass:"line-number"},[s._v("19")]),n("br"),n("span",{staticClass:"line-number"},[s._v("20")]),n("br"),n("span",{staticClass:"line-number"},[s._v("21")]),n("br"),n("span",{staticClass:"line-number"},[s._v("22")]),n("br"),n("span",{staticClass:"line-number"},[s._v("23")]),n("br"),n("span",{staticClass:"line-number"},[s._v("24")]),n("br"),n("span",{staticClass:"line-number"},[s._v("25")]),n("br"),n("span",{staticClass:"line-number"},[s._v("26")]),n("br"),n("span",{staticClass:"line-number"},[s._v("27")]),n("br"),n("span",{staticClass:"line-number"},[s._v("28")]),n("br"),n("span",{staticClass:"line-number"},[s._v("29")]),n("br"),n("span",{staticClass:"line-number"},[s._v("30")]),n("br"),n("span",{staticClass:"line-number"},[s._v("31")]),n("br"),n("span",{staticClass:"line-number"},[s._v("32")]),n("br"),n("span",{staticClass:"line-number"},[s._v("33")]),n("br"),n("span",{staticClass:"line-number"},[s._v("34")]),n("br"),n("span",{staticClass:"line-number"},[s._v("35")]),n("br"),n("span",{staticClass:"line-number"},[s._v("36")]),n("br"),n("span",{staticClass:"line-number"},[s._v("37")]),n("br"),n("span",{staticClass:"line-number"},[s._v("38")]),n("br")])]),n("ol",[n("li",[s._v("基类和派生类的关系:")])]),s._v(" "),n("img",{staticStyle:{zoom:"80%"},attrs:{src:"https://cdn.jsdelivr.net/gh/jacky1234/picArchieve@master/uPic/20230522_134836_85N7TS.png",alt:"444"}}),s._v(" "),n("p",[s._v("派生类的虚函数表:(基类的顺序和声明的顺序一致)")]),s._v(" "),n("img",{staticStyle:{zoom:"80%"},attrs:{src:"https://cdn.jsdelivr.net/gh/jacky1234/picArchieve@master/uPic/20230522_135051_qH0Fwa.png",alt:"555"}}),s._v(" "),n("ol",{attrs:{start:"2"}},[n("li",[n("p",[s._v("多继承无虚函数覆盖的情况:")]),s._v(" "),n("div",{staticClass:"language-c++ line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v('#include \nusing namespace std;\n\nclass Base1\n{\npublic:\n virtual void fun1() { cout << "Base1::fun1()" << endl; }\n virtual void B1_fun2() { cout << "Base1::B1_fun2()" << endl; }\n virtual void B1_fun3() { cout << "Base1::B1_fun3()" << endl; }\n};\nclass Base2\n{\npublic:\n virtual void fun1() { cout << "Base2::fun1()" << endl; }\n virtual void B2_fun2() { cout << "Base2::B2_fun2()" << endl; }\n virtual void B2_fun3() { cout << "Base2::B2_fun3()" << endl; }\n};\nclass Base3\n{\npublic:\n virtual void fun1() { cout << "Base3::fun1()" << endl; }\n virtual void B3_fun2() { cout << "Base3::B3_fun2()" << endl; }\n virtual void B3_fun3() { cout << "Base3::B3_fun3()" << endl; }\n};\n\nclass Derive : public Base1, public Base2, public Base3\n{\npublic:\n virtual void fun1() { cout << "Derive::fun1()" << endl; }\n virtual void D_fun2() { cout << "Derive::D_fun2()" << endl; }\n virtual void D_fun3() { cout << "Derive::D_fun3()" << endl; }\n};\n\nint main(){\n Base1 *p1 = new Derive();\n Base2 *p2 = new Derive();\n Base3 *p3 = new Derive();\n p1->fun1(); // Derive::fun1()\n p2->fun1(); // Derive::fun1()\n p3->fun1(); // Derive::fun1()\n return 0;\n}\n')])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br"),n("span",{staticClass:"line-number"},[s._v("8")]),n("br"),n("span",{staticClass:"line-number"},[s._v("9")]),n("br"),n("span",{staticClass:"line-number"},[s._v("10")]),n("br"),n("span",{staticClass:"line-number"},[s._v("11")]),n("br"),n("span",{staticClass:"line-number"},[s._v("12")]),n("br"),n("span",{staticClass:"line-number"},[s._v("13")]),n("br"),n("span",{staticClass:"line-number"},[s._v("14")]),n("br"),n("span",{staticClass:"line-number"},[s._v("15")]),n("br"),n("span",{staticClass:"line-number"},[s._v("16")]),n("br"),n("span",{staticClass:"line-number"},[s._v("17")]),n("br"),n("span",{staticClass:"line-number"},[s._v("18")]),n("br"),n("span",{staticClass:"line-number"},[s._v("19")]),n("br"),n("span",{staticClass:"line-number"},[s._v("20")]),n("br"),n("span",{staticClass:"line-number"},[s._v("21")]),n("br"),n("span",{staticClass:"line-number"},[s._v("22")]),n("br"),n("span",{staticClass:"line-number"},[s._v("23")]),n("br"),n("span",{staticClass:"line-number"},[s._v("24")]),n("br"),n("span",{staticClass:"line-number"},[s._v("25")]),n("br"),n("span",{staticClass:"line-number"},[s._v("26")]),n("br"),n("span",{staticClass:"line-number"},[s._v("27")]),n("br"),n("span",{staticClass:"line-number"},[s._v("28")]),n("br"),n("span",{staticClass:"line-number"},[s._v("29")]),n("br"),n("span",{staticClass:"line-number"},[s._v("30")]),n("br"),n("span",{staticClass:"line-number"},[s._v("31")]),n("br"),n("span",{staticClass:"line-number"},[s._v("32")]),n("br"),n("span",{staticClass:"line-number"},[s._v("33")]),n("br"),n("span",{staticClass:"line-number"},[s._v("34")]),n("br"),n("span",{staticClass:"line-number"},[s._v("35")]),n("br"),n("span",{staticClass:"line-number"},[s._v("36")]),n("br"),n("span",{staticClass:"line-number"},[s._v("37")]),n("br"),n("span",{staticClass:"line-number"},[s._v("38")]),n("br"),n("span",{staticClass:"line-number"},[s._v("39")]),n("br"),n("span",{staticClass:"line-number"},[s._v("40")]),n("br"),n("span",{staticClass:"line-number"},[s._v("41")]),n("br"),n("span",{staticClass:"line-number"},[s._v("42")]),n("br")])]),n("p",[s._v("基类和派生类的关系:")]),s._v(" "),n("img",{staticStyle:{zoom:"80%"},attrs:{src:"https://cdn.jsdelivr.net/gh/jacky1234/picArchieve@master/uPic/20230522_135227_T0cW2G.png",alt:"20230522_135227_T0cW2G"}}),s._v(" "),n("p",[s._v("派生类的虚函数表:")]),s._v(" "),n("img",{staticStyle:{zoom:"80%"},attrs:{src:"https://cdn.jsdelivr.net/gh/jacky1234/picArchieve@master/uPic/20230522_135452_Z2oBZ3.png",alt:"20230522_135452_Z2oBZ3"}})])]),s._v(" "),n("h2",{attrs:{id:"如何禁止构造函数的使用"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#如何禁止构造函数的使用"}},[s._v("#")]),s._v(" 如何禁止构造函数的使用?")]),s._v(" "),n("p",[n("strong",[s._v("面试高频指数:★★☆☆☆")])]),s._v(" "),n("p",[s._v("为类的构造函数增加 "),n("code",[s._v("= delete")]),s._v(" 修饰符,可以达到虽然声明了构造函数但禁止使用的目的。")]),s._v(" "),n("div",{staticClass:"language-c++ line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v("#include \n\nusing namespace std;\n\nclass A {\npublic:\n int var1, var2;\n A(){\n var1 = 10;\n var2 = 20;\n }\n A(int tmp1, int tmp2) = delete;\n};\n\nint main()\n{\n A ex1;\n A ex2(12,13); // error: use of deleted function 'A::A(int, int)'\n return 0;\n}\n")])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br"),n("span",{staticClass:"line-number"},[s._v("8")]),n("br"),n("span",{staticClass:"line-number"},[s._v("9")]),n("br"),n("span",{staticClass:"line-number"},[s._v("10")]),n("br"),n("span",{staticClass:"line-number"},[s._v("11")]),n("br"),n("span",{staticClass:"line-number"},[s._v("12")]),n("br"),n("span",{staticClass:"line-number"},[s._v("13")]),n("br"),n("span",{staticClass:"line-number"},[s._v("14")]),n("br"),n("span",{staticClass:"line-number"},[s._v("15")]),n("br"),n("span",{staticClass:"line-number"},[s._v("16")]),n("br"),n("span",{staticClass:"line-number"},[s._v("17")]),n("br"),n("span",{staticClass:"line-number"},[s._v("18")]),n("br"),n("span",{staticClass:"line-number"},[s._v("19")]),n("br"),n("span",{staticClass:"line-number"},[s._v("20")]),n("br")])]),n("p",[s._v("说明:上述代码中,使用了已经删除 "),n("code",[s._v("delete")]),s._v(" 的构造函数,程序出现错误。")]),s._v(" "),n("h2",{attrs:{id:"什么是类的默认构造函数"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#什么是类的默认构造函数"}},[s._v("#")]),s._v(" 什么是类的默认构造函数?")]),s._v(" "),n("p",[n("strong",[s._v("面试高频指数:★★★☆☆")])]),s._v(" "),n("p",[s._v("默认构造函数:未提供任何实参,来控制默认初始化过程的构造函数称为默认构造函数。")]),s._v(" "),n("div",{staticClass:"language-c++ line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v("#include \n\nusing namespace std;\n\nclass A\n{\npublic:\n A(){ // 类的默认构造函数\n var = 10;\n c = 'q';\n }\n int var;\n char c;\n};\n\nint main()\n{\n A ex;\n cout << ex.c << endl << ex.var << endl;\n return 0;\n}\n/*\n运行结果:\nq\n10\n*/\n")])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br"),n("span",{staticClass:"line-number"},[s._v("8")]),n("br"),n("span",{staticClass:"line-number"},[s._v("9")]),n("br"),n("span",{staticClass:"line-number"},[s._v("10")]),n("br"),n("span",{staticClass:"line-number"},[s._v("11")]),n("br"),n("span",{staticClass:"line-number"},[s._v("12")]),n("br"),n("span",{staticClass:"line-number"},[s._v("13")]),n("br"),n("span",{staticClass:"line-number"},[s._v("14")]),n("br"),n("span",{staticClass:"line-number"},[s._v("15")]),n("br"),n("span",{staticClass:"line-number"},[s._v("16")]),n("br"),n("span",{staticClass:"line-number"},[s._v("17")]),n("br"),n("span",{staticClass:"line-number"},[s._v("18")]),n("br"),n("span",{staticClass:"line-number"},[s._v("19")]),n("br"),n("span",{staticClass:"line-number"},[s._v("20")]),n("br"),n("span",{staticClass:"line-number"},[s._v("21")]),n("br"),n("span",{staticClass:"line-number"},[s._v("22")]),n("br"),n("span",{staticClass:"line-number"},[s._v("23")]),n("br"),n("span",{staticClass:"line-number"},[s._v("24")]),n("br"),n("span",{staticClass:"line-number"},[s._v("25")]),n("br"),n("span",{staticClass:"line-number"},[s._v("26")]),n("br")])]),n("p",[s._v("说明:上述程序中定义变量 "),n("code",[s._v("ex")]),s._v(" 时,未提供任何实参,程序运行时会调用默认的构造函数。")]),s._v(" "),n("h2",{attrs:{id:"构造函数、析构函数是否需要定义成虚函数-为什么"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#构造函数、析构函数是否需要定义成虚函数-为什么"}},[s._v("#")]),s._v(" 构造函数、析构函数是否需要定义成虚函数?为什么?")]),s._v(" "),n("p",[n("strong",[s._v("面试高频指数:★★★★☆")]),s._v("\n构造函数一般不定义为虚函数,原因:")]),s._v(" "),n("ul",[n("li",[n("p",[s._v("从存储空间的角度考虑:构造函数是在实例化对象的时候进行调用,如果此时将构造函数定义成虚函数,需要通过访问该对象所在的内存空间才能进行虚函数的调用(因为需要通过指向虚函数表的指针调用虚函数表,虽然虚函数表在编译时就有了,但是没有虚函数的指针,虚函数的指针只有在创建了对象才有),但是此时该对象还未创建,便无法进行虚函数的调用。所以构造函数不能定义成虚函数。")])]),s._v(" "),n("li",[n("p",[s._v("从使用的角度考虑:虚函数是基类的指针指向派生类的对象时,通过该指针实现对派生类的虚函数的调用,构造函数是在创建对象时自动调用的。")])]),s._v(" "),n("li",[n("p",[s._v("从实现上考虑:虚函数表是在创建对象之后才有的,因此不能定义成虚函数。")])]),s._v(" "),n("li",[n("p",[s._v("从类型上考虑:在创建对象时需要明确其类型。")])])]),s._v(" "),n("p",[s._v("析构函数一般定义成虚函数,原因:\n析构函数定义成虚函数是为了防止内存泄漏,因为当基类的指针或者引用指向或绑定到派生类的对象时,如果未将基类的析构函数定义成虚函数,会调用基类的析构函数,那么只能将基类的成员所占的空间释放掉,派生类中特有的就会无法释放内存空间导致内存泄漏。")]),s._v(" "),n("h2",{attrs:{id:"如何避免拷贝"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#如何避免拷贝"}},[s._v("#")]),s._v(" 如何避免拷贝?")]),s._v(" "),n("p",[n("strong",[s._v("面试高频指数:★★☆☆☆")]),s._v("\n最直观的想法是:将类的拷贝构造函数和赋值构造函数声明为私有 private,但对于类的成员函数和友元函数依然可以调用,达不到完全禁止类的对象被拷贝的目的,而且程序会出现错误,因为未对函数进行定义。")]),s._v(" "),n("p",[s._v("解决方法:声明一个基类,具体做法如下。")]),s._v(" "),n("ul",[n("li",[n("p",[s._v("定义一个基类,将其中的拷贝构造函数和赋值构造函数声明为私有 private")])]),s._v(" "),n("li",[n("p",[s._v("派生类以私有 private 的方式继承基类")])])]),s._v(" "),n("div",{staticClass:"language-c++ line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v("class Uncopyable\n{\npublic:\n Uncopyable() {}\n ~Uncopyable() {}\n\nprivate:\n Uncopyable(const Uncopyable &); // 拷贝构造函数\n Uncopyable &operator=(const Uncopyable &); // 赋值构造函数\n};\nclass A : private Uncopyable // 注意继承方式\n{\n};\n")])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br"),n("span",{staticClass:"line-number"},[s._v("8")]),n("br"),n("span",{staticClass:"line-number"},[s._v("9")]),n("br"),n("span",{staticClass:"line-number"},[s._v("10")]),n("br"),n("span",{staticClass:"line-number"},[s._v("11")]),n("br"),n("span",{staticClass:"line-number"},[s._v("12")]),n("br"),n("span",{staticClass:"line-number"},[s._v("13")]),n("br")])]),n("p",[s._v("简单解释:")]),s._v(" "),n("p",[s._v("能够保证,在派生类 A 的成员函数和友元函数中无法进行拷贝操作,因为无法调用基类 Uncopyable 的拷贝构造函数或赋值构造函数。同样,在类的外部也无法进行拷贝操作。")]),s._v(" "),n("h2",{attrs:{id:"如何减少构造函数开销"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#如何减少构造函数开销"}},[s._v("#")]),s._v(" 如何减少构造函数开销?")]),s._v(" "),n("p",[n("strong",[s._v("面试高频指数:★★☆☆☆")])]),s._v(" "),n("p",[s._v("在构造函数中使用类初始化列表,会减少调用默认的构造函数产生的开销,具体原因可以参考本章“为什么用成员初始化列表会快些?”这个问题。")]),s._v(" "),n("div",{staticClass:"language-c++ line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v('class A\n{\nprivate:\n int val;\npublic:\n A()\n {\n cout << "A()" << endl;\n }\n A(int tmp)\n {\n val = tmp;\n cout << "A(int " << val << ")" << endl;\n }\n};\nclass Test1\n{\nprivate:\n A ex;\n\npublic:\n Test1() : ex(1) // 成员列表初始化方式\n {\n }\n};\n')])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br"),n("span",{staticClass:"line-number"},[s._v("8")]),n("br"),n("span",{staticClass:"line-number"},[s._v("9")]),n("br"),n("span",{staticClass:"line-number"},[s._v("10")]),n("br"),n("span",{staticClass:"line-number"},[s._v("11")]),n("br"),n("span",{staticClass:"line-number"},[s._v("12")]),n("br"),n("span",{staticClass:"line-number"},[s._v("13")]),n("br"),n("span",{staticClass:"line-number"},[s._v("14")]),n("br"),n("span",{staticClass:"line-number"},[s._v("15")]),n("br"),n("span",{staticClass:"line-number"},[s._v("16")]),n("br"),n("span",{staticClass:"line-number"},[s._v("17")]),n("br"),n("span",{staticClass:"line-number"},[s._v("18")]),n("br"),n("span",{staticClass:"line-number"},[s._v("19")]),n("br"),n("span",{staticClass:"line-number"},[s._v("20")]),n("br"),n("span",{staticClass:"line-number"},[s._v("21")]),n("br"),n("span",{staticClass:"line-number"},[s._v("22")]),n("br"),n("span",{staticClass:"line-number"},[s._v("23")]),n("br"),n("span",{staticClass:"line-number"},[s._v("24")]),n("br"),n("span",{staticClass:"line-number"},[s._v("25")]),n("br")])]),n("h2",{attrs:{id:"多重继承时会出现什么状况-如何解决"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#多重继承时会出现什么状况-如何解决"}},[s._v("#")]),s._v(" 多重继承时会出现什么状况?如何解决?")]),s._v(" "),n("p",[n("strong",[s._v("面试高频指数:★★★★☆")]),s._v("\n多重继承(多继承):是指从多个直接基类中产生派生类。")]),s._v(" "),n("p",[s._v("多重继承容易出现的问题:命名冲突和数据冗余问题。")]),s._v(" "),n("p",[s._v("举例:")]),s._v(" "),n("div",{staticClass:"language-c++ line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v("#include \nusing namespace std;\n\n// 间接基类\nclass Base1\n{\npublic:\n int var1;\n};\n\n// 直接基类\nclass Base2 : public Base1\n{\npublic:\n int var2;\n};\n\n// 直接基类\nclass Base3 : public Base1\n{\npublic:\n int var3;\n};\n\n// 派生类\nclass Derive : public Base2, public Base3\n{\npublic:\n void set_var1(int tmp) { var1 = tmp; } // error: reference to 'var1' is ambiguous. 命名冲突\n void set_var2(int tmp) { var2 = tmp; }\n void set_var3(int tmp) { var3 = tmp; }\n void set_var4(int tmp) { var4 = tmp; }\n\nprivate:\n int var4;\n};\n\nint main()\n{\n Derive d;\n return 0;\n}\n")])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br"),n("span",{staticClass:"line-number"},[s._v("8")]),n("br"),n("span",{staticClass:"line-number"},[s._v("9")]),n("br"),n("span",{staticClass:"line-number"},[s._v("10")]),n("br"),n("span",{staticClass:"line-number"},[s._v("11")]),n("br"),n("span",{staticClass:"line-number"},[s._v("12")]),n("br"),n("span",{staticClass:"line-number"},[s._v("13")]),n("br"),n("span",{staticClass:"line-number"},[s._v("14")]),n("br"),n("span",{staticClass:"line-number"},[s._v("15")]),n("br"),n("span",{staticClass:"line-number"},[s._v("16")]),n("br"),n("span",{staticClass:"line-number"},[s._v("17")]),n("br"),n("span",{staticClass:"line-number"},[s._v("18")]),n("br"),n("span",{staticClass:"line-number"},[s._v("19")]),n("br"),n("span",{staticClass:"line-number"},[s._v("20")]),n("br"),n("span",{staticClass:"line-number"},[s._v("21")]),n("br"),n("span",{staticClass:"line-number"},[s._v("22")]),n("br"),n("span",{staticClass:"line-number"},[s._v("23")]),n("br"),n("span",{staticClass:"line-number"},[s._v("24")]),n("br"),n("span",{staticClass:"line-number"},[s._v("25")]),n("br"),n("span",{staticClass:"line-number"},[s._v("26")]),n("br"),n("span",{staticClass:"line-number"},[s._v("27")]),n("br"),n("span",{staticClass:"line-number"},[s._v("28")]),n("br"),n("span",{staticClass:"line-number"},[s._v("29")]),n("br"),n("span",{staticClass:"line-number"},[s._v("30")]),n("br"),n("span",{staticClass:"line-number"},[s._v("31")]),n("br"),n("span",{staticClass:"line-number"},[s._v("32")]),n("br"),n("span",{staticClass:"line-number"},[s._v("33")]),n("br"),n("span",{staticClass:"line-number"},[s._v("34")]),n("br"),n("span",{staticClass:"line-number"},[s._v("35")]),n("br"),n("span",{staticClass:"line-number"},[s._v("36")]),n("br"),n("span",{staticClass:"line-number"},[s._v("37")]),n("br"),n("span",{staticClass:"line-number"},[s._v("38")]),n("br"),n("span",{staticClass:"line-number"},[s._v("39")]),n("br"),n("span",{staticClass:"line-number"},[s._v("40")]),n("br"),n("span",{staticClass:"line-number"},[s._v("41")]),n("br"),n("span",{staticClass:"line-number"},[s._v("42")]),n("br")])]),n("p",[s._v("上述程序的继承关系如下:(菱形继承)")]),s._v(" "),n("img",{staticStyle:{zoom:"80%"},attrs:{src:"https://cdn.jsdelivr.net/gh/jacky1234/picArchieve@master/uPic/20230522_135250_JKrFCr.png",alt:"20230522_135250_JKrFCr"}}),s._v(" "),n("p",[s._v("上述代码中存的问题:\n对于派生类 Derive 上述代码中存在直接继承关系和间接继承关系。")]),s._v(" "),n("ul",[n("li",[n("p",[s._v("直接继承:Base2 、Base3")])]),s._v(" "),n("li",[n("p",[s._v("间接继承:Base1")])])]),s._v(" "),n("p",[s._v("对于派生类中继承的的成员变量 var1 ,从继承关系来看,实际上保存了两份,一份是来自基类 Base2,一份来自基类 Base3。因此,出现了命名冲突。")]),s._v(" "),n("p",[n("strong",[s._v("解决方法 1:")]),s._v(" 声明出现冲突的成员变量来源于哪个类")]),s._v(" "),n("div",{staticClass:"language-c++ line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v("#include \nusing namespace std;\n\n// 间接基类\nclass Base1\n{\npublic:\n int var1;\n};\n\n// 直接基类\nclass Base2 : public Base1\n{\npublic:\n int var2;\n};\n\n// 直接基类\nclass Base3 : public Base1\n{\npublic:\n int var3;\n};\n\n// 派生类\nclass Derive : public Base2, public Base3\n{\npublic:\n void set_var1(int tmp) { Base2::var1 = tmp; } // 这里声明成员变量来源于类 Base2,当然也可以声明来源于类 Base3\n void set_var2(int tmp) { var2 = tmp; }\n void set_var3(int tmp) { var3 = tmp; }\n void set_var4(int tmp) { var4 = tmp; }\n\nprivate:\n int var4;\n};\n\nint main()\n{\n Derive d;\n return 0;\n}\n")])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br"),n("span",{staticClass:"line-number"},[s._v("8")]),n("br"),n("span",{staticClass:"line-number"},[s._v("9")]),n("br"),n("span",{staticClass:"line-number"},[s._v("10")]),n("br"),n("span",{staticClass:"line-number"},[s._v("11")]),n("br"),n("span",{staticClass:"line-number"},[s._v("12")]),n("br"),n("span",{staticClass:"line-number"},[s._v("13")]),n("br"),n("span",{staticClass:"line-number"},[s._v("14")]),n("br"),n("span",{staticClass:"line-number"},[s._v("15")]),n("br"),n("span",{staticClass:"line-number"},[s._v("16")]),n("br"),n("span",{staticClass:"line-number"},[s._v("17")]),n("br"),n("span",{staticClass:"line-number"},[s._v("18")]),n("br"),n("span",{staticClass:"line-number"},[s._v("19")]),n("br"),n("span",{staticClass:"line-number"},[s._v("20")]),n("br"),n("span",{staticClass:"line-number"},[s._v("21")]),n("br"),n("span",{staticClass:"line-number"},[s._v("22")]),n("br"),n("span",{staticClass:"line-number"},[s._v("23")]),n("br"),n("span",{staticClass:"line-number"},[s._v("24")]),n("br"),n("span",{staticClass:"line-number"},[s._v("25")]),n("br"),n("span",{staticClass:"line-number"},[s._v("26")]),n("br"),n("span",{staticClass:"line-number"},[s._v("27")]),n("br"),n("span",{staticClass:"line-number"},[s._v("28")]),n("br"),n("span",{staticClass:"line-number"},[s._v("29")]),n("br"),n("span",{staticClass:"line-number"},[s._v("30")]),n("br"),n("span",{staticClass:"line-number"},[s._v("31")]),n("br"),n("span",{staticClass:"line-number"},[s._v("32")]),n("br"),n("span",{staticClass:"line-number"},[s._v("33")]),n("br"),n("span",{staticClass:"line-number"},[s._v("34")]),n("br"),n("span",{staticClass:"line-number"},[s._v("35")]),n("br"),n("span",{staticClass:"line-number"},[s._v("36")]),n("br"),n("span",{staticClass:"line-number"},[s._v("37")]),n("br"),n("span",{staticClass:"line-number"},[s._v("38")]),n("br"),n("span",{staticClass:"line-number"},[s._v("39")]),n("br"),n("span",{staticClass:"line-number"},[s._v("40")]),n("br"),n("span",{staticClass:"line-number"},[s._v("41")]),n("br"),n("span",{staticClass:"line-number"},[s._v("42")]),n("br")])]),n("p",[n("strong",[s._v("解决方法 2:")]),s._v(" 虚继承")]),s._v(" "),n("p",[s._v("使用虚继承的目的:保证存在命名冲突的成员变量在派生类中只保留一份,即使间接基类中的成员在派生类中只保留一份。在菱形继承关系中,间接基类称为虚基类,直接基类和间接基类之间的继承关系称为虚继承。")]),s._v(" "),n("p",[s._v("实现方式:在继承方式前面加上 virtual 关键字。")]),s._v(" "),n("div",{staticClass:"language-c++ line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v("#include \nusing namespace std;\n\n// 间接基类,即虚基类\nclass Base1\n{\npublic:\n int var1;\n};\n\n// 直接基类\nclass Base2 : virtual public Base1 // 虚继承\n{\npublic:\n int var2;\n};\n\n// 直接基类\nclass Base3 : virtual public Base1 // 虚继承\n{\npublic:\n int var3;\n};\n\n// 派生类\nclass Derive : public Base2, public Base3\n{\npublic:\n void set_var1(int tmp) { var1 = tmp; }\n void set_var2(int tmp) { var2 = tmp; }\n void set_var3(int tmp) { var3 = tmp; }\n void set_var4(int tmp) { var4 = tmp; }\n\nprivate:\n int var4;\n};\n\nint main()\n{\n Derive d;\n return 0;\n}\n")])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br"),n("span",{staticClass:"line-number"},[s._v("8")]),n("br"),n("span",{staticClass:"line-number"},[s._v("9")]),n("br"),n("span",{staticClass:"line-number"},[s._v("10")]),n("br"),n("span",{staticClass:"line-number"},[s._v("11")]),n("br"),n("span",{staticClass:"line-number"},[s._v("12")]),n("br"),n("span",{staticClass:"line-number"},[s._v("13")]),n("br"),n("span",{staticClass:"line-number"},[s._v("14")]),n("br"),n("span",{staticClass:"line-number"},[s._v("15")]),n("br"),n("span",{staticClass:"line-number"},[s._v("16")]),n("br"),n("span",{staticClass:"line-number"},[s._v("17")]),n("br"),n("span",{staticClass:"line-number"},[s._v("18")]),n("br"),n("span",{staticClass:"line-number"},[s._v("19")]),n("br"),n("span",{staticClass:"line-number"},[s._v("20")]),n("br"),n("span",{staticClass:"line-number"},[s._v("21")]),n("br"),n("span",{staticClass:"line-number"},[s._v("22")]),n("br"),n("span",{staticClass:"line-number"},[s._v("23")]),n("br"),n("span",{staticClass:"line-number"},[s._v("24")]),n("br"),n("span",{staticClass:"line-number"},[s._v("25")]),n("br"),n("span",{staticClass:"line-number"},[s._v("26")]),n("br"),n("span",{staticClass:"line-number"},[s._v("27")]),n("br"),n("span",{staticClass:"line-number"},[s._v("28")]),n("br"),n("span",{staticClass:"line-number"},[s._v("29")]),n("br"),n("span",{staticClass:"line-number"},[s._v("30")]),n("br"),n("span",{staticClass:"line-number"},[s._v("31")]),n("br"),n("span",{staticClass:"line-number"},[s._v("32")]),n("br"),n("span",{staticClass:"line-number"},[s._v("33")]),n("br"),n("span",{staticClass:"line-number"},[s._v("34")]),n("br"),n("span",{staticClass:"line-number"},[s._v("35")]),n("br"),n("span",{staticClass:"line-number"},[s._v("36")]),n("br"),n("span",{staticClass:"line-number"},[s._v("37")]),n("br"),n("span",{staticClass:"line-number"},[s._v("38")]),n("br"),n("span",{staticClass:"line-number"},[s._v("39")]),n("br"),n("span",{staticClass:"line-number"},[s._v("40")]),n("br"),n("span",{staticClass:"line-number"},[s._v("41")]),n("br"),n("span",{staticClass:"line-number"},[s._v("42")]),n("br")])]),n("p",[s._v("类之间的继承关系:")]),s._v(" "),n("img",{staticStyle:{zoom:"80%"},attrs:{src:"https://cdn.jsdelivr.net/gh/jacky1234/picArchieve@master/uPic/20230522_135322_yU5rkI.png",alt:"20230522_135322_yU5rkI"}}),s._v(" "),n("h2",{attrs:{id:"空类占多少字节-c-编译器会给一个空类自动生成哪些函数"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#空类占多少字节-c-编译器会给一个空类自动生成哪些函数"}},[s._v("#")]),s._v(" 空类占多少字节?C++ 编译器会给一个空类自动生成哪些函数?")]),s._v(" "),n("p",[n("strong",[s._v("面试高频指数:★★★☆☆")]),s._v(" "),n("strong",[s._v("空类声明时编译器不会生成任何成员函数:")])]),s._v(" "),n("p",[s._v("对于空类,声明编译器不会生成任何的成员函数,只会生成 1 个字节的占位符。")]),s._v(" "),n("div",{staticClass:"language-c++ line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v('#include \nusing namespace std;\n\nclass A\n{\n};\n\nint main()\n{\n cout << "sizeof(A):" << sizeof(A) << endl; // sizeof(A):1\n return 0;\n}\n')])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br"),n("span",{staticClass:"line-number"},[s._v("8")]),n("br"),n("span",{staticClass:"line-number"},[s._v("9")]),n("br"),n("span",{staticClass:"line-number"},[s._v("10")]),n("br"),n("span",{staticClass:"line-number"},[s._v("11")]),n("br"),n("span",{staticClass:"line-number"},[s._v("12")]),n("br")])]),n("p",[n("strong",[s._v("空类定义时编译器会生成 6 个成员函数:")])]),s._v(" "),n("p",[s._v("当空类 A 定义对象时,sizeof(A) 仍是为 1,但编译器会生成 6 个成员函数:缺省的构造函数、拷贝构造函数、析构函数、赋值运算符、两个取址运算符。")]),s._v(" "),n("div",{staticClass:"language-c++ line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v('#include \nusing namespace std;\n/*\nclass A\n{}; 该空类的等价写法如下:\n*/\nclass A\n{\npublic:\n A(){}; // 缺省构造函数\n A(const A &tmp){}; // 拷贝构造函数\n ~A(){}; // 析构函数\n A &operator=(const A &tmp){}; // 赋值运算符\n A *operator&() { return this; }; // 取址运算符\n const A *operator&() const { return this; }; // 取址运算符(const 版本)\n};\n\nint main()\n{\n A *p = new A();\n cout << "sizeof(A):" << sizeof(A) << endl; // sizeof(A):1\n delete p;\n return 0;\n}\n')])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br"),n("span",{staticClass:"line-number"},[s._v("8")]),n("br"),n("span",{staticClass:"line-number"},[s._v("9")]),n("br"),n("span",{staticClass:"line-number"},[s._v("10")]),n("br"),n("span",{staticClass:"line-number"},[s._v("11")]),n("br"),n("span",{staticClass:"line-number"},[s._v("12")]),n("br"),n("span",{staticClass:"line-number"},[s._v("13")]),n("br"),n("span",{staticClass:"line-number"},[s._v("14")]),n("br"),n("span",{staticClass:"line-number"},[s._v("15")]),n("br"),n("span",{staticClass:"line-number"},[s._v("16")]),n("br"),n("span",{staticClass:"line-number"},[s._v("17")]),n("br"),n("span",{staticClass:"line-number"},[s._v("18")]),n("br"),n("span",{staticClass:"line-number"},[s._v("19")]),n("br"),n("span",{staticClass:"line-number"},[s._v("20")]),n("br"),n("span",{staticClass:"line-number"},[s._v("21")]),n("br"),n("span",{staticClass:"line-number"},[s._v("22")]),n("br"),n("span",{staticClass:"line-number"},[s._v("23")]),n("br"),n("span",{staticClass:"line-number"},[s._v("24")]),n("br")])]),n("h2",{attrs:{id:"为什么拷贝构造函数必须为引用"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#为什么拷贝构造函数必须为引用"}},[s._v("#")]),s._v(" 为什么拷贝构造函数必须为引用?")]),s._v(" "),n("p",[n("strong",[s._v("面试高频指数:★★☆☆☆")])]),s._v(" "),n("p",[s._v("原因:避免拷贝构造函数无限制的递归,最终导致栈溢出。")]),s._v(" "),n("p",[s._v("举例说明:")]),s._v(" "),n("div",{staticClass:"language-c++ line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v('#include \nusing namespace std;\n\nclass A\n{\nprivate:\n int val;\n\npublic:\n A(int tmp) : val(tmp) // 带参数构造函数\n {\n cout << "A(int tmp)" << endl;\n }\n\n A(const A &tmp) // 拷贝构造函数\n {\n cout << "A(const A &tmp)" << endl;\n val = tmp.val;\n }\n\n A &operator=(const A &tmp) // 赋值函数(赋值运算符重载)\n {\n cout << "A &operator=(const A &tmp)" << endl;\n val = tmp.val;\n return *this;\n }\n\n void fun(A tmp)\n {\n }\n};\n\nint main()\n{\n A ex1(1);\n A ex2(2);\n A ex3 = ex1;\n ex2 = ex1;\n ex2.fun(ex1);\n return 0;\n}\n/*\n运行结果:\nA(int tmp)\nA(int tmp)\nA(const A &tmp)\nA &operator=(const A &tmp)\nA(const A &tmp)\n*/\n')])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br"),n("span",{staticClass:"line-number"},[s._v("8")]),n("br"),n("span",{staticClass:"line-number"},[s._v("9")]),n("br"),n("span",{staticClass:"line-number"},[s._v("10")]),n("br"),n("span",{staticClass:"line-number"},[s._v("11")]),n("br"),n("span",{staticClass:"line-number"},[s._v("12")]),n("br"),n("span",{staticClass:"line-number"},[s._v("13")]),n("br"),n("span",{staticClass:"line-number"},[s._v("14")]),n("br"),n("span",{staticClass:"line-number"},[s._v("15")]),n("br"),n("span",{staticClass:"line-number"},[s._v("16")]),n("br"),n("span",{staticClass:"line-number"},[s._v("17")]),n("br"),n("span",{staticClass:"line-number"},[s._v("18")]),n("br"),n("span",{staticClass:"line-number"},[s._v("19")]),n("br"),n("span",{staticClass:"line-number"},[s._v("20")]),n("br"),n("span",{staticClass:"line-number"},[s._v("21")]),n("br"),n("span",{staticClass:"line-number"},[s._v("22")]),n("br"),n("span",{staticClass:"line-number"},[s._v("23")]),n("br"),n("span",{staticClass:"line-number"},[s._v("24")]),n("br"),n("span",{staticClass:"line-number"},[s._v("25")]),n("br"),n("span",{staticClass:"line-number"},[s._v("26")]),n("br"),n("span",{staticClass:"line-number"},[s._v("27")]),n("br"),n("span",{staticClass:"line-number"},[s._v("28")]),n("br"),n("span",{staticClass:"line-number"},[s._v("29")]),n("br"),n("span",{staticClass:"line-number"},[s._v("30")]),n("br"),n("span",{staticClass:"line-number"},[s._v("31")]),n("br"),n("span",{staticClass:"line-number"},[s._v("32")]),n("br"),n("span",{staticClass:"line-number"},[s._v("33")]),n("br"),n("span",{staticClass:"line-number"},[s._v("34")]),n("br"),n("span",{staticClass:"line-number"},[s._v("35")]),n("br"),n("span",{staticClass:"line-number"},[s._v("36")]),n("br"),n("span",{staticClass:"line-number"},[s._v("37")]),n("br"),n("span",{staticClass:"line-number"},[s._v("38")]),n("br"),n("span",{staticClass:"line-number"},[s._v("39")]),n("br"),n("span",{staticClass:"line-number"},[s._v("40")]),n("br"),n("span",{staticClass:"line-number"},[s._v("41")]),n("br"),n("span",{staticClass:"line-number"},[s._v("42")]),n("br"),n("span",{staticClass:"line-number"},[s._v("43")]),n("br"),n("span",{staticClass:"line-number"},[s._v("44")]),n("br"),n("span",{staticClass:"line-number"},[s._v("45")]),n("br"),n("span",{staticClass:"line-number"},[s._v("46")]),n("br"),n("span",{staticClass:"line-number"},[s._v("47")]),n("br"),n("span",{staticClass:"line-number"},[s._v("48")]),n("br"),n("span",{staticClass:"line-number"},[s._v("49")]),n("br")])]),n("ul",[n("li",[s._v("说明 1:ex2 = ex1; 和 A ex3 = ex1; 为什么调用的函数不一样?\n对象 ex2 已经实例化了,不需要构造,此时只是将 ex1 赋值给 ex2,只会调用赋值函数;但是 ex3 还没有实例化,因此调用的是拷贝构造函数,构造出 ex3,而不是赋值函数,这里涉及到构造函数的隐式调用。")]),s._v(" "),n("li",[s._v("说明 2:如果拷贝构造函数中形参不是引用类型,A ex3 = ex1;会出现什么问题?\n构造 ex3,实质上是 ex3.A(ex1);,假如拷贝构造函数参数不是引用类型,那么将使得 ex3.A(ex1); 相当于 ex1 作为函数 A(const A tmp)的形参,在参数传递时相当于 A tmp = ex1,因为 tmp 没有被初始化,所以在 A tmp = ex1 中继续调用拷贝构造函数,接下来的是构造 tmp,也就是 tmp.A(ex1) ,必然又会有 ex1 作为函数 A(const A tmp); 的形参,在参数传递时相当于即 A tmp = ex1,那么又会触发拷贝构造函数,就这下永远的递归下去。")]),s._v(" "),n("li",[s._v("说明 3:为什么 ex2.fun(ex1); 会调用拷贝构造函数?\nex1 作为参数传递给 fun 函数, 即 A tmp = ex1;,这个过程会调用拷贝构造函数进行初始化。")])]),s._v(" "),n("h2",{attrs:{id:"c-类对象的初始化顺序"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#c-类对象的初始化顺序"}},[s._v("#")]),s._v(" C++ 类对象的初始化顺序")]),s._v(" "),n("p",[n("strong",[s._v("面试高频指数:★★★☆☆")])]),s._v(" "),n("p",[s._v("构造函数调用顺序:")]),s._v(" "),n("ul",[n("li",[n("p",[s._v("按照派生类继承基类的顺序,即派生列表中声明的顺序,依次调用基类的构造函数;")])]),s._v(" "),n("li",[n("p",[s._v("按照派生类中成员变量的声名顺序,依次调用派生类中成员变量所属类的构造函数;")])]),s._v(" "),n("li",[n("p",[s._v("执行派生类自身的构造函数。")])])]),s._v(" "),n("p",[s._v("综上可以得出,类对象的初始化顺序:基类构造函数–>派生类成员变量的构造函数–>自身构造函数\n注:")]),s._v(" "),n("ul",[n("li",[n("p",[s._v("基类构造函数的调用顺序与派生类的派生列表中的顺序有关;")])]),s._v(" "),n("li",[n("p",[s._v("成员变量的初始化顺序与声明顺序有关;")])]),s._v(" "),n("li",[n("p",[s._v("析构顺序和构造顺序相反。")])])]),s._v(" "),n("div",{staticClass:"language-c++ line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v('#include \nusing namespace std;\n\nclass A\n{\npublic:\n A() { cout << "A()" << endl; }\n ~A() { cout << "~A()" << endl; }\n};\n\nclass B\n{\npublic:\n B() { cout << "B()" << endl; }\n ~B() { cout << "~B()" << endl; }\n};\n\nclass Test : public A, public B // 派生列表\n{\npublic:\n Test() { cout << "Test()" << endl; }\n ~Test() { cout << "~Test()" << endl; }\n\nprivate:\n B ex1;\n A ex2;\n};\n\nint main()\n{\n Test ex;\n return 0;\n}\n/*\n运行结果:\nA()\nB()\nB()\nA()\nTest()\n~Test()\n~A()\n~B()\n~B()\n~A()\n*/\n')])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br"),n("span",{staticClass:"line-number"},[s._v("8")]),n("br"),n("span",{staticClass:"line-number"},[s._v("9")]),n("br"),n("span",{staticClass:"line-number"},[s._v("10")]),n("br"),n("span",{staticClass:"line-number"},[s._v("11")]),n("br"),n("span",{staticClass:"line-number"},[s._v("12")]),n("br"),n("span",{staticClass:"line-number"},[s._v("13")]),n("br"),n("span",{staticClass:"line-number"},[s._v("14")]),n("br"),n("span",{staticClass:"line-number"},[s._v("15")]),n("br"),n("span",{staticClass:"line-number"},[s._v("16")]),n("br"),n("span",{staticClass:"line-number"},[s._v("17")]),n("br"),n("span",{staticClass:"line-number"},[s._v("18")]),n("br"),n("span",{staticClass:"line-number"},[s._v("19")]),n("br"),n("span",{staticClass:"line-number"},[s._v("20")]),n("br"),n("span",{staticClass:"line-number"},[s._v("21")]),n("br"),n("span",{staticClass:"line-number"},[s._v("22")]),n("br"),n("span",{staticClass:"line-number"},[s._v("23")]),n("br"),n("span",{staticClass:"line-number"},[s._v("24")]),n("br"),n("span",{staticClass:"line-number"},[s._v("25")]),n("br"),n("span",{staticClass:"line-number"},[s._v("26")]),n("br"),n("span",{staticClass:"line-number"},[s._v("27")]),n("br"),n("span",{staticClass:"line-number"},[s._v("28")]),n("br"),n("span",{staticClass:"line-number"},[s._v("29")]),n("br"),n("span",{staticClass:"line-number"},[s._v("30")]),n("br"),n("span",{staticClass:"line-number"},[s._v("31")]),n("br"),n("span",{staticClass:"line-number"},[s._v("32")]),n("br"),n("span",{staticClass:"line-number"},[s._v("33")]),n("br"),n("span",{staticClass:"line-number"},[s._v("34")]),n("br"),n("span",{staticClass:"line-number"},[s._v("35")]),n("br"),n("span",{staticClass:"line-number"},[s._v("36")]),n("br"),n("span",{staticClass:"line-number"},[s._v("37")]),n("br"),n("span",{staticClass:"line-number"},[s._v("38")]),n("br"),n("span",{staticClass:"line-number"},[s._v("39")]),n("br"),n("span",{staticClass:"line-number"},[s._v("40")]),n("br"),n("span",{staticClass:"line-number"},[s._v("41")]),n("br"),n("span",{staticClass:"line-number"},[s._v("42")]),n("br"),n("span",{staticClass:"line-number"},[s._v("43")]),n("br"),n("span",{staticClass:"line-number"},[s._v("44")]),n("br"),n("span",{staticClass:"line-number"},[s._v("45")]),n("br"),n("span",{staticClass:"line-number"},[s._v("46")]),n("br")])]),n("p",[s._v("程序运行结果分析:")]),s._v(" "),n("ul",[n("li",[n("p",[s._v("首先调用基类 A 和 B 的构造函数,按照派生列表 public A, public B 的顺序构造;")])]),s._v(" "),n("li",[n("p",[s._v("然后调用派生类 Test 的成员变量 ex1 和 ex2 的构造函数,按照派生类中成员变量声明的顺序构造;")])]),s._v(" "),n("li",[n("p",[s._v("最后调用派生类的构造函数;")])]),s._v(" "),n("li",[n("p",[s._v("接下来调用析构函数,和构造函数调用的顺序相反。")])])]),s._v(" "),n("h2",{attrs:{id:"如何禁止一个类被实例化"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#如何禁止一个类被实例化"}},[s._v("#")]),s._v(" 如何禁止一个类被实例化?")]),s._v(" "),n("p",[n("strong",[s._v("面试高频指数:★★☆☆☆")])]),s._v(" "),n("p",[s._v("方法一:")]),s._v(" "),n("ul",[n("li",[n("p",[s._v("在类中定义一个纯虚函数,使该类成为抽象基类,因为不能创建抽象基类的实例化对象;")]),s._v(" "),n("div",{staticClass:"language-c++ line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v("#include \n\nusing namespace std;\n\n\nclass A {\npublic:\n int var1, var2;\n A(){\n var1 = 10;\n var2 = 20;\n }\n virtual void fun() = 0; // 纯虚函数\n};\n\nint main()\n{\n A ex1; // error: cannot declare variable 'ex1' to be of abstract type 'A'\n return 0;\n}\n")])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br"),n("span",{staticClass:"line-number"},[s._v("8")]),n("br"),n("span",{staticClass:"line-number"},[s._v("9")]),n("br"),n("span",{staticClass:"line-number"},[s._v("10")]),n("br"),n("span",{staticClass:"line-number"},[s._v("11")]),n("br"),n("span",{staticClass:"line-number"},[s._v("12")]),n("br"),n("span",{staticClass:"line-number"},[s._v("13")]),n("br"),n("span",{staticClass:"line-number"},[s._v("14")]),n("br"),n("span",{staticClass:"line-number"},[s._v("15")]),n("br"),n("span",{staticClass:"line-number"},[s._v("16")]),n("br"),n("span",{staticClass:"line-number"},[s._v("17")]),n("br"),n("span",{staticClass:"line-number"},[s._v("18")]),n("br"),n("span",{staticClass:"line-number"},[s._v("19")]),n("br"),n("span",{staticClass:"line-number"},[s._v("20")]),n("br")])])])]),s._v(" "),n("p",[s._v("方法二:")]),s._v(" "),n("ul",[n("li",[s._v("将类的构造函数声明为私有 "),n("code",[s._v("private")])])]),s._v(" "),n("h2",{attrs:{id:"为什么用成员初始化列表会快一些"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#为什么用成员初始化列表会快一些"}},[s._v("#")]),s._v(" 为什么用成员初始化列表会快一些?")]),s._v(" "),n("p",[n("strong",[s._v("面试高频指数:★★★☆☆")]),s._v("\n说明:数据类型可分为内置类型和用户自定义类型(类类型),对于用户自定义类型,利用成员初始化列表效率高。")]),s._v(" "),n("p",[s._v("原因:用户自定义类型如果使用类初始化列表,直接调用该成员变量对应的构造函数即完成初始化;如果在构造函数中初始化,因为 C++ 规定,对象的成员变量的初始化动作发生在进入构造函数本体之前,那么在执行构造函数的函数体之前首先调用默认的构造函数为成员变量设初值,在进入函数体之后,调用该成员变量对应的构造函数。因此,使用列表初始化会减少调用默认的构造函数的过程,效率高。")]),s._v(" "),n("div",{staticClass:"language-c++ line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v('#include \nusing namespace std;\nclass A\n{\nprivate:\n int val;\npublic:\n A()\n {\n cout << "A()" << endl;\n }\n A(int tmp)\n {\n val = tmp;\n cout << "A(int " << val << ")" << endl;\n }\n};\n\nclass Test1\n{\nprivate:\n A ex;\n\npublic:\n Test1() : ex(1) // 成员列表初始化方式\n {\n }\n};\n\nclass Test2\n{\nprivate:\n A ex;\n\npublic:\n Test2() // 函数体中赋值的方式\n {\n ex = A(2);\n }\n};\nint main()\n{\n Test1 ex1;\n cout << endl;\n Test2 ex2;\n return 0;\n}\n/*\n运行结果:\nA(int 1)\n\nA()\nA(int 2)\n*/\n')])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br"),n("span",{staticClass:"line-number"},[s._v("8")]),n("br"),n("span",{staticClass:"line-number"},[s._v("9")]),n("br"),n("span",{staticClass:"line-number"},[s._v("10")]),n("br"),n("span",{staticClass:"line-number"},[s._v("11")]),n("br"),n("span",{staticClass:"line-number"},[s._v("12")]),n("br"),n("span",{staticClass:"line-number"},[s._v("13")]),n("br"),n("span",{staticClass:"line-number"},[s._v("14")]),n("br"),n("span",{staticClass:"line-number"},[s._v("15")]),n("br"),n("span",{staticClass:"line-number"},[s._v("16")]),n("br"),n("span",{staticClass:"line-number"},[s._v("17")]),n("br"),n("span",{staticClass:"line-number"},[s._v("18")]),n("br"),n("span",{staticClass:"line-number"},[s._v("19")]),n("br"),n("span",{staticClass:"line-number"},[s._v("20")]),n("br"),n("span",{staticClass:"line-number"},[s._v("21")]),n("br"),n("span",{staticClass:"line-number"},[s._v("22")]),n("br"),n("span",{staticClass:"line-number"},[s._v("23")]),n("br"),n("span",{staticClass:"line-number"},[s._v("24")]),n("br"),n("span",{staticClass:"line-number"},[s._v("25")]),n("br"),n("span",{staticClass:"line-number"},[s._v("26")]),n("br"),n("span",{staticClass:"line-number"},[s._v("27")]),n("br"),n("span",{staticClass:"line-number"},[s._v("28")]),n("br"),n("span",{staticClass:"line-number"},[s._v("29")]),n("br"),n("span",{staticClass:"line-number"},[s._v("30")]),n("br"),n("span",{staticClass:"line-number"},[s._v("31")]),n("br"),n("span",{staticClass:"line-number"},[s._v("32")]),n("br"),n("span",{staticClass:"line-number"},[s._v("33")]),n("br"),n("span",{staticClass:"line-number"},[s._v("34")]),n("br"),n("span",{staticClass:"line-number"},[s._v("35")]),n("br"),n("span",{staticClass:"line-number"},[s._v("36")]),n("br"),n("span",{staticClass:"line-number"},[s._v("37")]),n("br"),n("span",{staticClass:"line-number"},[s._v("38")]),n("br"),n("span",{staticClass:"line-number"},[s._v("39")]),n("br"),n("span",{staticClass:"line-number"},[s._v("40")]),n("br"),n("span",{staticClass:"line-number"},[s._v("41")]),n("br"),n("span",{staticClass:"line-number"},[s._v("42")]),n("br"),n("span",{staticClass:"line-number"},[s._v("43")]),n("br"),n("span",{staticClass:"line-number"},[s._v("44")]),n("br"),n("span",{staticClass:"line-number"},[s._v("45")]),n("br"),n("span",{staticClass:"line-number"},[s._v("46")]),n("br"),n("span",{staticClass:"line-number"},[s._v("47")]),n("br"),n("span",{staticClass:"line-number"},[s._v("48")]),n("br"),n("span",{staticClass:"line-number"},[s._v("49")]),n("br"),n("span",{staticClass:"line-number"},[s._v("50")]),n("br"),n("span",{staticClass:"line-number"},[s._v("51")]),n("br"),n("span",{staticClass:"line-number"},[s._v("52")]),n("br"),n("span",{staticClass:"line-number"},[s._v("53")]),n("br"),n("span",{staticClass:"line-number"},[s._v("54")]),n("br")])]),n("p",[s._v("说明:\n从程序运行结果可以看出,使用成员列表初始化的方式会省去调用默认的构造函数的过程。")]),s._v(" "),n("h2",{attrs:{id:"实例化一个对象需要哪几个阶段"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#实例化一个对象需要哪几个阶段"}},[s._v("#")]),s._v(" 实例化一个对象需要哪几个阶段")]),s._v(" "),n("p",[n("strong",[s._v("面试高频指数:★★★☆☆")])]),s._v(" "),n("ol",[n("li",[s._v("分配空间\n创建类对象首先要为该对象分配内存空间。不同的对象,为其分配空间的时机未必相同。全局对象、静态对象、分配在栈区域内的对象,在编译阶段进行内存分配;存储在堆空间的对象,是在运行阶段进行内存分配。")]),s._v(" "),n("li",[s._v("初始化\n首先明确一点:初始化不同于赋值。初始化发生在赋值之前,初始化随对象的创建而进行,而赋值是在对象创建好后,为其赋上相应的值。这一点可以联想下上一个问题中提到:初始化列表先于构造函数体内的代码执行,初始化列表执行的是数据成员的初始化过程,这个可以从成员对象的构造函数被调用看的出来。")]),s._v(" "),n("li",[s._v("赋值\n对象初始化完成后,可以对其进行赋值。对于一个类的对象,其成员变量的赋值过程发生在类的构造函数的函数体中。当执行完该函数体,也就意味着类对象的实例化过程完成了。(总结:构造函数实现了对象的初始化和赋值两个过程,对象的初始化是通过初始化列表来完成,而对象的赋值则才是通过构造函数的函数体来实现。)")])]),s._v(" "),n("p",[s._v("注:对于拥有虚函数的类的对象,还需要给虚表指针赋值。")]),s._v(" "),n("ul",[n("li",[s._v("没有继承关系的类,分配完内存后,首先给虚表指针赋值,然后再列表初始化以及执行构造函数的函数体,即上述中的初始化和赋值操作。")]),s._v(" "),n("li",[s._v("有继承关系的类,分配内存之后,首先进行基类的构造过程,然后给该派生类的虚表指针赋值,最后再列表初始化以及执行构造函数的函数体,即上述中的初始化和赋值操作。")])]),s._v(" "),n("h2",{attrs:{id:"友元函数的作用及使用场景"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#友元函数的作用及使用场景"}},[s._v("#")]),s._v(" 友元函数的作用及使用场景")]),s._v(" "),n("p",[n("strong",[s._v("面试高频指数:★★☆☆☆")]),s._v("\n作用:友元提供了不同类的成员函数之间、类的成员函数与一般函数之间进行数据共享的机制。通过友元,一个不同函数或另一个类中的成员函数可以访问类中的私有成员和保护成员。")]),s._v(" "),n("p",[s._v("使用场景:")]),s._v(" "),n("ol",[n("li",[n("p",[s._v("普通函数定义为友元函数,使普通函数能够访问类的私有成员。")]),s._v(" "),n("div",{staticClass:"language-c++ line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v("#include \n\nusing namespace std;\n\nclass A\n{\n friend ostream &operator<<(ostream &_cout, const A &tmp); // 声明为类的友元函数\n\npublic:\n A(int tmp) : var(tmp)\n {\n }\n\nprivate:\n int var;\n};\n\nostream &operator<<(ostream &_cout, const A &tmp)\n{\n _cout << tmp.var;\n return _cout;\n}\n\nint main()\n{\n A ex(4);\n cout << ex << endl; // 4\n return 0;\n}\n")])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br"),n("span",{staticClass:"line-number"},[s._v("8")]),n("br"),n("span",{staticClass:"line-number"},[s._v("9")]),n("br"),n("span",{staticClass:"line-number"},[s._v("10")]),n("br"),n("span",{staticClass:"line-number"},[s._v("11")]),n("br"),n("span",{staticClass:"line-number"},[s._v("12")]),n("br"),n("span",{staticClass:"line-number"},[s._v("13")]),n("br"),n("span",{staticClass:"line-number"},[s._v("14")]),n("br"),n("span",{staticClass:"line-number"},[s._v("15")]),n("br"),n("span",{staticClass:"line-number"},[s._v("16")]),n("br"),n("span",{staticClass:"line-number"},[s._v("17")]),n("br"),n("span",{staticClass:"line-number"},[s._v("18")]),n("br"),n("span",{staticClass:"line-number"},[s._v("19")]),n("br"),n("span",{staticClass:"line-number"},[s._v("20")]),n("br"),n("span",{staticClass:"line-number"},[s._v("21")]),n("br"),n("span",{staticClass:"line-number"},[s._v("22")]),n("br"),n("span",{staticClass:"line-number"},[s._v("23")]),n("br"),n("span",{staticClass:"line-number"},[s._v("24")]),n("br"),n("span",{staticClass:"line-number"},[s._v("25")]),n("br"),n("span",{staticClass:"line-number"},[s._v("26")]),n("br"),n("span",{staticClass:"line-number"},[s._v("27")]),n("br"),n("span",{staticClass:"line-number"},[s._v("28")]),n("br"),n("span",{staticClass:"line-number"},[s._v("29")]),n("br")])])]),s._v(" "),n("li",[n("p",[s._v("友元类:类之间共享数据。")]),s._v(" "),n("div",{staticClass:"language-c++ line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v('#include \n\nusing namespace std;\n\nclass A\n{\n friend class B;\n\npublic:\n A() : var(10){}\n A(int tmp) : var(tmp) {}\n void fun()\n {\n cout << "fun():" << var << endl;\n }\n\nprivate:\n int var;\n};\n\nclass B\n{\npublic:\n B() {}\n void fun()\n {\n cout << "fun():" << ex.var << endl; // 访问类 A 中的私有成员\n }\n\nprivate:\n A ex;\n};\n\nint main()\n{\n B ex;\n ex.fun(); // fun():10\n return 0;\n}\n')])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br"),n("span",{staticClass:"line-number"},[s._v("8")]),n("br"),n("span",{staticClass:"line-number"},[s._v("9")]),n("br"),n("span",{staticClass:"line-number"},[s._v("10")]),n("br"),n("span",{staticClass:"line-number"},[s._v("11")]),n("br"),n("span",{staticClass:"line-number"},[s._v("12")]),n("br"),n("span",{staticClass:"line-number"},[s._v("13")]),n("br"),n("span",{staticClass:"line-number"},[s._v("14")]),n("br"),n("span",{staticClass:"line-number"},[s._v("15")]),n("br"),n("span",{staticClass:"line-number"},[s._v("16")]),n("br"),n("span",{staticClass:"line-number"},[s._v("17")]),n("br"),n("span",{staticClass:"line-number"},[s._v("18")]),n("br"),n("span",{staticClass:"line-number"},[s._v("19")]),n("br"),n("span",{staticClass:"line-number"},[s._v("20")]),n("br"),n("span",{staticClass:"line-number"},[s._v("21")]),n("br"),n("span",{staticClass:"line-number"},[s._v("22")]),n("br"),n("span",{staticClass:"line-number"},[s._v("23")]),n("br"),n("span",{staticClass:"line-number"},[s._v("24")]),n("br"),n("span",{staticClass:"line-number"},[s._v("25")]),n("br"),n("span",{staticClass:"line-number"},[s._v("26")]),n("br"),n("span",{staticClass:"line-number"},[s._v("27")]),n("br"),n("span",{staticClass:"line-number"},[s._v("28")]),n("br"),n("span",{staticClass:"line-number"},[s._v("29")]),n("br"),n("span",{staticClass:"line-number"},[s._v("30")]),n("br"),n("span",{staticClass:"line-number"},[s._v("31")]),n("br"),n("span",{staticClass:"line-number"},[s._v("32")]),n("br"),n("span",{staticClass:"line-number"},[s._v("33")]),n("br"),n("span",{staticClass:"line-number"},[s._v("34")]),n("br"),n("span",{staticClass:"line-number"},[s._v("35")]),n("br"),n("span",{staticClass:"line-number"},[s._v("36")]),n("br"),n("span",{staticClass:"line-number"},[s._v("37")]),n("br"),n("span",{staticClass:"line-number"},[s._v("38")]),n("br"),n("span",{staticClass:"line-number"},[s._v("39")]),n("br")])])])]),s._v(" "),n("h2",{attrs:{id:"静态绑定和动态绑定是怎么实现的"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#静态绑定和动态绑定是怎么实现的"}},[s._v("#")]),s._v(" 静态绑定和动态绑定是怎么实现的?")]),s._v(" "),n("p",[n("strong",[s._v("面试高频指数:★★★☆☆")])]),s._v(" "),n("p",[s._v("静态类型和动态类型:")]),s._v(" "),n("ul",[n("li",[n("p",[s._v("静态类型:变量在声明时的类型,是在编译阶段确定的。静态类型不能更改。")])]),s._v(" "),n("li",[n("p",[s._v("动态类型:目前所指对象的类型,是在运行阶段确定的。动态类型可以更改。")])])]),s._v(" "),n("p",[s._v("静态绑定和动态绑定:")]),s._v(" "),n("ul",[n("li",[n("p",[s._v("静态绑定是指程序在 编译阶段 确定对象的类型(静态类型)。")])]),s._v(" "),n("li",[n("p",[s._v("动态绑定是指程序在 运行阶段 确定对象的类型(动态类型)。")])])]),s._v(" "),n("p",[s._v("静态绑定和动态绑定的区别:")]),s._v(" "),n("ul",[n("li",[n("p",[s._v("发生的时期不同:如上。")])]),s._v(" "),n("li",[n("p",[s._v("对象的静态类型不能更改,动态类型可以更改。")])])]),s._v(" "),n("p",[s._v("注:对于类的成员函数,只有虚函数是动态绑定,其他都是静态绑定。")]),s._v(" "),n("div",{staticClass:"language-c++ line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v('#include \n\nusing namespace std;\n\nclass Base\n{\npublic:\n virtual void fun() { cout << "Base::fun()" << endl;\n }\n};\nclass Derive : public Base\n{\npublic:\n void fun() { cout << "Derive::fun()";\n }\n};\n\n\nint main()\n{\n Base *p = new Derive(); // p 的静态类型是 Base*,动态类型是 Derive*\n p->fun(); // fun 是虚函数,运行阶段进行动态绑定\n return 0;\n}\n/*\n运行结果:\nDerive::fun()\n*/\n')])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br"),n("span",{staticClass:"line-number"},[s._v("8")]),n("br"),n("span",{staticClass:"line-number"},[s._v("9")]),n("br"),n("span",{staticClass:"line-number"},[s._v("10")]),n("br"),n("span",{staticClass:"line-number"},[s._v("11")]),n("br"),n("span",{staticClass:"line-number"},[s._v("12")]),n("br"),n("span",{staticClass:"line-number"},[s._v("13")]),n("br"),n("span",{staticClass:"line-number"},[s._v("14")]),n("br"),n("span",{staticClass:"line-number"},[s._v("15")]),n("br"),n("span",{staticClass:"line-number"},[s._v("16")]),n("br"),n("span",{staticClass:"line-number"},[s._v("17")]),n("br"),n("span",{staticClass:"line-number"},[s._v("18")]),n("br"),n("span",{staticClass:"line-number"},[s._v("19")]),n("br"),n("span",{staticClass:"line-number"},[s._v("20")]),n("br"),n("span",{staticClass:"line-number"},[s._v("21")]),n("br"),n("span",{staticClass:"line-number"},[s._v("22")]),n("br"),n("span",{staticClass:"line-number"},[s._v("23")]),n("br"),n("span",{staticClass:"line-number"},[s._v("24")]),n("br"),n("span",{staticClass:"line-number"},[s._v("25")]),n("br"),n("span",{staticClass:"line-number"},[s._v("26")]),n("br"),n("span",{staticClass:"line-number"},[s._v("27")]),n("br"),n("span",{staticClass:"line-number"},[s._v("28")]),n("br")])]),n("h2",{attrs:{id:"深拷贝和浅拷贝的区别"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#深拷贝和浅拷贝的区别"}},[s._v("#")]),s._v(" 深拷贝和浅拷贝的区别")]),s._v(" "),n("p",[n("strong",[s._v("面试高频指数:★★★★★")]),s._v("\n如果一个类拥有资源,该类的对象进行复制时,如果资源重新分配,就是深拷贝,否则就是浅拷贝。")]),s._v(" "),n("ul",[n("li",[n("p",[s._v("深拷贝:该对象和原对象占用不同的内存空间,既拷贝存储在栈空间中的内容,又拷贝存储在堆空间中的内容。")])]),s._v(" "),n("li",[n("p",[s._v("浅拷贝:该对象和原对象占用同一块内存空间,仅拷贝类中位于栈空间中的内容。")])])]),s._v(" "),n("p",[s._v("当类的成员变量中有指针变量时,最好使用深拷贝。因为当两个对象指向同一块内存空间,如果使用浅拷贝,当其中一个对象的删除后,该块内存空间就会被释放,另外一个对象指向的就是垃圾内存。")]),s._v(" "),n("p",[n("strong",[s._v("浅拷贝实例")])]),s._v(" "),n("div",{staticClass:"language-c++ line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v('#include \n\nusing namespace std;\n\nclass Test\n{\nprivate:\n int *p;\n\npublic:\n Test(int tmp)\n {\n this->p = new int(tmp);\n cout << "Test(int tmp)" << endl;\n }\n ~Test()\n {\n if (p != NULL)\n {\n delete p;\n }\n cout << "~Test()" << endl;\n }\n};\n\nint main()\n{\n Test ex1(10);\n Test ex2 = ex1;\n return 0;\n}\n/*\n运行结果:\nTest(int tmp)\n~Test()\n*/\n')])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br"),n("span",{staticClass:"line-number"},[s._v("8")]),n("br"),n("span",{staticClass:"line-number"},[s._v("9")]),n("br"),n("span",{staticClass:"line-number"},[s._v("10")]),n("br"),n("span",{staticClass:"line-number"},[s._v("11")]),n("br"),n("span",{staticClass:"line-number"},[s._v("12")]),n("br"),n("span",{staticClass:"line-number"},[s._v("13")]),n("br"),n("span",{staticClass:"line-number"},[s._v("14")]),n("br"),n("span",{staticClass:"line-number"},[s._v("15")]),n("br"),n("span",{staticClass:"line-number"},[s._v("16")]),n("br"),n("span",{staticClass:"line-number"},[s._v("17")]),n("br"),n("span",{staticClass:"line-number"},[s._v("18")]),n("br"),n("span",{staticClass:"line-number"},[s._v("19")]),n("br"),n("span",{staticClass:"line-number"},[s._v("20")]),n("br"),n("span",{staticClass:"line-number"},[s._v("21")]),n("br"),n("span",{staticClass:"line-number"},[s._v("22")]),n("br"),n("span",{staticClass:"line-number"},[s._v("23")]),n("br"),n("span",{staticClass:"line-number"},[s._v("24")]),n("br"),n("span",{staticClass:"line-number"},[s._v("25")]),n("br"),n("span",{staticClass:"line-number"},[s._v("26")]),n("br"),n("span",{staticClass:"line-number"},[s._v("27")]),n("br"),n("span",{staticClass:"line-number"},[s._v("28")]),n("br"),n("span",{staticClass:"line-number"},[s._v("29")]),n("br"),n("span",{staticClass:"line-number"},[s._v("30")]),n("br"),n("span",{staticClass:"line-number"},[s._v("31")]),n("br"),n("span",{staticClass:"line-number"},[s._v("32")]),n("br"),n("span",{staticClass:"line-number"},[s._v("33")]),n("br"),n("span",{staticClass:"line-number"},[s._v("34")]),n("br"),n("span",{staticClass:"line-number"},[s._v("35")]),n("br"),n("span",{staticClass:"line-number"},[s._v("36")]),n("br")])]),n("p",[s._v("说明:上述代码中,类对象 ex1、ex2 实际上是指向同一块内存空间,对象析构时,ex2 先将内存释放了一次,之后 析构对象 ex1 时又将这块已经被释放过的内存再释放一次。对同一块内存空间释放了两次,会导致程序崩溃。")]),s._v(" "),n("p",[n("strong",[s._v("深拷贝实例:")])]),s._v(" "),n("div",{staticClass:"language-c++ line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v('#include \n\nusing namespace std;\n\nclass Test\n{\nprivate:\n int *p;\n\npublic:\n Test(int tmp)\n {\n p = new int(tmp);\n cout << "Test(int tmp)" << endl;\n }\n ~Test()\n {\n if (p != NULL)\n {\n delete p;\n }\n cout << "~Test()" << endl;\n }\n Test(const Test &tmp) // 定义拷贝构造函数\n {\n p = new int(*tmp.p);\n cout << "Test(const Test &tmp)" << endl;\n }\n\n};\n\nint main()\n{\n Test ex1(10);\n Test ex2 = ex1;\n return 0;\n}\n/*\nTest(int tmp)\nTest(const Test &tmp)\n~Test()\n~Test()\n*/\n')])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br"),n("span",{staticClass:"line-number"},[s._v("8")]),n("br"),n("span",{staticClass:"line-number"},[s._v("9")]),n("br"),n("span",{staticClass:"line-number"},[s._v("10")]),n("br"),n("span",{staticClass:"line-number"},[s._v("11")]),n("br"),n("span",{staticClass:"line-number"},[s._v("12")]),n("br"),n("span",{staticClass:"line-number"},[s._v("13")]),n("br"),n("span",{staticClass:"line-number"},[s._v("14")]),n("br"),n("span",{staticClass:"line-number"},[s._v("15")]),n("br"),n("span",{staticClass:"line-number"},[s._v("16")]),n("br"),n("span",{staticClass:"line-number"},[s._v("17")]),n("br"),n("span",{staticClass:"line-number"},[s._v("18")]),n("br"),n("span",{staticClass:"line-number"},[s._v("19")]),n("br"),n("span",{staticClass:"line-number"},[s._v("20")]),n("br"),n("span",{staticClass:"line-number"},[s._v("21")]),n("br"),n("span",{staticClass:"line-number"},[s._v("22")]),n("br"),n("span",{staticClass:"line-number"},[s._v("23")]),n("br"),n("span",{staticClass:"line-number"},[s._v("24")]),n("br"),n("span",{staticClass:"line-number"},[s._v("25")]),n("br"),n("span",{staticClass:"line-number"},[s._v("26")]),n("br"),n("span",{staticClass:"line-number"},[s._v("27")]),n("br"),n("span",{staticClass:"line-number"},[s._v("28")]),n("br"),n("span",{staticClass:"line-number"},[s._v("29")]),n("br"),n("span",{staticClass:"line-number"},[s._v("30")]),n("br"),n("span",{staticClass:"line-number"},[s._v("31")]),n("br"),n("span",{staticClass:"line-number"},[s._v("32")]),n("br"),n("span",{staticClass:"line-number"},[s._v("33")]),n("br"),n("span",{staticClass:"line-number"},[s._v("34")]),n("br"),n("span",{staticClass:"line-number"},[s._v("35")]),n("br"),n("span",{staticClass:"line-number"},[s._v("36")]),n("br"),n("span",{staticClass:"line-number"},[s._v("37")]),n("br"),n("span",{staticClass:"line-number"},[s._v("38")]),n("br"),n("span",{staticClass:"line-number"},[s._v("39")]),n("br"),n("span",{staticClass:"line-number"},[s._v("40")]),n("br"),n("span",{staticClass:"line-number"},[s._v("41")]),n("br"),n("span",{staticClass:"line-number"},[s._v("42")]),n("br"),n("span",{staticClass:"line-number"},[s._v("43")]),n("br")])]),n("h2",{attrs:{id:"编译时多态和运行时多态的区别"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#编译时多态和运行时多态的区别"}},[s._v("#")]),s._v(" 编译时多态和运行时多态的区别")]),s._v(" "),n("p",[n("strong",[s._v("面试高频指数:★★★☆☆")]),s._v("\n编译时多态:在程序编译过程中出现,发生在模板和函数重载中(泛型编程)。\n运行时多态:在程序运行过程中出现,发生在继承体系中,是指通过基类的指针或引用访问派生类中的虚函数。")]),s._v(" "),n("p",[s._v("编译时多态和运行时多态的区别:")]),s._v(" "),n("ul",[n("li",[n("p",[s._v("时期不同:编译时多态发生在程序编译过程中,运行时多态发生在程序的运行过程中;")])]),s._v(" "),n("li",[n("p",[s._v("实现方式不同:编译时多态运用泛型编程来实现,运行时多态借助虚函数来实现。")])])]),s._v(" "),n("h2",{attrs:{id:"实现一个类成员函数-要求不允许修改类的成员变量"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#实现一个类成员函数-要求不允许修改类的成员变量"}},[s._v("#")]),s._v(" 实现一个类成员函数,要求不允许修改类的成员变量?")]),s._v(" "),n("p",[n("strong",[s._v("面试高频指数:★★☆☆☆")])]),s._v(" "),n("p",[s._v("如果想达到一个类的成员函数不能修改类的成员变量,只需用 const 关键字来修饰该函数即可。\n该问题本质是考察 const 关键字修饰成员函数的作用,只不过以实例的方式来考察,面试者应熟练掌握 const 关键字的作用。")]),s._v(" "),n("div",{staticClass:"language-c++ line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v("#include \n\nusing namespace std;\n\nclass A\n{\npublic:\n int var1, var2;\n A()\n {\n var1 = 10;\n var2 = 20;\n }\n void fun() const // 不能在 const 修饰的成员函数中修改成员变量的值,除非该成员变量用 mutable 修饰\n {\n var1 = 100; // error: assignment of member 'A::var1' in read-only object\n }\n};\n\nint main()\n{\n A ex1;\n return 0;\n}\n")])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br"),n("span",{staticClass:"line-number"},[s._v("8")]),n("br"),n("span",{staticClass:"line-number"},[s._v("9")]),n("br"),n("span",{staticClass:"line-number"},[s._v("10")]),n("br"),n("span",{staticClass:"line-number"},[s._v("11")]),n("br"),n("span",{staticClass:"line-number"},[s._v("12")]),n("br"),n("span",{staticClass:"line-number"},[s._v("13")]),n("br"),n("span",{staticClass:"line-number"},[s._v("14")]),n("br"),n("span",{staticClass:"line-number"},[s._v("15")]),n("br"),n("span",{staticClass:"line-number"},[s._v("16")]),n("br"),n("span",{staticClass:"line-number"},[s._v("17")]),n("br"),n("span",{staticClass:"line-number"},[s._v("18")]),n("br"),n("span",{staticClass:"line-number"},[s._v("19")]),n("br"),n("span",{staticClass:"line-number"},[s._v("20")]),n("br"),n("span",{staticClass:"line-number"},[s._v("21")]),n("br"),n("span",{staticClass:"line-number"},[s._v("22")]),n("br"),n("span",{staticClass:"line-number"},[s._v("23")]),n("br"),n("span",{staticClass:"line-number"},[s._v("24")]),n("br")])]),n("h2",{attrs:{id:"如何让类不能被继承"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#如何让类不能被继承"}},[s._v("#")]),s._v(" 如何让类不能被继承?")]),s._v(" "),n("p",[n("strong",[s._v("面试高频指数:★★★☆☆")])]),s._v(" "),n("p",[s._v("解决方法一:借助 "),n("code",[s._v("final")]),s._v(" 关键字,用该关键字修饰的类不能被继承。")]),s._v(" "),n("div",{staticClass:"language-c++ line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v("#include \n\nusing namespace std;\n\nclass Base final\n{\n};\n\nclass Derive: public Base{ // error: cannot derive from 'final' base 'Base' in derived type 'Derive'\n\n};\n\nint main()\n{\n Derive ex;\n return 0;\n}\n")])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br"),n("span",{staticClass:"line-number"},[s._v("8")]),n("br"),n("span",{staticClass:"line-number"},[s._v("9")]),n("br"),n("span",{staticClass:"line-number"},[s._v("10")]),n("br"),n("span",{staticClass:"line-number"},[s._v("11")]),n("br"),n("span",{staticClass:"line-number"},[s._v("12")]),n("br"),n("span",{staticClass:"line-number"},[s._v("13")]),n("br"),n("span",{staticClass:"line-number"},[s._v("14")]),n("br"),n("span",{staticClass:"line-number"},[s._v("15")]),n("br"),n("span",{staticClass:"line-number"},[s._v("16")]),n("br"),n("span",{staticClass:"line-number"},[s._v("17")]),n("br")])]),n("p",[s._v("解决方法二:借助友元、虚继承和私有构造函数来实现")]),s._v(" "),n("div",{staticClass:"language-c++ line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v('#include \nusing namespace std;\n\ntemplate \nclass Base{\n friend T;\nprivate:\n Base(){\n cout << "base" << endl;\n }\n ~Base(){}\n};\n\nclass B:virtual public Base{ //一定注意 必须是虚继承\npublic:\n B(){\n cout << "B" << endl;\n }\n};\n\nclass C:public B{\npublic:\n C(){} // error: \'Base::Base() [with T = B]\' is private within this context\n};\n\n\nint main(){\n B b;\n return 0;\n}\n')])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br"),n("span",{staticClass:"line-number"},[s._v("8")]),n("br"),n("span",{staticClass:"line-number"},[s._v("9")]),n("br"),n("span",{staticClass:"line-number"},[s._v("10")]),n("br"),n("span",{staticClass:"line-number"},[s._v("11")]),n("br"),n("span",{staticClass:"line-number"},[s._v("12")]),n("br"),n("span",{staticClass:"line-number"},[s._v("13")]),n("br"),n("span",{staticClass:"line-number"},[s._v("14")]),n("br"),n("span",{staticClass:"line-number"},[s._v("15")]),n("br"),n("span",{staticClass:"line-number"},[s._v("16")]),n("br"),n("span",{staticClass:"line-number"},[s._v("17")]),n("br"),n("span",{staticClass:"line-number"},[s._v("18")]),n("br"),n("span",{staticClass:"line-number"},[s._v("19")]),n("br"),n("span",{staticClass:"line-number"},[s._v("20")]),n("br"),n("span",{staticClass:"line-number"},[s._v("21")]),n("br"),n("span",{staticClass:"line-number"},[s._v("22")]),n("br"),n("span",{staticClass:"line-number"},[s._v("23")]),n("br"),n("span",{staticClass:"line-number"},[s._v("24")]),n("br"),n("span",{staticClass:"line-number"},[s._v("25")]),n("br"),n("span",{staticClass:"line-number"},[s._v("26")]),n("br"),n("span",{staticClass:"line-number"},[s._v("27")]),n("br"),n("span",{staticClass:"line-number"},[s._v("28")]),n("br"),n("span",{staticClass:"line-number"},[s._v("29")]),n("br"),n("span",{staticClass:"line-number"},[s._v("30")]),n("br")])]),n("p",[s._v("说明:在上述代码中 B 类是不能被继承的类。\n具体原因:")]),s._v(" "),n("ul",[n("li",[s._v("虽然 Base 类构造函数和析构函数被声明为私有 private,在 B 类中,由于 B 是 Base 的友元,因此可以访问 Base 类构造函数,从而正常创建 B 类的对象;")]),s._v(" "),n("li",[s._v("B 类继承 Base 类采用虚继承的方式,创建 C 类的对象时,C 类的构造函数要负责 Base 类的构造,但是 Base 类的构造函数私有化了,C 类没有权限访问。因此,无法创建 C 类的对象, B 类是不能被继承的类。")])]),s._v(" "),n("p",[s._v("注意:在继承体系中,友元关系不能被继承,虽然 C 类继承了 B 类,B 类是 Base 类的友元,但是 C 类和 Base 类没有友元关系。")]),s._v(" "),n("h1",{attrs:{id:"语言特性相关"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#语言特性相关"}},[s._v("#")]),s._v(" 语言特性相关")]),s._v(" "),n("p",[s._v("第六章重点介绍和 C++ 语言特性相关的知识点,涉及到指针、引用、强制类型转换等。在本章中也增加了设计模式相关知识点,重点对单例模式进行介绍,包括其实现思想,应用场景,代码实现等。")]),s._v(" "),n("h2",{attrs:{id:"左值和右值的区别-左值引用和右值引用的区别-如何将左值转换成右值"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#左值和右值的区别-左值引用和右值引用的区别-如何将左值转换成右值"}},[s._v("#")]),s._v(" 左值和右值的区别?左值引用和右值引用的区别,如何将左值转换成右值?")]),s._v(" "),n("p",[n("strong",[s._v("面试高频指数:★★★★☆")]),s._v("\n左值:指表达式结束后依然存在的持久对象。")]),s._v(" "),n("p",[s._v("右值:表达式结束就不再存在的临时对象。")]),s._v(" "),n("p",[s._v("左值和右值的区别:左值持久,右值短暂")]),s._v(" "),n("p",[s._v("右值引用和左值引用的区别:")]),s._v(" "),n("ul",[n("li",[n("p",[s._v("左值引用不能绑定到要转换的表达式、字面常量或返回右值的表达式。右值引用恰好相反,可以绑定到这类表达式,但不能绑定到一个左值上。")])]),s._v(" "),n("li",[n("p",[s._v("右值引用必须绑定到右值的引用,通过 && 获得。右值引用只能绑定到一个将要销毁的对象上,因此可以自由地移动其资源。")])])]),s._v(" "),n("p",[s._v("std::move 可以将一个左值强制转化为右值,继而可以通过右值引用使用该值,以用于移动语义。")]),s._v(" "),n("div",{staticClass:"language-c++ line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v("#include \nusing namespace std;\n\nvoid fun1(int& tmp)\n{\n cout << \"fun1(int& tmp):\" << tmp << endl;\n}\n\nvoid fun2(int&& tmp)\n{\n cout << \"fun2(int&& tmp)\" << tmp << endl;\n}\n\nint main()\n{\n int var = 11;\n fun1(12); // error: cannot bind non-const lvalue reference of type 'int&' to an rvalue of type 'int'\n fun1(var);\n fun2(1);\n}\n")])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br"),n("span",{staticClass:"line-number"},[s._v("8")]),n("br"),n("span",{staticClass:"line-number"},[s._v("9")]),n("br"),n("span",{staticClass:"line-number"},[s._v("10")]),n("br"),n("span",{staticClass:"line-number"},[s._v("11")]),n("br"),n("span",{staticClass:"line-number"},[s._v("12")]),n("br"),n("span",{staticClass:"line-number"},[s._v("13")]),n("br"),n("span",{staticClass:"line-number"},[s._v("14")]),n("br"),n("span",{staticClass:"line-number"},[s._v("15")]),n("br"),n("span",{staticClass:"line-number"},[s._v("16")]),n("br"),n("span",{staticClass:"line-number"},[s._v("17")]),n("br"),n("span",{staticClass:"line-number"},[s._v("18")]),n("br"),n("span",{staticClass:"line-number"},[s._v("19")]),n("br"),n("span",{staticClass:"line-number"},[s._v("20")]),n("br")])]),n("h2",{attrs:{id:"std-move-函数的实现原理"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#std-move-函数的实现原理"}},[s._v("#")]),s._v(" std::move() 函数的实现原理")]),s._v(" "),n("p",[n("strong",[s._v("面试高频指数:★★★☆☆")])]),s._v(" "),n("p",[n("code",[s._v("std::move()")]),s._v(" 函数原型:")]),s._v(" "),n("div",{staticClass:"language-c++ line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v("template \ntypename remove_reference::type&& move(T&& t)\n{\n return static_cast::type &&>(t);\n}\n")])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br")])]),n("p",[s._v("说明:引用折叠原理")]),s._v(" "),n("p",[s._v("右值传递给上述函数的形参 T&& 依然是右值,即 T&& && 相当于 T&&。\n左值传递给上述函数的形参 T&& 依然是左值,即 T&& & 相当于 T&。\n小结:通过引用折叠原理可以知道,move() 函数的形参既可以是左值也可以是右值。")]),s._v(" "),n("p",[s._v("remove_reference 具体实现:")]),s._v(" "),n("div",{staticClass:"language-c++ line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v("//原始的,最通用的版本\ntemplate struct remove_reference{\n    typedef T type;  //定义 T 的类型别名为 type\n};\n \n//部分版本特例化,将用于左值引用和右值引用\ntemplate struct remove_reference //左值引用\n{ typedef T type; }\n \ntemplate struct remove_reference //右值引用\n{ typedef T type; }   \n  \n//举例如下,下列定义的a、b、c三个变量都是int类型\nint i;\nremove_refrence::type a;             //使用原版本,\nremove_refrence::type  b;             //左值引用特例版本\nremove_refrence::type  b;  //右值引用特例版本 \n")])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br"),n("span",{staticClass:"line-number"},[s._v("8")]),n("br"),n("span",{staticClass:"line-number"},[s._v("9")]),n("br"),n("span",{staticClass:"line-number"},[s._v("10")]),n("br"),n("span",{staticClass:"line-number"},[s._v("11")]),n("br"),n("span",{staticClass:"line-number"},[s._v("12")]),n("br"),n("span",{staticClass:"line-number"},[s._v("13")]),n("br"),n("span",{staticClass:"line-number"},[s._v("14")]),n("br"),n("span",{staticClass:"line-number"},[s._v("15")]),n("br"),n("span",{staticClass:"line-number"},[s._v("16")]),n("br"),n("span",{staticClass:"line-number"},[s._v("17")]),n("br")])]),n("p",[s._v("举例:")]),s._v(" "),n("div",{staticClass:"language-c++ line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v("int var = 10;\n\n转化过程:\n1. std::move(var) => std::move(int&& &) => 折叠后 std::move(int&)\n\n2. 此时:T 的类型为 int&,typename remove_reference::type 为 int,这里使用 remove_reference 的左值引用的特例化版本\n\n3. 通过 static_cast 将 int& 强制转换为 int&&\n\n整个std::move被实例化如下\nstring&& move(int& t)\n{\n    return static_cast(t); \n}\n")])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br"),n("span",{staticClass:"line-number"},[s._v("8")]),n("br"),n("span",{staticClass:"line-number"},[s._v("9")]),n("br"),n("span",{staticClass:"line-number"},[s._v("10")]),n("br"),n("span",{staticClass:"line-number"},[s._v("11")]),n("br"),n("span",{staticClass:"line-number"},[s._v("12")]),n("br"),n("span",{staticClass:"line-number"},[s._v("13")]),n("br"),n("span",{staticClass:"line-number"},[s._v("14")]),n("br")])]),n("p",[s._v("总结:\nstd::move() 实现原理:")]),s._v(" "),n("p",[s._v("利用引用折叠原理将右值经过 T&& 传递类型保持不变还是右值,而左值经过 T&& 变为普通的左值引用,以保证模板可以传递任意实参,且保持类型不变;\n然后通过 remove_refrence 移除引用,得到具体的类型 T;\n最后通过 static_cast<> 进行强制类型转换,返回 T&& 右值引用。")]),s._v(" "),n("h2",{attrs:{id:"什么是指针-指针的大小及用法"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#什么是指针-指针的大小及用法"}},[s._v("#")]),s._v(" 什么是指针?指针的大小及用法?")]),s._v(" "),n("p",[n("strong",[s._v("面试高频指数:★★☆☆☆")])]),s._v(" "),n("p",[n("strong",[s._v("指针:")]),s._v(" 指向另外一种类型的复合类型。")]),s._v(" "),n("p",[n("strong",[s._v("指针的大小:")]),s._v(" 在 64 位计算机中,指针占 8 个字节空间。")]),s._v(" "),n("div",{staticClass:"language-c++ line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v("#include\n\nusing namespace std;\n\nint main(){\n int *p = nullptr;\n cout << sizeof(p) << endl; // 8\n\n char *p1 = nullptr;\n cout << sizeof(p1) << endl; // 8\n return 0;\n}\n")])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br"),n("span",{staticClass:"line-number"},[s._v("8")]),n("br"),n("span",{staticClass:"line-number"},[s._v("9")]),n("br"),n("span",{staticClass:"line-number"},[s._v("10")]),n("br"),n("span",{staticClass:"line-number"},[s._v("11")]),n("br"),n("span",{staticClass:"line-number"},[s._v("12")]),n("br")])]),n("p",[n("strong",[s._v("指针的用法:")])]),s._v(" "),n("p",[s._v("指向普通对象的指针")]),s._v(" "),n("div",{staticClass:"language-c++ line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v("#include \n\nusing namespace std;\n\nclass A\n{\n};\n\nint main()\n{\n A *p = new A();\n return 0;\n}\n")])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br"),n("span",{staticClass:"line-number"},[s._v("8")]),n("br"),n("span",{staticClass:"line-number"},[s._v("9")]),n("br"),n("span",{staticClass:"line-number"},[s._v("10")]),n("br"),n("span",{staticClass:"line-number"},[s._v("11")]),n("br"),n("span",{staticClass:"line-number"},[s._v("12")]),n("br"),n("span",{staticClass:"line-number"},[s._v("13")]),n("br")])]),n("p",[s._v("指向常量对象的指针:常量指针")]),s._v(" "),n("div",{staticClass:"language-c++ line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v("#include \nusing namespace std;\n\nint main(void)\n{\n const int c_var = 10;\n const int * p = &c_var;\n cout << *p << endl;\n return 0;\n}\n")])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br"),n("span",{staticClass:"line-number"},[s._v("8")]),n("br"),n("span",{staticClass:"line-number"},[s._v("9")]),n("br"),n("span",{staticClass:"line-number"},[s._v("10")]),n("br")])]),n("p",[s._v("指向函数的指针:函数指针")]),s._v(" "),n("div",{staticClass:"language-c++ line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v("#include \nusing namespace std;\n\nint add(int a, int b){\n return a + b;\n}\n\nint main(void)\n{\n int (*fun_p)(int, int);\n fun_p = add;\n cout << fun_p(1, 6) << endl;\n return 0;\n}\n")])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br"),n("span",{staticClass:"line-number"},[s._v("8")]),n("br"),n("span",{staticClass:"line-number"},[s._v("9")]),n("br"),n("span",{staticClass:"line-number"},[s._v("10")]),n("br"),n("span",{staticClass:"line-number"},[s._v("11")]),n("br"),n("span",{staticClass:"line-number"},[s._v("12")]),n("br"),n("span",{staticClass:"line-number"},[s._v("13")]),n("br"),n("span",{staticClass:"line-number"},[s._v("14")]),n("br")])]),n("p",[s._v("指向对象成员的指针,包括指向对象成员函数的指针和指向对象成员变量的指针。\n特别注意:定义指向成员函数的指针时,要标明指针所属的类。")]),s._v(" "),n("div",{staticClass:"language-c++ line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v("#include \n\nusing namespace std;\n\nclass A\n{\npublic:\n int var1, var2;\n int add(){\n return var1 + var2;\n }\n};\n\nint main()\n{\n A ex;\n ex.var1 = 3;\n ex.var2 = 4;\n int *p = &ex.var1; // 指向对象成员变量的指针\n cout << *p << endl;\n\n int (A::*fun_p)();\n fun_p = A::add; // 指向对象成员函数的指针 fun_p\n cout << (ex.*fun_p)() << endl;\n return 0;\n}\n")])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br"),n("span",{staticClass:"line-number"},[s._v("8")]),n("br"),n("span",{staticClass:"line-number"},[s._v("9")]),n("br"),n("span",{staticClass:"line-number"},[s._v("10")]),n("br"),n("span",{staticClass:"line-number"},[s._v("11")]),n("br"),n("span",{staticClass:"line-number"},[s._v("12")]),n("br"),n("span",{staticClass:"line-number"},[s._v("13")]),n("br"),n("span",{staticClass:"line-number"},[s._v("14")]),n("br"),n("span",{staticClass:"line-number"},[s._v("15")]),n("br"),n("span",{staticClass:"line-number"},[s._v("16")]),n("br"),n("span",{staticClass:"line-number"},[s._v("17")]),n("br"),n("span",{staticClass:"line-number"},[s._v("18")]),n("br"),n("span",{staticClass:"line-number"},[s._v("19")]),n("br"),n("span",{staticClass:"line-number"},[s._v("20")]),n("br"),n("span",{staticClass:"line-number"},[s._v("21")]),n("br"),n("span",{staticClass:"line-number"},[s._v("22")]),n("br"),n("span",{staticClass:"line-number"},[s._v("23")]),n("br"),n("span",{staticClass:"line-number"},[s._v("24")]),n("br"),n("span",{staticClass:"line-number"},[s._v("25")]),n("br"),n("span",{staticClass:"line-number"},[s._v("26")]),n("br")])]),n("p",[s._v("this 指针:指向类的当前对象的指针常量。")]),s._v(" "),n("div",{staticClass:"language-c++ line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v('#include \n#include \nusing namespace std;\n\nclass A\n{\npublic:\n void set_name(string tmp)\n {\n this->name = tmp;\n }\n void set_age(int tmp)\n {\n this->age = age;\n }\n void set_sex(int tmp)\n {\n this->sex = tmp;\n }\n void show()\n {\n cout << "Name: " << this->name << endl;\n cout << "Age: " << this->age << endl;\n cout << "Sex: " << this->sex << endl;\n }\n\nprivate:\n string name;\n int age;\n int sex;\n};\n\nint main()\n{\n A *p = new A();\n p->set_name("Alice");\n p->set_age(16);\n p->set_sex(1);\n p->show();\n\n return 0;\n}\n')])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br"),n("span",{staticClass:"line-number"},[s._v("8")]),n("br"),n("span",{staticClass:"line-number"},[s._v("9")]),n("br"),n("span",{staticClass:"line-number"},[s._v("10")]),n("br"),n("span",{staticClass:"line-number"},[s._v("11")]),n("br"),n("span",{staticClass:"line-number"},[s._v("12")]),n("br"),n("span",{staticClass:"line-number"},[s._v("13")]),n("br"),n("span",{staticClass:"line-number"},[s._v("14")]),n("br"),n("span",{staticClass:"line-number"},[s._v("15")]),n("br"),n("span",{staticClass:"line-number"},[s._v("16")]),n("br"),n("span",{staticClass:"line-number"},[s._v("17")]),n("br"),n("span",{staticClass:"line-number"},[s._v("18")]),n("br"),n("span",{staticClass:"line-number"},[s._v("19")]),n("br"),n("span",{staticClass:"line-number"},[s._v("20")]),n("br"),n("span",{staticClass:"line-number"},[s._v("21")]),n("br"),n("span",{staticClass:"line-number"},[s._v("22")]),n("br"),n("span",{staticClass:"line-number"},[s._v("23")]),n("br"),n("span",{staticClass:"line-number"},[s._v("24")]),n("br"),n("span",{staticClass:"line-number"},[s._v("25")]),n("br"),n("span",{staticClass:"line-number"},[s._v("26")]),n("br"),n("span",{staticClass:"line-number"},[s._v("27")]),n("br"),n("span",{staticClass:"line-number"},[s._v("28")]),n("br"),n("span",{staticClass:"line-number"},[s._v("29")]),n("br"),n("span",{staticClass:"line-number"},[s._v("30")]),n("br"),n("span",{staticClass:"line-number"},[s._v("31")]),n("br"),n("span",{staticClass:"line-number"},[s._v("32")]),n("br"),n("span",{staticClass:"line-number"},[s._v("33")]),n("br"),n("span",{staticClass:"line-number"},[s._v("34")]),n("br"),n("span",{staticClass:"line-number"},[s._v("35")]),n("br"),n("span",{staticClass:"line-number"},[s._v("36")]),n("br"),n("span",{staticClass:"line-number"},[s._v("37")]),n("br"),n("span",{staticClass:"line-number"},[s._v("38")]),n("br"),n("span",{staticClass:"line-number"},[s._v("39")]),n("br"),n("span",{staticClass:"line-number"},[s._v("40")]),n("br"),n("span",{staticClass:"line-number"},[s._v("41")]),n("br"),n("span",{staticClass:"line-number"},[s._v("42")]),n("br")])]),n("h2",{attrs:{id:"什么是野指针和悬空指针"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#什么是野指针和悬空指针"}},[s._v("#")]),s._v(" 什么是野指针和悬空指针?")]),s._v(" "),n("p",[n("strong",[s._v("面试高频指数:★★★☆☆")])]),s._v(" "),n("p",[n("strong",[s._v("悬空指针:")])]),s._v(" "),n("p",[s._v("若指针指向一块内存空间,当这块内存空间被释放后,该指针依然指向这块内存空间,此时,称该指针为“悬空指针”。\n举例:")]),s._v(" "),n("div",{staticClass:"language-c++ line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v("void *p = malloc(size);\nfree(p);\n// 此时,p 指向的内存空间已释放, p 就是悬空指针。\n")])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br")])]),n("p",[n("strong",[s._v("野指针:")])]),s._v(" "),n("p",[s._v("“野指针”是指不确定其指向的指针,未初始化的指针为“野指针”。")]),s._v(" "),n("div",{staticClass:"language-c++ line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v("void *p;\n// 此时 p 是“野指针”。\n")])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br")])]),n("h2",{attrs:{id:"c-11-nullptr-比-null-优势"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#c-11-nullptr-比-null-优势"}},[s._v("#")]),s._v(" C++ 11 nullptr 比 NULL 优势")]),s._v(" "),n("p",[n("strong",[s._v("面试高频指数:★☆☆☆☆")])]),s._v(" "),n("ul",[n("li",[s._v("NULL:预处理变量,是一个宏,它的值是 0,定义在头文件 "),n("code",[s._v("")]),s._v(" 中,即 #define NULL 0。")]),s._v(" "),n("li",[s._v("nullptr:C++ 11 中的关键字,是一种特殊类型的字面值,可以被转换成任意其他类型。")])]),s._v(" "),n("p",[n("strong",[s._v("nullptr 的优势:")])]),s._v(" "),n("ol",[n("li",[s._v("有类型,类型是 typdef decltype(nullptr) nullptr_t;,使用 nullptr 提高代码的健壮性。")]),s._v(" "),n("li",[s._v("函数重载:因为 NULL 本质上是 0,在函数调用过程中,若出现函数重载并且传递的实参是 NULL,可能会出现,不知和哪一个函数匹配的情况;但是传递实参 nullptr 就不会出现这种情况。")])]),s._v(" "),n("div",{staticClass:"language-c++ line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v('#include \n#include \nusing namespace std;\n\nvoid fun(char const *p)\n{\n cout << "fun(char const *p)" << endl;\n}\n\nvoid fun(int tmp)\n{\n cout << "fun(int tmp)" << endl;\n}\n\nint main()\n{\n fun(nullptr); // fun(char const *p)\n /*\n fun(NULL); // error: call of overloaded \'fun(NULL)\' is ambiguous\n */\n return 0;\n}\n')])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br"),n("span",{staticClass:"line-number"},[s._v("8")]),n("br"),n("span",{staticClass:"line-number"},[s._v("9")]),n("br"),n("span",{staticClass:"line-number"},[s._v("10")]),n("br"),n("span",{staticClass:"line-number"},[s._v("11")]),n("br"),n("span",{staticClass:"line-number"},[s._v("12")]),n("br"),n("span",{staticClass:"line-number"},[s._v("13")]),n("br"),n("span",{staticClass:"line-number"},[s._v("14")]),n("br"),n("span",{staticClass:"line-number"},[s._v("15")]),n("br"),n("span",{staticClass:"line-number"},[s._v("16")]),n("br"),n("span",{staticClass:"line-number"},[s._v("17")]),n("br"),n("span",{staticClass:"line-number"},[s._v("18")]),n("br"),n("span",{staticClass:"line-number"},[s._v("19")]),n("br"),n("span",{staticClass:"line-number"},[s._v("20")]),n("br"),n("span",{staticClass:"line-number"},[s._v("21")]),n("br"),n("span",{staticClass:"line-number"},[s._v("22")]),n("br")])]),n("h2",{attrs:{id:"指针和引用的区别"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#指针和引用的区别"}},[s._v("#")]),s._v(" 指针和引用的区别?")]),s._v(" "),n("p",[n("strong",[s._v("面试高频指数:★★★★☆")])]),s._v(" "),n("ul",[n("li",[s._v("指针所指向的内存空间在程序运行过程中可以改变,而引用所绑定的对象一旦绑定就不能改变。(是否可变)")]),s._v(" "),n("li",[s._v("指针本身在内存中占有内存空间,引用相当于变量的别名,在内存中不占内存空间。(是否占内存)")]),s._v(" "),n("li",[s._v("指针可以为空,但是引用必须绑定对象。(是否可为空)")]),s._v(" "),n("li",[s._v("指针可以有多级,但是引用只能一级。(是否能为多级)")])]),s._v(" "),n("h2",{attrs:{id:"常量指针和指针常量的区别"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#常量指针和指针常量的区别"}},[s._v("#")]),s._v(" 常量指针和指针常量的区别")]),s._v(" "),n("p",[n("strong",[s._v("面试高频指数:★★★★☆")]),s._v(" "),n("strong",[s._v("常量指针:")]),s._v("\n常量指针本质上是个指针,只不过这个指针指向的对象是常量。\n特点:const 的位置在指针声明运算符 "),n("em",[s._v("的左侧。只要 const 位于")]),s._v(" 的左侧,无论它在类型名的左边或右边,都表示指向常量的指针。(可以这样理解,* 左侧表示指针指向的对象,该对象为常量,那么该指针为常量指针。)")]),s._v(" "),n("div",{staticClass:"language-c++ line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v("const int * p;\nint const * p;\n")])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br")])]),n("p",[s._v("注意 1:指针指向的对象不能通过这个指针来修改,也就是说常量指针可以被赋值为变量的地址,之所以叫做常量指针,是限制了通过这个指针修改变量的值。\n例如:")]),s._v(" "),n("div",{staticClass:"language-c++ line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v("#include \nusing namespace std;\n\nint main()\n{\n const int c_var = 8;\n const int *p = &c_var;\n *p = 6; // error: assignment of read-only location '* p'\n return 0;\n}\n")])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br"),n("span",{staticClass:"line-number"},[s._v("8")]),n("br"),n("span",{staticClass:"line-number"},[s._v("9")]),n("br"),n("span",{staticClass:"line-number"},[s._v("10")]),n("br")])]),n("p",[s._v("注意 2:虽然常量指针指向的对象不能变化,可是因为常量指针本身是一个变量,因此,可以被重新赋值。\n例如:")]),s._v(" "),n("div",{staticClass:"language-c++ line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v("#include \nusing namespace std;\n\nint main()\n{\n const int c_var1 = 8;\n const int c_var2 = 8;\n const int *p = &c_var1;\n p = &c_var2;\n return 0;\n}\n")])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br"),n("span",{staticClass:"line-number"},[s._v("8")]),n("br"),n("span",{staticClass:"line-number"},[s._v("9")]),n("br"),n("span",{staticClass:"line-number"},[s._v("10")]),n("br"),n("span",{staticClass:"line-number"},[s._v("11")]),n("br")])]),n("h2",{attrs:{id:"指针常量"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#指针常量"}},[s._v("#")]),s._v(" 指针常量")]),s._v(" "),n("p",[s._v("指针常量的本质上是个常量,只不过这个常量的值是一个指针。\n特点:const 位于指针声明操作符右侧,表明该对象本身是一个常量,"),n("em",[s._v("左侧表示该指针指向的类型,即以")]),s._v(" 为分界线,其左侧表示指针指向的类型,右侧表示指针本身的性质。")]),s._v(" "),n("div",{staticClass:"language-c++ line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v("const int var;\nint * const c_p = &var;\n")])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br")])]),n("p",[s._v("注意 1:指针常量的值是指针,这个值因为是常量,所以指针本身不能改变。")]),s._v(" "),n("div",{staticClass:"language-c++ line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v("#include \nusing namespace std;\n\nint main()\n{\n int var, var1;\n int * const c_p = &var;\n c_p = &var1; // error: assignment of read-only variable 'c_p'\n return 0;\n}\n")])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br"),n("span",{staticClass:"line-number"},[s._v("8")]),n("br"),n("span",{staticClass:"line-number"},[s._v("9")]),n("br"),n("span",{staticClass:"line-number"},[s._v("10")]),n("br")])]),n("p",[s._v("注意 2:指针的内容可以改变。")]),s._v(" "),n("div",{staticClass:"language-c++ line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v("#include \nusing namespace std;\n\nint main()\n{\n int var = 3;\n int * const c_p = &var;\n *c_p = 12;\n return 0;\n}\n")])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br"),n("span",{staticClass:"line-number"},[s._v("8")]),n("br"),n("span",{staticClass:"line-number"},[s._v("9")]),n("br"),n("span",{staticClass:"line-number"},[s._v("10")]),n("br")])]),n("h2",{attrs:{id:"函数指针和指针函数的区别"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#函数指针和指针函数的区别"}},[s._v("#")]),s._v(" 函数指针和指针函数的区别")]),s._v(" "),n("p",[n("strong",[s._v("面试高频指数:★★★★☆")]),s._v(" "),n("strong",[s._v("指针函数:")]),s._v("\n指针函数本质是一个函数,只不过该函数的返回值是一个指针。相对于普通函数而言,只是返回值是指针。")]),s._v(" "),n("div",{staticClass:"language-c++ line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v("#include \nusing namespace std;\n\nstruct Type\n{\n int var1;\n int var2;\n};\n\nType * fun(int tmp1, int tmp2){\n Type * t = new Type();\n t->var1 = tmp1;\n t->var2 = tmp2;\n return t;\n}\n\nint main()\n{\n Type *p = fun(5, 6);\n return 0;\n}\n")])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br"),n("span",{staticClass:"line-number"},[s._v("8")]),n("br"),n("span",{staticClass:"line-number"},[s._v("9")]),n("br"),n("span",{staticClass:"line-number"},[s._v("10")]),n("br"),n("span",{staticClass:"line-number"},[s._v("11")]),n("br"),n("span",{staticClass:"line-number"},[s._v("12")]),n("br"),n("span",{staticClass:"line-number"},[s._v("13")]),n("br"),n("span",{staticClass:"line-number"},[s._v("14")]),n("br"),n("span",{staticClass:"line-number"},[s._v("15")]),n("br"),n("span",{staticClass:"line-number"},[s._v("16")]),n("br"),n("span",{staticClass:"line-number"},[s._v("17")]),n("br"),n("span",{staticClass:"line-number"},[s._v("18")]),n("br"),n("span",{staticClass:"line-number"},[s._v("19")]),n("br"),n("span",{staticClass:"line-number"},[s._v("20")]),n("br"),n("span",{staticClass:"line-number"},[s._v("21")]),n("br")])]),n("p",[n("strong",[s._v("函数指针:")]),s._v("\n函数指针本质是一个指针变量,只不过这个指针指向一个函数。函数指针即指向函数的指针。")]),s._v(" "),n("p",[s._v("举例:")]),s._v(" "),n("div",{staticClass:"language-c++ line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v("#include \nusing namespace std;\nint fun1(int tmp1, int tmp2)\n{\n return tmp1 * tmp2;\n}\nint fun2(int tmp1, int tmp2)\n{\n return tmp1 / tmp2;\n}\n\nint main()\n{\n int (*fun)(int x, int y);\n fun = fun1;\n cout << fun(15, 5) << endl;\n fun = fun2;\n cout << fun(15, 5) << endl;\n return 0;\n}\n/*\n运行结果:\n75\n3\n*/\n")])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br"),n("span",{staticClass:"line-number"},[s._v("8")]),n("br"),n("span",{staticClass:"line-number"},[s._v("9")]),n("br"),n("span",{staticClass:"line-number"},[s._v("10")]),n("br"),n("span",{staticClass:"line-number"},[s._v("11")]),n("br"),n("span",{staticClass:"line-number"},[s._v("12")]),n("br"),n("span",{staticClass:"line-number"},[s._v("13")]),n("br"),n("span",{staticClass:"line-number"},[s._v("14")]),n("br"),n("span",{staticClass:"line-number"},[s._v("15")]),n("br"),n("span",{staticClass:"line-number"},[s._v("16")]),n("br"),n("span",{staticClass:"line-number"},[s._v("17")]),n("br"),n("span",{staticClass:"line-number"},[s._v("18")]),n("br"),n("span",{staticClass:"line-number"},[s._v("19")]),n("br"),n("span",{staticClass:"line-number"},[s._v("20")]),n("br"),n("span",{staticClass:"line-number"},[s._v("21")]),n("br"),n("span",{staticClass:"line-number"},[s._v("22")]),n("br"),n("span",{staticClass:"line-number"},[s._v("23")]),n("br"),n("span",{staticClass:"line-number"},[s._v("24")]),n("br"),n("span",{staticClass:"line-number"},[s._v("25")]),n("br")])]),n("p",[s._v("函数指针和指针函数的区别:")]),s._v(" "),n("ol",[n("li",[n("p",[s._v("本质不同")]),s._v(" "),n("p",[s._v("指针函数本质是一个函数,其返回值为指针。")]),s._v(" "),n("p",[s._v("函数指针本质是一个指针变量,其指向一个函数。")])]),s._v(" "),n("li",[n("p",[s._v("定义形式不同")]),s._v(" "),n("p",[s._v("指针函数:int"),n("em",[s._v("fun(int tmp1, int tmp2); ,这里")]),s._v(" 表示函数的返回值类型是指针类型。")]),s._v(" "),n("p",[s._v("函数指针:int ("),n("em",[s._v("fun)(int tmp1, int tmp2);,这里")]),s._v(" 表示变量本身是指针类型。")])]),s._v(" "),n("li",[n("p",[s._v("用法不同")])])]),s._v(" "),n("h2",{attrs:{id:"强制类型转换有哪几种"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#强制类型转换有哪几种"}},[s._v("#")]),s._v(" 强制类型转换有哪几种?")]),s._v(" "),n("p",[n("strong",[s._v("面试高频指数:★★★★☆")])]),s._v(" "),n("ul",[n("li",[n("p",[s._v("static_cast:用于数据的强制类型转换,强制将一种数据类型转换为另一种数据类型。")]),s._v(" "),n("ol",[n("li",[s._v("用于基本数据类型的转换。")]),s._v(" "),n("li",[s._v("用于类层次之间的基类和派生类之间 指针或者引用 的转换(不要求必须包含虚函数,但必须是有相互联系的")]),s._v(" "),n("li",[s._v("用于类层次之间的基类和派生类之间 指针或者引用 的转换(不要求必须包含虚函数,但必须是有相互联系的类),进行上行转换(派生类的指针或引用转换成基类表示)是安全的;进行下行转换(基类的指针或引用转换成派生类表示)由于没有动态类型检查,所以是不安全的,最好用 dynamic_cast 进行下行转换。")]),s._v(" "),n("li",[s._v("可以将空指针转化成目标类型的空指针。")]),s._v(" "),n("li",[s._v("可以将任何类型的表达式转化成 void 类型。")])])]),s._v(" "),n("li",[n("p",[s._v("const_cast:强制去掉常量属性,不能用于去掉变量的常量性,只能用于去除指针或引用的常量性,将常量指针转化为非常量指针或者将常量引用转化为非常量引用(注意:表达式的类型和要转化的类型是相同的)。")])]),s._v(" "),n("li",[n("p",[s._v("reinterpret_cast:改变指针或引用的类型、将指针或引用转换为一个足够长度的整型、将整型转化为指针或引用类型。")])]),s._v(" "),n("li",[n("p",[s._v("dynamic_cast:")]),s._v(" "),n("ol",[n("li",[n("p",[s._v("其他三种都是编译时完成的,动态类型转换是在程序运行时处理的,运行时会进行类型检查。")])]),s._v(" "),n("li",[n("p",[s._v("只能用于带有虚函数的基类或派生类的指针或者引用对象的转换,转换成功返回指向类型的指针或引用,转换失败返回 NULL;不能用于基本数据类型的转换。")])]),s._v(" "),n("li",[n("p",[s._v("在向上进行转换时,即派生类类的指针转换成基类类的指针和 static_cast 效果是一样的,(注意:这里只是改变了指针的类型,指针指向的对象的类型并未发生改变)。")]),s._v(" "),n("div",{staticClass:"language-c++ line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v('#include \n#include \n\nusing namespace std;\n\nclass Base\n{\n};\n\nclass Derive : public Base\n{\n};\n\nint main()\n{\n Base *p1 = new Derive();\n Derive *p2 = new Derive();\n\n //向上类型转换\n p1 = dynamic_cast(p2);\n if (p1 == NULL)\n {\n cout << "NULL" << endl;\n }\n else\n {\n cout << "NOT NULL" << endl; //输出\n }\n\n return 0;\n}\n')])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br"),n("span",{staticClass:"line-number"},[s._v("8")]),n("br"),n("span",{staticClass:"line-number"},[s._v("9")]),n("br"),n("span",{staticClass:"line-number"},[s._v("10")]),n("br"),n("span",{staticClass:"line-number"},[s._v("11")]),n("br"),n("span",{staticClass:"line-number"},[s._v("12")]),n("br"),n("span",{staticClass:"line-number"},[s._v("13")]),n("br"),n("span",{staticClass:"line-number"},[s._v("14")]),n("br"),n("span",{staticClass:"line-number"},[s._v("15")]),n("br"),n("span",{staticClass:"line-number"},[s._v("16")]),n("br"),n("span",{staticClass:"line-number"},[s._v("17")]),n("br"),n("span",{staticClass:"line-number"},[s._v("18")]),n("br"),n("span",{staticClass:"line-number"},[s._v("19")]),n("br"),n("span",{staticClass:"line-number"},[s._v("20")]),n("br"),n("span",{staticClass:"line-number"},[s._v("21")]),n("br"),n("span",{staticClass:"line-number"},[s._v("22")]),n("br"),n("span",{staticClass:"line-number"},[s._v("23")]),n("br"),n("span",{staticClass:"line-number"},[s._v("24")]),n("br"),n("span",{staticClass:"line-number"},[s._v("25")]),n("br"),n("span",{staticClass:"line-number"},[s._v("26")]),n("br"),n("span",{staticClass:"line-number"},[s._v("27")]),n("br"),n("span",{staticClass:"line-number"},[s._v("28")]),n("br"),n("span",{staticClass:"line-number"},[s._v("29")]),n("br"),n("span",{staticClass:"line-number"},[s._v("30")]),n("br"),n("span",{staticClass:"line-number"},[s._v("31")]),n("br")])])]),s._v(" "),n("li",[n("p",[s._v("在下行转换时,基类的指针类型转化为派生类类的指针类型,只有当要转换的指针指向的对象类型和转化以后的对象类型相同时,才会转化成功。")]),s._v(" "),n("div",{staticClass:"language-c++ line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v('#include \n#include \n\nusing namespace std;\n\nclass Base\n{\npublic:\n virtual void fun()\n {\n cout << "Base::fun()" << endl;\n }\n};\n\nclass Derive : public Base\n{\npublic:\n virtual void fun()\n {\n cout << "Derive::fun()" << endl;\n }\n};\n\nint main()\n{\n Base *p1 = new Derive();\n Base *p2 = new Base();\n Derive *p3 = new Derive();\n\n //转换成功\n p3 = dynamic_cast(p1);\n if (p3 == NULL)\n {\n cout << "NULL" << endl;\n }\n else\n {\n cout << "NOT NULL" << endl; // 输出\n }\n\n //转换失败\n p3 = dynamic_cast(p2);\n if (p3 == NULL)\n {\n cout << "NULL" << endl; // 输出\n }\n else\n {\n cout << "NOT NULL" << endl;\n }\n\n return 0;\n}\n')])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br"),n("span",{staticClass:"line-number"},[s._v("8")]),n("br"),n("span",{staticClass:"line-number"},[s._v("9")]),n("br"),n("span",{staticClass:"line-number"},[s._v("10")]),n("br"),n("span",{staticClass:"line-number"},[s._v("11")]),n("br"),n("span",{staticClass:"line-number"},[s._v("12")]),n("br"),n("span",{staticClass:"line-number"},[s._v("13")]),n("br"),n("span",{staticClass:"line-number"},[s._v("14")]),n("br"),n("span",{staticClass:"line-number"},[s._v("15")]),n("br"),n("span",{staticClass:"line-number"},[s._v("16")]),n("br"),n("span",{staticClass:"line-number"},[s._v("17")]),n("br"),n("span",{staticClass:"line-number"},[s._v("18")]),n("br"),n("span",{staticClass:"line-number"},[s._v("19")]),n("br"),n("span",{staticClass:"line-number"},[s._v("20")]),n("br"),n("span",{staticClass:"line-number"},[s._v("21")]),n("br"),n("span",{staticClass:"line-number"},[s._v("22")]),n("br"),n("span",{staticClass:"line-number"},[s._v("23")]),n("br"),n("span",{staticClass:"line-number"},[s._v("24")]),n("br"),n("span",{staticClass:"line-number"},[s._v("25")]),n("br"),n("span",{staticClass:"line-number"},[s._v("26")]),n("br"),n("span",{staticClass:"line-number"},[s._v("27")]),n("br"),n("span",{staticClass:"line-number"},[s._v("28")]),n("br"),n("span",{staticClass:"line-number"},[s._v("29")]),n("br"),n("span",{staticClass:"line-number"},[s._v("30")]),n("br"),n("span",{staticClass:"line-number"},[s._v("31")]),n("br"),n("span",{staticClass:"line-number"},[s._v("32")]),n("br"),n("span",{staticClass:"line-number"},[s._v("33")]),n("br"),n("span",{staticClass:"line-number"},[s._v("34")]),n("br"),n("span",{staticClass:"line-number"},[s._v("35")]),n("br"),n("span",{staticClass:"line-number"},[s._v("36")]),n("br"),n("span",{staticClass:"line-number"},[s._v("37")]),n("br"),n("span",{staticClass:"line-number"},[s._v("38")]),n("br"),n("span",{staticClass:"line-number"},[s._v("39")]),n("br"),n("span",{staticClass:"line-number"},[s._v("40")]),n("br"),n("span",{staticClass:"line-number"},[s._v("41")]),n("br"),n("span",{staticClass:"line-number"},[s._v("42")]),n("br"),n("span",{staticClass:"line-number"},[s._v("43")]),n("br"),n("span",{staticClass:"line-number"},[s._v("44")]),n("br"),n("span",{staticClass:"line-number"},[s._v("45")]),n("br"),n("span",{staticClass:"line-number"},[s._v("46")]),n("br"),n("span",{staticClass:"line-number"},[s._v("47")]),n("br"),n("span",{staticClass:"line-number"},[s._v("48")]),n("br"),n("span",{staticClass:"line-number"},[s._v("49")]),n("br"),n("span",{staticClass:"line-number"},[s._v("50")]),n("br"),n("span",{staticClass:"line-number"},[s._v("51")]),n("br"),n("span",{staticClass:"line-number"},[s._v("52")]),n("br"),n("span",{staticClass:"line-number"},[s._v("53")]),n("br")])])])])])]),s._v(" "),n("h2",{attrs:{id:"如何判断结构体是否相等-能否用-memcmp-函数判断结构体相等"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#如何判断结构体是否相等-能否用-memcmp-函数判断结构体相等"}},[s._v("#")]),s._v(" 如何判断结构体是否相等?能否用 memcmp 函数判断结构体相等?")]),s._v(" "),n("p",[n("strong",[s._v("面试高频指数:★★☆☆☆")])]),s._v(" "),n("p",[s._v("需要重载操作符 == 判断两个结构体是否相等,不能用函数 memcmp 来判断两个结构体是否相等,因为 memcmp 函数是逐个字节进行比较的,而结构体存在内存空间中保存时存在字节对齐,字节对齐时补的字节内容是随机的,会产生垃圾值,所以无法比较。")]),s._v(" "),n("p",[s._v("利用运算符重载来实现结构体对象的比较:")]),s._v(" "),n("div",{staticClass:"language-c++ line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v("#include \n\nusing namespace std;\n\nstruct A\n{\n char c;\n int val;\n A(char c_tmp, int tmp) : c(c_tmp), val(tmp) {}\n\n friend bool operator==(const A &tmp1, const A &tmp2); // 友元运算符重载函数\n};\n\nbool operator==(const A &tmp1, const A &tmp2)\n{\n return (tmp1.c == tmp2.c && tmp1.val == tmp2.val);\n}\n\nint main()\n{\n A ex1('a', 90), ex2('b', 80);\n if (ex1 == ex2)\n cout << \"ex1 == ex2\" << endl;\n else\n cout << \"ex1 != ex2\" << endl; // 输出\n return 0;\n}\n")])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br"),n("span",{staticClass:"line-number"},[s._v("8")]),n("br"),n("span",{staticClass:"line-number"},[s._v("9")]),n("br"),n("span",{staticClass:"line-number"},[s._v("10")]),n("br"),n("span",{staticClass:"line-number"},[s._v("11")]),n("br"),n("span",{staticClass:"line-number"},[s._v("12")]),n("br"),n("span",{staticClass:"line-number"},[s._v("13")]),n("br"),n("span",{staticClass:"line-number"},[s._v("14")]),n("br"),n("span",{staticClass:"line-number"},[s._v("15")]),n("br"),n("span",{staticClass:"line-number"},[s._v("16")]),n("br"),n("span",{staticClass:"line-number"},[s._v("17")]),n("br"),n("span",{staticClass:"line-number"},[s._v("18")]),n("br"),n("span",{staticClass:"line-number"},[s._v("19")]),n("br"),n("span",{staticClass:"line-number"},[s._v("20")]),n("br"),n("span",{staticClass:"line-number"},[s._v("21")]),n("br"),n("span",{staticClass:"line-number"},[s._v("22")]),n("br"),n("span",{staticClass:"line-number"},[s._v("23")]),n("br"),n("span",{staticClass:"line-number"},[s._v("24")]),n("br"),n("span",{staticClass:"line-number"},[s._v("25")]),n("br"),n("span",{staticClass:"line-number"},[s._v("26")]),n("br"),n("span",{staticClass:"line-number"},[s._v("27")]),n("br")])]),n("h2",{attrs:{id:"参数传递时-值传递、引用传递、指针传递的区别"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#参数传递时-值传递、引用传递、指针传递的区别"}},[s._v("#")]),s._v(" 参数传递时,值传递、引用传递、指针传递的区别?")]),s._v(" "),n("p",[n("strong",[s._v("面试高频指数:★★☆☆☆")])]),s._v(" "),n("p",[n("strong",[s._v("参数传递的三种方式:")])]),s._v(" "),n("ul",[n("li",[s._v("值传递:形参是实参的拷贝,函数对形参的所有操作不会影响实参。")]),s._v(" "),n("li",[s._v("指针传递:本质上是值传递,只不过拷贝的是指针的值,拷贝之后,实参和形参是不同的指针,通过指针可以间接的访问指针所指向的对象,从而可以修改它所指对象的值。")]),s._v(" "),n("li",[s._v("引用传递:当形参是引用类型时,我们说它对应的实参被引用传递。")])]),s._v(" "),n("div",{staticClass:"language-c++ line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v('#include \nusing namespace std;\n\nvoid fun1(int tmp){ // 值传递\n cout << &tmp << endl;\n}\n\nvoid fun2(int * tmp){ // 指针传递\n cout << tmp << endl;\n}\n\nvoid fun3(int &tmp){ // 引用传递\n cout << &tmp << endl;\n}\n\nint main()\n{\n int var = 5;\n cout << "var 在主函数中的地址:" << &var << endl;\n\n cout << "var 值传递时的地址:";\n fun1(var);\n\n cout << "var 指针传递时的地址:";\n fun2(&var);\n\n cout << "var 引用传递时的地址:";\n fun3(var);\n return 0;\n}\n\n/*\n运行结果:\nvar 在主函数中的地址:0x23fe4c\nvar 值传递时的地址:0x23fe20\nvar 指针传递时的地址:0x23fe4c\nvar 引用传递时的地址:0x23fe4c\n*/\n')])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br"),n("span",{staticClass:"line-number"},[s._v("8")]),n("br"),n("span",{staticClass:"line-number"},[s._v("9")]),n("br"),n("span",{staticClass:"line-number"},[s._v("10")]),n("br"),n("span",{staticClass:"line-number"},[s._v("11")]),n("br"),n("span",{staticClass:"line-number"},[s._v("12")]),n("br"),n("span",{staticClass:"line-number"},[s._v("13")]),n("br"),n("span",{staticClass:"line-number"},[s._v("14")]),n("br"),n("span",{staticClass:"line-number"},[s._v("15")]),n("br"),n("span",{staticClass:"line-number"},[s._v("16")]),n("br"),n("span",{staticClass:"line-number"},[s._v("17")]),n("br"),n("span",{staticClass:"line-number"},[s._v("18")]),n("br"),n("span",{staticClass:"line-number"},[s._v("19")]),n("br"),n("span",{staticClass:"line-number"},[s._v("20")]),n("br"),n("span",{staticClass:"line-number"},[s._v("21")]),n("br"),n("span",{staticClass:"line-number"},[s._v("22")]),n("br"),n("span",{staticClass:"line-number"},[s._v("23")]),n("br"),n("span",{staticClass:"line-number"},[s._v("24")]),n("br"),n("span",{staticClass:"line-number"},[s._v("25")]),n("br"),n("span",{staticClass:"line-number"},[s._v("26")]),n("br"),n("span",{staticClass:"line-number"},[s._v("27")]),n("br"),n("span",{staticClass:"line-number"},[s._v("28")]),n("br"),n("span",{staticClass:"line-number"},[s._v("29")]),n("br"),n("span",{staticClass:"line-number"},[s._v("30")]),n("br"),n("span",{staticClass:"line-number"},[s._v("31")]),n("br"),n("span",{staticClass:"line-number"},[s._v("32")]),n("br"),n("span",{staticClass:"line-number"},[s._v("33")]),n("br"),n("span",{staticClass:"line-number"},[s._v("34")]),n("br"),n("span",{staticClass:"line-number"},[s._v("35")]),n("br"),n("span",{staticClass:"line-number"},[s._v("36")]),n("br"),n("span",{staticClass:"line-number"},[s._v("37")]),n("br"),n("span",{staticClass:"line-number"},[s._v("38")]),n("br")])]),n("p",[s._v("说明:从上述代码的运行结果可以看出,只有在值传递时,形参和实参的地址不一样,在函数体内操作的不是变量本身。引用传递和指针传递,在函数体内操作的是变量本身。")]),s._v(" "),n("h2",{attrs:{id:"什么是模板-如何实现"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#什么是模板-如何实现"}},[s._v("#")]),s._v(" 什么是模板?如何实现?")]),s._v(" "),n("p",[n("strong",[s._v("面试高频指数:★★★☆☆")])]),s._v(" "),n("p",[s._v("模板:创建类或者函数的蓝图或者公式,分为函数模板和类模板。\n实现方式:模板定义以关键字 template 开始,后跟一个模板参数列表。")]),s._v(" "),n("ul",[n("li",[s._v("模板参数列表不能为空;")]),s._v(" "),n("li",[s._v("模板类型参数前必须使用关键字 class 或者 typename,在模板参数列表中这两个关键字含义相同,可互换使用。")])]),s._v(" "),n("div",{staticClass:"language-c++ line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v("template \n")])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br")])]),n("p",[s._v("函数模板:通过定义一个函数模板,可以避免为每一种类型定义一个新函数。")]),s._v(" "),n("ul",[n("li",[n("p",[s._v("对于函数模板而言,模板类型参数可以用来指定返回类型或函数的参数类型,以及在函数体内用于变量声明或类型转换。")])]),s._v(" "),n("li",[n("p",[s._v("函数模板实例化:当调用一个模板时,编译器用函数实参来推断模板实参,从而使用实参的类型来确定绑定到模板参数的类型。")])])]),s._v(" "),n("div",{staticClass:"language-c++ line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v("#include\n\nusing namespace std;\n\ntemplate \nT add_fun(const T & tmp1, const T & tmp2){\n return tmp1 + tmp2;\n}\n\nint main(){\n int var1, var2;\n cin >> var1 >> var2;\n cout << add_fun(var1, var2);\n\n double var3, var4;\n cin >> var3 >> var4;\n cout << add_fun(var3, var4);\n return 0;\n}\n")])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br"),n("span",{staticClass:"line-number"},[s._v("8")]),n("br"),n("span",{staticClass:"line-number"},[s._v("9")]),n("br"),n("span",{staticClass:"line-number"},[s._v("10")]),n("br"),n("span",{staticClass:"line-number"},[s._v("11")]),n("br"),n("span",{staticClass:"line-number"},[s._v("12")]),n("br"),n("span",{staticClass:"line-number"},[s._v("13")]),n("br"),n("span",{staticClass:"line-number"},[s._v("14")]),n("br"),n("span",{staticClass:"line-number"},[s._v("15")]),n("br"),n("span",{staticClass:"line-number"},[s._v("16")]),n("br"),n("span",{staticClass:"line-number"},[s._v("17")]),n("br"),n("span",{staticClass:"line-number"},[s._v("18")]),n("br"),n("span",{staticClass:"line-number"},[s._v("19")]),n("br")])]),n("p",[s._v("类模板:类似函数模板,类模板以关键字 template 开始,后跟模板参数列表。但是,编译器不能为类模板推断模板参数类型,需要在使用该类模板时,在模板名后面的尖括号中指明类型。")]),s._v(" "),n("div",{staticClass:"language-c++ line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v('#include \n\nusing namespace std;\n\ntemplate \nclass Complex\n{\npublic:\n //构造函数\n Complex(T a, T b)\n {\n this->a = a;\n this->b = b;\n }\n\n //运算符重载\n Complex operator+(Complex &c)\n {\n Complex tmp(this->a + c.a, this->b + c.b);\n cout << tmp.a << " " << tmp.b << endl;\n return tmp;\n }\n\nprivate:\n T a;\n T b;\n};\n\nint main()\n{\n Complex a(10, 20);\n Complex b(20, 30);\n Complex c = a + b;\n\n return 0;\n}\n')])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br"),n("span",{staticClass:"line-number"},[s._v("8")]),n("br"),n("span",{staticClass:"line-number"},[s._v("9")]),n("br"),n("span",{staticClass:"line-number"},[s._v("10")]),n("br"),n("span",{staticClass:"line-number"},[s._v("11")]),n("br"),n("span",{staticClass:"line-number"},[s._v("12")]),n("br"),n("span",{staticClass:"line-number"},[s._v("13")]),n("br"),n("span",{staticClass:"line-number"},[s._v("14")]),n("br"),n("span",{staticClass:"line-number"},[s._v("15")]),n("br"),n("span",{staticClass:"line-number"},[s._v("16")]),n("br"),n("span",{staticClass:"line-number"},[s._v("17")]),n("br"),n("span",{staticClass:"line-number"},[s._v("18")]),n("br"),n("span",{staticClass:"line-number"},[s._v("19")]),n("br"),n("span",{staticClass:"line-number"},[s._v("20")]),n("br"),n("span",{staticClass:"line-number"},[s._v("21")]),n("br"),n("span",{staticClass:"line-number"},[s._v("22")]),n("br"),n("span",{staticClass:"line-number"},[s._v("23")]),n("br"),n("span",{staticClass:"line-number"},[s._v("24")]),n("br"),n("span",{staticClass:"line-number"},[s._v("25")]),n("br"),n("span",{staticClass:"line-number"},[s._v("26")]),n("br"),n("span",{staticClass:"line-number"},[s._v("27")]),n("br"),n("span",{staticClass:"line-number"},[s._v("28")]),n("br"),n("span",{staticClass:"line-number"},[s._v("29")]),n("br"),n("span",{staticClass:"line-number"},[s._v("30")]),n("br"),n("span",{staticClass:"line-number"},[s._v("31")]),n("br"),n("span",{staticClass:"line-number"},[s._v("32")]),n("br"),n("span",{staticClass:"line-number"},[s._v("33")]),n("br"),n("span",{staticClass:"line-number"},[s._v("34")]),n("br"),n("span",{staticClass:"line-number"},[s._v("35")]),n("br"),n("span",{staticClass:"line-number"},[s._v("36")]),n("br")])]),n("h2",{attrs:{id:"函数模板和类模板的区别"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#函数模板和类模板的区别"}},[s._v("#")]),s._v(" 函数模板和类模板的区别?")]),s._v(" "),n("p",[n("strong",[s._v("面试高频指数:★★☆☆☆")])]),s._v(" "),n("ul",[n("li",[s._v("实例化方式不同:函数模板实例化由编译程序在处理函数调用时自动完成,类模板实例化需要在程序中显式指定。")]),s._v(" "),n("li",[s._v("实例化的结果不同:函数模板实例化后是一个函数,类模板实例化后是一个类。")]),s._v(" "),n("li",[s._v("默认参数:类模板在模板参数列表中可以有默认参数。")]),s._v(" "),n("li",[s._v("特化:函数模板只能全特化;而类模板可以全特化,也可以偏特化。")]),s._v(" "),n("li",[s._v("调用方式不同:函数模板可以隐式调用,也可以显式调用;类模板只能显式调用。")])]),s._v(" "),n("p",[s._v("函数模板调用方式举例:")]),s._v(" "),n("div",{staticClass:"language-c++ line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v("#include\n\nusing namespace std;\n\ntemplate \nT add_fun(const T & tmp1, const T & tmp2){\n return tmp1 + tmp2;\n}\n\nint main(){\n int var1, var2;\n cin >> var1 >> var2;\n cout << add_fun(var1, var2); // 显式调用\n\n double var3, var4;\n cin >> var3 >> var4;\n cout << add_fun(var3, var4); // 隐式调用\n return 0;\n}\n")])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br"),n("span",{staticClass:"line-number"},[s._v("8")]),n("br"),n("span",{staticClass:"line-number"},[s._v("9")]),n("br"),n("span",{staticClass:"line-number"},[s._v("10")]),n("br"),n("span",{staticClass:"line-number"},[s._v("11")]),n("br"),n("span",{staticClass:"line-number"},[s._v("12")]),n("br"),n("span",{staticClass:"line-number"},[s._v("13")]),n("br"),n("span",{staticClass:"line-number"},[s._v("14")]),n("br"),n("span",{staticClass:"line-number"},[s._v("15")]),n("br"),n("span",{staticClass:"line-number"},[s._v("16")]),n("br"),n("span",{staticClass:"line-number"},[s._v("17")]),n("br"),n("span",{staticClass:"line-number"},[s._v("18")]),n("br"),n("span",{staticClass:"line-number"},[s._v("19")]),n("br")])]),n("h2",{attrs:{id:"什么是可变参数模板"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#什么是可变参数模板"}},[s._v("#")]),s._v(" 什么是可变参数模板?")]),s._v(" "),n("p",[n("strong",[s._v("面试高频指数:★☆☆☆☆")])]),s._v(" "),n("p",[s._v("可变参数模板:接受可变数目参数的模板函数或模板类。将可变数目的参数被称为参数包,包括模板参数包和函数参数包。")]),s._v(" "),n("ul",[n("li",[s._v("模板参数包:表示零个或多个模板参数;")]),s._v(" "),n("li",[s._v("函数参数包:表示零个或多个函数参数。")])]),s._v(" "),n("p",[s._v("用省略号来指出一个模板参数或函数参数表示一个包,在模板参数列表中,class... 或 typename... 指出接下来的参数表示零个或多个类型的列表;一个类型名后面跟一个省略号表示零个或多个给定类型的非类型参数的列表。当需要知道包中有多少元素时,可以使用 sizeof... 运算符。")]),s._v(" "),n("div",{staticClass:"language-c++ line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v("template // Args 是模板参数包\nvoid foo(const T &t, const Args&... rest); // 可变参数模板,rest 是函数参数包\n")])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br")])]),n("p",[s._v("实例:")]),s._v(" "),n("div",{staticClass:"language-c++ line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v('#include \n\nusing namespace std;\n\ntemplate \nvoid print_fun(const T &t)\n{\n cout << t << endl; // 最后一个元素\n}\n\ntemplate \nvoid print_fun(const T &t, const Args &...args)\n{\n cout << t << " ";\n print_fun(args...);\n}\n\nint main()\n{\n print_fun("Hello", "wolrd", "!");\n return 0;\n}\n/*运行结果:\nHello wolrd !\n\n*/\n')])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br"),n("span",{staticClass:"line-number"},[s._v("8")]),n("br"),n("span",{staticClass:"line-number"},[s._v("9")]),n("br"),n("span",{staticClass:"line-number"},[s._v("10")]),n("br"),n("span",{staticClass:"line-number"},[s._v("11")]),n("br"),n("span",{staticClass:"line-number"},[s._v("12")]),n("br"),n("span",{staticClass:"line-number"},[s._v("13")]),n("br"),n("span",{staticClass:"line-number"},[s._v("14")]),n("br"),n("span",{staticClass:"line-number"},[s._v("15")]),n("br"),n("span",{staticClass:"line-number"},[s._v("16")]),n("br"),n("span",{staticClass:"line-number"},[s._v("17")]),n("br"),n("span",{staticClass:"line-number"},[s._v("18")]),n("br"),n("span",{staticClass:"line-number"},[s._v("19")]),n("br"),n("span",{staticClass:"line-number"},[s._v("20")]),n("br"),n("span",{staticClass:"line-number"},[s._v("21")]),n("br"),n("span",{staticClass:"line-number"},[s._v("22")]),n("br"),n("span",{staticClass:"line-number"},[s._v("23")]),n("br"),n("span",{staticClass:"line-number"},[s._v("24")]),n("br"),n("span",{staticClass:"line-number"},[s._v("25")]),n("br"),n("span",{staticClass:"line-number"},[s._v("26")]),n("br")])]),n("p",[s._v("说明:可变参数函数通常是递归的,第一个版本的 print_fun 负责终止递归并打印初始调用中的最后一个实参。第二个版本的 print_fun 是可变参数版本,打印绑定到 t 的实参,并用来调用自身来打印函数参数包中的剩余值。")]),s._v(" "),n("h2",{attrs:{id:"什么是模板特化-为什么特化"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#什么是模板特化-为什么特化"}},[s._v("#")]),s._v(" 什么是模板特化?为什么特化?")]),s._v(" "),n("p",[n("strong",[s._v("面试高频指数:★★★☆☆")]),s._v("\n模板特化的原因:模板并非对任何模板实参都合适、都能实例化,某些情况下,通用模板的定义对特定类型不合适,可能会编译失败,或者得不到正确的结果。因此,当不希望使用模板版本时,可以定义类或者函数模板的一个特例化版本。")]),s._v(" "),n("p",[s._v("模板特化:模板参数在某种特定类型下的具体实现。分为函数模板特化和类模板特化")]),s._v(" "),n("ul",[n("li",[n("p",[s._v("函数模板特化:将函数模板中的全部类型进行特例化,称为函数模板特化。")])]),s._v(" "),n("li",[n("p",[s._v("类模板特化:将类模板中的部分或全部类型进行特例化,称为类模板特化。")])])]),s._v(" "),n("p",[s._v("特化分为全特化和偏特化:")]),s._v(" "),n("ul",[n("li",[n("p",[s._v("全特化:模板中的模板参数全部特例化。")])]),s._v(" "),n("li",[n("p",[s._v("偏特化:模板中的模板参数只确定了一部分,剩余部分需要在编译器编译时确定。")])])]),s._v(" "),n("p",[s._v("说明:要区分下函数重载与函数模板特化\n定义函数模板的特化版本,本质上是接管了编译器的工作,为原函数模板定义了一个特殊实例,而不是函数重载,函数模板特化并不影响函数匹配。")]),s._v(" "),n("p",[s._v("实例:")]),s._v(" "),n("div",{staticClass:"language-c++ line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v('#include \n#include \n\nusing namespace std;\n//函数模板\ntemplate \nbool compare(T t1, T t2)\n{\n cout << "通用版本:";\n return t1 == t2;\n}\n\ntemplate <> //函数模板特化\nbool compare(char *t1, char *t2)\n{\n cout << "特化版本:";\n return strcmp(t1, t2) == 0;\n}\n\nint main(int argc, char *argv[])\n{\n char arr1[] = "hello";\n char arr2[] = "abc";\n cout << compare(123, 123) << endl;\n cout << compare(arr1, arr2) << endl;\n\n return 0;\n}\n/*\n运行结果:\n通用版本:1\n特化版本:0\n*/\n')])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br"),n("span",{staticClass:"line-number"},[s._v("8")]),n("br"),n("span",{staticClass:"line-number"},[s._v("9")]),n("br"),n("span",{staticClass:"line-number"},[s._v("10")]),n("br"),n("span",{staticClass:"line-number"},[s._v("11")]),n("br"),n("span",{staticClass:"line-number"},[s._v("12")]),n("br"),n("span",{staticClass:"line-number"},[s._v("13")]),n("br"),n("span",{staticClass:"line-number"},[s._v("14")]),n("br"),n("span",{staticClass:"line-number"},[s._v("15")]),n("br"),n("span",{staticClass:"line-number"},[s._v("16")]),n("br"),n("span",{staticClass:"line-number"},[s._v("17")]),n("br"),n("span",{staticClass:"line-number"},[s._v("18")]),n("br"),n("span",{staticClass:"line-number"},[s._v("19")]),n("br"),n("span",{staticClass:"line-number"},[s._v("20")]),n("br"),n("span",{staticClass:"line-number"},[s._v("21")]),n("br"),n("span",{staticClass:"line-number"},[s._v("22")]),n("br"),n("span",{staticClass:"line-number"},[s._v("23")]),n("br"),n("span",{staticClass:"line-number"},[s._v("24")]),n("br"),n("span",{staticClass:"line-number"},[s._v("25")]),n("br"),n("span",{staticClass:"line-number"},[s._v("26")]),n("br"),n("span",{staticClass:"line-number"},[s._v("27")]),n("br"),n("span",{staticClass:"line-number"},[s._v("28")]),n("br"),n("span",{staticClass:"line-number"},[s._v("29")]),n("br"),n("span",{staticClass:"line-number"},[s._v("30")]),n("br"),n("span",{staticClass:"line-number"},[s._v("31")]),n("br"),n("span",{staticClass:"line-number"},[s._v("32")]),n("br"),n("span",{staticClass:"line-number"},[s._v("33")]),n("br")])]),n("h2",{attrs:{id:"include-和-的区别"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#include-和-的区别"}},[s._v("#")]),s._v(' include " " 和 <> 的区别')]),s._v(" "),n("p",[n("strong",[s._v("面试高频指数:★☆☆☆☆")]),s._v('\ninclude<文件名> 和 #include"文件名" 的区别:')]),s._v(" "),n("p",[s._v('查找文件的位置:include<文件名> 在标准库头文件所在的目录中查找,如果没有,再到当前源文件所在目录下查找;#include"文件名" 在当前源文件所在目录中进行查找,如果没有;再到系统目录中查找。\n使用习惯:对于标准库中的头文件常用 include<文件名>,对于自己定义的头文件,常用 #include"文件名"')]),s._v(" "),n("h2",{attrs:{id:"switch-的-case-里为何不能定义变量"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#switch-的-case-里为何不能定义变量"}},[s._v("#")]),s._v(" switch 的 case 里为何不能定义变量")]),s._v(" "),n("p",[n("strong",[s._v("面试高频指数:★☆☆☆☆")])]),s._v(" "),n("ul",[n("li",[n("p",[s._v("switch 下面的这个花括号表示一块作用域,而不是每一个 case 表示一块作用域。如果在某一 case 中定义了变量,其作用域在这块花括号内,按理说在另一个 case 内可以使用该变量,但是在实际使用时,每一个 case 之间互不影响,是相对封闭的,参考如下实例。")]),s._v(" "),n("p",[s._v("实例:")]),s._v(" "),n("p",[s._v("下述代码中,在 switch 的 case 中定义的变量,没有实际意义,仅为了解释上述原因。")]),s._v(" "),n("div",{staticClass:"language-c++ line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v("#include \nusing namespace std;\n\nint main()\n{\n // 局部变量声明\n char var = 'D';\n\n switch (var)\n {\n case 'A':\n int cnt = 0; // 定义变量\n cout << \"Excellent.\" << endl\n << cnt;\n break;\n case 'B':\n case 'C':\n ++cnt;\n cout << \"Good.\" << endl\n << cnt;\n break;\n case 'D':\n cout << \"Not bad.\" << endl\n << cnt;\n break;\n case 'F':\n cout << \"Bad.\" << endl\n << cnt;\n break;\n default:\n cout << \"Bad.\" << endl\n << cnt;\n }\n\n return 0;\n}\n")])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br"),n("span",{staticClass:"line-number"},[s._v("8")]),n("br"),n("span",{staticClass:"line-number"},[s._v("9")]),n("br"),n("span",{staticClass:"line-number"},[s._v("10")]),n("br"),n("span",{staticClass:"line-number"},[s._v("11")]),n("br"),n("span",{staticClass:"line-number"},[s._v("12")]),n("br"),n("span",{staticClass:"line-number"},[s._v("13")]),n("br"),n("span",{staticClass:"line-number"},[s._v("14")]),n("br"),n("span",{staticClass:"line-number"},[s._v("15")]),n("br"),n("span",{staticClass:"line-number"},[s._v("16")]),n("br"),n("span",{staticClass:"line-number"},[s._v("17")]),n("br"),n("span",{staticClass:"line-number"},[s._v("18")]),n("br"),n("span",{staticClass:"line-number"},[s._v("19")]),n("br"),n("span",{staticClass:"line-number"},[s._v("20")]),n("br"),n("span",{staticClass:"line-number"},[s._v("21")]),n("br"),n("span",{staticClass:"line-number"},[s._v("22")]),n("br"),n("span",{staticClass:"line-number"},[s._v("23")]),n("br"),n("span",{staticClass:"line-number"},[s._v("24")]),n("br"),n("span",{staticClass:"line-number"},[s._v("25")]),n("br"),n("span",{staticClass:"line-number"},[s._v("26")]),n("br"),n("span",{staticClass:"line-number"},[s._v("27")]),n("br"),n("span",{staticClass:"line-number"},[s._v("28")]),n("br"),n("span",{staticClass:"line-number"},[s._v("29")]),n("br"),n("span",{staticClass:"line-number"},[s._v("30")]),n("br"),n("span",{staticClass:"line-number"},[s._v("31")]),n("br"),n("span",{staticClass:"line-number"},[s._v("32")]),n("br"),n("span",{staticClass:"line-number"},[s._v("33")]),n("br"),n("span",{staticClass:"line-number"},[s._v("34")]),n("br"),n("span",{staticClass:"line-number"},[s._v("35")]),n("br"),n("span",{staticClass:"line-number"},[s._v("36")]),n("br")])]),n("p",[s._v("简单解释:上述代码中在符合 A 的条件下定义了变量,当符合 B 或者 C 的条件时,对该变量进行自增操作,但是因为不符合条件 A 未对变量进行定义,该变量无法使用。")])])]),s._v(" "),n("h2",{attrs:{id:"迭代器的作用"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#迭代器的作用"}},[s._v("#")]),s._v(" 迭代器的作用?")]),s._v(" "),n("p",[n("strong",[s._v("面试高频指数:★☆☆☆☆")])]),s._v(" "),n("p",[s._v("迭代器:一种抽象的设计概念,在设计模式中有迭代器模式,即提供一种方法,使之能够依序寻访某个容器所含的各个元素,而无需暴露该容器的内部表述方式。")]),s._v(" "),n("p",[s._v("作用:在无需知道容器底层原理的情况下,遍历容器中的元素。")]),s._v(" "),n("p",[s._v("实例:")]),s._v(" "),n("div",{staticClass:"language-c++ line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v('#include \n#include \nusing namespace std;\n\nint main()\n{\n vector arr = {1, 2, 3, 4, 5, 6, 7, 8, 9, 0};\n vector::iterator iter = arr.begin(); // 定义迭代器\n for (; iter != arr.end(); ++iter)\n {\n cout << *iter << " ";\n }\n return 0;\n}\n/*\n运行结果:\n1 2 3 4 5 6 7 8 9 0\n*/\n')])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br"),n("span",{staticClass:"line-number"},[s._v("8")]),n("br"),n("span",{staticClass:"line-number"},[s._v("9")]),n("br"),n("span",{staticClass:"line-number"},[s._v("10")]),n("br"),n("span",{staticClass:"line-number"},[s._v("11")]),n("br"),n("span",{staticClass:"line-number"},[s._v("12")]),n("br"),n("span",{staticClass:"line-number"},[s._v("13")]),n("br"),n("span",{staticClass:"line-number"},[s._v("14")]),n("br"),n("span",{staticClass:"line-number"},[s._v("15")]),n("br"),n("span",{staticClass:"line-number"},[s._v("16")]),n("br"),n("span",{staticClass:"line-number"},[s._v("17")]),n("br"),n("span",{staticClass:"line-number"},[s._v("18")]),n("br")])]),n("h2",{attrs:{id:"泛型编程如何实现"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#泛型编程如何实现"}},[s._v("#")]),s._v(" 泛型编程如何实现?")]),s._v(" "),n("p",[n("strong",[s._v("面试高频指数:★★☆☆☆")])]),s._v(" "),n("p",[s._v("泛型编程实现的基础:模板。模板是创建类或者函数的蓝图或者说公式,当时用一个 vector 这样的泛型,或者 find 这样的泛型函数时,编译时会转化为特定的类或者函数。")]),s._v(" "),n("p",[s._v("泛型编程涉及到的知识点较广,例如:容器、迭代器、算法等都是泛型编程的实现实例。面试者可选择自己掌握比较扎实的一方面进行展开。")]),s._v(" "),n("ul",[n("li",[n("p",[s._v("容器:涉及到 STL 中的容器,例如:vector、list、map 等,可选其中熟悉底层原理的容器进行展开讲解。")])]),s._v(" "),n("li",[n("p",[s._v("迭代器:在无需知道容器底层原理的情况下,遍历容器中的元素。")])]),s._v(" "),n("li",[n("p",[s._v("模板:可参考本章节中的模板相关问题。")])])]),s._v(" "),n("h2",{attrs:{id:"什么是类型萃取"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#什么是类型萃取"}},[s._v("#")]),s._v(" 什么是类型萃取?")]),s._v(" "),n("p",[n("strong",[s._v("面试高频指数:★☆☆☆☆")])]),s._v(" "),n("p",[s._v("类型萃取使用模板技术来萃取类型(包含自定义类型和内置类型)的某些特性,用以判断该类型是否含有某些特性,从而在泛型算法中来对该类型进行特殊的处理用来提高效率或者其他。")]),s._v(" "),n("p",[s._v("C++ 类型萃取一般用于模板中,当我们定义一个模板函数后,需要知道模板类型形参并加以运用时就可以用类型萃取。\n比如我们需要在函数中进行拷贝,通常我们可以用内置函数 memcpy 或者自己写一个 for 循环来进行拷贝。")]),s._v(" "),n("h1",{attrs:{id:"设计模式"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#设计模式"}},[s._v("#")]),s._v(" 设计模式")]),s._v(" "),n("h2",{attrs:{id:"了解哪些设计模式"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#了解哪些设计模式"}},[s._v("#")]),s._v(" 了解哪些设计模式?")]),s._v(" "),n("p",[n("strong",[s._v("面试高频指数:★★★★☆")])]),s._v(" "),n("p",[s._v("《大话设计模式》一书中提到 24 种设计模式,这 24 种设计模式没必要面面俱到,但一定要深入了解其中的几种,最好结合自己在实际开发过程中的例子进行深入的了解。")]),s._v(" "),n("p",[n("strong",[s._v("设计模式有 6 大设计原则:")])]),s._v(" "),n("ol",[n("li",[s._v("**单一职责原则:**就一个类而言,应该仅有一个引起它变化的原因。")]),s._v(" "),n("li",[s._v("**开放封闭原则:**软件实体可以扩展,但是不可修改。即面对需求,对程序的改动可以通过增加代码来完成,但是不能改动现有的代码。")]),s._v(" "),n("li",[s._v("**里氏代换原则:**一个软件实体如果使用的是一个基类,那么一定适用于其派生类。即在软件中,把基类替换成派生类,程序的行为没有变化。")]),s._v(" "),n("li",[s._v("**依赖倒转原则:**抽象不应该依赖细节,细节应该依赖抽象。即针对接口编程,不要对实现编程。")]),s._v(" "),n("li",[s._v("**迪米特原则:**如果两个类不直接通信,那么这两个类就不应当发生直接的相互作用。如果一个类需要调用另一个类的某个方法的话,可以通过第三个类转发这个调用。")]),s._v(" "),n("li",[s._v("**接口隔离原则:**每个接口中不存在派生类用不到却必须实现的方法,如果不然,就要将接口拆分,使用多个隔离的接口。")])]),s._v(" "),n("p",[n("strong",[s._v("设计模式分为三类:")])]),s._v(" "),n("ol",[n("li",[n("p",[s._v("创造型模式:单例模式、工厂模式、建造者模式、原型模式")])]),s._v(" "),n("li",[n("p",[s._v("结构型模式:适配器模式、桥接模式、外观模式、组合模式、装饰模式、享元模式、代理模式")])]),s._v(" "),n("li",[n("p",[s._v("行为型模式:责任链模式、命令模式、解释器模式、迭代器模式、中介者模式、备忘录模式、观察者模式、状态模式、策略模式、模板方法模式、访问者模式")])])]),s._v(" "),n("p",[s._v("下面介绍常见的几种设计模式:")]),s._v(" "),n("ol",[n("li",[s._v("单例模式:保证一个类仅有一个实例,并提供一个访问它的全局访问点。")]),s._v(" "),n("li",[s._v("工厂模式:包括简单工厂模式、抽象工厂模式、工厂方法模式\n"),n("ul",[n("li",[s._v("简单工厂模式:主要用于创建对象。用一个工厂来根据输入的条件产生不同的类,然后根据不同类的虚函数得到不同的结果。")]),s._v(" "),n("li",[s._v("工厂方法模式:修正了简单工厂模式中不遵守开放封闭原则。把选择判断移到了客户端去实现,如果想添加新功能就不用修改原来的类,直接修改客户端即可。")]),s._v(" "),n("li",[s._v("抽象工厂模式:定义了一个创建一系列相关或相互依赖的接口,而无需指定他们的具体类。")])])]),s._v(" "),n("li",[s._v("观察者模式:定义了一种一对多的关系,让多个观察对象同时监听一个主题对象,主题对象发生变化时,会通知所有的观察者,使他们能够更新自己。")]),s._v(" "),n("li",[s._v("装饰模式:动态地给一个对象添加一些额外的职责,就增加功能来说,装饰模式比生成派生类更为灵活。")])]),s._v(" "),n("h2",{attrs:{id:"什么是单例模式-如何实现-应用场景"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#什么是单例模式-如何实现-应用场景"}},[s._v("#")]),s._v(" 什么是单例模式?如何实现?应用场景?")]),s._v(" "),n("p",[n("strong",[s._v("面试高频指数:★★★★★")])]),s._v(" "),n("p",[s._v("**单例模式:**保证类的实例化对象仅有一个,并且提供一个访问他的全局访问点。")]),s._v(" "),n("p",[n("strong",[s._v("应用场景:")])]),s._v(" "),n("ul",[n("li",[s._v("表示文件系统的类,一个操作系统一定是只有一个文件系统,因此文件系统的类的实例有且仅有一个。")]),s._v(" "),n("li",[s._v("打印机打印程序的实例,一台计算机可以连接好几台打印机,但是计算机上的打印程序只有一个,就可以通过单例模式来避免两个打印作业同时输出到打印机。")])]),s._v(" "),n("p",[n("strong",[s._v("实现方式:")]),s._v("\n单例模式可以通过全局或者静态变量的形式实现,这样比较简单,但是这样会影响封装性,难以保证别的代码不会对全局变量造成影响。")]),s._v(" "),n("ul",[n("li",[n("p",[s._v("默认的构造函数、拷贝构造函数、赋值构造函数声明为私有的,这样禁止在类的外部创建该对象;")])]),s._v(" "),n("li",[n("p",[s._v("全局访问点也要定义成 静态类型的成员函数,没有参数,返回该类的指针类型。因为使用实例化对象的时候是通过类直接调用该函数,并不是先创建一个该类的对象,通过对象调用。")])])]),s._v(" "),n("p",[n("strong",[s._v("不安全的实现方式:")]),s._v("\n原因:考虑当两个线程同时调用 getInstance 方法,并且同时检测到 instance 是 NULL,两个线程会同时实例化对象,不符合单例模式的要求。")]),s._v(" "),n("div",{staticClass:"language-c++ line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v("class Singleton{\nprivate:\n static Singleton * instance;\n Singleton(){}\n Singleton(const Singleton& tmp){}\n Singleton& operator=(const Singleton& tmp){}\npublic:\n static Singleton* getInstance(){\n if(instance == NULL){\n instance = new Singleton();\n }\n return instance;\n }\n};\nSingleton* Singleton::instance = NULL;\n")])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br"),n("span",{staticClass:"line-number"},[s._v("8")]),n("br"),n("span",{staticClass:"line-number"},[s._v("9")]),n("br"),n("span",{staticClass:"line-number"},[s._v("10")]),n("br"),n("span",{staticClass:"line-number"},[s._v("11")]),n("br"),n("span",{staticClass:"line-number"},[s._v("12")]),n("br"),n("span",{staticClass:"line-number"},[s._v("13")]),n("br"),n("span",{staticClass:"line-number"},[s._v("14")]),n("br"),n("span",{staticClass:"line-number"},[s._v("15")]),n("br")])]),n("p",[n("strong",[s._v("分类:")])]),s._v(" "),n("ul",[n("li",[n("p",[s._v("懒汉模式:直到第一次用到类的实例时才去实例化,上面是懒汉实现。")])]),s._v(" "),n("li",[n("p",[s._v("饿汉模式:类定义的时候就实例化。")])])]),s._v(" "),n("p",[n("strong",[s._v("线程安全的懒汉模式实现:")]),s._v("\n方法:加锁\n存在的问题:每次判断实例对象是否为空,都要被锁定,如果是多线程的话,就会造成大量线程阻塞。")]),s._v(" "),n("div",{staticClass:"language-c++ line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v("class Singleton{\nprivate:\n static pthread_mutex_t mutex;\n static Singleton * instance;\n Singleton(){\n pthread_mutex_init(&mutex, NULL);\n }\n Singleton(const Singleton& tmp){}\n Singleton& operator=(const Singleton& tmp){}\npublic:\n static Singleton* getInstance(){\n pthread_mutex_lock(&mutex);\n if(instance == NULL){\n instance = new Singleton();\n }\n pthread_mutex_unlock(&mutex);\n return instance;\n }\n};\nSingleton* Singleton::instance = NULL;\npthread_mutex_t Singleton::mutex;\n")])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br"),n("span",{staticClass:"line-number"},[s._v("8")]),n("br"),n("span",{staticClass:"line-number"},[s._v("9")]),n("br"),n("span",{staticClass:"line-number"},[s._v("10")]),n("br"),n("span",{staticClass:"line-number"},[s._v("11")]),n("br"),n("span",{staticClass:"line-number"},[s._v("12")]),n("br"),n("span",{staticClass:"line-number"},[s._v("13")]),n("br"),n("span",{staticClass:"line-number"},[s._v("14")]),n("br"),n("span",{staticClass:"line-number"},[s._v("15")]),n("br"),n("span",{staticClass:"line-number"},[s._v("16")]),n("br"),n("span",{staticClass:"line-number"},[s._v("17")]),n("br"),n("span",{staticClass:"line-number"},[s._v("18")]),n("br"),n("span",{staticClass:"line-number"},[s._v("19")]),n("br"),n("span",{staticClass:"line-number"},[s._v("20")]),n("br"),n("span",{staticClass:"line-number"},[s._v("21")]),n("br")])]),n("p",[s._v("方法:"),n("strong",[s._v("内部静态变量")]),s._v(",在全局访问点 "),n("code",[s._v("getInstance")]),s._v(" 中定义静态实例。")]),s._v(" "),n("div",{staticClass:"language-c++ line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v("class Singleton{\nprivate:\n static pthread_mutex_t mutex;\n Singleton(){\n pthread_mutex_init(&mutex, NULL);\n }\n Singleton(const Singleton& temp){}\n Singleton& operator=(const Singleton& temp){}\npublic:\n static Singleton* getInstance(){\n static Singleton instance;\n return &instance;\n }\n};\npthread_mutex_t Singleton::mutex;\n")])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br"),n("span",{staticClass:"line-number"},[s._v("8")]),n("br"),n("span",{staticClass:"line-number"},[s._v("9")]),n("br"),n("span",{staticClass:"line-number"},[s._v("10")]),n("br"),n("span",{staticClass:"line-number"},[s._v("11")]),n("br"),n("span",{staticClass:"line-number"},[s._v("12")]),n("br"),n("span",{staticClass:"line-number"},[s._v("13")]),n("br"),n("span",{staticClass:"line-number"},[s._v("14")]),n("br"),n("span",{staticClass:"line-number"},[s._v("15")]),n("br")])]),n("p",[s._v("饿汉模式的实现:\n饿汉模式本身就是线程安全的不用加锁。")]),s._v(" "),n("div",{staticClass:"language-c++ line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v("class Singleton{\nprivate:\n static Singleton* instance;\n Singleton(const Singleton& temp){}\n Singleton& operator=(const Singleton& temp){}\nprotected:\n Singleton(){}\npublic:\n static Singleton* getInstance(){\n return instance;\n }\n};\nSingleton* Singleton::instance = new Singleton();\n")])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br"),n("span",{staticClass:"line-number"},[s._v("8")]),n("br"),n("span",{staticClass:"line-number"},[s._v("9")]),n("br"),n("span",{staticClass:"line-number"},[s._v("10")]),n("br"),n("span",{staticClass:"line-number"},[s._v("11")]),n("br"),n("span",{staticClass:"line-number"},[s._v("12")]),n("br"),n("span",{staticClass:"line-number"},[s._v("13")]),n("br")])]),n("h2",{attrs:{id:"什么是工厂模式-如何实现-应用场景"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#什么是工厂模式-如何实现-应用场景"}},[s._v("#")]),s._v(" 什么是工厂模式?如何实现?应用场景?")]),s._v(" "),n("p",[n("strong",[s._v("面试高频指数:★★★☆☆")])]),s._v(" "),n("p",[n("strong",[s._v("工厂模式:包括简单工厂模式、抽象工厂模式、工厂方法模式")])]),s._v(" "),n("ul",[n("li",[s._v("简单工厂模式:主要用于创建对象。用一个工厂来根据输入的条件产生不同的类,然后根据不同类的虚函数得到不同的结果。")]),s._v(" "),n("li",[s._v("工厂方法模式:修正了简单工厂模式中不遵守开放封闭原则。把选择判断移到了客户端去实现,如果想添加新功能就不用修改原来的类,直接修改客户端即可。")]),s._v(" "),n("li",[s._v("抽象工厂模式:定义了一个创建一系列相关或相互依赖的接口,而无需指定他们的具体类。")])]),s._v(" "),n("ol",[n("li",[n("p",[s._v("简单工厂模式")]),s._v(" "),n("p",[s._v("主要用于创建对象。用一个工厂来根据输入的条件产生不同的类,然后根据不同类的虚函数得到不同的结果。")]),s._v(" "),n("p",[s._v("应用场景:")]),s._v(" "),n("ul",[n("li",[n("p",[s._v("适用于针对不同情况创建不同类时,只需传入工厂类的参数即可,无需了解具体实现方法。例如:计算器中对于同样的输入,执行不同的操作:加、减、乘、除。")]),s._v(" "),n("p",[s._v("实现方式:")]),s._v(" "),n("div",{staticClass:"language- line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v("#include \n#include \nusing namespace std;\n\n// Here is the product class\nclass Operation\n{\npublic:\n int var1, var2;\n virtual double GetResult()\n {\n double res = 0;\n return res;\n }\n};\n\nclass Add_Operation : public Operation\n{\npublic:\n virtual double GetResult()\n {\n return var1 + var2;\n }\n};\n\nclass Sub_Operation : public Operation\n{\npublic:\n virtual double GetResult()\n {\n return var1 - var2;\n }\n};\n\nclass Mul_Operation : public Operation\n{\npublic:\n virtual double GetResult()\n {\n return var1 * var2;\n }\n};\n\nclass Div_Operation : public Operation\n{\npublic:\n virtual double GetResult()\n {\n return var1 / var2;\n }\n};\n\n// Here is the Factory class\nclass Factory\n{\npublic:\n static Operation *CreateProduct(char op)\n {\n switch (op)\n {\n case '+':\n return new Add_Operation();\n\n case '-':\n return new Sub_Operation();\n\n case '*':\n return new Mul_Operation();\n\n case '/':\n return new Div_Operation();\n\n default:\n return new Add_Operation();\n }\n }\n};\n\nint main()\n{\n int a, b;\n cin >> a >> b;\n Operation *p = Factory::CreateProduct('+');\n p->var1 = a;\n p->var2 = b;\n cout << p->GetResult() << endl;\n\n p = Factory::CreateProduct('*');\n p->var1 = a;\n p->var2 = b;\n cout << p->GetResult() << endl;\n\n return 0;\n}\n")])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br"),n("span",{staticClass:"line-number"},[s._v("8")]),n("br"),n("span",{staticClass:"line-number"},[s._v("9")]),n("br"),n("span",{staticClass:"line-number"},[s._v("10")]),n("br"),n("span",{staticClass:"line-number"},[s._v("11")]),n("br"),n("span",{staticClass:"line-number"},[s._v("12")]),n("br"),n("span",{staticClass:"line-number"},[s._v("13")]),n("br"),n("span",{staticClass:"line-number"},[s._v("14")]),n("br"),n("span",{staticClass:"line-number"},[s._v("15")]),n("br"),n("span",{staticClass:"line-number"},[s._v("16")]),n("br"),n("span",{staticClass:"line-number"},[s._v("17")]),n("br"),n("span",{staticClass:"line-number"},[s._v("18")]),n("br"),n("span",{staticClass:"line-number"},[s._v("19")]),n("br"),n("span",{staticClass:"line-number"},[s._v("20")]),n("br"),n("span",{staticClass:"line-number"},[s._v("21")]),n("br"),n("span",{staticClass:"line-number"},[s._v("22")]),n("br"),n("span",{staticClass:"line-number"},[s._v("23")]),n("br"),n("span",{staticClass:"line-number"},[s._v("24")]),n("br"),n("span",{staticClass:"line-number"},[s._v("25")]),n("br"),n("span",{staticClass:"line-number"},[s._v("26")]),n("br"),n("span",{staticClass:"line-number"},[s._v("27")]),n("br"),n("span",{staticClass:"line-number"},[s._v("28")]),n("br"),n("span",{staticClass:"line-number"},[s._v("29")]),n("br"),n("span",{staticClass:"line-number"},[s._v("30")]),n("br"),n("span",{staticClass:"line-number"},[s._v("31")]),n("br"),n("span",{staticClass:"line-number"},[s._v("32")]),n("br"),n("span",{staticClass:"line-number"},[s._v("33")]),n("br"),n("span",{staticClass:"line-number"},[s._v("34")]),n("br"),n("span",{staticClass:"line-number"},[s._v("35")]),n("br"),n("span",{staticClass:"line-number"},[s._v("36")]),n("br"),n("span",{staticClass:"line-number"},[s._v("37")]),n("br"),n("span",{staticClass:"line-number"},[s._v("38")]),n("br"),n("span",{staticClass:"line-number"},[s._v("39")]),n("br"),n("span",{staticClass:"line-number"},[s._v("40")]),n("br"),n("span",{staticClass:"line-number"},[s._v("41")]),n("br"),n("span",{staticClass:"line-number"},[s._v("42")]),n("br"),n("span",{staticClass:"line-number"},[s._v("43")]),n("br"),n("span",{staticClass:"line-number"},[s._v("44")]),n("br"),n("span",{staticClass:"line-number"},[s._v("45")]),n("br"),n("span",{staticClass:"line-number"},[s._v("46")]),n("br"),n("span",{staticClass:"line-number"},[s._v("47")]),n("br"),n("span",{staticClass:"line-number"},[s._v("48")]),n("br"),n("span",{staticClass:"line-number"},[s._v("49")]),n("br"),n("span",{staticClass:"line-number"},[s._v("50")]),n("br"),n("span",{staticClass:"line-number"},[s._v("51")]),n("br"),n("span",{staticClass:"line-number"},[s._v("52")]),n("br"),n("span",{staticClass:"line-number"},[s._v("53")]),n("br"),n("span",{staticClass:"line-number"},[s._v("54")]),n("br"),n("span",{staticClass:"line-number"},[s._v("55")]),n("br"),n("span",{staticClass:"line-number"},[s._v("56")]),n("br"),n("span",{staticClass:"line-number"},[s._v("57")]),n("br"),n("span",{staticClass:"line-number"},[s._v("58")]),n("br"),n("span",{staticClass:"line-number"},[s._v("59")]),n("br"),n("span",{staticClass:"line-number"},[s._v("60")]),n("br"),n("span",{staticClass:"line-number"},[s._v("61")]),n("br"),n("span",{staticClass:"line-number"},[s._v("62")]),n("br"),n("span",{staticClass:"line-number"},[s._v("63")]),n("br"),n("span",{staticClass:"line-number"},[s._v("64")]),n("br"),n("span",{staticClass:"line-number"},[s._v("65")]),n("br"),n("span",{staticClass:"line-number"},[s._v("66")]),n("br"),n("span",{staticClass:"line-number"},[s._v("67")]),n("br"),n("span",{staticClass:"line-number"},[s._v("68")]),n("br"),n("span",{staticClass:"line-number"},[s._v("69")]),n("br"),n("span",{staticClass:"line-number"},[s._v("70")]),n("br"),n("span",{staticClass:"line-number"},[s._v("71")]),n("br"),n("span",{staticClass:"line-number"},[s._v("72")]),n("br"),n("span",{staticClass:"line-number"},[s._v("73")]),n("br"),n("span",{staticClass:"line-number"},[s._v("74")]),n("br"),n("span",{staticClass:"line-number"},[s._v("75")]),n("br"),n("span",{staticClass:"line-number"},[s._v("76")]),n("br"),n("span",{staticClass:"line-number"},[s._v("77")]),n("br"),n("span",{staticClass:"line-number"},[s._v("78")]),n("br"),n("span",{staticClass:"line-number"},[s._v("79")]),n("br"),n("span",{staticClass:"line-number"},[s._v("80")]),n("br"),n("span",{staticClass:"line-number"},[s._v("81")]),n("br"),n("span",{staticClass:"line-number"},[s._v("82")]),n("br"),n("span",{staticClass:"line-number"},[s._v("83")]),n("br"),n("span",{staticClass:"line-number"},[s._v("84")]),n("br"),n("span",{staticClass:"line-number"},[s._v("85")]),n("br"),n("span",{staticClass:"line-number"},[s._v("86")]),n("br"),n("span",{staticClass:"line-number"},[s._v("87")]),n("br"),n("span",{staticClass:"line-number"},[s._v("88")]),n("br"),n("span",{staticClass:"line-number"},[s._v("89")]),n("br"),n("span",{staticClass:"line-number"},[s._v("90")]),n("br"),n("span",{staticClass:"line-number"},[s._v("91")]),n("br"),n("span",{staticClass:"line-number"},[s._v("92")]),n("br"),n("span",{staticClass:"line-number"},[s._v("93")]),n("br"),n("span",{staticClass:"line-number"},[s._v("94")]),n("br")])])])])]),s._v(" "),n("li",[n("p",[s._v("工厂方法模式")]),s._v(" "),n("p",[s._v("修正了简单工厂模式中不遵守开放封闭原则。把选择判断移到了客户端去实现,如果想添加新功能就不用修改原来的类,直接修改客户端即可。")]),s._v(" "),n("p",[n("strong",[s._v("应用场景")]),s._v(":")]),s._v(" "),n("ul",[n("li",[s._v("一个类不知道它所需要的对象的类:在工厂方法模式中,客户端不需要知道具体产品类的类名,只需要知道所对应的工厂即可,具体的产品对象由具体工厂类创建;客户端需要知道创建具体产品的工厂类。")]),s._v(" "),n("li",[s._v("一个类通过其派生类来指定创建哪个对象:在工厂方法模式中,对于抽象工厂类只需要提供一个创建产品的接口,而由其派生类来确定具体要创建的对象,利用面向对象的多态性和里氏代换原则,在程序运行时,派生类对象将覆盖父类对象,从而使得系统更容易扩展。")]),s._v(" "),n("li",[s._v("将创建对象的任务委托给多个工厂派生类中的某一个,客户端在使用时可以无须关心是哪一个工厂派生类创建产品派生类,需要时再动态指定,可将具体工厂类的类名存储在配置文件或数据库中。")])]),s._v(" "),n("p",[n("strong",[s._v("实现方式:")])]),s._v(" "),n("div",{staticClass:"language-c++ line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v("#include \n#include \nusing namespace std;\n\n// Here is the product class\nclass Operation\n{\npublic:\n int var1, var2;\n virtual double GetResult()\n {\n double res = 0;\n return res;\n }\n};\n\nclass Add_Operation : public Operation\n{\npublic:\n virtual double GetResult()\n {\n return var1 + var2;\n }\n};\n\nclass Sub_Operation : public Operation\n{\npublic:\n virtual double GetResult()\n {\n return var1 - var2;\n }\n};\n\nclass Mul_Operation : public Operation\n{\npublic:\n virtual double GetResult()\n {\n return var1 * var2;\n }\n};\n\nclass Div_Operation : public Operation\n{\npublic:\n virtual double GetResult()\n {\n return var1 / var2;\n }\n};\n\nclass Factory\n{\npublic:\n virtual Operation *CreateProduct() = 0;\n};\n\nclass Add_Factory : public Factory\n{\npublic:\n Operation *CreateProduct()\n {\n return new Add_Operation();\n }\n};\n\nclass Sub_Factory : public Factory\n{\npublic:\n Operation *CreateProduct()\n {\n return new Sub_Operation();\n }\n};\n\nclass Mul_Factory : public Factory\n{\npublic:\n Operation *CreateProduct()\n {\n return new Mul_Operation();\n }\n};\n\nclass Div_Factory : public Factory\n{\npublic:\n Operation *CreateProduct()\n {\n return new Div_Operation();\n }\n};\n\nint main()\n{\n int a, b;\n cin >> a >> b;\n Add_Factory *p_fac = new Add_Factory();\n Operation *p_pro = p_fac->CreateProduct();\n p_pro->var1 = a;\n p_pro->var2 = b;\n cout << p_pro->GetResult() << endl;\n\n Mul_Factory *p_fac1 = new Mul_Factory();\n Operation *p_pro1 = p_fac1->CreateProduct();\n p_pro1->var1 = a;\n p_pro1->var2 = b;\n cout << p_pro1->GetResult() << endl;\n\n return 0;\n}\n")])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br"),n("span",{staticClass:"line-number"},[s._v("8")]),n("br"),n("span",{staticClass:"line-number"},[s._v("9")]),n("br"),n("span",{staticClass:"line-number"},[s._v("10")]),n("br"),n("span",{staticClass:"line-number"},[s._v("11")]),n("br"),n("span",{staticClass:"line-number"},[s._v("12")]),n("br"),n("span",{staticClass:"line-number"},[s._v("13")]),n("br"),n("span",{staticClass:"line-number"},[s._v("14")]),n("br"),n("span",{staticClass:"line-number"},[s._v("15")]),n("br"),n("span",{staticClass:"line-number"},[s._v("16")]),n("br"),n("span",{staticClass:"line-number"},[s._v("17")]),n("br"),n("span",{staticClass:"line-number"},[s._v("18")]),n("br"),n("span",{staticClass:"line-number"},[s._v("19")]),n("br"),n("span",{staticClass:"line-number"},[s._v("20")]),n("br"),n("span",{staticClass:"line-number"},[s._v("21")]),n("br"),n("span",{staticClass:"line-number"},[s._v("22")]),n("br"),n("span",{staticClass:"line-number"},[s._v("23")]),n("br"),n("span",{staticClass:"line-number"},[s._v("24")]),n("br"),n("span",{staticClass:"line-number"},[s._v("25")]),n("br"),n("span",{staticClass:"line-number"},[s._v("26")]),n("br"),n("span",{staticClass:"line-number"},[s._v("27")]),n("br"),n("span",{staticClass:"line-number"},[s._v("28")]),n("br"),n("span",{staticClass:"line-number"},[s._v("29")]),n("br"),n("span",{staticClass:"line-number"},[s._v("30")]),n("br"),n("span",{staticClass:"line-number"},[s._v("31")]),n("br"),n("span",{staticClass:"line-number"},[s._v("32")]),n("br"),n("span",{staticClass:"line-number"},[s._v("33")]),n("br"),n("span",{staticClass:"line-number"},[s._v("34")]),n("br"),n("span",{staticClass:"line-number"},[s._v("35")]),n("br"),n("span",{staticClass:"line-number"},[s._v("36")]),n("br"),n("span",{staticClass:"line-number"},[s._v("37")]),n("br"),n("span",{staticClass:"line-number"},[s._v("38")]),n("br"),n("span",{staticClass:"line-number"},[s._v("39")]),n("br"),n("span",{staticClass:"line-number"},[s._v("40")]),n("br"),n("span",{staticClass:"line-number"},[s._v("41")]),n("br"),n("span",{staticClass:"line-number"},[s._v("42")]),n("br"),n("span",{staticClass:"line-number"},[s._v("43")]),n("br"),n("span",{staticClass:"line-number"},[s._v("44")]),n("br"),n("span",{staticClass:"line-number"},[s._v("45")]),n("br"),n("span",{staticClass:"line-number"},[s._v("46")]),n("br"),n("span",{staticClass:"line-number"},[s._v("47")]),n("br"),n("span",{staticClass:"line-number"},[s._v("48")]),n("br"),n("span",{staticClass:"line-number"},[s._v("49")]),n("br"),n("span",{staticClass:"line-number"},[s._v("50")]),n("br"),n("span",{staticClass:"line-number"},[s._v("51")]),n("br"),n("span",{staticClass:"line-number"},[s._v("52")]),n("br"),n("span",{staticClass:"line-number"},[s._v("53")]),n("br"),n("span",{staticClass:"line-number"},[s._v("54")]),n("br"),n("span",{staticClass:"line-number"},[s._v("55")]),n("br"),n("span",{staticClass:"line-number"},[s._v("56")]),n("br"),n("span",{staticClass:"line-number"},[s._v("57")]),n("br"),n("span",{staticClass:"line-number"},[s._v("58")]),n("br"),n("span",{staticClass:"line-number"},[s._v("59")]),n("br"),n("span",{staticClass:"line-number"},[s._v("60")]),n("br"),n("span",{staticClass:"line-number"},[s._v("61")]),n("br"),n("span",{staticClass:"line-number"},[s._v("62")]),n("br"),n("span",{staticClass:"line-number"},[s._v("63")]),n("br"),n("span",{staticClass:"line-number"},[s._v("64")]),n("br"),n("span",{staticClass:"line-number"},[s._v("65")]),n("br"),n("span",{staticClass:"line-number"},[s._v("66")]),n("br"),n("span",{staticClass:"line-number"},[s._v("67")]),n("br"),n("span",{staticClass:"line-number"},[s._v("68")]),n("br"),n("span",{staticClass:"line-number"},[s._v("69")]),n("br"),n("span",{staticClass:"line-number"},[s._v("70")]),n("br"),n("span",{staticClass:"line-number"},[s._v("71")]),n("br"),n("span",{staticClass:"line-number"},[s._v("72")]),n("br"),n("span",{staticClass:"line-number"},[s._v("73")]),n("br"),n("span",{staticClass:"line-number"},[s._v("74")]),n("br"),n("span",{staticClass:"line-number"},[s._v("75")]),n("br"),n("span",{staticClass:"line-number"},[s._v("76")]),n("br"),n("span",{staticClass:"line-number"},[s._v("77")]),n("br"),n("span",{staticClass:"line-number"},[s._v("78")]),n("br"),n("span",{staticClass:"line-number"},[s._v("79")]),n("br"),n("span",{staticClass:"line-number"},[s._v("80")]),n("br"),n("span",{staticClass:"line-number"},[s._v("81")]),n("br"),n("span",{staticClass:"line-number"},[s._v("82")]),n("br"),n("span",{staticClass:"line-number"},[s._v("83")]),n("br"),n("span",{staticClass:"line-number"},[s._v("84")]),n("br"),n("span",{staticClass:"line-number"},[s._v("85")]),n("br"),n("span",{staticClass:"line-number"},[s._v("86")]),n("br"),n("span",{staticClass:"line-number"},[s._v("87")]),n("br"),n("span",{staticClass:"line-number"},[s._v("88")]),n("br"),n("span",{staticClass:"line-number"},[s._v("89")]),n("br"),n("span",{staticClass:"line-number"},[s._v("90")]),n("br"),n("span",{staticClass:"line-number"},[s._v("91")]),n("br"),n("span",{staticClass:"line-number"},[s._v("92")]),n("br"),n("span",{staticClass:"line-number"},[s._v("93")]),n("br"),n("span",{staticClass:"line-number"},[s._v("94")]),n("br"),n("span",{staticClass:"line-number"},[s._v("95")]),n("br"),n("span",{staticClass:"line-number"},[s._v("96")]),n("br"),n("span",{staticClass:"line-number"},[s._v("97")]),n("br"),n("span",{staticClass:"line-number"},[s._v("98")]),n("br"),n("span",{staticClass:"line-number"},[s._v("99")]),n("br"),n("span",{staticClass:"line-number"},[s._v("100")]),n("br"),n("span",{staticClass:"line-number"},[s._v("101")]),n("br"),n("span",{staticClass:"line-number"},[s._v("102")]),n("br"),n("span",{staticClass:"line-number"},[s._v("103")]),n("br"),n("span",{staticClass:"line-number"},[s._v("104")]),n("br"),n("span",{staticClass:"line-number"},[s._v("105")]),n("br"),n("span",{staticClass:"line-number"},[s._v("106")]),n("br"),n("span",{staticClass:"line-number"},[s._v("107")]),n("br"),n("span",{staticClass:"line-number"},[s._v("108")]),n("br"),n("span",{staticClass:"line-number"},[s._v("109")]),n("br"),n("span",{staticClass:"line-number"},[s._v("110")]),n("br"),n("span",{staticClass:"line-number"},[s._v("111")]),n("br"),n("span",{staticClass:"line-number"},[s._v("112")]),n("br")])])]),s._v(" "),n("li",[n("p",[s._v("抽象工厂模式")]),s._v(" "),n("p",[s._v("定义了一个创建一系列相关或相互依赖的接口,而无需指定他们的具体类。")]),s._v(" "),n("p",[n("strong",[s._v("应用场景:")])]),s._v(" "),n("ul",[n("li",[s._v("一个系统不应当依赖于产品类实例如何被创建、组合和表达的细节,这对于所有类型的工厂模式都是重要的。")]),s._v(" "),n("li",[s._v("系统中有多于一个的产品族,而每次只使用其中某一产品族。")]),s._v(" "),n("li",[s._v("属于同一个产品族的产品将在一起使用,这一约束必须在系统的设计中体现出来。")]),s._v(" "),n("li",[s._v("产品等级结构稳定,设计完成之后,不会向系统中增加新的产品等级结构或者删除已有的")]),s._v(" "),n("li",[s._v("产品等级结构。")])]),s._v(" "),n("p",[n("strong",[s._v("实现方式:")])]),s._v(" "),n("div",{staticClass:"language-c++ line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v("#include \n#include \nusing namespace std;\n\n// Here is the product class\nclass Operation_Pos\n{\npublic:\n int var1, var2;\n virtual double GetResult()\n {\n double res = 0;\n return res;\n }\n};\n\nclass Add_Operation_Pos : public Operation_Pos\n{\npublic:\n virtual double GetResult()\n {\n return var1 + var2;\n }\n};\n\nclass Sub_Operation_Pos : public Operation_Pos\n{\npublic:\n virtual double GetResult()\n {\n return var1 - var2;\n }\n};\n\nclass Mul_Operation_Pos : public Operation_Pos\n{\npublic:\n virtual double GetResult()\n {\n return var1 * var2;\n }\n};\n\nclass Div_Operation_Pos : public Operation_Pos\n{\npublic:\n virtual double GetResult()\n {\n return var1 / var2;\n }\n};\n/*********************************************************************************/\nclass Operation_Neg\n{\npublic:\n int var1, var2;\n virtual double GetResult()\n {\n double res = 0;\n return res;\n }\n};\n\nclass Add_Operation_Neg : public Operation_Neg\n{\npublic:\n virtual double GetResult()\n {\n return -(var1 + var2);\n }\n};\n\nclass Sub_Operation_Neg : public Operation_Neg\n{\npublic:\n virtual double GetResult()\n {\n return -(var1 - var2);\n }\n};\n\nclass Mul_Operation_Neg : public Operation_Neg\n{\npublic:\n virtual double GetResult()\n {\n return -(var1 * var2);\n }\n};\n\nclass Div_Operation_Neg : public Operation_Neg\n{\npublic:\n virtual double GetResult()\n {\n return -(var1 / var2);\n }\n};\n/*****************************************************************************************************/\n\n// Here is the Factory class\nclass Factory\n{\npublic:\n virtual Operation_Pos *CreateProduct_Pos() = 0;\n virtual Operation_Neg *CreateProduct_Neg() = 0;\n};\n\nclass Add_Factory : public Factory\n{\npublic:\n Operation_Pos *CreateProduct_Pos()\n {\n return new Add_Operation_Pos();\n }\n Operation_Neg *CreateProduct_Neg()\n {\n return new Add_Operation_Neg();\n }\n};\n\nclass Sub_Factory : public Factory\n{\npublic:\n Operation_Pos *CreateProduct_Pos()\n {\n return new Sub_Operation_Pos();\n }\n Operation_Neg *CreateProduct_Neg()\n {\n return new Sub_Operation_Neg();\n }\n};\n\nclass Mul_Factory : public Factory\n{\npublic:\n Operation_Pos *CreateProduct_Pos()\n {\n return new Mul_Operation_Pos();\n }\n Operation_Neg *CreateProduct_Neg()\n {\n return new Mul_Operation_Neg();\n }\n};\n\nclass Div_Factory : public Factory\n{\npublic:\n Operation_Pos *CreateProduct_Pos()\n {\n return new Div_Operation_Pos();\n }\n Operation_Neg *CreateProduct_Neg()\n {\n return new Div_Operation_Neg();\n }\n};\n\nint main()\n{\n int a, b;\n cin >> a >> b;\n Add_Factory *p_fac = new Add_Factory();\n Operation_Pos *p_pro = p_fac->CreateProduct_Pos();\n p_pro->var1 = a;\n p_pro->var2 = b;\n cout << p_pro->GetResult() << endl;\n\n Add_Factory *p_fac1 = new Add_Factory();\n Operation_Neg *p_pro1 = p_fac1->CreateProduct_Neg();\n p_pro1->var1 = a;\n p_pro1->var2 = b;\n cout << p_pro1->GetResult() << endl;\n\n return 0;\n}\n")])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br"),n("span",{staticClass:"line-number"},[s._v("8")]),n("br"),n("span",{staticClass:"line-number"},[s._v("9")]),n("br"),n("span",{staticClass:"line-number"},[s._v("10")]),n("br"),n("span",{staticClass:"line-number"},[s._v("11")]),n("br"),n("span",{staticClass:"line-number"},[s._v("12")]),n("br"),n("span",{staticClass:"line-number"},[s._v("13")]),n("br"),n("span",{staticClass:"line-number"},[s._v("14")]),n("br"),n("span",{staticClass:"line-number"},[s._v("15")]),n("br"),n("span",{staticClass:"line-number"},[s._v("16")]),n("br"),n("span",{staticClass:"line-number"},[s._v("17")]),n("br"),n("span",{staticClass:"line-number"},[s._v("18")]),n("br"),n("span",{staticClass:"line-number"},[s._v("19")]),n("br"),n("span",{staticClass:"line-number"},[s._v("20")]),n("br"),n("span",{staticClass:"line-number"},[s._v("21")]),n("br"),n("span",{staticClass:"line-number"},[s._v("22")]),n("br"),n("span",{staticClass:"line-number"},[s._v("23")]),n("br"),n("span",{staticClass:"line-number"},[s._v("24")]),n("br"),n("span",{staticClass:"line-number"},[s._v("25")]),n("br"),n("span",{staticClass:"line-number"},[s._v("26")]),n("br"),n("span",{staticClass:"line-number"},[s._v("27")]),n("br"),n("span",{staticClass:"line-number"},[s._v("28")]),n("br"),n("span",{staticClass:"line-number"},[s._v("29")]),n("br"),n("span",{staticClass:"line-number"},[s._v("30")]),n("br"),n("span",{staticClass:"line-number"},[s._v("31")]),n("br"),n("span",{staticClass:"line-number"},[s._v("32")]),n("br"),n("span",{staticClass:"line-number"},[s._v("33")]),n("br"),n("span",{staticClass:"line-number"},[s._v("34")]),n("br"),n("span",{staticClass:"line-number"},[s._v("35")]),n("br"),n("span",{staticClass:"line-number"},[s._v("36")]),n("br"),n("span",{staticClass:"line-number"},[s._v("37")]),n("br"),n("span",{staticClass:"line-number"},[s._v("38")]),n("br"),n("span",{staticClass:"line-number"},[s._v("39")]),n("br"),n("span",{staticClass:"line-number"},[s._v("40")]),n("br"),n("span",{staticClass:"line-number"},[s._v("41")]),n("br"),n("span",{staticClass:"line-number"},[s._v("42")]),n("br"),n("span",{staticClass:"line-number"},[s._v("43")]),n("br"),n("span",{staticClass:"line-number"},[s._v("44")]),n("br"),n("span",{staticClass:"line-number"},[s._v("45")]),n("br"),n("span",{staticClass:"line-number"},[s._v("46")]),n("br"),n("span",{staticClass:"line-number"},[s._v("47")]),n("br"),n("span",{staticClass:"line-number"},[s._v("48")]),n("br"),n("span",{staticClass:"line-number"},[s._v("49")]),n("br"),n("span",{staticClass:"line-number"},[s._v("50")]),n("br"),n("span",{staticClass:"line-number"},[s._v("51")]),n("br"),n("span",{staticClass:"line-number"},[s._v("52")]),n("br"),n("span",{staticClass:"line-number"},[s._v("53")]),n("br"),n("span",{staticClass:"line-number"},[s._v("54")]),n("br"),n("span",{staticClass:"line-number"},[s._v("55")]),n("br"),n("span",{staticClass:"line-number"},[s._v("56")]),n("br"),n("span",{staticClass:"line-number"},[s._v("57")]),n("br"),n("span",{staticClass:"line-number"},[s._v("58")]),n("br"),n("span",{staticClass:"line-number"},[s._v("59")]),n("br"),n("span",{staticClass:"line-number"},[s._v("60")]),n("br"),n("span",{staticClass:"line-number"},[s._v("61")]),n("br"),n("span",{staticClass:"line-number"},[s._v("62")]),n("br"),n("span",{staticClass:"line-number"},[s._v("63")]),n("br"),n("span",{staticClass:"line-number"},[s._v("64")]),n("br"),n("span",{staticClass:"line-number"},[s._v("65")]),n("br"),n("span",{staticClass:"line-number"},[s._v("66")]),n("br"),n("span",{staticClass:"line-number"},[s._v("67")]),n("br"),n("span",{staticClass:"line-number"},[s._v("68")]),n("br"),n("span",{staticClass:"line-number"},[s._v("69")]),n("br"),n("span",{staticClass:"line-number"},[s._v("70")]),n("br"),n("span",{staticClass:"line-number"},[s._v("71")]),n("br"),n("span",{staticClass:"line-number"},[s._v("72")]),n("br"),n("span",{staticClass:"line-number"},[s._v("73")]),n("br"),n("span",{staticClass:"line-number"},[s._v("74")]),n("br"),n("span",{staticClass:"line-number"},[s._v("75")]),n("br"),n("span",{staticClass:"line-number"},[s._v("76")]),n("br"),n("span",{staticClass:"line-number"},[s._v("77")]),n("br"),n("span",{staticClass:"line-number"},[s._v("78")]),n("br"),n("span",{staticClass:"line-number"},[s._v("79")]),n("br"),n("span",{staticClass:"line-number"},[s._v("80")]),n("br"),n("span",{staticClass:"line-number"},[s._v("81")]),n("br"),n("span",{staticClass:"line-number"},[s._v("82")]),n("br"),n("span",{staticClass:"line-number"},[s._v("83")]),n("br"),n("span",{staticClass:"line-number"},[s._v("84")]),n("br"),n("span",{staticClass:"line-number"},[s._v("85")]),n("br"),n("span",{staticClass:"line-number"},[s._v("86")]),n("br"),n("span",{staticClass:"line-number"},[s._v("87")]),n("br"),n("span",{staticClass:"line-number"},[s._v("88")]),n("br"),n("span",{staticClass:"line-number"},[s._v("89")]),n("br"),n("span",{staticClass:"line-number"},[s._v("90")]),n("br"),n("span",{staticClass:"line-number"},[s._v("91")]),n("br"),n("span",{staticClass:"line-number"},[s._v("92")]),n("br"),n("span",{staticClass:"line-number"},[s._v("93")]),n("br"),n("span",{staticClass:"line-number"},[s._v("94")]),n("br"),n("span",{staticClass:"line-number"},[s._v("95")]),n("br"),n("span",{staticClass:"line-number"},[s._v("96")]),n("br"),n("span",{staticClass:"line-number"},[s._v("97")]),n("br"),n("span",{staticClass:"line-number"},[s._v("98")]),n("br"),n("span",{staticClass:"line-number"},[s._v("99")]),n("br"),n("span",{staticClass:"line-number"},[s._v("100")]),n("br"),n("span",{staticClass:"line-number"},[s._v("101")]),n("br"),n("span",{staticClass:"line-number"},[s._v("102")]),n("br"),n("span",{staticClass:"line-number"},[s._v("103")]),n("br"),n("span",{staticClass:"line-number"},[s._v("104")]),n("br"),n("span",{staticClass:"line-number"},[s._v("105")]),n("br"),n("span",{staticClass:"line-number"},[s._v("106")]),n("br"),n("span",{staticClass:"line-number"},[s._v("107")]),n("br"),n("span",{staticClass:"line-number"},[s._v("108")]),n("br"),n("span",{staticClass:"line-number"},[s._v("109")]),n("br"),n("span",{staticClass:"line-number"},[s._v("110")]),n("br"),n("span",{staticClass:"line-number"},[s._v("111")]),n("br"),n("span",{staticClass:"line-number"},[s._v("112")]),n("br"),n("span",{staticClass:"line-number"},[s._v("113")]),n("br"),n("span",{staticClass:"line-number"},[s._v("114")]),n("br"),n("span",{staticClass:"line-number"},[s._v("115")]),n("br"),n("span",{staticClass:"line-number"},[s._v("116")]),n("br"),n("span",{staticClass:"line-number"},[s._v("117")]),n("br"),n("span",{staticClass:"line-number"},[s._v("118")]),n("br"),n("span",{staticClass:"line-number"},[s._v("119")]),n("br"),n("span",{staticClass:"line-number"},[s._v("120")]),n("br"),n("span",{staticClass:"line-number"},[s._v("121")]),n("br"),n("span",{staticClass:"line-number"},[s._v("122")]),n("br"),n("span",{staticClass:"line-number"},[s._v("123")]),n("br"),n("span",{staticClass:"line-number"},[s._v("124")]),n("br"),n("span",{staticClass:"line-number"},[s._v("125")]),n("br"),n("span",{staticClass:"line-number"},[s._v("126")]),n("br"),n("span",{staticClass:"line-number"},[s._v("127")]),n("br"),n("span",{staticClass:"line-number"},[s._v("128")]),n("br"),n("span",{staticClass:"line-number"},[s._v("129")]),n("br"),n("span",{staticClass:"line-number"},[s._v("130")]),n("br"),n("span",{staticClass:"line-number"},[s._v("131")]),n("br"),n("span",{staticClass:"line-number"},[s._v("132")]),n("br"),n("span",{staticClass:"line-number"},[s._v("133")]),n("br"),n("span",{staticClass:"line-number"},[s._v("134")]),n("br"),n("span",{staticClass:"line-number"},[s._v("135")]),n("br"),n("span",{staticClass:"line-number"},[s._v("136")]),n("br"),n("span",{staticClass:"line-number"},[s._v("137")]),n("br"),n("span",{staticClass:"line-number"},[s._v("138")]),n("br"),n("span",{staticClass:"line-number"},[s._v("139")]),n("br"),n("span",{staticClass:"line-number"},[s._v("140")]),n("br"),n("span",{staticClass:"line-number"},[s._v("141")]),n("br"),n("span",{staticClass:"line-number"},[s._v("142")]),n("br"),n("span",{staticClass:"line-number"},[s._v("143")]),n("br"),n("span",{staticClass:"line-number"},[s._v("144")]),n("br"),n("span",{staticClass:"line-number"},[s._v("145")]),n("br"),n("span",{staticClass:"line-number"},[s._v("146")]),n("br"),n("span",{staticClass:"line-number"},[s._v("147")]),n("br"),n("span",{staticClass:"line-number"},[s._v("148")]),n("br"),n("span",{staticClass:"line-number"},[s._v("149")]),n("br"),n("span",{staticClass:"line-number"},[s._v("150")]),n("br"),n("span",{staticClass:"line-number"},[s._v("151")]),n("br"),n("span",{staticClass:"line-number"},[s._v("152")]),n("br"),n("span",{staticClass:"line-number"},[s._v("153")]),n("br"),n("span",{staticClass:"line-number"},[s._v("154")]),n("br"),n("span",{staticClass:"line-number"},[s._v("155")]),n("br"),n("span",{staticClass:"line-number"},[s._v("156")]),n("br"),n("span",{staticClass:"line-number"},[s._v("157")]),n("br"),n("span",{staticClass:"line-number"},[s._v("158")]),n("br"),n("span",{staticClass:"line-number"},[s._v("159")]),n("br"),n("span",{staticClass:"line-number"},[s._v("160")]),n("br"),n("span",{staticClass:"line-number"},[s._v("161")]),n("br"),n("span",{staticClass:"line-number"},[s._v("162")]),n("br"),n("span",{staticClass:"line-number"},[s._v("163")]),n("br"),n("span",{staticClass:"line-number"},[s._v("164")]),n("br"),n("span",{staticClass:"line-number"},[s._v("165")]),n("br"),n("span",{staticClass:"line-number"},[s._v("166")]),n("br"),n("span",{staticClass:"line-number"},[s._v("167")]),n("br"),n("span",{staticClass:"line-number"},[s._v("168")]),n("br"),n("span",{staticClass:"line-number"},[s._v("169")]),n("br"),n("span",{staticClass:"line-number"},[s._v("170")]),n("br"),n("span",{staticClass:"line-number"},[s._v("171")]),n("br"),n("span",{staticClass:"line-number"},[s._v("172")]),n("br"),n("span",{staticClass:"line-number"},[s._v("173")]),n("br"),n("span",{staticClass:"line-number"},[s._v("174")]),n("br"),n("span",{staticClass:"line-number"},[s._v("175")]),n("br"),n("span",{staticClass:"line-number"},[s._v("176")]),n("br"),n("span",{staticClass:"line-number"},[s._v("177")]),n("br"),n("span",{staticClass:"line-number"},[s._v("178")]),n("br")])])])]),s._v(" "),n("h2",{attrs:{id:"什么是观察者模式-如何实现-应用场景"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#什么是观察者模式-如何实现-应用场景"}},[s._v("#")]),s._v(" 什么是观察者模式?如何实现?应用场景?")]),s._v(" "),n("p",[n("strong",[s._v("面试高频指数:★★★☆☆")])]),s._v(" "),n("p",[s._v("**观察者模式:**定义一种一(被观察类)对多(观察类)的关系,让多个观察对象同时监听一个被观察对象,被观察对象状态发生变化时,会通知所有的观察对象,使他们能够更新自己的状态。")]),s._v(" "),n("p",[n("strong",[s._v("观察者模式中存在两种角色:")])]),s._v(" "),n("ul",[n("li",[s._v("观察者:内部包含被观察者对象,当被观察者对象的状态发生变化时,更新自己的状态。(接收通知更新状态)")]),s._v(" "),n("li",[s._v("被观察者:内部包含了所有观察者对象,当状态发生变化时通知所有的观察者更新自己的状态。(发送通知)")])]),s._v(" "),n("p",[n("strong",[s._v("应用场景:")])]),s._v(" "),n("ul",[n("li",[n("p",[s._v("当一个对象的改变需要同时改变其他对象,且不知道具体有多少对象有待改变时,应该考虑使用观察者模式;")])]),s._v(" "),n("li",[n("p",[s._v("一个抽象模型有两个方面,其中一方面依赖于另一方面,这时可以用观察者模式将这两者封装在独立的对象中使它们各自独立地改变和复用。")])])]),s._v(" "),n("p",[n("strong",[s._v("实现方式:")])]),s._v(" "),n("div",{staticClass:"language-c++ line-numbers-mode"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[s._v('#include \n#include \n#include \nusing namespace std;\n\nclass Subject;\n//观察者 基类 (内部实例化了被观察者的对象sub)\nclass Observer\n{\nprotected:\n string name;\n Subject *sub;\n\npublic:\n Observer(string name, Subject *sub)\n {\n this->name = name;\n this->sub = sub;\n }\n virtual void update() = 0;\n};\n\nclass StockObserver : public Observer\n{\npublic:\n StockObserver(string name, Subject *sub) : Observer(name, sub)\n {\n }\n void update();\n};\n\nclass NBAObserver : public Observer\n{\npublic:\n NBAObserver(string name, Subject *sub) : Observer(name, sub)\n {\n }\n void update();\n};\n//被观察者 基类 (内部存放了所有的观察者对象,以便状态发生变化时,给观察者发通知)\nclass Subject\n{\nprotected:\n list observers;\n\npublic:\n string action; //被观察者对象的状态\n virtual void attach(Observer *) = 0;\n virtual void detach(Observer *) = 0;\n virtual void notify() = 0;\n};\n\nclass Secretary : public Subject\n{\n void attach(Observer *observer)\n {\n observers.push_back(observer);\n }\n void detach(Observer *observer)\n {\n list::iterator iter = observers.begin();\n while (iter != observers.end())\n {\n if ((*iter) == observer)\n {\n observers.erase(iter);\n return;\n }\n ++iter;\n }\n }\n void notify()\n {\n list::iterator iter = observers.begin();\n while (iter != observers.end())\n {\n (*iter)->update();\n ++iter;\n }\n }\n};\n\nvoid StockObserver::update()\n{\n cout << name << " 收到消息:" << sub->action << endl;\n if (sub->action == "梁所长来了!")\n {\n cout << "我马上关闭股票,装做很认真工作的样子!" << endl;\n }\n}\n\nvoid NBAObserver::update()\n{\n cout << name << " 收到消息:" << sub->action << endl;\n if (sub->action == "梁所长来了!")\n {\n cout << "我马上关闭NBA,装做很认真工作的样子!" << endl;\n }\n}\n\nint main()\n{\n Subject *dwq = new Secretary();\n Observer *xs = new NBAObserver("xiaoshuai", dwq);\n Observer *zy = new NBAObserver("zouyue", dwq);\n Observer *lm = new StockObserver("limin", dwq);\n\n dwq->attach(xs);\n dwq->attach(zy);\n dwq->attach(lm);\n\n dwq->action = "去吃饭了!";\n dwq->notify();\n cout << endl;\n dwq->action = "梁所长来了!";\n dwq->notify();\n return 0;\n}\n')])]),s._v(" "),n("div",{staticClass:"line-numbers-wrapper"},[n("span",{staticClass:"line-number"},[s._v("1")]),n("br"),n("span",{staticClass:"line-number"},[s._v("2")]),n("br"),n("span",{staticClass:"line-number"},[s._v("3")]),n("br"),n("span",{staticClass:"line-number"},[s._v("4")]),n("br"),n("span",{staticClass:"line-number"},[s._v("5")]),n("br"),n("span",{staticClass:"line-number"},[s._v("6")]),n("br"),n("span",{staticClass:"line-number"},[s._v("7")]),n("br"),n("span",{staticClass:"line-number"},[s._v("8")]),n("br"),n("span",{staticClass:"line-number"},[s._v("9")]),n("br"),n("span",{staticClass:"line-number"},[s._v("10")]),n("br"),n("span",{staticClass:"line-number"},[s._v("11")]),n("br"),n("span",{staticClass:"line-number"},[s._v("12")]),n("br"),n("span",{staticClass:"line-number"},[s._v("13")]),n("br"),n("span",{staticClass:"line-number"},[s._v("14")]),n("br"),n("span",{staticClass:"line-number"},[s._v("15")]),n("br"),n("span",{staticClass:"line-number"},[s._v("16")]),n("br"),n("span",{staticClass:"line-number"},[s._v("17")]),n("br"),n("span",{staticClass:"line-number"},[s._v("18")]),n("br"),n("span",{staticClass:"line-number"},[s._v("19")]),n("br"),n("span",{staticClass:"line-number"},[s._v("20")]),n("br"),n("span",{staticClass:"line-number"},[s._v("21")]),n("br"),n("span",{staticClass:"line-number"},[s._v("22")]),n("br"),n("span",{staticClass:"line-number"},[s._v("23")]),n("br"),n("span",{staticClass:"line-number"},[s._v("24")]),n("br"),n("span",{staticClass:"line-number"},[s._v("25")]),n("br"),n("span",{staticClass:"line-number"},[s._v("26")]),n("br"),n("span",{staticClass:"line-number"},[s._v("27")]),n("br"),n("span",{staticClass:"line-number"},[s._v("28")]),n("br"),n("span",{staticClass:"line-number"},[s._v("29")]),n("br"),n("span",{staticClass:"line-number"},[s._v("30")]),n("br"),n("span",{staticClass:"line-number"},[s._v("31")]),n("br"),n("span",{staticClass:"line-number"},[s._v("32")]),n("br"),n("span",{staticClass:"line-number"},[s._v("33")]),n("br"),n("span",{staticClass:"line-number"},[s._v("34")]),n("br"),n("span",{staticClass:"line-number"},[s._v("35")]),n("br"),n("span",{staticClass:"line-number"},[s._v("36")]),n("br"),n("span",{staticClass:"line-number"},[s._v("37")]),n("br"),n("span",{staticClass:"line-number"},[s._v("38")]),n("br"),n("span",{staticClass:"line-number"},[s._v("39")]),n("br"),n("span",{staticClass:"line-number"},[s._v("40")]),n("br"),n("span",{staticClass:"line-number"},[s._v("41")]),n("br"),n("span",{staticClass:"line-number"},[s._v("42")]),n("br"),n("span",{staticClass:"line-number"},[s._v("43")]),n("br"),n("span",{staticClass:"line-number"},[s._v("44")]),n("br"),n("span",{staticClass:"line-number"},[s._v("45")]),n("br"),n("span",{staticClass:"line-number"},[s._v("46")]),n("br"),n("span",{staticClass:"line-number"},[s._v("47")]),n("br"),n("span",{staticClass:"line-number"},[s._v("48")]),n("br"),n("span",{staticClass:"line-number"},[s._v("49")]),n("br"),n("span",{staticClass:"line-number"},[s._v("50")]),n("br"),n("span",{staticClass:"line-number"},[s._v("51")]),n("br"),n("span",{staticClass:"line-number"},[s._v("52")]),n("br"),n("span",{staticClass:"line-number"},[s._v("53")]),n("br"),n("span",{staticClass:"line-number"},[s._v("54")]),n("br"),n("span",{staticClass:"line-number"},[s._v("55")]),n("br"),n("span",{staticClass:"line-number"},[s._v("56")]),n("br"),n("span",{staticClass:"line-number"},[s._v("57")]),n("br"),n("span",{staticClass:"line-number"},[s._v("58")]),n("br"),n("span",{staticClass:"line-number"},[s._v("59")]),n("br"),n("span",{staticClass:"line-number"},[s._v("60")]),n("br"),n("span",{staticClass:"line-number"},[s._v("61")]),n("br"),n("span",{staticClass:"line-number"},[s._v("62")]),n("br"),n("span",{staticClass:"line-number"},[s._v("63")]),n("br"),n("span",{staticClass:"line-number"},[s._v("64")]),n("br"),n("span",{staticClass:"line-number"},[s._v("65")]),n("br"),n("span",{staticClass:"line-number"},[s._v("66")]),n("br"),n("span",{staticClass:"line-number"},[s._v("67")]),n("br"),n("span",{staticClass:"line-number"},[s._v("68")]),n("br"),n("span",{staticClass:"line-number"},[s._v("69")]),n("br"),n("span",{staticClass:"line-number"},[s._v("70")]),n("br"),n("span",{staticClass:"line-number"},[s._v("71")]),n("br"),n("span",{staticClass:"line-number"},[s._v("72")]),n("br"),n("span",{staticClass:"line-number"},[s._v("73")]),n("br"),n("span",{staticClass:"line-number"},[s._v("74")]),n("br"),n("span",{staticClass:"line-number"},[s._v("75")]),n("br"),n("span",{staticClass:"line-number"},[s._v("76")]),n("br"),n("span",{staticClass:"line-number"},[s._v("77")]),n("br"),n("span",{staticClass:"line-number"},[s._v("78")]),n("br"),n("span",{staticClass:"line-number"},[s._v("79")]),n("br"),n("span",{staticClass:"line-number"},[s._v("80")]),n("br"),n("span",{staticClass:"line-number"},[s._v("81")]),n("br"),n("span",{staticClass:"line-number"},[s._v("82")]),n("br"),n("span",{staticClass:"line-number"},[s._v("83")]),n("br"),n("span",{staticClass:"line-number"},[s._v("84")]),n("br"),n("span",{staticClass:"line-number"},[s._v("85")]),n("br"),n("span",{staticClass:"line-number"},[s._v("86")]),n("br"),n("span",{staticClass:"line-number"},[s._v("87")]),n("br"),n("span",{staticClass:"line-number"},[s._v("88")]),n("br"),n("span",{staticClass:"line-number"},[s._v("89")]),n("br"),n("span",{staticClass:"line-number"},[s._v("90")]),n("br"),n("span",{staticClass:"line-number"},[s._v("91")]),n("br"),n("span",{staticClass:"line-number"},[s._v("92")]),n("br"),n("span",{staticClass:"line-number"},[s._v("93")]),n("br"),n("span",{staticClass:"line-number"},[s._v("94")]),n("br"),n("span",{staticClass:"line-number"},[s._v("95")]),n("br"),n("span",{staticClass:"line-number"},[s._v("96")]),n("br"),n("span",{staticClass:"line-number"},[s._v("97")]),n("br"),n("span",{staticClass:"line-number"},[s._v("98")]),n("br"),n("span",{staticClass:"line-number"},[s._v("99")]),n("br"),n("span",{staticClass:"line-number"},[s._v("100")]),n("br"),n("span",{staticClass:"line-number"},[s._v("101")]),n("br"),n("span",{staticClass:"line-number"},[s._v("102")]),n("br"),n("span",{staticClass:"line-number"},[s._v("103")]),n("br"),n("span",{staticClass:"line-number"},[s._v("104")]),n("br"),n("span",{staticClass:"line-number"},[s._v("105")]),n("br"),n("span",{staticClass:"line-number"},[s._v("106")]),n("br"),n("span",{staticClass:"line-number"},[s._v("107")]),n("br"),n("span",{staticClass:"line-number"},[s._v("108")]),n("br"),n("span",{staticClass:"line-number"},[s._v("109")]),n("br"),n("span",{staticClass:"line-number"},[s._v("110")]),n("br"),n("span",{staticClass:"line-number"},[s._v("111")]),n("br"),n("span",{staticClass:"line-number"},[s._v("112")]),n("br"),n("span",{staticClass:"line-number"},[s._v("113")]),n("br"),n("span",{staticClass:"line-number"},[s._v("114")]),n("br"),n("span",{staticClass:"line-number"},[s._v("115")]),n("br"),n("span",{staticClass:"line-number"},[s._v("116")]),n("br"),n("span",{staticClass:"line-number"},[s._v("117")]),n("br"),n("span",{staticClass:"line-number"},[s._v("118")]),n("br")])]),n("p",[s._v("参考资料\n该 LeetBook 参考《Effective C++》、《More Effective C++》、《Effective C++》、《Visual C++ 代码参考与技巧大全》、《STL》源码剖析、《大话设计模式》、《设计模式:可复用面向对象软件的基础》整理。")])])}),[],!1,null,null,null);n.default=t.exports}}]); \ No newline at end of file diff --git a/assets/js/78.76a0e76b.js b/assets/js/78.76a0e76b.js new file mode 100644 index 0000000000..348e498199 --- /dev/null +++ b/assets/js/78.76a0e76b.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[78],{404:function(e,r,s){"use strict";s.r(r);var t=s(4),n=Object(t.a)({},(function(){var e=this,r=e._self._c;return r("ContentSlotsDistributor",{attrs:{"slot-key":e.$parent.slotKey}},[r("h2",{attrs:{id:"博客前言"}},[r("a",{staticClass:"header-anchor",attrs:{href:"#博客前言"}},[e._v("#")]),e._v(" 博客前言")]),e._v(" "),r("div",{staticClass:"custom-block tip"},[r("p",{staticClass:"custom-block-title"},[e._v("提示")]),e._v(" "),r("p",[e._v("笔者的博客涉及到如下支持")]),e._v(" "),r("ul",[r("li",[r("a",{attrs:{href:"https://blog.svend.cc/upic/",target:"_blank",rel:"noopener noreferrer"}},[e._v("upic"),r("OutboundLink")],1),e._v(": 提供图床功能")]),e._v(" "),r("li",[r("code",[e._v("vscode")]),e._v(": IDE 工具")]),e._v(" "),r("li",[r("a",{attrs:{href:"https://pages.github.com/",target:"_blank",rel:"noopener noreferrer"}},[e._v("github-pages"),r("OutboundLink")],1),e._v(": 发布博客")]),e._v(" "),r("li",[r("a",{attrs:{href:"http://iconfont.cn/",target:"_blank",rel:"noopener noreferrer"}},[e._v("iconfont"),r("OutboundLink")],1),e._v(": Iconfont(阿里巴巴矢量图标库), 博客中图标的主要来源")]),e._v(" "),r("li",[r("a",{attrs:{href:"https://vssue.js.org/",target:"_blank",rel:"noopener noreferrer"}},[e._v("Vssue"),r("OutboundLink")],1),e._v(": 评论支持, Enable comments support for static pages, based on the issue system of code hosting services.\n"),r("ul",[r("li",[r("a",{attrs:{href:"https://vssue.js.org/guide/vuepress.html#vuepress-plugin",target:"_blank",rel:"noopener noreferrer"}},[e._v("vuepress-plugin"),r("OutboundLink")],1)])])])]),e._v(" "),r("p",[e._v("另外需要对 github action, api 等需要了解相关的文档链接:")]),e._v(" "),r("ul",[r("li",[r("a",{attrs:{href:"https://docs.github.com/en",target:"_blank",rel:"noopener noreferrer"}},[e._v("github-docs"),r("OutboundLink")],1)]),e._v(" "),r("li",[r("a",{attrs:{href:"https://docs.github.com/zh",target:"_blank",rel:"noopener noreferrer"}},[e._v("github-docs-zh"),r("OutboundLink")],1)]),e._v(" "),r("li",[r("a",{attrs:{href:"https://docs.github.com/en/actions/quickstart",target:"_blank",rel:"noopener noreferrer"}},[e._v("actions"),r("OutboundLink")],1)])])]),e._v(" "),r("h2",{attrs:{id:"快速构建个人网站的一些方案"}},[r("a",{staticClass:"header-anchor",attrs:{href:"#快速构建个人网站的一些方案"}},[e._v("#")]),e._v(" 快速构建个人网站的一些方案")]),e._v(" "),r("p",[e._v("以下是几种快速构建个人网站的方案:")]),e._v(" "),r("ul",[r("li",[r("p",[e._v("使用网站建设平台:可以使用一些网站建设平台(例如 Wix、Squarespace、WordPress 等)来快速构建自己的个人网站。这些平台提供了丰富的模板和设计工具,使用户能够在不需要编写代码的情况下创建一个美观、功能丰富的网站。")])]),e._v(" "),r("li",[r("p",[e._v("使用静态网站生成器:静态网站生成器是一种工具,可以将 Markdown 或其他格式的文本文件转换成静态 HTML 文件。Jekyll、Hugo 和 Gatsby 等工具是一些受欢迎的静态网站生成器,它们提供了丰富的主题和插件,可以轻松创建具有不同风格的个人网站。")])]),e._v(" "),r("li",[r("p",[e._v("使用云主机和域名:如果您具有一定的技术背景和经验,可以选择购买云主机和域名,并自行搭建个人网站。这需要您具有一定的技术知识,并熟悉 Web 开发相关技术,如 HTML、CSS、JavaScript 等。")])])]),e._v(" "),r("p",[e._v("无论选择哪种方案,都应该确保您的个人网站易于导航、易于使用,并包含您的重要信息、作品和联系方式。")]),e._v(" "),r("h3",{attrs:{id:"hugo-vs-vuepress"}},[r("a",{staticClass:"header-anchor",attrs:{href:"#hugo-vs-vuepress"}},[e._v("#")]),e._v(" HUGO vs Vuepress")]),e._v(" "),r("p",[e._v("Hugo 和 VuePress 都是非常流行的静态网站生成器,它们都可以用来构建快速、高效的静态网站。下面是一些比较它们的主要区别:")]),e._v(" "),r("ul",[r("li",[r("p",[e._v("技术栈:Hugo 是基于 Go 语言编写的,而 VuePress 则是基于 Vue.js 构建的。这意味着如果您已经熟悉这些技术栈,那么选择哪个工具可能会更有优势。")])]),e._v(" "),r("li",[r("p",[e._v("定制性:Hugo 和 VuePress 都提供了很多主题和插件,可以帮助您快速创建一个漂亮的网站。然而,Hugo 的主题库更加丰富,而且对于一些特定的需求,比如对多语言的支持,Hugo 也更加容易定制。")])]),e._v(" "),r("li",[r("p",[e._v("功能:VuePress 在构建单页应用程序(SPA)方面表现出色,可以创建具有复杂交互和动画效果的网站。相比之下,Hugo 更适合构建博客、文档和其他静态网站。")])]),e._v(" "),r("li",[r("p",[e._v("性能:Hugo 的构建速度非常快,生成的静态页面也非常小巧,因此它可以提供非常出色的性能和可扩展性。VuePress 的性能也不错,但在处理大量页面时可能会稍微慢一些。")])])]),e._v(" "),r("p",[e._v("总之,如果您需要一个快速构建博客、文档或其他静态网站的工具,Hugo 是一个非常不错的选择。如果您需要构建具有复杂交互和动画效果的单页应用程序,或者您更熟悉 Vue.js 技术栈,那么 VuePress 可能更适合您。")]),e._v(" "),r("h2",{attrs:{id:"使用-vuepress-构建自己的个人网站"}},[r("a",{staticClass:"header-anchor",attrs:{href:"#使用-vuepress-构建自己的个人网站"}},[e._v("#")]),e._v(" 使用 vuepress 构建自己的个人网站")]),e._v(" "),r("p",[e._v("使用 VuePress 构建自己的个人网站需要以下步骤:")]),e._v(" "),r("ul",[r("li",[r("p",[e._v("安装 Node.js:VuePress 是基于 Node.js 构建的,因此您需要在计算机上安装 Node.js。您可以在 Node.js 官方网站上下载适合您操作系统的版本并安装。")])]),e._v(" "),r("li",[r("p",[e._v("创建 VuePress 项目:使用 VuePress 需要先创建一个项目,可以通过以下 "),r("a",{attrs:{href:"https://www.npmjs.com/package/create-vuepress-site",target:"_blank",rel:"noopener noreferrer"}},[e._v("create-vuepress-site"),r("OutboundLink")],1),e._v(" 命令在命令行中创建一个新的 VuePress 项目:")])])]),e._v(" "),r("div",{staticClass:"language-shell line-numbers-mode"},[r("pre",{pre:!0,attrs:{class:"language-shell"}},[r("code",[e._v("npx create-vuepress-site your-site-name\n")])]),e._v(" "),r("div",{staticClass:"line-numbers-wrapper"},[r("span",{staticClass:"line-number"},[e._v("1")]),r("br")])]),r("p",[e._v("这将创建一个名为 your-site-name 的新目录,其中包含 VuePress 的初始文件和目录。")]),e._v(" "),r("ul",[r("li",[r("p",[e._v("编辑配置文件:VuePress 项目有一个 config.js 文件,您可以在其中配置网站的标题、描述、主题、导航等等。在该文件中,您还可以定义页面和博客文章的路由和布局。")])]),e._v(" "),r("li",[r("p",[e._v("创建页面和文章:您可以在 VuePress 项目的 docs 目录下创建 Markdown 文件来编写页面和博客文章。这些 Markdown 文件将被转换为静态 HTML 页面,并作为网站的内容呈现。")])]),e._v(" "),r("li",[r("p",[e._v("本地预览:在编辑好您的网站内容后,您可以使用以下命令在本地启动一个 VuePress 服务器来预览您的网站:")])])]),e._v(" "),r("div",{staticClass:"language-shell line-numbers-mode"},[r("pre",{pre:!0,attrs:{class:"language-shell"}},[r("code",[r("span",{pre:!0,attrs:{class:"token function"}},[e._v("npm")]),e._v(" run docs:dev\n")])]),e._v(" "),r("div",{staticClass:"line-numbers-wrapper"},[r("span",{staticClass:"line-number"},[e._v("1")]),r("br")])]),r("p",[e._v("运行该命令后,您可以在浏览器中访问 "),r("a",{attrs:{href:"http://localhost:8080/",target:"_blank",rel:"noopener noreferrer"}},[e._v("http://localhost:8080/"),r("OutboundLink")],1),e._v(" 来查看您的网站。")]),e._v(" "),r("ul",[r("li",[e._v("构建和部署:当您满意于您的网站后,您可以使用以下命令构建一个静态的 VuePress 网站:")])]),e._v(" "),r("div",{staticClass:"language-shell line-numbers-mode"},[r("pre",{pre:!0,attrs:{class:"language-shell"}},[r("code",[r("span",{pre:!0,attrs:{class:"token function"}},[e._v("npm")]),e._v(" run docs:build\n")])]),e._v(" "),r("div",{staticClass:"line-numbers-wrapper"},[r("span",{staticClass:"line-number"},[e._v("1")]),r("br")])]),r("p",[e._v("运行该命令后,VuePress 将生成一个 dist 目录,其中包含您的网站的静态 HTML 页面和其他资源。您可以将该目录中的内容部署到您的服务器或者使用 GitHub Pages 等免费托管服务。")]),e._v(" "),r("p",[e._v("以上是使用 VuePress 构建个人网站的基本步骤,您可以根据您的需求进一步定制和扩展您的网站。")]),e._v(" "),r("h2",{attrs:{id:"参考"}},[r("a",{staticClass:"header-anchor",attrs:{href:"#参考"}},[e._v("#")]),e._v(" 参考")]),e._v(" "),r("ul",[r("li",[r("a",{attrs:{href:"https://vuepress.vuejs.org/zh/guide/getting-started.html",target:"_blank",rel:"noopener noreferrer"}},[e._v("vuepress-cn"),r("OutboundLink")],1)]),e._v(" "),r("li",[r("a",{attrs:{href:"https://vuepress.vuejs.org/",target:"_blank",rel:"noopener noreferrer"}},[e._v("vuepress"),r("OutboundLink")],1),e._v(" "),r("ul",[r("li",[e._v("源码解析"),r("a",{attrs:{href:"https://juejin.cn/post/6917643530588389390",target:"_blank",rel:"noopener noreferrer"}},[e._v("https://juejin.cn/post/6917643530588389390"),r("OutboundLink")],1)])])]),e._v(" "),r("li",[r("a",{attrs:{href:"https://github.com/xugaoyi/vuepress-theme-vdoing",target:"_blank",rel:"noopener noreferrer"}},[e._v("vdoing 主题"),r("OutboundLink")],1),e._v(" "),r("ul",[r("li",[e._v("fork "),r("a",{attrs:{href:"https://github.com/jacky1234/vuepress-theme-vdoing.git",target:"_blank",rel:"noopener noreferrer"}},[e._v("https://github.com/jacky1234/vuepress-theme-vdoing.git"),r("OutboundLink")],1)]),e._v(" "),r("li",[e._v("主题使用 "),r("a",{attrs:{href:"https://doc.xugaoyi.com/",target:"_blank",rel:"noopener noreferrer"}},[e._v("https://doc.xugaoyi.com/"),r("OutboundLink")],1)])])]),e._v(" "),r("li",[r("a",{attrs:{href:"https://github.com/shfshanyue/Daily-Question/tree/master",target:"_blank",rel:"noopener noreferrer"}},[e._v("Daily-Question*"),r("OutboundLink")],1)]),e._v(" "),r("li",[e._v("plugins\n"),r("ul",[r("li",[e._v("vuepress-plugin-auto-sidebar: "),r("a",{attrs:{href:"https://github.com/shanyuhai123/vuepress-plugin-auto-sidebar.git",target:"_blank",rel:"noopener noreferrer"}},[e._v("https://github.com/shanyuhai123/vuepress-plugin-auto-sidebar.git"),r("OutboundLink")],1)])])]),e._v(" "),r("li",[e._v("theme:\n"),r("ul",[r("li",[r("a",{attrs:{href:"https://github.com/search?q=vuepress-theme-%22&type=repositoriess",target:"_blank",rel:"noopener noreferrer"}},[e._v("github 搜索结果"),r("OutboundLink")],1)])])]),e._v(" "),r("li",[e._v("案例页面\n"),r("ul",[r("li",[r("a",{attrs:{href:"https://github.com/xugaoyi/vuepress-theme-vdoing/issues/537",target:"_blank",rel:"noopener noreferrer"}},[e._v("https://github.com/xugaoyi/vuepress-theme-vdoing/issues/537"),r("OutboundLink")],1)])])])])])}),[],!1,null,null,null);r.default=n.exports}}]); \ No newline at end of file diff --git a/assets/js/79.93272048.js b/assets/js/79.93272048.js new file mode 100644 index 0000000000..a6806831f5 --- /dev/null +++ b/assets/js/79.93272048.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[79],{405:function(t,s,e){"use strict";e.r(s);var a=e(4),r=Object(a.a)({},(function(){var t=this,s=t._self._c;return s("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[s("h2",{attrs:{id:"如何学"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#如何学"}},[t._v("#")]),t._v(" 如何学")]),t._v(" "),s("p",[t._v("以下是学习 VuePress 的一些网站地址:")]),t._v(" "),s("ul",[s("li",[t._v("VuePress 官方文档:"),s("a",{attrs:{href:"https://vuepress.vuejs.org/zh/",target:"_blank",rel:"noopener noreferrer"}},[t._v("https://vuepress.vuejs.org/zh/"),s("OutboundLink")],1)]),t._v(" "),s("li",[t._v("VuePress 官方示例仓库:"),s("a",{attrs:{href:"https://github.com/vuepressjs/vuepress-examples",target:"_blank",rel:"noopener noreferrer"}},[t._v("https://github.com/vuepressjs/vuepress-examples"),s("OutboundLink")],1)]),t._v(" "),s("li",[t._v("VuePress 插件列表:"),s("a",{attrs:{href:"https://vuepress-plugin.qingwei.tech/",target:"_blank",rel:"noopener noreferrer"}},[t._v("https://vuepress-plugin.qingwei.tech/"),s("OutboundLink")],1)]),t._v(" "),s("li",[t._v("VuePress 中文文档网站源码:"),s("a",{attrs:{href:"https://github.com/docschina/vuepress.vuejs.org",target:"_blank",rel:"noopener noreferrer"}},[t._v("https://github.com/docschina/vuepress.vuejs.org"),s("OutboundLink")],1)]),t._v(" "),s("li",[t._v("VuePress 官方 GitHub 仓库:"),s("a",{attrs:{href:"https://github.com/vuejs/vuepress",target:"_blank",rel:"noopener noreferrer"}},[t._v("https://github.com/vuejs/vuepress"),s("OutboundLink")],1)])]),t._v(" "),s("p",[t._v("除了上述网站,你还可以在各大搜索引擎中搜索相关的博客文章、视频教程等,来学习 VuePress。同时,VuePress 是建立在 Vue.js 之上的,如果你之前没有学习过 Vue.js,也可以先学习一下 Vue.js 的基础知识,这样对学习 VuePress 也会有帮助。")]),t._v(" "),s("h2",{attrs:{id:"内置对象"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#内置对象"}},[t._v("#")]),t._v(" 内置对象")]),t._v(" "),s("h3",{attrs:{id:"page-对象"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#page-对象"}},[t._v("#")]),t._v(" "),s("code",[t._v("$page")]),t._v(" 对象")]),t._v(" "),s("p",[t._v("$page 对象包含以下属性:")]),t._v(" "),s("ul",[s("li",[t._v("title:当前页面的标题。")]),t._v(" "),s("li",[t._v("description:当前页面的描述。")]),t._v(" "),s("li",[t._v("headers:当前页面的标题层级结构,如 h1、h2、h3 等。")]),t._v(" "),s("li",[t._v("frontmatter:当前页面的元数据,包括 YAML 头部信息和在 Markdown 文件中的 frontmatter 配置块中定义的内容。")]),t._v(" "),s("li",[t._v("lastUpdated:当前页面的最后更新时间。")]),t._v(" "),s("li",[t._v("permalink:当前页面的永久链接。")]),t._v(" "),s("li",[t._v("path:当前页面的相对路径。")]),t._v(" "),s("li",[t._v("regularPath:当前页面的绝对路径,不包括 base 配置项的路径。")]),t._v(" "),s("li",[t._v("key:当前页面的唯一标识符。")]),t._v(" "),s("li",[t._v("raw:当前页面的原始 Markdown 源代码。")])]),t._v(" "),s("h3",{attrs:{id:"contentclass"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#contentclass"}},[t._v("#")]),t._v(" "),s("code",[t._v("$contentClass")])]),t._v(" "),s("p",[t._v("在 VuePress 中,"),s("code",[t._v("{$contentClass}")]),t._v(" 是一个动态类名,它代表的是 Markdown 渲染后的内容容器元素的类名。在 VuePress 中,默认情况下,所有 Markdown 渲染后的内容都会被包含在一个容器元素中,该容器元素的类名就是 $contentClass。因此,使用 $contentClass 选择器来选中该容器元素,可以对渲染后的 Markdown 内容应用样式。")]),t._v(" "),s("p",[t._v("在上述 CSS 定义中,.code 类选择器和 $contentClass 类选择器一起定义了代码块的样式。例如,如果 $contentClass 的值是 markdown-body,则渲染后的 HTML 代码类似于:")]),t._v(" "),s("div",{staticClass:"language-html line-numbers-mode"},[s("pre",{pre:!0,attrs:{class:"language-html"}},[s("code",[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("div")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("class")]),s("span",{pre:!0,attrs:{class:"token attr-value"}},[s("span",{pre:!0,attrs:{class:"token punctuation attr-equals"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')]),t._v("markdown-body"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("pre")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("code")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("class")]),s("span",{pre:!0,attrs:{class:"token attr-value"}},[s("span",{pre:!0,attrs:{class:"token punctuation attr-equals"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')]),t._v("code"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v("..."),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),t._v("\n")])]),t._v(" "),s("div",{staticClass:"line-numbers-wrapper"},[s("span",{staticClass:"line-number"},[t._v("1")]),s("br"),s("span",{staticClass:"line-number"},[t._v("2")]),s("br"),s("span",{staticClass:"line-number"},[t._v("3")]),s("br")])]),s("p",[t._v("其中,markdown-body 是 $contentClass 的一个示例值,实际的值可能会根据不同的 VuePress 主题而不同。")]),t._v(" "),s("p",[t._v("Q:下面解释下 "),s("code",[t._v("
")]),t._v(" 标签")]),t._v(" "),s("p",[t._v("在 HTML 中,"),s("code",[t._v("
")]),t._v(" 标签用于定义预格式化的文本,即文本中的空格和换行符会被保留。通常用于显示计算机代码或其他可预格式化的文本内容。在示例中,"),s("code",[t._v("
")]),t._v("标签的作用是将代码块以预格式化的形式呈现给用户。")]),t._v(" "),s("h3",{attrs:{id:"vuepress-钩子函数-extendpagedata"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#vuepress-钩子函数-extendpagedata"}},[t._v("#")]),t._v(" vuepress 钩子函数: extendPageData")]),t._v(" "),s("p",[t._v("在 VuePress 的插件中,extendPageData 是一个生命周期钩子函数,在编译每一个页面时都会被调用,它接收一个 $page 参数,其中包含了当前页面的许多信息,例如:路径、正文内容、Front Matter 等等。这些信息可以被插件用于对页面进行修改、增强等操作。因此,$page 参数就是在编译当前页面时传入的,是 VuePress 本身定义的。插件通过 extendPageData 来拿到这个 $page 参数,进而进行一些自定义的操作。")])])}),[],!1,null,null,null);s.default=r.exports}}]);
\ No newline at end of file
diff --git a/assets/js/80.da400a7d.js b/assets/js/80.da400a7d.js
new file mode 100644
index 0000000000..85a1e7a623
--- /dev/null
+++ b/assets/js/80.da400a7d.js
@@ -0,0 +1 @@
+(window.webpackJsonp=window.webpackJsonp||[]).push([[80],{406:function(s,t,a){"use strict";a.r(t);var n=a(4),e=Object(n.a)({},(function(){var s=this,t=s._self._c;return t("ContentSlotsDistributor",{attrs:{"slot-key":s.$parent.slotKey}},[t("h1",{attrs:{id:"github-actions-实现自动部署静态博客"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#github-actions-实现自动部署静态博客"}},[s._v("#")]),s._v(" GitHub Actions 实现自动部署静态博客")]),s._v(" "),t("h2",{attrs:{id:"前言"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#前言"}},[s._v("#")]),s._v(" 前言")]),s._v(" "),t("p",[s._v("在使用 vuepress 搭建了一个静态博客后,挂在了 Github pages 和"),t("a",{attrs:{href:"https://dev.tencent.com/",target:"_blank",rel:"noopener noreferrer"}},[s._v("Coding pages"),t("OutboundLink")],1),s._v("上面。")]),s._v(" "),t("p",[s._v("coding pages 在国内的访问速度比 github pages 要快很多,而且还可以被百度收录。")]),s._v(" "),t("p",[s._v("一开始的部署方式是使用"),t("a",{attrs:{href:"https://github.com/jacky1234/publish-web-note/blob/main/deploy.sh",target:"_blank",rel:"noopener noreferrer"}},[s._v("sh 部署脚本"),t("OutboundLink")],1),s._v("把代码提交到这两个平台的仓库分支,虽然已经很方便了,但是我还想把博客未打包的源码提交到 Github 主分支上。这就需要我操作两次命令,"),t("strong",[s._v("我就想能不能只需要一次操作就可以同时把源码、部署代码一次性提交到两个平台呢?")])]),s._v(" "),t("h2",{attrs:{id:"实现"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#实现"}},[s._v("#")]),s._v(" 实现")]),s._v(" "),t("p",[s._v("在了解 GitHub Actions 最近(2019.12)刚正式发布了之后,尝试使用它发现能够满足我的需求。"),t("a",{attrs:{href:"http://www.ruanyifeng.com/blog/2019/09/getting-started-with-github-actions.html?20191227113947#comment-last",target:"_blank",rel:"noopener noreferrer"}},[s._v("GitHub Actions 入门教程"),t("OutboundLink")],1)]),s._v(" "),t("p",[s._v("首先,需要获取 token,后面会用到。获取方法:github 获取 token"),t("a",{attrs:{href:"https://help.github.com/en/articles/creating-a-personal-access-token-for-the-command-line",target:"_blank",rel:"noopener noreferrer"}},[s._v("官方文档"),t("OutboundLink")],1),s._v("、coding 获取 token"),t("a",{attrs:{href:"https://dev.tencent.com/help/doc/account/access-token",target:"_blank",rel:"noopener noreferrer"}},[s._v("官方文档"),t("OutboundLink")],1),s._v("。")]),s._v(" "),t("p",[s._v("然后,将这两个 token 同时储存到 github 仓库的"),t("code",[s._v("Settings/Secrets and variables")]),s._v("里面,关于更多内容可以参考 "),t("a",{attrs:{href:"https://docs.github.com/en/actions/security-guides/encrypted-secrets",target:"_blank",rel:"noopener noreferrer"}},[s._v("security-guides"),t("OutboundLink")],1),s._v(" 。变量名可以随便取,但是注意要和后面的"),t("code",[s._v("ci.yml")]),s._v("文件内的变量名一致,这里取的是"),t("code",[s._v("BLOG_PAGES_ACCESS_KEY")]),s._v("。 此变量的值来源于申请的"),t("code",[s._v("person access token")]),s._v(", 此 token 对仓库 "),t("code",[s._v("https://github.com/jacky1234/blogPages.git")]),s._v(" 具有读权限。")]),s._v(" "),t("p",[s._v("GitHub Actions 的配置文件叫做 workflow 文件,存放在代码仓库的"),t("code",[s._v(".github/workflows")]),s._v("目录。")]),s._v(" "),t("p",[s._v("workflow 文件采用 "),t("code",[s._v("YAML")]),s._v(" 格式,文件名可以任意取,但是后缀名统一为"),t("code",[s._v(".yml")]),s._v(",比如"),t("code",[s._v("ci.yml")]),s._v("。一个库可以有多个 workflow 文件。GitHub 只要发现"),t("code",[s._v(".github/workflows")]),s._v("目录里面有"),t("code",[s._v(".yml")]),s._v("文件,就会自动运行该文件。")]),s._v(" "),t("p",[s._v("我的"),t("code",[s._v("ci.yml")]),s._v("文件:")]),s._v(" "),t("div",{staticClass:"language-yaml line-numbers-mode"},[t("pre",{pre:!0,attrs:{class:"language-yaml"}},[t("code",[t("span",{pre:!0,attrs:{class:"token key atrule"}},[s._v("name")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(":")]),s._v(" CI\n\n"),t("span",{pre:!0,attrs:{class:"token comment"}},[s._v("#on: [push]")]),s._v("\n\n"),t("span",{pre:!0,attrs:{class:"token comment"}},[s._v("# 在master分支发生push事件时触发。")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token key atrule"}},[s._v("on")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(":")]),s._v("\n  "),t("span",{pre:!0,attrs:{class:"token key atrule"}},[s._v("push")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(":")]),s._v("\n    "),t("span",{pre:!0,attrs:{class:"token key atrule"}},[s._v("branches")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(":")]),s._v("\n      "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("-")]),s._v(" main\n      "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("-")]),s._v(" master\n\n"),t("span",{pre:!0,attrs:{class:"token key atrule"}},[s._v("env")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(":")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token comment"}},[s._v("# 设置环境变量")]),s._v("\n  "),t("span",{pre:!0,attrs:{class:"token key atrule"}},[s._v("TZ")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(":")]),s._v(" Asia/Shanghai "),t("span",{pre:!0,attrs:{class:"token comment"}},[s._v("# 时区(设置时区可使页面中的`最近更新时间`使用该时区时间)")]),s._v("\n\n"),t("span",{pre:!0,attrs:{class:"token key atrule"}},[s._v("jobs")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(":")]),s._v("\n  "),t("span",{pre:!0,attrs:{class:"token key atrule"}},[s._v("build")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(":")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token comment"}},[s._v("# 自定义名称")]),s._v("\n    "),t("span",{pre:!0,attrs:{class:"token key atrule"}},[s._v("runs-on")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(":")]),s._v(" ubuntu"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("-")]),s._v("latest "),t("span",{pre:!0,attrs:{class:"token comment"}},[s._v("# 运行在虚拟机环境ubuntu-latest")]),s._v("\n\n    "),t("span",{pre:!0,attrs:{class:"token key atrule"}},[s._v("strategy")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(":")]),s._v("\n      "),t("span",{pre:!0,attrs:{class:"token key atrule"}},[s._v("matrix")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(":")]),s._v("\n        "),t("span",{pre:!0,attrs:{class:"token key atrule"}},[s._v("node-version")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(":")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("[")]),s._v("14.x"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("]")]),s._v("\n\n    "),t("span",{pre:!0,attrs:{class:"token key atrule"}},[s._v("steps")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(":")]),s._v("\n      "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("-")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token key atrule"}},[s._v("name")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(":")]),s._v(" Checkout "),t("span",{pre:!0,attrs:{class:"token comment"}},[s._v("# 步骤1")]),s._v("\n        "),t("span",{pre:!0,attrs:{class:"token key atrule"}},[s._v("uses")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(":")]),s._v(" actions/checkout@v1 "),t("span",{pre:!0,attrs:{class:"token comment"}},[s._v("# 使用的动作。格式:userName/repoName。作用:检出仓库,获取源码。 官方actions库:https://github.com/actions")]),s._v("\n      "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("-")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token key atrule"}},[s._v("name")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(":")]),s._v(" Use Node.js $"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v(" matrix.node"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("-")]),s._v("version "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token comment"}},[s._v("# 步骤2")]),s._v("\n        "),t("span",{pre:!0,attrs:{class:"token key atrule"}},[s._v("uses")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(":")]),s._v(" actions/setup"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("-")]),s._v("node@v1 "),t("span",{pre:!0,attrs:{class:"token comment"}},[s._v("# 作用:安装nodejs")]),s._v("\n        "),t("span",{pre:!0,attrs:{class:"token key atrule"}},[s._v("with")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(":")]),s._v("\n          "),t("span",{pre:!0,attrs:{class:"token key atrule"}},[s._v("node-version")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(":")]),s._v(" $"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v(" matrix.node"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("-")]),s._v("version "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token comment"}},[s._v("# 版本")]),s._v("\n      "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("-")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token key atrule"}},[s._v("name")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(":")]),s._v(" Build"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("-")]),s._v("and"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("-")]),s._v("deploy "),t("span",{pre:!0,attrs:{class:"token comment"}},[s._v("# 步骤3")]),s._v("\n        "),t("span",{pre:!0,attrs:{class:"token key atrule"}},[s._v("run")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(":")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("|")]),t("span",{pre:!0,attrs:{class:"token scalar string"}},[s._v("\n          remote_addr=https://github.com/jacky1234/blogPages.git\n          commit_info=`git describe --all --always --long`\n          user_name=`git log -1 --pretty=format:'%an'`\n          user_email=`git log -1 --pretty=format:'%ae'`\n          deploy_branch=gh-pages")]),s._v("\n\n          yarn\n          yarn build\n          cd docs/.vuepress/dist\n          git config "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("-")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("-")]),s._v("global init.defaultBranch $deploy_branch\n          git init\n          git config user.name $"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("user_name"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n          git config user.email $"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("user_email"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n          git add "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("-")]),s._v("A\n          git commit "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("-")]),s._v('m "auto deploy'),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(' $commit_info"\n          remote_addr=`echo $remote_addr '),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("|")]),s._v(" awk "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("-")]),s._v("F'"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(":")]),s._v("//' '"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("print $2"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("'`\n          remote_addr=https"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(":")]),s._v("//$"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("user_name"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(":")]),s._v("$"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("secrets.BLOG_PAGES_ACCESS_KEY"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("@$"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("remote_addr"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n          git remote add origin $"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("remote_addr"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n          git push origin HEAD"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(":")]),s._v("$deploy_branch "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("-")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("-")]),s._v("force "),t("span",{pre:!0,attrs:{class:"token comment"}},[s._v("# 推送到github $deploy_branch分支")]),s._v("\n          echo 'successfully deploy to https"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(":")]),s._v("//github.com/jacky1234/blogPages'\n          cd "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("-")]),s._v("\n\n      "),t("span",{pre:!0,attrs:{class:"token comment"}},[s._v("# 只提交到github pages也可以使用github-pages-deploy-action,详见: https://github.com/JamesIves/github-pages-deploy-action")]),s._v("\n")])]),s._v(" "),t("div",{staticClass:"line-numbers-wrapper"},[t("span",{staticClass:"line-number"},[s._v("1")]),t("br"),t("span",{staticClass:"line-number"},[s._v("2")]),t("br"),t("span",{staticClass:"line-number"},[s._v("3")]),t("br"),t("span",{staticClass:"line-number"},[s._v("4")]),t("br"),t("span",{staticClass:"line-number"},[s._v("5")]),t("br"),t("span",{staticClass:"line-number"},[s._v("6")]),t("br"),t("span",{staticClass:"line-number"},[s._v("7")]),t("br"),t("span",{staticClass:"line-number"},[s._v("8")]),t("br"),t("span",{staticClass:"line-number"},[s._v("9")]),t("br"),t("span",{staticClass:"line-number"},[s._v("10")]),t("br"),t("span",{staticClass:"line-number"},[s._v("11")]),t("br"),t("span",{staticClass:"line-number"},[s._v("12")]),t("br"),t("span",{staticClass:"line-number"},[s._v("13")]),t("br"),t("span",{staticClass:"line-number"},[s._v("14")]),t("br"),t("span",{staticClass:"line-number"},[s._v("15")]),t("br"),t("span",{staticClass:"line-number"},[s._v("16")]),t("br"),t("span",{staticClass:"line-number"},[s._v("17")]),t("br"),t("span",{staticClass:"line-number"},[s._v("18")]),t("br"),t("span",{staticClass:"line-number"},[s._v("19")]),t("br"),t("span",{staticClass:"line-number"},[s._v("20")]),t("br"),t("span",{staticClass:"line-number"},[s._v("21")]),t("br"),t("span",{staticClass:"line-number"},[s._v("22")]),t("br"),t("span",{staticClass:"line-number"},[s._v("23")]),t("br"),t("span",{staticClass:"line-number"},[s._v("24")]),t("br"),t("span",{staticClass:"line-number"},[s._v("25")]),t("br"),t("span",{staticClass:"line-number"},[s._v("26")]),t("br"),t("span",{staticClass:"line-number"},[s._v("27")]),t("br"),t("span",{staticClass:"line-number"},[s._v("28")]),t("br"),t("span",{staticClass:"line-number"},[s._v("29")]),t("br"),t("span",{staticClass:"line-number"},[s._v("30")]),t("br"),t("span",{staticClass:"line-number"},[s._v("31")]),t("br"),t("span",{staticClass:"line-number"},[s._v("32")]),t("br"),t("span",{staticClass:"line-number"},[s._v("33")]),t("br"),t("span",{staticClass:"line-number"},[s._v("34")]),t("br"),t("span",{staticClass:"line-number"},[s._v("35")]),t("br"),t("span",{staticClass:"line-number"},[s._v("36")]),t("br"),t("span",{staticClass:"line-number"},[s._v("37")]),t("br"),t("span",{staticClass:"line-number"},[s._v("38")]),t("br"),t("span",{staticClass:"line-number"},[s._v("39")]),t("br"),t("span",{staticClass:"line-number"},[s._v("40")]),t("br"),t("span",{staticClass:"line-number"},[s._v("41")]),t("br"),t("span",{staticClass:"line-number"},[s._v("42")]),t("br"),t("span",{staticClass:"line-number"},[s._v("43")]),t("br"),t("span",{staticClass:"line-number"},[s._v("44")]),t("br"),t("span",{staticClass:"line-number"},[s._v("45")]),t("br"),t("span",{staticClass:"line-number"},[s._v("46")]),t("br"),t("span",{staticClass:"line-number"},[s._v("47")]),t("br"),t("span",{staticClass:"line-number"},[s._v("48")]),t("br"),t("span",{staticClass:"line-number"},[s._v("49")]),t("br"),t("span",{staticClass:"line-number"},[s._v("50")]),t("br"),t("span",{staticClass:"line-number"},[s._v("51")]),t("br"),t("span",{staticClass:"line-number"},[s._v("52")]),t("br"),t("span",{staticClass:"line-number"},[s._v("53")]),t("br"),t("span",{staticClass:"line-number"},[s._v("54")]),t("br")])]),t("p",[s._v("这个配置文件会在我 push 提交代码到主分支时触发工作,运行环境是"),t("code",[s._v("ubuntu-latest")]),s._v(",工作步骤:")]),s._v(" "),t("ul",[t("li",[s._v("一,获取仓库源码")]),s._v(" "),t("li",[s._v("二,安装 nodejs,打包项目有用到 nodejs")]),s._v(" "),t("li",[s._v("三,把 token 设置到环境变量,安装项目依赖,然后通过 git push 到指定仓库发布,")])]),s._v(" "),t("p",[s._v("再来看看将要被运行的"),t("code",[s._v("deploy.sh")]),s._v("部署代码:")]),s._v(" "),t("div",{staticClass:"language-sh line-numbers-mode"},[t("pre",{pre:!0,attrs:{class:"language-sh"}},[t("code",[t("span",{pre:!0,attrs:{class:"token shebang important"}},[s._v("#!/usr/bin/env sh")]),s._v("\n\n"),t("span",{pre:!0,attrs:{class:"token comment"}},[s._v("# 确保脚本抛出遇到的错误")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token builtin class-name"}},[s._v("set")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token parameter variable"}},[s._v("-e")]),s._v("\n\n"),t("span",{pre:!0,attrs:{class:"token comment"}},[s._v("# https://github.com/jacky1234/blogPages")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token assign-left variable"}},[s._v("push_addr")]),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v("https://github.com/jacky1234/blogPages.git "),t("span",{pre:!0,attrs:{class:"token comment"}},[s._v("# git提交地址,也可以手动设置,比如:push_addr=git@github.com:xugaoyi/vuepress-theme-vdoing.git")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token assign-left variable"}},[s._v("commit_info")]),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),t("span",{pre:!0,attrs:{class:"token variable"}},[t("span",{pre:!0,attrs:{class:"token variable"}},[s._v("`")]),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("git")]),s._v(" describe "),t("span",{pre:!0,attrs:{class:"token parameter variable"}},[s._v("--all")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token parameter variable"}},[s._v("--always")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token parameter variable"}},[s._v("--long")]),t("span",{pre:!0,attrs:{class:"token variable"}},[s._v("`")])]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token assign-left variable"}},[s._v("dist_path")]),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v("docs/.vuepress/dist "),t("span",{pre:!0,attrs:{class:"token comment"}},[s._v("# 打包生成的文件夹路径")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token assign-left variable"}},[s._v("push_branch")]),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v("gh-pages "),t("span",{pre:!0,attrs:{class:"token comment"}},[s._v("# 推送的分支")]),s._v("\n\n"),t("span",{pre:!0,attrs:{class:"token comment"}},[s._v("# 生成静态文件")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("npm")]),s._v(" run build\n\n"),t("span",{pre:!0,attrs:{class:"token comment"}},[s._v("# 进入生成的文件夹")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token builtin class-name"}},[s._v("cd")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token variable"}},[s._v("$dist_path")]),s._v("\n\n"),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("git")]),s._v(" init\n"),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("git")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("add")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token parameter variable"}},[s._v("-A")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("git")]),s._v(" commit "),t("span",{pre:!0,attrs:{class:"token parameter variable"}},[s._v("-m")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token string"}},[s._v('"deploy, '),t("span",{pre:!0,attrs:{class:"token variable"}},[s._v("$commit_info")]),s._v('"')]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("git")]),s._v(" push "),t("span",{pre:!0,attrs:{class:"token parameter variable"}},[s._v("-f")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token variable"}},[s._v("$push_addr")]),s._v(" HEAD:"),t("span",{pre:!0,attrs:{class:"token variable"}},[s._v("$push_branch")]),s._v("\n\n"),t("span",{pre:!0,attrs:{class:"token builtin class-name"}},[s._v("cd")]),s._v(" -\n"),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("rm")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token parameter variable"}},[s._v("-rf")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token variable"}},[s._v("$dist_path")]),s._v("\n")])]),s._v(" "),t("div",{staticClass:"line-numbers-wrapper"},[t("span",{staticClass:"line-number"},[s._v("1")]),t("br"),t("span",{staticClass:"line-number"},[s._v("2")]),t("br"),t("span",{staticClass:"line-number"},[s._v("3")]),t("br"),t("span",{staticClass:"line-number"},[s._v("4")]),t("br"),t("span",{staticClass:"line-number"},[s._v("5")]),t("br"),t("span",{staticClass:"line-number"},[s._v("6")]),t("br"),t("span",{staticClass:"line-number"},[s._v("7")]),t("br"),t("span",{staticClass:"line-number"},[s._v("8")]),t("br"),t("span",{staticClass:"line-number"},[s._v("9")]),t("br"),t("span",{staticClass:"line-number"},[s._v("10")]),t("br"),t("span",{staticClass:"line-number"},[s._v("11")]),t("br"),t("span",{staticClass:"line-number"},[s._v("12")]),t("br"),t("span",{staticClass:"line-number"},[s._v("13")]),t("br"),t("span",{staticClass:"line-number"},[s._v("14")]),t("br"),t("span",{staticClass:"line-number"},[s._v("15")]),t("br"),t("span",{staticClass:"line-number"},[s._v("16")]),t("br"),t("span",{staticClass:"line-number"},[s._v("17")]),t("br"),t("span",{staticClass:"line-number"},[s._v("18")]),t("br"),t("span",{staticClass:"line-number"},[s._v("19")]),t("br"),t("span",{staticClass:"line-number"},[s._v("20")]),t("br"),t("span",{staticClass:"line-number"},[s._v("21")]),t("br"),t("span",{staticClass:"line-number"},[s._v("22")]),t("br"),t("span",{staticClass:"line-number"},[s._v("23")]),t("br"),t("span",{staticClass:"line-number"},[s._v("24")]),t("br")])]),t("p",[s._v("这个文件使用"),t("a",{attrs:{href:"https://ipcmen.com/",target:"_blank",rel:"noopener noreferrer"}},[s._v("Shell 命令"),t("OutboundLink")],1),s._v("写的,它会先运行打包命令,进入打包好的文件,创建一个自定义域名的 CNAME 文件(如果你没有自定义域名可去掉这个命令),判断是否有 token 环境变量,如果没有说明是在本地自己的电脑上运行的部署,使用 ssh 代码仓库地址,如果有 token 环境变量,说明是 GitHub Actions 自动触发的部署,此时使用的是可以通过 toKen 来获取代码提交权限的提交地址。最后通过 git 命令提交到各自的仓库,完成部署。")]),s._v(" "),t("blockquote",[t("p",[s._v("提示:")]),s._v(" "),t("ul",[t("li",[t("p",[s._v("Shell 可以获取到环境变量。")])]),s._v(" "),t("li",[t("p",[s._v("我想给两个平台上部署的博客不一样的自定义域名,因此做了分开创建 CNAME 文件,分开提交。")])])])]),s._v(" "),t("p",[s._v("至此,我前面提到的需求就实现啦,只需要把源码 push 到 github 仓库这一个步骤,后面的博客打包、部署到 github 和 coding 等工作都由 GitHub Actions 来自动完成。")]),s._v(" "),t("p",[s._v("如下你想查看部署日志,你可以到 github 仓库的 Actions 这一项查看。")]),s._v(" "),t("p",[t("img",{attrs:{src:"https://cdn.staticaly.com/gh/xugaoyi/image_store/blog/20200103124813.png",alt:"部署日志",title:"部署日志"}})]),s._v(" "),t("h3",{attrs:{id:"ci-结果使用邮箱通知"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#ci-结果使用邮箱通知"}},[s._v("#")]),s._v(" CI 结果使用邮箱通知")]),s._v(" "),t("h4",{attrs:{id:"配置-qq-邮箱服务器地址"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#配置-qq-邮箱服务器地址"}},[s._v("#")]),s._v(" 配置 qq 邮箱服务器地址")]),s._v(" "),t("p",[s._v(":::\nIMAP/SMTP 设置方法\n用户名/帐户: 你的 QQ 邮箱完整的地址")]),s._v(" "),t("p",[s._v("密码: 生成的授权码")]),s._v(" "),t("p",[s._v("电子邮件地址: 你的 QQ 邮箱的完整邮件地址")]),s._v(" "),t("p",[s._v("接收邮件服务器: imap.qq.com,使用 SSL,端口号 993")]),s._v(" "),t("p",[s._v("发送邮件服务器: smtp.qq.com,使用 SSL,端口号 465 或 587")]),s._v(" "),t("p",[s._v(":::")]),s._v(" "),t("blockquote",[t("p",[s._v("qq 邮箱的授权码更多内容可见链接: "),t("a",{attrs:{href:"https://wx.mail.qq.com/list/readtemplate?name=app_intro.html#/agreement/authorizationCode",target:"_blank",rel:"noopener noreferrer"}},[s._v("SMTP/IMAP 服务"),t("OutboundLink")],1)])])])}),[],!1,null,null,null);t.default=e.exports}}]);
\ No newline at end of file
diff --git a/assets/js/81.75134db8.js b/assets/js/81.75134db8.js
new file mode 100644
index 0000000000..737171049c
--- /dev/null
+++ b/assets/js/81.75134db8.js
@@ -0,0 +1 @@
+(window.webpackJsonp=window.webpackJsonp||[]).push([[81],{407:function(e,r,t){"use strict";t.r(r);var a=t(4),n=Object(a.a)({},(function(){var e=this,r=e._self._c;return r("ContentSlotsDistributor",{attrs:{"slot-key":e.$parent.slotKey}},[r("blockquote",[r("p",[e._v("copied from "),r("a",{attrs:{href:"https://sideproject.guide/build#%E7%AC%AC%E4%B8%80%E7%89%88%E5%81%9A%E5%88%B0%E4%BB%80%E4%B9%88%E7%A8%8B%E5%BA%A6",target:"_blank",rel:"noopener noreferrer"}},[e._v("https://sideproject.guide/build#第一版做到什么程度"),r("OutboundLink")],1)])]),e._v(" "),r("h1",{attrs:{id:"如何快速实现你的点子"}},[r("a",{staticClass:"header-anchor",attrs:{href:"#如何快速实现你的点子"}},[e._v("#")]),e._v(" 如何快速实现你的点子")]),e._v(" "),r("p",[e._v("当你对你的点子燃起了足够的热情,迫不及待想要敲击键盘,用代码改变世界之前,先冷静一下。")]),e._v(" "),r("h2",{attrs:{id:"你不一定要写代码"}},[r("a",{staticClass:"header-anchor",attrs:{href:"#你不一定要写代码"}},[e._v("#")]),e._v(" 你不一定要写代码")]),e._v(" "),r("p",[e._v("每一行代码都需要被维护,每增加一行代码,你这个 Side Project 的成本就上升了一点。如果能不写代码就解决问题,那是最好的。")]),e._v(" "),r("p",[e._v("正确的解决问题的优先级:")]),e._v(" "),r("ol",[r("li",[e._v("不写代码")]),e._v(" "),r("li",[e._v("只写前端代码(包括 DAPP)")]),e._v(" "),r("li",[e._v("如果必须有后端服务,使用可以 Serverless 方式部署的写法")]),e._v(" "),r("li",[e._v("维护一个服务器")])]),e._v(" "),r("p",[e._v("简而言之,对于开发来讲,优化的目标应当是让自己当前和未来的劳动越少越好。如果一定要写代码来解决,使用你最熟悉的工具。")]),e._v(" "),r("h2",{attrs:{id:"第一版做到什么程度"}},[r("a",{staticClass:"header-anchor",attrs:{href:"#第一版做到什么程度"}},[e._v("#")]),e._v(" 第一版做到什么程度")]),e._v(" "),r("ul",[r("li",[e._v("是可用的,帮助用户解决了问题,或者提供了价值")]),e._v(" "),r("li",[e._v("提供渠道供用户反馈")]),e._v(" "),r("li",[e._v("花费时间最好不要超过一个月(因人的耐心而异),以便及时获得用户反馈")])]),e._v(" "),r("h2",{attrs:{id:"我使用的一些建筑工具"}},[r("a",{staticClass:"header-anchor",attrs:{href:"#我使用的一些建筑工具"}},[e._v("#")]),e._v(" 我使用的一些建筑工具")]),e._v(" "),r("ul",[r("li",[r("a",{attrs:{href:"https://tailwindcss.com/",target:"_blank",rel:"noopener noreferrer"}},[e._v("TailwindCSS"),r("OutboundLink")],1),e._v(": 使用 class 来定义样式,比直接写 CSS 方便一些")]),e._v(" "),r("li",[r("a",{attrs:{href:"https://reactjs.org/",target:"_blank",rel:"noopener noreferrer"}},[e._v("React"),r("OutboundLink")],1),e._v(": 模块化构建前端项目")]),e._v(" "),r("li",[r("a",{attrs:{href:"https://nextjs.org/",target:"_blank",rel:"noopener noreferrer"}},[e._v("Nextjs"),r("OutboundLink")],1),e._v(": 用 React 写多页应用更方便,性能优秀")]),e._v(" "),r("li",[r("a",{attrs:{href:"https://serverless.com/",target:"_blank",rel:"noopener noreferrer"}},[e._v("Serverless"),r("OutboundLink")],1),e._v(": 免运维")]),e._v(" "),r("li",[r("a",{attrs:{href:"https://vercel.com/",target:"_blank",rel:"noopener noreferrer"}},[e._v("Vercel"),r("OutboundLink")],1),e._v(": 一键部署 Nextjs 等应用,性能有保障")]),e._v(" "),r("li",[r("a",{attrs:{href:"https://aws.amazon.com/cn/dynamodb",target:"_blank",rel:"noopener noreferrer"}},[e._v("Dynamodb"),r("OutboundLink")],1),e._v(": Serverless 数据库")])])])}),[],!1,null,null,null);r.default=n.exports}}]);
\ No newline at end of file
diff --git a/assets/js/82.52f4f6ca.js b/assets/js/82.52f4f6ca.js
new file mode 100644
index 0000000000..60f975eb97
--- /dev/null
+++ b/assets/js/82.52f4f6ca.js
@@ -0,0 +1 @@
+(window.webpackJsonp=window.webpackJsonp||[]).push([[82],{408:function(_,v,t){"use strict";t.r(v);var l=t(4),i=Object(l.a)({},(function(){var _=this,v=_._self._c;return v("ContentSlotsDistributor",{attrs:{"slot-key":_.$parent.slotKey}},[v("h2",{attrs:{id:"招人"}},[v("a",{staticClass:"header-anchor",attrs:{href:"#招人"}},[_._v("#")]),_._v(" 招人")]),_._v(" "),v("blockquote",[v("p",[_._v("摘自: "),v("a",{attrs:{href:"https://mp.weixin.qq.com/s/1AR2VdQaVKfVWaj1Fvi_NA",target:"_blank",rel:"noopener noreferrer"}},[_._v("https://mp.weixin.qq.com/s/1AR2VdQaVKfVWaj1Fvi_NA"),v("OutboundLink")],1)])]),_._v(" "),v("h3",{attrs:{id:"定义人才"}},[v("a",{staticClass:"header-anchor",attrs:{href:"#定义人才"}},[_._v("#")]),_._v(" 定义人才")]),_._v(" "),v("blockquote",[v("p",[_._v("S、A、B、C 级人才定义")])]),_._v(" "),v("ul",[v("li",[v("p",[v("code",[_._v("S")]),_._v(": 心里有火,眼里有光,找方向、带队伍、卷出一片天。\n不用告诉他干啥,他来告诉你该干啥. 宏观战略到细节战术执行到抓团队结果;发现问题,能自己评估优先级,解决完了还会同步你;学习和进步的速度超过想象,经常感觉卧槽怎么这么厉害;自己能搭起来一个好团队")])]),_._v(" "),v("li",[v("p",[v("code",[_._v("A")]),_._v(": 能打胜仗,作风优良\n能了解并确认你背后的原因和交付物,还往往会多做好几步,产出优秀,及时同步,老板不用追截止日期和进度;定战术到抓结果;发现问题,会和 leader 确认优先级和方案以后解决问题,之后会复盘如何改进;会有意识的去学习;能配合 "),v("code",[_._v("HR")]),_._v(" 吸引到好人才")])]),_._v(" "),v("li",[v("p",[v("code",[_._v("B")]),_._v(": 各公司内卷和衰落之源\n简历很好看,名校大厂,历次跳槽涨了很多薪水,状态就两个字:油腻。各家一旦加速招聘,都会堆积很多 B 类人,极大稀释组织人才密度。产出不稳定,及格边缘徘徊,喜欢讨价还价指标,不愿意做份外工作,你不催他不动,有时候还可能没搞好或忘了,不问不会同步进展;发现问题等着别人给流程/推动,leader 给了解决方案以后,就照做;不太喜欢学新东西,偶尔学;通常招进来 C 类人")])]),_._v(" "),v("li",[v("p",[v("code",[_._v("C")]),_._v(": 打工人:推三下,动两下,牢骚一句。\n经常自己独立搞不定,需要别人盯很紧和协助,绝不做份外工作;发现问题就抱怨 leader 能力不够,抱怨公司不重视,吐槽流程吐槽管理,自己就是不去推动;发到眼前的学习材料也都懒得点开看,封闭/躺平心态;通常招进来比自己更差的人")])])]),_._v(" "),v("p",[_._v("关键核心负责人岗位、高杠杆/影响范围大的岗位(如产品经理)以及有招人权限的岗位,一定尽量找 S 或 A 级的,B 和 C 级人才是 STRONG NO。因为这些岗位招错人不仅仅是他的工资,更多是机会成本,往往导致整个业务时间被耽误。")]),_._v(" "),v("h3",{attrs:{id:"识人"}},[v("a",{staticClass:"header-anchor",attrs:{href:"#识人"}},[_._v("#")]),_._v(" 识人")]),_._v(" "),v("p",[v("strong",[_._v("大部分面试官喜欢招有强相关经验的人,因为短期产出高,而忽略自驱力等基本素质,导致长期组织内堆积 B/C 级人才,而他们又容易招进来比自己更差的人,开出了孽之花,恶性增强回路.")]),_._v(" 所以说招人是 CEO 和每一层 leader 的事儿,而不仅仅是 HR 的事儿。不仅要为岗位招聘,还要为公司招聘,为公司招到文化匹配的人才。如果有个人能力意愿都很强,但是现在没 HC,为公司招聘的人会努力推动他进来。")]),_._v(" "),v("p",[_._v("coming soon")]),_._v(" "),v("h4",{attrs:{id:"ask-模型"}},[v("a",{staticClass:"header-anchor",attrs:{href:"#ask-模型"}},[_._v("#")]),_._v(" ASK 模型")]),_._v(" "),v("blockquote",[v("p",[_._v("再引用一下 BOSS 直聘 CEO 赵鹏教我的 ASK 模型:")])]),_._v(" "),v("p",[v("strong",[_._v("Ability")]),_._v("(底层软素质,爹娘给的),"),v("strong",[_._v("Skill")]),_._v("(技能),"),v("strong",[_._v("Knowledge")]),_._v("(知识)")]),_._v(" "),v("ul",[v("li",[v("p",[_._v("要万分警惕:多数面试只问了 K 和 S,没有问 A。软素质不行,硬技能再高也不能要,这个坑我们踩了上百次")])]),_._v(" "),v("li",[v("p",[_._v("一二线厂积累的 Skill 就要很小心,可能只有 Skill 没有软素质,彼之蜜糖,我之砒霜")])]),_._v(" "),v("li",[v("p",[_._v("S 级的人,强主要强在 "),v("code",[_._v("Ability")])])]),_._v(" "),v("li",[v("p",[_._v("Ability: 聪明 正直 勤奋 上进 普世价值观 逻辑 常识通识 "),v("strong",[_._v("自驱")]),_._v(" (这是八条,8 plus+1) + 有感恩之心。这里面我认为最重要的是自驱")])])]),_._v(" "),v("p",[_._v("所以其实对于互联网公司这种主要靠脑汁的地方,对于核心关键岗位,我们面试和招人的时候主要还是应该考察 Ability,大部分公司就是被镀金大厂简历 B 级人才,Skill 强 Ability 弱的人坑了;有 Ability,进来再学 Skill 和 Knowledge 都很快。")]),_._v(" "),v("p",[_._v("复盘来看我们公司一些绩效差员工的 bad case,很多都是能力(这里重点指工作相关的 skill)够,但意愿(自驱力)不足的。所以一般遇到员工问题,我都会想这是能力问题还是意愿问题,区别 S/A 级人才和 B/C 级人才最主要的地方也是意愿,能力不足可以培养,也可以挪到其他更合适的岗位试试,意愿不够往往扶不上墙。")]),_._v(" "),v("h5",{attrs:{id:"ability-的考察"}},[v("a",{staticClass:"header-anchor",attrs:{href:"#ability-的考察"}},[_._v("#")]),_._v(" Ability 的考察")]),_._v(" "),v("p",[_._v("一、自驱力")]),_._v(" "),v("ul",[v("li",[v("p",[_._v("克服过最大的挑战/困难/苦是什么?")]),_._v(" "),v("ul",[v("li",[_._v("如果没有或很弱,通常是过去做的事情挑战不够")]),_._v(" "),v("li",[_._v("重点观察如何解决问题的")])])]),_._v(" "),v("li",[v("p",[_._v("最近几年的目标是什么?有为这个目标付出过什么?有大概路径吗?")]),_._v(" "),v("ul",[v("li",[_._v("有目标但行动很差的=光说不练=减分")]),_._v(" "),v("li",[_._v("没有目标/目标模糊/路径不清晰 = 减分")])])]),_._v(" "),v("li",[v("p",[_._v("一般几点到公司几点走?")]),_._v(" "),v("ul",[v("li",[_._v("我很少见到不勤奋能做好工作的,但这不是 deal-breaker;加班多 ≠ 自驱力强,也有加班多但产出很差的,只是自驱的人从概率看通常工作时间比较长")]),_._v(" "),v("li",[_._v("14 年张一鸣在找潜在并购公司的时候找我聊,最后问了我一句,你们公司加班多吗?")]),_._v(" "),v("li",[_._v("对于 IC(Individual Contributor 个人)来说主要看勤奋;对于 TL(Team Leader)主要看能多大程度调动团队产能,一般问团队工作时长情况")])])]),_._v(" "),v("li",[v("p",[_._v("有什么主动改进工作/改变公司,并有一定结果的 case 吗?")]),_._v(" "),v("ul",[v("li",[_._v("自驱力更多是有没有意愿主动去改进工作")]),_._v(" "),v("li",[_._v("关注主动自己想改进还是 leader 安排的任务")]),_._v(" "),v("li",[_._v("改进工作指把本质份内工作搞得更好;改变公司指的是分外工作,但感觉公司需要,就主动去优化")])])])]),_._v(" "),v("p",[_._v("二、其他能力")]),_._v(" "),v("h2",{attrs:{id:"links"}},[v("a",{staticClass:"header-anchor",attrs:{href:"#links"}},[_._v("#")]),_._v(" links")]),_._v(" "),v("ul",[v("li",[v("a",{attrs:{href:"https://mp.weixin.qq.com/s/1AR2VdQaVKfVWaj1Fvi_NA",target:"_blank",rel:"noopener noreferrer"}},[_._v("十年创业者,万字长文分享我是怎么招人的*"),v("OutboundLink")],1),_._v(": 讲述了识人、ASK 模型")]),_._v(" "),v("li",[v("a",{attrs:{href:"https://www.zhihu.com/topic/19578375/hot",target:"_blank",rel:"noopener noreferrer"}},[_._v("知乎-团队管理"),v("OutboundLink")],1)])])])}),[],!1,null,null,null);v.default=i.exports}}]);
\ No newline at end of file
diff --git a/assets/js/83.8c89e99f.js b/assets/js/83.8c89e99f.js
new file mode 100644
index 0000000000..ba48e92055
--- /dev/null
+++ b/assets/js/83.8c89e99f.js
@@ -0,0 +1 @@
+(window.webpackJsonp=window.webpackJsonp||[]).push([[83],{409:function(t,s,e){"use strict";e.r(s);var r=e(4),a=Object(r.a)({},(function(){var t=this,s=t._self._c;return s("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[s("div",{staticClass:"custom-block tip"},[s("p",{staticClass:"custom-block-title"},[t._v("提示")]),t._v(" "),s("p",[t._v("这里可能更加侧重方法学")]),t._v(" "),s("p",[t._v("关于设计好的代码思想,可以转链接 "),s("RouterLink",{attrs:{to:"/pages/db8380/"}},[t._v("设计模式和思想")])],1)]),t._v(" "),s("h2",{attrs:{id:"链接"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#链接"}},[t._v("#")]),t._v(" 链接")]),t._v(" "),s("ul",[s("li",[s("a",{attrs:{href:"https://mp.weixin.qq.com/s/Dl7umd-Z3QuvOwzjmy3Z4w",target:"_blank",rel:"noopener noreferrer"}},[t._v("如何提高代码质量"),s("OutboundLink")],1),t._v(": 大淘宝技术")])])])}),[],!1,null,null,null);s.default=a.exports}}]);
\ No newline at end of file
diff --git a/assets/js/84.77fef493.js b/assets/js/84.77fef493.js
new file mode 100644
index 0000000000..3ee520f5b0
--- /dev/null
+++ b/assets/js/84.77fef493.js
@@ -0,0 +1 @@
+(window.webpackJsonp=window.webpackJsonp||[]).push([[84],{411:function(t,s,n){"use strict";n.r(s);var e=n(4),i=Object(e.a)({},(function(){var t=this._self._c;return t("ContentSlotsDistributor",{attrs:{"slot-key":this.$parent.slotKey}},[t("p",[this._v("褪黑素的作用")]),this._v(" "),t("p",[this._v("睡眠的")])])}),[],!1,null,null,null);s.default=i.exports}}]);
\ No newline at end of file
diff --git a/assets/js/85.1cf2900b.js b/assets/js/85.1cf2900b.js
new file mode 100644
index 0000000000..d2f078a15d
--- /dev/null
+++ b/assets/js/85.1cf2900b.js
@@ -0,0 +1 @@
+(window.webpackJsonp=window.webpackJsonp||[]).push([[85],{410:function(a,e,t){"use strict";t.r(e);var r=t(4),n=Object(r.a)({},(function(){var a=this,e=a._self._c;return e("ContentSlotsDistributor",{attrs:{"slot-key":a.$parent.slotKey}},[e("h2",{attrs:{id:"常用"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#常用"}},[a._v("#")]),a._v(" 常用")]),a._v(" "),e("ul",[e("li",[e("a",{attrs:{href:"https://docs.oracle.com/javase/tutorial/java/IandI/defaultmethods.html",target:"_blank",rel:"noopener noreferrer"}},[a._v("The Java™ Tutorials"),e("OutboundLink")],1)]),a._v(" "),e("li",[e("a",{attrs:{href:"https://docs.oracle.com/javase/specs/jvms/se7/html/",target:"_blank",rel:"noopener noreferrer"}},[a._v("The Java® Virtual Machine Specification(JavaSE7)"),e("OutboundLink")],1)]),a._v(" "),e("li",[e("a",{attrs:{href:"https://docs.oracle.com/en/java/javase/index.html",target:"_blank",rel:"noopener noreferrer"}},[a._v("Java Platform, Standard Edition Documentation"),e("OutboundLink")],1)]),a._v(" "),e("li",[e("a",{attrs:{href:"https://dev.java/",target:"_blank",rel:"noopener noreferrer"}},[a._v("dev java"),e("OutboundLink")],1)]),a._v(" "),e("li",[e("a",{attrs:{href:"https://www.guardsquare.com/manual/configuration/usage",target:"_blank",rel:"noopener noreferrer"}},[a._v("ProGuard manual"),e("OutboundLink")],1)])])])}),[],!1,null,null,null);e.default=n.exports}}]);
\ No newline at end of file
diff --git a/assets/js/86.2def8f0a.js b/assets/js/86.2def8f0a.js
new file mode 100644
index 0000000000..5981b711b2
--- /dev/null
+++ b/assets/js/86.2def8f0a.js
@@ -0,0 +1 @@
+(window.webpackJsonp=window.webpackJsonp||[]).push([[86],{412:function(s,a,t){"use strict";t.r(a);var n=t(4),e=Object(n.a)({},(function(){var s=this,a=s._self._c;return a("ContentSlotsDistributor",{attrs:{"slot-key":s.$parent.slotKey}},[a("h2",{attrs:{id:"unsafe"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#unsafe"}},[s._v("#")]),s._v(" UnSafe")]),s._v(" "),a("p",[a("code",[s._v("sun.misc.Unsafe")]),s._v("是 Java 中的一个非公开类,它提供了直接操作内存和执行一些不安全操作的功能。这个类在 Java 的核心库中,并且不建议在生产环境中使用它,因为它可以绕过 Java 的安全检查,可能导致不安全的操作。")]),s._v(" "),a("p",[s._v("Unsafe 类可以在 Java 代码中执行以下一些操作:")]),s._v(" "),a("ul",[a("li",[a("p",[s._v("直接操作内存:Unsafe 类可以直接操作对象的内存,包括分配、读取和写入内存。这使得开发者可以绕过 Java 的安全检查,直接操作对象的内部,但也会增加出错的风险。")])]),s._v(" "),a("li",[a("p",[s._v("修改对象的成员变量:Unsafe 类可以获取对象成员变量在对象中的偏移量,然后通过偏移量来访问和修改对象的成员变量。这个功能可以用于在运行时动态修改对象的状态,但同样存在风险。")])]),s._v(" "),a("li",[a("p",[s._v("数组操作:Unsafe 类可以对数组进行内存操作,包括分配、读取和写入数组元素。这使得开发者可以在底层直接操作数组,但也容易导致越界访问和内存泄漏等问题。")])]),s._v(" "),a("li",[a("p",[s._v("线程同步:Unsafe 类提供了一些底层的线程同步操作,如 CAS(Compare and Swap)等。这些操作可以用于实现自定义的锁和同步机制,但使用不当可能导致线程安全问题。")])])]),s._v(" "),a("p",[s._v("由于 "),a("code",[s._v("Unsafe")]),s._v(" 类的功能非常强大,但同时也非常危险,因此它不是公开的 API,一般情况下不建议在生产环境中使用。在 Java 9 中,Unsafe 类的访问权限更加受限,因此更加不推荐在生产代码中使用它。\n在开发中,应尽量使用 Java 提供的公开 API,以确保代码的安全性和可维护性。如果确实需要执行一些高级和危险的操作,应该仔细研究相关文档,并且谨慎使用 Unsafe 类。")]),s._v(" "),a("h2",{attrs:{id:"示例"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#示例"}},[s._v("#")]),s._v(" 示例")]),s._v(" "),a("h3",{attrs:{id:"操作对象属性"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#操作对象属性"}},[s._v("#")]),s._v(" 操作对象属性")]),s._v(" "),a("blockquote",[a("p",[s._v("直接修改属性值")])]),s._v(" "),a("p",[s._v("使用 Java 的 Unsafe 类可以直接获取对象的偏移量,然后通过偏移量来访问对象的成员变量。请注意,Unsafe 类是 Java 中的一个非公开类,不建议在生产环境中使用它,因为它可以绕过 Java 的安全检查,可能导致不安全的操作。")]),s._v(" "),a("p",[s._v("下面是一个使用 Unsafe 类获取对象的偏移量并访问成员变量的示例代码:")]),s._v(" "),a("div",{staticClass:"language-java line-numbers-mode"},[a("pre",{pre:!0,attrs:{class:"language-java"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("import")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token import"}},[a("span",{pre:!0,attrs:{class:"token namespace"}},[s._v("sun"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),s._v("misc"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")])]),a("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Unsafe")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("import")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token import"}},[a("span",{pre:!0,attrs:{class:"token namespace"}},[s._v("java"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),s._v("lang"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),s._v("reflect"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")])]),a("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Field")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("public")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("class")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Main")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n    "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("public")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("static")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("void")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("main")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("String")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("[")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("]")]),s._v(" args"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("throws")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("NoSuchFieldException")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("IllegalAccessException")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n        "),a("span",{pre:!0,attrs:{class:"token comment"}},[s._v("// 获取Unsafe实例")]),s._v("\n        "),a("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Field")]),s._v(" unsafeField "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Unsafe")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("class")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("getDeclaredField")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[s._v('"theUnsafe"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n        unsafeField"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("setAccessible")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),a("span",{pre:!0,attrs:{class:"token boolean"}},[s._v("true")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n        "),a("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Unsafe")]),s._v(" unsafe "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Unsafe")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v(" unsafeField"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("get")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("null")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n\n        "),a("span",{pre:!0,attrs:{class:"token comment"}},[s._v("// 创建一个对象")]),s._v("\n        "),a("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("MyClass")]),s._v(" myObject "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("new")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("MyClass")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n        "),a("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("System")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),s._v("out"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("println")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[s._v('"Original value: "')]),s._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("+")]),s._v(" myObject"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("getValue")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n\n        "),a("span",{pre:!0,attrs:{class:"token comment"}},[s._v("// 获取成员变量在对象中的偏移量")]),s._v("\n        "),a("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Field")]),s._v(" valueField "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("MyClass")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("class")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("getDeclaredField")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[s._v('"value"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n        "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("long")]),s._v(" valueOffset "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" unsafe"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("objectFieldOffset")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("valueField"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n\n        "),a("span",{pre:!0,attrs:{class:"token comment"}},[s._v("// 使用偏移量设置新的值")]),s._v("\n        unsafe"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("putInt")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("myObject"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" valueOffset"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("42")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n\n        "),a("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("System")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),s._v("out"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("println")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[s._v('"New value: "')]),s._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("+")]),s._v(" myObject"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("getValue")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n    "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("class")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("MyClass")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n    "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("private")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("int")]),s._v(" value"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n\n    "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("public")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("int")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("getValue")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n        "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("return")]),s._v(" value"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n    "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n")])]),s._v(" "),a("div",{staticClass:"line-numbers-wrapper"},[a("span",{staticClass:"line-number"},[s._v("1")]),a("br"),a("span",{staticClass:"line-number"},[s._v("2")]),a("br"),a("span",{staticClass:"line-number"},[s._v("3")]),a("br"),a("span",{staticClass:"line-number"},[s._v("4")]),a("br"),a("span",{staticClass:"line-number"},[s._v("5")]),a("br"),a("span",{staticClass:"line-number"},[s._v("6")]),a("br"),a("span",{staticClass:"line-number"},[s._v("7")]),a("br"),a("span",{staticClass:"line-number"},[s._v("8")]),a("br"),a("span",{staticClass:"line-number"},[s._v("9")]),a("br"),a("span",{staticClass:"line-number"},[s._v("10")]),a("br"),a("span",{staticClass:"line-number"},[s._v("11")]),a("br"),a("span",{staticClass:"line-number"},[s._v("12")]),a("br"),a("span",{staticClass:"line-number"},[s._v("13")]),a("br"),a("span",{staticClass:"line-number"},[s._v("14")]),a("br"),a("span",{staticClass:"line-number"},[s._v("15")]),a("br"),a("span",{staticClass:"line-number"},[s._v("16")]),a("br"),a("span",{staticClass:"line-number"},[s._v("17")]),a("br"),a("span",{staticClass:"line-number"},[s._v("18")]),a("br"),a("span",{staticClass:"line-number"},[s._v("19")]),a("br"),a("span",{staticClass:"line-number"},[s._v("20")]),a("br"),a("span",{staticClass:"line-number"},[s._v("21")]),a("br"),a("span",{staticClass:"line-number"},[s._v("22")]),a("br"),a("span",{staticClass:"line-number"},[s._v("23")]),a("br"),a("span",{staticClass:"line-number"},[s._v("24")]),a("br"),a("span",{staticClass:"line-number"},[s._v("25")]),a("br"),a("span",{staticClass:"line-number"},[s._v("26")]),a("br"),a("span",{staticClass:"line-number"},[s._v("27")]),a("br"),a("span",{staticClass:"line-number"},[s._v("28")]),a("br"),a("span",{staticClass:"line-number"},[s._v("29")]),a("br"),a("span",{staticClass:"line-number"},[s._v("30")]),a("br"),a("span",{staticClass:"line-number"},[s._v("31")]),a("br"),a("span",{staticClass:"line-number"},[s._v("32")]),a("br")])]),a("p",[s._v("在这个示例中,我们通过反射获取 Unsafe 类的实例,然后获取 MyClass 对象的 value 成员变量在对象中的偏移量 valueOffset。接着,我们使用偏移量 valueOffset 来直接修改 MyClass 对象的 value 成员变量的值。注意,这里我们是直接修改对象内存的内容,这是非常不安全的操作,请谨慎使用。")])])}),[],!1,null,null,null);a.default=e.exports}}]);
\ No newline at end of file
diff --git a/assets/js/87.9fbbf8dc.js b/assets/js/87.9fbbf8dc.js
new file mode 100644
index 0000000000..3d7c525ee0
--- /dev/null
+++ b/assets/js/87.9fbbf8dc.js
@@ -0,0 +1 @@
+(window.webpackJsonp=window.webpackJsonp||[]).push([[87],{413:function(e,t,a){"use strict";a.r(t);var r=a(4),o=Object(r.a)({},(function(){var e=this,t=e._self._c;return t("ContentSlotsDistributor",{attrs:{"slot-key":e.$parent.slotKey}},[t("h2",{attrs:{id:"deque"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#deque"}},[e._v("#")]),e._v(" Deque")]),e._v(" "),t("blockquote",[t("p",[t("a",{attrs:{href:"https://cs.android.com/android/platform/superproject/main/+/main:libcore/ojluni/src/main/java/java/util/Deque.java;l=315?q=Deque.java&ss=android",target:"_blank",rel:"noopener noreferrer"}},[e._v("定义"),t("OutboundLink")],1)])]),e._v(" "),t("p",[e._v("一、常用方法")]),e._v(" "),t("ul",[t("li",[t("code",[e._v("poll")]),e._v(": Retrieves and removes the head of the queue represented by this deque, 返回值可为空")]),e._v(" "),t("li",[t("code",[e._v("pollFirst")]),e._v(": 同上")]),e._v(" "),t("li",[t("code",[e._v("pollLast")])]),e._v(" "),t("li",[t("code",[e._v("peek")]),e._v(": Retrieves, but does not remove, the head of the queue represented by this deque. 返回值可为空")]),e._v(" "),t("li",[t("code",[e._v("peekFirst")]),e._v(": 同上")]),e._v(" "),t("li",[t("code",[e._v("peekLast")])]),e._v(" "),t("li",[t("code",[e._v("add")]),e._v(": 在队尾插入,如果空间不足会异常")]),e._v(" "),t("li",[t("code",[e._v("addFirst")]),e._v(": 在队首插入,如果空间不足会异常")]),e._v(" "),t("li",[t("code",[e._v("addLast")]),e._v(": 同 add")]),e._v(" "),t("li",[t("code",[e._v("offer")]),e._v(": 在队尾插入. 有空间返回 true, 否则返回 false。 在 capacity-restricted deque 场景下,比 add 会好用")]),e._v(" "),t("li",[t("code",[e._v("offerFirst")]),e._v(": 在队首插入")]),e._v(" "),t("li",[t("code",[e._v("offerLast")]),e._v(": 同 offer")]),e._v(" "),t("li",[t("code",[e._v("remove")]),e._v(": Retrieves and removes the head of the queue represented by this deque. 如果为空会异常")]),e._v(" "),t("li",[t("code",[e._v("removeFist")]),e._v(": 同上")]),e._v(" "),t("li",[t("code",[e._v("removeLast")])]),e._v(" "),t("li",[t("code",[e._v("pop")]),e._v(": 同 removeFirst、remove, 如果为空会异常")]),e._v(" "),t("li",[t("code",[e._v("push")]),e._v(": 队首插入,如果有空间的话。 如果无空间,会异常")])]),e._v(" "),t("blockquote",[t("p",[e._v("经常可以看到 push 和 pop 配套使用")])]),e._v(" "),t("h3",{attrs:{id:"arraydeque"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#arraydeque"}},[e._v("#")]),e._v(" ArrayDeque")]),e._v(" "),t("blockquote",[t("p",[e._v("Resizable-array implementation of the Deque interface. Array deques have no capacity restrictions; they grow as necessary to support usage. They are not thread-safe; in the absence of external synchronization, they do not support concurrent access by multiple threads. Null elements are prohibited. This class is likely to be faster than {java.util.Stack} when used as a stack, and faster than LinkedList when used as a queue.\n"),t("a",{attrs:{href:"https://cs.android.com/android/platform/superproject/main/+/main:libcore/ojluni/src/main/java/java/util/ArrayDeque.java",target:"_blank",rel:"noopener noreferrer"}},[e._v("源码链接"),t("OutboundLink")],1)])])])}),[],!1,null,null,null);t.default=o.exports}}]);
\ No newline at end of file
diff --git a/assets/js/88.f0f85fcf.js b/assets/js/88.f0f85fcf.js
new file mode 100644
index 0000000000..0e140faa8b
--- /dev/null
+++ b/assets/js/88.f0f85fcf.js
@@ -0,0 +1 @@
+(window.webpackJsonp=window.webpackJsonp||[]).push([[88],{414:function(e,s,a){"use strict";a.r(s);var t=a(4),r=Object(t.a)({},(function(){var e=this,s=e._self._c;return s("ContentSlotsDistributor",{attrs:{"slot-key":e.$parent.slotKey}},[s("h2",{attrs:{id:"api"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#api"}},[e._v("#")]),e._v(" api")]),e._v(" "),s("h3",{attrs:{id:"getgenericsuperclass"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#getgenericsuperclass"}},[e._v("#")]),e._v(" getGenericSuperclass")]),e._v(" "),s("blockquote",[s("p",[s("code",[e._v("getGenericSuperclass")]),e._v(" 是 Java 中 java.lang.Class 类的方法之一。它用于获取表示某个类的父类的 Type,其中 Type 是 Java 泛型类型的表示形式。这个方法通常与 Java 泛型一起使用,以便在运行时获取类的泛型信息。")])]),e._v(" "),s("div",{staticClass:"language-java line-numbers-mode"},[s("pre",{pre:!0,attrs:{class:"language-java"}},[s("code",[s("span",{pre:!0,attrs:{class:"token class-name"}},[e._v("Type")]),e._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[e._v("getGenericSuperclass")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(")")]),e._v("\n")])]),e._v(" "),s("div",{staticClass:"line-numbers-wrapper"},[s("span",{staticClass:"line-number"},[e._v("1")]),s("br")])]),s("p",[e._v("返回类型:Type,表示该类的父类的泛型类型。")]),e._v(" "),s("p",[s("code",[e._v("getGenericSuperclass")]),e._v(" 的常见使用场景包括:")]),e._v(" "),s("ul",[s("li",[s("p",[e._v("获取父类的泛型类型信息: 通过 getGenericSuperclass,您可以在运行时获取类的父类的泛型类型信息。这对于实现泛型工具类或进行运行时类型检查非常有用。例如,可以获取某个类的直接父类的泛型类型,然后进一步分析这些泛型参数。")])]),e._v(" "),s("li",[s("p",[e._v("实现通用的序列化和反序列化: 当您需要将对象序列化为字节数组或反序列化为对象时, getGenericSuperclass 可以帮助您获取类的父类的泛型信息,以便正确地序列化和反序列化泛型对象。")])]),e._v(" "),s("li",[s("p",[e._v("构建通用的数据访问层(DAO): 在数据访问层中,您可能需要动态地根据模型类来构建 SQL 查询。通过 getGenericSuperclass,您可以获取模型类的泛型信息,以便根据泛型类型生成合适的 SQL 查询。")])]),e._v(" "),s("li",[s("p",[e._v("动态代理: 使用 Java 动态代理机制时,您可能需要获取被代理类的泛型信息。getGenericSuperclass 可以帮助您确定代理类需要实现的接口和泛型参数。")])]),e._v(" "),s("li",[s("p",[e._v("反射操作: 对于任何需要在运行时进行反射操作的情况,getGenericSuperclass 可以提供更多有关类层次结构和泛型类型的信息。")])])]),e._v(" "),s("p",[e._v("需要注意的是,getGenericSuperclass 方法只能获取直接父类的泛型信息,如果类的层次结构更加复杂,您可能需要进一步递归检查超类以获取完整的泛型信息。此外,泛型类型的擦除规则也会影响到 getGenericSuperclass 返回的类型。因此,在使用这个方法时,要仔细考虑泛型类型的实际情况。")])])}),[],!1,null,null,null);s.default=r.exports}}]);
\ No newline at end of file
diff --git a/assets/js/89.3e155781.js b/assets/js/89.3e155781.js
new file mode 100644
index 0000000000..78f5e0c482
--- /dev/null
+++ b/assets/js/89.3e155781.js
@@ -0,0 +1 @@
+(window.webpackJsonp=window.webpackJsonp||[]).push([[89],{415:function(t,e,n){"use strict";n.r(e);var r=n(4),s=Object(r.a)({},(function(){var t=this._self._c;return t("ContentSlotsDistributor",{attrs:{"slot-key":this.$parent.slotKey}},[t("p",[t("a",{attrs:{href:"https://geeknote.net/wick/posts/2354",target:"_blank",rel:"noopener noreferrer"}},[this._v("Mac 使用 Jenv 实现 Jdk 多版本管理"),t("OutboundLink")],1)])])}),[],!1,null,null,null);e.default=s.exports}}]);
\ No newline at end of file
diff --git a/assets/js/9.fd10529f.js b/assets/js/9.fd10529f.js
new file mode 100644
index 0000000000..f1c9c228d0
--- /dev/null
+++ b/assets/js/9.fd10529f.js
@@ -0,0 +1 @@
+(window.webpackJsonp=window.webpackJsonp||[]).push([[9,4,13,15,25,32,37],{251:function(t,e,i){},252:function(t,e,i){"use strict";i.r(e);var s=i(11),n={props:{item:{required:!0}},computed:{link(){return Object(s.c)(this.item.link)},exact(){return this.$site.locales?Object.keys(this.$site.locales).some(t=>t===this.link):"/"===this.link}},methods:{isExternal:s.g,isMailto:s.h,isTel:s.i,focusoutAction(){this.$emit("focusout")}}},r=i(4),a=Object(r.a)(n,(function(){var t=this,e=t._self._c;return t.isExternal(t.link)?e("a",{staticClass:"nav-link external",attrs:{href:t.link,target:t.isMailto(t.link)||t.isTel(t.link)?null:"_blank",rel:t.isMailto(t.link)||t.isTel(t.link)?null:"noopener noreferrer"},on:{focusout:t.focusoutAction}},[t._v("\n  "+t._s(t.item.text)+"\n  "),e("OutboundLink")],1):e("router-link",{staticClass:"nav-link",attrs:{to:t.link,exact:t.exact},nativeOn:{focusout:function(e){return t.focusoutAction.apply(null,arguments)}}},[t._v(t._s(t.item.text))])}),[],!1,null,null,null);e.default=a.exports},253:function(t,e,i){},254:function(t,e,i){"use strict";i.r(e);var s={name:"DropdownTransition",methods:{setHeight(t){t.style.height=t.scrollHeight+"px"},unsetHeight(t){t.style.height=""}}},n=(i(255),i(4)),r=Object(n.a)(s,(function(){return(0,this._self._c)("transition",{attrs:{name:"dropdown"},on:{enter:this.setHeight,"after-enter":this.unsetHeight,"before-leave":this.setHeight}},[this._t("default")],2)}),[],!1,null,null,null);e.default=r.exports},255:function(t,e,i){"use strict";i(251)},259:function(t,e,i){},260:function(t,e,i){},261:function(t,e,i){"use strict";i(253)},266:function(t,e,i){},269:function(t,e,i){"use strict";i.r(e);var s=i(252),n=i(254),r=i(97),a=i.n(r),o={components:{NavLink:s.default,DropdownTransition:n.default},data:()=>({open:!1,isMQMobile:!1}),props:{item:{required:!0}},computed:{dropdownAriaLabel(){return this.item.ariaLabel||this.item.text}},beforeMount(){this.isMQMobile=window.innerWidth<720,window.addEventListener("resize",()=>{this.isMQMobile=window.innerWidth<720})},methods:{toggle(){this.isMQMobile&&(this.open=!this.open)},isLastItemOfArray:(t,e)=>a()(e)===t},watch:{$route(){this.open=!1}}},l=(i(261),i(4)),u=Object(l.a)(o,(function(){var t=this,e=t._self._c;return e("div",{staticClass:"dropdown-wrapper",class:{open:t.open}},[e("button",{staticClass:"dropdown-title",attrs:{type:"button","aria-label":t.dropdownAriaLabel},on:{click:t.toggle}},[t.item.link?e("router-link",{staticClass:"link-title",attrs:{to:t.item.link}},[t._v(t._s(t.item.text))]):t._e(),t._v(" "),e("span",{directives:[{name:"show",rawName:"v-show",value:!t.item.link,expression:"!item.link"}],staticClass:"title"},[t._v(t._s(t.item.text))]),t._v(" "),e("span",{staticClass:"arrow",class:t.open?"down":"right"})],1),t._v(" "),e("DropdownTransition",[e("ul",{directives:[{name:"show",rawName:"v-show",value:t.open,expression:"open"}],staticClass:"nav-dropdown"},t._l(t.item.items,(function(i,s){return e("li",{key:i.link||s,staticClass:"dropdown-item"},["links"===i.type?e("h4",[t._v(t._s(i.text))]):t._e(),t._v(" "),"links"===i.type?e("ul",{staticClass:"dropdown-subitem-wrapper"},t._l(i.items,(function(s){return e("li",{key:s.link,staticClass:"dropdown-subitem"},[e("NavLink",{attrs:{item:s},on:{focusout:function(e){t.isLastItemOfArray(s,i.items)&&t.isLastItemOfArray(i,t.item.items)&&t.toggle()}}})],1)})),0):e("NavLink",{attrs:{item:i},on:{focusout:function(e){t.isLastItemOfArray(i,t.item.items)&&t.toggle()}}})],1)})),0)])],1)}),[],!1,null,null,null);e.default=u.exports},274:function(t,e,i){"use strict";i(259)},275:function(t,e,i){"use strict";i(260)},276:function(t,e,i){"use strict";i.r(e);var s=i(269),n=i(11),r={components:{NavLink:i(252).default,DropdownLink:s.default},computed:{userNav(){return this.$themeLocaleConfig.nav||this.$site.themeConfig.nav||[]},nav(){const{locales:t}=this.$site;if(t&&Object.keys(t).length>1){const e=this.$page.path,i=this.$router.options.routes,s=this.$site.themeConfig.locales||{},n={text:this.$themeLocaleConfig.selectText||"Languages",ariaLabel:this.$themeLocaleConfig.ariaLabel||"Select language",items:Object.keys(t).map(n=>{const r=t[n],a=s[n]&&s[n].label||r.lang;let o;return r.lang===this.$lang?o=e:(o=e.replace(this.$localeConfig.path,n),i.some(t=>t.path===o)||(o=n)),{text:a,link:o}})};return[...this.userNav,n]}return this.userNav},userLinks(){return(this.nav||[]).map(t=>Object.assign(Object(n.k)(t),{items:(t.items||[]).map(n.k)}))},repoLink(){const{repo:t}=this.$site.themeConfig;return t?/^https?:/.test(t)?t:"https://github.com/"+t:null},repoLabel(){if(!this.repoLink)return;if(this.$site.themeConfig.repoLabel)return this.$site.themeConfig.repoLabel;const t=this.repoLink.match(/^https?:\/\/[^/]+/)[0],e=["GitHub","GitLab","Bitbucket"];for(let i=0;i"group"===e.type?a(t,e):"page"===e.type&&Object(r.f)(t,e.path))}var o={name:"SidebarLinks",components:{SidebarGroup:s.default,SidebarLink:n.default},props:["items","depth","sidebarDepth","initialOpenGroupIndex"],data(){return{openGroupIndex:this.initialOpenGroupIndex||0}},created(){this.refreshIndex()},watch:{$route(){this.refreshIndex()}},methods:{refreshIndex(){const t=function(t,e){for(let i=0;i-1&&(this.openGroupIndex=t)},toggleGroup(t){this.openGroupIndex=t===this.openGroupIndex?-1:t},isActive(t){return Object(r.f)(this.$route,t.regularPath)}}},l=i(4),u=Object(l.a)(o,(function(){var t=this,e=t._self._c;return t.items.length?e("ul",{staticClass:"sidebar-links"},t._l(t.items,(function(i,s){return e("li",{key:s},["group"===i.type?e("SidebarGroup",{attrs:{item:i,open:s===t.openGroupIndex,collapsable:i.collapsable||i.collapsible,depth:t.depth},on:{toggle:function(e){return t.toggleGroup(s)}}}):e("SidebarLink",{attrs:{sidebarDepth:t.sidebarDepth,item:i}})],1)})),0):t._e()}),[],!1,null,null,null);e.default=u.exports},279:function(t,e,i){"use strict";i.r(e);var s=i(11);function n(t,e,i,s){return t("router-link",{props:{to:e,activeClass:"",exactActiveClass:""},class:{active:s,"sidebar-link":!0}},i)}function r(t,e,i,a,o,l=1){return!e||l>o?null:t("ul",{class:"sidebar-sub-headers"},e.map(e=>{const u=Object(s.f)(a,i+"#"+e.slug);return t("li",{class:"sidebar-sub-header level"+e.level},[n(t,i+"#"+e.slug,e.title,u),r(t,e.children,i,a,o,l+1)])}))}var a={functional:!0,props:["item","sidebarDepth"],render(t,{parent:{$page:e,$site:i,$route:a,$themeConfig:o,$themeLocaleConfig:l},props:{item:u,sidebarDepth:c}}){const p=Object(s.f)(a,u.path),h="auto"===u.type?p||u.children.some(t=>Object(s.f)(a,u.basePath+"#"+t.slug)):p,d="external"===u.type?function(t,e,i){return t("a",{attrs:{href:e,target:"_blank",rel:"noopener noreferrer"},class:{"sidebar-link":!0}},[i,t("OutboundLink")])}(t,u.path,u.title||u.path):n(t,u.path,u.title||u.path,h),f=[e.frontmatter.sidebarDepth,c,l.sidebarDepth,o.sidebarDepth,1].find(t=>void 0!==t),b=l.displayAllHeaders||o.displayAllHeaders;if("auto"===u.type)return[d,r(t,u.children,u.basePath,a,f)];if((h||b)&&u.headers&&!s.e.test(u.path)){return[d,r(t,Object(s.d)(u.headers),u.path,a,f)]}return d}},o=(i(275),i(4)),l=Object(o.a)(a,void 0,void 0,!1,null,null,null);e.default=l.exports},297:function(t,e,i){"use strict";i(266)},298:function(t,e,i){},302:function(t,e,i){"use strict";i.r(e);var s=i(11),n={name:"SidebarGroup",props:["item","open","collapsable","depth"],components:{DropdownTransition:i(254).default},beforeCreate(){this.$options.components.SidebarLinks=i(277).default},methods:{isActive:s.f}},r=(i(297),i(4)),a=Object(r.a)(n,(function(){var t=this,e=t._self._c;return e("section",{staticClass:"sidebar-group",class:[{collapsable:t.collapsable,"is-sub-group":0!==t.depth},"depth-"+t.depth]},[t.item.path?e("router-link",{staticClass:"sidebar-heading clickable",class:{open:t.open,active:t.isActive(t.$route,t.item.path)},attrs:{to:t.item.path},nativeOn:{click:function(e){return t.$emit("toggle")}}},[e("span",[t._v(t._s(t.item.title))]),t._v(" "),t.collapsable?e("span",{staticClass:"arrow",class:t.open?"down":"right"}):t._e()]):e("p",{staticClass:"sidebar-heading",class:{open:t.open},on:{click:function(e){return t.$emit("toggle")}}},[e("span",[t._v(t._s(t.item.title))]),t._v(" "),t.collapsable?e("span",{staticClass:"arrow",class:t.open?"down":"right"}):t._e()]),t._v(" "),e("DropdownTransition",[t.open||!t.collapsable?e("SidebarLinks",{staticClass:"sidebar-group-items",attrs:{items:t.item.children,"sidebar-depth":t.item.sidebarDepth,"initial-open-group-index":t.item.initialOpenGroupIndex,depth:t.depth+1}}):t._e()],1)],1)}),[],!1,null,null,null);e.default=a.exports},321:function(t,e,i){"use strict";i(298)},342:function(t,e,i){"use strict";i.r(e);var s=i(277),n=i(276),r={name:"Sidebar",components:{SidebarLinks:s.default,NavLinks:n.default},props:["items"],computed:{blogger(){return this.$themeConfig.blogger}}},a=(i(321),i(4)),o=Object(a.a)(r,(function(){var t=this,e=t._self._c;return e("aside",{staticClass:"sidebar"},[t.blogger?e("div",{staticClass:"blogger"},[e("img",{attrs:{src:t.blogger.avatar}}),t._v(" "),e("div",{staticClass:"blogger-info"},[e("h3",[t._v(t._s(t.blogger.name))]),t._v(" "),t.blogger.social?e("div",{staticClass:"icons"},t._l(t.blogger.social.icons,(function(t,i){return e("a",{key:i,class:["iconfont",t.iconClass],attrs:{href:t.link,title:t.title,target:"_blank"}})})),0):e("span",[t._v(t._s(t.blogger.slogan))])])]):t._e(),t._v(" "),e("NavLinks"),t._v(" "),t._t("top"),t._v(" "),e("SidebarLinks",{attrs:{depth:0,items:t.items}}),t._v(" "),t._t("bottom")],2)}),[],!1,null,null,null);e.default=o.exports}}]);
\ No newline at end of file
diff --git a/assets/js/90.8821aeec.js b/assets/js/90.8821aeec.js
new file mode 100644
index 0000000000..cffffdbc66
--- /dev/null
+++ b/assets/js/90.8821aeec.js
@@ -0,0 +1 @@
+(window.webpackJsonp=window.webpackJsonp||[]).push([[90],{416:function(n,i,a){"use strict";a.r(i);var e=a(4),u=Object(e.a)({},(function(){var n=this,i=n._self._c;return i("ContentSlotsDistributor",{attrs:{"slot-key":n.$parent.slotKey}},[i("h2",{attrs:{id:"介绍"}},[i("a",{staticClass:"header-anchor",attrs:{href:"#介绍"}},[n._v("#")]),n._v(" 介绍")]),n._v(" "),i("ol",[i("li",[i("p",[i("strong",[n._v("Linux 内核")]),n._v(": Linux 是一个免费、开源的 Unix-like 操作系统内核,最初由 Linus Torvalds 开发。它负责管理硬件资源、文件系统、进程管理等底层操作系统功能。Linux 内核是操作系统的核心组件,但它本身不足以构成一个完整的操作系统。")])]),n._v(" "),i("li",[i("p",[i("strong",[n._v("Linux 发行版(Linux Distribution)")]),n._v(": 为了创建一个完整的操作系统,Linux 内核需要与其他组件(如 GNU 工具、库、Shell、图形界面等)集成在一起。这个整合的过程由不同的 Linux 发行版完成。每个 Linux 发行版都基于 Linux 内核,并添加了其他必要的软件和工具,以提供一个功能完备的操作系统。Debian、Ubuntu、Fedora、CentOS、Arch Linux 等都是不同的 Linux 发行版。")])]),n._v(" "),i("li",[i("p",[i("strong",[n._v("Debian 和 Linux 的关系")]),n._v(": Debian 是一个基于 Linux 内核的操作系统发行版,它使用 Linux 内核作为其操作系统内核。Debian 通过将 Linux 内核与其他软件包(如 GNU 工具、桌面环境、应用程序等)整合在一起,提供了一个完整的 Linux 操作系统。")])])]),n._v(" "),i("p",[n._v('所以,Linux 既指代了操作系统内核,也用来描述基于该内核的操作系统。一般情况下,当人们说 "Linux" 时,他们更可能是指整个操作系统,而不仅仅是内核。然而,在严格的技术术语中,"Linux" 是指内核,而 Linux 发行版是指整个操作系统。')]),n._v(" "),i("h2",{attrs:{id:"发行版"}},[i("a",{staticClass:"header-anchor",attrs:{href:"#发行版"}},[n._v("#")]),n._v(" 发行版")]),n._v(" "),i("h3",{attrs:{id:"debian"}},[i("a",{staticClass:"header-anchor",attrs:{href:"#debian"}},[n._v("#")]),n._v(" Debian")]),n._v(" "),i("p",[n._v("Debian 是一种基于 Linux 内核的操作系统发行版。具体来说,以下是关于 Debian 和 Linux 之间关系的详细信息:")]),n._v(" "),i("p",[n._v("Debian 是操作系统: Debian 不仅包含了 Linux 内核,还包括了一个完整的操作系统环境,包括 GNU 工具(如 Bash shell、Coreutils、GCC 编译器等)以及大量其他软件包。Debian 通过将 Linux 内核与其他软件包和工具集成在一起,创建了一个功能完备的操作系统。")]),n._v(" "),i("p",[n._v("Debian 使用 Linux 内核: Debian 采用了 Linux 内核作为其操作系统的内核。Linux 是一个开源的 Unix-like 内核,由 Linus Torvalds 在 1991 年创建。Debian 选择了 Linux 内核作为其默认内核,因为它具有广泛的硬件支持和强大的性能。")]),n._v(" "),i("p",[n._v('Debian 的多个版本使用不同的 Linux 内核: Debian 的不同版本(如稳定版、测试版、不稳定版等)可能会使用不同版本的 Linux 内核,以适应不同的需求和硬件架构。例如,Debian 11(代号 "Bullseye")使用了特定版本的 Linux 内核,而下一个版本可能会使用更新的内核版本。')]),n._v(" "),i("p",[n._v("Debian 的定制内核: 尽管 Debian 默认使用标准的 Linux 内核,但用户和管理员有时可以选择定制内核以满足特定需求。他们可以使用 Debian 提供的工具来编译和安装自己的内核,或者使用第三方内核。")]),n._v(" "),i("p",[n._v("总的来说,Debian 是一个基于 Linux 内核的操作系统发行版,它不仅包含了 Linux 内核,还包括了许多其他关键组件和软件包,以提供一个完整的、功能丰富的操作系统环境。 Debian 与 Linux 内核之间的协作和集成使其成为广泛使用的 Linux 发行版之一。")])])}),[],!1,null,null,null);i.default=u.exports}}]);
\ No newline at end of file
diff --git a/assets/js/91.d1fb6ddb.js b/assets/js/91.d1fb6ddb.js
new file mode 100644
index 0000000000..d1dd2b3890
--- /dev/null
+++ b/assets/js/91.d1fb6ddb.js
@@ -0,0 +1 @@
+(window.webpackJsonp=window.webpackJsonp||[]).push([[91],{417:function(e,t,r){"use strict";r.r(t);var a=r(4),n=Object(a.a)({},(function(){var e=this,t=e._self._c;return t("ContentSlotsDistributor",{attrs:{"slot-key":e.$parent.slotKey}},[t("blockquote",[t("p",[e._v("本文对音视频内容做了梳理,梳理,个人原创内容较少,大部分是资源的整合")])]),e._v(" "),t("h2",{attrs:{id:"opengl"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#opengl"}},[e._v("#")]),e._v(" OpenGL")]),e._v(" "),t("h2",{attrs:{id:"ffmepg"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#ffmepg"}},[e._v("#")]),e._v(" FFMEPG")]),e._v(" "),t("blockquote",[t("p",[e._v("FFmpeg is the leading multimedia framework, able to decode, encode, transcode, mux, demux, stream, filter and play pretty much anything that humans and machines have created. It supports the most obscure ancient formats up to the cutting edge. No matter if they were designed by some standards committee, the community or a corporation. It is also highly portable: FFmpeg compiles, runs, and passes our testing infrastructure FATE across Linux, Mac OS X, Microsoft Windows, the BSDs, Solaris, etc. under a wide variety of build environments, machine architectures, and configurations.\n更多内容可以见官网 "),t("a",{attrs:{href:"https://ffmpeg.org/",target:"_blank",rel:"noopener noreferrer"}},[e._v("ffmpeg"),t("OutboundLink")],1)])]),e._v(" "),t("h3",{attrs:{id:"ffmpeg-tools"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#ffmpeg-tools"}},[e._v("#")]),e._v(" FFmpeg Tools")]),e._v(" "),t("ul",[t("li",[e._v("ffmpeg")]),e._v(" "),t("li",[e._v("ffplay")]),e._v(" "),t("li",[e._v("ffprobe")])]),e._v(" "),t("h2",{attrs:{id:"其他"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#其他"}},[e._v("#")]),e._v(" 其他")]),e._v(" "),t("h2",{attrs:{id:"链接"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#链接"}},[e._v("#")]),e._v(" 链接")]),e._v(" "),t("ul",[t("li",[t("a",{attrs:{href:"https://github.com/jacky1234/learningVideo",target:"_blank",rel:"noopener noreferrer"}},[e._v("github-learningVideo*"),t("OutboundLink")],1)]),e._v(" "),t("li",[t("a",{attrs:{href:"https://mp.weixin.qq.com/mp/appmsgalbum?__biz=MzA4MjU1MDk3Ng==&action=getalbum&album_id=1337187910394920960&scene=173&from_msgid=2451531032&from_itemidx=1&count=3&nolastread=1#wechat_redirect",target:"_blank",rel:"noopener noreferrer"}},[e._v("微信-音视频杂谈专题"),t("OutboundLink")],1)]),e._v(" "),t("li",[t("a",{attrs:{href:"https://www.jianshu.com/u/f717b78f593b",target:"_blank",rel:"noopener noreferrer"}},[e._v("简书-yabin 小站-音视频开发之旅"),t("OutboundLink")],1)]),e._v(" "),t("li",[t("a",{attrs:{href:"https://source.android.com/docs/core/graphics?hl=zh-cn",target:"_blank",rel:"noopener noreferrer"}},[e._v("Android-图形架构概述"),t("OutboundLink")],1)])]),e._v(" "),t("h3",{attrs:{id:"sub"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#sub"}},[e._v("#")]),e._v(" SUB")]),e._v(" "),t("ul",[t("li",[t("a",{attrs:{href:"https://www.jianshu.com/p/5f3495d7b76b",target:"_blank",rel:"noopener noreferrer"}},[e._v("SurfaceView 与 TextureView"),t("OutboundLink")],1)])])])}),[],!1,null,null,null);t.default=n.exports}}]);
\ No newline at end of file
diff --git a/assets/js/92.84eb3950.js b/assets/js/92.84eb3950.js
new file mode 100644
index 0000000000..54d4333fa2
--- /dev/null
+++ b/assets/js/92.84eb3950.js
@@ -0,0 +1 @@
+(window.webpackJsonp=window.webpackJsonp||[]).push([[92],{418:function(t,a,s){"use strict";s.r(a);var n=s(4),e=Object(n.a)({},(function(){var t=this,a=t._self._c;return a("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[a("h1",{attrs:{id:"测试页面"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#测试页面"}},[t._v("#")]),t._v(" 测试页面")]),t._v(" "),a("h2",{attrs:{id:"rtext"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#rtext"}},[t._v("#")]),t._v(" RText")]),t._v(" "),a("blockquote",[a("Badge",{attrs:{type:"warning",text:"提示",vertical:"top"}}),t._v(" 暂时没有处理 text 内容为连接的情况\n")],1),t._v(" "),a("ul",[a("li",[t._v("red :"),a("RText",{attrs:{text:"123",color:"red"}})],1),t._v(" "),a("li",[t._v("green : "),a("RText",{attrs:{text:"123",color:"green"}})],1)]),t._v(" "),a("h2",{attrs:{id:"badge"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#badge"}},[t._v("#")]),t._v(" Badge")]),t._v(" "),a("div",{staticClass:"language-html line-numbers-mode"},[a("pre",{pre:!0,attrs:{class:"language-html"}},[a("code",[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("template")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v("\n  "),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("div")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v("\n    "),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("Badge")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("type")]),a("span",{pre:!0,attrs:{class:"token attr-value"}},[a("span",{pre:!0,attrs:{class:"token punctuation attr-equals"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')]),t._v("tip"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')])]),t._v(" "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("text")]),a("span",{pre:!0,attrs:{class:"token attr-value"}},[a("span",{pre:!0,attrs:{class:"token punctuation attr-equals"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')]),t._v("Tip"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')])]),t._v(" "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("vertical")]),a("span",{pre:!0,attrs:{class:"token attr-value"}},[a("span",{pre:!0,attrs:{class:"token punctuation attr-equals"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')]),t._v("middle"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')])]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("/>")])]),t._v("\n    "),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("Badge")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("type")]),a("span",{pre:!0,attrs:{class:"token attr-value"}},[a("span",{pre:!0,attrs:{class:"token punctuation attr-equals"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')]),t._v("warning"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')])]),t._v(" "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("text")]),a("span",{pre:!0,attrs:{class:"token attr-value"}},[a("span",{pre:!0,attrs:{class:"token punctuation attr-equals"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')]),t._v("Warning"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')])]),t._v(" "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("vertical")]),a("span",{pre:!0,attrs:{class:"token attr-value"}},[a("span",{pre:!0,attrs:{class:"token punctuation attr-equals"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')]),t._v("top"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')])]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("/>")])]),t._v("\n    "),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("Badge")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("type")]),a("span",{pre:!0,attrs:{class:"token attr-value"}},[a("span",{pre:!0,attrs:{class:"token punctuation attr-equals"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')]),t._v("error"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v("Error"),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),t._v("\n  "),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("script")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),a("span",{pre:!0,attrs:{class:"token script"}},[a("span",{pre:!0,attrs:{class:"token language-javascript"}},[t._v("\n  "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" Badge "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("from")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"./Badge.vue"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n  "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("export")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("default")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n    "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("components")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n      Badge"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n    "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n  "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])]),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),t._v("\n")])]),t._v(" "),a("div",{staticClass:"line-numbers-wrapper"},[a("span",{staticClass:"line-number"},[t._v("1")]),a("br"),a("span",{staticClass:"line-number"},[t._v("2")]),a("br"),a("span",{staticClass:"line-number"},[t._v("3")]),a("br"),a("span",{staticClass:"line-number"},[t._v("4")]),a("br"),a("span",{staticClass:"line-number"},[t._v("5")]),a("br"),a("span",{staticClass:"line-number"},[t._v("6")]),a("br"),a("span",{staticClass:"line-number"},[t._v("7")]),a("br"),a("span",{staticClass:"line-number"},[t._v("8")]),a("br"),a("span",{staticClass:"line-number"},[t._v("9")]),a("br"),a("span",{staticClass:"line-number"},[t._v("10")]),a("br"),a("span",{staticClass:"line-number"},[t._v("11")]),a("br"),a("span",{staticClass:"line-number"},[t._v("12")]),a("br"),a("span",{staticClass:"line-number"},[t._v("13")]),a("br"),a("span",{staticClass:"line-number"},[t._v("14")]),a("br"),a("span",{staticClass:"line-number"},[t._v("15")]),a("br"),a("span",{staticClass:"line-number"},[t._v("16")]),a("br"),a("span",{staticClass:"line-number"},[t._v("17")]),a("br")])]),a("p",[t._v("《沁园春·雪》 "),a("Badge",{attrs:{text:"摘"}})],1),t._v(" "),a("p",[t._v("北国风光"),a("Badge",{attrs:{text:"注释",type:"warning"}}),t._v(",千里冰封,万里雪飘。")],1),t._v(" "),a("blockquote",[a("Badge",{attrs:{text:"译文",type:"error",vertical:"middle"}}),t._v(": 北方的风光。\n")],1),t._v(" "),a("h2",{attrs:{id:"todo"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#todo"}},[t._v("#")]),t._v(" TODO")]),t._v(" "),a("ul",[a("li",[a("code",[t._v("RSS")]),t._v(" 订阅服务")])]),t._v(" "),a("h2",{attrs:{id:"代码块选项卡"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#代码块选项卡"}},[t._v("#")]),t._v(" 代码块选项卡")]),t._v(" "),a("code-group",[a("code-block",{attrs:{title:"YARN",active:""}},[a("div",{staticClass:"language-bash line-numbers-mode"},[a("pre",{pre:!0,attrs:{class:"language-bash"}},[a("code",[a("span",{pre:!0,attrs:{class:"token function"}},[t._v("yarn")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("add")]),t._v(" vuepress-theme-vdoing "),a("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("-D")]),t._v("\n")])]),t._v(" "),a("div",{staticClass:"line-numbers-wrapper"},[a("span",{staticClass:"line-number"},[t._v("1")]),a("br")])])]),t._v(" "),a("code-block",{attrs:{title:"NPM"}},[a("div",{staticClass:"language-bash line-numbers-mode"},[a("pre",{pre:!0,attrs:{class:"language-bash"}},[a("code",[a("span",{pre:!0,attrs:{class:"token function"}},[t._v("npm")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("install")]),t._v(" vuepress-theme-vdoing "),a("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("-D")]),t._v("\n")])]),t._v(" "),a("div",{staticClass:"line-numbers-wrapper"},[a("span",{staticClass:"line-number"},[t._v("1")]),a("br")])])])],1),t._v(" "),a("h2",{attrs:{id:"链接"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#链接"}},[t._v("#")]),t._v(" 链接")]),t._v(" "),a("ul",[a("li",[a("a",{attrs:{href:"https://doc.xugaoyi.com/pages/197691/",target:"_blank",rel:"noopener noreferrer"}},[t._v("vuepress-theme-vdoing"),a("OutboundLink")],1)])])],1)}),[],!1,null,null,null);a.default=e.exports}}]);
\ No newline at end of file
diff --git a/assets/js/93.7c1db7dc.js b/assets/js/93.7c1db7dc.js
new file mode 100644
index 0000000000..476b967551
--- /dev/null
+++ b/assets/js/93.7c1db7dc.js
@@ -0,0 +1 @@
+(window.webpackJsonp=window.webpackJsonp||[]).push([[93],{419:function(t,r,a){"use strict";a.r(r);var e=a(4),s=Object(e.a)({},(function(){var t=this,r=t._self._c;return r("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[r("h2",{attrs:{id:"常用"}},[r("a",{staticClass:"header-anchor",attrs:{href:"#常用"}},[t._v("#")]),t._v(" 常用")]),t._v(" "),r("h3",{attrs:{id:"谢谢"}},[r("a",{staticClass:"header-anchor",attrs:{href:"#谢谢"}},[t._v("#")]),t._v(" 谢谢")]),t._v(" "),r("p",[t._v("一、委婉的客套,表达自己的荣幸")]),t._v(" "),r("p",[t._v("如: 我本来挺无聊的,幸好你来找我帮忙,让我有些事情可做,正好打发时间。并且我也正好喜欢干这个事,你不用客气,顺手的事情。")]),t._v(" "),r("p",[t._v("二、大方接受,拉近关系")]),t._v(" "),r("p",[t._v("没事,咱们两个什么关系,你别跟我客气,有啥事情尽管吩咐。只要我能够办到的,我二话不说,肯定会帮你的")]),t._v(" "),r("p",[t._v("三、主动吸引,大胆追求")]),t._v(" "),r("p",[t._v("正好我帮了你,明天我们一起去看电影吧")]),t._v(" "),r("h2",{attrs:{id:"链接"}},[r("a",{staticClass:"header-anchor",attrs:{href:"#链接"}},[t._v("#")]),t._v(" 链接")]),t._v(" "),r("ul",[r("li",[r("a",{attrs:{href:"https://www.163.com/dy/article/G7VM2ACI0528D2LL.html",target:"_blank",rel:"noopener noreferrer"}},[t._v("https://www.163.com/dy/article/G7VM2ACI0528D2LL.html"),r("OutboundLink")],1)])])])}),[],!1,null,null,null);r.default=s.exports}}]);
\ No newline at end of file
diff --git a/assets/js/94.c33623d6.js b/assets/js/94.c33623d6.js
new file mode 100644
index 0000000000..e978d962b1
--- /dev/null
+++ b/assets/js/94.c33623d6.js
@@ -0,0 +1 @@
+(window.webpackJsonp=window.webpackJsonp||[]).push([[94],{420:function(t,e,r){"use strict";r.r(e);var s=r(4),_=Object(s.a)({},(function(){var t=this,e=t._self._c;return e("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[e("h2",{attrs:{id:"高效获取信息-rss-订阅服务"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#高效获取信息-rss-订阅服务"}},[t._v("#")]),t._v(" 高效获取信息-RSS 订阅服务")]),t._v(" "),e("blockquote",[e("p",[e("a",{attrs:{href:"https://sspai.com/post/56391",target:"_blank",rel:"noopener noreferrer"}},[t._v("高效获取信息,你需要这份 RSS 入门指南-少数派"),e("OutboundLink")],1)])]),t._v(" "),e("h3",{attrs:{id:"什么是-rss"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#什么是-rss"}},[t._v("#")]),t._v(" 什么是 RSS")]),t._v(" "),e("p",[e("code",[t._v("RSS")]),t._v("(Really Simple Syndication)是一种用于获取即时更新内容的标准格式。它允许用户订阅自己感兴趣的网站内容,并通过一个 RSS 阅读器或 RSS 聚合器收集和显示这些内容。RSS 聚合器是一种工具,能够将多个不同来源的 RSS 订阅汇集在一起,以便用户可以在一个地方查看多个网站的更新。")]),t._v(" "),e("p",[t._v("一个 RSS 聚合器和网络是一个提供订阅和管理 RSS 源的服务。它通常包括以下功能:")]),t._v(" "),e("ul",[e("li",[t._v("订阅管理:用户可以添加和删除他们感兴趣的 RSS 源。他们可以根据自己的兴趣和喜好,定制自己的订阅列表。")]),t._v(" "),e("li",[t._v("更新通知:一旦用户订阅的网站有新的内容发布,聚合器会自动检测到,并向用户发送通知。这可以通过电子邮件、移动应用程序通知或在用户界面上显示未读计数等方式实现。")]),t._v(" "),e("li",[t._v("聚合显示:聚合器会将多个订阅的网站内容集中在一个界面中显示,用户可以在一个地方浏览和阅读各个网站的更新。这样,用户不必逐个访问每个网站来查看新的内容。")]),t._v(" "),e("li",[t._v("分类和标签:聚合器通常允许用户为订阅的源分配分类和标签,以便更好地组织和管理订阅列表。")]),t._v(" "),e("li",[t._v("搜索功能:聚合器可能提供搜索功能,使用户能够在他们的订阅中查找特定的关键词或主题。")]),t._v(" "),e("li",[t._v("社交分享:有些聚合器还允许用户将感兴趣的内容分享到社交媒体平台或通过电子邮件发送给其他人。")])]),t._v(" "),e("p",[t._v("通过使用一个 RSS 聚合器和网络,用户可以更方便地跟踪自己关注的网站和内容更新。它提供了一个集中管理和浏览订阅的平台,使用户能够更高效地获取所需的信息。")]),t._v(" "),e("h3",{attrs:{id:"订阅程序简介"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#订阅程序简介"}},[t._v("#")]),t._v(" 订阅程序简介")]),t._v(" "),e("p",[t._v("构建自己的 RSS 订阅程序可以涉及以下几个步骤:")]),t._v(" "),e("ol",[e("li",[t._v("确定需求:首先,明确你的 RSS 订阅程序的目标和功能。考虑你想要订阅的网站类型、数据的处理方式以及用户界面的设计。")]),t._v(" "),e("li",[t._v("获取 RSS 源:确定你要订阅的网站,并找到它们的 RSS 源链接。RSS 源链接通常可以在网站的页面底部或头部找到,以及在 HTML 代码中的"),e("link"),t._v("标签中。")]),t._v(" "),e("li",[t._v("解析 RSS 数据:使用编程语言和相关的库或框架,如 Python 的 feedparser 库,来解析 RSS 数据。这样你可以从每个 RSS 源中提取标题、摘要、链接和其他相关信息。")]),t._v(" "),e("li",[t._v("存储数据:确定如何存储解析的 RSS 数据。你可以选择使用数据库,如 MySQL 或 MongoDB,或者使用文件系统存储数据。")]),t._v(" "),e("li",[t._v("定期更新:设置一个定期的任务或脚本来获取和更新 RSS 数据。你可以使用定时任务工具,如 cron(Unix)或 Task Scheduler(Windows),或者在你的程序中实现一个定时循环来执行这个任务。")]),t._v(" "),e("li",[t._v("用户界面:设计和开发一个用户界面,使用户能够订阅和管理 RSS 源,并查看更新的内容。你可以使用 Web 开发技术,如 HTML、CSS 和 JavaScript,或者选择开发桌面或移动应用程序。")]),t._v(" "),e("li",[t._v("用户管理:实现用户认证和授权功能,以便用户可以创建个人账户、保存其订阅设置和与其他用户进行交互。")]),t._v(" "),e("li",[t._v("通知和交互:为用户提供通知机制,以便他们可以接收更新的提醒,如电子邮件通知或移动应用程序推送通知。另外,你还可以提供用户交互功能,如评论、点赞和分享。")]),t._v(" "),e("li",[t._v("测试和优化:对你的 RSS 订阅程序进行全面的测试,确保其功能正常并具有良好的用户体验。根据用户反馈和需求进行改进和优化。")]),t._v(" "),e("li",[t._v("部署和维护:将你的 RSS 订阅程序部署到服务器或云平台上,并确保它的可用性和稳定性。定期进行维护和更新,以适应新的需求和技术变化。")])]),t._v(" "),e("p",[t._v("需要注意的是,构建一个完整的 RSS 订阅程序需要一定的编程知识和技能。你可以选择使用现有的开源框架或库来简化开发过程,如 Django(Python)或 Ruby on Rails(Ruby)。另外,查阅相关的文档和教程,并积极参与相关开发社区,将有助于你更好地理解和解决遇到的问题。")]),t._v(" "),e("h2",{attrs:{id:"通过-github-订阅-hacker-news-每日-top-10"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#通过-github-订阅-hacker-news-每日-top-10"}},[t._v("#")]),t._v(" 通过 GitHub 订阅 Hacker News 每日 top 10")]),t._v(" "),e("div",{staticClass:"custom-block tip"},[e("p",{staticClass:"custom-block-title"},[t._v("提示")]),t._v(" "),e("p",[t._v("这是我偶然间看到 timqian 的一篇文章,按照这个思路可以做很多事情,文章链接\n"),e("a",{attrs:{href:"https://blog.t9t.io/headllines-2020-09-03/",target:"_blank",rel:"noopener noreferrer"}},[t._v("通过 GitHub 订阅 Hacker News 每日 top 10"),e("OutboundLink")],1)]),t._v(" "),e("p",[t._v("此项目 mock 发布到: "),e("a",{attrs:{href:"https://github.com/jacky1234/blogPages/issues",target:"_blank",rel:"noopener noreferrer"}},[t._v("https://github.com/jacky1234/blogPages/issues"),e("OutboundLink")],1)])]),t._v(" "),e("p",[e("strong",[t._v("Hacker News 网站介绍")])]),t._v(" "),e("p",[t._v("Hacker News("),e("a",{attrs:{href:"https://news.ycombinator.com/",target:"_blank",rel:"noopener noreferrer"}},[t._v("https://news.ycombinator.com/"),e("OutboundLink")],1),t._v(")。Hacker News 是一个知名的社区驱动的科技新闻聚合网站,由风投公司 Y Combinator 创建和运营。")]),t._v(" "),e("p",[t._v("Hacker News 以其简洁而干净的界面而闻名,旨在提供有关计算机科学、创业、科技和相关领域的新闻、文章和讨论。这个网站的用户主要是来自科技行业、创业者、开发者和对技术感兴趣的人。")]),t._v(" "),e("p",[e("strong",[t._v("主要特点")])]),t._v(" "),e("ul",[e("li",[t._v("投票和排序:Hacker News 的用户可以投票对他们认为有价值的新闻和评论。这些投票决定了内容在页面上的排名,从而使用户可以看到最有趣和受欢迎的内容。")]),t._v(" "),e("li",[t._v("评论系统:每篇新闻都有一个评论区,用户可以在这里讨论和分享他们的观点。Hacker News 的评论区通常充满了高质量的技术和行业相关的讨论。")]),t._v(" "),e("li",[t._v("每日和每周最佳:Hacker News 社区会每天和每周评选出最佳的新闻和讨论,这些内容通常反映了最新的技术趋势和有趣的见解。")]),t._v(" "),e("li",[t._v("无广告和质量控制:Hacker News 没有广告,这有助于保持用户体验的清爽和聚焦在内容上。此外,网站还采取了措施来防止滥用和垃圾信息的出现,以确保内容的质量。")])]),t._v(" "),e("p",[e("strong",[t._v("投票")]),t._v("\nHacker News 采用了一种投票衰减机制。这意味着新闻和文章的排名会随着时间的推移逐渐下降,而每天并不会重新进行投票。然而,用户可以随时投票支持他们认为有价值的内容,并通过评论和讨论来影响话题的发展。这种机制旨在确保新的和有趣的内容能够在网站上持续受到关注,同时避免过度重视旧的内容")]),t._v(" "),e("p",[t._v("Hacker News 成为了一个受欢迎的平台,吸引了广大的技术社区,并且提供了丰富的技术和行业信息。无论您是想了解最新的科技新闻、寻找有关创业的见解,还是与其他技术爱好者进行交流,Hacker News 都是一个值得关注和参与的社区。")])])}),[],!1,null,null,null);e.default=_.exports}}]);
\ No newline at end of file
diff --git a/assets/js/95.1f164633.js b/assets/js/95.1f164633.js
new file mode 100644
index 0000000000..bb48fae09f
--- /dev/null
+++ b/assets/js/95.1f164633.js
@@ -0,0 +1 @@
+(window.webpackJsonp=window.webpackJsonp||[]).push([[95],{421:function(s,t,a){"use strict";a.r(t);var n=a(4),e=Object(n.a)({},(function(){var s=this,t=s._self._c;return t("ContentSlotsDistributor",{attrs:{"slot-key":s.$parent.slotKey}},[t("h2",{attrs:{id:"概念"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#概念"}},[s._v("#")]),s._v(" 概念")]),s._v(" "),t("h3",{attrs:{id:"全双工-半双工-单工"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#全双工-半双工-单工"}},[s._v("#")]),s._v(" 全双工/半双工/单工")]),s._v(" "),t("blockquote",[t("p",[t("a",{attrs:{href:"https://www.cnblogs.com/kungfupanda/archive/2009/12/22/1629972.html",target:"_blank",rel:"noopener noreferrer"}},[s._v("https://www.cnblogs.com/kungfupanda/archive/2009/12/22/1629972.html"),t("OutboundLink")],1)])]),s._v(" "),t("h2",{attrs:{id:"前端"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#前端"}},[s._v("#")]),s._v(" 前端")]),s._v(" "),t("h3",{attrs:{id:"lds"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#lds"}},[s._v("#")]),s._v(" LDS")]),s._v(" "),t("p",[s._v('在计算机编程中,"LDS" 通常指的是 "Local Data Storage",也就是本地数据存储。本地缓存是一种在计算机程序中常用的技术,用于临时存储数据,以便在稍后的时间快速访问。')]),s._v(" "),t("p",[s._v("通过使用本地缓存,程序可以避免频繁地从远程服务器或磁盘读取数据,从而提高应用程序的性能和响应速度。当程序需要某些数据时,它首先会查看本地缓存是否有该数据的副本。如果有,程序将直接从本地缓存中获取数据,而不必重新获取远程数据或从磁盘读取。")]),s._v(" "),t("p",[s._v("本地缓存通常用于存储临时性的数据,例如用户的偏好设置、临时计算结果、用户界面状态等。这些数据在程序的执行期间可能会频繁地被读取和写入,因此将它们存储在本地缓存中可以大大提高应用程序的性能和效率。")]),s._v(" "),t("p",[s._v("总的来说,LDS(本地缓存)在计算机程序中是一种重要的技术,用于临时存储数据并提高应用程序的性能。")]),s._v(" "),t("h3",{attrs:{id:"html-中的-ssr"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#html-中的-ssr"}},[s._v("#")]),s._v(" html 中的 SSR")]),s._v(" "),t("p",[s._v('在 HTML 上,"SSR" 通常指的是"Server-Side Rendering",这是一种用于构建 Web 应用程序的技术。与前端渲染(Client-Side Rendering)不同,SSR 在服务器端生成 HTML 内容,然后将其发送到客户端,这样可以提供更好的首次加载性能、搜索引擎优化(SEO)和用户体验。')]),s._v(" "),t("p",[s._v("以下是关于 HTML 中的 SSR 技术的一些介绍:")]),s._v(" "),t("ol",[t("li",[t("p",[s._v("Server-Side Rendering(SSR):\nSSR 是一种将 Web 应用程序的页面内容在服务器端进行渲染,然后将渲染好的 HTML 内容发送到客户端的过程。这使得客户端在加载页面时无需等待 JavaScript 的加载和执行,提高了首次加载速度。")])]),s._v(" "),t("li",[t("p",[s._v("优势:")])])]),s._v(" "),t("ul",[t("li",[s._v("首次加载性能:因为服务器已经渲染好了 HTML 内容,用户在访问时可以立即看到页面内容,无需等待 JavaScript 加载和执行。")]),s._v(" "),t("li",[s._v("搜索引擎优化(SEO):搜索引擎可以更容易地爬取服务器端渲染的内容,提高页面在搜索结果中的排名。")]),s._v(" "),t("li",[s._v("用户体验:用户不会在加载时看到空白页面或加载中的状态,提供更好的用户体验。")])]),s._v(" "),t("ol",{attrs:{start:"3"}},[t("li",[s._v("实现方式:")])]),s._v(" "),t("ul",[t("li",[s._v("前端框架支持:许多前端框架(如 React、Vue、Angular 等)都提供了 SSR 的支持,通过服务器端渲染框架可以实现服务器端渲染。")]),s._v(" "),t("li",[s._v("服务器配置:需要在服务器端配置以支持 SSR,通常需要使用 Node.js 等服务器端技术。")]),s._v(" "),t("li",[s._v("路由管理:SSR 通常需要处理路由,确保服务器端和客户端路由保持同步。")])]),s._v(" "),t("ol",{attrs:{start:"4"}},[t("li",[s._v("挑战:")])]),s._v(" "),t("ul",[t("li",[s._v("复杂性:SSR 需要服务器端和客户端之间的协调,可能增加应用程序的复杂性。")]),s._v(" "),t("li",[s._v("性能开销:服务器端渲染需要在服务器上执行额外的计算和渲染,可能导致性能开销。")]),s._v(" "),t("li",[s._v("前后端分离:如果应用程序已经是前后端分离的,将其改造为 SSR 可能需要一些工作。")])]),s._v(" "),t("ol",{attrs:{start:"5"}},[t("li",[s._v("使用场景:")])]),s._v(" "),t("ul",[t("li",[s._v("内容驱动网站:对于以内容为主要特点的网站,SSR 可以提供更好的 SEO 支持。")]),s._v(" "),t("li",[s._v("首次加载性能要求高:对于要求快速首次加载的应用,SSR 可以提供更好的用户体验。")])]),s._v(" "),t("p",[s._v("总之,Server-Side Rendering(SSR)是一种在服务器端进行 HTML 渲染的技术,可以提供更好的首次加载性能和搜索引擎优化。在使用时,需要考虑应用程序的架构和性能需求,权衡其优劣势。")]),s._v(" "),t("h2",{attrs:{id:"后端"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#后端"}},[s._v("#")]),s._v(" 后端")]),s._v(" "),t("h3",{attrs:{id:"反向-正向代理"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#反向-正向代理"}},[s._v("#")]),s._v(" 反向/正向代理")]),s._v(" "),t("p",[s._v("在 IT 行业中,反向代理(Reverse Proxy)是一种网络代理服务器的配置方式,它充当了服务器和客户端之间的中间人。与传统的正向代理(Forward Proxy)不同,正向代理是为客户端提供代理服务,而反向代理是为服务器提供代理服务。")]),s._v(" "),t("p",[s._v("反向代理的工作原理是将客户端的请求转发到后端服务器,并将服务器的响应返回给客户端。客户端发送请求时,先与反向代理建立连接,然后反向代理根据配置的规则将请求转发到后端的真实服务器上。后端服务器处理请求并返回响应,然后反向代理将响应返回给客户端,客户端则认为响应是直接来自于反向代理。")]),s._v(" "),t("p",[s._v("反向代理的主要作用有以下几个方面:")]),s._v(" "),t("ol",[t("li",[s._v("负载均衡:反向代理可以根据预设的负载均衡算法将客户端请求分发到多个后端服务器,从而平衡服务器的负载,提高系统的性能和可靠性。")]),s._v(" "),t("li",[s._v("缓存静态内容:反向代理可以缓存静态资源,如图片、CSS 文件等,以减轻后端服务器的负担,提高响应速度。")]),s._v(" "),t("li",[s._v("SSL/TLS 加密:反向代理可以作为 SSL/TLS 终端,将客户端的 HTTPS 请求转发给后端服务器,并将响应返回给客户端,实现对传输内容的加密和安全性保护。")]),s._v(" "),t("li",[s._v("安全过滤:反向代理可以对传入的请求进行安全过滤和防御,例如阻止恶意请求、DDoS 攻击和 Web 应用程序漏洞等。")])]),s._v(" "),t("p",[s._v("通过使用反向代理,可以提高网络应用的可扩展性、安全性和性能,同时为系统管理员提供了更好的控制和管理手段。")]),s._v(" "),t("h3",{attrs:{id:"wlan0"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#wlan0"}},[s._v("#")]),s._v(" wlan0")]),s._v(" "),t("p",[s._v('"wlan0"是指在 Android 设备上表示无线局域网(Wi-Fi)接口的网络接口名称。在大多数 Android 设备中,无线网络接口通常被标识为"wlan0",但也有一些设备可能使用其他名称,如"wlan1"、"wlan2"等,这取决于设备的硬件和配置。')]),s._v(" "),t("p",[s._v('通过"wlan0"网络接口,Android 设备可以连接到 Wi-Fi 网络并进行无线通信。它负责处理与 Wi-Fi 相关的功能,包括扫描可用网络、建立连接、传输数据等。')]),s._v(" "),t("p",[s._v("使用命令"),t("code",[s._v("adb shell ip address show wlan")]),s._v('"可以查看设备上"wlan0"接口的 IP 地址信息。这样可以获取设备当前连接的 Wi-Fi 网络的 IP 地址,以及其他相关的网络配置信息。')]),s._v(" "),t("h3",{attrs:{id:"devops"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#devops"}},[s._v("#")]),s._v(" DevOps")]),s._v(" "),t("p",[t("strong",[s._v("DevOps 是一种软件开发和运维的实践方法")]),s._v(",旨在通过加强开发团队和运维团队之间的协作和沟通,实现快速、可靠的软件交付和部署。")]),s._v(" "),t("p",[s._v("DevOps 的目标是通过自动化、持续集成和持续交付等实践,将软件开发、测试、部署和运维的过程整合起来,从而加快软件的交付速度、提高质量,并增强系统的稳定性和可扩展性。")]),s._v(" "),t("p",[s._v("DevOps 强调以下几个关键概念和实践:")]),s._v(" "),t("ol",[t("li",[s._v("自动化:通过自动化工具和流程,减少人工操作,提高效率和一致性。")]),s._v(" "),t("li",[s._v("持续集成:将代码频繁地集成到共享的代码库中,通过自动化构建、测试和静态代码分析等环节,确保代码质量和稳定性。")]),s._v(" "),t("li",[s._v("持续交付:在持续集成的基础上,将软件交付到生产环境中,实现快速的软件发布和部署。")]),s._v(" "),t("li",[s._v("基础设施即代码:使用代码和自动化工具来管理和配置基础设施,以便快速、可靠地创建、部署和管理基础设施资源。")]),s._v(" "),t("li",[s._v("监控和日志:通过实时监控和日志记录,及时发现和解决系统问题,提高系统的可用性和性能。")]),s._v(" "),t("li",[s._v("跨团队协作:强调开发团队和运维团队之间的协作和沟通,打破组织内的隔阂,促进快速响应和问题解决。")])]),s._v(" "),t("p",[s._v("DevOps 的目标是通过整合开发和运维流程,加强团队协作,实现更高效、更可靠的软件交付和运维。它可以帮助组织更快速地响应市场需求、降低软件交付的风险和成本,并提供更好的用户体验。")]),s._v(" "),t("h3",{attrs:{id:"数据库系统"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#数据库系统"}},[s._v("#")]),s._v(" 数据库系统")]),s._v(" "),t("blockquote",[t("p",[s._v("MongoDB、Redis 和关系型数据库是常见的数据库系统,它们在数据存储和访问方面具有不同的特点和适用场景。")])]),s._v(" "),t("p",[s._v("MongoDB、Redis 和关系型数据库是常见的数据库系统,它们在数据存储和访问方面具有不同的特点和适用场景。")]),s._v(" "),t("ol",[t("li",[s._v("关系型数据库(如 MySQL、PostgreSQL):")])]),s._v(" "),t("ul",[t("li",[s._v("结构化数据存储:关系型数据库使用表格(表)来组织和存储数据,数据以行和列的形式呈现,并且需要定义表的结构(模式)。")]),s._v(" "),t("li",[s._v("强一致性:关系型数据库提供强一致性,即数据的读取和写入操作是同步和可靠的。")]),s._v(" "),t("li",[s._v("SQL 查询语言:关系型数据库使用 SQL(Structured Query Language)进行数据查询和操作。")]),s._v(" "),t("li",[s._v("适用场景:适合存储结构化数据,如订单、用户信息等,并需要进行复杂的事务处理和关系查询。")])]),s._v(" "),t("ol",{attrs:{start:"2"}},[t("li",[s._v("MongoDB:")])]),s._v(" "),t("ul",[t("li",[s._v("非结构化数据存储:MongoDB 是一种面向文档的数据库,数据以类似 JSON 的 BSON 格式存储,不需要预定义模式,可以灵活地存储非结构化数据。")]),s._v(" "),t("li",[s._v("高可扩展性:MongoDB 支持水平扩展,可以轻松处理大规模数据和高并发请求。")]),s._v(" "),t("li",[s._v("分布式数据库:MongoDB 可以作为分布式数据库,通过副本集和分片技术实现数据的冗余备份和水平切分。")]),s._v(" "),t("li",[s._v("适用场景:适合存储大量非结构化数据,如日志、用户行为记录等,并需要灵活性和可扩展性。")])]),s._v(" "),t("ol",{attrs:{start:"3"}},[t("li",[s._v("Redis:")])]),s._v(" "),t("ul",[t("li",[s._v("键值存储:Redis 是一种键值存储数据库,数据以键值对的形式存储,可以存储多种类型的值,如字符串、列表、哈希表等。")]),s._v(" "),t("li",[s._v("内存数据库:Redis 将数据存储在内存中,因此读取和写入速度非常快,适合高速缓存和需要快速访问的应用场景。")]),s._v(" "),t("li",[s._v("高性能:Redis 具有高并发性能和低延迟,适合处理实时数据和高频读写操作。")]),s._v(" "),t("li",[s._v("适用场景:适合缓存、会话管理、排行榜、发布/订阅等场景,以及需要高性能、低延迟的应用程序。")])]),s._v(" "),t("p",[s._v("总结:\n关系型数据库适合存储结构化数据和复杂的关系查询,MongoDB 适合存储非结构化数据和需要灵活性、可扩展性的场景,而 Redis 适合高速缓存和需要快速访问的应用场景。选择合适的数据库取决于数据的特性、应用程序的需求以及性能和可扩展性的要求。在某些情况下,这些数据库系统也可以结合使用,以满足不同的需求。")]),s._v(" "),t("h3",{attrs:{id:"服务熔断"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#服务熔断"}},[s._v("#")]),s._v(" 服务熔断")]),s._v(" "),t("p",[s._v("服务器的熔断机制是一种用于保护系统和服务稳定性的机制。它是一种自动化的故障处理机制,旨在避免系统由于故障或异常情况而崩溃或无法正常工作。")]),s._v(" "),t("p",[s._v("熔断机制通常在分布式系统和微服务架构中使用,用于处理服务间的通信和依赖关系。当一个服务发生故障或异常时,熔断机制会自动断开对该服务的调用,并在一段时间内阻止对该服务的进一步请求。这样可以避免故障服务的连锁反应,保护系统的稳定性和可靠性。")]),s._v(" "),t("p",[s._v("熔断机制的主要目标是:")]),s._v(" "),t("ol",[t("li",[s._v("快速失败:在服务发生故障或异常时,立即中断对该服务的调用,而不是等待超时或无限等待响应。")]),s._v(" "),t("li",[s._v("避免资源浪费:停止对故障服务的请求可以释放资源,避免浪费服务器资源和网络带宽。")]),s._v(" "),t("li",[s._v("快速恢复:熔断机制通常会有一个恢复时间窗口,在该时间窗口内尝试重新调用故障服务,以验证其是否已经恢复正常。如果故障服务恢复正常,则继续正常的请求转发。")])]),s._v(" "),t("p",[s._v("熔断机制的实现通常通过设置一些 "),t("strong",[s._v("阈值和监控机制")]),s._v(" 来触发熔断和恢复。例如,可以设置对服务的请求失败率、响应时间超过阈值等指标进行监控,当这些指标超过预设的阈值时,触发熔断操作。")]),s._v(" "),t("p",[s._v("熔断机制的好处是可以提高系统的稳定性和可用性,避免故障服务对整个系统的影响。它还可以减少客户端对故障服务的等待时间,提供更好的用户体验。同时,熔断机制也可以提供实时的故障监控和告警信息,帮助运维人员及时发现和解决问题。")]),s._v(" "),t("p",[s._v("总而言之,服务器的熔断机制是一种自动化的故障处理机制,用于保护系统和服务的稳定性。通过快速失败、避免资源浪费和快速恢复等措施,它可以防止故障服务对整个系统造成连锁反应,并提供更好的用户体验和系统可靠性。")]),s._v(" "),t("h3",{attrs:{id:"uv-vv-pv-dau-gmv"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#uv-vv-pv-dau-gmv"}},[s._v("#")]),s._v(" uv/vv/pv/dau/gmv")]),s._v(" "),t("p",[s._v("在互联网和网站分析领域中,UV、PV 和 VV 是常用的指标,用于衡量网站流量和用户活跃度。")]),s._v(" "),t("ul",[t("li",[s._v("UV(Unique Visitor)表示独立访客数,即在一段时间内(通常是一天),访问网站的不同用户数量。UV 指标用于计算网站的用户数量和覆盖范围,每个独立访客只计算一次,无论其在该时间段内访问了多少次。")]),s._v(" "),t("li",[s._v("PV(Page View)表示页面浏览量,即网站在一段时间内的页面浏览次数。每当用户访问一个页面,PV 就会增加一次。PV 指标用于衡量网站的流量和页面受欢迎程度,高 PV 值通常表示用户对网站内容的浏览兴趣。")]),s._v(" "),t("li",[s._v("VV(Visit View)表示访问次数,即在一段时间内的访问次数。VV 指标统计了用户对网站的不同访问行为,每次用户进入网站算作一次访问,无论期间有多少页面浏览。")]),s._v(" "),t("li",[s._v("DAU(Daily Active User)日活跃用户数量")]),s._v(" "),t("li",[s._v("MAU(monthly active users)月活跃用户人数")]),s._v(" "),t("li",[s._v("GMV(Gross Merchandise Volume,网站成交金额) 通常称为网站成交金额,属于电商平台企业成交类指标,主要指拍下订单的总金额,包含付款和未付款两部分")])]),s._v(" "),t("p",[s._v("这些指标在网站分析中被广泛使用,可以帮助分析师和网站管理员了解网站的流量情况、用户活跃度和用户行为,从而进行数据分析和优化网站策略。")]),s._v(" "),t("h3",{attrs:{id:"faas"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#faas"}},[s._v("#")]),s._v(" FaaS")]),s._v(" "),t("blockquote",[t("p",[s._v("FaaS(Function as a Service)")])]),s._v(" "),t("ul",[t("li",[s._v("Event-driven execution.")]),s._v(" "),t("li",[s._v("Developers delegate all server-specific tasks to the FaaS platform.")]),s._v(" "),t("li",[s._v("Developers only write business logic that is invoked by the platform, allowing for a more resilient requirement - - evolution as business needs change.")])]),s._v(" "),t("h3",{attrs:{id:"url-编码"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#url-编码"}},[s._v("#")]),s._v(" URL 编码")]),s._v(" "),t("blockquote",[t("p",[t("code",[s._v("%2F")]),s._v(" 与 "),t("code",[s._v("/")]),s._v(" 的编码关系是怎样的?")])]),s._v(" "),t("p",[t("code",[s._v("%2F")]),s._v(" 和 "),t("code",[s._v("/")]),s._v(" 之间存在编码关系。")]),s._v(" "),t("p",[s._v("URL 编码是一种将特殊字符转换为 URL 安全格式的过程。在 URL 中,某些字符具有特殊含义,如 "),t("code",[s._v("/")]),s._v(" 是用于分隔路径的字符。如果一个字符在 URL 中具有特殊含义,但需要表示该字符本身而不是其特殊含义,就需要对其进行编码。")]),s._v(" "),t("p",[s._v("在 URL 编码中,每个字符都可以表示为 "),t("code",[s._v("%")]),s._v(" 加上两个十六进制数字的形式。对于 "),t("code",[s._v("/")]),s._v(" 字符,其编码是 "),t("code",[s._v("%2F")]),s._v("。")]),s._v(" "),t("p",[s._v("当在 URL 中包含 "),t("code",[s._v("/")]),s._v(" 字符时,为了避免与路径分隔符混淆,需要对其进行编码,即将 "),t("code",[s._v("/")]),s._v(" 转换为 "),t("code",[s._v("%2F")]),s._v("。这样可以确保在 URL 中正确传递和解析这个字符。")]),s._v(" "),t("p",[s._v("例如,如果要将路径 "),t("code",[s._v("/path/to/file")]),s._v(" 进行 URL 编码,编码后的结果将是 "),t("code",[s._v("%2Fpath%2Fto%2Ffile")]),s._v("。在这个编码后的 URL 中,"),t("code",[s._v("%2F")]),s._v(" 代表原始的 "),t("code",[s._v("/")]),s._v(" 字符。")]),s._v(" "),t("p",[s._v("总结起来,"),t("code",[s._v("%2F")]),s._v(" 是 "),t("code",[s._v("/")]),s._v(" 字符的 URL 编码表示形式,用于在 URL 中表示路径分隔符而不引起歧义。")]),s._v(" "),t("p",[t("strong",[s._v("常用 URL 编码")])]),s._v(" "),t("p",[s._v("URL 编码是一种将特殊字符转换为 URL 安全格式的方法,通常使用百分号(%)后跟两个十六进制数字表示字符。以下是一些常见的 URL 编码:")]),s._v(" "),t("ul",[t("li",[s._v('空格: 空格通常被编码为"%20"。')]),s._v(" "),t("li",[s._v('问号(?): 问号通常被编码为"%3F"。')]),s._v(" "),t("li",[s._v('等号(=): 等号通常被编码为"%3D"。')]),s._v(" "),t("li",[s._v('与号(&): 与号通常被编码为"%26"。')]),s._v(" "),t("li",[s._v('斜杠(/): 斜杠通常被编码为"%2F"。')]),s._v(" "),t("li",[s._v('冒号(:): 冒号通常被编码为"%3A"。')]),s._v(" "),t("li",[s._v('井号(#): 井号通常被编码为"%23"。')]),s._v(" "),t("li",[s._v('百分号(%): 百分号自身也需要进行编码,变成"%25"。')]),s._v(" "),t("li",[s._v('加号(+): 在 URL 查询字符串中,加号通常用来表示空格,所以它有时需要编码为"%2B"。')]),s._v(" "),t("li",[s._v("其他特殊字符: 根据需要,其他特殊字符也可以被编码,例如:空格(%20)、双引号(%22)、单引号(%27)、大于号(%3E)、小于号(%3C)等。")])]),s._v(" "),t("p",[s._v("请注意,不同编程语言和库提供了用于 URL 编码和解码的内置函数或方法,以便更容易地处理 URL 中的特殊字符。")]),s._v(" "),t("h3",{attrs:{id:"ascii"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#ascii"}},[s._v("#")]),s._v(" ASCII")]),s._v(" "),t("p",[s._v("ASCII(American Standard Code for Information Interchange)字符集是一个最初为英语和其他西欧语言设计的字符编码标准。它使用 7 位(或 8 位,包括一个奇偶校验位)来表示字符,包括控制字符、数字、字母、标点符号和特殊字符。ASCII 字符集包括以下内容:")]),s._v(" "),t("ul",[t("li",[t("p",[t("strong",[s._v("控制字符")]),s._v(": 这些字符通常没有可见的图形表示,用于控制文本终端和通信设备的行为。例如,换行符(\\n)、回车符(\\r)和制表符(\\t)等。")])]),s._v(" "),t("li",[t("p",[t("strong",[s._v("可打印字符")]),s._v(": 这些字符具有可见的图形表示,包括大写字母(A-Z)、小写字母(a-z)、数字(0-9)和常见标点符号(例如逗号、句点、感叹号等)。")])]),s._v(" "),t("li",[t("p",[t("strong",[s._v("特殊字符")]),s._v(": 这些字符包括空格(空格符)、制表符(\\t)、换行符(\\n)、回车符(\\r)以及其他一些特殊用途的字符(例如退格符 \\b)。")])])]),s._v(" "),t("p",[s._v("ASCII 字符集总共包含 128 个字符,编号从 0 到 127。这些字符在计算机和通信中被广泛使用,尤其是在早期计算机系统和文本通信中。由于它是一个 7 位字符集,因此只包含 128 个字符,不包括一些非拉丁字符(例如希腊字母、俄罗斯字母等)。")]),s._v(" "),t("p",[s._v("虽然 ASCII 字符集最初是为英语设计的,但它仍然是计算机系统中最常见的字符编码之一,并且在许多编程语言、操作系统和通信协议中被广泛使用。然而,在处理多语言文本和国际化需求时,通常需要使用更多容纳更多字符的字符编码,例如 UTF-8、UTF-16 等。")]),s._v(" "),t("h3",{attrs:{id:"染色概念"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#染色概念"}},[s._v("#")]),s._v(" 染色概念")]),s._v(" "),t("blockquote",[t("p",[s._v("uid 染色")])]),s._v(" "),t("p",[s._v("通过 UID(User ID)染色是一种常见的技术手段,用于在公司的平台或系统中对用户进行标识、分组或定制化处理。UID 是唯一标识用户的标识符,每个用户在系统中都有一个唯一的 UID。")]),s._v(" "),t("p",[s._v("UID 染色的过程通常包括以下几个步骤:")]),s._v(" "),t("ul",[t("li",[t("p",[s._v("用户注册或登录:当用户在公司的平台上注册或登录时,系统会为其分配一个唯一的 UID。")])]),s._v(" "),t("li",[t("p",[s._v("UID 绑定:在用户注册或登录后,系统将 UID 与用户的个人信息进行绑定,以便后续识别和操作。")])]),s._v(" "),t("li",[t("p",[s._v("UID 映射:公司的平台会根据业务需求,将特定的功能、服务或内容与特定的 UID 进行映射。这样可以针对不同的用户群体进行个性化处理。")])]),s._v(" "),t("li",[t("p",[s._v("染色规则定义:在 UID 染色过程中,公司会定义一系列染色规则或条件。这些规则可能基于用户的属性、行为、偏好等信息,用于将用户划分为不同的群体或标签。")])]),s._v(" "),t("li",[t("p",[s._v("个性化处理:通过 UID 染色,公司可以根据染色规则将用户分配到相应的群体或标签中,并针对不同群体提供个性化的功能、服务或内容。例如,向特定群体的用户展示特定的推荐内容、定制化的界面布局等。")])])]),s._v(" "),t("p",[s._v("UID 染色可以帮助公司更好地理解和满足用户的需求,提供更个性化、精准的用户体验。它可以用于用户分析、精准营销、A/B 测试等场景,帮助公司优化产品和服务,提升用户满意度和业务效果。")]),s._v(" "),t("h2",{attrs:{id:"websocket-vs-socket"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#websocket-vs-socket"}},[s._v("#")]),s._v(" websocket VS socket")]),s._v(" "),t("p",[t("strong",[s._v("WebSocket 和 Socket 都是用于在网络上进行通信的技术,但它们在工作方式和应用场景上有很大的区别")]),s._v(":")]),s._v(" "),t("p",[t("strong",[s._v("WebSocket")]),s._v(":")]),s._v(" "),t("ul",[t("li",[s._v("WebSocket 是一种基于 HTTP 协议的通信协议,它允许客户端和服务器之间建立持久连接,以便双向实时通信。(应用层(Application Layer)的通信协议)")]),s._v(" "),t("li",[s._v("WebSocket 协议是一种高级协议,构建在 HTTP 协议之上,因此可以穿越大多数防火墙和代理服务器。")]),s._v(" "),t("li",[s._v("WebSocket 通信是事件驱动的,它允许服务器主动向客户端发送消息,而不需要客户端发起请求。")]),s._v(" "),t("li",[s._v("sWebSocket 通信通常用于实时性要求高的应用,如在线游戏、在线聊天、实时监控等。")])]),s._v(" "),t("p",[t("strong",[s._v("Socket")]),s._v(":")]),s._v(" "),t("ul",[t("li",[s._v("Socket 是一种低级别的通信协议,它提供了一种在网络上建立连接并进行数据传输的通用方式。(位于传输层(Transport Layer))")]),s._v(" "),t("li",[s._v("Socket 通信需要在客户端和服务器之间建立连接,然后通过套接字发送和接收数据。")]),s._v(" "),t("li",[s._v("Socket 通信可以用于各种类型的应用,包括文件传输、远程控制、数据采集等。")]),s._v(" "),t("li",[s._v("Socket 通信通常需要客户端主动发起连接,服务器接受连接请求,因此它通常是一种请求响应型的通信。")])]),s._v(" "),t("p",[t("strong",[s._v("总结")]),s._v(":")]),s._v(" "),t("p",[s._v("WebSocket 适用于实时性要求高的应用,它提供了一种高级别、事件驱动的通信方式,适用于构建实时互动性应用。Socket 通信更灵活,适用于各种不同类型的应用,但它通常需要更多的管理和处理,适用于构建自定义通信协议或处理特定的通信需求。选择 WebSocket 还是 Socket 取决于您的应用需求和设计。")]),s._v(" "),t("h3",{attrs:{id:"dao-data-access-object"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#dao-data-access-object"}},[s._v("#")]),s._v(" Dao(Data Access Object)")]),s._v(" "),t("p",[s._v("是一种模式,用于在应用程序和数据存储之间提供一个抽象层,以简化数据存储访问。它通常是用于创建、更新、检索和删除数据的方法的集合,并且它涵盖了数据存储的所有细节,以便应用程序可以专注于业务逻辑。因此,它是数据操作层的重要组成部分。")]),s._v(" "),t("h3",{attrs:{id:"mapper"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#mapper"}},[s._v("#")]),s._v(" mapper")]),s._v(" "),t("p",[s._v('在 Java 中,"Mapper" 是一个常见的术语,通常用于描述一种用于将数据从一种形式映射到另一种形式的工具或组件。在不同的上下文中,"Mapper" 可以表示不同的含义,以下是其中一些常见的用法:')]),s._v(" "),t("ol",[t("li",[t("strong",[s._v("数据访问对象(Data Access Object)Mapper")]),s._v(":")])]),s._v(" "),t("p",[s._v("在数据访问层中,Mapper 通常是指数据访问对象(DAO)的一部分。它用于将数据库表的记录(通常是关系型数据库表)映射到 Java 对象,或者将 Java 对象映射到数据库表。这是一种常见的 ORM(对象关系映射)模式的实现。例如,在使用 Hibernate、MyBatis 或 JPA 等持久化框架时,通常会编写 Mapper 接口或配置文件来定义对象到数据库表的映射关系。")]),s._v(" "),t("div",{staticClass:"language-java line-numbers-mode"},[t("pre",{pre:!0,attrs:{class:"language-java"}},[t("code",[t("span",{pre:!0,attrs:{class:"token comment"}},[s._v("// MyBatis Mapper Interface")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("public")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("interface")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("UserMapper")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n    "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("User")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("getUserById")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("int")]),s._v(" id"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n    "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("void")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("insertUser")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("User")]),s._v(" user"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n")])]),s._v(" "),t("div",{staticClass:"line-numbers-wrapper"},[t("span",{staticClass:"line-number"},[s._v("1")]),t("br"),t("span",{staticClass:"line-number"},[s._v("2")]),t("br"),t("span",{staticClass:"line-number"},[s._v("3")]),t("br"),t("span",{staticClass:"line-number"},[s._v("4")]),t("br"),t("span",{staticClass:"line-number"},[s._v("5")]),t("br")])]),t("ol",{attrs:{start:"2"}},[t("li",[t("strong",[s._v("对象映射器(Object Mapper)")]),s._v(":")])]),s._v(" "),t("p",[s._v("在处理不同数据格式(例如 JSON、XML)的时候,对象映射器通常用于将数据转换为 Java 对象或将 Java 对象转换为数据。一些流行的 Java 对象映射器包括 Jackson(用于 JSON)、JAXB(Java Architecture for XML Binding,用于 XML)、Dozer 等。")]),s._v(" "),t("div",{staticClass:"language-java line-numbers-mode"},[t("pre",{pre:!0,attrs:{class:"language-java"}},[t("code",[t("span",{pre:!0,attrs:{class:"token comment"}},[s._v("// 使用 Jackson ObjectMapper 将 JSON 字符串转换为 Java 对象")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("ObjectMapper")]),s._v(" objectMapper "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("new")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("ObjectMapper")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("User")]),s._v(" user "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" objectMapper"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("readValue")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("jsonString"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("User")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("class")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n")])]),s._v(" "),t("div",{staticClass:"line-numbers-wrapper"},[t("span",{staticClass:"line-number"},[s._v("1")]),t("br"),t("span",{staticClass:"line-number"},[s._v("2")]),t("br"),t("span",{staticClass:"line-number"},[s._v("3")]),t("br")])]),t("ol",{attrs:{start:"3"}},[t("li",[t("strong",[s._v("模型-视图映射器(Model-View Mapper)")]),s._v(":")])]),s._v(" "),t("p",[s._v("在 Web 应用程序中,模型-视图映射器通常用于将应用程序的模型数据映射到视图层(通常是 HTML 或其他视图模板)以进行渲染。一些 Java Web 框架(例如 Spring MVC)提供了视图解析器和模型映射器,用于处理这种类型的映射。")]),s._v(" "),t("div",{staticClass:"language-java line-numbers-mode"},[t("pre",{pre:!0,attrs:{class:"language-java"}},[t("code",[t("span",{pre:!0,attrs:{class:"token comment"}},[s._v("// Spring MVC Controller method with Model-View Mapping")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[s._v("@GetMapping")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token string"}},[s._v('"/user/{id}"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("public")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("String")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("getUser")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[s._v("@PathVariable")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token string"}},[s._v('"id"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("int")]),s._v(" id"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Model")]),s._v(" model"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n    "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("User")]),s._v(" user "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" userService"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("getUserById")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("id"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n    model"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("addAttribute")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token string"}},[s._v('"user"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" user"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n    "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("return")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token string"}},[s._v('"user-profile"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token comment"}},[s._v("// View name")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n")])]),s._v(" "),t("div",{staticClass:"line-numbers-wrapper"},[t("span",{staticClass:"line-number"},[s._v("1")]),t("br"),t("span",{staticClass:"line-number"},[s._v("2")]),t("br"),t("span",{staticClass:"line-number"},[s._v("3")]),t("br"),t("span",{staticClass:"line-number"},[s._v("4")]),t("br"),t("span",{staticClass:"line-number"},[s._v("5")]),t("br"),t("span",{staticClass:"line-number"},[s._v("6")]),t("br"),t("span",{staticClass:"line-number"},[s._v("7")]),t("br")])]),t("ol",{attrs:{start:"4"}},[t("li",[t("strong",[s._v("其他映射器")]),s._v(":")])]),s._v(" "),t("p",[s._v("在不同领域中,Mapper 可能具有不同的含义。例如,图形映射器用于将图像的像素映射到屏幕上,地图映射器用于将地理坐标映射到地图上,等等。")]),s._v(" "),t("p",[s._v('总之,"Mapper" 是一个通用的术语,它描述了一种将数据从一种形式映射到另一种形式的工具或组件。在不同的上下文中,它可以表示不同类型的映射,包括数据访问、对象映射、模型-视图映射以及其他领域中的映射。在 Java 中,您可以使用各种库和框架来实现这些映射。')]),s._v(" "),t("h3",{attrs:{id:"jdbc-java-database-connectivity"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#jdbc-java-database-connectivity"}},[s._v("#")]),s._v(" JDBC(Java Database Connectivity)")]),s._v(" "),t("ul",[t("li",[s._v("定义:JDBC 是 Java 用于与关系型数据库交互的标准 API。它允许 Java 应用程序与数据库建立连接、执行 SQL 查询、插入、更新和删除数据。")]),s._v(" "),t("li",[s._v("用途:JDBC 用于直接管理数据库连接和执行 SQL 操作。它是一个底层的、面向关系型数据库的 API。开发人员需要手动编写 SQL 语句,并处理数据库连接、事务等细节。")]),s._v(" "),t("li",[s._v("工作方式:JDBC 提供了一组接口和类,允许 Java 应用程序执行以下操作:\n"),t("ul",[t("li",[s._v("建立数据库连接")]),s._v(" "),t("li",[s._v("创建和执行 SQL 语句")]),s._v(" "),t("li",[s._v("处理结果集")]),s._v(" "),t("li",[s._v("管理事务")])])]),s._v(" "),t("li",[s._v("示例:以下是一个简单的 JDBC 示例,用于连接到数据库并执行查询操作:")])]),s._v(" "),t("div",{staticClass:"language-java line-numbers-mode"},[t("pre",{pre:!0,attrs:{class:"language-java"}},[t("code",[t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("import")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token import"}},[t("span",{pre:!0,attrs:{class:"token namespace"}},[s._v("java"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),s._v("sql"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")])]),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Connection")])]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("import")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token import"}},[t("span",{pre:!0,attrs:{class:"token namespace"}},[s._v("java"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),s._v("sql"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")])]),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("DriverManager")])]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("import")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token import"}},[t("span",{pre:!0,attrs:{class:"token namespace"}},[s._v("java"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),s._v("sql"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")])]),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("ResultSet")])]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("import")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token import"}},[t("span",{pre:!0,attrs:{class:"token namespace"}},[s._v("java"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),s._v("sql"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")])]),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Statement")])]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n\n"),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("public")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("class")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("JDBCDemo")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n    "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("public")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("static")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("void")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("main")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("String")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("[")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("]")]),s._v(" args"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n        "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("try")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n            "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Class")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("forName")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token string"}},[s._v('"com.mysql.jdbc.Driver"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n            "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Connection")]),s._v(" connection "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("DriverManager")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("getConnection")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token string"}},[s._v('"jdbc:mysql://localhost:3306/mydb"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token string"}},[s._v('"username"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token string"}},[s._v('"password"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n            "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Statement")]),s._v(" statement "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" connection"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("createStatement")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n            "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("ResultSet")]),s._v(" resultSet "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" statement"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("executeQuery")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token string"}},[s._v('"SELECT * FROM users"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n            "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("while")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("resultSet"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("next")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n                "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("System")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),s._v("out"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("println")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("resultSet"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("getString")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token string"}},[s._v('"username"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n            "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n            resultSet"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("close")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n            statement"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("close")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n            connection"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("close")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n        "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("catch")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Exception")]),s._v(" e"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n            e"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("printStackTrace")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n        "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n    "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n")])]),s._v(" "),t("div",{staticClass:"line-numbers-wrapper"},[t("span",{staticClass:"line-number"},[s._v("1")]),t("br"),t("span",{staticClass:"line-number"},[s._v("2")]),t("br"),t("span",{staticClass:"line-number"},[s._v("3")]),t("br"),t("span",{staticClass:"line-number"},[s._v("4")]),t("br"),t("span",{staticClass:"line-number"},[s._v("5")]),t("br"),t("span",{staticClass:"line-number"},[s._v("6")]),t("br"),t("span",{staticClass:"line-number"},[s._v("7")]),t("br"),t("span",{staticClass:"line-number"},[s._v("8")]),t("br"),t("span",{staticClass:"line-number"},[s._v("9")]),t("br"),t("span",{staticClass:"line-number"},[s._v("10")]),t("br"),t("span",{staticClass:"line-number"},[s._v("11")]),t("br"),t("span",{staticClass:"line-number"},[s._v("12")]),t("br"),t("span",{staticClass:"line-number"},[s._v("13")]),t("br"),t("span",{staticClass:"line-number"},[s._v("14")]),t("br"),t("span",{staticClass:"line-number"},[s._v("15")]),t("br"),t("span",{staticClass:"line-number"},[s._v("16")]),t("br"),t("span",{staticClass:"line-number"},[s._v("17")]),t("br"),t("span",{staticClass:"line-number"},[s._v("18")]),t("br"),t("span",{staticClass:"line-number"},[s._v("19")]),t("br"),t("span",{staticClass:"line-number"},[s._v("20")]),t("br"),t("span",{staticClass:"line-number"},[s._v("21")]),t("br"),t("span",{staticClass:"line-number"},[s._v("22")]),t("br"),t("span",{staticClass:"line-number"},[s._v("23")]),t("br")])]),t("h3",{attrs:{id:"jpa-java-persistence-api"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#jpa-java-persistence-api"}},[s._v("#")]),s._v(" JPA(Java Persistence API)")]),s._v(" "),t("ul",[t("li",[s._v("定义:JPA 是 Java 的持久化 API,用于将 Java 对象映射到数据库表。它提供了一种更高级别、面向对象的方式来处理持久化,而不需要编写大量的 SQL 代码。")]),s._v(" "),t("li",[s._v("用途:JPA 用于简化数据持久化的过程,提供了对象关系映射(ORM)的功能。它允许开发人员通过定义实体类和注解来描述数据库表和对象之间的映射,而不需要编写复杂的 SQL 查询。")]),s._v(" "),t("li",[s._v("工作方式:JPA 通过注解或 XML 配置文件来描述实体类与数据库表之间的映射关系。开发人员可以使用 JPA 提供的 API 来执行 CRUD(创建、读取、更新、删除)操作,而不需要编写原始 SQL 语句。")]),s._v(" "),t("li",[s._v("示例:以下是一个简单的 JPA 示例,用于定义实体类和执行查询操作:")])]),s._v(" "),t("div",{staticClass:"language-java line-numbers-mode"},[t("pre",{pre:!0,attrs:{class:"language-java"}},[t("code",[t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("import")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token import"}},[t("span",{pre:!0,attrs:{class:"token namespace"}},[s._v("javax"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),s._v("persistence"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")])]),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("*")])]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n\n"),t("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[s._v("@Entity")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[s._v("@Table")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("name "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token string"}},[s._v('"users"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("public")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("class")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("User")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n    "),t("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[s._v("@Id")]),s._v("\n    "),t("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[s._v("@GeneratedValue")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("strategy "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("GenerationType")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token constant"}},[s._v("IDENTITY")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v("\n    "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("private")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Long")]),s._v(" id"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n\n    "),t("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[s._v("@Column")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("name "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token string"}},[s._v('"username"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v("\n    "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("private")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("String")]),s._v(" username"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n\n    "),t("span",{pre:!0,attrs:{class:"token comment"}},[s._v("// Getters and setters")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n\n"),t("span",{pre:!0,attrs:{class:"token comment"}},[s._v("// 使用 JPA 查询")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("EntityManagerFactory")]),s._v(" emf "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Persistence")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("createEntityManagerFactory")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token string"}},[s._v('"my-persistence-unit"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("EntityManager")]),s._v(" em "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" emf"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("createEntityManager")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("TypedQuery")]),t("span",{pre:!0,attrs:{class:"token generics"}},[t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("<")]),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("User")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(">")])]),s._v(" query "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" em"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("createQuery")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token string"}},[s._v('"SELECT u FROM User u WHERE u.username = :username"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("User")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("class")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\nquery"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("setParameter")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token string"}},[s._v('"username"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token string"}},[s._v('"john"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("List")]),t("span",{pre:!0,attrs:{class:"token generics"}},[t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("<")]),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("User")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(">")])]),s._v(" users "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" query"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("getResultList")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n\n")])]),s._v(" "),t("div",{staticClass:"line-numbers-wrapper"},[t("span",{staticClass:"line-number"},[s._v("1")]),t("br"),t("span",{staticClass:"line-number"},[s._v("2")]),t("br"),t("span",{staticClass:"line-number"},[s._v("3")]),t("br"),t("span",{staticClass:"line-number"},[s._v("4")]),t("br"),t("span",{staticClass:"line-number"},[s._v("5")]),t("br"),t("span",{staticClass:"line-number"},[s._v("6")]),t("br"),t("span",{staticClass:"line-number"},[s._v("7")]),t("br"),t("span",{staticClass:"line-number"},[s._v("8")]),t("br"),t("span",{staticClass:"line-number"},[s._v("9")]),t("br"),t("span",{staticClass:"line-number"},[s._v("10")]),t("br"),t("span",{staticClass:"line-number"},[s._v("11")]),t("br"),t("span",{staticClass:"line-number"},[s._v("12")]),t("br"),t("span",{staticClass:"line-number"},[s._v("13")]),t("br"),t("span",{staticClass:"line-number"},[s._v("14")]),t("br"),t("span",{staticClass:"line-number"},[s._v("15")]),t("br"),t("span",{staticClass:"line-number"},[s._v("16")]),t("br"),t("span",{staticClass:"line-number"},[s._v("17")]),t("br"),t("span",{staticClass:"line-number"},[s._v("18")]),t("br"),t("span",{staticClass:"line-number"},[s._v("19")]),t("br"),t("span",{staticClass:"line-number"},[s._v("20")]),t("br"),t("span",{staticClass:"line-number"},[s._v("21")]),t("br"),t("span",{staticClass:"line-number"},[s._v("22")]),t("br")])]),t("h3",{attrs:{id:"jwt"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#jwt"}},[s._v("#")]),s._v(" jwt")]),s._v(" "),t("p",[s._v("JWT(JSON Web Token)是一种用于在网络应用之间安全传输信息的开放标准(RFC 7519)。它通过使用数字签名或加密来验证信息的可信性,通常用于实现用户身份验证和授权。JWT 认证的工作原理如下:")]),s._v(" "),t("ul",[t("li",[t("p",[s._v("用户登录:用户通过提供有效的凭证(通常是用户名和密码)来登录应用程序。")])]),s._v(" "),t("li",[t("p",[s._v("生成 JWT:一旦用户成功登录,服务器将生成一个 JWT。JWT 通常包含以下信息:")]),s._v(" "),t("ul",[t("li",[s._v("用户标识(例如用户 ID 或用户名)")]),s._v(" "),t("li",[s._v("过期时间(JWT 的有效期)")]),s._v(" "),t("li",[s._v("其他自定义的声明(例如用户角色、权限等)\n服务器使用一个密钥来签名 JWT,以确保它的完整性和真实性。")])])]),s._v(" "),t("li",[t("p",[s._v("将 JWT 发送给客户端:生成的 JWT 将被发送回客户端,通常存储在客户端的 Cookie 或本地存储中。")])]),s._v(" "),t("li",[t("p",[s._v("客户端请求受保护资源:当客户端尝试访问需要身份验证的资源时,它将在请求中包含 JWT。通常,JWT 放在请求的授权头(Authorization Header)中,以 Bearer Token 的形式传递。")])]),s._v(" "),t("li",[t("p",[s._v("服务器验证 JWT:服务器收到包含 JWT 的请求后,将验证 JWT 的签名以确保其完整性和真实性。如果 JWT 有效且未过期,则服务器将允许访问受保护的资源。")])]),s._v(" "),t("li",[t("p",[s._v("响应受保护资源:如果 JWT 有效,服务器将响应客户端请求并提供受保护资源。")])])]),s._v(" "),t("p",[t("strong",[s._v("JWT 认证的优点包括")]),s._v(":")]),s._v(" "),t("ul",[t("li",[s._v("无状态:JWT 本身包含了所有必要的信息,服务器不需要存储用户的会话信息。这使得应用程序更容易扩展,因为它不需要依赖于特定的会话存储机制。")]),s._v(" "),t("li",[s._v("安全性:JWT 可以使用数字签名来保护数据的完整性,也可以使用加密来保护数据的隐私。这使得它非常适合在不信任的网络中进行安全通信。")]),s._v(" "),t("li",[s._v("跨域支持:JWT 可以轻松地在不同域之间传递,因为它可以通过 HTTP 请求头进行传递。")]),s._v(" "),t("li",[s._v("可扩展性:JWT 允许包含自定义声明,可以用于存储用户角色、权限和其他自定义信息。")])]),s._v(" "),t("p",[s._v("需要注意的是,JWT 也有一些潜在的安全风险,例如,如果密钥丢失或泄露,攻击者可能会伪造有效的 JWT。因此,在实施 JWT 认证时,必须采取适当的安全措施来保护密钥和令牌。此外,JWT 通常不适用于存储大量敏感信息,因为它们可以在客户端解码。")]),s._v(" "),t("h3",{attrs:{id:"cors"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#cors"}},[s._v("#")]),s._v(" CORS")]),s._v(" "),t("p",[s._v('全称是"跨域资源共享"(Cross-origin resource sharing)CORS 需要浏览器和服务器同时支持。目前,所有浏览器都支持该功能,IE 浏览器不能低于 IE10。整个 CORS 通信过程,都是浏览器自动完成,不需要用户参与。对于开发者来说,CORS 通信与同源的 AJAX 通信没有差别,代码完全一样。浏览器一旦发现 AJAX 请求跨源,就会自动添加一些附加的头信息,有时还会多出一次附加的请求,但用户不会有感觉。因此,实现 CORS 通信的关键是服务器。只要服务器实现了 CORS 接口,就可以跨源通信。')]),s._v(" "),t("h3",{attrs:{id:"swagger3"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#swagger3"}},[s._v("#")]),s._v(" Swagger3")]),s._v(" "),t("p",[s._v("Swagger 3.0 是一种用于定义、构建和文档化 RESTful API 的规范。它使开发人员能够创建具有可读性和易于理解的 API 文档,同时还提供了工具和库来自动生成客户端 SDK 和服务器存根。以下是如何使用 Swagger 3.0 来定义和文档化 Java 中的 RESTful API 的基本步骤:")]),s._v(" "),t("ol",[t("li",[t("strong",[s._v("添加 Swagger 依赖")]),s._v(":")])]),s._v(" "),t("p",[s._v("首先,您需要在 Java 项目中添加 Swagger 的依赖库。这通常包括 "),t("code",[s._v("swagger-core")]),s._v(" 和 "),t("code",[s._v("swagger-ui")]),s._v("。您可以使用 Maven 或 Gradle 来添加这些依赖。\n使用 Maven,您可以将以下依赖添加到您的 pom.xml 文件中:")]),s._v(" "),t("div",{staticClass:"language-xml line-numbers-mode"},[t("pre",{pre:!0,attrs:{class:"language-xml"}},[t("code",[t("span",{pre:!0,attrs:{class:"token tag"}},[t("span",{pre:!0,attrs:{class:"token tag"}},[t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("<")]),s._v("dependency")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(">")])]),s._v("\n    "),t("span",{pre:!0,attrs:{class:"token tag"}},[t("span",{pre:!0,attrs:{class:"token tag"}},[t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("<")]),s._v("groupId")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(">")])]),s._v("io.swagger.core.v3"),t("span",{pre:!0,attrs:{class:"token tag"}},[t("span",{pre:!0,attrs:{class:"token tag"}},[t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("")])]),s._v("\n    "),t("span",{pre:!0,attrs:{class:"token tag"}},[t("span",{pre:!0,attrs:{class:"token tag"}},[t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("<")]),s._v("artifactId")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(">")])]),s._v("swagger-core"),t("span",{pre:!0,attrs:{class:"token tag"}},[t("span",{pre:!0,attrs:{class:"token tag"}},[t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("")])]),s._v("\n    "),t("span",{pre:!0,attrs:{class:"token tag"}},[t("span",{pre:!0,attrs:{class:"token tag"}},[t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("<")]),s._v("version")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(">")])]),s._v("2.1.10"),t("span",{pre:!0,attrs:{class:"token tag"}},[t("span",{pre:!0,attrs:{class:"token tag"}},[t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("")])]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token tag"}},[t("span",{pre:!0,attrs:{class:"token tag"}},[t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("")])]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token tag"}},[t("span",{pre:!0,attrs:{class:"token tag"}},[t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("<")]),s._v("dependency")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(">")])]),s._v("\n    "),t("span",{pre:!0,attrs:{class:"token tag"}},[t("span",{pre:!0,attrs:{class:"token tag"}},[t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("<")]),s._v("groupId")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(">")])]),s._v("org.webjars"),t("span",{pre:!0,attrs:{class:"token tag"}},[t("span",{pre:!0,attrs:{class:"token tag"}},[t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("")])]),s._v("\n    "),t("span",{pre:!0,attrs:{class:"token tag"}},[t("span",{pre:!0,attrs:{class:"token tag"}},[t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("<")]),s._v("artifactId")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(">")])]),s._v("swagger-ui"),t("span",{pre:!0,attrs:{class:"token tag"}},[t("span",{pre:!0,attrs:{class:"token tag"}},[t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("")])]),s._v("\n    "),t("span",{pre:!0,attrs:{class:"token tag"}},[t("span",{pre:!0,attrs:{class:"token tag"}},[t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("<")]),s._v("version")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(">")])]),s._v("3.51.3"),t("span",{pre:!0,attrs:{class:"token tag"}},[t("span",{pre:!0,attrs:{class:"token tag"}},[t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("")])]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token tag"}},[t("span",{pre:!0,attrs:{class:"token tag"}},[t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("")])]),s._v("\n")])]),s._v(" "),t("div",{staticClass:"line-numbers-wrapper"},[t("span",{staticClass:"line-number"},[s._v("1")]),t("br"),t("span",{staticClass:"line-number"},[s._v("2")]),t("br"),t("span",{staticClass:"line-number"},[s._v("3")]),t("br"),t("span",{staticClass:"line-number"},[s._v("4")]),t("br"),t("span",{staticClass:"line-number"},[s._v("5")]),t("br"),t("span",{staticClass:"line-number"},[s._v("6")]),t("br"),t("span",{staticClass:"line-number"},[s._v("7")]),t("br"),t("span",{staticClass:"line-number"},[s._v("8")]),t("br"),t("span",{staticClass:"line-number"},[s._v("9")]),t("br"),t("span",{staticClass:"line-number"},[s._v("10")]),t("br")])]),t("ol",{attrs:{start:"2"}},[t("li",[t("strong",[s._v("创建 API 文档")]),s._v(":")])]),s._v(" "),t("p",[s._v("在 Java 代码中,您可以使用 Swagger 注解来描述您的 RESTful API。Swagger 提供了一些常用的注解,如 "),t("code",[s._v("@Api")]),s._v(", "),t("code",[s._v("@ApiOperation")]),s._v(", "),t("code",[s._v("@ApiParam")]),s._v(" 等,用于定义 API 的信息、操作和参数。")]),s._v(" "),t("div",{staticClass:"language-java line-numbers-mode"},[t("pre",{pre:!0,attrs:{class:"language-java"}},[t("code",[t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("import")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token import"}},[t("span",{pre:!0,attrs:{class:"token namespace"}},[s._v("io"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),s._v("swagger"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),s._v("annotations"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")])]),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("*")])]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("import")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token import"}},[t("span",{pre:!0,attrs:{class:"token namespace"}},[s._v("org"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),s._v("springframework"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),s._v("web"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),s._v("bind"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),s._v("annotation"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")])]),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("*")])]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n\n"),t("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[s._v("@RestController")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[s._v("@RequestMapping")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token string"}},[s._v('"/api"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[s._v("@Api")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("tags "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token string"}},[s._v('"Sample API"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("public")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("class")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("SampleController")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n    "),t("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[s._v("@GetMapping")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token string"}},[s._v('"/hello"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v("\n    "),t("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[s._v("@ApiOperation")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token string"}},[s._v('"Say hello"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v("\n    "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("public")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("String")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("sayHello")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("\n        "),t("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[s._v("@RequestParam")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("value "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token string"}},[s._v('"name"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" defaultValue "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token string"}},[s._v('"World"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v("\n        "),t("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[s._v("@ApiParam")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token string"}},[s._v('"Name to greet"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("String")]),s._v(" name\n    "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n        "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("return")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token string"}},[s._v('"Hello, "')]),s._v(" "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("+")]),s._v(" name "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("+")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token string"}},[s._v('"!"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n    "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n")])]),s._v(" "),t("div",{staticClass:"line-numbers-wrapper"},[t("span",{staticClass:"line-number"},[s._v("1")]),t("br"),t("span",{staticClass:"line-number"},[s._v("2")]),t("br"),t("span",{staticClass:"line-number"},[s._v("3")]),t("br"),t("span",{staticClass:"line-number"},[s._v("4")]),t("br"),t("span",{staticClass:"line-number"},[s._v("5")]),t("br"),t("span",{staticClass:"line-number"},[s._v("6")]),t("br"),t("span",{staticClass:"line-number"},[s._v("7")]),t("br"),t("span",{staticClass:"line-number"},[s._v("8")]),t("br"),t("span",{staticClass:"line-number"},[s._v("9")]),t("br"),t("span",{staticClass:"line-number"},[s._v("10")]),t("br"),t("span",{staticClass:"line-number"},[s._v("11")]),t("br"),t("span",{staticClass:"line-number"},[s._v("12")]),t("br"),t("span",{staticClass:"line-number"},[s._v("13")]),t("br"),t("span",{staticClass:"line-number"},[s._v("14")]),t("br"),t("span",{staticClass:"line-number"},[s._v("15")]),t("br"),t("span",{staticClass:"line-number"},[s._v("16")]),t("br")])]),t("ol",{attrs:{start:"3"}},[t("li",[t("strong",[s._v("配置 Swagger")]),s._v(":")])]),s._v(" "),t("p",[s._v("在您的 Java 应用程序中,您需要配置 Swagger 来生成 API 文档。这通常涉及创建一个 Swagger 配置类,并将其与 Spring Boot 或其他 Java 框架集成。")]),s._v(" "),t("div",{staticClass:"language-java line-numbers-mode"},[t("pre",{pre:!0,attrs:{class:"language-java"}},[t("code",[t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("import")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token import"}},[t("span",{pre:!0,attrs:{class:"token namespace"}},[s._v("org"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),s._v("springframework"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),s._v("context"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),s._v("annotation"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")])]),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("*")])]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("import")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token import"}},[t("span",{pre:!0,attrs:{class:"token namespace"}},[s._v("springfox"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),s._v("documentation"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),s._v("spring"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),s._v("web"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),s._v("plugins"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")])]),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("*")])]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("import")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token import"}},[t("span",{pre:!0,attrs:{class:"token namespace"}},[s._v("springfox"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),s._v("documentation"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),s._v("swagger2"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),s._v("annotations"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")])]),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("*")])]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n\n"),t("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[s._v("@Configuration")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[s._v("@EnableSwagger2")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("public")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("class")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("SwaggerConfig")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n    "),t("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[s._v("@Bean")]),s._v("\n    "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("public")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Docket")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("api")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n        "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("return")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("new")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Docket")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("DocumentationType")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token constant"}},[s._v("SWAGGER_2")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v("\n            "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("select")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v("\n            "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("apis")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("RequestHandlerSelectors")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("basePackage")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token string"}},[s._v('"com.example"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v("\n            "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("paths")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("PathSelectors")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("any")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v("\n            "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("build")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n    "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n")])]),s._v(" "),t("div",{staticClass:"line-numbers-wrapper"},[t("span",{staticClass:"line-number"},[s._v("1")]),t("br"),t("span",{staticClass:"line-number"},[s._v("2")]),t("br"),t("span",{staticClass:"line-number"},[s._v("3")]),t("br"),t("span",{staticClass:"line-number"},[s._v("4")]),t("br"),t("span",{staticClass:"line-number"},[s._v("5")]),t("br"),t("span",{staticClass:"line-number"},[s._v("6")]),t("br"),t("span",{staticClass:"line-number"},[s._v("7")]),t("br"),t("span",{staticClass:"line-number"},[s._v("8")]),t("br"),t("span",{staticClass:"line-number"},[s._v("9")]),t("br"),t("span",{staticClass:"line-number"},[s._v("10")]),t("br"),t("span",{staticClass:"line-number"},[s._v("11")]),t("br"),t("span",{staticClass:"line-number"},[s._v("12")]),t("br"),t("span",{staticClass:"line-number"},[s._v("13")]),t("br"),t("span",{staticClass:"line-number"},[s._v("14")]),t("br"),t("span",{staticClass:"line-number"},[s._v("15")]),t("br"),t("span",{staticClass:"line-number"},[s._v("16")]),t("br")])]),t("ol",{attrs:{start:"4"}},[t("li",[t("strong",[s._v("访问 Swagger UI")]),s._v(":")])]),s._v(" "),t("p",[s._v("启动您的 Java 应用程序后,您可以在浏览器中访问 Swagger UI,通常位于 /swagger-ui.html。这将显示一个可交互的 API 文档,允许您浏览和测试您的 API。\n例如:"),t("a",{attrs:{href:"http://localhost:8080/swagger-ui.html",target:"_blank",rel:"noopener noreferrer"}},[s._v("http://localhost:8080/swagger-ui.html"),t("OutboundLink")],1)]),s._v(" "),t("p",[s._v("这些是使用 Swagger 3.0(OpenAPI 3.0)来定义和文档化 Java RESTful API 的基本步骤。通过注解和配置,您可以更详细地定义您的 API,包括操作、请求和响应。Swagger 将根据这些信息生成详细的 API 文档,并提供交互式界面来测试 API。这有助于团队更好地理解和使用您的 API。")]),s._v(" "),t("h3",{attrs:{id:"restful-api"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#restful-api"}},[s._v("#")]),s._v(" RESTful API")]),s._v(" "),t("p",[s._v("RESTful API(Representational State Transfer API)是一种基于 HTTP 协议的应用程序编程接口(API)设计风格,它采用了一组约定和约束,旨在使网络应用程序更加简单、可伸缩和易于扩展。RESTful API 的设计风格是由 Roy Fielding 在他的博士论文中首次提出的,并成为了构建分布式网络应用的一种常见方式。")]),s._v(" "),t("p",[s._v("以下是 RESTful API 的主要特点和原则:")]),s._v(" "),t("ol",[t("li",[t("p",[t("strong",[s._v("资源(Resources)")]),s._v(":在 RESTful API 中,一切都是资源,每个资源都有一个唯一的标识符(通常是 URL)。资源可以是物理实体(例如数据库记录)、虚拟实体(例如计算机服务)或抽象概念(例如订单或用户)。")])]),s._v(" "),t("li",[t("p",[t("strong",[s._v("HTTP 动词")]),s._v(":RESTful API 使用 HTTP 方法来执行操作。常见的 HTTP 动词包括 GET(获取资源)、POST(创建资源)、PUT(更新资源)和 DELETE(删除资源)。这些动词与资源的 CRUD 操作(创建、读取、更新、删除)相对应。")])]),s._v(" "),t("li",[t("p",[t("strong",[s._v("状态无关性(Statelessness)")]),s._v(":每个 HTTP 请求都包含了足够的信息,服务器不需要保存客户端的状态。每个请求都应该是独立的,这样可以更容易实现负载均衡和横向扩展。")])]),s._v(" "),t("li",[t("p",[t("strong",[s._v("统一接口(Uniform Interface)")]),s._v(":RESTful API 的接口应该是简单、一致和易于理解的。这使得客户端能够轻松地与不同的服务进行交互。")])]),s._v(" "),t("li",[t("p",[t("strong",[s._v("资源的表述(Resource Representation)")]),s._v(":资源的表述是资源的具体数据,通常以 JSON 或 XML 格式返回给客户端。客户端可以使用这些表述来操作资源。")])]),s._v(" "),t("li",[t("p",[t("strong",[s._v("无状态通信(Stateless Communication)")]),s._v(":每个请求都应该包含足够的信息,以便服务器可以理解它,而不需要查看之前的请求。这使得 RESTful API 易于缓存和代理。")])]),s._v(" "),t("li",[t("p",[t("strong",[s._v("自我描述性(Self-Descriptive Messages)")]),s._v(":每个请求和响应都应该包含足够的信息,以便客户端和服务器都能理解它,而不需要事先了解上下文。")])]),s._v(" "),t("li",[t("p",[t("strong",[s._v("按需响应(On-Demand Response)")]),s._v(":客户端决定何时请求资源,服务器不会自动推送数据。这使得客户端可以按需获取数据,减少不必要的网络流量。")])])]),s._v(" "),t("p",[s._v("RESTful API 通常使用 URL 来唯一标识资源,使用 HTTP 方法来执行操作,使用状态码来表示操作的结果。它们可以通过 URL 参数、HTTP 头部和请求体来传递数据,通常使用 JSON 或 XML 格式返回数据。")]),s._v(" "),t("p",[s._v("总之,RESTful API 是一种简单、可伸缩和易于理解的 API 设计风格,广泛用于构建 Web 服务和分布式系统。它的设计原则强调资源、状态无关性和统一接口,使得开发者能够构建灵活和可维护的应用程序。")]),s._v(" "),t("h3",{attrs:{id:"aspectj-实现-aop"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#aspectj-实现-aop"}},[s._v("#")]),s._v(" AspectJ 实现 AOP")]),s._v(" "),t("p",[s._v("在 Spring 中,您可以使用 AspectJ 来实现面向切面编程(AOP)。AspectJ 是一个强大的 AOP 框架,它可以与 Spring 集成以实现更复杂的横切关注点。以下是在 Spring 中使用 AspectJ 来实现 AOP 的一般步骤:")]),s._v(" "),t("ol",[t("li",[t("strong",[s._v("添加 AspectJ 依赖")]),s._v(":首先,您需要在项目中添加 AspectJ 的依赖。如果使用 Maven,可以在 pom.xml 中添加以下依赖:")])]),s._v(" "),t("div",{staticClass:"language-xml line-numbers-mode"},[t("pre",{pre:!0,attrs:{class:"language-xml"}},[t("code",[t("span",{pre:!0,attrs:{class:"token tag"}},[t("span",{pre:!0,attrs:{class:"token tag"}},[t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("<")]),s._v("dependency")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(">")])]),s._v("\n    "),t("span",{pre:!0,attrs:{class:"token tag"}},[t("span",{pre:!0,attrs:{class:"token tag"}},[t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("<")]),s._v("groupId")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(">")])]),s._v("org.aspectj"),t("span",{pre:!0,attrs:{class:"token tag"}},[t("span",{pre:!0,attrs:{class:"token tag"}},[t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("")])]),s._v("\n    "),t("span",{pre:!0,attrs:{class:"token tag"}},[t("span",{pre:!0,attrs:{class:"token tag"}},[t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("<")]),s._v("artifactId")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(">")])]),s._v("aspectjweaver"),t("span",{pre:!0,attrs:{class:"token tag"}},[t("span",{pre:!0,attrs:{class:"token tag"}},[t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("")])]),s._v("\n    "),t("span",{pre:!0,attrs:{class:"token tag"}},[t("span",{pre:!0,attrs:{class:"token tag"}},[t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("<")]),s._v("version")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(">")])]),s._v("1.9.7"),t("span",{pre:!0,attrs:{class:"token tag"}},[t("span",{pre:!0,attrs:{class:"token tag"}},[t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("")])]),s._v(" "),t("span",{pre:!0,attrs:{class:"token comment"}},[s._v("\x3c!-- 使用合适的版本 --\x3e")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token tag"}},[t("span",{pre:!0,attrs:{class:"token tag"}},[t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("")])]),s._v("\n")])]),s._v(" "),t("div",{staticClass:"line-numbers-wrapper"},[t("span",{staticClass:"line-number"},[s._v("1")]),t("br"),t("span",{staticClass:"line-number"},[s._v("2")]),t("br"),t("span",{staticClass:"line-number"},[s._v("3")]),t("br"),t("span",{staticClass:"line-number"},[s._v("4")]),t("br"),t("span",{staticClass:"line-number"},[s._v("5")]),t("br")])]),t("ol",{attrs:{start:"2"}},[t("li",[t("strong",[s._v("创建切面类")]),s._v(":创建一个 Java 类来充当您的切面。切面类通常包含各种通知(Advice),以定义在何时和何地执行横切关注点。一个简单的切面类示例:")])]),s._v(" "),t("div",{staticClass:"language-java line-numbers-mode"},[t("pre",{pre:!0,attrs:{class:"language-java"}},[t("code",[t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("import")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token import"}},[t("span",{pre:!0,attrs:{class:"token namespace"}},[s._v("org"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),s._v("aspectj"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),s._v("lang"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),s._v("annotation"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")])]),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Aspect")])]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("import")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token import"}},[t("span",{pre:!0,attrs:{class:"token namespace"}},[s._v("org"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),s._v("aspectj"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),s._v("lang"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),s._v("annotation"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")])]),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Before")])]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("import")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token import"}},[t("span",{pre:!0,attrs:{class:"token namespace"}},[s._v("org"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),s._v("springframework"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),s._v("stereotype"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")])]),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Component")])]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n\n"),t("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[s._v("@Aspect")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[s._v("@Component")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("public")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("class")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("MyAspect")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n    "),t("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[s._v("@Before")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token string"}},[s._v('"execution(* com.example.service.*.*(..))"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v("\n    "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("public")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("void")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("beforeServiceMethods")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n        "),t("span",{pre:!0,attrs:{class:"token comment"}},[s._v("// 在service包中的所有方法执行前执行此通知")]),s._v("\n        "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("System")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),s._v("out"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("println")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token string"}},[s._v('"Before executing a service method..."')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n    "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n")])]),s._v(" "),t("div",{staticClass:"line-numbers-wrapper"},[t("span",{staticClass:"line-number"},[s._v("1")]),t("br"),t("span",{staticClass:"line-number"},[s._v("2")]),t("br"),t("span",{staticClass:"line-number"},[s._v("3")]),t("br"),t("span",{staticClass:"line-number"},[s._v("4")]),t("br"),t("span",{staticClass:"line-number"},[s._v("5")]),t("br"),t("span",{staticClass:"line-number"},[s._v("6")]),t("br"),t("span",{staticClass:"line-number"},[s._v("7")]),t("br"),t("span",{staticClass:"line-number"},[s._v("8")]),t("br"),t("span",{staticClass:"line-number"},[s._v("9")]),t("br"),t("span",{staticClass:"line-number"},[s._v("10")]),t("br"),t("span",{staticClass:"line-number"},[s._v("11")]),t("br"),t("span",{staticClass:"line-number"},[s._v("12")]),t("br"),t("span",{staticClass:"line-number"},[s._v("13")]),t("br")])]),t("p",[s._v("在上面的示例中,"),t("code",[s._v("@Aspect")]),s._v(" 注解将该类标记为一个切面,@Before 注解定义了一个前置通知,它在 com.example.service 包中的所有方法执行前执行。")]),s._v(" "),t("ol",{attrs:{start:"3"}},[t("li",[t("strong",[s._v("配置 AspectJ 支持")]),s._v(":在 Spring 配置文件中启用 AspectJ 支持。您可以使用 XML 配置或基于 Java 的配置来完成这一步。")])]),s._v(" "),t("ul",[t("li",[s._v("XML 配置示例:")])]),s._v(" "),t("div",{staticClass:"language-xml line-numbers-mode"},[t("pre",{pre:!0,attrs:{class:"language-xml"}},[t("code",[t("span",{pre:!0,attrs:{class:"token tag"}},[t("span",{pre:!0,attrs:{class:"token tag"}},[t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("<")]),t("span",{pre:!0,attrs:{class:"token namespace"}},[s._v("aop:")]),s._v("aspectj-autoproxy")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("/>")])]),s._v("\n")])]),s._v(" "),t("div",{staticClass:"line-numbers-wrapper"},[t("span",{staticClass:"line-number"},[s._v("1")]),t("br")])]),t("ul",[t("li",[s._v("Java 配置示例:")])]),s._v(" "),t("div",{staticClass:"language-java line-numbers-mode"},[t("pre",{pre:!0,attrs:{class:"language-java"}},[t("code",[t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("import")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token import"}},[t("span",{pre:!0,attrs:{class:"token namespace"}},[s._v("org"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),s._v("springframework"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),s._v("context"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),s._v("annotation"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")])]),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("EnableAspectJAutoProxy")])]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n\n"),t("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[s._v("@Configuration")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[s._v("@EnableAspectJAutoProxy")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("public")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("class")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("AppConfig")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n    "),t("span",{pre:!0,attrs:{class:"token comment"}},[s._v("// 其他配置...")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n")])]),s._v(" "),t("div",{staticClass:"line-numbers-wrapper"},[t("span",{staticClass:"line-number"},[s._v("1")]),t("br"),t("span",{staticClass:"line-number"},[s._v("2")]),t("br"),t("span",{staticClass:"line-number"},[s._v("3")]),t("br"),t("span",{staticClass:"line-number"},[s._v("4")]),t("br"),t("span",{staticClass:"line-number"},[s._v("5")]),t("br"),t("span",{staticClass:"line-number"},[s._v("6")]),t("br"),t("span",{staticClass:"line-number"},[s._v("7")]),t("br")])]),t("ol",{attrs:{start:"4"}},[t("li",[t("p",[t("strong",[s._v("在目标 Bean 上应用切面")]),s._v(":确保您的切面生效,需要在目标 Bean 上应用切面。您可以使用 "),t("code",[s._v("@Component")]),s._v(" 或其他 Spring 组件扫描注解来确保目标 Bean 被 Spring 管理。")])]),s._v(" "),t("li",[t("p",[t("strong",[s._v("运行应用程序")]),s._v(":启动您的 Spring 应用程序。AspectJ 将会自动拦截匹配切点表达式的方法,并在适当的时候执行通知。")])]),s._v(" "),t("li",[t("p",[t("strong",[s._v("验证 AOP 效果")]),s._v(":调用目标 Bean 上的方法,然后检查切面的通知是否按预期执行。")])])]),s._v(" "),t("p",[s._v("这些是使用 AspectJ 在 Spring 中实现 AOP 的一般步骤。您可以根据具体的需求和场景定义不同类型的通知(前置、后置、环绕等)以及切点表达式来捕获不同的横切关注点。AspectJ 提供了丰富的语法和功能,以满足各种 AOP 需求。")]),s._v(" "),t("hr"),s._v(" "),t("p",[t("strong",[s._v("AspectJ 的工作原理涉及以下几个关键概念和组件")])]),s._v(" "),t("ul",[t("li",[t("p",[s._v("切面(Aspect):切面是一个模块,它包含了一组通知(Advice)和切点(Pointcut)。通知定义了在何时和何地执行横切关注点,而切点定义了在何处执行通知。")])]),s._v(" "),t("li",[t("p",[s._v("通知(Advice):通知是切面的具体行为。AspectJ 支持多种类型的通知,包括前置通知(Before)、后置通知(After)、环绕通知(Around)等。通知是在切点处执行的代码片段。")])]),s._v(" "),t("li",[t("p",[s._v("切点(Pointcut):切点是一个表达式,它定义了在程序中的哪些位置执行通知。切点可以使用 AspectJ 的切点表达式语言来定义,例如,执行某个包中的所有方法或者执行某个特定注解标记的方法。")])]),s._v(" "),t("li",[t("p",[s._v("连接点(Join Point):连接点是程序执行过程中的一个具体点,例如方法的调用、方法的执行、对象的创建等。连接点是切点的实际实例,它是通知实际执行的地方。")])]),s._v(" "),t("li",[t("p",[s._v("织入(Weaving):织入是将切面与应用程序的目标代码连接在一起的过程。在编译时、类加载时或运行时,AspectJ 可以将切面织入到目标代码中,以执行通知。")])]),s._v(" "),t("li",[t("p",[s._v("目标对象(Target Object):目标对象是应用程序中的原始对象,它可能包含横切关注点。切面可以通过通知来影响目标对象的行为。")])])]),s._v(" "),t("p",[t("strong",[s._v("AspectJ 的工作原理可以概括为以下几个步骤")])]),s._v(" "),t("ol",[t("li",[t("p",[s._v("定义切面:开发人员定义一个切面,其中包含了通知和切点的定义。")])]),s._v(" "),t("li",[t("p",[s._v("编写切点表达式:开发人员编写切点表达式,以指定在何处执行通知。切点表达式可以选择性地使用各种条件,如方法名称、方法参数、注解等。")])]),s._v(" "),t("li",[t("p",[s._v("织入切面:AspectJ 在适当的时机将切面织入到目标代码中。这可以在编译时、类加载时或运行时进行。")])]),s._v(" "),t("li",[t("p",[s._v("执行通知:当程序执行达到切点时,AspectJ 执行与切点相关联的通知。通知可以在切点之前、之后或代替切点执行。")])])]),s._v(" "),t("h2",{attrs:{id:"常用依赖"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#常用依赖"}},[s._v("#")]),s._v(" 常用依赖")]),s._v(" "),t("h3",{attrs:{id:"lombok"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#lombok"}},[s._v("#")]),s._v(" lombok")]),s._v(" "),t("blockquote",[t("p",[t("code",[s._v("org.projectlombok:lombok")]),s._v(":Lombok 是一个 Java 库,它通过使用注解来减少 Java 代码的样板代码,从而简化 Java 开发")])]),s._v(" "),t("p",[t("code",[s._v("@Data")]),s._v("注解是 Lombok 库中的一个注解,它可以自动生成 Java 类的通用方法,如 toString、equals、hashCode 和"),t("code",[s._v("Getter/Setter")]),s._v("方法等。然而,如果您想要使用"),t("code",[s._v("@Data")]),s._v("注解生成 Getter 方法,但不生成 Setter 方法,可以使用@Getter 注解来实现这一目标。以下是示例:")]),s._v(" "),t("div",{staticClass:"language-java line-numbers-mode"},[t("pre",{pre:!0,attrs:{class:"language-java"}},[t("code",[t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("import")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token import"}},[t("span",{pre:!0,attrs:{class:"token namespace"}},[s._v("lombok"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")])]),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Data")])]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("import")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token import"}},[t("span",{pre:!0,attrs:{class:"token namespace"}},[s._v("lombok"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")])]),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Getter")])]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n\n"),t("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[s._v("@Data")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("public")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("class")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("MyData")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n    "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("private")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("String")]),s._v(" field1"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n\n    "),t("span",{pre:!0,attrs:{class:"token comment"}},[s._v("// 使用@Getter注解生成Getter方法,但不生成Setter方法")]),s._v("\n    "),t("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[s._v("@Getter")]),s._v("\n    "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("private")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("String")]),s._v(" field2"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n")])]),s._v(" "),t("div",{staticClass:"line-numbers-wrapper"},[t("span",{staticClass:"line-number"},[s._v("1")]),t("br"),t("span",{staticClass:"line-number"},[s._v("2")]),t("br"),t("span",{staticClass:"line-number"},[s._v("3")]),t("br"),t("span",{staticClass:"line-number"},[s._v("4")]),t("br"),t("span",{staticClass:"line-number"},[s._v("5")]),t("br"),t("span",{staticClass:"line-number"},[s._v("6")]),t("br"),t("span",{staticClass:"line-number"},[s._v("7")]),t("br"),t("span",{staticClass:"line-number"},[s._v("8")]),t("br"),t("span",{staticClass:"line-number"},[s._v("9")]),t("br"),t("span",{staticClass:"line-number"},[s._v("10")]),t("br"),t("span",{staticClass:"line-number"},[s._v("11")]),t("br")])]),t("p",[s._v("在这个示例中,"),t("code",[s._v("@Data")]),s._v("注解用于自动生成通用方法,包括 Getter 方法。然而,通过在 field2 上使用@Getter 注解,我们告诉 Lombok 只生成 Getter 方法,而不生成 Setter 方法。")]),s._v(" "),t("p",[s._v("这样,对于 field1,"),t("code",[s._v("@Data")]),s._v("会生成 Getter 和 Setter 方法,而对于 field2,只会生成 Getter 方法。")]),s._v(" "),t("p",[s._v("请确保您已经将 Lombok 库添加到项目的依赖中,以便使用这些注解。通常,您需要在项目的 build.gradle 或 pom.xml 文件中添加 Lombok 的依赖。")]),s._v(" "),t("p",[t("strong",[s._v("声明")])]),s._v(" "),t("code-group",[t("code-block",{attrs:{title:"gradle",active:""}},[t("div",{staticClass:"language-groovy line-numbers-mode"},[t("pre",{pre:!0,attrs:{class:"language-groovy"}},[t("code",[s._v("implementation "),t("span",{pre:!0,attrs:{class:"token string"}},[s._v("'org.projectlombok:lombok:1.18.22'")]),s._v("\nannotationProcessor "),t("span",{pre:!0,attrs:{class:"token string"}},[s._v("'org.projectlombok:lombok:1.18.22'")]),s._v("\n")])]),s._v(" "),t("div",{staticClass:"line-numbers-wrapper"},[t("span",{staticClass:"line-number"},[s._v("1")]),t("br"),t("span",{staticClass:"line-number"},[s._v("2")]),t("br")])])]),s._v(" "),t("code-block",{attrs:{title:"maven"}},[t("div",{staticClass:"language-groovy line-numbers-mode"},[t("pre",{pre:!0,attrs:{class:"language-groovy"}},[t("code",[t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("<")]),s._v("dependency"),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v(">")]),s._v("\n    "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("<")]),s._v("groupId"),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v(">")]),s._v("org"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),s._v("projectlombok"),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("<")]),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("/")]),s._v("groupId"),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v(">")]),s._v("\n    "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("<")]),s._v("artifactId"),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v(">")]),s._v("lombok"),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("<")]),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("/")]),s._v("artifactId"),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v(">")]),s._v("\n    "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("<")]),s._v("optional"),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v(">")]),t("span",{pre:!0,attrs:{class:"token boolean"}},[s._v("true")]),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("<")]),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("/")]),s._v("optional"),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v(">")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("<")]),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("/")]),s._v("dependency"),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v(">")]),s._v("\n")])]),s._v(" "),t("div",{staticClass:"line-numbers-wrapper"},[t("span",{staticClass:"line-number"},[s._v("1")]),t("br"),t("span",{staticClass:"line-number"},[s._v("2")]),t("br"),t("span",{staticClass:"line-number"},[s._v("3")]),t("br"),t("span",{staticClass:"line-number"},[s._v("4")]),t("br"),t("span",{staticClass:"line-number"},[s._v("5")]),t("br")])])])],1),s._v(" "),t("p",[s._v("在 maven 申明中,如果"),t("code",[s._v("@Data")]),s._v("注解不生成相关方法,可以尝试。 "),t("code",[s._v("reload maven")]),s._v(" 根据 IDE 的提示操作")]),s._v(" "),t("h3",{attrs:{id:"logback"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#logback"}},[s._v("#")]),s._v(" logback")]),s._v(" "),t("p",[s._v("Logback 是一个开源的日志框架,用于在 Java 应用程序中记录日志。它是 log4j 框架的继承者,并提供了更多的功能和性能优化。Logback 被广泛用于各种 Java 应用程序中,包括 Web 应用、企业应用和后端服务。以下是 Logback 的主要特点和用法:")]),s._v(" "),t("p",[t("strong",[s._v("特点")]),s._v(":")]),s._v(" "),t("ul",[t("li",[t("p",[s._v("高性能:Logback 被设计为高性能的日志框架,能够在不影响应用程序性能的情况下记录大量日志。")])]),s._v(" "),t("li",[t("p",[s._v("灵活的配置:Logback 支持 XML 和 Groovy 等多种配置方式,允许开发人员灵活配置日志记录器、格式化器、输出目标等。")])]),s._v(" "),t("li",[t("p",[s._v("多种输出目标:Logback 支持多种输出目标,包括控制台、文件、远程服务器、数据库等。您可以根据需要将日志记录到不同的地方。")])]),s._v(" "),t("li",[t("p",[s._v("异步日志记录:Logback 支持异步日志记录,可以将日志记录操作异步执行,以提高应用程序的性能。")])]),s._v(" "),t("li",[t("p",[s._v("可插拔的组件:Logback 的组件(如 Appenders、Layouts 和 Filters)都是可插拔的,可以根据需求进行扩展或替换。")])]),s._v(" "),t("li",[t("p",[s._v("日志级别:Logback 支持不同的日志级别,包括 TRACE、DEBUG、INFO、WARN 和 ERROR,允许开发人员根据需要记录不同详细程度的日志。")])])]),s._v(" "),t("p",[t("strong",[s._v("用法")]),s._v(":")]),s._v(" "),t("ol",[t("li",[t("strong",[s._v("添加 Logback 依赖")]),s._v(":首先,在项目的依赖管理中添加 Logback 的依赖。通常,您可以在 Maven 或 Gradle 中添加以下依赖:")])]),s._v(" "),t("div",{staticClass:"language-xml line-numbers-mode"},[t("pre",{pre:!0,attrs:{class:"language-xml"}},[t("code",[t("span",{pre:!0,attrs:{class:"token tag"}},[t("span",{pre:!0,attrs:{class:"token tag"}},[t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("<")]),s._v("dependency")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(">")])]),s._v("\n    "),t("span",{pre:!0,attrs:{class:"token tag"}},[t("span",{pre:!0,attrs:{class:"token tag"}},[t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("<")]),s._v("groupId")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(">")])]),s._v("ch.qos.logback"),t("span",{pre:!0,attrs:{class:"token tag"}},[t("span",{pre:!0,attrs:{class:"token tag"}},[t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("")])]),s._v("\n    "),t("span",{pre:!0,attrs:{class:"token tag"}},[t("span",{pre:!0,attrs:{class:"token tag"}},[t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("<")]),s._v("artifactId")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(">")])]),s._v("logback-classic"),t("span",{pre:!0,attrs:{class:"token tag"}},[t("span",{pre:!0,attrs:{class:"token tag"}},[t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("")])]),s._v("\n    "),t("span",{pre:!0,attrs:{class:"token tag"}},[t("span",{pre:!0,attrs:{class:"token tag"}},[t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("<")]),s._v("version")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(">")])]),s._v("2.0.0"),t("span",{pre:!0,attrs:{class:"token tag"}},[t("span",{pre:!0,attrs:{class:"token tag"}},[t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("")])]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token tag"}},[t("span",{pre:!0,attrs:{class:"token tag"}},[t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("")])]),s._v("\n")])]),s._v(" "),t("div",{staticClass:"line-numbers-wrapper"},[t("span",{staticClass:"line-number"},[s._v("1")]),t("br"),t("span",{staticClass:"line-number"},[s._v("2")]),t("br"),t("span",{staticClass:"line-number"},[s._v("3")]),t("br"),t("span",{staticClass:"line-number"},[s._v("4")]),t("br"),t("span",{staticClass:"line-number"},[s._v("5")]),t("br")])]),t("ol",{attrs:{start:"2"}},[t("li",[t("strong",[s._v("创建 Logback 配置文件")]),s._v(":您需要创建 Logback 的配置文件,通常命名为"),t("code",[s._v("logback.xml")]),s._v("或"),t("code",[s._v("logback.groovy")]),s._v("。该文件用于配置日志记录器、输出目标、格式化等。")])]),s._v(" "),t("p",[s._v("以下是一个示例的 logback.xml 配置文件:")]),s._v(" "),t("div",{staticClass:"language-xml line-numbers-mode"},[t("pre",{pre:!0,attrs:{class:"language-xml"}},[t("code",[t("span",{pre:!0,attrs:{class:"token tag"}},[t("span",{pre:!0,attrs:{class:"token tag"}},[t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("<")]),s._v("configuration")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(">")])]),s._v("\n    "),t("span",{pre:!0,attrs:{class:"token tag"}},[t("span",{pre:!0,attrs:{class:"token tag"}},[t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("<")]),s._v("appender")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token attr-name"}},[s._v("name")]),t("span",{pre:!0,attrs:{class:"token attr-value"}},[t("span",{pre:!0,attrs:{class:"token punctuation attr-equals"}},[s._v("=")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v('"')]),s._v("CONSOLE"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v('"')])]),s._v(" "),t("span",{pre:!0,attrs:{class:"token attr-name"}},[s._v("class")]),t("span",{pre:!0,attrs:{class:"token attr-value"}},[t("span",{pre:!0,attrs:{class:"token punctuation attr-equals"}},[s._v("=")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v('"')]),s._v("ch.qos.logback.core.ConsoleAppender"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v('"')])]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(">")])]),s._v("\n        "),t("span",{pre:!0,attrs:{class:"token tag"}},[t("span",{pre:!0,attrs:{class:"token tag"}},[t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("<")]),s._v("encoder")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(">")])]),s._v("\n            "),t("span",{pre:!0,attrs:{class:"token tag"}},[t("span",{pre:!0,attrs:{class:"token tag"}},[t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("<")]),s._v("pattern")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(">")])]),s._v("%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n"),t("span",{pre:!0,attrs:{class:"token tag"}},[t("span",{pre:!0,attrs:{class:"token tag"}},[t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("")])]),s._v("\n        "),t("span",{pre:!0,attrs:{class:"token tag"}},[t("span",{pre:!0,attrs:{class:"token tag"}},[t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("")])]),s._v("\n    "),t("span",{pre:!0,attrs:{class:"token tag"}},[t("span",{pre:!0,attrs:{class:"token tag"}},[t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("")])]),s._v("\n    "),t("span",{pre:!0,attrs:{class:"token tag"}},[t("span",{pre:!0,attrs:{class:"token tag"}},[t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("<")]),s._v("root")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token attr-name"}},[s._v("level")]),t("span",{pre:!0,attrs:{class:"token attr-value"}},[t("span",{pre:!0,attrs:{class:"token punctuation attr-equals"}},[s._v("=")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v('"')]),s._v("debug"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v('"')])]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(">")])]),s._v("\n        "),t("span",{pre:!0,attrs:{class:"token tag"}},[t("span",{pre:!0,attrs:{class:"token tag"}},[t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("<")]),s._v("appender-ref")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token attr-name"}},[s._v("ref")]),t("span",{pre:!0,attrs:{class:"token attr-value"}},[t("span",{pre:!0,attrs:{class:"token punctuation attr-equals"}},[s._v("=")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v('"')]),s._v("CONSOLE"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v('"')])]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("/>")])]),s._v("\n    "),t("span",{pre:!0,attrs:{class:"token tag"}},[t("span",{pre:!0,attrs:{class:"token tag"}},[t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("")])]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token tag"}},[t("span",{pre:!0,attrs:{class:"token tag"}},[t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("")])]),s._v("\n")])]),s._v(" "),t("div",{staticClass:"line-numbers-wrapper"},[t("span",{staticClass:"line-number"},[s._v("1")]),t("br"),t("span",{staticClass:"line-number"},[s._v("2")]),t("br"),t("span",{staticClass:"line-number"},[s._v("3")]),t("br"),t("span",{staticClass:"line-number"},[s._v("4")]),t("br"),t("span",{staticClass:"line-number"},[s._v("5")]),t("br"),t("span",{staticClass:"line-number"},[s._v("6")]),t("br"),t("span",{staticClass:"line-number"},[s._v("7")]),t("br"),t("span",{staticClass:"line-number"},[s._v("8")]),t("br"),t("span",{staticClass:"line-number"},[s._v("9")]),t("br"),t("span",{staticClass:"line-number"},[s._v("10")]),t("br")])]),t("ol",{attrs:{start:"3"}},[t("li",[t("strong",[s._v("在代码中使用 Logback")]),s._v(":在应用程序代码中,您可以通过 Logback 的日志记录器(Logger)来记录日志。通常,您需要在类中创建一个 Logger 实例,并使用不同级别的日志记录方法来记录信息。")])]),s._v(" "),t("div",{staticClass:"language-java line-numbers-mode"},[t("pre",{pre:!0,attrs:{class:"language-java"}},[t("code",[t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("import")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token import"}},[t("span",{pre:!0,attrs:{class:"token namespace"}},[s._v("org"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),s._v("slf4j"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")])]),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Logger")])]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("import")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token import"}},[t("span",{pre:!0,attrs:{class:"token namespace"}},[s._v("org"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),s._v("slf4j"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")])]),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("LoggerFactory")])]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n\n"),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("public")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("class")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("MyClass")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n    "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("private")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("static")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("final")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Logger")]),s._v(" logger "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("LoggerFactory")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("getLogger")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("MyClass")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("class")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n\n    "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("public")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("void")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("doSomething")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n        logger"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("debug")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token string"}},[s._v('"Debug message"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n        logger"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("info")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token string"}},[s._v('"Info message"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n        logger"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("warn")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token string"}},[s._v('"Warning message"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n        logger"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("error")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token string"}},[s._v('"Error message"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n    "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n")])]),s._v(" "),t("div",{staticClass:"line-numbers-wrapper"},[t("span",{staticClass:"line-number"},[s._v("1")]),t("br"),t("span",{staticClass:"line-number"},[s._v("2")]),t("br"),t("span",{staticClass:"line-number"},[s._v("3")]),t("br"),t("span",{staticClass:"line-number"},[s._v("4")]),t("br"),t("span",{staticClass:"line-number"},[s._v("5")]),t("br"),t("span",{staticClass:"line-number"},[s._v("6")]),t("br"),t("span",{staticClass:"line-number"},[s._v("7")]),t("br"),t("span",{staticClass:"line-number"},[s._v("8")]),t("br"),t("span",{staticClass:"line-number"},[s._v("9")]),t("br"),t("span",{staticClass:"line-number"},[s._v("10")]),t("br"),t("span",{staticClass:"line-number"},[s._v("11")]),t("br"),t("span",{staticClass:"line-number"},[s._v("12")]),t("br"),t("span",{staticClass:"line-number"},[s._v("13")]),t("br")])]),t("ol",{attrs:{start:"4"}},[t("li",[t("strong",[s._v("运行和查看日志")]),s._v(":运行应用程序后,Logback 将根据配置记录日志。您可以在控制台、日志文件或其他配置的输出目标中查看日志信息。")])]),s._v(" "),t("p",[s._v("总之,Logback 是一个功能强大且易于使用的日志框架,它可以帮助您在 Java 应用程序中进行灵活和高性能的日志记录。通过合适的配置和日志级别,您可以控制日志的详细程度,并轻松地跟踪和调试应用程序。")]),s._v(" "),t("h3",{attrs:{id:"mybatis"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#mybatis"}},[s._v("#")]),s._v(" mybatis")]),s._v(" "),t("p",[t("strong",[s._v("链接:")])]),s._v(" "),t("ul",[t("li",[s._v("Mybatis 官方文档:"),t("a",{attrs:{href:"http://www.mybatis.org/mybatis-3/zh/index.html",target:"_blank",rel:"noopener noreferrer"}},[s._v("http://www.mybatis.org/mybatis-3/zh/index.html"),t("OutboundLink")],1)]),s._v(" "),t("li",[s._v("Mybatis 官方脚手架文档:"),t("a",{attrs:{href:"http://www.mybatis.org/spring-boot-starter/mybatis-spring-boot-autoconfigure/",target:"_blank",rel:"noopener noreferrer"}},[s._v("http://www.mybatis.org/spring-boot-starter/mybatis-spring-boot-autoconfigure/"),t("OutboundLink")],1)]),s._v(" "),t("li",[s._v("Mybatis 整合 Spring Boot 官方 demo:"),t("a",{attrs:{href:"https://github.com/mybatis/spring-boot-starter/tree/master/mybatis-spring-boot-samples",target:"_blank",rel:"noopener noreferrer"}},[s._v("https://github.com/mybatis/spring-boot-starter/tree/master/mybatis-spring-boot-samples"),t("OutboundLink")],1)])]),s._v(" "),t("p",[t("strong",[s._v("原理简述:")])]),s._v(" "),t("p",[s._v("MyBatis 是一个流行的 Java 持久性框架,它提供了一种将 Java 对象映射到数据库表的方法,同时还支持灵活的 SQL 查询。下面是 MyBatis 的一些核心原理和工作方式:")]),s._v(" "),t("ul",[t("li",[t("p",[t("strong",[s._v("SQL 映射文件")])]),s._v(" "),t("p",[s._v("MyBatis 的核心是 SQL 映射文件,这些文件包含了 SQL 语句和映射规则,将 Java 对象与数据库表进行映射。每个映射文件通常对应一个数据库表,并定义了如何将数据从数据库表映射到 Java 对象以及反之。")])]),s._v(" "),t("li",[t("p",[t("strong",[s._v("配置文件")])]),s._v(" "),t("p",[s._v("MyBatis 需要一个配置文件来初始化和配置框架。该配置文件指定了数据库连接信息、映射文件的位置、缓存策略等配置选项。这个配置文件通常是 mybatis-config.xml。")])]),s._v(" "),t("li",[t("p",[t("strong",[s._v("SqlSessionFactory")])]),s._v(" "),t("p",[s._v("SqlSessionFactory 是 MyBatis 的核心接口之一,它是用于创建 SqlSession 的工厂。SqlSession 是 MyBatis 中用于执行 SQL 操作的主要接口。")])]),s._v(" "),t("li",[t("p",[t("strong",[s._v("SqlSession")])]),s._v(" "),t("p",[s._v("SqlSession 表示与数据库的一次会话,它提供了执行 SQL 语句、提交事务、关闭会话等操作。通常,每个数据库操作都需要创建一个 SqlSession 实例。")])]),s._v(" "),t("li",[t("p",[t("strong",[s._v("Mapper 接口")])]),s._v(" "),t("p",[s._v("MyBatis 支持将 SQL 映射文件中的 SQL 语句绑定到 Java 接口的方法上。开发者可以创建 Mapper 接口,并使用注解或 XML 配置将接口方法与 SQL 语句进行绑定。MyBatis 会自动生成 Mapper 接口的实现类,用于执行 SQL 操作。")])]),s._v(" "),t("li",[t("p",[t("strong",[s._v("执行 SQL 查询")])]),s._v(" "),t("p",[s._v("当应用程序调用 Mapper 接口的方法时,MyBatis 会根据方法的配置找到相应的 SQL 语句,并将参数传递给 SQL 语句执行。查询结果将被映射到 Java 对象,并返回给调用方。")])]),s._v(" "),t("li",[t("p",[t("strong",[s._v("缓存")])]),s._v(" "),t("p",[s._v("MyBatis 支持查询结果的缓存,以提高性能。它支持两种缓存:本地缓存(SqlSession 级别)和二级缓存(全局级别)。开发者可以根据需求配置缓存。")])]),s._v(" "),t("li",[t("p",[t("strong",[s._v("动态 SQL")])]),s._v(" "),t("p",[s._v("MyBatis 允许使用动态 SQL 构建复杂的 SQL 查询。动态 SQL 允许根据条件包含或排除 SQL 语句的一部分,以实现动态的 SQL 查询。")])]),s._v(" "),t("li",[t("p",[t("strong",[s._v("事务管理")])]),s._v(" "),t("p",[s._v("MyBatis 支持事务管理,可以通过配置来启用或禁用事务。开发者可以使用 commit 和 rollback 操作来管理事务。")])]),s._v(" "),t("li",[t("p",[t("strong",[s._v("插件机制")])]),s._v(" "),t("p",[s._v("MyBatis 提供了一个插件机制,允许开发者扩展框架的功能。您可以编写自定义插件,例如自定义拦截器,来干预 SQL 执行过程。")])])]),s._v(" "),t("p",[s._v("总之,MyBatis 的核心原理涉及 SQL 映射文件、配置文件、SqlSessionFactory、SqlSession、Mapper 接口、SQL 执行、缓存、事务管理等组件的协同工作,使开发者能够轻松地进行数据库访问并进行对象-关系映射。这使得 MyBatis 成为了一个强大且灵活的持久层框架。")]),s._v(" "),t("h2",{attrs:{id:"其他"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#其他"}},[s._v("#")]),s._v(" 其他")]),s._v(" "),t("h3",{attrs:{id:"nginx"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#nginx"}},[s._v("#")]),s._v(" nginx")]),s._v(" "),t("ul",[t("li",[t("a",{attrs:{href:"https://www.nginx.com/",target:"_blank",rel:"noopener noreferrer"}},[s._v("nginx"),t("OutboundLink")],1)]),s._v(" "),t("li",[t("a",{attrs:{href:"https://cloud.tencent.com/developer/article/1943958",target:"_blank",rel:"noopener noreferrer"}},[s._v("全面了解 Nginx 主要应用场景"),t("OutboundLink")],1)])]),s._v(" "),t("p",[s._v('Nginx(发音为"engine-x")是一个高性能的开源 Web 服务器,也可以用作反向代理服务器、负载均衡器、HTTP 缓存以及用于处理 HTTP 请求的应用程序服务器。以下是关于 Nginx 的一些重要信息和功能:')]),s._v(" "),t("ul",[t("li",[t("p",[s._v("高性能:Nginx 以其出色的性能而闻名,特别适用于高流量的网站和应用程序。它使用异步事件驱动的架构,能够处理大量并发连接而不消耗太多内存或系统资源。")])]),s._v(" "),t("li",[t("p",[s._v("反向代理:Nginx 可以用作反向代理服务器,将客户端请求转发给后端服务器,然后将响应返回给客户端。这使得 Nginx 成为构建可伸缩的应用程序架构的重要工具,可以将流量分发给多个后端服务器。")])]),s._v(" "),t("li",[t("p",[s._v("负载均衡:Nginx 支持多种负载均衡算法,包括轮询、IP 哈希、最小连接数等。这使得它可以均衡地分发请求到多个后端服务器,提高应用程序的可用性和性能。")])]),s._v(" "),t("li",[t("p",[s._v("HTTP 缓存:Nginx 充当 HTTP 缓存代理时,可以缓存响应数据,减轻后端服务器的负载,并加快客户端的响应时间。它支持静态文件缓存以及动态内容的缓存。")])]),s._v(" "),t("li",[t("p",[s._v("SSL/TLS 终止:Nginx 可以终止 SSL/TLS 连接,允许您在 Nginx 服务器上配置和管理 HTTPS 通信。这对于加密 Web 流量非常重要。")])]),s._v(" "),t("li",[t("p",[s._v("虚拟主机:Nginx 支持虚拟主机配置,使得可以在同一台服务器上托管多个域名或应用程序,同时保持隔离性和安全性。")])]),s._v(" "),t("li",[t("p",[s._v("模块化架构:Nginx 的模块化架构允许您根据需要加载不同的功能模块,因此可以根据特定的用例自定义配置。")])]),s._v(" "),t("li",[t("p",[s._v("日志和监控:Nginx 生成详细的访问日志,可以帮助您监控网站或应用程序的性能,并进行故障排除。")])]),s._v(" "),t("li",[t("p",[s._v("开源和社区支持:Nginx 是一个开源项目,拥有庞大的社区,提供了丰富的文档、插件和扩展,以及活跃的讨论和支持。")])])]),s._v(" "),t("p",[s._v("总的来说,Nginx 是一个强大而灵活的 Web 服务器和反向代理服务器,适用于各种用例,从简单的静态网站托管到大规模的应用程序负载均衡。它是许多现代 Web 架构的关键组件之一。")]),s._v(" "),t("h3",{attrs:{id:"kibana"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#kibana"}},[s._v("#")]),s._v(" kibana")]),s._v(" "),t("p",[s._v("Kibana 是一个开源的数据可视化工具,通常与 Elasticsearch 结合使用,用于实时地探索、分析和可视化存储在 Elasticsearch 中的数据。Kibana 的主要功能包括:")]),s._v(" "),t("ul",[t("li",[t("p",[s._v("数据可视化:Kibana 允许用户创建各种类型的数据可视化,包括折线图、柱状图、饼图、地图、仪表盘等,以便更直观地理解数据。")])]),s._v(" "),t("li",[t("p",[s._v("实时搜索和过滤:用户可以使用 Kibana 的搜索和过滤功能,轻松地在大量数据中查找、筛选和定位感兴趣的信息。")])]),s._v(" "),t("li",[t("p",[s._v("仪表盘:Kibana 仪表盘是一个可自定义的集合,可以将多个可视化组件组合到一个页面上,以创建自己的仪表盘,以便监控关键性能指标和数据。")])]),s._v(" "),t("li",[t("p",[s._v("日志和事件数据分析:Kibana 被广泛用于分析大规模的日志和事件数据,帮助运维人员、开发人员和安全团队查找问题、追踪日志、发现异常和实施安全监控。")])]),s._v(" "),t("li",[t("p",[s._v("地理数据可视化:Kibana 具有地图可视化功能,可以在地图上显示地理位置相关的数据,如地理热图、点云图、区域边界等。")])]),s._v(" "),t("li",[t("p",[s._v("插件扩展:Kibana 是可扩展的,可以通过插件和扩展来增强其功能,满足不同的需求。Elastic 提供了丰富的插件,同时社区也开发了许多第三方插件。")])]),s._v(" "),t("li",[t("p",[s._v("用户管理和访问控制:Kibana 支持用户认证和授权,可以配置不同用户和角色的访问权限,以保护敏感数据和控制用户能够执行的操作。")])]),s._v(" "),t("li",[t("p",[s._v("集成 Elasticsearch:Kibana 最常与 Elasticsearch 集成使用,Elasticsearch 作为数据存储和检索引擎,Kibana 则负责数据可视化和分析。这个组合通常与 Logstash 一起使用,形成 ELK 堆栈,用于处理、存储和可视化日志数据。")])])]),s._v(" "),t("p",[s._v("总之,Kibana 是一个功能强大的数据可视化工具,适用于各种领域,包括运维监控、应用性能分析、日志分析、安全信息与事件管理(SIEM)等。它可以帮助用户更好地理解和利用其数据,以做出更明智的决策和行动。")]),s._v(" "),t("h3",{attrs:{id:"kubernetes"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#kubernetes"}},[s._v("#")]),s._v(" Kubernetes")]),s._v(" "),t("p",[s._v("Kubernetes(通常缩写为 K8s)是一个开源的容器编排平台,用于自动化应用程序的部署、扩展和管理。Kubernetes 服务器开发涉及构建和维护 Kubernetes 的核心组件,以及为 Kubernetes 编写扩展和插件。以下是 Kubernetes 服务器开发的主要方面和任务:")]),s._v(" "),t("ol",[t("li",[t("strong",[s._v("核心组件开发")])])]),s._v(" "),t("ul",[t("li",[s._v("API 服务器(kube-apiserver):API 服务器是 Kubernetes 集群的控制平面组件之一,它提供了 Kubernetes API 的端点。开发人员可以扩展 API 服务器以添加自定义 API 资源或自定义控制器。")]),s._v(" "),t("li",[s._v("控制器管理器(kube-controller-manager):Kubernetes 中的控制器负责保持集群的期望状态。您可以编写自定义控制器来管理自定义资源。")]),s._v(" "),t("li",[s._v("调度器(kube-scheduler):调度器决定在哪个节点上运行 Pod。定制调度策略可能需要修改或扩展调度器。")])]),s._v(" "),t("p",[t("strong",[s._v("2. 插件和扩展")])]),s._v(" "),t("ul",[t("li",[s._v("CRI 插件:Container Runtime Interface(CRI)插件用于与容器运行时交互,例如 Docker、containerd 等。开发自定义 CRI 插件以支持其他容器运行时。")]),s._v(" "),t("li",[s._v("CNI 插件:Container Network Interface(CNI)插件用于配置 Pod 之间和 Pod 与外部网络之间的网络连接。您可以开发自定义 CNI 插件以满足特定网络要求。")]),s._v(" "),t("li",[s._v("扩展 API:Kubernetes 允许您自定义 API 资源和控制器,以满足应用程序特定的需求。这可以通过 Kubernetes 的自定义资源定义(CRD)来实现。")])]),s._v(" "),t("p",[t("strong",[s._v("3. 安全性和认证")])]),s._v(" "),t("ul",[t("li",[s._v("确保 Kubernetes 组件的安全性,并实施适当的身份验证和授权机制以保护集群。")]),s._v(" "),t("li",[s._v("开发和维护服务账户、角色和角色绑定,以控制 Pod 对 Kubernetes API 的访问权限。")])]),s._v(" "),t("p",[t("strong",[s._v("4. 版本兼容性")])]),s._v(" "),t("ul",[t("li",[s._v("跟踪 Kubernetes 的发行版本,并确保自己的扩展和插件与不同版本的 Kubernetes 兼容。")])]),s._v(" "),t("p",[t("strong",[s._v("5. 测试和调试")])]),s._v(" "),t("ul",[t("li",[s._v("编写单元测试、集成测试和端到端测试,以确保自己的代码在 Kubernetes 集群中正常工作。")]),s._v(" "),t("li",[s._v("开发和使用日志记录和监控工具,以便追踪和解决问题。")])]),s._v(" "),t("p",[t("strong",[s._v("6. 社区参与")])]),s._v(" "),t("ul",[t("li",[s._v("Kubernetes 是一个开源项目,具有活跃的社区。参与社区,与其他开发人员合作解决问题,讨论新功能和改进,参加工作组和会议。")])]),s._v(" "),t("p",[t("strong",[s._v("7. 文档和教育")])]),s._v(" "),t("ul",[t("li",[s._v("编写文档和教程,以帮助其他开发人员了解如何使用和扩展 Kubernetes。")])]),s._v(" "),t("p",[s._v("Kubernetes 服务器开发是一个复杂的任务,需要深入了解 Kubernetes 的核心原理和架构。此外,Kubernetes 社区提供了大量的文档和资源,以帮助开发人员入门和深入研究 Kubernetes 开发。")]),s._v(" "),t("p",[t("strong",[s._v("链接")])]),s._v(" "),t("ul",[t("li",[t("a",{attrs:{href:"https://www.redhat.com/zh/topics/containers/kubernetes-architecture#%E6%A6%82%E8%BF%B0",target:"_blank",rel:"noopener noreferrer"}},[s._v("Kubernetes 架构详解"),t("OutboundLink")],1)])])],1)}),[],!1,null,null,null);t.default=e.exports}}]);
\ No newline at end of file
diff --git a/assets/js/96.9f028032.js b/assets/js/96.9f028032.js
new file mode 100644
index 0000000000..ab11fce527
--- /dev/null
+++ b/assets/js/96.9f028032.js
@@ -0,0 +1 @@
+(window.webpackJsonp=window.webpackJsonp||[]).push([[96],{422:function(s,t,a){"use strict";a.r(t);var n=a(4),e=Object(n.a)({},(function(){var s=this,t=s._self._c;return t("ContentSlotsDistributor",{attrs:{"slot-key":s.$parent.slotKey}},[t("div",{staticClass:"custom-block tip"},[t("p",{staticClass:"custom-block-title"},[s._v("提示")]),s._v(" "),t("p",[s._v("设计模式是在软件开发中常用的解决问题的方法和经验总结。它们提供了一套被广泛认可的解决方案,用于解决在软件设计和开发过程中常见的问题。设计模式通过定义了一些通用的架构模式、结构模式和行为模式,帮助开发人员更好地组织和管理代码,并提高代码的可维护性、可扩展性和重用性。")]),s._v(" "),t("p",[s._v("另外可以看看 "),t("a",{attrs:{href:"https://coolshell.cn/articles/21672.html",target:"_blank",rel:"noopener noreferrer"}},[s._v("我做系统架构的一些原则"),t("OutboundLink")],1),s._v(" 很有思考深度")])]),s._v(" "),t("h2",{attrs:{id:"看懂-uml-类图和时序图"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#看懂-uml-类图和时序图"}},[s._v("#")]),s._v(" 看懂 UML 类图和时序图")]),s._v(" "),t("blockquote",[t("p",[s._v("更多内容可见: "),t("a",{attrs:{href:"https://design-patterns.readthedocs.io/zh_CN/latest/read_uml.html",target:"_blank",rel:"noopener noreferrer"}},[s._v("https://design-patterns.readthedocs.io/zh_CN/latest/read_uml.html"),t("OutboundLink")],1)])]),s._v(" "),t("p",[t("strong",[s._v("示例")]),s._v(" "),t("img",{attrs:{src:"https://raw.githubusercontent.com/jacky1234/picArchieve/master/uPic/shrpmn.jpg",alt:"uml_class_struct"}})]),s._v(" "),t("ul",[t("li",[s._v("车的类图结构为"),t("code",[s._v("<>")]),s._v(",表示车是一个抽象类;")]),s._v(" "),t("li",[s._v("它有两个继承类:小汽车和自行车;它们之间的关系为实现关系,使用带空心箭头的虚线表示;")]),s._v(" "),t("li",[s._v("小汽车为与 SUV 之间也是继承关系,它们之间的关系为泛化关系,使用带空心箭头的实线表示;")]),s._v(" "),t("li",[s._v("小汽车与发动机之间是组合关系,使用带实心箭头的实线表示;")]),s._v(" "),t("li",[s._v("学生与班级之间是聚合关系,使用带空心箭头的实线表示;")]),s._v(" "),t("li",[s._v("学生与身份证之间为关联关系,使用一根实线表示;")]),s._v(" "),t("li",[s._v("学生上学需要用到自行车,与自行车是一种依赖关系,使用带箭头的虚线表示;")])]),s._v(" "),t("p",[t("strong",[t("a",{attrs:{href:"https://www.kancloud.cn/digest/xing-designpattern/143734",target:"_blank",rel:"noopener noreferrer"}},[s._v("说明"),t("OutboundLink")],1)])]),s._v(" "),t("ol",[t("li",[s._v("可见性表示该属性对于类外的元素而言是否可见,包括公有(public)、私有(private)和受保护(protected)三种,在类图中分别用符号+、- 和 # 表示。")])]),s._v(" "),t("h3",{attrs:{id:"聚合与组合"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#聚合与组合"}},[s._v("#")]),s._v(" 聚合与组合")]),s._v(" "),t("p",[s._v('在 UML(统一建模语言)中,"聚合"(Aggregation)和"组合"(Composition)是用来表示类之间的关联关系的两个术语。')]),s._v(" "),t("p",[s._v("聚合表示类之间的一种关联关系,其中一个类(整体)包含另一个类(部分)。聚合关系是一种弱关系,意味着整体对象和部分对象可以存在独立于彼此的生命周期。聚合关系通常使用一个带空心菱形的线表示,该菱形指向整体对象。")]),s._v(" "),t("p",[s._v("组合表示类之间的一种关联关系,其中一个类(整体)包含另一个类(部分)。组合关系是一种强关系,意味着整体对象和部分对象的生命周期是紧密相连的,部分对象不能独立存在。如果整体对象被销毁,部分对象也将被销毁。组合关系通常使用一个带实心菱形的线表示,该菱形指向整体对象。")]),s._v(" "),t("p",[s._v('简而言之,聚合关系表示"整体-部分"的关系,而组合关系表示"整体-部分"的强关系,部分对象与整体对象有更紧密的依赖关系。')]),s._v(" "),t("h2",{attrs:{id:"设计模式的六大原则"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#设计模式的六大原则"}},[s._v("#")]),s._v(" 设计模式的六大原则")]),s._v(" "),t("blockquote",[t("p",[s._v("更多内容可见: "),t("a",{attrs:{href:"https://www.kancloud.cn/digest/xing-designpattern/143718",target:"_blank",rel:"noopener noreferrer"}},[s._v("https://www.kancloud.cn/digest/xing-designpattern/143718"),t("OutboundLink")],1)])]),s._v(" "),t("ol",[t("li",[s._v("单一职责原则")]),s._v(" "),t("li",[s._v("开闭原则\n"),t("blockquote",[t("p",[s._v("对于扩展是开放的,但是对于修改是封闭的。")])])]),s._v(" "),t("li",[s._v("里氏替换原则\n"),t("blockquote",[t("p",[s._v("里氏替换原则是继承复用的基石。只有当衍生类可以替换掉基类,软件单位的功能不会受到影响时,基类才能真正的被复用,而衍生类也才能够在基类的基础上增加新的行为。")])])]),s._v(" "),t("li",[s._v("依赖倒置原则\n"),t("blockquote",[t("p",[s._v("在 java 中的表现是:模块间的依赖通过抽象发生,实体类之间不发生直接的依赖关系,其依赖关系是通过接口或抽象类产生。")])])]),s._v(" "),t("li",[s._v("接口隔离原则\n"),t("blockquote",[t("p",[s._v("接口隔离的目的是系统解开耦合,从而容易重构,更改和重新部署 。")])])]),s._v(" "),t("li",[s._v("迪米特原则")])]),s._v(" "),t("h2",{attrs:{id:"spi"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#spi"}},[s._v("#")]),s._v(" SPI")]),s._v(" "),t("div",{staticClass:"custom-block tip"},[t("p",{staticClass:"custom-block-title"},[s._v("提示")]),s._v(" "),t("p",[s._v("SPI 是 Java 平台提供的一种机制,允许应用程序在运行时动态加载和发现实现某个接口的服务提供者\n通常我们会使用 google 的 AutoService 来简化整个过程 SPI 过程.")]),s._v(" "),t("blockquote",[t("p",[s._v("AutoService: configuration/metadata generator for java.util.ServiceLoader-style service providers")])]),s._v(" "),t("p",[s._v("你可以在 "),t("a",{attrs:{href:"https://mvnrepository.com/artifact/com.google.auto.service/auto-service",target:"_blank",rel:"noopener noreferrer"}},[s._v("mvnrepository"),t("OutboundLink")],1),s._v(" 查看最新的 AutoService 版本")])]),s._v(" "),t("p",[s._v("Google Autoservice 的原理如下:")]),s._v(" "),t("ol",[t("li",[t("p",[s._v("定义服务接口:首先,您需要定义一个服务接口,该接口定义了所需的功能或行为。接口通常在一个单独的库或模块中定义,并作为提供者和使用者之间的契约。")])]),s._v(" "),t("li",[t("p",[s._v("实现服务提供者:接下来,您需要实现服务接口的一个或多个具体实现。每个实现都需要提供一个无参数的构造函数,并且通常在独立的模块中实现。")])]),s._v(" "),t("li",[t("p",[s._v("创建 SPI 配置文件:为了将服务提供者注册到应用程序中,您需要创建一个 SPI 配置文件。该配置文件是一个文本文件,位于 META-INF/services 目录下,文件名与服务接口的全限定名相同。在配置文件中,每一行包含一个服务提供者的完全限定名。")])]),s._v(" "),t("li",[t("p",[s._v("使用 Google Autoservice 注解:为了简化服务提供者的注册过程,您可以使用 Google Autoservice 库中提供的"),t("code",[s._v("@AutoService")]),s._v(" 注解。将此注解应用于服务提供者的实现类上,它将自动生成 SPI 配置文件,并将服务提供者自动注册到应用程序中。")])]),s._v(" "),t("li",[t("p",[s._v("加载和使用服务提供者:在应用程序中,您可以使用 Java 的 ServiceLoader 类来加载和使用服务提供者。ServiceLoader 类允许您动态加载服务提供者的实现,并在运行时获取它们的实例。")])])]),s._v(" "),t("p",[s._v("通过使用 Google Autoservice 库,您可以简化 SPI 的使用过程,自动注册和发现服务提供者,从而实现更灵活和可扩展的应用程序架构。")]),s._v(" "),t("h2",{attrs:{id:"aop"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#aop"}},[s._v("#")]),s._v(" AOP")]),s._v(" "),t("div",{staticClass:"custom-block tip"},[t("p",{staticClass:"custom-block-title"},[s._v("提示")]),s._v(" "),t("p",[s._v("AOP 它提倡的是针对同一类问题的统一处理.\n那么 AOP 这种编程思想有什么用呢,一般来说,主要用于不想侵入原有代码的场景中,例如 SDK 需要无侵入的在宿主中插入一些代码,做日志埋点、性能监控、动态权限控制、甚至是代码调试等等。")])]),s._v(" "),t("p",[s._v("Spring DI(依赖注入) IOC(控制反转)")]),s._v(" "),t("p",[t("a",{attrs:{href:"https://juejin.im/entry/589fd852128fe100659443b8",target:"_blank",rel:"noopener noreferrer"}},[s._v("面向切面编程。"),t("OutboundLink")],1)]),s._v(" "),t("p",[s._v("有一些工具和库帮助我们使用 AOP:")]),s._v(" "),t("ul",[t("li",[s._v("AspectJ: 一个 JavaTM 语言的面向切面编程的无缝扩展(适用 Android)。")]),s._v(" "),t("li",[s._v("Jake 大神的 Hugo,"),t("a",{attrs:{href:"https://github.com/JakeWharton/hugo",target:"_blank",rel:"noopener noreferrer"}},[s._v("https://github.com/JakeWharton/hugo"),t("OutboundLink")],1)]),s._v(" "),t("li",[s._v("Javassist for Android: 用于字节码操作的知名 java 类库 Javassist 的 Android 平台移植版。")]),s._v(" "),t("li",[s._v("DexMaker: Dalvik 虚拟机上,在编译期或者运行时生成代码的 Java API。")]),s._v(" "),t("li",[s._v("ASMDEX: 一个类似 ASM 的字节码操作库,运行在 Android 平台,操作 Dex 字节码。")])]),s._v(" "),t("h2",{attrs:{id:"结构型设计模式"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#结构型设计模式"}},[s._v("#")]),s._v(" 结构型设计模式")]),s._v(" "),t("h3",{attrs:{id:"mvc-mvp-mvvm"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#mvc-mvp-mvvm"}},[s._v("#")]),s._v(" MVC MVP MVVM")]),s._v(" "),t("div",{staticClass:"custom-block tip"},[t("p",{staticClass:"custom-block-title"},[s._v("提示")]),s._v(" "),t("p",[s._v("MVC(Model-View-Controller),MVP(Model-View-Presenter)和 MVVM(Model-View-ViewModel)是三种常见的架构模式。它们被广泛应用于各种编程语言和框架中,以帮助开发人员组织和管理代码,并实现良好的可维护性和可扩展性。")]),s._v(" "),t("p",[s._v("他们间的区别可以参考:")]),s._v(" "),t("ul",[t("li",[t("a",{attrs:{href:"https://zhuanlan.zhihu.com/p/38108311",target:"_blank",rel:"noopener noreferrer"}},[s._v("MVC,MVP 和 MVVM 模式如何选择?"),t("OutboundLink")],1)]),s._v(" "),t("li",[t("a",{attrs:{href:"https://www.geeksforgeeks.org/difference-between-mvc-mvp-and-mvvm-architecture-pattern-in-android/",target:"_blank",rel:"noopener noreferrer"}},[s._v("difference-between-mvc-mvp-and-mvvm-architecture-pattern-in-android"),t("OutboundLink")],1)])])]),s._v(" "),t("h4",{attrs:{id:"mvc"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#mvc"}},[s._v("#")]),s._v(" MVC")]),s._v(" "),t("p",[s._v("MVC 是一种经典的设计模式,用于将应用程序的逻辑、数据和用户界面相互分离。它包括以下三个核心组件:")]),s._v(" "),t("ul",[t("li",[s._v("视图(View): It is the UI(User Interface) layer that holds components that are visible on the screen")]),s._v(" "),t("li",[s._v("控制器(Controller): This component establishes the relationship between the View and the Model")]),s._v(" "),t("li",[s._v("模型(Model): This component stores the application data.")])]),s._v(" "),t("p",[s._v("在传统的 MVC 模式中,View 和 Controller 是紧密耦合的,它们之间存在双向的交互。然而,在 Android 中,通常使用了一种变种的 MVC 模式,称为 Passive View。在 Passive View 中,View 不直接与 Model 进行交互,而是通过 Controller 来间接操作和更新 Model。")]),s._v(" "),t("p",[s._v("一、mvc 的结构")]),s._v(" "),t("p",[t("img",{attrs:{src:"https://raw.githubusercontent.com/jacky1234/picArchieve/master/uPic/OxN8jk.jpg",alt:"mvc"}})]),s._v(" "),t("p",[s._v("二、MVC 的调用关系")]),s._v(" "),t("p",[s._v("用户的对 View 操作以后,View 捕获到这个操作,会把处理的权利交移给 Controller(Pass calls);Controller 接着会执行相关的业务逻辑,这些业务逻辑可能需要对 Model 进行相应的操作;当 Model 变更了以后,会通过观察者模式(Observer Pattern)通知 View;View 通过观察者模式收到 Model 变更的消息以后,会向 Model 请求最新的数据,然后重新更新界面。")]),s._v(" "),t("h5",{attrs:{id:"优缺点"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#优缺点"}},[s._v("#")]),s._v(" 优缺点")]),s._v(" "),t("p",[s._v("一、优点")]),s._v(" "),t("p",[s._v("1、把业务逻辑全部分离到 Controller 中,模块化程度高")]),s._v(" "),t("blockquote",[t("p",[s._v("当业务逻辑变更的时候,不需要变更 View 和 Model,只需要 Controller 换成另外一个 Controller 就行了(Swappable Controller)。")])]),s._v(" "),t("p",[s._v("2、观察者模式可以做到多视图同时更新")]),s._v(" "),t("p",[s._v("二、缺点")]),s._v(" "),t("p",[s._v("1、Controller 测试困难")]),s._v(" "),t("blockquote",[t("p",[s._v("因为视图同步操作是由 View 自己执行,而 View 只能在有 UI 的环境下运行。在没有 UI 环境下对 Controller 进行单元测试的时候,Controller 业务逻辑的正确性是无法验证的:Controller 更新 Model 的时候,无法对 View 的更新操作进行断言。")])]),s._v(" "),t("p",[s._v("2、View 无法组件化")]),s._v(" "),t("blockquote",[t("p",[s._v("View 是强依赖特定的 Model 的,如果需要把这个 View 抽出来作为一个另外一个应用程序可复用的组件就困难了。因为不同程序的的 Domain Model 是不一样的")])]),s._v(" "),t("h4",{attrs:{id:"mvp"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#mvp"}},[s._v("#")]),s._v(" MVP")]),s._v(" "),t("p",[t("strong",[s._v("MVP 由以下三个组件组成")])]),s._v(" "),t("ul",[t("li",[s._v("Model(模型):用于存储数据的层。它负责处理领域逻辑(现实世界的业务规则)并与数据库和网络层进行通信。")]),s._v(" "),t("li",[s._v("View(视图):用户界面(UI)层。它提供数据的可视化,并跟踪用户的操作,以便通知 Presenter。")]),s._v(" "),t("li",[s._v("Presenter(展示者):从模型中获取数据并应用 UI 逻辑以决定要显示的内容。它管理视图的状态,并根据来自视图的用户输入通知采取行动。")])]),s._v(" "),t("p",[s._v("和 MVC 模式一样,用户对 View 的操作都会从 View 交移给 Presenter。Presenter 同样的会执行相应的业务逻辑,并且对 Model 进行相应的操作;而这时候 Model 也是通过观察者模式把自己变更的消息传递出去,但是是传给 Presenter 而不是 View。Presenter 获取到 Model 变更的消息以后,"),t("RText",{attrs:{text:"通过 View 提供的接口更新界面",color:"red"}}),s._v(". 如下图:")],1),s._v(" "),t("p",[t("img",{attrs:{src:"https://cdn.jsdelivr.net/gh/jacky1234/picArchieve@master/uPic/20230607_204217_XqBRZI.jpg",alt:"MVP"}})]),s._v(" "),t("p",[s._v("二、特点")]),s._v(" "),t("ol",[t("li",[s._v("各部分之间的通信,都是双向的。")]),s._v(" "),t("li",[s._v("View 与 Model 不发生联系,都通过 Presenter 传递。")]),s._v(" "),t("li",[s._v('View 非常薄,不部署任何业务逻辑,称为"被动视图"(Passive View),即没有任何主动性,而 Presenter 非常厚,所有逻辑都部署在那里。')])]),s._v(" "),t("h5",{attrs:{id:"优缺点-2"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#优缺点-2"}},[s._v("#")]),s._v(" 优缺点")]),s._v(" "),t("p",[s._v("一、优点")]),s._v(" "),t("p",[s._v("1、便于测试")]),s._v(" "),t("blockquote",[t("p",[s._v("Presenter 对 View 是通过接口进行,在对 Presenter 进行不依赖 UI 环境的单元测试的时候。可以通过 Mock 一个 View 对象,这个对象只需要实现了 View 的接口即可。然后依赖注入到 Presenter 中,单元测试的时候就可以完整的测试 Presenter 业务逻辑的正确性。这里根据上面的例子给出了 Presenter 的单元测试样例。")])]),s._v(" "),t("p",[s._v("2、View 可以进行组件化")]),s._v(" "),t("blockquote",[t("p",[s._v("在 MVP 当中,View 不依赖 Model。这样就可以让 View 从特定的业务场景中脱离出来,可以说 View 可以做到对业务逻辑完全无知。它只需要提供一系列接口提供给上层操作。这样就可以做高度可复用的 View 组件。")])]),s._v(" "),t("p",[s._v("二、缺点")]),s._v(" "),t("p",[s._v("1、Presenter 中除了业务逻辑以外,还有大量的 View->Model,Model->View 的手动同步逻辑,造成 Presenter 比较笨重,维护起来会比较困难")]),s._v(" "),t("h4",{attrs:{id:"mvvm"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#mvvm"}},[s._v("#")]),s._v(" MVVM")]),s._v(" "),t("p",[s._v("TODO")]),s._v(" "),t("h3",{attrs:{id:"桥接模式"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#桥接模式"}},[s._v("#")]),s._v(" 桥接模式")]),s._v(" "),t("p",[s._v("桥接模式(Bridge Pattern):将抽象部分与它的实现部分分离,使它们都可以独立地变化。它是一种对象结构型模式,又称为柄体(Handle and Body)模式或接口(Interface)模式。\n"),t("strong",[s._v("任何多维度变化类或者说多个树状类之间的耦合都可以使用桥接模式来实现解耦。")])]),s._v(" "),t("p",[s._v("桥接模式包含如下角色:")]),s._v(" "),t("ul",[t("li",[s._v("Abstraction:抽象类")]),s._v(" "),t("li",[s._v("RefinedAbstraction:扩充抽象类")]),s._v(" "),t("li",[s._v("Implementor:实现类接口")]),s._v(" "),t("li",[s._v("ConcreteImplementor:具体实现类")])]),s._v(" "),t("p",[t("img",{attrs:{src:"https://cdn.jsdelivr.net/gh/jacky1234/picArchieve@master/uPic/20230607_211250_HVrz9M.jpg",alt:""}})]),s._v(" "),t("h3",{attrs:{id:"适配器模式"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#适配器模式"}},[s._v("#")]),s._v(" 适配器模式")]),s._v(" "),t("p",[s._v("适配器模式包含如下角色:")]),s._v(" "),t("ul",[t("li",[s._v("Target:目标抽象类")]),s._v(" "),t("li",[s._v("Adapter:适配器类")]),s._v(" "),t("li",[s._v("Adaptee:适配者类")]),s._v(" "),t("li",[s._v("Client:客户类")])]),s._v(" "),t("p",[t("strong",[s._v("对象适配器")]),s._v(" "),t("img",{attrs:{src:"http://design-patterns.readthedocs.io/zh_CN/latest/_images/Adapter.jpg",alt:""}})]),s._v(" "),t("p",[t("strong",[s._v("类适配器")]),s._v(" "),t("img",{attrs:{src:"http://design-patterns.readthedocs.io/zh_CN/latest/_images/Adapter_classModel.jpg",alt:""}})]),s._v(" "),t("h3",{attrs:{id:"装饰模式"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#装饰模式"}},[s._v("#")]),s._v(" 装饰模式")]),s._v(" "),t("p",[s._v("装饰模式(Decorator Pattern) :动态地给一个对象增加一些额外的职责(Responsibility),就"),t("strong",[s._v("增加对象功能来说,装饰模式比生成子类实现更为灵活")]),s._v("。"),t("em",[s._v("其别名也可以称为包装器(Wrapper),与适配器模式的别名相同,但它们适用于不同的场合。")])]),s._v(" "),t("p",[t("strong",[s._v("装饰模式包含如下角色")]),s._v(":")]),s._v(" "),t("ul",[t("li",[s._v("Component: 抽象构件")]),s._v(" "),t("li",[s._v("ConcreteComponent: 具体构件")]),s._v(" "),t("li",[s._v("Decorator: 抽象装饰类")]),s._v(" "),t("li",[s._v("ConcreteDecorator: 具体装饰类")])]),s._v(" "),t("p",[t("img",{attrs:{src:"http://design-patterns.readthedocs.io/zh_CN/latest/_images/Decorator.jpg",alt:""}})]),s._v(" "),t("p",[s._v("示例参考:一下鸿洋老师的解决方案了,大家可以看他的文章:"),t("a",{attrs:{href:"http://blog.csdn.net/lmj623565791/article/details/51854533",target:"_blank",rel:"noopener noreferrer"}},[s._v("优雅的为 RecyclerView 添加 HeaderView 和 FooterView"),t("OutboundLink")],1)]),s._v(" "),t("ul",[t("li",[t("a",{attrs:{href:"https://github.com/jacky1234/JackLogger",target:"_blank",rel:"noopener noreferrer"}},[s._v("参考我的 github 项目-JackLogger"),t("OutboundLink")],1)])]),s._v(" "),t("h3",{attrs:{id:"代理模式"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#代理模式"}},[s._v("#")]),s._v(" 代理模式")]),s._v(" "),t("p",[t("strong",[s._v("分类")])]),s._v(" "),t("ul",[t("li",[s._v("静态代理:运行之前代理类的 class 编译文件已经存在")]),s._v(" "),t("li",[s._v("动态代理:通过反射动态的生成代理者对象。(在执行阶段才知道代理谁)")])]),s._v(" "),t("p",[t("strong",[s._v("模式结构")]),s._v(" "),t("em",[s._v("代理模式包含如下角色:")])]),s._v(" "),t("ul",[t("li",[s._v("Subject: 抽象主题角色")]),s._v(" "),t("li",[s._v("Proxy: 代理主题角色")]),s._v(" "),t("li",[s._v("RealSubject: 真实主题角色")])]),s._v(" "),t("p",[t("img",{attrs:{src:"http://design-patterns.readthedocs.io/zh_CN/latest/_images/Proxy.jpg",alt:"Proxy"}})]),s._v(" "),t("h4",{attrs:{id:"静态代理"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#静态代理"}},[s._v("#")]),s._v(" 静态代理")]),s._v(" "),t("p",[t("strong",[s._v("一个静态代理示例")])]),s._v(" "),t("div",{staticClass:"language-java line-numbers-mode"},[t("pre",{pre:!0,attrs:{class:"language-java"}},[t("code",[t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("public")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("class")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Lawyer")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("implements")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("ILaysuit")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n    "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("private")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("ILaysuit")]),s._v(" mLawsuit"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("  "),t("span",{pre:!0,attrs:{class:"token comment"}},[s._v("//持有一个具体被代理者的引用")]),s._v("\n\n    "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("public")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Lawyer")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("ILaysuit")]),s._v(" mLawsuit"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n        "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("this")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),s._v("mLawsuit "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" mLawsuit"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n    "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n\n    "),t("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[s._v("@Override")]),s._v("\n    "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("public")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("void")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("submit")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n        mLawsuit"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("submit")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n    "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n\n    "),t("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[s._v("@Override")]),s._v("\n    "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("public")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("void")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("burden")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n        mLawsuit"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("burden")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n    "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n\n    "),t("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[s._v("@Override")]),s._v("\n    "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("public")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("void")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("defend")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n        mLawsuit"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("defend")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n    "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n\n    "),t("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[s._v("@Override")]),s._v("\n    "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("public")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("void")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("finish")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n        mLawsuit"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("finish")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n    "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("public")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("class")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Xiaomin")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("implements")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("ILaysuit")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token comment"}},[s._v("//使用")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("public")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("class")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Client")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n    "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("public")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("static")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("void")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("main")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("String")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("[")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("]")]),s._v(" args"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n        "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("ILaysuit")]),s._v(" mLawyer "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("new")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Lawyer")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("new")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Xiaomin")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n        mLawyer"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("submit")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n        mLawyer"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("burden")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n        mLawyer"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("defend")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n        mLawyer"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("finish")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n    "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n")])]),s._v(" "),t("div",{staticClass:"line-numbers-wrapper"},[t("span",{staticClass:"line-number"},[s._v("1")]),t("br"),t("span",{staticClass:"line-number"},[s._v("2")]),t("br"),t("span",{staticClass:"line-number"},[s._v("3")]),t("br"),t("span",{staticClass:"line-number"},[s._v("4")]),t("br"),t("span",{staticClass:"line-number"},[s._v("5")]),t("br"),t("span",{staticClass:"line-number"},[s._v("6")]),t("br"),t("span",{staticClass:"line-number"},[s._v("7")]),t("br"),t("span",{staticClass:"line-number"},[s._v("8")]),t("br"),t("span",{staticClass:"line-number"},[s._v("9")]),t("br"),t("span",{staticClass:"line-number"},[s._v("10")]),t("br"),t("span",{staticClass:"line-number"},[s._v("11")]),t("br"),t("span",{staticClass:"line-number"},[s._v("12")]),t("br"),t("span",{staticClass:"line-number"},[s._v("13")]),t("br"),t("span",{staticClass:"line-number"},[s._v("14")]),t("br"),t("span",{staticClass:"line-number"},[s._v("15")]),t("br"),t("span",{staticClass:"line-number"},[s._v("16")]),t("br"),t("span",{staticClass:"line-number"},[s._v("17")]),t("br"),t("span",{staticClass:"line-number"},[s._v("18")]),t("br"),t("span",{staticClass:"line-number"},[s._v("19")]),t("br"),t("span",{staticClass:"line-number"},[s._v("20")]),t("br"),t("span",{staticClass:"line-number"},[s._v("21")]),t("br"),t("span",{staticClass:"line-number"},[s._v("22")]),t("br"),t("span",{staticClass:"line-number"},[s._v("23")]),t("br"),t("span",{staticClass:"line-number"},[s._v("24")]),t("br"),t("span",{staticClass:"line-number"},[s._v("25")]),t("br"),t("span",{staticClass:"line-number"},[s._v("26")]),t("br"),t("span",{staticClass:"line-number"},[s._v("27")]),t("br"),t("span",{staticClass:"line-number"},[s._v("28")]),t("br"),t("span",{staticClass:"line-number"},[s._v("29")]),t("br"),t("span",{staticClass:"line-number"},[s._v("30")]),t("br"),t("span",{staticClass:"line-number"},[s._v("31")]),t("br"),t("span",{staticClass:"line-number"},[s._v("32")]),t("br"),t("span",{staticClass:"line-number"},[s._v("33")]),t("br"),t("span",{staticClass:"line-number"},[s._v("34")]),t("br"),t("span",{staticClass:"line-number"},[s._v("35")]),t("br"),t("span",{staticClass:"line-number"},[s._v("36")]),t("br"),t("span",{staticClass:"line-number"},[s._v("37")]),t("br"),t("span",{staticClass:"line-number"},[s._v("38")]),t("br")])]),t("h4",{attrs:{id:"动态代理"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#动态代理"}},[s._v("#")]),s._v(" "),t("a",{attrs:{href:"https://juejin.im/post/5ad3e6b36fb9a028ba1fee6a",target:"_blank",rel:"noopener noreferrer"}},[s._v("动态代理"),t("OutboundLink")],1)]),s._v(" "),t("ul",[t("li",[s._v("动态代理是一种较为高级的代理模式,它的典型应用就是 Spring AOP。")]),s._v(" "),t("li",[s._v("如果按照这种方法使用代理模式,那么真实主题角色必须是事先已经存在的,并将其作为代理对象的内部成员属性。如果一个真实主题角色必须对应一个代理主题角色,这将导致系统中的类个数急剧增加,因此需要想办法减少系统中类的个数,此外,如何在事先不知道真实主题角色的情况下使用代理主题角色,这都是动态代理需要解决的问题。")]),s._v(" "),t("li",[s._v("使用上,通过 Proxy 的 static 方法 newProxyInstance,传入 InvocationHandler(包含了真实主题对象),请看下面的例子")])]),s._v(" "),t("p",[s._v("一、动态代理:")]),s._v(" "),t("div",{staticClass:"language-java line-numbers-mode"},[t("pre",{pre:!0,attrs:{class:"language-java"}},[t("code",[t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("public")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("class")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Client")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("public")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("static")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("void")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("main")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("String")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("[")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("]")]),s._v(" args"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n  "),t("span",{pre:!0,attrs:{class:"token comment"}},[s._v("// 构造小明")]),s._v("\n  "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("final")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("ILaysuit")]),s._v(" xiaomin "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("new")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Xiaomin")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n\n  "),t("span",{pre:!0,attrs:{class:"token comment"}},[s._v("// 构造一个动态代理")]),s._v("\n  "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("InvocationHandler")]),s._v(" proxy "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("new")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("DynamicProxy")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("xiaomin"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n\n  "),t("span",{pre:!0,attrs:{class:"token comment"}},[s._v("/**\n   - 构造代理律师 xiaomin.getClass().getInterfaces() 同 new\n   - Class[]{ILaysuit.class}\n   */")]),s._v("\n  "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("ILaysuit")]),s._v(" lawyer "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("ILaysuit")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Proxy")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("newProxyInstance")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("xiaomin"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("getClass")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("getClassLoader")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v("xiaomin"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("getClass")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("getInterfaces")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" proxy"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n\n  lawyer"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("submit")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token string"}},[s._v('"老板拖欠工资"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n  lawyer"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("burden")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token string"}},[s._v('"这是合同书和去年的银行流水号"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n  lawyer"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("defend")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token string"}},[s._v('"证据确凿,无可厚非"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n  lawyer"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("finish")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token string"}},[s._v('"诉讼成功,老板结算拖欠工资"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n\n"),t("span",{pre:!0,attrs:{class:"token comment"}},[s._v("//")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("public")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("class")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("DynamicProxy")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("implements")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("InvocationHandler")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("private")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Object")]),s._v(" obj"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token comment"}},[s._v("//被代理对象的引用")]),s._v("\n\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("public")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("DynamicProxy")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Object")]),s._v(" obj"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n  "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("this")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),s._v("obj "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" obj"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n\n "),t("span",{pre:!0,attrs:{class:"token comment"}},[s._v("/**\n  - proxy:被代理对象\n  */")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[s._v("@Override")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("public")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Object")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("invoke")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Object")]),s._v(" proxy"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Method")]),s._v(" method"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Object")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("[")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("]")]),s._v(" args"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v("\n   "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("throws")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Throwable")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n  "),t("span",{pre:!0,attrs:{class:"token comment"}},[s._v("/**\n   - 通过 invoke 方法调用具体的被代理方法,也就是真实方法\n   */")]),s._v("\n  "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Object")]),s._v(" result "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" method"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("invoke")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("obj"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" args"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n  "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("return")]),s._v(" result"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n\n"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n")])]),s._v(" "),t("div",{staticClass:"line-numbers-wrapper"},[t("span",{staticClass:"line-number"},[s._v("1")]),t("br"),t("span",{staticClass:"line-number"},[s._v("2")]),t("br"),t("span",{staticClass:"line-number"},[s._v("3")]),t("br"),t("span",{staticClass:"line-number"},[s._v("4")]),t("br"),t("span",{staticClass:"line-number"},[s._v("5")]),t("br"),t("span",{staticClass:"line-number"},[s._v("6")]),t("br"),t("span",{staticClass:"line-number"},[s._v("7")]),t("br"),t("span",{staticClass:"line-number"},[s._v("8")]),t("br"),t("span",{staticClass:"line-number"},[s._v("9")]),t("br"),t("span",{staticClass:"line-number"},[s._v("10")]),t("br"),t("span",{staticClass:"line-number"},[s._v("11")]),t("br"),t("span",{staticClass:"line-number"},[s._v("12")]),t("br"),t("span",{staticClass:"line-number"},[s._v("13")]),t("br"),t("span",{staticClass:"line-number"},[s._v("14")]),t("br"),t("span",{staticClass:"line-number"},[s._v("15")]),t("br"),t("span",{staticClass:"line-number"},[s._v("16")]),t("br"),t("span",{staticClass:"line-number"},[s._v("17")]),t("br"),t("span",{staticClass:"line-number"},[s._v("18")]),t("br"),t("span",{staticClass:"line-number"},[s._v("19")]),t("br"),t("span",{staticClass:"line-number"},[s._v("20")]),t("br"),t("span",{staticClass:"line-number"},[s._v("21")]),t("br"),t("span",{staticClass:"line-number"},[s._v("22")]),t("br"),t("span",{staticClass:"line-number"},[s._v("23")]),t("br"),t("span",{staticClass:"line-number"},[s._v("24")]),t("br"),t("span",{staticClass:"line-number"},[s._v("25")]),t("br"),t("span",{staticClass:"line-number"},[s._v("26")]),t("br"),t("span",{staticClass:"line-number"},[s._v("27")]),t("br"),t("span",{staticClass:"line-number"},[s._v("28")]),t("br"),t("span",{staticClass:"line-number"},[s._v("29")]),t("br"),t("span",{staticClass:"line-number"},[s._v("30")]),t("br"),t("span",{staticClass:"line-number"},[s._v("31")]),t("br"),t("span",{staticClass:"line-number"},[s._v("32")]),t("br"),t("span",{staticClass:"line-number"},[s._v("33")]),t("br"),t("span",{staticClass:"line-number"},[s._v("34")]),t("br"),t("span",{staticClass:"line-number"},[s._v("35")]),t("br"),t("span",{staticClass:"line-number"},[s._v("36")]),t("br"),t("span",{staticClass:"line-number"},[s._v("37")]),t("br"),t("span",{staticClass:"line-number"},[s._v("38")]),t("br"),t("span",{staticClass:"line-number"},[s._v("39")]),t("br"),t("span",{staticClass:"line-number"},[s._v("40")]),t("br"),t("span",{staticClass:"line-number"},[s._v("41")]),t("br"),t("span",{staticClass:"line-number"},[s._v("42")]),t("br"),t("span",{staticClass:"line-number"},[s._v("43")]),t("br")])]),t("h2",{attrs:{id:"创建型设计模式"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#创建型设计模式"}},[s._v("#")]),s._v(" 创建型设计模式")]),s._v(" "),t("h3",{attrs:{id:"单例模式"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#单例模式"}},[s._v("#")]),s._v(" 单例模式")]),s._v(" "),t("p",[s._v("一、DCL(double check lock)")]),s._v(" "),t("div",{staticClass:"language-java line-numbers-mode"},[t("pre",{pre:!0,attrs:{class:"language-java"}},[t("code",[t("span",{pre:!0,attrs:{class:"token comment"}},[s._v("/**\n * 双重检查锁模式: 对线程安全的懒惰模式的改进: 方法上的synchronized在每次调用时都要加锁, 性能太低.\n */")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("final")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("class")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("DoubleCheckedLockingSingleton")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n    "),t("span",{pre:!0,attrs:{class:"token comment"}},[s._v("/** 实例对象, 这里还没有添加volatile关键字 */")]),s._v("\n    "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("private")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("static")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("volatile")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("DoubleCheckedLockingSingleton")]),s._v(" instance "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("null")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n\n    "),t("span",{pre:!0,attrs:{class:"token comment"}},[s._v("/** 禁用构造方法 */")]),s._v("\n    "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("private")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("DoubleCheckedLockingSingleton")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n\n    "),t("span",{pre:!0,attrs:{class:"token comment"}},[s._v("/**\n     * 获取对象: 将方法上的synchronized移至内部\n     * @return instance 本类的实例\n     */")]),s._v("\n    "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("public")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("static")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("DoubleCheckedLockingSingleton")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("getInstance")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n        "),t("span",{pre:!0,attrs:{class:"token comment"}},[s._v("// 先判断实例是否存在")]),s._v("\n        "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("if")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("instance "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("==")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("null")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n            "),t("span",{pre:!0,attrs:{class:"token comment"}},[s._v("// 加锁创建实例")]),s._v("\n            "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("synchronized")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("DoubleCheckedLockingSingleton")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("class")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n                "),t("span",{pre:!0,attrs:{class:"token comment"}},[s._v("// 再次判断, 因为可能出现某个线程拿了锁之后, 还没来得及执行初始化就释放了锁,")]),s._v("\n                "),t("span",{pre:!0,attrs:{class:"token comment"}},[s._v("// 而此时其他的线程拿到了锁又执行到此处 ==> 这些线程都会创建一个实例, 从而创建多个实例对象")]),s._v("\n                "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("if")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("instance "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("==")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("null")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n                    instance "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("new")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("DoubleCheckedLockingSingleton")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n                "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n            "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n        "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n        "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("return")]),s._v(" instance"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n    "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n")])]),s._v(" "),t("div",{staticClass:"line-numbers-wrapper"},[t("span",{staticClass:"line-number"},[s._v("1")]),t("br"),t("span",{staticClass:"line-number"},[s._v("2")]),t("br"),t("span",{staticClass:"line-number"},[s._v("3")]),t("br"),t("span",{staticClass:"line-number"},[s._v("4")]),t("br"),t("span",{staticClass:"line-number"},[s._v("5")]),t("br"),t("span",{staticClass:"line-number"},[s._v("6")]),t("br"),t("span",{staticClass:"line-number"},[s._v("7")]),t("br"),t("span",{staticClass:"line-number"},[s._v("8")]),t("br"),t("span",{staticClass:"line-number"},[s._v("9")]),t("br"),t("span",{staticClass:"line-number"},[s._v("10")]),t("br"),t("span",{staticClass:"line-number"},[s._v("11")]),t("br"),t("span",{staticClass:"line-number"},[s._v("12")]),t("br"),t("span",{staticClass:"line-number"},[s._v("13")]),t("br"),t("span",{staticClass:"line-number"},[s._v("14")]),t("br"),t("span",{staticClass:"line-number"},[s._v("15")]),t("br"),t("span",{staticClass:"line-number"},[s._v("16")]),t("br"),t("span",{staticClass:"line-number"},[s._v("17")]),t("br"),t("span",{staticClass:"line-number"},[s._v("18")]),t("br"),t("span",{staticClass:"line-number"},[s._v("19")]),t("br"),t("span",{staticClass:"line-number"},[s._v("20")]),t("br"),t("span",{staticClass:"line-number"},[s._v("21")]),t("br"),t("span",{staticClass:"line-number"},[s._v("22")]),t("br"),t("span",{staticClass:"line-number"},[s._v("23")]),t("br"),t("span",{staticClass:"line-number"},[s._v("24")]),t("br"),t("span",{staticClass:"line-number"},[s._v("25")]),t("br"),t("span",{staticClass:"line-number"},[s._v("26")]),t("br"),t("span",{staticClass:"line-number"},[s._v("27")]),t("br"),t("span",{staticClass:"line-number"},[s._v("28")]),t("br"),t("span",{staticClass:"line-number"},[s._v("29")]),t("br")])]),t("p",[s._v("说明:")]),s._v(" "),t("ul",[t("li",[t("strong",[s._v("volatile")]),s._v(" 关键字禁止了 JVM 的指令重排序")])]),s._v(" "),t("p",[s._v("二、内部类")]),s._v(" "),t("div",{staticClass:"language-java line-numbers-mode"},[t("pre",{pre:!0,attrs:{class:"language-java"}},[t("code",[t("span",{pre:!0,attrs:{class:"token comment"}},[s._v("/**\n * 静态内部类模式, 也称作Singleton Holder(单持有者)模式: 线程安全, 懒惰模式的一种, 用到时再加载\n */")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("final")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("class")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("StaticInnerSingleton")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n    "),t("span",{pre:!0,attrs:{class:"token comment"}},[s._v("/** 禁用构造方法 */")]),s._v("\n    "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("private")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("StaticInnerSingleton")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n\n    "),t("span",{pre:!0,attrs:{class:"token comment"}},[s._v("/**\n     * 通过静态内部类获取单例对象, 没有加锁, 线程安全, 并发性能高\n     * @return SingletonHolder.instance 内部类的实例\n     */")]),s._v("\n    "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("public")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("static")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("StaticInnerSingleton")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("getInstance")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n        "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("return")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("SingletonHolder")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),s._v("instance"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n    "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n\n    "),t("span",{pre:!0,attrs:{class:"token comment"}},[s._v("/** 静态内部类创建单例对象 */")]),s._v("\n    "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("private")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("static")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("class")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("SingletonHolder")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n        "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("private")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("static")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("final")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("StaticInnerSingleton")]),s._v(" instance "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("new")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("StaticInnerSingleton")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n    "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n")])]),s._v(" "),t("div",{staticClass:"line-numbers-wrapper"},[t("span",{staticClass:"line-number"},[s._v("1")]),t("br"),t("span",{staticClass:"line-number"},[s._v("2")]),t("br"),t("span",{staticClass:"line-number"},[s._v("3")]),t("br"),t("span",{staticClass:"line-number"},[s._v("4")]),t("br"),t("span",{staticClass:"line-number"},[s._v("5")]),t("br"),t("span",{staticClass:"line-number"},[s._v("6")]),t("br"),t("span",{staticClass:"line-number"},[s._v("7")]),t("br"),t("span",{staticClass:"line-number"},[s._v("8")]),t("br"),t("span",{staticClass:"line-number"},[s._v("9")]),t("br"),t("span",{staticClass:"line-number"},[s._v("10")]),t("br"),t("span",{staticClass:"line-number"},[s._v("11")]),t("br"),t("span",{staticClass:"line-number"},[s._v("12")]),t("br"),t("span",{staticClass:"line-number"},[s._v("13")]),t("br"),t("span",{staticClass:"line-number"},[s._v("14")]),t("br"),t("span",{staticClass:"line-number"},[s._v("15")]),t("br"),t("span",{staticClass:"line-number"},[s._v("16")]),t("br"),t("span",{staticClass:"line-number"},[s._v("17")]),t("br"),t("span",{staticClass:"line-number"},[s._v("18")]),t("br"),t("span",{staticClass:"line-number"},[s._v("19")]),t("br"),t("span",{staticClass:"line-number"},[s._v("20")]),t("br")])]),t("p",[s._v("比较推荐这种方式, 没有加锁, 线程安全, 用到时再加载, 并发行能高")]),s._v(" "),t("h3",{attrs:{id:"建造者模式"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#建造者模式"}},[s._v("#")]),s._v(" 建造者模式")]),s._v(" "),t("h3",{attrs:{id:"工厂方法模式"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#工厂方法模式"}},[s._v("#")]),s._v(" 工厂方法模式")]),s._v(" "),t("p",[s._v("工厂方法模式包含如下角色:")]),s._v(" "),t("ul",[t("li",[s._v("Product:抽象产品")]),s._v(" "),t("li",[s._v("ConcreteProduct:具体产品")]),s._v(" "),t("li",[s._v("Factory:抽象工厂")]),s._v(" "),t("li",[s._v("ConcreteFactory:具体工厂")])]),s._v(" "),t("p",[t("img",{attrs:{src:"http://design-patterns.readthedocs.io/zh_CN/latest/_images/FactoryMethod.jpg",alt:"FactoryMethod"}})]),s._v(" "),t("div",{staticClass:"language-java line-numbers-mode"},[t("pre",{pre:!0,attrs:{class:"language-java"}},[t("code",[t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("public")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("class")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("FactoryImpl")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("extends")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Factory")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[s._v("@Override")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("public")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token generics"}},[t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("<")]),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("T")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("extends")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Car")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(">")])]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("T")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("createCar")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Class")]),t("span",{pre:!0,attrs:{class:"token generics"}},[t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("<")]),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("T")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(">")])]),s._v(" clz"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n  "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Car")]),s._v(" car "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("null")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n  "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("try")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token comment"}},[s._v("//   car = (Car) Class.forName(clz.getName()).newInstance();")]),s._v("\n   car "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Car")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v(" clz"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("newInstance")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n  "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("catch")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Exception")]),s._v(" e"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n   e"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("printStackTrace")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n  "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n  "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("return")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("T")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v(" car"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n\n")])]),s._v(" "),t("div",{staticClass:"line-numbers-wrapper"},[t("span",{staticClass:"line-number"},[s._v("1")]),t("br"),t("span",{staticClass:"line-number"},[s._v("2")]),t("br"),t("span",{staticClass:"line-number"},[s._v("3")]),t("br"),t("span",{staticClass:"line-number"},[s._v("4")]),t("br"),t("span",{staticClass:"line-number"},[s._v("5")]),t("br"),t("span",{staticClass:"line-number"},[s._v("6")]),t("br"),t("span",{staticClass:"line-number"},[s._v("7")]),t("br"),t("span",{staticClass:"line-number"},[s._v("8")]),t("br"),t("span",{staticClass:"line-number"},[s._v("9")]),t("br"),t("span",{staticClass:"line-number"},[s._v("10")]),t("br"),t("span",{staticClass:"line-number"},[s._v("11")]),t("br"),t("span",{staticClass:"line-number"},[s._v("12")]),t("br"),t("span",{staticClass:"line-number"},[s._v("13")]),t("br"),t("span",{staticClass:"line-number"},[s._v("14")]),t("br")])]),t("h2",{attrs:{id:"行为设计模式"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#行为设计模式"}},[s._v("#")]),s._v(" 行为设计模式")]),s._v(" "),t("h3",{attrs:{id:"观察者模式"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#观察者模式"}},[s._v("#")]),s._v(" 观察者模式")]),s._v(" "),t("p",[s._v("观察者模式包含如下角色:")]),s._v(" "),t("ul",[t("li",[s._v("Subject: 目标")]),s._v(" "),t("li",[s._v("ConcreteSubject: 具体目标")]),s._v(" "),t("li",[s._v("Observer: 观察者")]),s._v(" "),t("li",[s._v("ConcreteObserver: 具体观察者")])]),s._v(" "),t("p",[t("img",{attrs:{src:"http://design-patterns.readthedocs.io/zh_CN/latest/_images/Obeserver.jpg",alt:"Obeserver"}})]),s._v(" "),t("h3",{attrs:{id:"迭代器模式"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#迭代器模式"}},[s._v("#")]),s._v(" "),t("a",{attrs:{href:"http://blog.csdn.net/zhengzhb/article/details/7610745",target:"_blank",rel:"noopener noreferrer"}},[s._v("迭代器模式"),t("OutboundLink")],1)]),s._v(" "),t("h3",{attrs:{id:"备忘录模式"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#备忘录模式"}},[s._v("#")]),s._v(" 备忘录模式")]),s._v(" "),t("p",[s._v("备忘录模式又叫做快照模式(Snapshot Pattern)或 Token 模式,是对象的行为模式。")]),s._v(" "),t("p",[s._v("备忘录对象是一个用来存储另外一个对象内部状态的快照的对象。备忘录模式的用意是在不破坏封装的条件下,将一个对象的状态捕捉(Capture)住,并外部化,存储起来,从而可以在将来合适的时候把这个对象还原到存储起来的状态。备忘录模式常常与命令模式和迭代子模式一同使用。")]),s._v(" "),t("h2",{attrs:{id:"模式对比"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#模式对比"}},[s._v("#")]),s._v(" 模式对比")]),s._v(" "),t("h3",{attrs:{id:"代理模式和装饰模式区别"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#代理模式和装饰模式区别"}},[s._v("#")]),s._v(" 代理模式和装饰模式区别")]),s._v(" "),t("ul",[t("li",[s._v("从语意上讲,代理模式是为控制对被代理对象的访问,而装饰模式是为了增加被装饰对象的功能")]),s._v(" "),t("li",[s._v("代理类所能代理的类完全由代理类确定,装饰类装饰的对象需要根据实际使用时客户端的组合来确定")]),s._v(" "),t("li",[s._v("被代理对象由代理对象创建,客户端甚至不需要知道被代理类的存在;被装饰对象由客户端创建并传给装饰对象。")]),s._v(" "),t("li",[s._v("装饰模式,是面向对象编程领域中,一种动态地往一个类中添加新的行为的设计模式。就功能而言,**装饰模式相比生成子类更为灵活,这样可以给某个对象而不是整个类添加一些功能。")])]),s._v(" "),t("h2",{attrs:{id:"链接"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#链接"}},[s._v("#")]),s._v(" 链接")]),s._v(" "),t("ul",[t("li",[t("a",{attrs:{href:"https://design-patterns.readthedocs.io/zh_CN/latest/index.html",target:"_blank",rel:"noopener noreferrer"}},[s._v("Graphic Design Patterns"),t("OutboundLink")],1),s._v(" 图说设计模式")]),s._v(" "),t("li",[t("a",{attrs:{href:"https://www.kancloud.cn/digest/xing-designpattern/143717",target:"_blank",rel:"noopener noreferrer"}},[s._v("写最好的设计模式专栏"),t("OutboundLink")],1)])])])}),[],!1,null,null,null);t.default=e.exports}}]);
\ No newline at end of file
diff --git a/assets/js/97.a25be736.js b/assets/js/97.a25be736.js
new file mode 100644
index 0000000000..155c853d52
--- /dev/null
+++ b/assets/js/97.a25be736.js
@@ -0,0 +1 @@
+(window.webpackJsonp=window.webpackJsonp||[]).push([[97],{423:function(t,a,s){"use strict";s.r(a);var n=s(4),e=Object(n.a)({},(function(){var t=this,a=t._self._c;return a("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[a("h2",{attrs:{id:"环境准备"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#环境准备"}},[t._v("#")]),t._v(" 环境准备")]),t._v(" "),a("p",[t._v("要进行 frida 的研究,你需要准备一台可以 root 的手机. 这里有一些链接可以帮助到你. 这里主要介绍使用 "),a("code",[t._v("magisk")]),t._v(" 获取 root 权限")]),t._v(" "),a("blockquote",[a("p",[t._v("参考:"),a("a",{attrs:{href:"https://sspai.com/post/57923",target:"_blank",rel:"noopener noreferrer"}},[t._v("Pixel 4 XL 刷入 Magisk、Root"),a("OutboundLink")],1)])]),t._v(" "),a("h3",{attrs:{id:"magisk"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#magisk"}},[t._v("#")]),t._v(" magisk")]),t._v(" "),a("p",[t._v("这里介绍使用 "),a("code",[t._v("magisk")]),t._v(" 辅助获取,root 权限")]),t._v(" "),a("h4",{attrs:{id:"modules-介绍"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#modules-介绍"}},[t._v("#")]),t._v(" modules 介绍")]),t._v(" "),a("ul",[a("li",[t._v("Systemless Hosts")]),t._v(" "),a("li",[t._v("Custom Certificate Authorities")])]),t._v(" "),a("h4",{attrs:{id:"magiskhidepropsconf-使用"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#magiskhidepropsconf-使用"}},[t._v("#")]),t._v(" MagiskHidePropsConf 使用")]),t._v(" "),a("blockquote",[a("p",[a("a",{attrs:{href:"https://github.com/Magisk-Modules-Repo/MagiskHidePropsConf/blob/master/README.md",target:"_blank",rel:"noopener noreferrer"}},[t._v("MagiskHidePropsConf"),a("OutboundLink")],1),t._v(" 可以修改系统的配置属性,比如设置全局设置 app debuggable。 但是作者截止 2023 年一月份,不再维护此项目了")])]),t._v(" "),a("p",[t._v("一、首先从"),a("a",{attrs:{href:"https://forum.xda-developers.com/t/module-deprecated-magiskhide-props-config-safetynet-prop-edits-and-more-v6-1-2.3789228/",target:"_blank",rel:"noopener noreferrer"}},[t._v("网站"),a("OutboundLink")],1),t._v("下载 6.1.2 版本的 MagiskHidePropsConf 模块包二、设置 debuggale 过程如下")]),t._v(" "),a("p",[t._v("这一步主要的步骤是设置 "),a("code",[t._v("ro.debuggable 1")]),t._v(",这样所有的 app 就都可以调试了。步骤如下:")]),t._v(" "),a("div",{staticClass:"language-shell line-numbers-mode"},[a("pre",{pre:!0,attrs:{class:"language-shell"}},[a("code",[t._v("adb shell "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("#adb 进入命令行模式")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("su")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("#切换至超级用户")]),t._v("\nmagisk resetprop ro.debuggable "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),t._v("\nstop"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("start"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("#一定要通过该方式重启")]),t._v("\n")])]),t._v(" "),a("div",{staticClass:"line-numbers-wrapper"},[a("span",{staticClass:"line-number"},[t._v("1")]),a("br"),a("span",{staticClass:"line-number"},[t._v("2")]),a("br"),a("span",{staticClass:"line-number"},[t._v("3")]),a("br"),a("span",{staticClass:"line-number"},[t._v("4")]),a("br")])]),a("p",[t._v("至此重启手机后,你的手机里面的应用应该就可以全局 debug 了.")]),t._v(" "),a("p",[t._v("如下图:")]),t._v(" "),a("p",[a("img",{attrs:{src:"https://cdn.jsdelivr.net/gh/jacky1234/picArchieve@master/uPic/20230606_203711_lH345Z.png",alt:""}})]),t._v(" "),a("h4",{attrs:{id:"magiskfrida"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#magiskfrida"}},[t._v("#")]),t._v(" MagiskFrida")]),t._v(" "),a("blockquote",[a("p",[t._v("MagiskFrida lets you run frida-server on boot with Magisk。 如果你想使用最新的 frida-server 版本,可以尝试更新 MagiskFrida 模块. 点击"),a("a",{attrs:{href:"https://github.com/ViRb3/magisk-frida",target:"_blank",rel:"noopener noreferrer"}},[t._v("magisk-frida"),a("OutboundLink")],1),t._v("查看")])]),t._v(" "),a("h2",{attrs:{id:"frida"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#frida"}},[t._v("#")]),t._v(" frida")]),t._v(" "),a("div",{staticClass:"custom-block tip"},[a("p",{staticClass:"custom-block-title"},[t._v("提示")]),t._v(" "),a("p",[t._v("Frida: Dynamic instrumentation toolkit for developers, reverse-engineers, and security researchers.")]),t._v(" "),a("p",[t._v("个人非常喜欢 frida 平台,不仅是因为功能的强大,还提供了实时交互工具 "),a("code",[t._v("objection")])]),t._v(" "),a("p",[t._v("链接")]),t._v(" "),a("ul",[a("li",[a("a",{attrs:{href:"https://frida.re/",target:"_blank",rel:"noopener noreferrer"}},[t._v("frida"),a("OutboundLink")],1)]),t._v(" "),a("li",[a("a",{attrs:{href:"https://frida.re/docs/javascript-api/",target:"_blank",rel:"noopener noreferrer"}},[t._v("javascript-api"),a("OutboundLink")],1)])])]),t._v(" "),a("h3",{attrs:{id:"gadget"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#gadget"}},[t._v("#")]),t._v(" Gadget")]),t._v(" "),a("p",[t._v("Frida Gadget 是 Frida 框架的一个组件,它用于在目标应用程序中注入 Frida 运行时,从而实现对应用程序的动态分析和修改。")]),t._v(" "),a("p",[t._v("Frida 是一个功能强大的动态代码注入和调试工具,可以用于在运行时修改和监视应用程序的行为。它支持多种操作系统和架构,并提供了丰富的 API,使得开发人员能够在应用程序运行时进行代码注入、函数挂钩、数据修改等操作。")]),t._v(" "),a("p",[t._v("Frida Gadget 是 Frida 框架的一部分,它是一个特殊的库,被注入到目标应用程序中。注入 Frida Gadget 后,Frida 可以与目标应用程序交互,监视和修改其运行时行为。Frida Gadget 允许开发人员在应用程序的上下文中执行 JavaScript 代码,从而实现各种功能,如函数跟踪、API 调用监视、数据修改等。")]),t._v(" "),a("p",[t._v("使用 Frida Gadget,开发人员可以进行以下操作:")]),t._v(" "),a("ul",[a("li",[t._v("动态函数跟踪:可以跟踪目标应用程序中的函数调用,并获取参数、返回值等信息,用于分析应用程序的执行流程和内部逻辑。")]),t._v(" "),a("li",[t._v("API 调用监视:可以监视目标应用程序对特定 API 的调用,包括系统级 API 和应用程序特定的 API,用于分析应用程序的行为和检测潜在的安全问题。")]),t._v(" "),a("li",[t._v("数据修改和重定向:可以在运行时修改目标应用程序的内存数据,包括修改变量的值、修改函数的实现等,用于实现应用程序的动态修改和调试。")]),t._v(" "),a("li",[t._v("密码破解和漏洞分析:可以通过 Frida Gadget 对目标应用程序进行动态分析,帮助发现潜在的安全漏洞和进行密码破解。")])]),t._v(" "),a("p",[t._v("总之,Frida Gadget 是 Frida 框架中的一个关键组件,它为开发人员提供了强大的动态分析和修改目标应用程序的能力,帮助他们进行应用程序的逆向工程、安全分析和调试等任务。")]),t._v(" "),a("h3",{attrs:{id:"stalker"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#stalker"}},[t._v("#")]),t._v(" stalker")]),t._v(" "),a("p",[t._v("Frida Stalker 是 Frida 框架的一个特性,它提供了一种高级的动态分析技术,用于跟踪目标应用程序的执行流程。")]),t._v(" "),a("p",[t._v("Stalker 基于 Frida 框架的动态代码注入能力,通过在目标应用程序中注入代码,并在运行时跟踪其指令的执行,从而实现对应用程序的静态和动态分析。Stalker 的主要目标是捕获和分析目标应用程序的控制流,包括函数调用、基本块的执行顺序、分支跳转等。")]),t._v(" "),a("p",[t._v("使用 Frida Stalker,开发人员可以进行以下操作:")]),t._v(" "),a("ul",[a("li",[t._v("函数调用跟踪:Stalker 可以跟踪目标应用程序中的函数调用,记录函数的入口、返回地址和参数,以及函数的执行时间和频率。这对于分析应用程序的执行路径、理解函数之间的调用关系和参数传递非常有帮助。")]),t._v(" "),a("li",[t._v("基本块跟踪:Stalker 可以跟踪目标应用程序中的基本块(一组连续的指令),记录基本块的执行顺序和频率,以及基本块之间的跳转关系。这有助于分析应用程序的控制流,包括条件分支、循环和函数调用。")]),t._v(" "),a("li",[t._v("动态分析和调试:Stalker 可以在运行时对目标应用程序进行动态分析和调试,例如捕获函数调用的参数和返回值、监视特定的 API 调用、跟踪内存访问等。这使得开发人员能够深入了解应用程序的行为,快速定位问题和漏洞,并进行动态修改和调试。")]),t._v(" "),a("li",[t._v("逆向工程:Stalker 可以用于逆向工程任务,如反编译、恢复数据结构和算法等。通过跟踪目标应用程序的执行流程,开发人员可以还原出应用程序的逻辑和算法,帮助理解其内部工作原理。")])]),t._v(" "),a("p",[t._v("总之,Frida Stalker 是 Frida 框架中的一个重要功能,它提供了强大的动态分析能力,帮助开发人员深入理解和分析目标应用程序的执行流程,从而实现应用程序的逆向工程、安全分析和调试等任务。")]),t._v(" "),a("h3",{attrs:{id:"tutorials"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#tutorials"}},[t._v("#")]),t._v(" Tutorials")]),t._v(" "),a("h4",{attrs:{id:"founctions"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#founctions"}},[t._v("#")]),t._v(" Founctions")]),t._v(" "),a("p",[t._v("解释官方示例的 "),a("a",{attrs:{href:"https://frida.re/docs/functions/",target:"_blank",rel:"noopener noreferrer"}},[t._v("Injecting Strings and Calling a Function"),a("OutboundLink")],1),t._v(" 的一段 snippet code")]),t._v(" "),a("div",{staticClass:"language-python line-numbers-mode"},[a("pre",{pre:!0,attrs:{class:"language-python"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" frida\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" sys\n\nsession "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" frida"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("attach"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"hi"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\nscript "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" session"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("create_script"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token triple-quoted-string string"}},[t._v('"""\nconst st = Memory.allocUtf8String("TESTMEPLZ!");\nconst f = new NativeFunction(ptr("%s"), \'int\', [\'pointer\']);\n    // In NativeFunction param 2 is the return value type,\n    // and param 3 is an array of input types\nf(st);\n"""')]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("%")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("int")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("sys"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("argv"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("16")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("def")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("on_message")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("message"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" data"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v("\n    "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("print")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("message"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\nscript"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("on"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'message'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" on_message"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\nscript"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("load"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])]),t._v(" "),a("div",{staticClass:"line-numbers-wrapper"},[a("span",{staticClass:"line-number"},[t._v("1")]),a("br"),a("span",{staticClass:"line-number"},[t._v("2")]),a("br"),a("span",{staticClass:"line-number"},[t._v("3")]),a("br"),a("span",{staticClass:"line-number"},[t._v("4")]),a("br"),a("span",{staticClass:"line-number"},[t._v("5")]),a("br"),a("span",{staticClass:"line-number"},[t._v("6")]),a("br"),a("span",{staticClass:"line-number"},[t._v("7")]),a("br"),a("span",{staticClass:"line-number"},[t._v("8")]),a("br"),a("span",{staticClass:"line-number"},[t._v("9")]),a("br"),a("span",{staticClass:"line-number"},[t._v("10")]),a("br"),a("span",{staticClass:"line-number"},[t._v("11")]),a("br"),a("span",{staticClass:"line-number"},[t._v("12")]),a("br"),a("span",{staticClass:"line-number"},[t._v("13")]),a("br"),a("span",{staticClass:"line-number"},[t._v("14")]),a("br"),a("span",{staticClass:"line-number"},[t._v("15")]),a("br")])]),a("p",[t._v('这段代码使用 Frida 进行动态插桩,目标应用程序是名为 "hi" 的进程。')]),t._v(" "),a("p",[t._v('首先,你导入了 frida 和 sys 模块。然后,使用 frida.attach 方法附加到目标应用程序 "hi",创建了一个 Frida 会话(session)。')]),t._v(" "),a("p",[t._v("接下来,你使用 session.create_script 创建了一个脚本对象,并将 JavaScript 代码作为参数传递给它。这个 JavaScript 代码块使用了 Frida 的 Memory.allocUtf8String 方法来分配一个 UTF-8 字符串的内存,并将其赋值给变量 st。然后,使用 NativeFunction 创建了一个函数对象 f,该函数对象会调用一个地址为 %s 的函数,返回值类型为整数,参数类型为指针。")]),t._v(" "),a("p",[a("code",[t._v('ptr("%s")')]),t._v(" 是一个占位符,将在代码中的字符串中被实际的地址值替换。 "),a("code",[t._v("int(sys.argv[1], 16)")]),t._v(" 用于获取命令行参数并将其解析为十六进制的整数值。")]),t._v(" "),a("p",[t._v("然后,你定义了一个 "),a("code",[t._v("on_message")]),t._v(" 函数作为消息处理程序,用于处理来自 Frida 脚本的消息。")]),t._v(" "),a("p",[t._v("接下来,使用 "),a("code",[t._v("script.on('message', on_message)")]),t._v(" 注册了消息处理程序。当 Frida 脚本收到消息时,"),a("code",[t._v("on_message")]),t._v(" 函数将被调用。")]),t._v(" "),a("p",[t._v("然后,调用 "),a("code",[t._v("script.load()")]),t._v(" 加载 Frida 脚本,使其开始在目标应用程序中执行。")]),t._v(" "),a("p",[t._v("最后,通过 "),a("code",[t._v("print(message)")]),t._v(" 将收到的消息打印出来,以便你查看和处理。")]),t._v(" "),a("p",[t._v('请确保在运行此代码之前,已经正确配置 Frida 环境,并且目标应用程序 "hi" 已经运行并可附加。你还需要根据你的具体需求定义 '),a("code",[t._v("on_message")]),t._v(" 函数,并根据代码中的占位符 %s 提供实际的地址值。")]),t._v(" "),a("p",[t._v("运行脚本后,当 Frida 脚本收到消息时,on_message 函数会将消息打印出来,供你查看和处理。")]),t._v(" "),a("h4",{attrs:{id:"message"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#message"}},[t._v("#")]),t._v(" Message")]),t._v(" "),a("div",{staticClass:"custom-block tip"},[a("p",{staticClass:"custom-block-title"},[t._v("提示")]),t._v(" "),a("p",[t._v("这块内容主要包含了如下内容, 更多详情可见"),a("a",{attrs:{href:"https://frida.re/docs/messages/",target:"_blank",rel:"noopener noreferrer"}},[t._v("文档"),a("OutboundLink")],1)]),t._v(" "),a("ul",[a("li",[t._v("Sending messages from a target process")]),t._v(" "),a("li",[t._v("Receiving messages in a target process")]),t._v(" "),a("li",[t._v("Blocking receives in the target process: 监听目标进程调用方法参数,通过 python 客户端修改调用参数示例")])])]),t._v(" "),a("p",[t._v("一、Sending messages from a target process")]),t._v(" "),a("div",{staticClass:"language-python line-numbers-mode"},[a("pre",{pre:!0,attrs:{class:"language-python"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" frida\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" sys\n\nsession "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" frida"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("attach"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"hello"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\nscript "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" session"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("create_script"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"send(1337);"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("def")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("on_message")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("message"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" data"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v("\n    "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("print")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("message"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\nscript"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("on"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'message'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" on_message"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\nscript"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("load"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\nsys"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("stdin"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("read"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])]),t._v(" "),a("div",{staticClass:"line-numbers-wrapper"},[a("span",{staticClass:"line-number"},[t._v("1")]),a("br"),a("span",{staticClass:"line-number"},[t._v("2")]),a("br"),a("span",{staticClass:"line-number"},[t._v("3")]),a("br"),a("span",{staticClass:"line-number"},[t._v("4")]),a("br"),a("span",{staticClass:"line-number"},[t._v("5")]),a("br"),a("span",{staticClass:"line-number"},[t._v("6")]),a("br"),a("span",{staticClass:"line-number"},[t._v("7")]),a("br"),a("span",{staticClass:"line-number"},[t._v("8")]),a("br"),a("span",{staticClass:"line-number"},[t._v("9")]),a("br"),a("span",{staticClass:"line-number"},[t._v("10")]),a("br")])]),a("p",[t._v("首先使用 "),a("code",[t._v("frida.attach")]),t._v(' 方法连接到目标应用程序 "hello"。然后,你创建了一个脚本对象,并使用 '),a("code",[t._v("session.create_script")]),t._v(" 方法创建了一个脚本,该脚本调用了 send(1337) 函数。")]),t._v(" "),a("p",[t._v("接下来,你定义了一个 on_message 函数,用于处理从脚本收到的消息,并打印出来。然后,你将 on_message 函数注册到脚本的 'message' 事件上,以便在脚本接收到消息时被调用。")]),t._v(" "),a("p",[t._v("最后,你使用 "),a("code",[t._v("script.load()")]),t._v(" 方法加载脚本,并使用 "),a("code",[t._v("sys.stdin.read()")]),t._v(" 使程序等待用户输入。这样做是为了保持脚本的运行,直到手动终止程序。")]),t._v(" "),a("h4",{attrs:{id:"ios"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#ios"}},[t._v("#")]),t._v(" IOS")]),t._v(" "),a("h4",{attrs:{id:"android"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#android"}},[t._v("#")]),t._v(" Android")]),t._v(" "),a("blockquote",[a("p",[t._v("内容 "),a("a",{attrs:{href:"https://frida.re/docs/android/",target:"_blank",rel:"noopener noreferrer"}},[t._v("链接"),a("OutboundLink")],1)])]),t._v(" "),a("p",[a("strong",[t._v("frida-server")])]),t._v(" "),a("ul",[a("li",[a("code",[t._v("frida-server --help")]),t._v(" 帮助")]),t._v(" "),a("li",[a("code",[t._v("frida-server --version")]),t._v(" check the version of the Frida server on the device or emulator.")]),t._v(" "),a("li",[a("code",[t._v("lsof | grep frida | grep LISTEN")]),t._v(" 查看 frida 当前监听的端口,下面的数据说明当前监听的端口为 27042 "),a("img",{attrs:{src:"https://cdn.jsdelivr.net/gh/jacky1234/picArchieve@master/uPic/20230617_155921_3MIbuy.png",alt:"frida-server-port"}})])]),t._v(" "),a("p",[t._v("二、升级 "),a("code",[t._v("frida-server")])]),t._v(" "),a("ol",[a("li",[t._v("首先升级 magisk-frida 到指定版本")]),t._v(" "),a("li",[t._v("下载指定的 "),a("code",[t._v("frida-server")]),t._v(" 并 push 到 "),a("code",[t._v("/data/local/tmp/")]),t._v(" 目录")]),t._v(" "),a("li",[t._v("重启。通过 magisk 加载最新的 "),a("code",[t._v("frida-server")])])]),t._v(" "),a("h3",{attrs:{id:"tools"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#tools"}},[t._v("#")]),t._v(" Tools")]),t._v(" "),a("h4",{attrs:{id:"frida-cli"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#frida-cli"}},[t._v("#")]),t._v(" frida cli")]),t._v(" "),a("ul",[a("li",[a("code",[t._v("frida -h")])]),t._v(" "),a("li",[a("code",[t._v("frida -U -l  -f ")]),t._v(" 将 Frida 附加到目标进程")]),t._v(" "),a("li",[a("code",[t._v("frida -D  -l  ")]),t._v(" 以 attach 模式加载 script,此种情况下会打印出 js 的错误。 (而直接使用)")]),t._v(" "),a("li",[a("code",[t._v("frida -D  -l  -f ")]),t._v(" 以 spawn 模式加载 script")])]),t._v(" "),a("h4",{attrs:{id:"frida-ps"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#frida-ps"}},[t._v("#")]),t._v(" frida-ps")]),t._v(" "),a("blockquote",[a("p",[t._v("This is a command-line tool for listing processes, which is very useful when interacting with a remote system.")])]),t._v(" "),a("ul",[a("li",[a("code",[t._v("frida-ps -U")]),t._v(" Connect Frida to an iPad over USB and list running processes")]),t._v(" "),a("li",[a("code",[t._v("frida-ps -Ua")]),t._v(" List running applications")]),t._v(" "),a("li",[a("code",[t._v("frida-ps -Uai")]),t._v(" List installed applications")]),t._v(" "),a("li",[a("code",[t._v("frida-ps -D ")]),t._v(" Connect Frida to the specific device")])]),t._v(" "),a("h4",{attrs:{id:"frida-trace"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#frida-trace"}},[t._v("#")]),t._v(" frida-trace")]),t._v(" "),a("blockquote",[a("p",[t._v("frida-trace is a tool for dynamically tracing function calls. "),a("a",{attrs:{href:"https://frida.re/docs/frida-trace/",target:"_blank",rel:"noopener noreferrer"}},[t._v("链接"),a("OutboundLink")],1)])]),t._v(" "),a("ul",[a("li",[a("code",[t._v("frida-trace -h")])]),t._v(" "),a("li",[a("code",[t._v('frida-trace -U -i "Java_*" ')]),t._v(" trace JNI 方法")])]),t._v(" "),a("h4",{attrs:{id:"frida-ls-devices"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#frida-ls-devices"}},[t._v("#")]),t._v(" frida-ls-devices")]),t._v(" "),a("blockquote",[a("p",[t._v("This is a command-line tool for killing processes.")])]),t._v(" "),a("p",[t._v("You can acquire PIDs from frida-ps tool.")]),t._v(" "),a("h4",{attrs:{id:"frida-kill"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#frida-kill"}},[t._v("#")]),t._v(" frida-kill")]),t._v(" "),a("ul",[a("li",[a("code",[t._v("frida-kill -D  ")])])]),t._v(" "),a("h4",{attrs:{id:"gum-graft"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#gum-graft"}},[t._v("#")]),t._v(" gum-graft")]),t._v(" "),a("blockquote",[a("p",[t._v("The gum-graft tool is used for patching binaries ahead of time to allow Interceptor to instrument them in environments where runtime code modifications are prohibited. For now this only means Apple mobile OSes when strict code-signing policies are at play – i.e. on jailed systems when running an app without a debugger having been attached. In such cases, override the Gadget code_signing option and set it to required.\n"),a("a",{attrs:{href:"https://frida.re/docs/gum-graft/",target:"_blank",rel:"noopener noreferrer"}},[t._v("链接"),a("OutboundLink")],1)])]),t._v(" "),a("h2",{attrs:{id:"objection"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#objection"}},[t._v("#")]),t._v(" objection")]),t._v(" "),a("div",{staticClass:"custom-block tip"},[a("p",{staticClass:"custom-block-title"},[t._v("提示")]),t._v(" "),a("p",[a("code",[t._v("objection")]),t._v(" is a runtime mobile exploration toolkit, powered by Frida, built to help you assess the security posture of your mobile applications, without needing a jailbreak.")]),t._v(" "),a("p",[t._v("帮助链接: "),a("a",{attrs:{href:"https://github.com/sensepost/objection/wiki",target:"_blank",rel:"noopener noreferrer"}},[t._v("objection-wiki"),a("OutboundLink")],1)])]),t._v(" "),a("h3",{attrs:{id:"常用命令"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#常用命令"}},[t._v("#")]),t._v(" 常用命令")]),t._v(" "),a("ul",[a("li",[a("code",[t._v("objection --help")]),t._v(": 帮助命令")]),t._v(" "),a("li",[a("code",[t._v("help android hooking watch class_method")]),t._v(": 命令中使用,监听 class")]),t._v(" "),a("li",[a("code",[t._v("objection -S  -g  explore -P ~/.objection/plugins")]),t._v(" "),a("code",[t._v("-P")]),t._v(" 指定了插件的路径。使用 explore 模式会导致应用重启")]),t._v(" "),a("li",[a("code",[t._v("env")])]),t._v(" "),a("li",[a("code",[t._v("evaluate ")])]),t._v(" "),a("li",[a("code",[t._v("reconnect")])]),t._v(" "),a("li",[t._v("jobs: 任务命令\n"),a("ul",[a("li",[a("code",[t._v("jobs list")]),t._v(": list current jobs")]),t._v(" "),a("li",[a("code",[t._v("jobs kill ")])])])])]),t._v(" "),a("h3",{attrs:{id:"memory"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#memory"}},[t._v("#")]),t._v(" memory")]),t._v(" "),a("blockquote",[a("p",[a("a",{attrs:{href:"https://www.anquanke.com/post/id/197657#h3-2",target:"_blank",rel:"noopener noreferrer"}},[t._v("https://www.anquanke.com/post/id/197657#h3-2"),a("OutboundLink")],1)])]),t._v(" "),a("ul",[a("li",[a("code",[t._v("memory list modules")])]),t._v(" "),a("li",[a("code",[t._v("memory list exports libssl.so --json /root/libart.json")])])]),t._v(" "),a("h3",{attrs:{id:"android-2"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#android-2"}},[t._v("#")]),t._v(" android")]),t._v(" "),a("p",[t._v("一、hooking")]),t._v(" "),a("ul",[a("li",[t._v("list\n"),a("ul",[a("li",[a("code",[t._v("android hooking list classes")])]),t._v(" "),a("li",[a("code",[t._v("android hooking list class_loaders")])]),t._v(" "),a("li",[a("code",[t._v("android hooking list class_methods")])]),t._v(" "),a("li",[a("code",[t._v("android hooking list activity")])])])]),t._v(" "),a("li",[t._v("search\n"),a("ul",[a("li",[a("code",[t._v("android hooking search methods")])]),t._v(" "),a("li",[a("code",[t._v("android hooking search classes")])])])]),t._v(" "),a("li",[a("code",[t._v("android hooking generate simple")])]),t._v(" "),a("li",[t._v("watch\n"),a("ul",[a("li",[a("code",[t._v("android hooking watch class")])]),t._v(" "),a("li",[a("code",[t._v("android hooking watch class_method")]),t._v(": 查看哪些个方法的参数、返回值和调用栈, 参数: --dump-args --dump-return --dump-backtrace")])])]),t._v(" "),a("li",[t._v("set")])]),t._v(" "),a("h4",{attrs:{id:"内存堆搜索与执行"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#内存堆搜索与执行"}},[t._v("#")]),t._v(" 内存堆搜索与执行")]),t._v(" "),a("blockquote",[a("p",[a("a",{attrs:{href:"https://www.anquanke.com/post/id/197657#h3-3",target:"_blank",rel:"noopener noreferrer"}},[t._v("https://www.anquanke.com/post/id/197657#h3-3"),a("OutboundLink")],1)])]),t._v(" "),a("ul",[a("li",[a("code",[t._v("android heap search instances com.android.settings.DisplaySettings")])]),t._v(" "),a("li",[a("code",[t._v("android heap execute 0x2526 getPreferenceScreenResId")])]),t._v(" "),a("li",[a("code",[t._v("android heap evaluate 0x2526")]),t._v(" 进入迷你编辑器")])]),t._v(" "),a("h3",{attrs:{id:"file"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#file"}},[t._v("#")]),t._v(" file")]),t._v(" "),a("h3",{attrs:{id:"import"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#import"}},[t._v("#")]),t._v(" import")]),t._v(" "),a("blockquote",[a("p",[t._v("Import fridascript from a full path and run it")])]),t._v(" "),a("h3",{attrs:{id:"plugin"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#plugin"}},[t._v("#")]),t._v(" plugin")]),t._v(" "),a("blockquote",[a("p",[t._v("Work with plugins. 下面介绍一些常用的 objection 的 plugin")])]),t._v(" "),a("h4",{attrs:{id:"wallbreaker"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#wallbreaker"}},[t._v("#")]),t._v(" Wallbreaker")]),t._v(" "),a("blockquote",[a("p",[a("a",{attrs:{href:"https://github.com/hluwa/Wallbreaker",target:"_blank",rel:"noopener noreferrer"}},[t._v("https://github.com/hluwa/Wallbreaker"),a("OutboundLink")],1),t._v(" 入门: "),a("a",{attrs:{href:"https://mp.weixin.qq.com/s/qpj3ezUdm-X6ZwcWcibeAw",target:"_blank",rel:"noopener noreferrer"}},[t._v("使用 Wallbreaker 快速分析 Java 类/对象结构"),a("OutboundLink")],1)])]),t._v(" "),a("p",[t._v("一、使用")]),t._v(" "),a("ul",[a("li",[t._v("安装 "),a("code",[t._v("objection: pip3 install objection")])]),t._v(" "),a("li",[t._v("下载 wallbreaker 到自己的插件目录: "),a("code",[t._v("git clone https://github.com/hluwa/Wallbreaker ~/.objection/plugins/Wallbreaker")])]),t._v(" "),a("li",[t._v("启动 frida-server,使用 -P 参数 "),a("RText",{attrs:{text:"带着插件启动 objection",color:"green"}}),t._v(": "),a("code",[t._v("objection -g com.app.name explore -P ~/.objection/plugins")])],1)]),t._v(" "),a("p",[t._v("二、使用")]),t._v(" "),a("ul",[a("li",[a("code",[t._v("plugin wallbreaker classsearch ")]),t._v(" 搜索类:根据给的 pattern 对所有类名进行匹配,列出匹配到的所有类名。")]),t._v(" "),a("li",[a("code",[t._v("plugin wallbreaker objectsearch ")]),t._v(" 搜索对象:根据类名搜索内存中已经被创建的实例,列出 handle 和 toString() 的结果。")]),t._v(" "),a("li",[a("code",[t._v("plugin wallbreaker classdump  [--fullname]")]),t._v(" ClassDump: 输出类的结构, 若加了 --fullname 参数,打印的数据中类名会带着完整的包名。")]),t._v(" "),a("li",[a("code",[t._v("plugin wallbreaker objectdump  [--fullname]")]),t._v(" ObjectDump: 在 ClassDump 的基础上,输出指定对象中的每个字段的数据。")])]),t._v(" "),a("h4",{attrs:{id:"frida-dexdump"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#frida-dexdump"}},[t._v("#")]),t._v(" FRIDA-DEXDump")]),t._v(" "),a("blockquote",[a("p",[t._v("frida-dexdump is a frida tool to find and dump dex in memory to support security engineers in analyzing malware.\n更多内容点击查看:"),a("a",{attrs:{href:"https://github.com/hluwa/FRIDA-DEXDump",target:"_blank",rel:"noopener noreferrer"}},[t._v("FRIDA-DEXDump"),a("OutboundLink")],1)])]),t._v(" "),a("p",[t._v("使用命令 "),a("code",[t._v("frida-dexdump -D  -f ")]),t._v(" 开始 dump dex")]),t._v(" "),a("h2",{attrs:{id:"最佳实践"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#最佳实践"}},[t._v("#")]),t._v(" 最佳实践")]),t._v(" "),a("blockquote",[a("p",[t._v("This section is meant to contain best practices and pitfalls commonly encountered when using Frida. see: "),a("a",{attrs:{href:"https://frida.re/docs/best-practices/",target:"_blank",rel:"noopener noreferrer"}},[t._v("https://frida.re/docs/best-practices/"),a("OutboundLink")],1)])]),t._v(" "),a("p",[t._v("一、修改参数。绑定到调用对象上,防止对象被 GC")]),t._v(" "),a("blockquote",[a("p",[t._v("This way you can read arguments in onEnter and access them later in onLeave.")])]),t._v(" "),a("div",{staticClass:"language-js line-numbers-mode"},[a("pre",{pre:!0,attrs:{class:"language-js"}},[a("code",[a("span",{pre:!0,attrs:{class:"token function"}},[t._v("onEnter")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("args")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n  "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" buf "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Memory"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("allocUtf8String")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'mystring'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n  "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("this")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("buf "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" buf"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n  args"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" buf"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])]),t._v(" "),a("div",{staticClass:"line-numbers-wrapper"},[a("span",{staticClass:"line-number"},[t._v("1")]),a("br"),a("span",{staticClass:"line-number"},[t._v("2")]),a("br"),a("span",{staticClass:"line-number"},[t._v("3")]),a("br"),a("span",{staticClass:"line-number"},[t._v("4")]),a("br"),a("span",{staticClass:"line-number"},[t._v("5")]),a("br")])]),a("p",[t._v("二、函数调用后仍然使用的对象")]),t._v(" "),a("div",{staticClass:"language-js line-numbers-mode"},[a("pre",{pre:!0,attrs:{class:"language-js"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" myStringBuf "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Memory"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("allocUtf8String")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'mystring'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\nInterceptor"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("attach")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("f"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n\t"),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("onEnter")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("args")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n\t\targs"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" myStringBuf\n\t"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])]),t._v(" "),a("div",{staticClass:"line-numbers-wrapper"},[a("span",{staticClass:"line-number"},[t._v("1")]),a("br"),a("span",{staticClass:"line-number"},[t._v("2")]),a("br"),a("span",{staticClass:"line-number"},[t._v("3")]),a("br"),a("span",{staticClass:"line-number"},[t._v("4")]),a("br"),a("span",{staticClass:"line-number"},[t._v("5")]),a("br"),a("span",{staticClass:"line-number"},[t._v("6")]),a("br"),a("span",{staticClass:"line-number"},[t._v("7")]),a("br")])]),a("p",[t._v("三、Reuse arguments")]),t._v(" "),a("div",{staticClass:"language-js line-numbers-mode"},[a("pre",{pre:!0,attrs:{class:"language-js"}},[a("code",[t._v("Interceptor"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("attach")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("f"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n\t"),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("onEnter")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("args")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n\t\t"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!")]),t._v("args"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("readUtf8String")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("4")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("includes")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'MZ'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n\t\t\tconsole"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("hexdump")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("args"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\t\t"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\t"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])]),t._v(" "),a("div",{staticClass:"line-numbers-wrapper"},[a("span",{staticClass:"line-number"},[t._v("1")]),a("br"),a("span",{staticClass:"line-number"},[t._v("2")]),a("br"),a("span",{staticClass:"line-number"},[t._v("3")]),a("br"),a("span",{staticClass:"line-number"},[t._v("4")]),a("br"),a("span",{staticClass:"line-number"},[t._v("5")]),a("br"),a("span",{staticClass:"line-number"},[t._v("6")]),a("br"),a("span",{staticClass:"line-number"},[t._v("7")]),a("br")])]),a("p",[t._v("In the above example the first argument is obtained from the args array twice, and this is paying the cost of querying frida-gum for this information twice. To avoid wasting precious CPU cycles when needing the same argument multiple times, "),a("strong",[t._v("it is best to store this information using a local variable")]),t._v(":")]),t._v(" "),a("div",{staticClass:"language-js line-numbers-mode"},[a("pre",{pre:!0,attrs:{class:"language-js"}},[a("code",[t._v("Interceptor"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("attach")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("f"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n\t"),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("onEnter")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("args")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n\t\t"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" firstArg "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" args"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v("\n\t\t"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!")]),t._v("firstArg"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("readUtf8String")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("4")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("includes")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'MZ'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n\t\t\tconsole"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("hexdump")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("firstArg"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\t\t"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\t"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])]),t._v(" "),a("div",{staticClass:"line-numbers-wrapper"},[a("span",{staticClass:"line-number"},[t._v("1")]),a("br"),a("span",{staticClass:"line-number"},[t._v("2")]),a("br"),a("span",{staticClass:"line-number"},[t._v("3")]),a("br"),a("span",{staticClass:"line-number"},[t._v("4")]),a("br"),a("span",{staticClass:"line-number"},[t._v("5")]),a("br"),a("span",{staticClass:"line-number"},[t._v("6")]),a("br"),a("span",{staticClass:"line-number"},[t._v("7")]),a("br"),a("span",{staticClass:"line-number"},[t._v("8")]),a("br")])]),a("h2",{attrs:{id:"apm"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#apm"}},[t._v("#")]),t._v(" APM")]),t._v(" "),a("blockquote",[a("p",[t._v("使用 frida 分析 android 的卡顿技巧")])]),t._v(" "),a("p",[t._v("使用 Frida 来分析 Android 应用的卡顿问题是一种高效的技巧,可以帮助你快速定位卡顿的原因。以下是一些使用 Frida 分析 Android 卡顿问题的技巧:")]),t._v(" "),a("ul",[a("li",[a("p",[t._v("Hook 主线程消息循环:使用 Frida 在主线程消息循环中插入代码,例如在 Looper.loop() 函数处进行 Hook。这样你可以跟踪主线程的消息处理,并检测是否有耗时的任务导致卡顿。")])]),t._v(" "),a("li",[a("p",[t._v("Hook 动画相关方法:如果应用中使用了动画,可以尝试 Hook 与动画相关的方法,例如 ViewPropertyAnimator 或 ObjectAnimator 相关的方法,以检测动画的性能问题。")])]),t._v(" "),a("li",[a("p",[t._v("检测 IO 操作:Hook 文件读写和网络请求相关的方法,以便检测是否有阻塞 IO 操作导致卡顿。")])]),t._v(" "),a("li",[a("p",[t._v("检测耗时计算:Hook 应用中的复杂计算或者大量数据处理的方法,以便找出可能导致卡顿的耗时操作。")])]),t._v(" "),a("li",[a("p",[t._v("TraceCompat API:在关键方法中插入 TraceCompat 的 beginSection 和 endSection,可以使用 Perfetto 或者 Systrace 来分析应用的执行流程和耗时。")])]),t._v(" "),a("li",[a("p",[t._v("监听消息队列:通过 Hook MessageQueue.enqueueMessage() 方法,可以监视消息队列中的消息处理情况,从而找出消息处理时间过长的情况。")])]),t._v(" "),a("li",[a("p",[t._v("监控线程状态:使用 Frida 监控线程状态,例如检测线程是否处于等待状态或者死锁状态。")])]),t._v(" "),a("li",[a("p",[t._v("统计方法耗时:使用 Frida 统计方法的执行时间,并记录下方法的调用栈,从而找到耗时操作的位置。")])])]),t._v(" "),a("p",[t._v("请注意,使用 Frida 进行分析需要一定的技术知识和经验,建议在分析之前先熟悉 Frida 的基本用法和 Android 应用的工作原理。同时,为了保证分析的准确性和可靠性,建议在开发环境或者测试环境中进行分析,而不是在生产环境中直接运行 Frida 脚本。")]),t._v(" "),a("h2",{attrs:{id:"其他"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#其他"}},[t._v("#")]),t._v(" 其他")]),t._v(" "),a("h3",{attrs:{id:"对象的比较"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#对象的比较"}},[t._v("#")]),t._v(" 对象的比较")]),t._v(" "),a("blockquote",[a("p",[t._v("looperClazz.getMainLooper() === looperClazz.myLooper() 在 frida 的 script 为什么就不能正常 true 呢?")])]),t._v(" "),a("p",[t._v("案例来自于如下脚本。")]),t._v(" "),a("div",{staticClass:"language-javascript line-numbers-mode"},[a("pre",{pre:!0,attrs:{class:"language-javascript"}},[a("code",[t._v("clazz"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("dispatchMessage"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function-variable function"}},[t._v("implementation")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("function")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("v1")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n  "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// console.log(dumpThreadInfo(looperClazz.getMainLooper().getThread()));")]),t._v("\n  "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("looperClazz"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("getMainLooper")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("===")]),t._v(" looperClazz"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("myLooper")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n    "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("var")]),t._v(" bundle "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" v1"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("getData")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n    "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("...")]),t._v("\n    bundle"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("clazz"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("dispatchMessage")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("apply")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("this")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" arguments"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n  "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("else")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n    clazz"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("dispatchMessage")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("apply")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("this")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" arguments"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n  "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])]),t._v(" "),a("div",{staticClass:"line-numbers-wrapper"},[a("span",{staticClass:"line-number"},[t._v("1")]),a("br"),a("span",{staticClass:"line-number"},[t._v("2")]),a("br"),a("span",{staticClass:"line-number"},[t._v("3")]),a("br"),a("span",{staticClass:"line-number"},[t._v("4")]),a("br"),a("span",{staticClass:"line-number"},[t._v("5")]),a("br"),a("span",{staticClass:"line-number"},[t._v("6")]),a("br"),a("span",{staticClass:"line-number"},[t._v("7")]),a("br"),a("span",{staticClass:"line-number"},[t._v("8")]),a("br"),a("span",{staticClass:"line-number"},[t._v("9")]),a("br"),a("span",{staticClass:"line-number"},[t._v("10")]),a("br")])]),a("p",[t._v("后面使用如下方式解决了:")]),t._v(" "),a("div",{staticClass:"language-javascript line-numbers-mode"},[a("pre",{pre:!0,attrs:{class:"language-javascript"}},[a("code",[t._v("looperClazz"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("getMainLooper")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("hashCode")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("===")]),t._v(" looperClazz"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("myLooper")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("hashCode")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])]),t._v(" "),a("div",{staticClass:"line-numbers-wrapper"},[a("span",{staticClass:"line-number"},[t._v("1")]),a("br")])]),a("p",[t._v("原理待补充...")]),t._v(" "),a("p",[t._v("另外 Frida JavaScript api 也提供了 "),a("code",[t._v("Java.isMainThread()")]),t._v(" 更加方便简单了")]),t._v(" "),a("h3",{attrs:{id:"handle"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#handle"}},[t._v("#")]),t._v(" $handle")]),t._v(" "),a("p",[t._v("在 Frida 中,"),a("code",[t._v("$handle")]),t._v(" 是一个特殊的属性,用于获取 Java 对象在内存中的句柄(handle)。句柄是一个用于标识对象在内存中位置的唯一值。每个 Java 对象都有一个对应的句柄,可以通过$handle 属性来获取。")]),t._v(" "),a("p",[t._v("在下述示例中,mRouteServiceTable.$handle 获取了 mRouteServiceTable 对象的句柄,然后使用 add(offset)方法来计算出 mRouteServiceTable 对象的内存地址。offset 是指向 mTable 字段的偏移量,通过添加偏移量到对象句柄,我们可以获取到 mRouteServiceTable 对象在内存中的实际地址。")]),t._v(" "),a("p",[t._v("获取对象句柄和计算内存地址通常用于 Frida 的低级别内存操作,比如通过 Interceptor 监视对象的读写,或者直接修改对象的字段值。这样的低级别内存操作在某些场景下非常有用,特别是在需要对 Java 对象进行"),a("strong",[t._v("细粒度控制和监视")]),t._v("的时候。")]),t._v(" "),a("p",[t._v("例子:")]),t._v(" "),a("div",{staticClass:"language-javascript line-numbers-mode"},[a("pre",{pre:!0,attrs:{class:"language-javascript"}},[a("code",[t._v("Java"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("perform")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("function")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n\t"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("var")]),t._v(" ServiceHub "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Java"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("use")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'com.example.ServiceHub'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 替换为实际的包名和类名")]),t._v("\n\n\t"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("var")]),t._v(" mRouteServiceTable "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" ServiceHub"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("mRouteServiceTable\n\t"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("var")]),t._v(" HashMap "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Java"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("use")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'java.util.HashMap'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n\t"),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 获取HashMap类的定义")]),t._v("\n\t"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("var")]),t._v(" HashMapDef "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Java"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("use")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'java.util.HashMap'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("class\n\t"),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 获取HashMap类的成员变量表")]),t._v("\n\t"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("var")]),t._v(" fields "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" HashMapDef"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("getDeclaredFields")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\t"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("var")]),t._v(" mTableField "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("null")]),t._v("\n\n\t"),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 遍历成员变量表,找到mTable字段")]),t._v("\n\t"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("var")]),t._v(" i "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" i "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v(" fields"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("length"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" i"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("++")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n\t\t"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("var")]),t._v(" field "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" fields"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("i"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v("\n\t\t"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("field"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("toString")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("indexOf")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'java.util.HashMap$Node[]'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!==")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n\t\t\tmTableField "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" field\n\t\t\t"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("break")]),t._v("\n\t\t"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\t"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n\t"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("mTableField "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!==")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("null")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n\t\t"),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 获取mTable字段在内存中的偏移量")]),t._v("\n\t\t"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("var")]),t._v(" offset "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" mTableField"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'offset'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("toInt")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\t\t"),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 计算mRouteServiceTable对象的内存地址")]),t._v("\n\t\t"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("var")]),t._v(" mRouteServiceTableAddr "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" mRouteServiceTable"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("$handle"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("add")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("offset"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n\t\t"),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 使用Interceptor监视mRouteServiceTable对象的读取和写入操作")]),t._v("\n\t\tInterceptor"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("attach")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("mRouteServiceTableAddr"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n\t\t\t"),a("span",{pre:!0,attrs:{class:"token function-variable function"}},[t._v("onGet")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("function")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("args")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n\t\t\t\tconsole"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Reading from mRouteServiceTable: '")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" args"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("readPointer")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\t\t\t"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n\t\t\t"),a("span",{pre:!0,attrs:{class:"token function-variable function"}},[t._v("onSet")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("function")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("args")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n\t\t\t\tconsole"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Writing to mRouteServiceTable: '")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" args"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("readPointer")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\t\t\t"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n\t\t"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\t"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])]),t._v(" "),a("div",{staticClass:"line-numbers-wrapper"},[a("span",{staticClass:"line-number"},[t._v("1")]),a("br"),a("span",{staticClass:"line-number"},[t._v("2")]),a("br"),a("span",{staticClass:"line-number"},[t._v("3")]),a("br"),a("span",{staticClass:"line-number"},[t._v("4")]),a("br"),a("span",{staticClass:"line-number"},[t._v("5")]),a("br"),a("span",{staticClass:"line-number"},[t._v("6")]),a("br"),a("span",{staticClass:"line-number"},[t._v("7")]),a("br"),a("span",{staticClass:"line-number"},[t._v("8")]),a("br"),a("span",{staticClass:"line-number"},[t._v("9")]),a("br"),a("span",{staticClass:"line-number"},[t._v("10")]),a("br"),a("span",{staticClass:"line-number"},[t._v("11")]),a("br"),a("span",{staticClass:"line-number"},[t._v("12")]),a("br"),a("span",{staticClass:"line-number"},[t._v("13")]),a("br"),a("span",{staticClass:"line-number"},[t._v("14")]),a("br"),a("span",{staticClass:"line-number"},[t._v("15")]),a("br"),a("span",{staticClass:"line-number"},[t._v("16")]),a("br"),a("span",{staticClass:"line-number"},[t._v("17")]),a("br"),a("span",{staticClass:"line-number"},[t._v("18")]),a("br"),a("span",{staticClass:"line-number"},[t._v("19")]),a("br"),a("span",{staticClass:"line-number"},[t._v("20")]),a("br"),a("span",{staticClass:"line-number"},[t._v("21")]),a("br"),a("span",{staticClass:"line-number"},[t._v("22")]),a("br"),a("span",{staticClass:"line-number"},[t._v("23")]),a("br"),a("span",{staticClass:"line-number"},[t._v("24")]),a("br"),a("span",{staticClass:"line-number"},[t._v("25")]),a("br"),a("span",{staticClass:"line-number"},[t._v("26")]),a("br"),a("span",{staticClass:"line-number"},[t._v("27")]),a("br"),a("span",{staticClass:"line-number"},[t._v("28")]),a("br"),a("span",{staticClass:"line-number"},[t._v("29")]),a("br"),a("span",{staticClass:"line-number"},[t._v("30")]),a("br"),a("span",{staticClass:"line-number"},[t._v("31")]),a("br"),a("span",{staticClass:"line-number"},[t._v("32")]),a("br"),a("span",{staticClass:"line-number"},[t._v("33")]),a("br"),a("span",{staticClass:"line-number"},[t._v("34")]),a("br"),a("span",{staticClass:"line-number"},[t._v("35")]),a("br"),a("span",{staticClass:"line-number"},[t._v("36")]),a("br"),a("span",{staticClass:"line-number"},[t._v("37")]),a("br"),a("span",{staticClass:"line-number"},[t._v("38")]),a("br")])]),a("p",[t._v("Interceptor.attach 是 Frida 中的一个功能,用于拦截函数调用。它可以用于监视和修改函数的参数和返回值。在你的代码中,Interceptor.attach 用于拦截对 mRouteServiceTable 对象的读取和写入操作。")]),t._v(" "),a("p",[a("code",[t._v("onGet")]),t._v(" 和 "),a("code",[t._v("onSet")]),t._v(" 是用于定义回调函数的两个参数,它们分别在拦截的函数调用读取或写入 mRouteServiceTable 对象时触发。")]),t._v(" "),a("ul",[a("li",[a("p",[t._v("onGet: 当有代码尝试读取 mRouteServiceTable 对象时,这个回调函数会被调用。args[0]代表被读取的对象的指针。通过 readPointer()方法,可以读取这个指针所指向的内存地址。在这里,你可以添加代码来监视读取操作或对读取进行一些处理。")])]),t._v(" "),a("li",[a("p",[t._v("onSet: 当有代码尝试写入 mRouteServiceTable 对象时,这个回调函数会被调用。args[0]代表被写入的对象的指针。通过 readPointer()方法,可以读取这个指针所指向的内存地址。在这里,你可以添加代码来监视写入操作或对写入进行一些处理。")])])]),t._v(" "),a("p",[t._v("使用 Interceptor.attach 和 onGet、onSet 回调函数,你可以实现对 mRouteServiceTable 对象的读写操作进行拦截和监视,从而在运行时获取或修改该对象的内容。")]),t._v(" "),a("h3",{attrs:{id:"访问修改静态属性字段"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#访问修改静态属性字段"}},[t._v("#")]),t._v(" 访问修改静态属性字段")]),t._v(" "),a("blockquote",[a("p",[t._v("假设,我们要修改 com.example.app.MyClass 的 MAX_VALUE 值(final 类型也可以)")])]),t._v(" "),a("div",{staticClass:"language-javascript line-numbers-mode"},[a("pre",{pre:!0,attrs:{class:"language-javascript"}},[a("code",[a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Attach to the process")]),t._v("\nJava"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("perform")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("function")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n\t"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("var")]),t._v(" clazz "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Java"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("use")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'com.example.app.MyClass'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n\t"),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 获取原先值")]),t._v("\n\tconsole"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'>'")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" clazz"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("$className "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("')i]'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'clazz'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" clazz"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token constant"}},[t._v("MAX_VALUE")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("value"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\t"),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 直接修改,也可以改 final 字段")]),t._v("\n\tclazz"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token constant"}},[t._v("MAX_VALUE")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("value "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("100")]),t._v("\n\tconsole"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'>'")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" clazz"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("$className "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("')o]'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'clazz'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" clazz"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token constant"}},[t._v("MAX_VALUE")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("value"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])]),t._v(" "),a("div",{staticClass:"line-numbers-wrapper"},[a("span",{staticClass:"line-number"},[t._v("1")]),a("br"),a("span",{staticClass:"line-number"},[t._v("2")]),a("br"),a("span",{staticClass:"line-number"},[t._v("3")]),a("br"),a("span",{staticClass:"line-number"},[t._v("4")]),a("br"),a("span",{staticClass:"line-number"},[t._v("5")]),a("br"),a("span",{staticClass:"line-number"},[t._v("6")]),a("br"),a("span",{staticClass:"line-number"},[t._v("7")]),a("br"),a("span",{staticClass:"line-number"},[t._v("8")]),a("br"),a("span",{staticClass:"line-number"},[t._v("9")]),a("br"),a("span",{staticClass:"line-number"},[t._v("10")]),a("br")])]),a("h3",{attrs:{id:"符号"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#符号"}},[t._v("#")]),t._v(" "),a("code",[t._v("$")]),t._v("符号")]),t._v(" "),a("blockquote",[a("p",[t._v("在 Frida 中,$ 符号用于访问一些特殊的对象和属性,以便与 Java 的交互更加便捷。以下是一些常见的 $ 符号及其用法:")])]),t._v(" "),a("ul",[a("li",[a("code",[t._v("clazz.$new()")]),t._v(": 创建一个对象")]),t._v(" "),a("li",[a("code",[t._v("clazz.$className")]),t._v(": 获取 class 的 className")]),t._v(" "),a("li",[t._v("代表内部类,这与 java 是一样的")])]),t._v(" "),a("h3",{attrs:{id:"根据特征搜索类"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#根据特征搜索类"}},[t._v("#")]),t._v(" 根据特征搜索类")]),t._v(" "),a("p",[t._v("一、背景")]),t._v(" "),a("blockquote",[a("p",[t._v("在生产环境获取 progurad 类名")])]),t._v(" "),a("h3",{attrs:{id:"破解方法论"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#破解方法论"}},[t._v("#")]),t._v(" 破解方法论")]),t._v(" "),a("p",[t._v("Frida 是一个功能强大的动态分析工具,可用于 Android 和 iOS 应用的逆向工程、漏洞分析、代码修改等方面。以下是使用 Frida 破解应用的一般思路:")]),t._v(" "),a("ul",[a("li",[t._v("目标分析: 首先,你需要确定要破解的目标应用,并分析它的功能、运行机制以及可能存在的漏洞。这可以包括查找敏感信息、关键函数、加密/解密逻辑等。")]),t._v(" "),a("li",[t._v("环境设置: 安装 Frida 并设置好开发环境。你需要 Frida 的命令行工具以及 Python 包,以便在 Frida 脚本中使用 Python。")]),t._v(" "),a("li",[t._v("Hooking: 使用 Frida 脚本 Hook 应用中的函数。通过 Hooking,你可以插入自己的代码到目标应用的运行流程中。这样你就可以观察、修改、替换函数的行为。")]),t._v(" "),a("li",[t._v("函数分析: 一旦成功 Hook 了目标函数,你可以通过 Frida 提供的 API 监控函数的输入、输出参数,甚至修改它们。这可以用于绕过验证、修改敏感数据等。")]),t._v(" "),a("li",[t._v("数据抓取: 使用 Frida 脚本获取应用中的敏感数据。例如,你可以监控网络通信、文件读写操作,获取加密密钥等。")]),t._v(" "),a("li",[t._v("漏洞挖掘: Frida 可用于发现应用中的漏洞,例如不正确的验证逻辑、代码注入漏洞等。你可以 Hook 目标函数并分析其行为,寻找可能的漏洞。")]),t._v(" "),a("li",[t._v("反编译与修改: 通过 Hooking,你可以获得应用内存中的代码,然后可以反编译它。这允许你修改应用的代码、跳过验证、绕过限制等。")]),t._v(" "),a("li",[t._v("安全检测: Frida 也可用于安全评估。你可以 Hook 安全敏感函数,检测是否有未经授权的访问、数据泄露等。")])]),t._v(" "),a("p",[t._v("需要注意的是,Frida 用于破解应用涉及法律和伦理问题,因此在使用 Frida 进行逆向工程之前,请务必了解并遵守法律法规,以及遵循合法的使用方式。不当的使用 Frida 可能会侵犯应用开发者的权益,甚至可能触犯法律。")]),t._v(" "),a("h3",{attrs:{id:"破解思想"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#破解思想"}},[t._v("#")]),t._v(" 破解思想")]),t._v(" "),a("ul",[a("li",[t._v("使用 file monitor 监控文件的打开情况")]),t._v(" "),a("li",[t._v("hook 系统的非方法,可以避免")])]),t._v(" "),a("h2",{attrs:{id:"链接"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#链接"}},[t._v("#")]),t._v(" 链接")]),t._v(" "),a("ul",[a("li",[a("a",{attrs:{href:"https://www.anquanke.com/post/id/197657",target:"_blank",rel:"noopener noreferrer"}},[t._v("实用 FRIDA 进阶:内存漫游、hook anywhere、抓包-安全客"),a("OutboundLink")],1)]),t._v(" "),a("li",[a("a",{attrs:{href:"https://www.anquanke.com/post/id/197670",target:"_blank",rel:"noopener noreferrer"}},[t._v("实用 FRIDA 进阶:脱壳、自动化、高频问题-安全客"),a("OutboundLink")],1)]),t._v(" "),a("li",[a("a",{attrs:{href:"https://github.com/jacky1234/hooker",target:"_blank",rel:"noopener noreferrer"}},[t._v("hooker"),a("OutboundLink")],1),t._v(" hooker 是一个基于 frida 实现的逆向工具包。为逆向开发人员提供统一化的脚本包管理方式、通杀脚本、自动化生成 hook 脚本、内存漫游探测 activity 和 service、frida 版 JustTrustMe。")]),t._v(" "),a("li",[a("a",{attrs:{href:"https://github.com/jacky1234/radar4hooker",target:"_blank",rel:"noopener noreferrer"}},[t._v("radar4hooker"),a("OutboundLink")],1),t._v(" 为 hooker 提供的 dex 增强功能库")])])])}),[],!1,null,null,null);a.default=e.exports}}]);
\ No newline at end of file
diff --git a/assets/js/98.c63a5061.js b/assets/js/98.c63a5061.js
new file mode 100644
index 0000000000..8c2b2faf1d
--- /dev/null
+++ b/assets/js/98.c63a5061.js
@@ -0,0 +1 @@
+(window.webpackJsonp=window.webpackJsonp||[]).push([[98],{424:function(t,e,n){"use strict";n.r(e);var r=n(4),o=Object(r.a)({},(function(){var t=this._self._c;return t("ContentSlotsDistributor",{attrs:{"slot-key":this.$parent.slotKey}},[t("blockquote",[t("p",[t("a",{attrs:{href:"https://developer.android.com/training/articles/keystore?hl=zh-cn",target:"_blank",rel:"noopener noreferrer"}},[this._v("Android 密钥库系统"),t("OutboundLink")],1)])]),this._v(" "),t("p",[this._v("TODO")])])}),[],!1,null,null,null);e.default=o.exports}}]);
\ No newline at end of file
diff --git a/assets/js/99.3f671d22.js b/assets/js/99.3f671d22.js
new file mode 100644
index 0000000000..06a4bbd01a
--- /dev/null
+++ b/assets/js/99.3f671d22.js
@@ -0,0 +1 @@
+(window.webpackJsonp=window.webpackJsonp||[]).push([[99],{425:function(t,n,s){"use strict";s.r(n);var e=s(4),o=Object(e.a)({},(function(){return(0,this._self._c)("ContentSlotsDistributor",{attrs:{"slot-key":this.$parent.slotKey}})}),[],!1,null,null,null);n.default=o.exports}}]);
\ No newline at end of file
diff --git a/assets/js/app.d4a66103.js b/assets/js/app.d4a66103.js
new file mode 100644
index 0000000000..7f7a6466ad
--- /dev/null
+++ b/assets/js/app.d4a66103.js
@@ -0,0 +1,16 @@
+(window.webpackJsonp=window.webpackJsonp||[]).push([[0],[]]);!function(e){function t(t){for(var a,o,l=t[0],s=t[1],c=t[2],p=0,d=[];pfunction e(t,n,a,r=1){if("string"==typeof t)return h(n,t,a);if(Array.isArray(t))return Object.assign(h(n,t[0],a),{title:t[1]});{r>3&&console.error("[vuepress] detected a too deep nested sidebar group.");const i=t.children||[];return 0===i.length&&t.path?Object.assign(h(n,t.path,a),{title:t.title}):{type:"group",path:t.path,title:t.title,sidebarDepth:t.sidebarDepth,initialOpenGroupIndex:t.initialOpenGroupIndex,children:i.map(t=>e(t,n,a,r+1)),collapsable:!1!==t.collapsable}}}(e,r,n)):[]}return[]}function m(e){const t=g(e.headers||[]);return[{type:"group",collapsable:!1,title:e.title,path:null,children:t.map(t=>({type:"auto",title:t.title,basePath:e.path,path:e.path+"#"+t.slug,children:t.children||[]}))}]}function g(e){let t;return(e=e.map(e=>Object.assign({},e))).forEach(e=>{2===e.level?t=e:t&&(t.children||(t.children=[])).push(e)}),e.filter(e=>2===e.level)}function v(e){return Object.assign(e,{type:e.items&&e.items.length?"links":"link"})}function b(e){return Object.prototype.toString.call(e).match(/\[object (.*?)\]/)[1].toLowerCase()}function y(e){let t=e.frontmatter.date||e.lastUpdated||new Date,n=new Date(t);return"Invalid Date"==n&&t&&(n=new Date(t.replace(/-/g,"/"))),n.getTime()}function k(e,t){return y(t)-y(e)}},function(e,t){e.exports=function(e){return null!=e&&"object"==typeof e}},function(e,t,n){var a=n(15),r=n(149),i=n(150),o=a?a.toStringTag:void 0;e.exports=function(e){return null==e?void 0===e?"[object Undefined]":"[object Null]":o&&o in Object(e)?r(e):i(e)}},function(e,t,n){"use strict";var a=n(6),r=n(17),i=n(29);e.exports=a?function(e,t,n){return r.f(e,t,i(1,n))}:function(e,t,n){return e[t]=n,e}},function(e,t,n){var a=n(7).Symbol;e.exports=a},function(e,t){var n=/^\s+|\s+$/g,a=/^[-+]0x[0-9a-f]+$/i,r=/^0b[01]+$/i,i=/^0o[0-7]+$/i,o=parseInt,l="object"==typeof global&&global&&global.Object===Object&&global,s="object"==typeof self&&self&&self.Object===Object&&self,c=l||s||Function("return this")(),u=Object.prototype.toString,p=Math.max,d=Math.min,h=function(){return c.Date.now()};function f(e){var t=typeof e;return!!e&&("object"==t||"function"==t)}function m(e){if("number"==typeof e)return e;if(function(e){return"symbol"==typeof e||function(e){return!!e&&"object"==typeof e}(e)&&"[object Symbol]"==u.call(e)}(e))return NaN;if(f(e)){var t="function"==typeof e.valueOf?e.valueOf():e;e=f(t)?t+"":t}if("string"!=typeof e)return 0===e?e:+e;e=e.replace(n,"");var l=r.test(e);return l||i.test(e)?o(e.slice(2),l?2:8):a.test(e)?NaN:+e}e.exports=function(e,t,n){var a,r,i,o,l,s,c=0,u=!1,g=!1,v=!0;if("function"!=typeof e)throw new TypeError("Expected a function");function b(t){var n=a,i=r;return a=r=void 0,c=t,o=e.apply(i,n)}function y(e){return c=e,l=setTimeout(E,t),u?b(e):o}function k(e){var n=e-s;return void 0===s||n>=t||n<0||g&&e-c>=i}function E(){var e=h();if(k(e))return _(e);l=setTimeout(E,function(e){var n=t-(e-s);return g?d(n,i-(e-c)):n}(e))}function _(e){return l=void 0,v&&a?b(e):(a=r=void 0,o)}function x(){var e=h(),n=k(e);if(a=arguments,r=this,s=e,n){if(void 0===l)return y(s);if(g)return l=setTimeout(E,t),b(s)}return void 0===l&&(l=setTimeout(E,t)),o}return t=m(t)||0,f(n)&&(u=!!n.leading,i=(g="maxWait"in n)?p(m(n.maxWait)||0,t):i,v="trailing"in n?!!n.trailing:v),x.cancel=function(){void 0!==l&&clearTimeout(l),c=0,a=s=r=l=void 0},x.flush=function(){return void 0===l?o:_(h())},x}},function(e,t,n){"use strict";var a=n(6),r=n(63),i=n(110),o=n(37),l=n(53),s=TypeError,c=Object.defineProperty,u=Object.getOwnPropertyDescriptor;t.f=a?i?function(e,t,n){if(o(e),t=l(t),o(n),"function"==typeof e&&"prototype"===t&&"value"in n&&"writable"in n&&!n.writable){var a=u(e,t);a&&a.writable&&(e[t]=n.value,n={configurable:"configurable"in n?n.configurable:a.configurable,enumerable:"enumerable"in n?n.enumerable:a.enumerable,writable:!1})}return c(e,t,n)}:c:function(e,t,n){if(o(e),t=l(t),o(n),r)try{return c(e,t,n)}catch(e){}if("get"in n||"set"in n)throw s("Accessors not supported");return"value"in n&&(e[t]=n.value),e}},function(e,t,n){"use strict";var a=n(2),r=a({}.toString),i=a("".slice);e.exports=function(e){return i(r(e),8,-1)}},function(e,t,n){var a=n(154),r=n(155),i=n(156),o=n(157),l=n(158);function s(e){var t=-1,n=null==e?0:e.length;for(this.clear();++t
'};function r(e,t,n){return en?n:e}function i(e){return 100*(-1+e)}n.configure=function(e){var t,n;for(t in e)void 0!==(n=e[t])&&e.hasOwnProperty(t)&&(a[t]=n);return this},n.status=null,n.set=function(e){var t=n.isStarted();e=r(e,a.minimum,1),n.status=1===e?null:e;var s=n.render(!t),c=s.querySelector(a.barSelector),u=a.speed,p=a.easing;return s.offsetWidth,o((function(t){""===a.positionUsing&&(a.positionUsing=n.getPositioningCSS()),l(c,function(e,t,n){var r;return(r="translate3d"===a.positionUsing?{transform:"translate3d("+i(e)+"%,0,0)"}:"translate"===a.positionUsing?{transform:"translate("+i(e)+"%,0)"}:{"margin-left":i(e)+"%"}).transition="all "+t+"ms "+n,r}(e,u,p)),1===e?(l(s,{transition:"none",opacity:1}),s.offsetWidth,setTimeout((function(){l(s,{transition:"all "+u+"ms linear",opacity:0}),setTimeout((function(){n.remove(),t()}),u)}),u)):setTimeout(t,u)})),this},n.isStarted=function(){return"number"==typeof n.status},n.start=function(){n.status||n.set(0);var e=function(){setTimeout((function(){n.status&&(n.trickle(),e())}),a.trickleSpeed)};return a.trickle&&e(),this},n.done=function(e){return e||n.status?n.inc(.3+.5*Math.random()).set(1):this},n.inc=function(e){var t=n.status;return t?("number"!=typeof e&&(e=(1-t)*r(Math.random()*t,.1,.95)),t=r(t+e,0,.994),n.set(t)):n.start()},n.trickle=function(){return n.inc(Math.random()*a.trickleRate)},e=0,t=0,n.promise=function(a){return a&&"resolved"!==a.state()?(0===t&&n.start(),e++,t++,a.always((function(){0==--t?(e=0,n.done()):n.set((e-t)/e)})),this):this},n.render=function(e){if(n.isRendered())return document.getElementById("nprogress");c(document.documentElement,"nprogress-busy");var t=document.createElement("div");t.id="nprogress",t.innerHTML=a.template;var r,o=t.querySelector(a.barSelector),s=e?"-100":i(n.status||0),u=document.querySelector(a.parent);return l(o,{transition:"all 0 linear",transform:"translate3d("+s+"%,0,0)"}),a.showSpinner||(r=t.querySelector(a.spinnerSelector))&&d(r),u!=document.body&&c(u,"nprogress-custom-parent"),u.appendChild(t),t},n.remove=function(){u(document.documentElement,"nprogress-busy"),u(document.querySelector(a.parent),"nprogress-custom-parent");var e=document.getElementById("nprogress");e&&d(e)},n.isRendered=function(){return!!document.getElementById("nprogress")},n.getPositioningCSS=function(){var e=document.body.style,t="WebkitTransform"in e?"Webkit":"MozTransform"in e?"Moz":"msTransform"in e?"ms":"OTransform"in e?"O":"";return t+"Perspective"in e?"translate3d":t+"Transform"in e?"translate":"margin"};var o=function(){var e=[];function t(){var n=e.shift();n&&n(t)}return function(n){e.push(n),1==e.length&&t()}}(),l=function(){var e=["Webkit","O","Moz","ms"],t={};function n(n){return n=n.replace(/^-ms-/,"ms-").replace(/-([\da-z])/gi,(function(e,t){return t.toUpperCase()})),t[n]||(t[n]=function(t){var n=document.body.style;if(t in n)return t;for(var a,r=e.length,i=t.charAt(0).toUpperCase()+t.slice(1);r--;)if((a=e[r]+i)in n)return a;return t}(n))}function a(e,t,a){t=n(t),e.style[t]=a}return function(e,t){var n,r,i=arguments;if(2==i.length)for(n in t)void 0!==(r=t[n])&&t.hasOwnProperty(n)&&a(e,n,r);else a(e,i[1],i[2])}}();function s(e,t){return("string"==typeof e?e:p(e)).indexOf(" "+t+" ")>=0}function c(e,t){var n=p(e),a=n+t;s(n,t)||(e.className=a.substring(1))}function u(e,t){var n,a=p(e);s(e,t)&&(n=a.replace(" "+t+" "," "),e.className=n.substring(1,n.length-1))}function p(e){return(" "+(e.className||"")+" ").replace(/\s+/gi," ")}function d(e){e&&e.parentNode&&e.parentNode.removeChild(e)}return n})?a.call(t,n,t,e):a)||(e.exports=r)},function(e,t,n){"use strict";var a=n(26),r=n(36),i=n(38),o=n(129),l=n(131);a({target:"Array",proto:!0,arity:1,forced:n(3)((function(){return 4294967297!==[].push.call({length:4294967296},1)}))||!function(){try{Object.defineProperty([],"length",{writable:!1}).push()}catch(e){return e instanceof TypeError}}()},{push:function(e){var t=r(this),n=i(t),a=arguments.length;l(n+a);for(var s=0;s-1&&e%1==0&&e<=9007199254740991}},function(e,t,n){var a=n(5),r=n(46),i=/\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,o=/^\w*$/;e.exports=function(e,t){if(a(e))return!1;var n=typeof e;return!("number"!=n&&"symbol"!=n&&"boolean"!=n&&null!=e&&!r(e))||(o.test(e)||!i.test(e)||null!=t&&e in Object(t))}},function(e,t,n){var a=n(13),r=n(12);e.exports=function(e){return"symbol"==typeof e||r(e)&&"[object Symbol]"==a(e)}},function(e,t){e.exports=function(e){return e}},function(e,t){e.exports=function(e){return e.webpackPolyfill||(e.deprecate=function(){},e.paths=[],e.children||(e.children=[]),Object.defineProperty(e,"loaded",{enumerable:!0,get:function(){return e.l}}),Object.defineProperty(e,"id",{enumerable:!0,get:function(){return e.i}}),e.webpackPolyfill=1),e}},function(e,t,n){"use strict";var a=n(6),r=n(27),i=n(103),o=n(29),l=n(30),s=n(53),c=n(8),u=n(63),p=Object.getOwnPropertyDescriptor;t.f=a?p:function(e,t){if(e=l(e),t=s(t),u)try{return p(e,t)}catch(e){}if(c(e,t))return o(!r(i.f,e,t),e[t])}},function(e,t,n){"use strict";var a=n(2),r=n(3),i=n(18),o=Object,l=a("".split);e.exports=r((function(){return!o("z").propertyIsEnumerable(0)}))?function(e){return"String"===i(e)?l(e,""):o(e)}:o},function(e,t,n){"use strict";var a=n(52),r=TypeError;e.exports=function(e){if(a(e))throw r("Can't call method on "+e);return e}},function(e,t,n){"use strict";e.exports=function(e){return null==e}},function(e,t,n){"use strict";var a=n(104),r=n(55);e.exports=function(e){var t=a(e,"string");return r(t)?t:t+""}},function(e,t,n){"use strict";var a="object"==typeof document&&document.all,r=void 0===a&&void 0!==a;e.exports={all:a,IS_HTMLDDA:r}},function(e,t,n){"use strict";var a=n(31),r=n(0),i=n(56),o=n(57),l=Object;e.exports=o?function(e){return"symbol"==typeof e}:function(e){var t=a("Symbol");return r(t)&&i(t.prototype,l(e))}},function(e,t,n){"use strict";var a=n(2);e.exports=a({}.isPrototypeOf)},function(e,t,n){"use strict";var a=n(58);e.exports=a&&!Symbol.sham&&"symbol"==typeof Symbol.iterator},function(e,t,n){"use strict";var a=n(59),r=n(3),i=n(1).String;e.exports=!!Object.getOwnPropertySymbols&&!r((function(){var e=Symbol("symbol detection");return!i(e)||!(Object(e)instanceof Symbol)||!Symbol.sham&&a&&a<41}))},function(e,t,n){"use strict";var a,r,i=n(1),o=n(105),l=i.process,s=i.Deno,c=l&&l.versions||s&&s.version,u=c&&c.v8;u&&(r=(a=u.split("."))[0]>0&&a[0]<4?1:+(a[0]+a[1])),!r&&o&&(!(a=o.match(/Edge\/(\d+)/))||a[1]>=74)&&(a=o.match(/Chrome\/(\d+)/))&&(r=+a[1]),e.exports=r},function(e,t,n){"use strict";var a=n(61),r=n(34);(e.exports=function(e,t){return r[e]||(r[e]=void 0!==t?t:{})})("versions",[]).push({version:"3.32.2",mode:a?"pure":"global",copyright:"© 2014-2023 Denis Pushkarev (zloirock.ru)",license:"https://github.com/zloirock/core-js/blob/v3.32.2/LICENSE",source:"https://github.com/zloirock/core-js"})},function(e,t,n){"use strict";e.exports=!1},function(e,t,n){"use strict";var a=n(2),r=0,i=Math.random(),o=a(1..toString);e.exports=function(e){return"Symbol("+(void 0===e?"":e)+")_"+o(++r+i,36)}},function(e,t,n){"use strict";var a=n(6),r=n(3),i=n(109);e.exports=!a&&!r((function(){return 7!==Object.defineProperty(i("div"),"a",{get:function(){return 7}}).a}))},function(e,t,n){"use strict";e.exports={}},function(e,t,n){"use strict";var a=n(8),r=n(116),i=n(49),o=n(17);e.exports=function(e,t,n){for(var l=r(t),s=o.f,c=i.f,u=0;uu))return!1;var d=s.get(e),h=s.get(t);if(d&&h)return d==t&&h==e;var f=-1,m=!0,g=2&n?new a:void 0;for(s.set(e,t),s.set(t,e);++f-1&&e%1==0&&e]/;e.exports=function(e){var t,n=""+e,r=a.exec(n);if(!r)return n;var i="",o=0,l=0;for(o=r.index;o({codeTabs:[],activeCodeTabIndex:-1}),watch:{activeCodeTabIndex(e){this.codeTabs.forEach(e=>{e.elm.classList.remove("theme-code-block__active")}),this.codeTabs[e].elm.classList.add("theme-code-block__active")}},mounted(){this.codeTabs=(this.$slots.default||[]).filter(e=>Boolean(e.componentOptions)).map((e,t)=>(""===e.componentOptions.propsData.active&&(this.activeCodeTabIndex=t),{title:e.componentOptions.propsData.title,elm:e.elm})),-1===this.activeCodeTabIndex&&this.codeTabs.length>0&&(this.activeCodeTabIndex=0)},methods:{changeCodeTab(e){this.activeCodeTabIndex=e}}},r=(n(244),n(4)),i=Object(r.a)(a,(function(){var e=this,t=e._self._c;return t("div",{staticClass:"theme-code-group"},[t("div",{staticClass:"theme-code-group__nav"},[t("ul",{staticClass:"theme-code-group__ul"},e._l(e.codeTabs,(function(n,a){return t("li",{key:n.title,staticClass:"theme-code-group__li"},[t("button",{staticClass:"theme-code-group__nav-tab",class:{"theme-code-group__nav-tab-active":a===e.activeCodeTabIndex},on:{click:function(t){return e.changeCodeTab(a)}}},[e._v("\n "+e._s(n.title)+"\n ")])])})),0)]),e._v(" "),e._t("default"),e._v(" "),e.codeTabs.length<1?t("pre",{staticClass:"pre-blank"},[e._v("// Make sure to add code blocks to your code group")]):e._e()],2)}),[],!1,null,"2f5f1757",null);t.default=i.exports},function(e,t){e.exports=function(e){var t=null==e?0:e.length;return t?e[t-1]:void 0}},function(e,t,n){"use strict";var a=n(0),r=n(17),i=n(100),o=n(35);e.exports=function(e,t,n,l){l||(l={});var s=l.enumerable,c=void 0!==l.name?l.name:t;if(a(n)&&i(n,c,l),l.global)s?e[t]=n:o(t,n);else{try{l.unsafe?e[t]&&(s=!0):delete e[t]}catch(e){}s?e[t]=n:r.f(e,t,{value:n,enumerable:!1,configurable:!l.nonConfigurable,writable:!l.nonWritable})}return e}},function(e,t,n){"use strict";var a=n(140),r=String;e.exports=function(e){if("Symbol"===a(e))throw TypeError("Cannot convert a Symbol value to a string");return r(e)}},function(e,t,n){"use strict";var a=n(2),r=n(3),i=n(0),o=n(8),l=n(6),s=n(111).CONFIGURABLE,c=n(112),u=n(113),p=u.enforce,d=u.get,h=String,f=Object.defineProperty,m=a("".slice),g=a("".replace),v=a([].join),b=l&&!r((function(){return 8!==f((function(){}),"length",{value:8}).length})),y=String(String).split("String"),k=e.exports=function(e,t,n){"Symbol("===m(h(t),0,7)&&(t="["+g(h(t),/^Symbol\(([^)]*)\)/,"$1")+"]"),n&&n.getter&&(t="get "+t),n&&n.setter&&(t="set "+t),(!o(e,"name")||s&&e.name!==t)&&(l?f(e,"name",{value:t,configurable:!0}):e.name=t),b&&n&&o(n,"arity")&&e.length!==n.arity&&f(e,"length",{value:n.arity});try{n&&o(n,"constructor")&&n.constructor?l&&f(e,"prototype",{writable:!1}):e.prototype&&(e.prototype=void 0)}catch(e){}var a=p(e);return o(a,"source")||(a.source=v(y,"string"==typeof t?t:"")),e};Function.prototype.toString=k((function(){return i(this)&&d(this).source||c(this)}),"toString")},function(e,t,n){e.exports=n(250)},function(e,t,n){"use strict";var a=n(26),r=n(126).left,i=n(127),o=n(59);a({target:"Array",proto:!0,forced:!n(128)&&o>79&&o<83||!i("reduce")},{reduce:function(e){var t=arguments.length;return r(this,e,t,t>1?arguments[1]:void 0)}})},function(e,t,n){"use strict";var a={}.propertyIsEnumerable,r=Object.getOwnPropertyDescriptor,i=r&&!a.call({1:2},1);t.f=i?function(e){var t=r(this,e);return!!t&&t.enumerable}:a},function(e,t,n){"use strict";var a=n(27),r=n(9),i=n(55),o=n(106),l=n(108),s=n(33),c=TypeError,u=s("toPrimitive");e.exports=function(e,t){if(!r(e)||i(e))return e;var n,s=o(e,u);if(s){if(void 0===t&&(t="default"),n=a(s,e,t),!r(n)||i(n))return n;throw c("Can't convert object to primitive value")}return void 0===t&&(t="number"),l(e,t)}},function(e,t,n){"use strict";e.exports="undefined"!=typeof navigator&&String(navigator.userAgent)||""},function(e,t,n){"use strict";var a=n(32),r=n(52);e.exports=function(e,t){var n=e[t];return r(n)?void 0:a(n)}},function(e,t,n){"use strict";var a=String;e.exports=function(e){try{return a(e)}catch(e){return"Object"}}},function(e,t,n){"use strict";var a=n(27),r=n(0),i=n(9),o=TypeError;e.exports=function(e,t){var n,l;if("string"===t&&r(n=e.toString)&&!i(l=a(n,e)))return l;if(r(n=e.valueOf)&&!i(l=a(n,e)))return l;if("string"!==t&&r(n=e.toString)&&!i(l=a(n,e)))return l;throw o("Can't convert object to primitive value")}},function(e,t,n){"use strict";var a=n(1),r=n(9),i=a.document,o=r(i)&&r(i.createElement);e.exports=function(e){return o?i.createElement(e):{}}},function(e,t,n){"use strict";var a=n(6),r=n(3);e.exports=a&&r((function(){return 42!==Object.defineProperty((function(){}),"prototype",{value:42,writable:!1}).prototype}))},function(e,t,n){"use strict";var a=n(6),r=n(8),i=Function.prototype,o=a&&Object.getOwnPropertyDescriptor,l=r(i,"name"),s=l&&"something"===function(){}.name,c=l&&(!a||a&&o(i,"name").configurable);e.exports={EXISTS:l,PROPER:s,CONFIGURABLE:c}},function(e,t,n){"use strict";var a=n(2),r=n(0),i=n(34),o=a(Function.toString);r(i.inspectSource)||(i.inspectSource=function(e){return o(e)}),e.exports=i.inspectSource},function(e,t,n){"use strict";var a,r,i,o=n(114),l=n(1),s=n(9),c=n(14),u=n(8),p=n(34),d=n(115),h=n(64),f=l.TypeError,m=l.WeakMap;if(o||p.state){var g=p.state||(p.state=new m);g.get=g.get,g.has=g.has,g.set=g.set,a=function(e,t){if(g.has(e))throw f("Object already initialized");return t.facade=e,g.set(e,t),t},r=function(e){return g.get(e)||{}},i=function(e){return g.has(e)}}else{var v=d("state");h[v]=!0,a=function(e,t){if(u(e,v))throw f("Object already initialized");return t.facade=e,c(e,v,t),t},r=function(e){return u(e,v)?e[v]:{}},i=function(e){return u(e,v)}}e.exports={set:a,get:r,has:i,enforce:function(e){return i(e)?r(e):a(e,{})},getterFor:function(e){return function(t){var n;if(!s(t)||(n=r(t)).type!==e)throw f("Incompatible receiver, "+e+" required");return n}}}},function(e,t,n){"use strict";var a=n(1),r=n(0),i=a.WeakMap;e.exports=r(i)&&/native code/.test(String(i))},function(e,t,n){"use strict";var a=n(60),r=n(62),i=a("keys");e.exports=function(e){return i[e]||(i[e]=r(e))}},function(e,t,n){"use strict";var a=n(31),r=n(2),i=n(117),o=n(124),l=n(37),s=r([].concat);e.exports=a("Reflect","ownKeys")||function(e){var t=i.f(l(e)),n=o.f;return n?s(t,n(e)):t}},function(e,t,n){"use strict";var a=n(118),r=n(123).concat("length","prototype");t.f=Object.getOwnPropertyNames||function(e){return a(e,r)}},function(e,t,n){"use strict";var a=n(2),r=n(8),i=n(30),o=n(119).indexOf,l=n(64),s=a([].push);e.exports=function(e,t){var n,a=i(e),c=0,u=[];for(n in a)!r(l,n)&&r(a,n)&&s(u,n);for(;t.length>c;)r(a,n=t[c++])&&(~o(u,n)||s(u,n));return u}},function(e,t,n){"use strict";var a=n(30),r=n(120),i=n(38),o=function(e){return function(t,n,o){var l,s=a(t),c=i(s),u=r(o,c);if(e&&n!=n){for(;c>u;)if((l=s[u++])!=l)return!0}else for(;c>u;u++)if((e||u in s)&&s[u]===n)return e||u||0;return!e&&-1}};e.exports={includes:o(!0),indexOf:o(!1)}},function(e,t,n){"use strict";var a=n(66),r=Math.max,i=Math.min;e.exports=function(e,t){var n=a(e);return n<0?r(n+t,0):i(n,t)}},function(e,t,n){"use strict";var a=Math.ceil,r=Math.floor;e.exports=Math.trunc||function(e){var t=+e;return(t>0?r:a)(t)}},function(e,t,n){"use strict";var a=n(66),r=Math.min;e.exports=function(e){return e>0?r(a(e),9007199254740991):0}},function(e,t,n){"use strict";e.exports=["constructor","hasOwnProperty","isPrototypeOf","propertyIsEnumerable","toLocaleString","toString","valueOf"]},function(e,t,n){"use strict";t.f=Object.getOwnPropertySymbols},function(e,t,n){"use strict";var a=n(3),r=n(0),i=/#|\.prototype\./,o=function(e,t){var n=s[l(e)];return n===u||n!==c&&(r(t)?a(t):!!t)},l=o.normalize=function(e){return String(e).replace(i,".").toLowerCase()},s=o.data={},c=o.NATIVE="N",u=o.POLYFILL="P";e.exports=o},function(e,t,n){"use strict";var a=n(32),r=n(36),i=n(50),o=n(38),l=TypeError,s=function(e){return function(t,n,s,c){a(n);var u=r(t),p=i(u),d=o(u),h=e?d-1:0,f=e?-1:1;if(s<2)for(;;){if(h in p){c=p[h],h+=f;break}if(h+=f,e?h<0:d<=h)throw l("Reduce of empty array with no initial value")}for(;e?h>=0:d>h;h+=f)h in p&&(c=n(c,p[h],h,u));return c}};e.exports={left:s(!1),right:s(!0)}},function(e,t,n){"use strict";var a=n(3);e.exports=function(e,t){var n=[][e];return!!n&&a((function(){n.call(null,t||function(){return 1},1)}))}},function(e,t,n){"use strict";var a=n(1),r=n(18);e.exports="process"===r(a.process)},function(e,t,n){"use strict";var a=n(6),r=n(130),i=TypeError,o=Object.getOwnPropertyDescriptor,l=a&&!function(){if(void 0!==this)return!0;try{Object.defineProperty([],"length",{writable:!1}).length=1}catch(e){return e instanceof TypeError}}();e.exports=l?function(e,t){if(r(e)&&!o(e,"length").writable)throw i("Cannot set read only .length");return e.length=t}:function(e,t){return e.length=t}},function(e,t,n){"use strict";var a=n(18);e.exports=Array.isArray||function(e){return"Array"===a(e)}},function(e,t,n){"use strict";var a=TypeError;e.exports=function(e){if(e>9007199254740991)throw a("Maximum allowed index exceeded");return e}},function(e,t,n){"use strict";var a=n(26),r=n(1),i=n(133),o=n(134),l=r.WebAssembly,s=7!==Error("e",{cause:7}).cause,c=function(e,t){var n={};n[e]=o(e,t,s),a({global:!0,constructor:!0,arity:1,forced:s},n)},u=function(e,t){if(l&&l[e]){var n={};n[e]=o("WebAssembly."+e,t,s),a({target:"WebAssembly",stat:!0,constructor:!0,arity:1,forced:s},n)}};c("Error",(function(e){return function(t){return i(e,this,arguments)}})),c("EvalError",(function(e){return function(t){return i(e,this,arguments)}})),c("RangeError",(function(e){return function(t){return i(e,this,arguments)}})),c("ReferenceError",(function(e){return function(t){return i(e,this,arguments)}})),c("SyntaxError",(function(e){return function(t){return i(e,this,arguments)}})),c("TypeError",(function(e){return function(t){return i(e,this,arguments)}})),c("URIError",(function(e){return function(t){return i(e,this,arguments)}})),u("CompileError",(function(e){return function(t){return i(e,this,arguments)}})),u("LinkError",(function(e){return function(t){return i(e,this,arguments)}})),u("RuntimeError",(function(e){return function(t){return i(e,this,arguments)}}))},function(e,t,n){"use strict";var a=n(28),r=Function.prototype,i=r.apply,o=r.call;e.exports="object"==typeof Reflect&&Reflect.apply||(a?o.bind(i):function(){return o.apply(i,arguments)})},function(e,t,n){"use strict";var a=n(31),r=n(8),i=n(14),o=n(56),l=n(67),s=n(65),c=n(137),u=n(138),p=n(139),d=n(142),h=n(143),f=n(6),m=n(61);e.exports=function(e,t,n,g){var v=g?2:1,b=e.split("."),y=b[b.length-1],k=a.apply(null,b);if(k){var E=k.prototype;if(!m&&r(E,"cause")&&delete E.cause,!n)return k;var _=a("Error"),x=t((function(e,t){var n=p(g?t:e,void 0),a=g?new k(e):new k;return void 0!==n&&i(a,"message",n),h(a,x,a.stack,2),this&&o(E,this)&&u(a,this,x),arguments.length>v&&d(a,arguments[v]),a}));if(x.prototype=E,"Error"!==y?l?l(x,_):s(x,_,{name:!0}):f&&"stackTraceLimit"in k&&(c(x,k,"stackTraceLimit"),c(x,k,"prepareStackTrace")),s(x,k),!m)try{E.name!==y&&i(E,"name",y),E.constructor=x}catch(e){}return x}}},function(e,t,n){"use strict";var a=n(2),r=n(32);e.exports=function(e,t,n){try{return a(r(Object.getOwnPropertyDescriptor(e,t)[n]))}catch(e){}}},function(e,t,n){"use strict";var a=n(0),r=String,i=TypeError;e.exports=function(e){if("object"==typeof e||a(e))return e;throw i("Can't set "+r(e)+" as a prototype")}},function(e,t,n){"use strict";var a=n(17).f;e.exports=function(e,t,n){n in e||a(e,n,{configurable:!0,get:function(){return t[n]},set:function(e){t[n]=e}})}},function(e,t,n){"use strict";var a=n(0),r=n(9),i=n(67);e.exports=function(e,t,n){var o,l;return i&&a(o=t.constructor)&&o!==n&&r(l=o.prototype)&&l!==n.prototype&&i(e,l),e}},function(e,t,n){"use strict";var a=n(99);e.exports=function(e,t){return void 0===e?arguments.length<2?"":t:a(e)}},function(e,t,n){"use strict";var a=n(141),r=n(0),i=n(18),o=n(33)("toStringTag"),l=Object,s="Arguments"===i(function(){return arguments}());e.exports=a?i:function(e){var t,n,a;return void 0===e?"Undefined":null===e?"Null":"string"==typeof(n=function(e,t){try{return e[t]}catch(e){}}(t=l(e),o))?n:s?i(t):"Object"===(a=i(t))&&r(t.callee)?"Arguments":a}},function(e,t,n){"use strict";var a={};a[n(33)("toStringTag")]="z",e.exports="[object z]"===String(a)},function(e,t,n){"use strict";var a=n(9),r=n(14);e.exports=function(e,t){a(t)&&"cause"in t&&r(e,"cause",t.cause)}},function(e,t,n){"use strict";var a=n(14),r=n(144),i=n(145),o=Error.captureStackTrace;e.exports=function(e,t,n,l){i&&(o?o(e,t):a(e,"stack",r(n,l)))}},function(e,t,n){"use strict";var a=n(2),r=Error,i=a("".replace),o=String(r("zxcasd").stack),l=/\n\s*at [^:]*:[^\n]*/,s=l.test(o);e.exports=function(e,t){if(s&&"string"==typeof e&&!r.prepareStackTrace)for(;t--;)e=i(e,l,"");return e}},function(e,t,n){"use strict";var a=n(3),r=n(29);e.exports=!a((function(){var e=Error("a");return!("stack"in e)||(Object.defineProperty(e,"stack",r(1,7)),7!==e.stack)}))},function(e,t,n){var a=n(68),r=n(147);e.exports=function e(t,n,i,o,l){var s=-1,c=t.length;for(i||(i=r),l||(l=[]);++s0&&i(u)?n>1?e(u,n-1,i,o,l):a(l,u):o||(l[l.length]=u)}return l}},function(e,t,n){var a=n(15),r=n(39),i=n(5),o=a?a.isConcatSpreadable:void 0;e.exports=function(e){return i(e)||r(e)||!!(o&&e&&e[o])}},function(e,t,n){var a=n(13),r=n(12);e.exports=function(e){return r(e)&&"[object Arguments]"==a(e)}},function(e,t,n){var a=n(15),r=Object.prototype,i=r.hasOwnProperty,o=r.toString,l=a?a.toStringTag:void 0;e.exports=function(e){var t=i.call(e,l),n=e[l];try{e[l]=void 0;var a=!0}catch(e){}var r=o.call(e);return a&&(t?e[l]=n:delete e[l]),r}},function(e,t){var n=Object.prototype.toString;e.exports=function(e){return n.call(e)}},function(e,t,n){var a=n(152),r=n(208),i=n(47),o=n(5),l=n(219);e.exports=function(e){return"function"==typeof e?e:null==e?i:"object"==typeof e?o(e)?r(e[0],e[1]):a(e):l(e)}},function(e,t,n){var a=n(153),r=n(207),i=n(85);e.exports=function(e){var t=r(e);return 1==t.length&&t[0][2]?i(t[0][0],t[0][1]):function(n){return n===e||a(n,e,t)}}},function(e,t,n){var a=n(70),r=n(74);e.exports=function(e,t,n,i){var o=n.length,l=o,s=!i;if(null==e)return!l;for(e=Object(e);o--;){var c=n[o];if(s&&c[2]?c[1]!==e[c[0]]:!(c[0]in e))return!1}for(;++o-1}},function(e,t,n){var a=n(20);e.exports=function(e,t){var n=this.__data__,r=a(n,e);return r<0?(++this.size,n.push([e,t])):n[r][1]=t,this}},function(e,t,n){var a=n(19);e.exports=function(){this.__data__=new a,this.size=0}},function(e,t){e.exports=function(e){var t=this.__data__,n=t.delete(e);return this.size=t.size,n}},function(e,t){e.exports=function(e){return this.__data__.get(e)}},function(e,t){e.exports=function(e){return this.__data__.has(e)}},function(e,t,n){var a=n(19),r=n(40),i=n(42);e.exports=function(e,t){var n=this.__data__;if(n instanceof a){var o=n.__data__;if(!r||o.length<199)return o.push([e,t]),this.size=++n.size,this;n=this.__data__=new i(o)}return n.set(e,t),this.size=n.size,this}},function(e,t,n){var a=n(72),r=n(165),i=n(41),o=n(73),l=/^\[object .+?Constructor\]$/,s=Function.prototype,c=Object.prototype,u=s.toString,p=c.hasOwnProperty,d=RegExp("^"+u.call(p).replace(/[\\^$.*+?()[\]{}|]/g,"\\$&").replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g,"$1.*?")+"$");e.exports=function(e){return!(!i(e)||r(e))&&(a(e)?d:l).test(o(e))}},function(e,t,n){var a,r=n(166),i=(a=/[^.]+$/.exec(r&&r.keys&&r.keys.IE_PROTO||""))?"Symbol(src)_1."+a:"";e.exports=function(e){return!!i&&i in e}},function(e,t,n){var a=n(7)["__core-js_shared__"];e.exports=a},function(e,t){e.exports=function(e,t){return null==e?void 0:e[t]}},function(e,t,n){var a=n(169),r=n(19),i=n(40);e.exports=function(){this.size=0,this.__data__={hash:new a,map:new(i||r),string:new a}}},function(e,t,n){var a=n(170),r=n(171),i=n(172),o=n(173),l=n(174);function s(e){var t=-1,n=null==e?0:e.length;for(this.clear();++t0){if(++t>=800)return arguments[0]}else t=0;return e.apply(void 0,arguments)}}},function(e,t,n){var a=n(76),r=n(231),i=n(236),o=n(77),l=n(237),s=n(43);e.exports=function(e,t,n){var c=-1,u=r,p=e.length,d=!0,h=[],f=h;if(n)d=!1,u=i;else if(p>=200){var m=t?null:l(e);if(m)return s(m);d=!1,u=o,f=new a}else f=t?[]:h;e:for(;++c-1}},function(e,t,n){var a=n(233),r=n(234),i=n(235);e.exports=function(e,t,n){return t==t?i(e,t,n):a(e,r,n)}},function(e,t){e.exports=function(e,t,n,a){for(var r=e.length,i=n+(a?1:-1);a?i--:++i=0&&Math.floor(t)===t&&isFinite(e)}function m(e){return o(e)&&"function"==typeof e.then&&"function"==typeof e.catch}function g(e){return null==e?"":Array.isArray(e)||d(e)&&e.toString===p?JSON.stringify(e,null,2):String(e)}function v(e){var t=parseFloat(e);return isNaN(t)?e:t}function b(e,t){for(var n=Object.create(null),a=e.split(","),r=0;r-1)return e.splice(a,1)}}var E=Object.prototype.hasOwnProperty;function _(e,t){return E.call(e,t)}function x(e){var t=Object.create(null);return function(n){return t[n]||(t[n]=e(n))}}var w=/-(\w)/g,A=x((function(e){return e.replace(w,(function(e,t){return t?t.toUpperCase():""}))})),j=x((function(e){return e.charAt(0).toUpperCase()+e.slice(1)})),B=/\B([A-Z])/g,T=x((function(e){return e.replace(B,"-$1").toLowerCase()}));var P=Function.prototype.bind?function(e,t){return e.bind(t)}:function(e,t){function n(n){var a=arguments.length;return a?a>1?e.apply(t,arguments):e.call(t,n):e.call(t)}return n._length=e.length,n};function C(e,t){t=t||0;for(var n=e.length-t,a=new Array(n);n--;)a[n]=e[n+t];return a}function O(e,t){for(var n in t)e[n]=t[n];return e}function S(e){for(var t={},n=0;n0,X=G&&G.indexOf("edge/")>0;G&&G.indexOf("android");var Q=G&&/iphone|ipad|ipod|ios/.test(G);G&&/chrome\/\d+/.test(G),G&&/phantomjs/.test(G);var ee,te=G&&G.match(/firefox\/(\d+)/),ne={}.watch,ae=!1;if(W)try{var re={};Object.defineProperty(re,"passive",{get:function(){ae=!0}}),window.addEventListener("test-passive",null,re)}catch(e){}var ie=function(){return void 0===ee&&(ee=!W&&"undefined"!=typeof global&&(global.process&&"server"===global.process.env.VUE_ENV)),ee},oe=W&&window.__VUE_DEVTOOLS_GLOBAL_HOOK__;function le(e){return"function"==typeof e&&/native code/.test(e.toString())}var se,ce="undefined"!=typeof Symbol&&le(Symbol)&&"undefined"!=typeof Reflect&&le(Reflect.ownKeys);se="undefined"!=typeof Set&&le(Set)?Set:function(){function e(){this.set=Object.create(null)}return e.prototype.has=function(e){return!0===this.set[e]},e.prototype.add=function(e){this.set[e]=!0},e.prototype.clear=function(){this.set=Object.create(null)},e}();var ue=null;function pe(e){void 0===e&&(e=null),e||ue&&ue._scope.off(),ue=e,e&&e._scope.on()}var de=function(){function e(e,t,n,a,r,i,o,l){this.tag=e,this.data=t,this.children=n,this.text=a,this.elm=r,this.ns=void 0,this.context=i,this.fnContext=void 0,this.fnOptions=void 0,this.fnScopeId=void 0,this.key=t&&t.key,this.componentOptions=o,this.componentInstance=void 0,this.parent=void 0,this.raw=!1,this.isStatic=!1,this.isRootInsert=!0,this.isComment=!1,this.isCloned=!1,this.isOnce=!1,this.asyncFactory=l,this.asyncMeta=void 0,this.isAsyncPlaceholder=!1}return Object.defineProperty(e.prototype,"child",{get:function(){return this.componentInstance},enumerable:!1,configurable:!0}),e}(),he=function(e){void 0===e&&(e="");var t=new de;return t.text=e,t.isComment=!0,t};function fe(e){return new de(void 0,void 0,void 0,String(e))}function me(e){var t=new de(e.tag,e.data,e.children&&e.children.slice(),e.text,e.elm,e.context,e.componentOptions,e.asyncFactory);return t.ns=e.ns,t.isStatic=e.isStatic,t.key=e.key,t.isComment=e.isComment,t.fnContext=e.fnContext,t.fnOptions=e.fnOptions,t.fnScopeId=e.fnScopeId,t.asyncMeta=e.asyncMeta,t.isCloned=!0,t}var ge=0,ve=[],be=function(){function e(){this._pending=!1,this.id=ge++,this.subs=[]}return e.prototype.addSub=function(e){this.subs.push(e)},e.prototype.removeSub=function(e){this.subs[this.subs.indexOf(e)]=null,this._pending||(this._pending=!0,ve.push(this))},e.prototype.depend=function(t){e.target&&e.target.addDep(this)},e.prototype.notify=function(e){var t=this.subs.filter((function(e){return e}));for(var n=0,a=t.length;n0&&(Ge((c=e(c,"".concat(n||"","_").concat(a)))[0])&&Ge(p)&&(d[u]=fe(p.text+c[0].text),c.shift()),d.push.apply(d,c)):s(c)?Ge(p)?d[u]=fe(p.text+c):""!==c&&d.push(fe(c)):Ge(c)&&Ge(p)?d[u]=fe(p.text+c.text):(l(t._isVList)&&o(c.tag)&&i(c.key)&&o(n)&&(c.key="__vlist".concat(n,"_").concat(a,"__")),d.push(c)));return d}(e):void 0}function Ge(e){return o(e)&&o(e.text)&&!1===e.isComment}function Ke(e,t){var n,a,i,l,s=null;if(r(e)||"string"==typeof e)for(s=new Array(e.length),n=0,a=e.length;n0,l=t?!!t.$stable:!o,s=t&&t.$key;if(t){if(t._normalized)return t._normalized;if(l&&r&&r!==a&&s===r.$key&&!o&&!r.$hasNormal)return r;for(var c in i={},t)t[c]&&"$"!==c[0]&&(i[c]=mt(e,n,c,t[c]))}else i={};for(var u in n)u in i||(i[u]=gt(n,u));return t&&Object.isExtensible(t)&&(t._normalized=i),H(i,"$stable",l),H(i,"$key",s),H(i,"$hasNormal",o),i}function mt(e,t,n,a){var i=function(){var t=ue;pe(e);var n=arguments.length?a.apply(null,arguments):a({}),i=(n=n&&"object"==typeof n&&!r(n)?[n]:We(n))&&n[0];return pe(t),n&&(!i||1===n.length&&i.isComment&&!ht(i))?void 0:n};return a.proxy&&Object.defineProperty(t,n,{get:i,enumerable:!0,configurable:!0}),i}function gt(e,t){return function(){return e[t]}}function vt(e){return{get attrs(){if(!e._attrsProxy){var t=e._attrsProxy={};H(t,"_v_attr_proxy",!0),bt(t,e.$attrs,a,e,"$attrs")}return e._attrsProxy},get listeners(){e._listenersProxy||bt(e._listenersProxy={},e.$listeners,a,e,"$listeners");return e._listenersProxy},get slots(){return function(e){e._slotsProxy||kt(e._slotsProxy={},e.$scopedSlots);return e._slotsProxy}(e)},emit:P(e.$emit,e),expose:function(t){t&&Object.keys(t).forEach((function(n){return Me(e,t,n)}))}}}function bt(e,t,n,a,r){var i=!1;for(var o in t)o in e?t[o]!==n[o]&&(i=!0):(i=!0,yt(e,o,a,r));for(var o in e)o in t||(i=!0,delete e[o]);return i}function yt(e,t,n,a){Object.defineProperty(e,t,{enumerable:!0,configurable:!0,get:function(){return n[a][t]}})}function kt(e,t){for(var n in t)e[n]=t[n];for(var n in e)n in t||delete e[n]}var Et=null;function _t(e,t){return(e.__esModule||ce&&"Module"===e[Symbol.toStringTag])&&(e=e.default),u(e)?t.extend(e):e}function xt(e){if(r(e))for(var t=0;tdocument.createEvent("Event").timeStamp&&(sn=function(){return cn.now()})}var un=function(e,t){if(e.post){if(!t.post)return 1}else if(t.post)return-1;return e.id-t.id};function pn(){var e,t;for(ln=sn(),rn=!0,en.sort(un),on=0;onon&&en[n].id>e.id;)n--;en.splice(n+1,0,e)}else en.push(e);an||(an=!0,It(pn))}}function hn(e,t){if(e){for(var n=Object.create(null),a=ce?Reflect.ownKeys(e):Object.keys(e),r=0;r-1)if(i&&!_(r,"default"))o=!1;else if(""===o||o===T(e)){var s=Ln(String,r.type);(s<0||l-1:"string"==typeof e?e.split(",").indexOf(t)>-1:!!h(e)&&e.test(t)}function Kn(e,t){var n=e.cache,a=e.keys,r=e._vnode;for(var i in n){var o=n[i];if(o){var l=o.name;l&&!t(l)&&Yn(n,i,a,r)}}}function Yn(e,t,n,a){var r=e[t];!r||a&&r.tag===a.tag||r.componentInstance.$destroy(),e[t]=null,k(n,t)}qn.prototype._init=function(e){var t=this;t._uid=Zn++,t._isVue=!0,t.__v_skip=!0,t._scope=new Ne(!0),t._scope._vm=!0,e&&e._isComponent?function(e,t){var n=e.$options=Object.create(e.constructor.options),a=t._parentVnode;n.parent=t.parent,n._parentVnode=a;var r=a.componentOptions;n.propsData=r.propsData,n._parentListeners=r.listeners,n._renderChildren=r.children,n._componentTag=r.tag,t.render&&(n.render=t.render,n.staticRenderFns=t.staticRenderFns)}(t,e):t.$options=Pn(Hn(t.constructor),e||{},t),t._renderProxy=t,t._self=t,function(e){var t=e.$options,n=t.parent;if(n&&!t.abstract){for(;n.$options.abstract&&n.$parent;)n=n.$parent;n.$children.push(e)}e.$parent=n,e.$root=n?n.$root:e,e.$children=[],e.$refs={},e._provided=n?n._provided:Object.create(null),e._watcher=null,e._inactive=null,e._directInactive=!1,e._isMounted=!1,e._isDestroyed=!1,e._isBeingDestroyed=!1}(t),function(e){e._events=Object.create(null),e._hasHookEvent=!1;var t=e.$options._parentListeners;t&&Wt(e,t)}(t),function(e){e._vnode=null,e._staticTrees=null;var t=e.$options,n=e.$vnode=t._parentVnode,r=n&&n.context;e.$slots=pt(t._renderChildren,r),e.$scopedSlots=n?ft(e.$parent,n.data.scopedSlots,e.$slots):a,e._c=function(t,n,a,r){return wt(e,t,n,a,r,!1)},e.$createElement=function(t,n,a,r){return wt(e,t,n,a,r,!0)};var i=n&&n.data;Oe(e,"$attrs",i&&i.attrs||a,null,!0),Oe(e,"$listeners",t._parentListeners||a,null,!0)}(t),Qt(t,"beforeCreate",void 0,!1),function(e){var t=hn(e.$options.inject,e);t&&(Be(!1),Object.keys(t).forEach((function(n){Oe(e,n,t[n])})),Be(!0))}(t),In(t),function(e){var t=e.$options.provide;if(t){var n=c(t)?t.call(e):t;if(!u(n))return;for(var a=Fe(e),r=ce?Reflect.ownKeys(n):Object.keys(n),i=0;i1?C(n):n;for(var a=C(arguments,1),r='event handler for "'.concat(e,'"'),i=0,o=n.length;iparseInt(this.max)&&Yn(e,t[0],t,this._vnode),this.vnodeToCache=null}}},created:function(){this.cache=Object.create(null),this.keys=[]},destroyed:function(){for(var e in this.cache)Yn(this.cache,e,this.keys)},mounted:function(){var e=this;this.cacheVNode(),this.$watch("include",(function(t){Kn(e,(function(e){return Gn(t,e)}))})),this.$watch("exclude",(function(t){Kn(e,(function(e){return!Gn(t,e)}))}))},updated:function(){this.cacheVNode()},render:function(){var e=this.$slots.default,t=xt(e),n=t&&t.componentOptions;if(n){var a=Wn(n),r=this.include,i=this.exclude;if(r&&(!a||!Gn(r,a))||i&&a&&Gn(i,a))return t;var o=this.cache,l=this.keys,s=null==t.key?n.Ctor.cid+(n.tag?"::".concat(n.tag):""):t.key;o[s]?(t.componentInstance=o[s].componentInstance,k(l,s),l.push(s)):(this.vnodeToCache=t,this.keyToCache=s),t.data.keepAlive=!0}return t||e&&e[0]}}};!function(e){var t={get:function(){return F}};Object.defineProperty(e,"config",t),e.util={warn:_n,extend:O,mergeOptions:Pn,defineReactive:Oe},e.set=Se,e.delete=Ue,e.nextTick=It,e.observable=function(e){return Ce(e),e},e.options=Object.create(null),R.forEach((function(t){e.options[t+"s"]=Object.create(null)})),e.options._base=e,O(e.options.components,Qn),function(e){e.use=function(e){var t=this._installedPlugins||(this._installedPlugins=[]);if(t.indexOf(e)>-1)return this;var n=C(arguments,1);return n.unshift(this),c(e.install)?e.install.apply(e,n):c(e)&&e.apply(null,n),t.push(e),this}}(e),function(e){e.mixin=function(e){return this.options=Pn(this.options,e),this}}(e),Vn(e),function(e){R.forEach((function(t){e[t]=function(e,n){return n?("component"===t&&d(n)&&(n.name=n.name||e,n=this.options._base.extend(n)),"directive"===t&&c(n)&&(n={bind:n,update:n}),this.options[t+"s"][e]=n,n):this.options[t+"s"][e]}}))}(e)}(qn),Object.defineProperty(qn.prototype,"$isServer",{get:ie}),Object.defineProperty(qn.prototype,"$ssrContext",{get:function(){return this.$vnode&&this.$vnode.ssrContext}}),Object.defineProperty(qn,"FunctionalRenderContext",{value:fn}),qn.version="2.7.14";var ea=b("style,class"),ta=b("input,textarea,option,select,progress"),na=b("contenteditable,draggable,spellcheck"),aa=b("events,caret,typing,plaintext-only"),ra=b("allowfullscreen,async,autofocus,autoplay,checked,compact,controls,declare,default,defaultchecked,defaultmuted,defaultselected,defer,disabled,enabled,formnovalidate,hidden,indeterminate,inert,ismap,itemscope,loop,multiple,muted,nohref,noresize,noshade,novalidate,nowrap,open,pauseonexit,readonly,required,reversed,scoped,seamless,selected,sortable,truespeed,typemustmatch,visible"),ia="http://www.w3.org/1999/xlink",oa=function(e){return":"===e.charAt(5)&&"xlink"===e.slice(0,5)},la=function(e){return oa(e)?e.slice(6,e.length):""},sa=function(e){return null==e||!1===e};function ca(e){for(var t=e.data,n=e,a=e;o(a.componentInstance);)(a=a.componentInstance._vnode)&&a.data&&(t=ua(a.data,t));for(;o(n=n.parent);)n&&n.data&&(t=ua(t,n.data));return function(e,t){if(o(e)||o(t))return pa(e,da(t));return""}(t.staticClass,t.class)}function ua(e,t){return{staticClass:pa(e.staticClass,t.staticClass),class:o(e.class)?[e.class,t.class]:t.class}}function pa(e,t){return e?t?e+" "+t:e:t||""}function da(e){return Array.isArray(e)?function(e){for(var t,n="",a=0,r=e.length;a-1?Da(e,t,n):ra(t)?sa(n)?e.removeAttribute(t):(n="allowfullscreen"===t&&"EMBED"===e.tagName?"true":t,e.setAttribute(t,n)):na(t)?e.setAttribute(t,function(e,t){return sa(t)||"false"===t?"false":"contenteditable"===e&&aa(t)?t:"true"}(t,n)):oa(t)?sa(n)?e.removeAttributeNS(ia,la(t)):e.setAttributeNS(ia,t,n):Da(e,t,n)}function Da(e,t,n){if(sa(n))e.removeAttribute(t);else{if(K&&!Y&&"TEXTAREA"===e.tagName&&"placeholder"===t&&""!==n&&!e.__ieph){var a=function(t){t.stopImmediatePropagation(),e.removeEventListener("input",a)};e.addEventListener("input",a),e.__ieph=!0}e.setAttribute(t,n)}}var za={create:$a,update:$a};function Ia(e,t){var n=t.elm,a=t.data,r=e.data;if(!(i(a.staticClass)&&i(a.class)&&(i(r)||i(r.staticClass)&&i(r.class)))){var l=ca(t),s=n._transitionClasses;o(s)&&(l=pa(l,da(s))),l!==n._prevClass&&(n.setAttribute("class",l),n._prevClass=l)}}var Ma,Ra={create:Ia,update:Ia};function Na(e,t,n){var a=Ma;return function r(){var i=t.apply(null,arguments);null!==i&&Za(e,r,n,a)}}var Fa=Ct&&!(te&&Number(te[1])<=53);function Ja(e,t,n,a){if(Fa){var r=ln,i=t;t=i._wrapper=function(e){if(e.target===e.currentTarget||e.timeStamp>=r||e.timeStamp<=0||e.target.ownerDocument!==document)return i.apply(this,arguments)}}Ma.addEventListener(e,t,ae?{capture:n,passive:a}:n)}function Za(e,t,n,a){(a||Ma).removeEventListener(e,t._wrapper||t,n)}function Ha(e,t){if(!i(e.data.on)||!i(t.data.on)){var n=t.data.on||{},a=e.data.on||{};Ma=t.elm||e.elm,function(e){if(o(e.__r)){var t=K?"change":"input";e[t]=[].concat(e.__r,e[t]||[]),delete e.__r}o(e.__c)&&(e.change=[].concat(e.__c,e.change||[]),delete e.__c)}(n),He(n,a,Ja,Za,Na,t.context),Ma=void 0}}var qa,Va={create:Ha,update:Ha,destroy:function(e){return Ha(e,xa)}};function Wa(e,t){if(!i(e.data.domProps)||!i(t.data.domProps)){var n,a,r=t.elm,s=e.data.domProps||{},c=t.data.domProps||{};for(n in(o(c.__ob__)||l(c._v_attr_proxy))&&(c=t.data.domProps=O({},c)),s)n in c||(r[n]="");for(n in c){if(a=c[n],"textContent"===n||"innerHTML"===n){if(t.children&&(t.children.length=0),a===s[n])continue;1===r.childNodes.length&&r.removeChild(r.childNodes[0])}if("value"===n&&"PROGRESS"!==r.tagName){r._value=a;var u=i(a)?"":String(a);Ga(r,u)&&(r.value=u)}else if("innerHTML"===n&&ma(r.tagName)&&i(r.innerHTML)){(qa=qa||document.createElement("div")).innerHTML="".concat(a,"");for(var p=qa.firstChild;r.firstChild;)r.removeChild(r.firstChild);for(;p.firstChild;)r.appendChild(p.firstChild)}else if(a!==s[n])try{r[n]=a}catch(e){}}}}function Ga(e,t){return!e.composing&&("OPTION"===e.tagName||function(e,t){var n=!0;try{n=document.activeElement!==e}catch(e){}return n&&e.value!==t}(e,t)||function(e,t){var n=e.value,a=e._vModifiers;if(o(a)){if(a.number)return v(n)!==v(t);if(a.trim)return n.trim()!==t.trim()}return n!==t}(e,t))}var Ka={create:Wa,update:Wa},Ya=x((function(e){var t={},n=/:(.+)/;return e.split(/;(?![^(]*\))/g).forEach((function(e){if(e){var a=e.split(n);a.length>1&&(t[a[0].trim()]=a[1].trim())}})),t}));function Xa(e){var t=Qa(e.style);return e.staticStyle?O(e.staticStyle,t):t}function Qa(e){return Array.isArray(e)?S(e):"string"==typeof e?Ya(e):e}var er,tr=/^--/,nr=/\s*!important$/,ar=function(e,t,n){if(tr.test(t))e.style.setProperty(t,n);else if(nr.test(n))e.style.setProperty(T(t),n.replace(nr,""),"important");else{var a=ir(t);if(Array.isArray(n))for(var r=0,i=n.length;r-1?t.split(sr).forEach((function(t){return e.classList.add(t)})):e.classList.add(t);else{var n=" ".concat(e.getAttribute("class")||""," ");n.indexOf(" "+t+" ")<0&&e.setAttribute("class",(n+t).trim())}}function ur(e,t){if(t&&(t=t.trim()))if(e.classList)t.indexOf(" ")>-1?t.split(sr).forEach((function(t){return e.classList.remove(t)})):e.classList.remove(t),e.classList.length||e.removeAttribute("class");else{for(var n=" ".concat(e.getAttribute("class")||""," "),a=" "+t+" ";n.indexOf(a)>=0;)n=n.replace(a," ");(n=n.trim())?e.setAttribute("class",n):e.removeAttribute("class")}}function pr(e){if(e){if("object"==typeof e){var t={};return!1!==e.css&&O(t,dr(e.name||"v")),O(t,e),t}return"string"==typeof e?dr(e):void 0}}var dr=x((function(e){return{enterClass:"".concat(e,"-enter"),enterToClass:"".concat(e,"-enter-to"),enterActiveClass:"".concat(e,"-enter-active"),leaveClass:"".concat(e,"-leave"),leaveToClass:"".concat(e,"-leave-to"),leaveActiveClass:"".concat(e,"-leave-active")}})),hr=W&&!Y,fr="transition",mr="transitionend",gr="animation",vr="animationend";hr&&(void 0===window.ontransitionend&&void 0!==window.onwebkittransitionend&&(fr="WebkitTransition",mr="webkitTransitionEnd"),void 0===window.onanimationend&&void 0!==window.onwebkitanimationend&&(gr="WebkitAnimation",vr="webkitAnimationEnd"));var br=W?window.requestAnimationFrame?window.requestAnimationFrame.bind(window):setTimeout:function(e){return e()};function yr(e){br((function(){br(e)}))}function kr(e,t){var n=e._transitionClasses||(e._transitionClasses=[]);n.indexOf(t)<0&&(n.push(t),cr(e,t))}function Er(e,t){e._transitionClasses&&k(e._transitionClasses,t),ur(e,t)}function _r(e,t,n){var a=wr(e,t),r=a.type,i=a.timeout,o=a.propCount;if(!r)return n();var l="transition"===r?mr:vr,s=0,c=function(){e.removeEventListener(l,u),n()},u=function(t){t.target===e&&++s>=o&&c()};setTimeout((function(){s0&&(n="transition",u=o,p=i.length):"animation"===t?c>0&&(n="animation",u=c,p=s.length):p=(n=(u=Math.max(o,c))>0?o>c?"transition":"animation":null)?"transition"===n?i.length:s.length:0,{type:n,timeout:u,propCount:p,hasTransform:"transition"===n&&xr.test(a[fr+"Property"])}}function Ar(e,t){for(;e.length1}function Or(e,t){!0!==t.data.show&&Br(t)}var Sr=function(e){var t,n,a={},c=e.modules,u=e.nodeOps;for(t=0;tf?k(e,i(n[v+1])?null:n[v+1].elm,n,h,v,a):h>v&&_(t,p,f)}(p,m,v,n,c):o(v)?(o(e.text)&&u.setTextContent(p,""),k(p,null,v,0,v.length-1,n)):o(m)?_(m,0,m.length-1):o(e.text)&&u.setTextContent(p,""):e.text!==t.text&&u.setTextContent(p,t.text),o(f)&&o(h=f.hook)&&o(h=h.postpatch)&&h(e,t)}}}function j(e,t,n){if(l(n)&&o(e.parent))e.parent.data.pendingInsert=t;else for(var a=0;a-1,o.selected!==i&&(o.selected=i);else if(D(zr(o),a))return void(e.selectedIndex!==l&&(e.selectedIndex=l));r||(e.selectedIndex=-1)}}function Dr(e,t){return t.every((function(t){return!D(t,e)}))}function zr(e){return"_value"in e?e._value:e.value}function Ir(e){e.target.composing=!0}function Mr(e){e.target.composing&&(e.target.composing=!1,Rr(e.target,"input"))}function Rr(e,t){var n=document.createEvent("HTMLEvents");n.initEvent(t,!0,!0),e.dispatchEvent(n)}function Nr(e){return!e.componentInstance||e.data&&e.data.transition?e:Nr(e.componentInstance._vnode)}var Fr={model:Ur,show:{bind:function(e,t,n){var a=t.value,r=(n=Nr(n)).data&&n.data.transition,i=e.__vOriginalDisplay="none"===e.style.display?"":e.style.display;a&&r?(n.data.show=!0,Br(n,(function(){e.style.display=i}))):e.style.display=a?i:"none"},update:function(e,t,n){var a=t.value;!a!=!t.oldValue&&((n=Nr(n)).data&&n.data.transition?(n.data.show=!0,a?Br(n,(function(){e.style.display=e.__vOriginalDisplay})):Tr(n,(function(){e.style.display="none"}))):e.style.display=a?e.__vOriginalDisplay:"none")},unbind:function(e,t,n,a,r){r||(e.style.display=e.__vOriginalDisplay)}}},Jr={name:String,appear:Boolean,css:Boolean,mode:String,type:String,enterClass:String,leaveClass:String,enterToClass:String,leaveToClass:String,enterActiveClass:String,leaveActiveClass:String,appearClass:String,appearActiveClass:String,appearToClass:String,duration:[Number,String,Object]};function Zr(e){var t=e&&e.componentOptions;return t&&t.Ctor.options.abstract?Zr(xt(t.children)):e}function Hr(e){var t={},n=e.$options;for(var a in n.propsData)t[a]=e[a];var r=n._parentListeners;for(var a in r)t[A(a)]=r[a];return t}function qr(e,t){if(/\d-keep-alive$/.test(t.tag))return e("keep-alive",{props:t.componentOptions.propsData})}var Vr=function(e){return e.tag||ht(e)},Wr=function(e){return"show"===e.name},Gr={name:"transition",props:Jr,abstract:!0,render:function(e){var t=this,n=this.$slots.default;if(n&&(n=n.filter(Vr)).length){0;var a=this.mode;0;var r=n[0];if(function(e){for(;e=e.parent;)if(e.data.transition)return!0}(this.$vnode))return r;var i=Zr(r);if(!i)return r;if(this._leaving)return qr(e,r);var o="__transition-".concat(this._uid,"-");i.key=null==i.key?i.isComment?o+"comment":o+i.tag:s(i.key)?0===String(i.key).indexOf(o)?i.key:o+i.key:i.key;var l=(i.data||(i.data={})).transition=Hr(this),c=this._vnode,u=Zr(c);if(i.data.directives&&i.data.directives.some(Wr)&&(i.data.show=!0),u&&u.data&&!function(e,t){return t.key===e.key&&t.tag===e.tag}(i,u)&&!ht(u)&&(!u.componentInstance||!u.componentInstance._vnode.isComment)){var p=u.data.transition=O({},l);if("out-in"===a)return this._leaving=!0,qe(p,"afterLeave",(function(){t._leaving=!1,t.$forceUpdate()})),qr(e,r);if("in-out"===a){if(ht(i))return c;var d,h=function(){d()};qe(l,"afterEnter",h),qe(l,"enterCancelled",h),qe(p,"delayLeave",(function(e){d=e}))}}return r}}},Kr=O({tag:String,moveClass:String},Jr);function Yr(e){e.elm._moveCb&&e.elm._moveCb(),e.elm._enterCb&&e.elm._enterCb()}function Xr(e){e.data.newPos=e.elm.getBoundingClientRect()}function Qr(e){var t=e.data.pos,n=e.data.newPos,a=t.left-n.left,r=t.top-n.top;if(a||r){e.data.moved=!0;var i=e.elm.style;i.transform=i.WebkitTransform="translate(".concat(a,"px,").concat(r,"px)"),i.transitionDuration="0s"}}delete Kr.mode;var ei={Transition:Gr,TransitionGroup:{props:Kr,beforeMount:function(){var e=this,t=this._update;this._update=function(n,a){var r=Kt(e);e.__patch__(e._vnode,e.kept,!1,!0),e._vnode=e.kept,r(),t.call(e,n,a)}},render:function(e){for(var t=this.tag||this.$vnode.data.tag||"span",n=Object.create(null),a=this.prevChildren=this.children,r=this.$slots.default||[],i=this.children=[],o=Hr(this),l=0;l-1?va[e]=t.constructor===window.HTMLUnknownElement||t.constructor===window.HTMLElement:va[e]=/HTMLUnknownElement/.test(t.toString())},O(qn.options.directives,Fr),O(qn.options.components,ei),qn.prototype.__patch__=W?Sr:U,qn.prototype.$mount=function(e,t){return function(e,t,n){var a;e.$el=t,e.$options.render||(e.$options.render=he),Qt(e,"beforeMount"),a=function(){e._update(e._render(),n)},new Zt(e,a,U,{before:function(){e._isMounted&&!e._isDestroyed&&Qt(e,"beforeUpdate")}},!0),n=!1;var r=e._preWatchers;if(r)for(var i=0;i=0&&(t=e.slice(a),e=e.slice(0,a));var r=e.indexOf("?");return r>=0&&(n=e.slice(r+1),e=e.slice(0,r)),{path:e,query:n,hash:t}}(r.path||""),c=t&&t.path||"/",u=s.path?Ei(s.path,c,n||r.append):c,p=function(e,t,n){void 0===t&&(t={});var a,r=n||si;try{a=r(e||"")}catch(e){a={}}for(var i in t){var o=t[i];a[i]=Array.isArray(o)?o.map(li):li(o)}return a}(s.query,r.query,a&&a.options.parseQuery),d=r.hash||s.hash;return d&&"#"!==d.charAt(0)&&(d="#"+d),{_normalized:!0,path:u,query:p,hash:d}}var Fi,Ji=function(){},Zi={name:"RouterLink",props:{to:{type:[String,Object],required:!0},tag:{type:String,default:"a"},custom:Boolean,exact:Boolean,exactPath:Boolean,append:Boolean,replace:Boolean,activeClass:String,exactActiveClass:String,ariaCurrentValue:{type:String,default:"page"},event:{type:[String,Array],default:"click"}},render:function(e){var t=this,n=this.$router,a=this.$route,r=n.resolve(this.to,a,this.append),i=r.location,o=r.route,l=r.href,s={},c=n.options.linkActiveClass,u=n.options.linkExactActiveClass,p=null==c?"router-link-active":c,d=null==u?"router-link-exact-active":u,h=null==this.activeClass?p:this.activeClass,f=null==this.exactActiveClass?d:this.exactActiveClass,m=o.redirectedFrom?pi(null,Ni(o.redirectedFrom),null,n):o;s[f]=gi(a,m,this.exactPath),s[h]=this.exact||this.exactPath?s[f]:function(e,t){return 0===e.path.replace(ui,"/").indexOf(t.path.replace(ui,"/"))&&(!t.hash||e.hash===t.hash)&&function(e,t){for(var n in t)if(!(n in e))return!1;return!0}(e.query,t.query)}(a,m);var g=s[f]?this.ariaCurrentValue:null,v=function(e){Hi(e)&&(t.replace?n.replace(i,Ji):n.push(i,Ji))},b={click:Hi};Array.isArray(this.event)?this.event.forEach((function(e){b[e]=v})):b[this.event]=v;var y={class:s},k=!this.$scopedSlots.$hasNormal&&this.$scopedSlots.default&&this.$scopedSlots.default({href:l,route:o,navigate:v,isActive:s[h],isExactActive:s[f]});if(k){if(1===k.length)return k[0];if(k.length>1||!k.length)return 0===k.length?e():e("span",{},k)}if("a"===this.tag)y.on=b,y.attrs={href:l,"aria-current":g};else{var E=function e(t){var n;if(t)for(var a=0;a-1&&(l.params[d]=n.params[d]);return l.path=Ri(u.path,l.params),s(u,l,o)}if(l.path){l.params={};for(var h=0;h-1}function xo(e,t){return _o(e)&&e._isRouter&&(null==t||e.type===t)}function wo(e,t,n){var a=function(r){r>=e.length?n():e[r]?t(e[r],(function(){a(r+1)})):a(r+1)};a(0)}function Ao(e){return function(t,n,a){var r=!1,i=0,o=null;jo(e,(function(e,t,n,l){if("function"==typeof e&&void 0===e.cid){r=!0,i++;var s,c=Po((function(t){var r;((r=t).__esModule||To&&"Module"===r[Symbol.toStringTag])&&(t=t.default),e.resolved="function"==typeof t?t:Fi.extend(t),n.components[l]=t,--i<=0&&a()})),u=Po((function(e){var t="Failed to resolve async component "+l+": "+e;o||(o=_o(e)?e:new Error(t),a(o))}));try{s=e(c,u)}catch(e){u(e)}if(s)if("function"==typeof s.then)s.then(c,u);else{var p=s.component;p&&"function"==typeof p.then&&p.then(c,u)}}})),r||a()}}function jo(e,t){return Bo(e.map((function(e){return Object.keys(e.components).map((function(n){return t(e.components[n],e.instances[n],e,n)}))})))}function Bo(e){return Array.prototype.concat.apply([],e)}var To="function"==typeof Symbol&&"symbol"==typeof Symbol.toStringTag;function Po(e){var t=!1;return function(){for(var n=[],a=arguments.length;a--;)n[a]=arguments[a];if(!t)return t=!0,e.apply(this,n)}}var Co=function(e,t){this.router=e,this.base=function(e){if(!e)if(qi){var t=document.querySelector("base");e=(e=t&&t.getAttribute("href")||"/").replace(/^https?:\/\/[^\/]+/,"")}else e="/";"/"!==e.charAt(0)&&(e="/"+e);return e.replace(/\/$/,"")}(t),this.current=hi,this.pending=null,this.ready=!1,this.readyCbs=[],this.readyErrorCbs=[],this.errorCbs=[],this.listeners=[]};function Oo(e,t,n,a){var r=jo(e,(function(e,a,r,i){var o=function(e,t){"function"!=typeof e&&(e=Fi.extend(e));return e.options[t]}(e,t);if(o)return Array.isArray(o)?o.map((function(e){return n(e,a,r,i)})):n(o,a,r,i)}));return Bo(a?r.reverse():r)}function So(e,t){if(t)return function(){return e.apply(t,arguments)}}Co.prototype.listen=function(e){this.cb=e},Co.prototype.onReady=function(e,t){this.ready?e():(this.readyCbs.push(e),t&&this.readyErrorCbs.push(t))},Co.prototype.onError=function(e){this.errorCbs.push(e)},Co.prototype.transitionTo=function(e,t,n){var a,r=this;try{a=this.router.match(e,this.current)}catch(e){throw this.errorCbs.forEach((function(t){t(e)})),e}var i=this.current;this.confirmTransition(a,(function(){r.updateRoute(a),t&&t(a),r.ensureURL(),r.router.afterHooks.forEach((function(e){e&&e(a,i)})),r.ready||(r.ready=!0,r.readyCbs.forEach((function(e){e(a)})))}),(function(e){n&&n(e),e&&!r.ready&&(xo(e,vo.redirected)&&i===hi||(r.ready=!0,r.readyErrorCbs.forEach((function(t){t(e)}))))}))},Co.prototype.confirmTransition=function(e,t,n){var a=this,r=this.current;this.pending=e;var i,o,l=function(e){!xo(e)&&_o(e)&&(a.errorCbs.length?a.errorCbs.forEach((function(t){t(e)})):console.error(e)),n&&n(e)},s=e.matched.length-1,c=r.matched.length-1;if(gi(e,r)&&s===c&&e.matched[s]===r.matched[c])return this.ensureURL(),e.hash&&ro(this.router,r,e,!1),l(((o=ko(i=r,e,vo.duplicated,'Avoided redundant navigation to current location: "'+i.fullPath+'".')).name="NavigationDuplicated",o));var u=function(e,t){var n,a=Math.max(e.length,t.length);for(n=0;n0)){var t=this.router,n=t.options.scrollBehavior,a=fo&&n;a&&this.listeners.push(ao());var r=function(){var n=e.current,r=$o(e.base);e.current===hi&&r===e._startLocation||e.transitionTo(r,(function(e){a&&ro(t,e,n,!0)}))};window.addEventListener("popstate",r),this.listeners.push((function(){window.removeEventListener("popstate",r)}))}},t.prototype.go=function(e){window.history.go(e)},t.prototype.push=function(e,t,n){var a=this,r=this.current;this.transitionTo(e,(function(e){mo(_i(a.base+e.fullPath)),ro(a.router,e,r,!1),t&&t(e)}),n)},t.prototype.replace=function(e,t,n){var a=this,r=this.current;this.transitionTo(e,(function(e){go(_i(a.base+e.fullPath)),ro(a.router,e,r,!1),t&&t(e)}),n)},t.prototype.ensureURL=function(e){if($o(this.base)!==this.current.fullPath){var t=_i(this.base+this.current.fullPath);e?mo(t):go(t)}},t.prototype.getCurrentLocation=function(){return $o(this.base)},t}(Co);function $o(e){var t=window.location.pathname,n=t.toLowerCase(),a=e.toLowerCase();return!e||n!==a&&0!==n.indexOf(_i(a+"/"))||(t=t.slice(e.length)),(t||"/")+window.location.search+window.location.hash}var Lo=function(e){function t(t,n,a){e.call(this,t,n),a&&function(e){var t=$o(e);if(!/^\/#/.test(t))return window.location.replace(_i(e+"/#"+t)),!0}(this.base)||Do()}return e&&(t.__proto__=e),t.prototype=Object.create(e&&e.prototype),t.prototype.constructor=t,t.prototype.setupListeners=function(){var e=this;if(!(this.listeners.length>0)){var t=this.router.options.scrollBehavior,n=fo&&t;n&&this.listeners.push(ao());var a=function(){var t=e.current;Do()&&e.transitionTo(zo(),(function(a){n&&ro(e.router,a,t,!0),fo||Ro(a.fullPath)}))},r=fo?"popstate":"hashchange";window.addEventListener(r,a),this.listeners.push((function(){window.removeEventListener(r,a)}))}},t.prototype.push=function(e,t,n){var a=this,r=this.current;this.transitionTo(e,(function(e){Mo(e.fullPath),ro(a.router,e,r,!1),t&&t(e)}),n)},t.prototype.replace=function(e,t,n){var a=this,r=this.current;this.transitionTo(e,(function(e){Ro(e.fullPath),ro(a.router,e,r,!1),t&&t(e)}),n)},t.prototype.go=function(e){window.history.go(e)},t.prototype.ensureURL=function(e){var t=this.current.fullPath;zo()!==t&&(e?Mo(t):Ro(t))},t.prototype.getCurrentLocation=function(){return zo()},t}(Co);function Do(){var e=zo();return"/"===e.charAt(0)||(Ro("/"+e),!1)}function zo(){var e=window.location.href,t=e.indexOf("#");return t<0?"":e=e.slice(t+1)}function Io(e){var t=window.location.href,n=t.indexOf("#");return(n>=0?t.slice(0,n):t)+"#"+e}function Mo(e){fo?mo(Io(e)):window.location.hash=e}function Ro(e){fo?go(Io(e)):window.location.replace(Io(e))}var No=function(e){function t(t,n){e.call(this,t,n),this.stack=[],this.index=-1}return e&&(t.__proto__=e),t.prototype=Object.create(e&&e.prototype),t.prototype.constructor=t,t.prototype.push=function(e,t,n){var a=this;this.transitionTo(e,(function(e){a.stack=a.stack.slice(0,a.index+1).concat(e),a.index++,t&&t(e)}),n)},t.prototype.replace=function(e,t,n){var a=this;this.transitionTo(e,(function(e){a.stack=a.stack.slice(0,a.index).concat(e),t&&t(e)}),n)},t.prototype.go=function(e){var t=this,n=this.index+e;if(!(n<0||n>=this.stack.length)){var a=this.stack[n];this.confirmTransition(a,(function(){var e=t.current;t.index=n,t.updateRoute(a),t.router.afterHooks.forEach((function(t){t&&t(a,e)}))}),(function(e){xo(e,vo.duplicated)&&(t.index=n)}))}},t.prototype.getCurrentLocation=function(){var e=this.stack[this.stack.length-1];return e?e.fullPath:"/"},t.prototype.ensureURL=function(){},t}(Co),Fo=function(e){void 0===e&&(e={}),this.app=null,this.apps=[],this.options=e,this.beforeHooks=[],this.resolveHooks=[],this.afterHooks=[],this.matcher=Gi(e.routes||[],this);var t=e.mode||"hash";switch(this.fallback="history"===t&&!fo&&!1!==e.fallback,this.fallback&&(t="hash"),qi||(t="abstract"),this.mode=t,t){case"history":this.history=new Uo(this,e.base);break;case"hash":this.history=new Lo(this,e.base,this.fallback);break;case"abstract":this.history=new No(this,e.base);break;default:0}},Jo={currentRoute:{configurable:!0}};Fo.prototype.match=function(e,t,n){return this.matcher.match(e,t,n)},Jo.currentRoute.get=function(){return this.history&&this.history.current},Fo.prototype.init=function(e){var t=this;if(this.apps.push(e),e.$once("hook:destroyed",(function(){var n=t.apps.indexOf(e);n>-1&&t.apps.splice(n,1),t.app===e&&(t.app=t.apps[0]||null),t.app||t.history.teardown()})),!this.app){this.app=e;var n=this.history;if(n instanceof Uo||n instanceof Lo){var a=function(e){n.setupListeners(),function(e){var a=n.current,r=t.options.scrollBehavior;fo&&r&&"fullPath"in e&&ro(t,e,a,!1)}(e)};n.transitionTo(n.getCurrentLocation(),a,a)}n.listen((function(e){t.apps.forEach((function(t){t._route=e}))}))}},Fo.prototype.beforeEach=function(e){return Ho(this.beforeHooks,e)},Fo.prototype.beforeResolve=function(e){return Ho(this.resolveHooks,e)},Fo.prototype.afterEach=function(e){return Ho(this.afterHooks,e)},Fo.prototype.onReady=function(e,t){this.history.onReady(e,t)},Fo.prototype.onError=function(e){this.history.onError(e)},Fo.prototype.push=function(e,t,n){var a=this;if(!t&&!n&&"undefined"!=typeof Promise)return new Promise((function(t,n){a.history.push(e,t,n)}));this.history.push(e,t,n)},Fo.prototype.replace=function(e,t,n){var a=this;if(!t&&!n&&"undefined"!=typeof Promise)return new Promise((function(t,n){a.history.replace(e,t,n)}));this.history.replace(e,t,n)},Fo.prototype.go=function(e){this.history.go(e)},Fo.prototype.back=function(){this.go(-1)},Fo.prototype.forward=function(){this.go(1)},Fo.prototype.getMatchedComponents=function(e){var t=e?e.matched?e:this.resolve(e).route:this.currentRoute;return t?[].concat.apply([],t.matched.map((function(e){return Object.keys(e.components).map((function(t){return e.components[t]}))}))):[]},Fo.prototype.resolve=function(e,t,n){var a=Ni(e,t=t||this.history.current,n,this),r=this.match(a,t),i=r.redirectedFrom||r.fullPath;return{location:a,route:r,href:function(e,t,n){var a="hash"===n?"#"+t:t;return e?_i(e+"/"+a):a}(this.history.base,i,this.mode),normalizedTo:a,resolved:r}},Fo.prototype.getRoutes=function(){return this.matcher.getRoutes()},Fo.prototype.addRoute=function(e,t){this.matcher.addRoute(e,t),this.history.current!==hi&&this.history.transitionTo(this.history.getCurrentLocation())},Fo.prototype.addRoutes=function(e){this.matcher.addRoutes(e),this.history.current!==hi&&this.history.transitionTo(this.history.getCurrentLocation())},Object.defineProperties(Fo.prototype,Jo);var Zo=Fo;function Ho(e,t){return e.push(t),function(){var n=e.indexOf(t);n>-1&&e.splice(n,1)}}Fo.install=function e(t){if(!e.installed||Fi!==t){e.installed=!0,Fi=t;var n=function(e){return void 0!==e},a=function(e,t){var a=e.$options._parentVnode;n(a)&&n(a=a.data)&&n(a=a.registerRouteInstance)&&a(e,t)};t.mixin({beforeCreate:function(){n(this.$options.router)?(this._routerRoot=this,this._router=this.$options.router,this._router.init(this),t.util.defineReactive(this,"_route",this._router.history.current)):this._routerRoot=this.$parent&&this.$parent._routerRoot||this,a(this,this)},destroyed:function(){a(this)}}),Object.defineProperty(t.prototype,"$router",{get:function(){return this._routerRoot._router}}),Object.defineProperty(t.prototype,"$route",{get:function(){return this._routerRoot._route}}),t.component("RouterView",yi),t.component("RouterLink",Zi);var r=t.config.optionMergeStrategies;r.beforeRouteEnter=r.beforeRouteLeave=r.beforeRouteUpdate=r.created}},Fo.version="3.6.5",Fo.isNavigationFailure=xo,Fo.NavigationFailureType=vo,Fo.START_LOCATION=hi,qi&&window.Vue&&window.Vue.use(Fo);n(102);n(25),n(132);var qo={"components/AlgoliaSearchBox":()=>Promise.all([n.e(0),n.e(14)]).then(n.bind(null,359)),"components/ArchivesPage":()=>Promise.all([n.e(0),n.e(17)]).then(n.bind(null,331)),"components/ArticleInfo":()=>Promise.all([n.e(0),n.e(20)]).then(n.bind(null,332)),"components/BloggerBar":()=>Promise.all([n.e(0),n.e(21)]).then(n.bind(null,333)),"components/BodyBgImg":()=>Promise.all([n.e(0),n.e(22)]).then(n.bind(null,334)),"components/Buttons":()=>Promise.all([n.e(0),n.e(18)]).then(n.bind(null,335)),"components/Catalogue":()=>Promise.all([n.e(0),n.e(23)]).then(n.bind(null,336)),"components/CategoriesBar":()=>Promise.all([n.e(0),n.e(24)]).then(n.bind(null,300)),"components/CategoriesPage":()=>Promise.all([n.e(0),n.e(11)]).then(n.bind(null,337)),"components/DropdownLink":()=>Promise.all([n.e(0),n.e(15)]).then(n.bind(null,269)),"components/DropdownTransition":()=>Promise.all([n.e(0),n.e(25)]).then(n.bind(null,254)),"components/Footer":()=>Promise.all([n.e(0),n.e(26)]).then(n.bind(null,338)),"components/Home":()=>Promise.all([n.e(0),n.e(1)]).then(n.bind(null,355)),"components/MainLayout":()=>Promise.all([n.e(0),n.e(27)]).then(n.bind(null,270)),"components/NavLink":()=>n.e(37).then(n.bind(null,252)),"components/NavLinks":()=>Promise.all([n.e(0),n.e(13)]).then(n.bind(null,276)),"components/Navbar":()=>Promise.all([n.e(0),n.e(10)]).then(n.bind(null,330)),"components/Page":()=>Promise.all([n.e(0),n.e(2),n.e(34)]).then(n.bind(null,356)),"components/PageEdit":()=>Promise.all([n.e(0),n.e(19)]).then(n.bind(null,339)),"components/PageNav":()=>Promise.all([n.e(0),n.e(16)]).then(n.bind(null,340)),"components/Pagination":()=>Promise.all([n.e(0),n.e(28)]).then(n.bind(null,268)),"components/PostList":()=>Promise.all([n.e(0),n.e(29)]).then(n.bind(null,267)),"components/RightMenu":()=>Promise.all([n.e(0),n.e(30)]).then(n.bind(null,341)),"components/Sidebar":()=>Promise.all([n.e(0),n.e(9)]).then(n.bind(null,342)),"components/SidebarButton":()=>Promise.all([n.e(0),n.e(31)]).then(n.bind(null,306)),"components/SidebarGroup":()=>Promise.all([n.e(0),n.e(4)]).then(n.bind(null,302)),"components/SidebarLink":()=>Promise.all([n.e(0),n.e(32)]).then(n.bind(null,279)),"components/SidebarLinks":()=>Promise.all([n.e(0),n.e(4)]).then(n.bind(null,277)),"components/TagsBar":()=>Promise.all([n.e(0),n.e(33)]).then(n.bind(null,301)),"components/TagsPage":()=>Promise.all([n.e(0),n.e(12)]).then(n.bind(null,343)),"components/UpdateArticle":()=>Promise.all([n.e(0),n.e(35)]).then(n.bind(null,305)),"global-components/Badge":()=>Promise.all([n.e(0),n.e(5)]).then(n.bind(null,363)),"global-components/CodeBlock":()=>Promise.resolve().then(n.bind(null,95)),"global-components/CodeGroup":()=>Promise.resolve().then(n.bind(null,96)),"layouts/404":()=>Promise.all([n.e(0),n.e(6)]).then(n.bind(null,360)),"layouts/Layout":()=>Promise.all([n.e(0),n.e(1),n.e(2),n.e(3)]).then(n.bind(null,361)),NotFound:()=>Promise.all([n.e(0),n.e(6)]).then(n.bind(null,360)),Layout:()=>Promise.all([n.e(0),n.e(1),n.e(2),n.e(3)]).then(n.bind(null,361))},Vo={"v-9b6f56f2":()=>n.e(38).then(n.bind(null,364)),"v-793035b6":()=>n.e(39).then(n.bind(null,365)),"v-2cb2f234":()=>n.e(40).then(n.bind(null,366)),"v-398ec241":()=>n.e(41).then(n.bind(null,367)),"v-73eb8dca":()=>n.e(42).then(n.bind(null,368)),"v-0aa82876":()=>n.e(43).then(n.bind(null,369)),"v-19390582":()=>n.e(44).then(n.bind(null,370)),"v-bbba8304":()=>n.e(45).then(n.bind(null,371)),"v-4931c646":()=>n.e(46).then(n.bind(null,372)),"v-49a8aada":()=>n.e(47).then(n.bind(null,373)),"v-7f01ed9e":()=>n.e(48).then(n.bind(null,374)),"v-27216da0":()=>n.e(49).then(n.bind(null,375)),"v-5d7cf408":()=>n.e(50).then(n.bind(null,376)),"v-0c593678":()=>n.e(51).then(n.bind(null,377)),"v-2c61710f":()=>n.e(52).then(n.bind(null,378)),"v-520581ee":()=>n.e(53).then(n.bind(null,379)),"v-26d8a1d0":()=>n.e(54).then(n.bind(null,380)),"v-12b4125a":()=>n.e(55).then(n.bind(null,381)),"v-fdbad532":()=>n.e(56).then(n.bind(null,382)),"v-69225a59":()=>n.e(57).then(n.bind(null,383)),"v-c88140a0":()=>n.e(58).then(n.bind(null,384)),"v-d88d59ce":()=>n.e(59).then(n.bind(null,385)),"v-07c2d32e":()=>n.e(60).then(n.bind(null,386)),"v-209934f9":()=>n.e(61).then(n.bind(null,387)),"v-3c45a879":()=>n.e(62).then(n.bind(null,388)),"v-d5a6414e":()=>n.e(63).then(n.bind(null,389)),"v-49456eb6":()=>n.e(64).then(n.bind(null,390)),"v-16dcf019":()=>n.e(65).then(n.bind(null,391)),"v-192249b9":()=>n.e(66).then(n.bind(null,392)),"v-7e599067":()=>n.e(67).then(n.bind(null,393)),"v-0aab8a99":()=>n.e(68).then(n.bind(null,394)),"v-913bd424":()=>n.e(69).then(n.bind(null,395)),"v-5ca2e717":()=>n.e(70).then(n.bind(null,396)),"v-0f7771e7":()=>n.e(71).then(n.bind(null,397)),"v-18dff181":()=>n.e(72).then(n.bind(null,398)),"v-070ecef7":()=>n.e(73).then(n.bind(null,399)),"v-1b2f2f72":()=>n.e(74).then(n.bind(null,400)),"v-7816d697":()=>n.e(75).then(n.bind(null,401)),"v-86d5fbe8":()=>n.e(76).then(n.bind(null,402)),"v-12e360e7":()=>n.e(77).then(n.bind(null,403)),"v-15dd7598":()=>n.e(78).then(n.bind(null,404)),"v-609ee02a":()=>n.e(79).then(n.bind(null,405)),"v-305a0220":()=>n.e(80).then(n.bind(null,406)),"v-5178a0a2":()=>n.e(81).then(n.bind(null,407)),"v-968fc044":()=>n.e(82).then(n.bind(null,408)),"v-32c1407b":()=>n.e(83).then(n.bind(null,409)),"v-98f03ec0":()=>n.e(85).then(n.bind(null,410)),"v-90d8d00a":()=>n.e(84).then(n.bind(null,411)),"v-59d0a910":()=>n.e(86).then(n.bind(null,412)),"v-409f96f4":()=>n.e(87).then(n.bind(null,413)),"v-21640095":()=>n.e(88).then(n.bind(null,414)),"v-01db55a2":()=>n.e(89).then(n.bind(null,415)),"v-d3a2f914":()=>n.e(90).then(n.bind(null,416)),"v-68e19f6a":()=>n.e(91).then(n.bind(null,417)),"v-3ee66df2":()=>n.e(92).then(n.bind(null,418)),"v-0461446e":()=>n.e(93).then(n.bind(null,419)),"v-ab0b636a":()=>n.e(94).then(n.bind(null,420)),"v-033ef56a":()=>n.e(95).then(n.bind(null,421)),"v-6f79c7d0":()=>n.e(96).then(n.bind(null,422)),"v-718a15ee":()=>n.e(97).then(n.bind(null,423)),"v-1519562b":()=>n.e(98).then(n.bind(null,424)),"v-8685c0b6":()=>n.e(99).then(n.bind(null,425)),"v-37fae6a5":()=>n.e(100).then(n.bind(null,426)),"v-a106e244":()=>n.e(101).then(n.bind(null,427)),"v-e5a14ea8":()=>n.e(102).then(n.bind(null,428)),"v-f28180c4":()=>n.e(103).then(n.bind(null,429)),"v-6c8e6ac8":()=>n.e(104).then(n.bind(null,430)),"v-5a42538e":()=>n.e(105).then(n.bind(null,431)),"v-1cd3a514":()=>n.e(106).then(n.bind(null,432)),"v-f470e9b6":()=>n.e(107).then(n.bind(null,433)),"v-5f92b685":()=>n.e(108).then(n.bind(null,434)),"v-6b12deb6":()=>n.e(109).then(n.bind(null,435)),"v-5cfab93e":()=>n.e(110).then(n.bind(null,436)),"v-11478c3a":()=>n.e(111).then(n.bind(null,437)),"v-352e8304":()=>n.e(112).then(n.bind(null,438)),"v-823cdc00":()=>n.e(113).then(n.bind(null,439)),"v-31f4e97c":()=>n.e(114).then(n.bind(null,440)),"v-3694ce14":()=>n.e(115).then(n.bind(null,441)),"v-2aba85c9":()=>n.e(116).then(n.bind(null,442)),"v-b57d7aaa":()=>n.e(117).then(n.bind(null,443)),"v-555c4ccc":()=>n.e(118).then(n.bind(null,444)),"v-17f021f1":()=>n.e(119).then(n.bind(null,445)),"v-29c2a9a6":()=>n.e(120).then(n.bind(null,446)),"v-4450a94c":()=>n.e(121).then(n.bind(null,447)),"v-4933d72d":()=>n.e(122).then(n.bind(null,448)),"v-ea3f7700":()=>n.e(123).then(n.bind(null,449)),"v-42978a06":()=>n.e(124).then(n.bind(null,450)),"v-31aad69b":()=>n.e(125).then(n.bind(null,451)),"v-57119e11":()=>n.e(126).then(n.bind(null,452)),"v-7b614492":()=>n.e(127).then(n.bind(null,453)),"v-e91b9212":()=>n.e(128).then(n.bind(null,454)),"v-491acd04":()=>n.e(129).then(n.bind(null,455)),"v-54256f98":()=>n.e(130).then(n.bind(null,456)),"v-9e089f2c":()=>n.e(131).then(n.bind(null,457)),"v-0d3d092a":()=>n.e(132).then(n.bind(null,458)),"v-6f103bde":()=>n.e(133).then(n.bind(null,459)),"v-1f42625e":()=>n.e(134).then(n.bind(null,460)),"v-3ae19d8b":()=>n.e(135).then(n.bind(null,461)),"v-0792688a":()=>n.e(136).then(n.bind(null,462)),"v-267e6c49":()=>n.e(137).then(n.bind(null,463)),"v-99fa62a6":()=>n.e(138).then(n.bind(null,464)),"v-15bcd010":()=>n.e(139).then(n.bind(null,465)),"v-518d82c3":()=>n.e(140).then(n.bind(null,466)),"v-40ca211c":()=>n.e(141).then(n.bind(null,467)),"v-375d6f79":()=>n.e(142).then(n.bind(null,468)),"v-8ad6e996":()=>n.e(143).then(n.bind(null,469)),"v-4c298fed":()=>n.e(144).then(n.bind(null,470)),"v-08eab131":()=>n.e(145).then(n.bind(null,471)),"v-08afd4b1":()=>n.e(146).then(n.bind(null,472)),"v-e2fc03e2":()=>n.e(149).then(n.bind(null,473)),"v-415cd298":()=>n.e(150).then(n.bind(null,474)),"v-7ec4ede6":()=>n.e(152).then(n.bind(null,475)),"v-3e23eb06":()=>n.e(151).then(n.bind(null,476)),"v-427b9d2c":()=>n.e(154).then(n.bind(null,477)),"v-642f49fb":()=>n.e(153).then(n.bind(null,478)),"v-93da6800":()=>n.e(155).then(n.bind(null,479)),"v-02ac7740":()=>n.e(156).then(n.bind(null,480)),"v-668a7bff":()=>n.e(157).then(n.bind(null,481)),"v-adf4c11e":()=>n.e(158).then(n.bind(null,482)),"v-be2e851e":()=>n.e(159).then(n.bind(null,483)),"v-590e6280":()=>n.e(160).then(n.bind(null,484)),"v-416ea53c":()=>n.e(161).then(n.bind(null,485)),"v-5fe14fb1":()=>n.e(162).then(n.bind(null,486)),"v-28c38e47":()=>n.e(148).then(n.bind(null,487)),"v-7082d399":()=>n.e(147).then(n.bind(null,488))};function Wo(e){const t=Object.create(null);return function(n){return t[n]||(t[n]=e(n))}}const Go=/-(\w)/g,Ko=Wo(e=>e.replace(Go,(e,t)=>t?t.toUpperCase():"")),Yo=/\B([A-Z])/g,Xo=Wo(e=>e.replace(Yo,"-$1").toLowerCase()),Qo=Wo(e=>e.charAt(0).toUpperCase()+e.slice(1));function el(e,t){if(!t)return;if(e(t))return e(t);return t.includes("-")?e(Qo(Ko(t))):e(Qo(t))||e(Xo(t))}const tl=Object.assign({},qo,Vo),nl=e=>tl[e],al=e=>Vo[e],rl=e=>qo[e],il=e=>qn.component(e);function ol(e){return el(al,e)}function ll(e){return el(rl,e)}function sl(e){return el(nl,e)}function cl(e){return el(il,e)}function ul(...e){return Promise.all(e.filter(e=>e).map(async e=>{if(!cl(e)&&sl(e)){const t=await sl(e)();qn.component(e,t.default)}}))}function pl(e,t){"undefined"!=typeof window&&window.__VUEPRESS__&&(window.__VUEPRESS__[e]=t)}var dl=n(93),hl=n.n(dl),fl=n(94),ml=n.n(fl),gl={created(){if(this.siteMeta=this.$site.headTags.filter(([e])=>"meta"===e).map(([e,t])=>t),this.$ssrContext){const t=this.getMergedMetaTags();this.$ssrContext.title=this.$title,this.$ssrContext.lang=this.$lang,this.$ssrContext.pageMeta=(e=t)?e.map(e=>{let t="{t+=` ${n}="${ml()(e[n])}"`}),t+">"}).join("\n "):"",this.$ssrContext.canonicalLink=bl(this.$canonicalUrl)}var e},mounted(){this.currentMetaTags=[...document.querySelectorAll("meta")],this.updateMeta(),this.updateCanonicalLink()},methods:{updateMeta(){document.title=this.$title,document.documentElement.lang=this.$lang;const e=this.getMergedMetaTags();this.currentMetaTags=yl(e,this.currentMetaTags)},getMergedMetaTags(){const e=this.$page.frontmatter.meta||[];return hl()([{name:"description",content:this.$description}],e,this.siteMeta,kl)},updateCanonicalLink(){vl(),this.$canonicalUrl&&document.head.insertAdjacentHTML("beforeend",bl(this.$canonicalUrl))}},watch:{$page(){this.updateMeta(),this.updateCanonicalLink()}},beforeDestroy(){yl(null,this.currentMetaTags),vl()}};function vl(){const e=document.querySelector("link[rel='canonical']");e&&e.remove()}function bl(e=""){return e?``:""}function yl(e,t){if(t&&[...t].filter(e=>e.parentNode===document.head).forEach(e=>document.head.removeChild(e)),e)return e.map(e=>{const t=document.createElement("meta");return Object.keys(e).forEach(n=>{t.setAttribute(n,e[n])}),document.head.appendChild(t),t})}function kl(e){for(const t of["name","property","itemprop"])if(e.hasOwnProperty(t))return e[t]+t;return JSON.stringify(e)}var El=n(16),_l=n.n(El),xl={mounted(){window.addEventListener("scroll",this.onScroll)},methods:{onScroll:_l()((function(){this.setActiveHash()}),300),setActiveHash(){const e=[].slice.call(document.querySelectorAll(".sidebar-link")),t=[].slice.call(document.querySelectorAll(".header-anchor")).filter(t=>e.some(e=>e.hash===t.hash)),n=Math.max(window.pageYOffset,document.documentElement.scrollTop,document.body.scrollTop),a=Math.max(document.documentElement.scrollHeight,document.body.scrollHeight),r=window.innerHeight+n;for(let e=0;e=i.parentElement.offsetTop+10&&(!o||n{this.$nextTick(()=>{this.$vuepress.$set("disableScrollBehavior",!1)})})}}}},beforeDestroy(){window.removeEventListener("scroll",this.onScroll)}},wl=n(24),Al=n.n(wl),jl={mounted(){Al.a.configure({showSpinner:!1}),this.$router.beforeEach((e,t,n)=>{e.path===t.path||qn.component(e.name)||Al.a.start(),n()}),this.$router.afterEach(()=>{Al.a.done(),this.isSidebarOpen=!1})}},Bl=(n(240),Object.assign||function(e){for(var t=1;t1&&void 0!==arguments[1]?arguments[1]:{},a=window.Promise||function(e){function t(){}e(t,t)},r=function(e){var t=e.target;t!==A?-1!==y.indexOf(t)&&m({target:t}):f()},i=function(){if(!E&&w.original){var e=window.pageYOffset||document.documentElement.scrollTop||document.body.scrollTop||0;Math.abs(_-e)>x.scrollOffset&&setTimeout(f,150)}},o=function(e){var t=e.key||e.keyCode;"Escape"!==t&&"Esc"!==t&&27!==t||f()},l=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},t=e;if(e.background&&(A.style.background=e.background),e.container&&e.container instanceof Object&&(t.container=Bl({},x.container,e.container)),e.template){var n=Pl(e.template)?e.template:document.querySelector(e.template);t.template=n}return x=Bl({},x,t),y.forEach((function(e){e.dispatchEvent($l("medium-zoom:update",{detail:{zoom:j}}))})),j},s=function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};return e(Bl({},x,t))},c=function(){for(var e=arguments.length,t=Array(e),n=0;n0?t.reduce((function(e,t){return[].concat(e,Ol(t))}),[]):y;return a.forEach((function(e){e.classList.remove("medium-zoom-image"),e.dispatchEvent($l("medium-zoom:detach",{detail:{zoom:j}}))})),y=y.filter((function(e){return-1===a.indexOf(e)})),j},p=function(e,t){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};return y.forEach((function(a){a.addEventListener("medium-zoom:"+e,t,n)})),k.push({type:"medium-zoom:"+e,listener:t,options:n}),j},d=function(e,t){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};return y.forEach((function(a){a.removeEventListener("medium-zoom:"+e,t,n)})),k=k.filter((function(n){return!(n.type==="medium-zoom:"+e&&n.listener.toString()===t.toString())})),j},h=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},t=e.target,n=function(){var e={width:document.documentElement.clientWidth,height:document.documentElement.clientHeight,left:0,top:0,right:0,bottom:0},t=void 0,n=void 0;if(x.container)if(x.container instanceof Object)t=(e=Bl({},e,x.container)).width-e.left-e.right-2*x.margin,n=e.height-e.top-e.bottom-2*x.margin;else{var a=(Pl(x.container)?x.container:document.querySelector(x.container)).getBoundingClientRect(),r=a.width,i=a.height,o=a.left,l=a.top;e=Bl({},e,{width:r,height:i,left:o,top:l})}t=t||e.width-2*x.margin,n=n||e.height-2*x.margin;var s=w.zoomedHd||w.original,c=Cl(s)?t:s.naturalWidth||t,u=Cl(s)?n:s.naturalHeight||n,p=s.getBoundingClientRect(),d=p.top,h=p.left,f=p.width,m=p.height,g=Math.min(Math.max(f,c),t)/f,v=Math.min(Math.max(m,u),n)/m,b=Math.min(g,v),y="scale("+b+") translate3d("+((t-f)/2-h+x.margin+e.left)/b+"px, "+((n-m)/2-d+x.margin+e.top)/b+"px, 0)";w.zoomed.style.transform=y,w.zoomedHd&&(w.zoomedHd.style.transform=y)};return new a((function(e){if(t&&-1===y.indexOf(t))e(j);else{if(w.zoomed)e(j);else{if(t)w.original=t;else{if(!(y.length>0))return void e(j);var a=y;w.original=a[0]}if(w.original.dispatchEvent($l("medium-zoom:open",{detail:{zoom:j}})),_=window.pageYOffset||document.documentElement.scrollTop||document.body.scrollTop||0,E=!0,w.zoomed=Ul(w.original),document.body.appendChild(A),x.template){var r=Pl(x.template)?x.template:document.querySelector(x.template);w.template=document.createElement("div"),w.template.appendChild(r.content.cloneNode(!0)),document.body.appendChild(w.template)}if(w.original.parentElement&&"PICTURE"===w.original.parentElement.tagName&&w.original.currentSrc&&(w.zoomed.src=w.original.currentSrc),document.body.appendChild(w.zoomed),window.requestAnimationFrame((function(){document.body.classList.add("medium-zoom--opened")})),w.original.classList.add("medium-zoom-image--hidden"),w.zoomed.classList.add("medium-zoom-image--opened"),w.zoomed.addEventListener("click",f),w.zoomed.addEventListener("transitionend",(function t(){E=!1,w.zoomed.removeEventListener("transitionend",t),w.original.dispatchEvent($l("medium-zoom:opened",{detail:{zoom:j}})),e(j)})),w.original.getAttribute("data-zoom-src")){w.zoomedHd=w.zoomed.cloneNode(),w.zoomedHd.removeAttribute("srcset"),w.zoomedHd.removeAttribute("sizes"),w.zoomedHd.removeAttribute("loading"),w.zoomedHd.src=w.zoomed.getAttribute("data-zoom-src"),w.zoomedHd.onerror=function(){clearInterval(i),console.warn("Unable to reach the zoom image target "+w.zoomedHd.src),w.zoomedHd=null,n()};var i=setInterval((function(){w.zoomedHd.complete&&(clearInterval(i),w.zoomedHd.classList.add("medium-zoom-image--opened"),w.zoomedHd.addEventListener("click",f),document.body.appendChild(w.zoomedHd),n())}),10)}else if(w.original.hasAttribute("srcset")){w.zoomedHd=w.zoomed.cloneNode(),w.zoomedHd.removeAttribute("sizes"),w.zoomedHd.removeAttribute("loading");var o=w.zoomedHd.addEventListener("load",(function(){w.zoomedHd.removeEventListener("load",o),w.zoomedHd.classList.add("medium-zoom-image--opened"),w.zoomedHd.addEventListener("click",f),document.body.appendChild(w.zoomedHd),n()}))}else n()}}}))},f=function(){return new a((function(e){if(!E&&w.original){E=!0,document.body.classList.remove("medium-zoom--opened"),w.zoomed.style.transform="",w.zoomedHd&&(w.zoomedHd.style.transform=""),w.template&&(w.template.style.transition="opacity 150ms",w.template.style.opacity=0),w.original.dispatchEvent($l("medium-zoom:close",{detail:{zoom:j}})),w.zoomed.addEventListener("transitionend",(function t(){w.original.classList.remove("medium-zoom-image--hidden"),document.body.removeChild(w.zoomed),w.zoomedHd&&document.body.removeChild(w.zoomedHd),document.body.removeChild(A),w.zoomed.classList.remove("medium-zoom-image--opened"),w.template&&document.body.removeChild(w.template),E=!1,w.zoomed.removeEventListener("transitionend",t),w.original.dispatchEvent($l("medium-zoom:closed",{detail:{zoom:j}})),w.original=null,w.zoomed=null,w.zoomedHd=null,w.template=null,e(j)}))}else e(j)}))},m=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},t=e.target;return w.original?f():h({target:t})},g=function(){return x},v=function(){return y},b=function(){return w.original},y=[],k=[],E=!1,_=0,x=n,w={original:null,zoomed:null,zoomedHd:null,template:null};"[object Object]"===Object.prototype.toString.call(t)?x=t:(t||"string"==typeof t)&&c(t),x=Bl({margin:0,background:"#fff",scrollOffset:40,container:null,template:null},x);var A=Sl(x.background);document.addEventListener("click",r),document.addEventListener("keyup",o),document.addEventListener("scroll",i),window.addEventListener("resize",f);var j={open:h,close:f,toggle:m,update:l,clone:s,attach:c,detach:u,on:p,off:d,getOptions:g,getImages:v,getZoomedImage:b};return j},Dl={data:()=>({zoom:null}),mounted(){this.updateZoom()},updated(){this.updateZoom()},methods:{updateZoom(){setTimeout(()=>{this.zoom&&this.zoom.detach(),this.zoom=Ll(".theme-default-content :not(a) > img",void 0)},1e3)}}};n(241),n(242);class zl{constructor(){this.containerEl=document.getElementById("message-container"),this.containerEl||(this.containerEl=document.createElement("div"),this.containerEl.id="message-container",document.body.appendChild(this.containerEl))}show({text:e="",duration:t=3e3}){let n=document.createElement("div");n.className="message move-in",n.innerHTML=`\n \n \n \n
${e}
\n `,this.containerEl.appendChild(n),t>0&&setTimeout(()=>{this.close(n)},t)}close(e){e.className=e.className.replace("move-in",""),e.className+="move-out",e.addEventListener("animationend",()=>{e.remove()})}}var Il={mounted(){!!/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)||this.updateCopy()},updated(){!!/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)||this.updateCopy()},methods:{updateCopy(){setTimeout(()=>{(['div[class*="language-"] pre','div[class*="aside-code"] aside']instanceof Array||Array.isArray(['div[class*="language-"] pre','div[class*="aside-code"] aside']))&&['div[class*="language-"] pre','div[class*="aside-code"] aside'].forEach(e=>{document.querySelectorAll(e).forEach(this.generateCopyButton)})},1e3)},generateCopyButton(e){if(e.classList.contains("codecopy-enabled"))return;const t=document.createElement("i");t.className="code-copy",t.innerHTML='',t.title="copy",t.addEventListener("click",()=>{this.copyToClipboard(e.innerText)}),e.appendChild(t),e.classList.add("codecopy-enabled")},copyToClipboard(e){const t=document.createElement("textarea");t.value=e,t.setAttribute("readonly",""),t.style.position="absolute",t.style.left="-9999px",document.body.appendChild(t);const n=document.getSelection().rangeCount>0&&document.getSelection().getRangeAt(0);t.select(),document.execCommand("copy");(new zl).show({text:"copy success",duration:1e3}),document.body.removeChild(t),n&&(document.getSelection().removeAllRanges(),document.getSelection().addRange(n))}}},Ml="auto",Rl="zoom-in",Nl="zoom-out",Fl="grab",Jl="move";function Zl(e,t,n){var a=!(arguments.length>3&&void 0!==arguments[3])||arguments[3],r={passive:!1};a?e.addEventListener(t,n,r):e.removeEventListener(t,n,r)}function Hl(e,t){if(e){var n=new Image;n.onload=function(){t&&t(n)},n.src=e}}function ql(e){return e.dataset.original?e.dataset.original:"A"===e.parentNode.tagName?e.parentNode.getAttribute("href"):null}function Vl(e,t,n){!function(e){var t=Wl,n=Gl;if(e.transition){var a=e.transition;delete e.transition,e[t]=a}if(e.transform){var r=e.transform;delete e.transform,e[n]=r}}(t);var a=e.style,r={};for(var i in t)n&&(r[i]=a[i]||""),a[i]=t[i];return r}var Wl="transition",Gl="transform",Kl="transform",Yl="transitionend";var Xl=function(){},Ql={enableGrab:!0,preloadImage:!1,closeOnWindowResize:!0,transitionDuration:.4,transitionTimingFunction:"cubic-bezier(0.4, 0, 0, 1)",bgColor:"rgb(255, 255, 255)",bgOpacity:1,scaleBase:1,scaleExtra:.5,scrollThreshold:40,zIndex:998,customSize:null,onOpen:Xl,onClose:Xl,onGrab:Xl,onMove:Xl,onRelease:Xl,onBeforeOpen:Xl,onBeforeClose:Xl,onBeforeGrab:Xl,onBeforeRelease:Xl,onImageLoading:Xl,onImageLoaded:Xl},es={init:function(e){var t,n;t=this,n=e,Object.getOwnPropertyNames(Object.getPrototypeOf(t)).forEach((function(e){t[e]=t[e].bind(n)}))},click:function(e){if(e.preventDefault(),ns(e))return window.open(this.target.srcOriginal||e.currentTarget.src,"_blank");this.shown?this.released?this.close():this.release():this.open(e.currentTarget)},scroll:function(){var e=document.documentElement||document.body.parentNode||document.body,t=window.pageXOffset||e.scrollLeft,n=window.pageYOffset||e.scrollTop;null===this.lastScrollPosition&&(this.lastScrollPosition={x:t,y:n});var a=this.lastScrollPosition.x-t,r=this.lastScrollPosition.y-n,i=this.options.scrollThreshold;(Math.abs(r)>=i||Math.abs(a)>=i)&&(this.lastScrollPosition=null,this.close())},keydown:function(e){(function(e){return"Escape"===(e.key||e.code)||27===e.keyCode})(e)&&(this.released?this.close():this.release(this.close))},mousedown:function(e){if(ts(e)&&!ns(e)){e.preventDefault();var t=e.clientX,n=e.clientY;this.pressTimer=setTimeout(function(){this.grab(t,n)}.bind(this),200)}},mousemove:function(e){this.released||this.move(e.clientX,e.clientY)},mouseup:function(e){ts(e)&&!ns(e)&&(clearTimeout(this.pressTimer),this.released?this.close():this.release())},touchstart:function(e){e.preventDefault();var t=e.touches[0],n=t.clientX,a=t.clientY;this.pressTimer=setTimeout(function(){this.grab(n,a)}.bind(this),200)},touchmove:function(e){if(!this.released){var t=e.touches[0],n=t.clientX,a=t.clientY;this.move(n,a)}},touchend:function(e){(function(e){e.targetTouches.length})(e)||(clearTimeout(this.pressTimer),this.released?this.close():this.release())},clickOverlay:function(){this.close()},resizeWindow:function(){this.close()}};function ts(e){return 0===e.button}function ns(e){return e.metaKey||e.ctrlKey}var as={init:function(e){this.el=document.createElement("div"),this.instance=e,this.parent=document.body,Vl(this.el,{position:"fixed",top:0,left:0,right:0,bottom:0,opacity:0}),this.updateStyle(e.options),Zl(this.el,"click",e.handler.clickOverlay.bind(e))},updateStyle:function(e){Vl(this.el,{zIndex:e.zIndex,backgroundColor:e.bgColor,transition:"opacity\n "+e.transitionDuration+"s\n "+e.transitionTimingFunction})},insert:function(){this.parent.appendChild(this.el)},remove:function(){this.parent.removeChild(this.el)},fadeIn:function(){this.el.offsetWidth,this.el.style.opacity=this.instance.options.bgOpacity},fadeOut:function(){this.el.style.opacity=0}},rs="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},is=function(){function e(e,t){for(var n=0;nm||d>g)return{x:m,y:g}}return{x:d,y:d}}};function ss(){var e=document.documentElement;return{x:Math.min(e.clientWidth,window.innerWidth)/2,y:Math.min(e.clientHeight,window.innerHeight)/2}}function cs(e,t,n){["mousedown","mousemove","mouseup","touchstart","touchmove","touchend"].forEach((function(a){Zl(e,a,t[a],n)}))}var us=function(){function e(t){!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,e),this.target=Object.create(ls),this.overlay=Object.create(as),this.handler=Object.create(es),this.body=document.body,this.shown=!1,this.lock=!1,this.released=!0,this.lastScrollPosition=null,this.pressTimer=null,this.options=os({},Ql,t),this.overlay.init(this),this.handler.init(this)}return is(e,[{key:"listen",value:function(e){if("string"==typeof e)for(var t=document.querySelectorAll(e),n=t.length;n--;)this.listen(t[n]);else"IMG"===e.tagName&&(e.style.cursor=Rl,Zl(e,"click",this.handler.click),this.options.preloadImage&&Hl(ql(e)));return this}},{key:"config",value:function(e){return e?(os(this.options,e),this.overlay.updateStyle(this.options),this):this.options}},{key:"open",value:function(e){var t=this,n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:this.options.onOpen;if(!this.shown&&!this.lock){var a="string"==typeof e?document.querySelector(e):e;if("IMG"===a.tagName){if(this.options.onBeforeOpen(a),this.target.init(a,this),!this.options.preloadImage){var r=this.target.srcOriginal;null!=r&&(this.options.onImageLoading(a),Hl(r,this.options.onImageLoaded))}this.shown=!0,this.lock=!0,this.target.zoomIn(),this.overlay.insert(),this.overlay.fadeIn(),Zl(document,"scroll",this.handler.scroll),Zl(document,"keydown",this.handler.keydown),this.options.closeOnWindowResize&&Zl(window,"resize",this.handler.resizeWindow);var i=function e(){Zl(a,Yl,e,!1),t.lock=!1,t.target.upgradeSource(),t.options.enableGrab&&cs(document,t.handler,!0),n(a)};return Zl(a,Yl,i),this}}}},{key:"close",value:function(){var e=this,t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:this.options.onClose;if(this.shown&&!this.lock){var n=this.target.el;this.options.onBeforeClose(n),this.lock=!0,this.body.style.cursor=Ml,this.overlay.fadeOut(),this.target.zoomOut(),Zl(document,"scroll",this.handler.scroll,!1),Zl(document,"keydown",this.handler.keydown,!1),this.options.closeOnWindowResize&&Zl(window,"resize",this.handler.resizeWindow,!1);var a=function a(){Zl(n,Yl,a,!1),e.shown=!1,e.lock=!1,e.target.downgradeSource(),e.options.enableGrab&&cs(document,e.handler,!1),e.target.restoreCloseStyle(),e.overlay.remove(),t(n)};return Zl(n,Yl,a),this}}},{key:"grab",value:function(e,t){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:this.options.scaleExtra,a=arguments.length>3&&void 0!==arguments[3]?arguments[3]:this.options.onGrab;if(this.shown&&!this.lock){var r=this.target.el;this.options.onBeforeGrab(r),this.released=!1,this.target.grab(e,t,n);var i=function e(){Zl(r,Yl,e,!1),a(r)};return Zl(r,Yl,i),this}}},{key:"move",value:function(e,t){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:this.options.scaleExtra,a=arguments.length>3&&void 0!==arguments[3]?arguments[3]:this.options.onMove;if(this.shown&&!this.lock){this.released=!1,this.body.style.cursor=Jl,this.target.move(e,t,n);var r=this.target.el,i=function e(){Zl(r,Yl,e,!1),a(r)};return Zl(r,Yl,i),this}}},{key:"release",value:function(){var e=this,t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:this.options.onRelease;if(this.shown&&!this.lock){var n=this.target.el;this.options.onBeforeRelease(n),this.lock=!0,this.body.style.cursor=Ml,this.target.restoreOpenStyle();var a=function a(){Zl(n,Yl,a,!1),e.lock=!1,e.released=!0,t(n)};return Zl(n,Yl,a),this}}}]),e}();const ps=JSON.parse('{"bgColor":"rgba(0,0,0,0.6)"}'),ds=Number("500");class hs{constructor(){this.instance=new us(ps)}update(e=".theme-vdoing-content img:not(.no-zoom)"){"undefined"!=typeof window&&this.instance.listen(e)}updateDelay(e=".theme-vdoing-content img:not(.no-zoom)",t=ds){setTimeout(()=>this.update(e),t)}}var fs=[gl,xl,jl,Dl,Il,{watch:{"$page.path"(){void 0!==this.$vuepress.zooming&&this.$vuepress.zooming.updateDelay()}},mounted(){this.$vuepress.zooming=new hs,this.$vuepress.zooming.updateDelay()}}],ms={name:"GlobalLayout",computed:{layout(){const e=this.getLayout();return pl("layout",e),qn.component(e)}},methods:{getLayout(){if(this.$page.path){const e=this.$page.frontmatter.layout;return e&&(this.$vuepress.getLayoutAsyncComponent(e)||this.$vuepress.getVueComponent(e))?e:"Layout"}return"NotFound"}}},gs=n(4),vs=Object(gs.a)(ms,(function(){return(0,this._self._c)(this.layout,{tag:"component"})}),[],!1,null,null,null).exports;!function(e,t,n){switch(t){case"components":e[t]||(e[t]={}),Object.assign(e[t],n);break;case"mixins":e[t]||(e[t]=[]),e[t].push(...n);break;default:throw new Error("Unknown option name.")}}(vs,"mixins",fs);const bs=[{name:"v-9b6f56f2",path:"/fe/",component:vs,beforeEnter:(e,t,n)=>{ul("Layout","v-9b6f56f2").then(n)}},{path:"/fe/index.html",redirect:"/fe/"},{path:"/00.目录页/01.前端.html",redirect:"/fe/"},{name:"v-793035b6",path:"/other/",component:vs,beforeEnter:(e,t,n)=>{ul("Layout","v-793035b6").then(n)}},{path:"/other/index.html",redirect:"/other/"},{path:"/00.目录页/0400.其他.html",redirect:"/other/"},{name:"v-2cb2f234",path:"/server/",component:vs,beforeEnter:(e,t,n)=>{ul("Layout","v-2cb2f234").then(n)}},{path:"/server/index.html",redirect:"/server/"},{path:"/00.目录页/0401.server.html",redirect:"/server/"},{name:"v-398ec241",path:"/tool/",component:vs,beforeEnter:(e,t,n)=>{ul("Layout","v-398ec241").then(n)}},{path:"/tool/index.html",redirect:"/tool/"},{path:"/00.目录页/0401.工具.html",redirect:"/tool/"},{name:"v-73eb8dca",path:"/blog/",component:vs,beforeEnter:(e,t,n)=>{ul("Layout","v-73eb8dca").then(n)}},{path:"/blog/index.html",redirect:"/blog/"},{path:"/00.目录页/0405.博客.html",redirect:"/blog/"},{name:"v-0aa82876",path:"/java/",component:vs,beforeEnter:(e,t,n)=>{ul("Layout","v-0aa82876").then(n)}},{path:"/java/index.html",redirect:"/java/"},{path:"/00.目录页/0408.java.html",redirect:"/java/"},{name:"v-19390582",path:"/python/",component:vs,beforeEnter:(e,t,n)=>{ul("Layout","v-19390582").then(n)}},{path:"/python/index.html",redirect:"/python/"},{path:"/00.目录页/0408.python.html",redirect:"/python/"},{name:"v-bbba8304",path:"/more/",component:vs,beforeEnter:(e,t,n)=>{ul("Layout","v-bbba8304").then(n)}},{path:"/more/index.html",redirect:"/more/"},{path:"/00.目录页/0410.more.html",redirect:"/more/"},{name:"v-4931c646",path:"/mime/",component:vs,beforeEnter:(e,t,n)=>{ul("Layout","v-4931c646").then(n)}},{path:"/mime/index.html",redirect:"/mime/"},{path:"/00.目录页/0500.mine.html",redirect:"/mime/"},{name:"v-49a8aada",path:"/web/",component:vs,beforeEnter:(e,t,n)=>{ul("Layout","v-49a8aada").then(n)}},{path:"/web/index.html",redirect:"/web/"},{path:"/01.前端/02.web.html",redirect:"/web/"},{name:"v-7f01ed9e",path:"/android/",component:vs,beforeEnter:(e,t,n)=>{ul("Layout","v-7f01ed9e").then(n)}},{path:"/android/index.html",redirect:"/android/"},{path:"/01.前端/05.android.html",redirect:"/android/"},{name:"v-27216da0",path:"/iOS/",component:vs,beforeEnter:(e,t,n)=>{ul("Layout","v-27216da0").then(n)}},{path:"/iOS/index.html",redirect:"/iOS/"},{path:"/01.前端/06.iOS.html",redirect:"/iOS/"},{name:"v-5d7cf408",path:"/react/",component:vs,beforeEnter:(e,t,n)=>{ul("Layout","v-5d7cf408").then(n)}},{path:"/react/index.html",redirect:"/react/"},{path:"/01.前端/11.react.html",redirect:"/react/"},{name:"v-0c593678",path:"/vue/",component:vs,beforeEnter:(e,t,n)=>{ul("Layout","v-0c593678").then(n)}},{path:"/vue/index.html",redirect:"/vue/"},{path:"/01.前端/12.vue.html",redirect:"/vue/"},{name:"v-2c61710f",path:"/pages/0140a0/",component:vs,beforeEnter:(e,t,n)=>{ul("Layout","v-2c61710f").then(n)}},{path:"/pages/0140a0/index.html",redirect:"/pages/0140a0/"},{path:"/04.其他/01.工具/00.shell.html",redirect:"/pages/0140a0/"},{name:"v-520581ee",path:"/pages/7071e6/",component:vs,beforeEnter:(e,t,n)=>{ul("Layout","v-520581ee").then(n)}},{path:"/pages/7071e6/index.html",redirect:"/pages/7071e6/"},{path:"/04.其他/01.工具/01.git.html",redirect:"/pages/7071e6/"},{name:"v-26d8a1d0",path:"/pages/3869be/",component:vs,beforeEnter:(e,t,n)=>{ul("Layout","v-26d8a1d0").then(n)}},{path:"/pages/3869be/index.html",redirect:"/pages/3869be/"},{path:"/04.其他/01.工具/02.web工具.html",redirect:"/pages/3869be/"},{name:"v-12b4125a",path:"/pages/669dfc/",component:vs,beforeEnter:(e,t,n)=>{ul("Layout","v-12b4125a").then(n)}},{path:"/pages/669dfc/index.html",redirect:"/pages/669dfc/"},{path:"/04.其他/01.工具/03.npm.html",redirect:"/pages/669dfc/"},{name:"v-fdbad532",path:"/pages/37f363/",component:vs,beforeEnter:(e,t,n)=>{ul("Layout","v-fdbad532").then(n)}},{path:"/pages/37f363/index.html",redirect:"/pages/37f363/"},{path:"/04.其他/01.工具/05.adb.html",redirect:"/pages/37f363/"},{name:"v-69225a59",path:"/pages/907793/",component:vs,beforeEnter:(e,t,n)=>{ul("Layout","v-69225a59").then(n)}},{path:"/pages/907793/index.html",redirect:"/pages/907793/"},{path:"/04.其他/01.工具/06.aapt.html",redirect:"/pages/907793/"},{name:"v-c88140a0",path:"/pages/977efe/",component:vs,beforeEnter:(e,t,n)=>{ul("Layout","v-c88140a0").then(n)}},{path:"/pages/977efe/index.html",redirect:"/pages/977efe/"},{path:"/04.其他/01.工具/07.c++工具.html",redirect:"/pages/977efe/"},{name:"v-d88d59ce",path:"/pages/7ee6cc/",component:vs,beforeEnter:(e,t,n)=>{ul("Layout","v-d88d59ce").then(n)}},{path:"/pages/7ee6cc/index.html",redirect:"/pages/7ee6cc/"},{path:"/04.其他/01.工具/08.pip3.html",redirect:"/pages/7ee6cc/"},{name:"v-07c2d32e",path:"/pages/89d231/",component:vs,beforeEnter:(e,t,n)=>{ul("Layout","v-07c2d32e").then(n)}},{path:"/pages/89d231/index.html",redirect:"/pages/89d231/"},{path:"/04.其他/01.工具/09.vim.html",redirect:"/pages/89d231/"},{name:"v-209934f9",path:"/pages/1c262c/",component:vs,beforeEnter:(e,t,n)=>{ul("Layout","v-209934f9").then(n)}},{path:"/pages/1c262c/index.html",redirect:"/pages/1c262c/"},{path:"/04.其他/01.工具/12.docker.html",redirect:"/pages/1c262c/"},{name:"v-3c45a879",path:"/pages/8cb2e1/",component:vs,beforeEnter:(e,t,n)=>{ul("Layout","v-3c45a879").then(n)}},{path:"/pages/8cb2e1/index.html",redirect:"/pages/8cb2e1/"},{path:"/04.其他/01.工具/13.unbuntuOnWindows.html",redirect:"/pages/8cb2e1/"},{name:"v-d5a6414e",path:"/pages/bd17b5/",component:vs,beforeEnter:(e,t,n)=>{ul("Layout","v-d5a6414e").then(n)}},{path:"/pages/bd17b5/index.html",redirect:"/pages/bd17b5/"},{path:"/04.其他/01.工具/14.ides.html",redirect:"/pages/bd17b5/"},{name:"v-49456eb6",path:"/pages/f9c14d/",component:vs,beforeEnter:(e,t,n)=>{ul("Layout","v-49456eb6").then(n)}},{path:"/pages/f9c14d/index.html",redirect:"/pages/f9c14d/"},{path:"/04.其他/01.工具/15.zsh高效的shell.html",redirect:"/pages/f9c14d/"},{name:"v-16dcf019",path:"/pages/514538/",component:vs,beforeEnter:(e,t,n)=>{ul("Layout","v-16dcf019").then(n)}},{path:"/pages/514538/index.html",redirect:"/pages/514538/"},{path:"/04.其他/01.工具/16.github.html",redirect:"/pages/514538/"},{name:"v-192249b9",path:"/pages/0cdfba/",component:vs,beforeEnter:(e,t,n)=>{ul("Layout","v-192249b9").then(n)}},{path:"/pages/0cdfba/index.html",redirect:"/pages/0cdfba/"},{path:"/04.其他/01.工具/20.gradle.html",redirect:"/pages/0cdfba/"},{name:"v-7e599067",path:"/pages/c80e98/",component:vs,beforeEnter:(e,t,n)=>{ul("Layout","v-7e599067").then(n)}},{path:"/pages/c80e98/index.html",redirect:"/pages/c80e98/"},{path:"/04.其他/01.工具/21.mvn.html",redirect:"/pages/c80e98/"},{name:"v-0aab8a99",path:"/pages/79f386/",component:vs,beforeEnter:(e,t,n)=>{ul("Layout","v-0aab8a99").then(n)}},{path:"/pages/79f386/index.html",redirect:"/pages/79f386/"},{path:"/04.其他/01.工具/50.jadx.html",redirect:"/pages/79f386/"},{name:"v-913bd424",path:"/pages/cb9d0f/",component:vs,beforeEnter:(e,t,n)=>{ul("Layout","v-913bd424").then(n)}},{path:"/pages/cb9d0f/index.html",redirect:"/pages/cb9d0f/"},{path:"/04.其他/02.网络/00.网络.html",redirect:"/pages/cb9d0f/"},{name:"v-5ca2e717",path:"/pages/2a8b7b/",component:vs,beforeEnter:(e,t,n)=>{ul("Layout","v-5ca2e717").then(n)}},{path:"/pages/2a8b7b/index.html",redirect:"/pages/2a8b7b/"},{path:"/04.其他/02.网络/01.HTTP.html",redirect:"/pages/2a8b7b/"},{name:"v-0f7771e7",path:"/pages/3dd4b2/",component:vs,beforeEnter:(e,t,n)=>{ul("Layout","v-0f7771e7").then(n)}},{path:"/pages/3dd4b2/index.html",redirect:"/pages/3dd4b2/"},{path:"/04.其他/02.网络/02.HTTPS.html",redirect:"/pages/3dd4b2/"},{name:"v-18dff181",path:"/pages/59b0a9/",component:vs,beforeEnter:(e,t,n)=>{ul("Layout","v-18dff181").then(n)}},{path:"/pages/59b0a9/index.html",redirect:"/pages/59b0a9/"},{path:"/04.其他/02.网络/03.CDN-DNS-httpDNS.html",redirect:"/pages/59b0a9/"},{name:"v-070ecef7",path:"/pages/f1d871/",component:vs,beforeEnter:(e,t,n)=>{ul("Layout","v-070ecef7").then(n)}},{path:"/pages/f1d871/index.html",redirect:"/pages/f1d871/"},{path:"/04.其他/02.网络/04.okhttp.html",redirect:"/pages/f1d871/"},{name:"v-1b2f2f72",path:"/pages/109caf/",component:vs,beforeEnter:(e,t,n)=>{ul("Layout","v-1b2f2f72").then(n)}},{path:"/pages/109caf/index.html",redirect:"/pages/109caf/"},{path:"/04.其他/02.网络/05.移动端的网络优化.html",redirect:"/pages/109caf/"},{name:"v-7816d697",path:"/pages/10a997/",component:vs,beforeEnter:(e,t,n)=>{ul("Layout","v-7816d697").then(n)}},{path:"/pages/10a997/index.html",redirect:"/pages/10a997/"},{path:"/04.其他/02.网络/06.websocket-socket.html",redirect:"/pages/10a997/"},{name:"v-86d5fbe8",path:"/pages/6ea216/",component:vs,beforeEnter:(e,t,n)=>{ul("Layout","v-86d5fbe8").then(n)}},{path:"/pages/6ea216/index.html",redirect:"/pages/6ea216/"},{path:"/04.其他/03.语言/01.C&C++/01.前言.html",redirect:"/pages/6ea216/"},{name:"v-12e360e7",path:"/pages/ca8e7a/",component:vs,beforeEnter:(e,t,n)=>{ul("Layout","v-12e360e7").then(n)}},{path:"/pages/ca8e7a/index.html",redirect:"/pages/ca8e7a/"},{path:"/04.其他/03.语言/01.C&C++/05.C++面试突击.html",redirect:"/pages/ca8e7a/"},{name:"v-15dd7598",path:"/pages/df7642/",component:vs,beforeEnter:(e,t,n)=>{ul("Layout","v-15dd7598").then(n)}},{path:"/pages/df7642/index.html",redirect:"/pages/df7642/"},{path:"/04.其他/05.博客/01.写博客的那些事.html",redirect:"/pages/df7642/"},{name:"v-609ee02a",path:"/pages/30ec1d/",component:vs,beforeEnter:(e,t,n)=>{ul("Layout","v-609ee02a").then(n)}},{path:"/pages/30ec1d/index.html",redirect:"/pages/30ec1d/"},{path:"/04.其他/05.博客/02.vuepress简单记录.html",redirect:"/pages/30ec1d/"},{name:"v-305a0220",path:"/pages/a96c0f/",component:vs,beforeEnter:(e,t,n)=>{ul("Layout","v-305a0220").then(n)}},{path:"/pages/a96c0f/index.html",redirect:"/pages/a96c0f/"},{path:"/04.其他/05.博客/03.GitHub Actions 实现自动部署静态博客.html",redirect:"/pages/a96c0f/"},{name:"v-5178a0a2",path:"/pages/857c89/",component:vs,beforeEnter:(e,t,n)=>{ul("Layout","v-5178a0a2").then(n)}},{path:"/pages/857c89/index.html",redirect:"/pages/857c89/"},{path:"/04.其他/06.side-project/02.快速实现.html",redirect:"/pages/857c89/"},{name:"v-968fc044",path:"/pages/186356/",component:vs,beforeEnter:(e,t,n)=>{ul("Layout","v-968fc044").then(n)}},{path:"/pages/186356/index.html",redirect:"/pages/186356/"},{path:"/04.其他/07.成长/02.管理说.html",redirect:"/pages/186356/"},{name:"v-32c1407b",path:"/pages/bea5e2/",component:vs,beforeEnter:(e,t,n)=>{ul("Layout","v-32c1407b").then(n)}},{path:"/pages/bea5e2/index.html",redirect:"/pages/bea5e2/"},{path:"/04.其他/07.成长/03.coding.html",redirect:"/pages/bea5e2/"},{name:"v-98f03ec0",path:"/pages/c38a8f/",component:vs,beforeEnter:(e,t,n)=>{ul("Layout","v-98f03ec0").then(n)}},{path:"/pages/c38a8f/index.html",redirect:"/pages/c38a8f/"},{path:"/04.其他/08.java/01.tutorial.html",redirect:"/pages/c38a8f/"},{name:"v-90d8d00a",path:"/pages/b21fed/",component:vs,beforeEnter:(e,t,n)=>{ul("Layout","v-90d8d00a").then(n)}},{path:"/pages/b21fed/index.html",redirect:"/pages/b21fed/"},{path:"/04.其他/07.成长/10.如何睡觉.html",redirect:"/pages/b21fed/"},{name:"v-59d0a910",path:"/pages/c3229c/",component:vs,beforeEnter:(e,t,n)=>{ul("Layout","v-59d0a910").then(n)}},{path:"/pages/c3229c/index.html",redirect:"/pages/c3229c/"},{path:"/04.其他/08.java/100.UnSafe.html",redirect:"/pages/c3229c/"},{name:"v-409f96f4",path:"/pages/55dc87/",component:vs,beforeEnter:(e,t,n)=>{ul("Layout","v-409f96f4").then(n)}},{path:"/pages/55dc87/index.html",redirect:"/pages/55dc87/"},{path:"/04.其他/08.java/101.集合.html",redirect:"/pages/55dc87/"},{name:"v-21640095",path:"/pages/ed7a6a/",component:vs,beforeEnter:(e,t,n)=>{ul("Layout","v-21640095").then(n)}},{path:"/pages/ed7a6a/index.html",redirect:"/pages/ed7a6a/"},{path:"/04.其他/08.java/102.Class类.html",redirect:"/pages/ed7a6a/"},{name:"v-01db55a2",path:"/pages/935419/",component:vs,beforeEnter:(e,t,n)=>{ul("Layout","v-01db55a2").then(n)}},{path:"/pages/935419/index.html",redirect:"/pages/935419/"},{path:"/04.其他/08.java/50.使用 Jenv 实现 Jdk 多版本管理.html",redirect:"/pages/935419/"},{name:"v-d3a2f914",path:"/pages/18abfe/",component:vs,beforeEnter:(e,t,n)=>{ul("Layout","v-d3a2f914").then(n)}},{path:"/pages/18abfe/index.html",redirect:"/pages/18abfe/"},{path:"/04.其他/09.linux/01.tutorial.html",redirect:"/pages/18abfe/"},{name:"v-68e19f6a",path:"/pages/086701/",component:vs,beforeEnter:(e,t,n)=>{ul("Layout","v-68e19f6a").then(n)}},{path:"/pages/086701/index.html",redirect:"/pages/086701/"},{path:"/04.其他/10.更多/10.音视频概述.html",redirect:"/pages/086701/"},{name:"v-3ee66df2",path:"/pages/d3b34e/",component:vs,beforeEnter:(e,t,n)=>{ul("Layout","v-3ee66df2").then(n)}},{path:"/pages/d3b34e/index.html",redirect:"/pages/d3b34e/"},{path:"/04.其他/10.更多/100.测试页面.html",redirect:"/pages/d3b34e/"},{name:"v-0461446e",path:"/pages/6cd2e1/",component:vs,beforeEnter:(e,t,n)=>{ul("Layout","v-0461446e").then(n)}},{path:"/pages/6cd2e1/index.html",redirect:"/pages/6cd2e1/"},{path:"/04.其他/10.更多/101.沟通的艺术.html",redirect:"/pages/6cd2e1/"},{name:"v-ab0b636a",path:"/pages/d9fade/",component:vs,beforeEnter:(e,t,n)=>{ul("Layout","v-ab0b636a").then(n)}},{path:"/pages/d9fade/index.html",redirect:"/pages/d9fade/"},{path:"/04.其他/10.更多/12.效率.html",redirect:"/pages/d9fade/"},{name:"v-033ef56a",path:"/pages/f7262c/",component:vs,beforeEnter:(e,t,n)=>{ul("Layout","v-033ef56a").then(n)}},{path:"/pages/f7262c/index.html",redirect:"/pages/f7262c/"},{path:"/04.其他/10.更多/13.技术专业词汇.html",redirect:"/pages/f7262c/"},{name:"v-6f79c7d0",path:"/pages/db8380/",component:vs,beforeEnter:(e,t,n)=>{ul("Layout","v-6f79c7d0").then(n)}},{path:"/pages/db8380/index.html",redirect:"/pages/db8380/"},{path:"/04.其他/10.更多/14.设计模式和思想.html",redirect:"/pages/db8380/"},{name:"v-718a15ee",path:"/pages/0fe5d6/",component:vs,beforeEnter:(e,t,n)=>{ul("Layout","v-718a15ee").then(n)}},{path:"/pages/0fe5d6/index.html",redirect:"/pages/0fe5d6/"},{path:"/04.其他/10.更多/20.frida.html",redirect:"/pages/0fe5d6/"},{name:"v-1519562b",path:"/pages/10e7db/",component:vs,beforeEnter:(e,t,n)=>{ul("Layout","v-1519562b").then(n)}},{path:"/pages/10e7db/index.html",redirect:"/pages/10e7db/"},{path:"/04.其他/10.更多/21.Android密钥库系统.html",redirect:"/pages/10e7db/"},{name:"v-8685c0b6",path:"/pages/03456e/",component:vs,beforeEnter:(e,t,n)=>{ul("Layout","v-8685c0b6").then(n)}},{path:"/pages/03456e/index.html",redirect:"/pages/03456e/"},{path:"/04.其他/10.更多/30.使用腾讯云服务器.html",redirect:"/pages/03456e/"},{name:"v-37fae6a5",path:"/pages/3d30c9/",component:vs,beforeEnter:(e,t,n)=>{ul("Layout","v-37fae6a5").then(n)}},{path:"/pages/3d30c9/index.html",redirect:"/pages/3d30c9/"},{path:"/04.其他/10.更多/5.正则.html",redirect:"/pages/3d30c9/"},{name:"v-a106e244",path:"/pages/7c68cb/",component:vs,beforeEnter:(e,t,n)=>{ul("Layout","v-a106e244").then(n)}},{path:"/pages/7c68cb/index.html",redirect:"/pages/7c68cb/"},{path:"/04.其他/10.更多/96.读kk大神聊房价.html",redirect:"/pages/7c68cb/"},{name:"v-e5a14ea8",path:"/pages/2af3e9/",component:vs,beforeEnter:(e,t,n)=>{ul("Layout","v-e5a14ea8").then(n)}},{path:"/pages/2af3e9/index.html",redirect:"/pages/2af3e9/"},{path:"/04.其他/10.更多/97.效率秘籍.html",redirect:"/pages/2af3e9/"},{name:"v-f28180c4",path:"/pages/3adccf/",component:vs,beforeEnter:(e,t,n)=>{ul("Layout","v-f28180c4").then(n)}},{path:"/pages/3adccf/index.html",redirect:"/pages/3adccf/"},{path:"/04.其他/10.更多/98.mac常用工具使用.html",redirect:"/pages/3adccf/"},{name:"v-6c8e6ac8",path:"/pages/c76462/",component:vs,beforeEnter:(e,t,n)=>{ul("Layout","v-6c8e6ac8").then(n)}},{path:"/pages/c76462/index.html",redirect:"/pages/c76462/"},{path:"/04.其他/10.更多/99.财经基础.html",redirect:"/pages/c76462/"},{name:"v-5a42538e",path:"/pages/79c121/",component:vs,beforeEnter:(e,t,n)=>{ul("Layout","v-5a42538e").then(n)}},{path:"/pages/79c121/index.html",redirect:"/pages/79c121/"},{path:"/04.其他/11.生活方式/01.tiktok在国内使用.html",redirect:"/pages/79c121/"},{name:"v-1cd3a514",path:"/pages/5a96b7/",component:vs,beforeEnter:(e,t,n)=>{ul("Layout","v-1cd3a514").then(n)}},{path:"/pages/5a96b7/index.html",redirect:"/pages/5a96b7/"},{path:"/05.收藏夹/01.网站.html",redirect:"/pages/5a96b7/"},{name:"v-f470e9b6",path:"/archives/",component:vs,beforeEnter:(e,t,n)=>{ul("Layout","v-f470e9b6").then(n)}},{path:"/archives/index.html",redirect:"/archives/"},{path:"/@pages/archivesPage.html",redirect:"/archives/"},{name:"v-5f92b685",path:"/categories/",component:vs,beforeEnter:(e,t,n)=>{ul("Layout","v-5f92b685").then(n)}},{path:"/categories/index.html",redirect:"/categories/"},{path:"/@pages/categoriesPage.html",redirect:"/categories/"},{name:"v-6b12deb6",path:"/tags/",component:vs,beforeEnter:(e,t,n)=>{ul("Layout","v-6b12deb6").then(n)}},{path:"/tags/index.html",redirect:"/tags/"},{path:"/@pages/tagsPage.html",redirect:"/tags/"},{name:"v-5cfab93e",path:"/",component:vs,beforeEnter:(e,t,n)=>{ul("Layout","v-5cfab93e").then(n)}},{path:"/index.html",redirect:"/"},{name:"v-11478c3a",path:"/pages/1bc90b/",component:vs,beforeEnter:(e,t,n)=>{ul("Layout","v-11478c3a").then(n)}},{path:"/pages/1bc90b/index.html",redirect:"/pages/1bc90b/"},{path:"/mine/1000.switch.html",redirect:"/pages/1bc90b/"},{name:"v-352e8304",path:"/pages/6c1d02/",component:vs,beforeEnter:(e,t,n)=>{ul("Layout","v-352e8304").then(n)}},{path:"/pages/6c1d02/index.html",redirect:"/pages/6c1d02/"},{path:"/mine/900.小伟小娟/100.小伟和小娟.html",redirect:"/pages/6c1d02/"},{name:"v-823cdc00",path:"/pages/aaf954/",component:vs,beforeEnter:(e,t,n)=>{ul("Layout","v-823cdc00").then(n)}},{path:"/pages/aaf954/index.html",redirect:"/pages/aaf954/"},{path:"/mine/999.gradle鉴权脚本.html",redirect:"/pages/aaf954/"},{name:"v-31f4e97c",path:"/pages/dd1044/",component:vs,beforeEnter:(e,t,n)=>{ul("Layout","v-31f4e97c").then(n)}},{path:"/pages/dd1044/index.html",redirect:"/pages/dd1044/"},{path:"/《android》/00.Android概述.html",redirect:"/pages/dd1044/"},{name:"v-3694ce14",path:"/pages/420ab6/",component:vs,beforeEnter:(e,t,n)=>{ul("Layout","v-3694ce14").then(n)}},{path:"/pages/420ab6/index.html",redirect:"/pages/420ab6/"},{path:"/《android》/01.android图形系统.html",redirect:"/pages/420ab6/"},{name:"v-2aba85c9",path:"/pages/21df4f/",component:vs,beforeEnter:(e,t,n)=>{ul("Layout","v-2aba85c9").then(n)}},{path:"/pages/21df4f/index.html",redirect:"/pages/21df4f/"},{path:"/《android》/1000.其他/01.生产环境Message分发处理设计.html",redirect:"/pages/21df4f/"},{name:"v-b57d7aaa",path:"/pages/eae245/",component:vs,beforeEnter:(e,t,n)=>{ul("Layout","v-b57d7aaa").then(n)}},{path:"/pages/eae245/index.html",redirect:"/pages/eae245/"},{path:"/《android》/1000.其他/50.卡顿分析工具.html",redirect:"/pages/eae245/"},{name:"v-555c4ccc",path:"/pages/29a4de/",component:vs,beforeEnter:(e,t,n)=>{ul("Layout","v-555c4ccc").then(n)}},{path:"/pages/29a4de/index.html",redirect:"/pages/29a4de/"},{path:"/《android》/1000.其他/51.perfetto.html",redirect:"/pages/29a4de/"},{name:"v-17f021f1",path:"/pages/cd0789/",component:vs,beforeEnter:(e,t,n)=>{ul("Layout","v-17f021f1").then(n)}},{path:"/pages/cd0789/index.html",redirect:"/pages/cd0789/"},{path:"/《android》/1000.其他/52.提升UI加载速度的几点思考.html",redirect:"/pages/cd0789/"},{name:"v-29c2a9a6",path:"/pages/5d8ba8/",component:vs,beforeEnter:(e,t,n)=>{ul("Layout","v-29c2a9a6").then(n)}},{path:"/pages/5d8ba8/index.html",redirect:"/pages/5d8ba8/"},{path:"/《android》/1000.其他/53.Android零耗时首帧体验整理.html",redirect:"/pages/5d8ba8/"},{name:"v-4450a94c",path:"/pages/d2d3e5/",component:vs,beforeEnter:(e,t,n)=>{ul("Layout","v-4450a94c").then(n)}},{path:"/pages/d2d3e5/index.html",redirect:"/pages/d2d3e5/"},{path:"/《android》/1000.其他/54.jsbridge.html",redirect:"/pages/d2d3e5/"},{name:"v-4933d72d",path:"/pages/b6bad0/",component:vs,beforeEnter:(e,t,n)=>{ul("Layout","v-4933d72d").then(n)}},{path:"/pages/b6bad0/index.html",redirect:"/pages/b6bad0/"},{path:"/《android》/5.性能/1.Android稳定性治理.html",redirect:"/pages/b6bad0/"},{name:"v-ea3f7700",path:"/pages/9b0a57/",component:vs,beforeEnter:(e,t,n)=>{ul("Layout","v-ea3f7700").then(n)}},{path:"/pages/9b0a57/index.html",redirect:"/pages/9b0a57/"},{path:"/《android》/5.性能/100.apm相关概念.html",redirect:"/pages/9b0a57/"},{name:"v-42978a06",path:"/pages/a0d7dc/",component:vs,beforeEnter:(e,t,n)=>{ul("Layout","v-42978a06").then(n)}},{path:"/pages/a0d7dc/index.html",redirect:"/pages/a0d7dc/"},{path:"/《android》/5.性能/12.Android低端机性能优化.html",redirect:"/pages/a0d7dc/"},{name:"v-31aad69b",path:"/pages/c8fb65/",component:vs,beforeEnter:(e,t,n)=>{ul("Layout","v-31aad69b").then(n)}},{path:"/pages/c8fb65/index.html",redirect:"/pages/c8fb65/"},{path:"/《android》/6.三方库解析/01.retrofit动态代理设计.html",redirect:"/pages/c8fb65/"},{name:"v-57119e11",path:"/pages/12d86f/",component:vs,beforeEnter:(e,t,n)=>{ul("Layout","v-57119e11").then(n)}},{path:"/pages/12d86f/index.html",redirect:"/pages/12d86f/"},{path:"/《iOS》/01.tutorial.html",redirect:"/pages/12d86f/"},{name:"v-7b614492",path:"/pages/4595e1/",component:vs,beforeEnter:(e,t,n)=>{ul("Layout","v-7b614492").then(n)}},{path:"/pages/4595e1/index.html",redirect:"/pages/4595e1/"},{path:"/《python》/00.python学习.html",redirect:"/pages/4595e1/"},{name:"v-e91b9212",path:"/pages/02f88a/",component:vs,beforeEnter:(e,t,n)=>{ul("Layout","v-e91b9212").then(n)}},{path:"/pages/02f88a/index.html",redirect:"/pages/02f88a/"},{path:"/《python》/01.语法/10.字符串.html",redirect:"/pages/02f88a/"},{name:"v-491acd04",path:"/pages/140cb3/",component:vs,beforeEnter:(e,t,n)=>{ul("Layout","v-491acd04").then(n)}},{path:"/pages/140cb3/index.html",redirect:"/pages/140cb3/"},{path:"/《python》/10.其他/01.python snippet code.html",redirect:"/pages/140cb3/"},{name:"v-54256f98",path:"/pages/dc1698/",component:vs,beforeEnter:(e,t,n)=>{ul("Layout","v-54256f98").then(n)}},{path:"/pages/dc1698/index.html",redirect:"/pages/dc1698/"},{path:"/《python》/10.其他/02.python版本管理.html",redirect:"/pages/dc1698/"},{name:"v-9e089f2c",path:"/pages/3aeda3/",component:vs,beforeEnter:(e,t,n)=>{ul("Layout","v-9e089f2c").then(n)}},{path:"/pages/3aeda3/index.html",redirect:"/pages/3aeda3/"},{path:"/《python》/100.BeautifulSoup的使用.html",redirect:"/pages/3aeda3/"},{name:"v-0d3d092a",path:"/pages/f85f1b/",component:vs,beforeEnter:(e,t,n)=>{ul("Layout","v-0d3d092a").then(n)}},{path:"/pages/f85f1b/index.html",redirect:"/pages/f85f1b/"},{path:"/《react》/02.hooks.html",redirect:"/pages/f85f1b/"},{name:"v-6f103bde",path:"/pages/82e5d7/",component:vs,beforeEnter:(e,t,n)=>{ul("Layout","v-6f103bde").then(n)}},{path:"/pages/82e5d7/index.html",redirect:"/pages/82e5d7/"},{path:"/《react》/03.components.html",redirect:"/pages/82e5d7/"},{name:"v-1f42625e",path:"/pages/0c11ea/",component:vs,beforeEnter:(e,t,n)=>{ul("Layout","v-1f42625e").then(n)}},{path:"/pages/0c11ea/index.html",redirect:"/pages/0c11ea/"},{path:"/《react》/04.apis.html",redirect:"/pages/0c11ea/"},{name:"v-3ae19d8b",path:"/pages/4db36a/",component:vs,beforeEnter:(e,t,n)=>{ul("Layout","v-3ae19d8b").then(n)}},{path:"/pages/4db36a/index.html",redirect:"/pages/4db36a/"},{path:"/《react》/50.记一次React回调函数.html",redirect:"/pages/4db36a/"},{name:"v-0792688a",path:"/pages/0d7cc1/",component:vs,beforeEnter:(e,t,n)=>{ul("Layout","v-0792688a").then(n)}},{path:"/pages/0d7cc1/index.html",redirect:"/pages/0d7cc1/"},{path:"/《server》/00.tutorial.html",redirect:"/pages/0d7cc1/"},{name:"v-267e6c49",path:"/pages/6ab0a7/",component:vs,beforeEnter:(e,t,n)=>{ul("Layout","v-267e6c49").then(n)}},{path:"/pages/6ab0a7/index.html",redirect:"/pages/6ab0a7/"},{path:"/《server》/01.spring/01.spring.html",redirect:"/pages/6ab0a7/"},{name:"v-99fa62a6",path:"/pages/39870b/",component:vs,beforeEnter:(e,t,n)=>{ul("Layout","v-99fa62a6").then(n)}},{path:"/pages/39870b/index.html",redirect:"/pages/39870b/"},{path:"/《server》/01.spring/02.了解spring.html",redirect:"/pages/39870b/"},{name:"v-15bcd010",path:"/pages/233ea5/",component:vs,beforeEnter:(e,t,n)=>{ul("Layout","v-15bcd010").then(n)}},{path:"/pages/233ea5/index.html",redirect:"/pages/233ea5/"},{path:"/《server》/02.数据库/01.database.html",redirect:"/pages/233ea5/"},{name:"v-518d82c3",path:"/pages/e9db87/",component:vs,beforeEnter:(e,t,n)=>{ul("Layout","v-518d82c3").then(n)}},{path:"/pages/e9db87/index.html",redirect:"/pages/e9db87/"},{path:"/《server》/02.数据库/02.mysql学习笔记.html",redirect:"/pages/e9db87/"},{name:"v-40ca211c",path:"/pages/e4a24e/",component:vs,beforeEnter:(e,t,n)=>{ul("Layout","v-40ca211c").then(n)}},{path:"/pages/e4a24e/index.html",redirect:"/pages/e4a24e/"},{path:"/《server》/02.数据库/05.sql.html",redirect:"/pages/e4a24e/"},{name:"v-375d6f79",path:"/pages/d8cbeb/",component:vs,beforeEnter:(e,t,n)=>{ul("Layout","v-375d6f79").then(n)}},{path:"/pages/d8cbeb/index.html",redirect:"/pages/d8cbeb/"},{path:"/《server》/10.其他 /10.elasticsearch.html",redirect:"/pages/d8cbeb/"},{name:"v-8ad6e996",path:"/pages/22d48b/",component:vs,beforeEnter:(e,t,n)=>{ul("Layout","v-8ad6e996").then(n)}},{path:"/pages/22d48b/index.html",redirect:"/pages/22d48b/"},{path:"/《server》/10.其他 /100.面试题整理.html",redirect:"/pages/22d48b/"},{name:"v-4c298fed",path:"/pages/c65eb4/",component:vs,beforeEnter:(e,t,n)=>{ul("Layout","v-4c298fed").then(n)}},{path:"/pages/c65eb4/index.html",redirect:"/pages/c65eb4/"},{path:"/《server》/10.其他 /50.websocket.html",redirect:"/pages/c65eb4/"},{name:"v-08eab131",path:"/pages/9f55fd/",component:vs,beforeEnter:(e,t,n)=>{ul("Layout","v-08eab131").then(n)}},{path:"/pages/9f55fd/index.html",redirect:"/pages/9f55fd/"},{path:"/《spring-boot》/01.tutorial.html",redirect:"/pages/9f55fd/"},{name:"v-08afd4b1",path:"/pages/ce4afc/",component:vs,beforeEnter:(e,t,n)=>{ul("Layout","v-08afd4b1").then(n)}},{path:"/pages/ce4afc/index.html",redirect:"/pages/ce4afc/"},{path:"/《vue》/01.tutorial.html",redirect:"/pages/ce4afc/"},{name:"v-e2fc03e2",path:"/pages/86683c/",component:vs,beforeEnter:(e,t,n)=>{ul("Layout","v-e2fc03e2").then(n)}},{path:"/pages/86683c/index.html",redirect:"/pages/86683c/"},{path:"/《vue》/10.极客课堂/01.事件.html",redirect:"/pages/86683c/"},{name:"v-415cd298",path:"/pages/4f9b39/",component:vs,beforeEnter:(e,t,n)=>{ul("Layout","v-415cd298").then(n)}},{path:"/pages/4f9b39/index.html",redirect:"/pages/4f9b39/"},{path:"/《vue》/10.极客课堂/02.属性.html",redirect:"/pages/4f9b39/"},{name:"v-7ec4ede6",path:"/pages/f23ed2/",component:vs,beforeEnter:(e,t,n)=>{ul("Layout","v-7ec4ede6").then(n)}},{path:"/pages/f23ed2/index.html",redirect:"/pages/f23ed2/"},{path:"/《vue》/10.极客课堂/04.指令.html",redirect:"/pages/f23ed2/"},{name:"v-3e23eb06",path:"/pages/cb9380/",component:vs,beforeEnter:(e,t,n)=>{ul("Layout","v-3e23eb06").then(n)}},{path:"/pages/cb9380/index.html",redirect:"/pages/cb9380/"},{path:"/《vue》/10.极客课堂/03.双向绑定和单项数据流不冲突.html",redirect:"/pages/cb9380/"},{name:"v-427b9d2c",path:"/pages/651b48/",component:vs,beforeEnter:(e,t,n)=>{ul("Layout","v-427b9d2c").then(n)}},{path:"/pages/651b48/index.html",redirect:"/pages/651b48/"},{path:"/《vue》/10.极客课堂/10.理解虚拟Dom和key属性的作用.html",redirect:"/pages/651b48/"},{name:"v-642f49fb",path:"/pages/f9b0df/",component:vs,beforeEnter:(e,t,n)=>{ul("Layout","v-642f49fb").then(n)}},{path:"/pages/f9b0df/index.html",redirect:"/pages/f9b0df/"},{path:"/《vue》/10.极客课堂/05.vue传递数据-slot.html",redirect:"/pages/f9b0df/"},{name:"v-93da6800",path:"/pages/6570ab/",component:vs,beforeEnter:(e,t,n)=>{ul("Layout","v-93da6800").then(n)}},{path:"/pages/6570ab/index.html",redirect:"/pages/6570ab/"},{path:"/《vue》/10.极客课堂/11.如何触发组件更新.html",redirect:"/pages/6570ab/"},{name:"v-02ac7740",path:"/pages/59f768/",component:vs,beforeEnter:(e,t,n)=>{ul("Layout","v-02ac7740").then(n)}},{path:"/pages/59f768/index.html",redirect:"/pages/59f768/"},{path:"/《vue》/10.极客课堂/16.如何优雅地获取跨层级实例.html",redirect:"/pages/59f768/"},{name:"v-668a7bff",path:"/pages/9c451e/",component:vs,beforeEnter:(e,t,n)=>{ul("Layout","v-668a7bff").then(n)}},{path:"/pages/9c451e/index.html",redirect:"/pages/9c451e/"},{path:"/《web》/01.javascript/50.技巧记录.html",redirect:"/pages/9c451e/"},{name:"v-adf4c11e",path:"/pages/d8c80d/",component:vs,beforeEnter:(e,t,n)=>{ul("Layout","v-adf4c11e").then(n)}},{path:"/pages/d8c80d/index.html",redirect:"/pages/d8c80d/"},{path:"/《web》/01.tutorial.html",redirect:"/pages/d8c80d/"},{name:"v-be2e851e",path:"/pages/548959/",component:vs,beforeEnter:(e,t,n)=>{ul("Layout","v-be2e851e").then(n)}},{path:"/pages/548959/index.html",redirect:"/pages/548959/"},{path:"/《web》/02.javascript.html",redirect:"/pages/548959/"},{name:"v-590e6280",path:"/pages/4f876a/",component:vs,beforeEnter:(e,t,n)=>{ul("Layout","v-590e6280").then(n)}},{path:"/pages/4f876a/index.html",redirect:"/pages/4f876a/"},{path:"/《web》/10.web术语概念.html",redirect:"/pages/4f876a/"},{name:"v-416ea53c",path:"/pages/411579/",component:vs,beforeEnter:(e,t,n)=>{ul("Layout","v-416ea53c").then(n)}},{path:"/pages/411579/index.html",redirect:"/pages/411579/"},{path:"/《web》/10.其他/01.node版本管理.html",redirect:"/pages/411579/"},{name:"v-5fe14fb1",path:"/pages/d2a447/",component:vs,beforeEnter:(e,t,n)=>{ul("Layout","v-5fe14fb1").then(n)}},{path:"/pages/d2a447/index.html",redirect:"/pages/d2a447/"},{path:"/《web》/50.nextjs.html",redirect:"/pages/d2a447/"},{name:"v-28c38e47",path:"/pages/7e542a/",component:vs,beforeEnter:(e,t,n)=>{ul("Layout","v-28c38e47").then(n)}},{path:"/pages/7e542a/index.html",redirect:"/pages/7e542a/"},{path:"/《vue》/10.极客课堂/00.前言.html",redirect:"/pages/7e542a/"},{name:"v-7082d399",path:"/pages/8fbdb4/",component:vs,beforeEnter:(e,t,n)=>{ul("Layout","v-7082d399").then(n)}},{path:"/pages/8fbdb4/index.html",redirect:"/pages/8fbdb4/"},{path:"/《vue》/01.笔记/02.原理.html",redirect:"/pages/8fbdb4/"},{path:"*",component:vs}],ys={title:"一个程序员的进阶之路",description:"勤学如春起之苗,不见其增,日有所长;辍学如磨刀之石,不见其损,日有所亏。",base:"/blogPages/",headTags:[["meta",{name:"theme-color",content:"#3eaf7c"}],["meta",{name:"apple-mobile-web-app-capable",content:"yes"}],["meta",{name:"apple-mobile-web-app-status-bar-style",content:"black"}]],pages:[{title:"前端",frontmatter:{pageComponent:{name:"Catalogue",data:{path:"01.前端",imgUrl:"https://cdn.jsdelivr.net/gh/jacky1234/picArchieve@master/uPic/20230522_164539_kGo3QV.png",description:"前端内容"}},title:"前端",date:"2023-05-22T16:44:30.000Z",permalink:"/fe/",tags:[null],sidebar:!1,article:!1,comment:!1,editLink:!1,author:{name:"Jacky",email:"jackdoson2011@gmail.com",link:"https://github.com/jacky1234"}},regularPath:"/00.%E7%9B%AE%E5%BD%95%E9%A1%B5/01.%E5%89%8D%E7%AB%AF.html",relativePath:"00.目录页/01.前端.md",key:"v-9b6f56f2",path:"/fe/",lastUpdated:"2023/05/30, 21:13:53",lastUpdatedTimestamp:1685452433e3},{title:"other",frontmatter:{pageComponent:{name:"Catalogue",data:{path:"04.其他",imgUrl:"https://cdn.jsdelivr.net/gh/jacky1234/picArchieve@master/uPic/20230521_202721_0YoPV0.png",description:"其他内容"}},title:"other",date:"2019-05-21T11:32:12.000Z",permalink:"/other/",sidebar:!1,article:!1,comment:!1,editLink:!1,author:{name:"Jacky",email:"jackdoson2011@gmail.com",link:"https://github.com/jacky1234"}},regularPath:"/00.%E7%9B%AE%E5%BD%95%E9%A1%B5/0400.%E5%85%B6%E4%BB%96.html",relativePath:"00.目录页/0400.其他.md",key:"v-793035b6",path:"/other/",lastUpdated:"2023/05/25, 00:07:08",lastUpdatedTimestamp:1684944428e3},{title:"server",frontmatter:{pageComponent:{name:"Catalogue",data:{path:"《server》",imgUrl:"https://cdn.jsdelivr.net/gh/jacky1234/picArchieve@master/uPic/20230903_115510_6axkJ5.png",description:"服务器相关"}},title:"server",date:"2023-05-23T21:22:55.000Z",permalink:"/server/",sidebar:!1,article:!1,comment:!1,editLink:!1,categories:["目录页"],tags:["工具"],author:{name:"Jacky",email:"jackdoson2011@gmail.com",link:"https://github.com/jacky1234"}},regularPath:"/00.%E7%9B%AE%E5%BD%95%E9%A1%B5/0401.server.html",relativePath:"00.目录页/0401.server.md",key:"v-2cb2f234",path:"/server/",lastUpdated:"2023/09/03, 11:57:29",lastUpdatedTimestamp:1693713449e3},{title:"工具",frontmatter:{pageComponent:{name:"Catalogue",data:{path:"04.其他/01.工具",imgUrl:"https://cdn.jsdelivr.net/gh/jacky1234/picArchieve@master/uPic/20230523_212609_z8dM8R.png",description:"工具内容"}},title:"工具",date:"2023-05-23T21:22:55.000Z",permalink:"/tool/",sidebar:!1,article:!1,comment:!1,editLink:!1,categories:["目录页"],tags:["工具"],author:{name:"Jacky",email:"jackdoson2011@gmail.com",link:"https://github.com/jacky1234"}},regularPath:"/00.%E7%9B%AE%E5%BD%95%E9%A1%B5/0401.%E5%B7%A5%E5%85%B7.html",relativePath:"00.目录页/0401.工具.md",key:"v-398ec241",path:"/tool/",lastUpdated:"2023/05/25, 00:07:08",lastUpdatedTimestamp:1684944428e3},{title:"博客",frontmatter:{pageComponent:{name:"Catalogue",data:{path:"04.其他/05.博客",imgUrl:"https://cdn.jsdelivr.net/gh/jacky1234/picArchieve@master/uPic/20230523_214848_whZZ8J.png",description:"搭建博客"}},title:"博客",date:"2023-05-23T21:22:55.000Z",permalink:"/blog/",sidebar:!1,article:!1,comment:!1,editLink:!1,categories:["目录页"],tags:["blog"],author:{name:"Jacky",email:"jackdoson2011@gmail.com",link:"https://github.com/jacky1234"}},regularPath:"/00.%E7%9B%AE%E5%BD%95%E9%A1%B5/0405.%E5%8D%9A%E5%AE%A2.html",relativePath:"00.目录页/0405.博客.md",key:"v-73eb8dca",path:"/blog/",lastUpdated:"2023/06/08, 21:43:37",lastUpdatedTimestamp:1686231817e3},{title:"Java",frontmatter:{pageComponent:{name:"Catalogue",data:{path:"04.其他/08.java",imgUrl:"https://raw.githubusercontent.com/jacky1234/picArchieve/master/uPic/java.png",description:"java"}},title:"Java",date:"2023-05-23T21:22:55.000Z",permalink:"/java/",sidebar:!1,article:!1,comment:!1,editLink:!1,categories:["目录页"],tags:["java"],author:{name:"Jacky",email:"jackdoson2011@gmail.com",link:"https://github.com/jacky1234"}},regularPath:"/00.%E7%9B%AE%E5%BD%95%E9%A1%B5/0408.java.html",relativePath:"00.目录页/0408.java.md",key:"v-0aa82876",path:"/java/",lastUpdated:"2023/08/09, 08:53:37",lastUpdatedTimestamp:1691542417e3},{title:"python",frontmatter:{pageComponent:{name:"Catalogue",data:{path:"《python》",imgUrl:"https://cdn.jsdelivr.net/gh/jacky1234/picArchieve@master/uPic/20230601_170824_ROTOkB.png",description:"python 学习"}},title:"python",date:"2023-06-01T17:07:10.000Z",categories:["目录页"],permalink:"/python/",sidebar:!1,article:!1,comment:!1,editLink:!1,tags:[null],author:{name:"Jacky",email:"jackdoson2011@gmail.com",link:"https://github.com/jacky1234"}},regularPath:"/00.%E7%9B%AE%E5%BD%95%E9%A1%B5/0408.python.html",relativePath:"00.目录页/0408.python.md",key:"v-19390582",path:"/python/",lastUpdated:"2023/06/01, 17:12:57",lastUpdatedTimestamp:1685610777e3},{title:"more",frontmatter:{pageComponent:{name:"Catalogue",data:{path:"04.其他/10.更多",imgUrl:"https://cdn.jsdelivr.net/gh/jacky1234/picArchieve@master/uPic/20230607_110827_jY0HcA.png",description:"more content"}},title:"more",date:"2023-06-07T11:03:24.000Z",permalink:"/more/",sidebar:!1,article:!1,comment:!1,editLink:!1,categories:["目录页"],tags:[null],author:{name:"Jacky",email:"jackdoson2011@gmail.com",link:"https://github.com/jacky1234"}},regularPath:"/00.%E7%9B%AE%E5%BD%95%E9%A1%B5/0410.more.html",relativePath:"00.目录页/0410.more.md",key:"v-bbba8304",path:"/more/",lastUpdated:"2023/06/07, 21:13:47",lastUpdatedTimestamp:1686143627e3},{title:"mime",frontmatter:{pageComponent:{name:"Catalogue",data:{path:"mine",imgUrl:"https://cdn.jsdelivr.net/gh/jacky1234/picArchieve@master/uPic/20230630_102944_mC1XsH.png",description:"secret and so on"}},title:"mime",date:"2023-06-07T11:03:24.000Z",permalink:"/mime/",sidebar:!1,article:!1,comment:!1,editLink:!1,categories:["目录页"],tags:[null],author:{name:"Jacky",email:"jackdoson2011@gmail.com",link:"https://github.com/jacky1234"}},regularPath:"/00.%E7%9B%AE%E5%BD%95%E9%A1%B5/0500.mine.html",relativePath:"00.目录页/0500.mine.md",key:"v-4931c646",path:"/mime/",lastUpdated:"2023/08/05, 14:56:28",lastUpdatedTimestamp:1691218588e3},{title:"web",frontmatter:{pageComponent:{name:"Catalogue",data:{path:"《web》",imgUrl:"https://raw.githubusercontent.com/jacky1234/picArchieve/master/uPic/web.png",description:"web开发技术整理"}},title:"web",date:"2023-07-05T23:47:34.000Z",permalink:"/web/",categories:["目录页"],tags:["web"],sidebar:!1,article:!1,comment:!1,editLink:!1,author:{name:"Jacky",email:"jackdoson2011@gmail.com",link:"https://github.com/jacky1234"}},regularPath:"/01.%E5%89%8D%E7%AB%AF/02.web.html",relativePath:"01.前端/02.web.md",key:"v-49a8aada",path:"/web/",lastUpdated:"2023/07/06, 00:09:19",lastUpdatedTimestamp:1688573359e3},{title:"android",frontmatter:{pageComponent:{name:"Catalogue",data:{path:"《android》",imgUrl:"https://cdn.jsdelivr.net/gh/jacky1234/picArchieve@master/uPic/20230625_220333_gxmTug.png",description:"本章内容是 android 学习"}},title:"android",date:"2023-05-22T23:21:13.000Z",permalink:"/android/",categories:[null],tags:["android"],sidebar:!1,article:!1,comment:!1,editLink:!1,author:{name:"Jacky",email:"jackdoson2011@gmail.com",link:"https://github.com/jacky1234"}},regularPath:"/01.%E5%89%8D%E7%AB%AF/05.android.html",relativePath:"01.前端/05.android.md",key:"v-7f01ed9e",path:"/android/",lastUpdated:"2023/07/06, 00:09:19",lastUpdatedTimestamp:1688573359e3},{title:"iOS",frontmatter:{pageComponent:{name:"Catalogue",data:{path:"《iOS》",imgUrl:"https://cdn.jsdelivr.net/gh/jacky1234/picArchieve@master/uPic/20230625_220321_n17dIV.png",description:"本章内容是 iOS 学习"}},title:"iOS",date:"2023-05-22T23:21:13.000Z",permalink:"/iOS/",categories:[null],tags:["android"],sidebar:!1,article:!1,comment:!1,editLink:!1,author:{name:"Jacky",email:"jackdoson2011@gmail.com",link:"https://github.com/jacky1234"}},regularPath:"/01.%E5%89%8D%E7%AB%AF/06.iOS.html",relativePath:"01.前端/06.iOS.md",key:"v-27216da0",path:"/iOS/",lastUpdated:"2023/07/06, 00:09:19",lastUpdatedTimestamp:1688573359e3},{title:"《react》笔记",frontmatter:{pageComponent:{name:"Catalogue",data:{path:"《react》",imgUrl:"https://cdn.jsdelivr.net/gh/jacky1234/picArchieve@master/uPic/20230524_165853_AGOGeF.png",description:"本章内容是博主的React学习笔记,非教程文档,请以官方文档为准。"}},title:"《react》笔记",date:"2023-05-22T23:21:13.000Z",permalink:"/react/",categories:["前端"],tags:["react","web"],sidebar:!1,article:!1,comment:!1,editLink:!1,author:{name:"Jacky",email:"jackdoson2011@gmail.com",link:"https://github.com/jacky1234"}},regularPath:"/01.%E5%89%8D%E7%AB%AF/11.react.html",relativePath:"01.前端/11.react.md",key:"v-5d7cf408",path:"/react/",lastUpdated:"2023/06/04, 17:54:47",lastUpdatedTimestamp:1685872487e3},{title:"《vue》笔记",frontmatter:{pageComponent:{name:"Catalogue",data:{path:"《vue》",imgUrl:"https://cdn.jsdelivr.net/gh/jacky1234/picArchieve@master/uPic/20230522_173341_2c5D6q.png",description:"本章内容是博主的Vue学习笔记,非教程文档,请以官方文档为准。"}},title:"《vue》笔记",date:"2023-05-22T17:00:47.000Z",permalink:"/vue/",sidebar:!1,article:!1,comment:!1,editLink:!1,categories:["前端"],tags:["vue","web"],author:{name:"Jacky",email:"jackdoson2011@gmail.com",link:"https://github.com/jacky1234"}},regularPath:"/01.%E5%89%8D%E7%AB%AF/12.vue.html",relativePath:"01.前端/12.vue.md",key:"v-0c593678",path:"/vue/",lastUpdated:"2023/06/04, 17:54:47",lastUpdatedTimestamp:1685872487e3},{title:"shell",frontmatter:{title:"shell",date:"2023-06-04T11:54:30.000Z",permalink:"/pages/0140a0/",categories:["其他","工具"],tags:["shell","linux"],author:{name:"Jacky",email:"jackdoson2011@gmail.com",link:"https://github.com/jacky1234"}},regularPath:"/04.%E5%85%B6%E4%BB%96/01.%E5%B7%A5%E5%85%B7/00.shell.html",relativePath:"04.其他/01.工具/00.shell.md",key:"v-2c61710f",path:"/pages/0140a0/",headers:[{level:2,title:"语法",slug:"语法"},{level:3,title:"变量扩展语法",slug:"变量扩展语法"},{level:3,title:"Here Tag",slug:"here-tag"},{level:2,title:"安装相关",slug:"安装相关"},{level:3,title:"brew",slug:"brew"},{level:3,title:"apt-get",slug:"apt-get"},{level:2,title:"文本/文件",slug:"文本-文件"},{level:3,title:"lsof",slug:"lsof"},{level:3,title:"ls",slug:"ls"},{level:3,title:"rg",slug:"rg"},{level:3,title:"fd",slug:"fd"},{level:2,title:"网络",slug:"网络"},{level:3,title:"ifconfig",slug:"ifconfig"},{level:3,title:"netstat",slug:"netstat"},{level:3,title:"dig",slug:"dig"},{level:3,title:"nslookup",slug:"nslookup"},{level:3,title:"wget",slug:"wget"},{level:3,title:"curl",slug:"curl"},{level:4,title:"下载 shell 并执行",slug:"下载-shell-并执行"},{level:4,title:"保存到其他目录",slug:"保存到其他目录"},{level:4,title:"请求",slug:"请求"},{level:3,title:"netcat/nc",slug:"netcat-nc"},{level:2,title:"解压缩",slug:"解压缩"},{level:3,title:"xz",slug:"xz"},{level:3,title:"tar",slug:"tar"},{level:2,title:"其他",slug:"其他"},{level:3,title:"kill",slug:"kill"},{level:3,title:"剪切板",slug:"剪切板"},{level:2,title:"案例",slug:"案例"},{level:3,title:"词频统计",slug:"词频统计"},{level:3,title:"转置文件",slug:"转置文件"},{level:3,title:"提取 ANDROID SERIAL",slug:"提取-android-serial"}],lastUpdated:"2023/09/17, 22:27:30",lastUpdatedTimestamp:169496085e4},{title:"git",frontmatter:{sidebar:"auto",title:"git",date:"2019-05-20T12:58:26.000Z",permalink:"/pages/7071e6/",categories:["其他","tool"],tags:[null],author:{name:"Jacky",email:"jackdoson2011@gmail.com",link:"https://github.com/jacky1234"}},regularPath:"/04.%E5%85%B6%E4%BB%96/01.%E5%B7%A5%E5%85%B7/01.git.html",relativePath:"04.其他/01.工具/01.git.md",key:"v-520581ee",path:"/pages/7071e6/",headers:[{level:2,title:"实用操作",slug:"实用操作"},{level:3,title:"分离 header",slug:"分离-header"},{level:2,title:"常用命令",slug:"常用命令"},{level:2,title:"常用操作",slug:"常用操作"},{level:3,title:"撤销提交到 stage 的修改",slug:"撤销提交到-stage-的修改"},{level:3,title:"查看",slug:"查看"},{level:3,title:"stash",slug:"stash"},{level:3,title:"批量设置 git config",slug:"批量设置-git-config"},{level:2,title:"术语",slug:"术语"},{level:3,title:"stage changes(暂存区)",slug:"stage-changes-暂存区"},{level:2,title:"最佳实践",slug:"最佳实践"},{level:3,title:"rebase 开发规范",slug:"rebase-开发规范"},{level:2,title:"hook",slug:"hook"}],lastUpdated:"2023/09/11, 17:54:51",lastUpdatedTimestamp:1694426091e3},{title:"web工具",frontmatter:{title:"web工具",date:"2023-06-29T18:50:23.000Z",permalink:"/pages/3869be/",categories:["其他","工具"],tags:["npm","npx"],author:{name:"Jacky",email:"jackdoson2011@gmail.com",link:"https://github.com/jacky1234"}},regularPath:"/04.%E5%85%B6%E4%BB%96/01.%E5%B7%A5%E5%85%B7/02.web%E5%B7%A5%E5%85%B7.html",relativePath:"04.其他/01.工具/02.web工具.md",key:"v-26d8a1d0",path:"/pages/3869be/",headers:[{level:2,title:"npm",slug:"npm"},{level:2,title:"npx",slug:"npx"}],lastUpdated:"2023/08/07, 09:14:32",lastUpdatedTimestamp:1691370872e3},{title:"npm",frontmatter:{title:"npm",date:"2023-08-07T08:49:33.000Z",permalink:"/pages/669dfc/",categories:["其他","工具"],tags:["npm"],author:{name:"Jacky",email:"jackdoson2011@gmail.com",link:"https://github.com/jacky1234"}},regularPath:"/04.%E5%85%B6%E4%BB%96/01.%E5%B7%A5%E5%85%B7/03.npm.html",relativePath:"04.其他/01.工具/03.npm.md",key:"v-12b4125a",path:"/pages/669dfc/",headers:[{level:2,title:"常用命令",slug:"常用命令"},{level:3,title:"查看子依赖",slug:"查看子依赖"},{level:3,title:"版本控制",slug:"版本控制"},{level:2,title:"其他",slug:"其他"}],lastUpdated:"2023/08/07, 09:42:20",lastUpdatedTimestamp:169137254e4},{title:"adb",frontmatter:{title:"adb",date:"2023-04-28T07:22:13.000Z",permalink:"/pages/37f363/",categories:["other","tool"],tags:[null],author:{name:"Jacky",email:"jackdoson2011@gmail.com",link:"https://github.com/jacky1234"}},regularPath:"/04.%E5%85%B6%E4%BB%96/01.%E5%B7%A5%E5%85%B7/05.adb.html",relativePath:"04.其他/01.工具/05.adb.md",key:"v-fdbad532",path:"/pages/37f363/",headers:[{level:2,title:"常用",slug:"常用"},{level:3,title:"dumpsys",slug:"dumpsys"},{level:3,title:"am",slug:"am"},{level:3,title:"ps",slug:"ps"},{level:3,title:"logcat",slug:"logcat"},{level:3,title:"input",slug:"input"},{level:3,title:"其他",slug:"其他"},{level:2,title:"Tricks",slug:"tricks"},{level:2,title:"实践",slug:"实践"},{level:3,title:"访问私有目录文件",slug:"访问私有目录文件"},{level:3,title:"接口转发",slug:"接口转发"}],lastUpdated:"2023/08/17, 20:31:29",lastUpdatedTimestamp:1692275489e3},{title:"aapt",frontmatter:{title:"aapt",date:"2023-05-31T15:34:46.000Z",permalink:"/pages/907793/",categories:["其他","工具"],tags:[null],author:{name:"Jacky",email:"jackdoson2011@gmail.com",link:"https://github.com/jacky1234"}},regularPath:"/04.%E5%85%B6%E4%BB%96/01.%E5%B7%A5%E5%85%B7/06.aapt.html",relativePath:"04.其他/01.工具/06.aapt.md",key:"v-69225a59",path:"/pages/907793/",headers:[{level:2,title:"aapt 命令及其功能:",slug:"aapt-命令及其功能"}],lastUpdated:"2023/05/31, 19:06:42",lastUpdatedTimestamp:1685531202e3},{title:"c++工具",frontmatter:{title:"c++工具",date:"2023-05-31T16:41:51.000Z",permalink:"/pages/977efe/",categories:["其他","工具"],tags:["c++","gcc","compile"],author:{name:"Jacky",email:"jackdoson2011@gmail.com",link:"https://github.com/jacky1234"}},regularPath:"/04.%E5%85%B6%E4%BB%96/01.%E5%B7%A5%E5%85%B7/07.c++%E5%B7%A5%E5%85%B7.html",relativePath:"04.其他/01.工具/07.c++工具.md",key:"v-c88140a0",path:"/pages/977efe/",headers:[{level:2,title:"编译工具 gcc",slug:"编译工具-gcc"},{level:3,title:"常用命令",slug:"常用命令"}],lastUpdated:"2023/06/04, 14:48:33",lastUpdatedTimestamp:1685861313e3},{title:"pip3",frontmatter:{title:"pip3",date:"2023-06-02T17:12:38.000Z",permalink:"/pages/7ee6cc/",categories:["其他","工具"],tags:["python","pip3"],author:{name:"Jacky",email:"jackdoson2011@gmail.com",link:"https://github.com/jacky1234"}},regularPath:"/04.%E5%85%B6%E4%BB%96/01.%E5%B7%A5%E5%85%B7/08.pip3.html",relativePath:"04.其他/01.工具/08.pip3.md",key:"v-d88d59ce",path:"/pages/7ee6cc/",headers:[{level:2,title:"pip3 的常见用法",slug:"pip3-的常见用法"},{level:2,title:"pip3 版本问题",slug:"pip3-版本问题"},{level:2,title:"package 模块版本控制",slug:"package-模块版本控制"}],lastUpdated:"2023/09/17, 22:27:30",lastUpdatedTimestamp:169496085e4},{title:"vim",frontmatter:{title:"vim",date:"2023-05-25T16:59:21.000Z",permalink:"/pages/89d231/",categories:["《linux》","shell"],tags:["vim","shell"],author:{name:"Jacky",email:"jackdoson2011@gmail.com",link:"https://github.com/jacky1234"}},regularPath:"/04.%E5%85%B6%E4%BB%96/01.%E5%B7%A5%E5%85%B7/09.vim.html",relativePath:"04.其他/01.工具/09.vim.md",key:"v-07c2d32e",path:"/pages/89d231/",headers:[{level:2,title:"基础操作",slug:"基础操作"},{level:3,title:"命令模式",slug:"命令模式"},{level:3,title:"编辑模式",slug:"编辑模式"},{level:3,title:"可视模式",slug:"可视模式"},{level:3,title:"光标",slug:"光标"},{level:3,title:"查找",slug:"查找"},{level:3,title:"替换",slug:"替换"},{level:3,title:"删除",slug:"删除"},{level:3,title:"复制粘贴",slug:"复制粘贴"},{level:4,title:"复制多行",slug:"复制多行"},{level:3,title:"退出",slug:"退出"},{level:3,title:"其他",slug:"其他"},{level:2,title:"vimtutor",slug:"vimtutor"},{level:2,title:"vimgrep",slug:"vimgrep"},{level:3,title:"用法",slug:"用法"},{level:2,title:"vimgrepadd",slug:"vimgrepadd"},{level:2,title:"插件",slug:"插件"},{level:3,title:"插件管理器 vim-plug",slug:"插件管理器-vim-plug"},{level:3,title:"常用 plugin",slug:"常用-plugin"},{level:2,title:"其他",slug:"其他-2"},{level:3,title:"正则表达式技巧",slug:"正则表达式技巧"},{level:3,title:"vim 查看另外的文件",slug:"vim-查看另外的文件"},{level:3,title:"quickFix",slug:"quickfix"},{level:4,title:"多个 quickFix 窗口",slug:"多个-quickfix-窗口"},{level:3,title:"visual 模式复制问题",slug:"visual-模式复制问题"},{level:2,title:"参考",slug:"参考"}],lastUpdated:"2023/09/15, 11:57:23",lastUpdatedTimestamp:1694750243e3},{title:"docker",frontmatter:{title:"docker",date:"2023-06-02T09:05:47.000Z",permalink:"/pages/1c262c/",categories:["其他","更多"],tags:["docker"],author:{name:"Jacky",email:"jackdoson2011@gmail.com",link:"https://github.com/jacky1234"}},regularPath:"/04.%E5%85%B6%E4%BB%96/01.%E5%B7%A5%E5%85%B7/12.docker.html",relativePath:"04.其他/01.工具/12.docker.md",key:"v-209934f9",path:"/pages/1c262c/",headers:[{level:2,title:"环境",slug:"环境"},{level:2,title:"常用命令",slug:"常用命令"},{level:2,title:"技巧",slug:"技巧"},{level:2,title:"原理",slug:"原理"},{level:2,title:"其他",slug:"其他"},{level:3,title:"容器中 mysql 链接主机",slug:"容器中-mysql-链接主机"},{level:2,title:"链接",slug:"链接"}],lastUpdated:"2023/09/12, 17:52:59",lastUpdatedTimestamp:1694512379e3},{title:"unbuntuOnWindows",frontmatter:{title:"unbuntuOnWindows",date:"2023-06-10T09:05:54.000Z",permalink:"/pages/8cb2e1/",categories:["其他","工具"],tags:["unbuntu"],author:{name:"Jacky",email:"jackdoson2011@gmail.com",link:"https://github.com/jacky1234"}},regularPath:"/04.%E5%85%B6%E4%BB%96/01.%E5%B7%A5%E5%85%B7/13.unbuntuOnWindows.html",relativePath:"04.其他/01.工具/13.unbuntuOnWindows.md",key:"v-3c45a879",path:"/pages/8cb2e1/",headers:[{level:2,title:"Ubuntu on Windows",slug:"ubuntu-on-windows"},{level:2,title:"设置环境",slug:"设置环境"},{level:3,title:"vscode terminal",slug:"vscode-terminal"}],lastUpdated:"2023/06/10, 09:29:25",lastUpdatedTimestamp:1686360565e3},{title:"ides",frontmatter:{title:"ides",date:"2023-06-10T09:12:19.000Z",permalink:"/pages/bd17b5/",categories:["其他","工具"],tags:["ide"],author:{name:"Jacky",email:"jackdoson2011@gmail.com",link:"https://github.com/jacky1234"}},regularPath:"/04.%E5%85%B6%E4%BB%96/01.%E5%B7%A5%E5%85%B7/14.ides.html",relativePath:"04.其他/01.工具/14.ides.md",key:"v-d5a6414e",path:"/pages/bd17b5/",headers:[{level:2,title:"Android studio",slug:"android-studio"},{level:2,title:"vscode",slug:"vscode"},{level:3,title:"插件",slug:"插件"},{level:3,title:"替换技巧",slug:"替换技巧"},{level:2,title:"python",slug:"python"}],lastUpdated:"2023/09/13, 08:57:18",lastUpdatedTimestamp:1694566638e3},{title:"zsh高效的shell",frontmatter:{title:"zsh高效的shell",date:"2023-06-10T13:51:13.000Z",permalink:"/pages/f9c14d/",categories:["其他","工具"],tags:[null],author:{name:"Jacky",email:"jackdoson2011@gmail.com",link:"https://github.com/jacky1234"}},regularPath:"/04.%E5%85%B6%E4%BB%96/01.%E5%B7%A5%E5%85%B7/15.zsh%E9%AB%98%E6%95%88%E7%9A%84shell.html",relativePath:"04.其他/01.工具/15.zsh高效的shell.md",key:"v-49456eb6",path:"/pages/f9c14d/",headers:[{level:2,title:"常用",slug:"常用"},{level:2,title:"配置",slug:"配置"},{level:2,title:"常用插件",slug:"常用插件"},{level:2,title:"zsh-autosuggestions",slug:"zsh-autosuggestions"},{level:2,title:"zsh-syntax-highlighting",slug:"zsh-syntax-highlighting"}],lastUpdated:"2023/06/15, 21:49:15",lastUpdatedTimestamp:1686836955e3},{title:"github",frontmatter:{title:"github",date:"2023-06-14T21:18:34.000Z",permalink:"/pages/514538/",categories:["其他","工具"],tags:[null],author:{name:"Jacky",email:"jackdoson2011@gmail.com",link:"https://github.com/jacky1234"}},regularPath:"/04.%E5%85%B6%E4%BB%96/01.%E5%B7%A5%E5%85%B7/16.github.html",relativePath:"04.其他/01.工具/16.github.md",key:"v-16dcf019",path:"/pages/514538/",headers:[{level:2,title:"workflows",slug:"workflows"},{level:3,title:"trigger workflow",slug:"trigger-workflow"},{level:4,title:"schedule",slug:"schedule"},{level:3,title:"Reuse workflows",slug:"reuse-workflows"},{level:3,title:"workflow commands",slug:"workflow-commands"},{level:4,title:"multiline strings*",slug:"multiline-strings"},{level:2,title:"授权",slug:"授权"},{level:3,title:"QQ 邮箱",slug:"qq-邮箱"},{level:2,title:"链接",slug:"链接"}],lastUpdated:"2023/06/26, 20:01:54",lastUpdatedTimestamp:1687780914e3},{title:"gradle",frontmatter:{title:"gradle",date:"2023-05-23T15:22:54.000Z",permalink:"/pages/0cdfba/",categories:["其他","工具"],tags:["gradle","依赖"],author:{name:"Jacky",email:"jackdoson2011@gmail.com",link:"https://github.com/jacky1234"}},regularPath:"/04.%E5%85%B6%E4%BB%96/01.%E5%B7%A5%E5%85%B7/20.gradle.html",relativePath:"04.其他/01.工具/20.gradle.md",key:"v-192249b9",path:"/pages/0cdfba/",headers:[{level:2,title:"常用",slug:"常用"},{level:2,title:"AGP",slug:"agp"},{level:3,title:"AGP 升级",slug:"agp-升级"},{level:3,title:"prefab",slug:"prefab"},{level:2,title:"Controlling Transitives",slug:"controlling-transitives"},{level:3,title:"share versions",slug:"share-versions"},{level:3,title:"解决版本号冲突",slug:"解决版本号冲突"},{level:2,title:"其他",slug:"其他"},{level:3,title:"调试",slug:"调试"}],lastUpdated:"2023/09/11, 17:54:51",lastUpdatedTimestamp:1694426091e3},{title:"mvn",frontmatter:{title:"mvn",date:"2023-09-03T23:32:14.000Z",permalink:"/pages/c80e98/",categories:["其他","工具"],tags:[null],author:{name:"Jacky",email:"jackdoson2011@gmail.com",link:"https://github.com/jacky1234"}},regularPath:"/04.%E5%85%B6%E4%BB%96/01.%E5%B7%A5%E5%85%B7/21.mvn.html",relativePath:"04.其他/01.工具/21.mvn.md",key:"v-7e599067",path:"/pages/c80e98/",lastUpdated:"2023/09/04, 00:04:37",lastUpdatedTimestamp:1693757077e3},{title:"jadx",frontmatter:{title:"jadx",date:"2023-06-29T16:34:22.000Z",permalink:"/pages/79f386/",categories:["其他","工具"],tags:["jadx","逆向"],author:{name:"Jacky",email:"jackdoson2011@gmail.com",link:"https://github.com/jacky1234"}},regularPath:"/04.%E5%85%B6%E4%BB%96/01.%E5%B7%A5%E5%85%B7/50.jadx.html",relativePath:"04.其他/01.工具/50.jadx.md",key:"v-0aab8a99",path:"/pages/79f386/",headers:[{level:2,title:"介绍",slug:"介绍"}],lastUpdated:"2023/06/29, 22:10:54",lastUpdatedTimestamp:1688047854e3},{title:"网络",frontmatter:{title:"网络",date:"2023-05-24T17:51:50.000Z",permalink:"/pages/cb9d0f/",categories:["其他","网络"],tags:[null],author:{name:"Jacky",email:"jackdoson2011@gmail.com",link:"https://github.com/jacky1234"}},regularPath:"/04.%E5%85%B6%E4%BB%96/02.%E7%BD%91%E7%BB%9C/00.%E7%BD%91%E7%BB%9C.html",relativePath:"04.其他/02.网络/00.网络.md",key:"v-913bd424",path:"/pages/cb9d0f/",headers:[{level:2,title:"IPv4 地址的表示",slug:"ipv4-地址的表示"}],lastUpdated:"2023/06/02, 16:02:06",lastUpdatedTimestamp:1685692926e3},{title:"HTTP",frontmatter:{title:"HTTP",date:"2023-04-28T07:22:13.000Z",permalink:"/pages/2a8b7b/",sidebar:"auto",categories:["网络"],tags:[null],author:{name:"Jacky",email:"jackdoson2011@gmail.com",link:"https://github.com/jacky1234"}},regularPath:"/04.%E5%85%B6%E4%BB%96/02.%E7%BD%91%E7%BB%9C/01.HTTP.html",relativePath:"04.其他/02.网络/01.HTTP.md",key:"v-5ca2e717",path:"/pages/2a8b7b/",headers:[{level:2,title:"SESSION 和 COOKIE",slug:"session-和-cookie"}],lastUpdated:"2023/05/23, 22:29:48",lastUpdatedTimestamp:1684852188e3},{title:"HTTPS",frontmatter:{title:"HTTPS",date:"2023-04-28T07:22:13.000Z",permalink:"/pages/3dd4b2/",sidebar:"auto",categories:["网络"],tags:[null],author:{name:"Jacky",email:"jackdoson2011@gmail.com",link:"https://github.com/jacky1234"}},regularPath:"/04.%E5%85%B6%E4%BB%96/02.%E7%BD%91%E7%BB%9C/02.HTTPS.html",relativePath:"04.其他/02.网络/02.HTTPS.md",key:"v-0f7771e7",path:"/pages/3dd4b2/",headers:[{level:2,title:"网络基础",slug:"网络基础"},{level:3,title:"OSI 7 层模型",slug:"osi-7-层模型"},{level:3,title:"公钥与私钥",slug:"公钥与私钥"},{level:3,title:"证书",slug:"证书"},{level:2,title:"HTTPS 协议的总体思路",slug:"https-协议的总体思路"},{level:2,title:"实战",slug:"实战"},{level:3,title:"http 安全实践",slug:"http-安全实践"},{level:2,title:"附录",slug:"附录"}],lastUpdated:"2023/05/23, 22:29:48",lastUpdatedTimestamp:1684852188e3},{title:"CDN-DNS-httpDNS",frontmatter:{title:"CDN-DNS-httpDNS",date:"2023-04-28T07:22:13.000Z",permalink:"/pages/59b0a9/",sidebar:"auto",categories:["网络"],tags:[null],author:{name:"Jacky",email:"jackdoson2011@gmail.com",link:"https://github.com/jacky1234"}},regularPath:"/04.%E5%85%B6%E4%BB%96/02.%E7%BD%91%E7%BB%9C/03.CDN-DNS-httpDNS.html",relativePath:"04.其他/02.网络/03.CDN-DNS-httpDNS.md",key:"v-18dff181",path:"/pages/59b0a9/",headers:[{level:2,title:"DNS",slug:"dns"},{level:4,title:"域名解析过程",slug:"域名解析过程"},{level:5,title:"国内 ISP LocalDNS 问题",slug:"国内-isp-localdns-问题"},{level:4,title:"DNS TTL",slug:"dns-ttl"},{level:4,title:"HttpDNS",slug:"httpdns"},{level:5,title:"HttpDNS 的缓存设计",slug:"httpdns-的缓存设计"},{level:5,title:"HttpDNS 的调度设计",slug:"httpdns-的调度设计"},{level:2,title:"CDN",slug:"cdn"},{level:4,title:"CNAME解析",slug:"cname解析"},{level:4,title:"CDN分发系统",slug:"cdn分发系统"},{level:5,title:"客户端如何找到相应的边缘节点进行访问呢?",slug:"客户端如何找到相应的边缘节点进行访问呢"}],lastUpdated:"2023/05/23, 00:05:49",lastUpdatedTimestamp:1684771549e3},{title:"okhttp",frontmatter:{title:"okhttp",date:"2023-04-28T07:22:13.000Z",permalink:"/pages/f1d871/",sidebar:"auto",categories:["网络"],tags:[null],author:{name:"Jacky",email:"jackdoson2011@gmail.com",link:"https://github.com/jacky1234"}},regularPath:"/04.%E5%85%B6%E4%BB%96/02.%E7%BD%91%E7%BB%9C/04.okhttp.html",relativePath:"04.其他/02.网络/04.okhttp.md",key:"v-070ecef7",path:"/pages/f1d871/",lastUpdated:"2023/05/23, 00:05:49",lastUpdatedTimestamp:1684771549e3},{title:"移动端的网络优化",frontmatter:{title:"移动端的网络优化",date:"2023-04-28T07:22:13.000Z",permalink:"/pages/109caf/",sidebar:"auto",categories:["网络"],tags:[null],author:{name:"Jacky",email:"jackdoson2011@gmail.com",link:"https://github.com/jacky1234"}},regularPath:"/04.%E5%85%B6%E4%BB%96/02.%E7%BD%91%E7%BB%9C/05.%E7%A7%BB%E5%8A%A8%E7%AB%AF%E7%9A%84%E7%BD%91%E7%BB%9C%E4%BC%98%E5%8C%96.html",relativePath:"04.其他/02.网络/05.移动端的网络优化.md",key:"v-1b2f2f72",path:"/pages/109caf/",headers:[{level:3,title:"请求速度优化",slug:"请求速度优化"},{level:2,title:"参考",slug:"参考"}],lastUpdated:"2023/05/23, 00:05:49",lastUpdatedTimestamp:1684771549e3},{title:"websocket-socket",frontmatter:{title:"websocket-socket",date:"2023-04-28T07:22:13.000Z",permalink:"/pages/10a997/",sidebar:"auto",categories:["网络"],tags:[null],author:{name:"Jacky",email:"jackdoson2011@gmail.com",link:"https://github.com/jacky1234"}},regularPath:"/04.%E5%85%B6%E4%BB%96/02.%E7%BD%91%E7%BB%9C/06.websocket-socket.html",relativePath:"04.其他/02.网络/06.websocket-socket.md",key:"v-7816d697",path:"/pages/10a997/",headers:[{level:2,title:"WebSocket",slug:"websocket"},{level:3,title:"附件",slug:"附件"},{level:2,title:"Socket",slug:"socket"},{level:3,title:"常见问题汇总",slug:"常见问题汇总"},{level:4,title:"半包,粘包与分包",slug:"半包-粘包与分包"},{level:4,title:"TCP的三次握手与四次挥手",slug:"tcp的三次握手与四次挥手"},{level:5,title:"三次握手建立连接",slug:"三次握手建立连接"},{level:5,title:"四次握手断开连接",slug:"四次握手断开连接"},{level:2,title:"WebSocket 与 Socket 区别",slug:"websocket-与-socket-区别"}],lastUpdated:"2023/05/23, 00:05:49",lastUpdatedTimestamp:1684771549e3},{title:"前言",frontmatter:{title:"前言",date:"2023-05-22T16:40:54.000Z",permalink:"/pages/6ea216/",categories:["other","语言","C&C++"],tags:[null],author:{name:"Jacky",email:"jackdoson2011@gmail.com",link:"https://github.com/jacky1234"}},regularPath:"/04.%E5%85%B6%E4%BB%96/03.%E8%AF%AD%E8%A8%80/01.C&C++/01.%E5%89%8D%E8%A8%80.html",relativePath:"04.其他/03.语言/01.C&C++/01.前言.md",key:"v-86d5fbe8",path:"/pages/6ea216/",headers:[{level:2,title:"link",slug:"link"}],lastUpdated:"2023/05/23, 00:05:49",lastUpdatedTimestamp:1684771549e3},{title:"C++面试突击",frontmatter:{title:"C++面试突击",date:"2023-04-28T07:27:40.000Z",permalink:"/pages/ca8e7a/",categories:["语言"],tags:["C","C++","面试"],author:{name:"Jacky",email:"jackdoson2011@gmail.com",link:"https://github.com/jacky1234"}},regularPath:"/04.%E5%85%B6%E4%BB%96/03.%E8%AF%AD%E8%A8%80/01.C&C++/05.C++%E9%9D%A2%E8%AF%95%E7%AA%81%E5%87%BB.html",relativePath:"04.其他/03.语言/01.C&C++/05.C++面试突击.md",key:"v-12e360e7",path:"/pages/ca8e7a/",headers:[{level:2,title:"C++ 程序编译过程",slug:"c-程序编译过程"},{level:2,title:"C++ 内存管理",slug:"c-内存管理"},{level:2,title:"栈和堆的区别",slug:"栈和堆的区别"},{level:2,title:"变量的区别",slug:"变量的区别"},{level:2,title:"全局变量定义在头文件中有什么问题?",slug:"全局变量定义在头文件中有什么问题"},{level:2,title:"对象创建限制在堆或栈",slug:"对象创建限制在堆或栈"},{level:2,title:"内存对齐",slug:"内存对齐"},{level:2,title:"类的大小",slug:"类的大小"},{level:2,title:"什么是内存泄露",slug:"什么是内存泄露"},{level:2,title:"怎么防止内存泄漏?内存泄漏检测工具的原理?",slug:"怎么防止内存泄漏-内存泄漏检测工具的原理"},{level:2,title:"智能指针的实现原理",slug:"智能指针的实现原理"},{level:2,title:"一个 uniqueptr 怎么赋值给另一个 uniqueptr 对象?",slug:"一个-unique-ptr-怎么赋值给另一个-unique-ptr-对象"},{level:2,title:"使用智能指针会出现什么问题?怎么解决?",slug:"使用智能指针会出现什么问题-怎么解决"},{level:2,title:"C++ 11 新特性",slug:"c-11-新特性"},{level:2,title:"C 和 C++ 的区别",slug:"c-和-c-的区别"},{level:2,title:"Java 和 C++ 的区别",slug:"java-和-c-的区别"},{level:2,title:"Python 和 C++ 的区别",slug:"python-和-c-的区别"},{level:2,title:"什么是面向对象?面向对象的三大特性",slug:"什么是面向对象-面向对象的三大特性"},{level:2,title:"重载、重写、隐藏的区别",slug:"重载、重写、隐藏的区别"},{level:2,title:"如何理解 C++ 是面向对象编程",slug:"如何理解-c-是面向对象编程"},{level:2,title:"什么是多态?多态如何实现?",slug:"什么是多态-多态如何实现"},{level:2,title:"sizeof 和 strlen 的区别",slug:"sizeof-和-strlen-的区别"},{level:2,title:"lambda 表达式(匿名函数)的具体应用和使用场景",slug:"lambda-表达式-匿名函数-的具体应用和使用场景"},{level:2,title:"explicit 的作用(如何避免编译器进行隐式类型转换)",slug:"explicit-的作用-如何避免编译器进行隐式类型转换"},{level:2,title:"C 和 C++ static 的区别",slug:"c-和-c-static-的区别"},{level:2,title:"static 的作用",slug:"static-的作用"},{level:2,title:"static 在类中使用的注意事项(定义、初始化和使用)",slug:"static-在类中使用的注意事项-定义、初始化和使用"},{level:2,title:"static 全局变量和普通全局变量的异同",slug:"static-全局变量和普通全局变量的异同"},{level:2,title:"const 作用及用法",slug:"const-作用及用法"},{level:2,title:"define 和 const 的区别",slug:"define-和-const-的区别"},{level:2,title:"define 和 typedef 的区别",slug:"define-和-typedef-的区别"},{level:2,title:"用宏实现比较大小,以及两个数中的最小值",slug:"用宏实现比较大小-以及两个数中的最小值"},{level:2,title:"inline 作用及使用方法",slug:"inline-作用及使用方法"},{level:2,title:"inline 函数工作原理",slug:"inline-函数工作原理"},{level:2,title:"宏定义(define)和内联函数(inline)的区别",slug:"宏定义-define-和内联函数-inline-的区别"},{level:2,title:"new 的作用?",slug:"new-的作用"},{level:2,title:"new 和 malloc 如何判断是否申请到内存?",slug:"new-和-malloc-如何判断是否申请到内存"},{level:2,title:"delete 实现原理?delete 和 delete[] 的区别?",slug:"delete-实现原理-delete-和-delete-的区别"},{level:2,title:"new 和 malloc 的区别,delete 和 free 的区别",slug:"new-和-malloc-的区别-delete-和-free-的区别"},{level:2,title:"malloc 的原理?malloc 的底层实现?",slug:"malloc-的原理-malloc-的底层实现"},{level:2,title:"C 和 C++ struct 的区别?",slug:"c-和-c-struct-的区别"},{level:2,title:"为什么有了 class 还保留 struct?",slug:"为什么有了-class-还保留-struct"},{level:2,title:"struct 和 union 的区别",slug:"struct-和-union-的区别"},{level:2,title:"class 和 struct 的异同",slug:"class-和-struct-的异同"},{level:2,title:"volatile 的作用?是否具有原子性,对编译器有什么影响?",slug:"volatile-的作用-是否具有原子性-对编译器有什么影响"},{level:2,title:"什么情况下一定要用 volatile, 能否和 const 一起使用?",slug:"什么情况下一定要用-volatile-能否和-const-一起使用"},{level:2,title:"返回函数中静态变量的地址会发生什么?",slug:"返回函数中静态变量的地址会发生什么"},{level:2,title:"extern C 的作用?",slug:"extern-c-的作用"},{level:2,title:"sizeof(1==1) 在 C 和 C++ 中分别是什么结果?",slug:"sizeof-1-1-在-c-和-c-中分别是什么结果"},{level:2,title:"memcpy 函数的底层原理?",slug:"memcpy-函数的底层原理"},{level:2,title:"strcpy 函数有什么缺陷?",slug:"strcpy-函数有什么缺陷"},{level:2,title:"auto 类型推导的原理",slug:"auto-类型推导的原理"},{level:2,title:"什么是虚函数?什么是纯虚函数?",slug:"什么是虚函数-什么是纯虚函数"},{level:2,title:"虚函数和纯虚函数的区别?",slug:"虚函数和纯虚函数的区别"},{level:2,title:"虚函数的实现机制",slug:"虚函数的实现机制"},{level:2,title:"单继承和多继承的虚函数表结构",slug:"单继承和多继承的虚函数表结构"},{level:2,title:"如何禁止构造函数的使用?",slug:"如何禁止构造函数的使用"},{level:2,title:"什么是类的默认构造函数?",slug:"什么是类的默认构造函数"},{level:2,title:"构造函数、析构函数是否需要定义成虚函数?为什么?",slug:"构造函数、析构函数是否需要定义成虚函数-为什么"},{level:2,title:"如何避免拷贝?",slug:"如何避免拷贝"},{level:2,title:"如何减少构造函数开销?",slug:"如何减少构造函数开销"},{level:2,title:"多重继承时会出现什么状况?如何解决?",slug:"多重继承时会出现什么状况-如何解决"},{level:2,title:"空类占多少字节?C++ 编译器会给一个空类自动生成哪些函数?",slug:"空类占多少字节-c-编译器会给一个空类自动生成哪些函数"},{level:2,title:"为什么拷贝构造函数必须为引用?",slug:"为什么拷贝构造函数必须为引用"},{level:2,title:"C++ 类对象的初始化顺序",slug:"c-类对象的初始化顺序"},{level:2,title:"如何禁止一个类被实例化?",slug:"如何禁止一个类被实例化"},{level:2,title:"为什么用成员初始化列表会快一些?",slug:"为什么用成员初始化列表会快一些"},{level:2,title:"实例化一个对象需要哪几个阶段",slug:"实例化一个对象需要哪几个阶段"},{level:2,title:"友元函数的作用及使用场景",slug:"友元函数的作用及使用场景"},{level:2,title:"静态绑定和动态绑定是怎么实现的?",slug:"静态绑定和动态绑定是怎么实现的"},{level:2,title:"深拷贝和浅拷贝的区别",slug:"深拷贝和浅拷贝的区别"},{level:2,title:"编译时多态和运行时多态的区别",slug:"编译时多态和运行时多态的区别"},{level:2,title:"实现一个类成员函数,要求不允许修改类的成员变量?",slug:"实现一个类成员函数-要求不允许修改类的成员变量"},{level:2,title:"如何让类不能被继承?",slug:"如何让类不能被继承"},{level:2,title:"左值和右值的区别?左值引用和右值引用的区别,如何将左值转换成右值?",slug:"左值和右值的区别-左值引用和右值引用的区别-如何将左值转换成右值"},{level:2,title:"std::move() 函数的实现原理",slug:"std-move-函数的实现原理"},{level:2,title:"什么是指针?指针的大小及用法?",slug:"什么是指针-指针的大小及用法"},{level:2,title:"什么是野指针和悬空指针?",slug:"什么是野指针和悬空指针"},{level:2,title:"C++ 11 nullptr 比 NULL 优势",slug:"c-11-nullptr-比-null-优势"},{level:2,title:"指针和引用的区别?",slug:"指针和引用的区别"},{level:2,title:"常量指针和指针常量的区别",slug:"常量指针和指针常量的区别"},{level:2,title:"指针常量",slug:"指针常量"},{level:2,title:"函数指针和指针函数的区别",slug:"函数指针和指针函数的区别"},{level:2,title:"强制类型转换有哪几种?",slug:"强制类型转换有哪几种"},{level:2,title:"如何判断结构体是否相等?能否用 memcmp 函数判断结构体相等?",slug:"如何判断结构体是否相等-能否用-memcmp-函数判断结构体相等"},{level:2,title:"参数传递时,值传递、引用传递、指针传递的区别?",slug:"参数传递时-值传递、引用传递、指针传递的区别"},{level:2,title:"什么是模板?如何实现?",slug:"什么是模板-如何实现"},{level:2,title:"函数模板和类模板的区别?",slug:"函数模板和类模板的区别"},{level:2,title:"什么是可变参数模板?",slug:"什么是可变参数模板"},{level:2,title:"什么是模板特化?为什么特化?",slug:"什么是模板特化-为什么特化"},{level:2,title:'include " " 和 的区别',slug:"include-和-的区别"},{level:2,title:"switch 的 case 里为何不能定义变量",slug:"switch-的-case-里为何不能定义变量"},{level:2,title:"迭代器的作用?",slug:"迭代器的作用"},{level:2,title:"泛型编程如何实现?",slug:"泛型编程如何实现"},{level:2,title:"什么是类型萃取?",slug:"什么是类型萃取"},{level:2,title:"了解哪些设计模式?",slug:"了解哪些设计模式"},{level:2,title:"什么是单例模式?如何实现?应用场景?",slug:"什么是单例模式-如何实现-应用场景"},{level:2,title:"什么是工厂模式?如何实现?应用场景?",slug:"什么是工厂模式-如何实现-应用场景"},{level:2,title:"什么是观察者模式?如何实现?应用场景?",slug:"什么是观察者模式-如何实现-应用场景"}],lastUpdated:"2023/05/26, 17:09:24",lastUpdatedTimestamp:1685092164e3},{title:"博客指南",frontmatter:{title:"博客指南",date:"2023-04-25T00:17:27.000Z",permalink:"/pages/df7642/",tags:["blog","github"],author:{name:"Jacky",email:"jackdoson2011@gmail.com",link:"https://github.com/jacky1234"},categories:["其他","博客"]},regularPath:"/04.%E5%85%B6%E4%BB%96/05.%E5%8D%9A%E5%AE%A2/01.%E5%86%99%E5%8D%9A%E5%AE%A2%E7%9A%84%E9%82%A3%E4%BA%9B%E4%BA%8B.html",relativePath:"04.其他/05.博客/01.写博客的那些事.md",key:"v-15dd7598",path:"/pages/df7642/",headers:[{level:2,title:"博客前言",slug:"博客前言"},{level:2,title:"快速构建个人网站的一些方案",slug:"快速构建个人网站的一些方案"},{level:3,title:"HUGO vs Vuepress",slug:"hugo-vs-vuepress"},{level:2,title:"使用 vuepress 构建自己的个人网站",slug:"使用-vuepress-构建自己的个人网站"},{level:2,title:"参考",slug:"参考"}],lastUpdated:"2023/07/02, 21:28:55",lastUpdatedTimestamp:1688304535e3},{title:"vuepress的简单记录",frontmatter:{title:"vuepress的简单记录",date:"2023-05-03T20:18:42.000Z",permalink:"/pages/30ec1d/",categories:["其他","博客"],tags:["vuepress","blog"],author:{name:"Jacky",email:"jackdoson2011@gmail.com",link:"https://github.com/jacky1234"}},regularPath:"/04.%E5%85%B6%E4%BB%96/05.%E5%8D%9A%E5%AE%A2/02.vuepress%E7%AE%80%E5%8D%95%E8%AE%B0%E5%BD%95.html",relativePath:"04.其他/05.博客/02.vuepress简单记录.md",key:"v-609ee02a",path:"/pages/30ec1d/",headers:[{level:2,title:"如何学",slug:"如何学"},{level:2,title:"内置对象",slug:"内置对象"},{level:3,title:"$page 对象",slug:"page-对象"},{level:3,title:"$contentClass",slug:"contentclass"},{level:3,title:"vuepress 钩子函数: extendPageData",slug:"vuepress-钩子函数-extendpagedata"}],lastUpdated:"2023/06/09, 20:00:16",lastUpdatedTimestamp:1686312016e3},{title:"GitHub Actions 实现自动部署静态博客",frontmatter:{title:"GitHub Actions 实现自动部署静态博客",date:"2023-04-25T10:50:44.000Z",permalink:"/pages/a96c0f/",categories:["其他","博客"],tags:["博客"],author:{name:"Jacky",email:"jackdoson2011@gmail.com",link:"https://github.com/jacky1234"}},regularPath:"/04.%E5%85%B6%E4%BB%96/05.%E5%8D%9A%E5%AE%A2/03.GitHub%20Actions%20%E5%AE%9E%E7%8E%B0%E8%87%AA%E5%8A%A8%E9%83%A8%E7%BD%B2%E9%9D%99%E6%80%81%E5%8D%9A%E5%AE%A2.html",relativePath:"04.其他/05.博客/03.GitHub Actions 实现自动部署静态博客.md",key:"v-305a0220",path:"/pages/a96c0f/",headers:[{level:2,title:"前言",slug:"前言"},{level:2,title:"实现",slug:"实现"},{level:3,title:"CI 结果使用邮箱通知",slug:"ci-结果使用邮箱通知"},{level:4,title:"配置 qq 邮箱服务器地址",slug:"配置-qq-邮箱服务器地址"}],excerpt:'
\n

# 前言

\n

在使用 vuepress 搭建了一个静态博客后,挂在了 Github pages 和Coding pages上面。

\n

coding pages 在国内的访问速度比 github pages 要快很多,而且还可以被百度收录。

\n',lastUpdated:"2023/06/14, 22:06:42",lastUpdatedTimestamp:1686751602e3},{title:"快速实现",frontmatter:{title:"快速实现",date:"2023-07-04T16:28:41.000Z",permalink:"/pages/857c89/",categories:["其他","side-project"],tags:[null],author:{name:"Jacky",email:"jackdoson2011@gmail.com",link:"https://github.com/jacky1234"}},regularPath:"/04.%E5%85%B6%E4%BB%96/06.side-project/02.%E5%BF%AB%E9%80%9F%E5%AE%9E%E7%8E%B0.html",relativePath:"04.其他/06.side-project/02.快速实现.md",key:"v-5178a0a2",path:"/pages/857c89/",headers:[{level:2,title:"你不一定要写代码",slug:"你不一定要写代码"},{level:2,title:"第一版做到什么程度",slug:"第一版做到什么程度"},{level:2,title:"我使用的一些建筑工具",slug:"我使用的一些建筑工具"}],lastUpdated:"2023/07/04, 19:58:05",lastUpdatedTimestamp:1688471885e3},{title:"管理学",frontmatter:{title:"管理学",date:"2023-07-05T10:45:20.000Z",permalink:"/pages/186356/",categories:["其他","成长"],tags:[null],author:{name:"Jacky",email:"jackdoson2011@gmail.com",link:"https://github.com/jacky1234"}},regularPath:"/04.%E5%85%B6%E4%BB%96/07.%E6%88%90%E9%95%BF/02.%E7%AE%A1%E7%90%86%E8%AF%B4.html",relativePath:"04.其他/07.成长/02.管理说.md",key:"v-968fc044",path:"/pages/186356/",headers:[{level:2,title:"招人",slug:"招人"},{level:3,title:"定义人才",slug:"定义人才"},{level:3,title:"识人",slug:"识人"},{level:4,title:"ASK 模型",slug:"ask-模型"},{level:5,title:"Ability 的考察",slug:"ability-的考察"},{level:2,title:"links",slug:"links"}],lastUpdated:"2023/07/06, 18:13:54",lastUpdatedTimestamp:1688638434e3},{title:"技术规范等整理",frontmatter:{title:"技术规范等整理",date:"2023-07-05T21:07:05.000Z",permalink:"/pages/bea5e2/",categories:["其他","成长"],tags:[null],author:{name:"Jacky",email:"jackdoson2011@gmail.com",link:"https://github.com/jacky1234"}},regularPath:"/04.%E5%85%B6%E4%BB%96/07.%E6%88%90%E9%95%BF/03.coding.html",relativePath:"04.其他/07.成长/03.coding.md",key:"v-32c1407b",path:"/pages/bea5e2/",headers:[{level:2,title:"链接",slug:"链接"}],lastUpdated:"2023/07/05, 22:00:26",lastUpdatedTimestamp:1688565626e3},{title:"Java tutorial",frontmatter:{title:"Java tutorial",date:"2023-08-22T23:20:05.000Z",permalink:"/pages/c38a8f/",categories:["其他","java"],tags:[null],author:{name:"Jacky",email:"jackdoson2011@gmail.com",link:"https://github.com/jacky1234"}},regularPath:"/04.%E5%85%B6%E4%BB%96/08.java/01.tutorial.html",relativePath:"04.其他/08.java/01.tutorial.md",key:"v-98f03ec0",path:"/pages/c38a8f/",headers:[{level:2,title:"常用",slug:"常用"}],lastUpdated:"2023/09/17, 22:27:30",lastUpdatedTimestamp:169496085e4},{title:"如何睡觉",frontmatter:{title:"如何睡觉",date:"2023-07-05T10:39:47.000Z",permalink:"/pages/b21fed/",categories:["其他","成长"],tags:[null],author:{name:"Jacky",email:"jackdoson2011@gmail.com",link:"https://github.com/jacky1234"}},regularPath:"/04.%E5%85%B6%E4%BB%96/07.%E6%88%90%E9%95%BF/10.%E5%A6%82%E4%BD%95%E7%9D%A1%E8%A7%89.html",relativePath:"04.其他/07.成长/10.如何睡觉.md",key:"v-90d8d00a",path:"/pages/b21fed/",lastUpdated:"2023/07/05, 22:00:26",lastUpdatedTimestamp:1688565626e3},{title:"UnSafe",frontmatter:{title:"UnSafe",date:"2023-08-03T21:51:54.000Z",permalink:"/pages/c3229c/",categories:["其他","java"],tags:["java","unsafe"],author:{name:"Jacky",email:"jackdoson2011@gmail.com",link:"https://github.com/jacky1234"}},regularPath:"/04.%E5%85%B6%E4%BB%96/08.java/100.UnSafe.html",relativePath:"04.其他/08.java/100.UnSafe.md",key:"v-59d0a910",path:"/pages/c3229c/",headers:[{level:2,title:"UnSafe",slug:"unsafe"},{level:2,title:"示例",slug:"示例"},{level:3,title:"操作对象属性",slug:"操作对象属性"}],lastUpdated:"2023/08/03, 22:01:49",lastUpdatedTimestamp:1691071309e3},{title:"集合",frontmatter:{title:"集合",date:"2023-08-09T08:24:23.000Z",permalink:"/pages/55dc87/",categories:["其他","java"],tags:["collection","queue","deque"],author:{name:"Jacky",email:"jackdoson2011@gmail.com",link:"https://github.com/jacky1234"}},regularPath:"/04.%E5%85%B6%E4%BB%96/08.java/101.%E9%9B%86%E5%90%88.html",relativePath:"04.其他/08.java/101.集合.md",key:"v-409f96f4",path:"/pages/55dc87/",headers:[{level:2,title:"Deque",slug:"deque"},{level:3,title:"ArrayDeque",slug:"arraydeque"}],lastUpdated:"2023/08/23, 17:58:27",lastUpdatedTimestamp:1692784707e3},{title:"Class类",frontmatter:{title:"Class类",date:"2023-08-22T16:55:56.000Z",permalink:"/pages/ed7a6a/",categories:["其他","java"],tags:[null],author:{name:"Jacky",email:"jackdoson2011@gmail.com",link:"https://github.com/jacky1234"}},regularPath:"/04.%E5%85%B6%E4%BB%96/08.java/102.Class%E7%B1%BB.html",relativePath:"04.其他/08.java/102.Class类.md",key:"v-21640095",path:"/pages/ed7a6a/",headers:[{level:2,title:"api",slug:"api"},{level:3,title:"getGenericSuperclass",slug:"getgenericsuperclass"}],lastUpdated:"2023/08/22, 22:10:19",lastUpdatedTimestamp:1692713419e3},{title:"使用 Jenv 实现 Jdk 多版本管理",frontmatter:{title:"使用 Jenv 实现 Jdk 多版本管理",date:"2023-09-17T22:14:00.000Z",permalink:"/pages/935419/",categories:["其他","java"],tags:[null],author:{name:"Jacky",email:"jackdoson2011@gmail.com",link:"https://github.com/jacky1234"}},regularPath:"/04.%E5%85%B6%E4%BB%96/08.java/50.%E4%BD%BF%E7%94%A8%20Jenv%20%E5%AE%9E%E7%8E%B0%20Jdk%20%E5%A4%9A%E7%89%88%E6%9C%AC%E7%AE%A1%E7%90%86.html",relativePath:"04.其他/08.java/50.使用 Jenv 实现 Jdk 多版本管理.md",key:"v-01db55a2",path:"/pages/935419/",lastUpdated:"2023/09/17, 22:27:30",lastUpdatedTimestamp:169496085e4},{title:"tutorial",frontmatter:{title:"tutorial",date:"2023-09-11T11:24:59.000Z",permalink:"/pages/18abfe/",categories:["其他","linux"],tags:["linux"],author:{name:"Jacky",email:"jackdoson2011@gmail.com",link:"https://github.com/jacky1234"}},regularPath:"/04.%E5%85%B6%E4%BB%96/09.linux/01.tutorial.html",relativePath:"04.其他/09.linux/01.tutorial.md",key:"v-d3a2f914",path:"/pages/18abfe/",headers:[{level:2,title:"介绍",slug:"介绍"},{level:2,title:"发行版",slug:"发行版"},{level:3,title:"Debian",slug:"debian"}],lastUpdated:"2023/09/11, 11:39:30",lastUpdatedTimestamp:169440357e4},{title:"音视频概述",frontmatter:{title:"音视频概述",date:"2023-05-28T14:29:00.000Z",permalink:"/pages/086701/",categories:["《音视频开发》"],tags:["音视频"],author:{name:"Jacky",email:"jackdoson2011@gmail.com",link:"https://github.com/jacky1234"}},regularPath:"/04.%E5%85%B6%E4%BB%96/10.%E6%9B%B4%E5%A4%9A/10.%E9%9F%B3%E8%A7%86%E9%A2%91%E6%A6%82%E8%BF%B0.html",relativePath:"04.其他/10.更多/10.音视频概述.md",key:"v-68e19f6a",path:"/pages/086701/",headers:[{level:2,title:"OpenGL",slug:"opengl"},{level:2,title:"FFMEPG",slug:"ffmepg"},{level:3,title:"FFmpeg Tools",slug:"ffmpeg-tools"},{level:2,title:"其他",slug:"其他"},{level:2,title:"链接",slug:"链接"},{level:3,title:"SUB",slug:"sub"}],lastUpdated:"2023/07/19, 21:58:25",lastUpdatedTimestamp:1689775105e3},{title:"测试页面",frontmatter:{title:"测试页面",date:"2023-05-25T17:06:44.000Z",permalink:"/pages/d3b34e/",categories:["《linux》","shell"],tags:[null],author:{name:"Jacky",email:"jackdoson2011@gmail.com",link:"https://github.com/jacky1234"}},regularPath:"/04.%E5%85%B6%E4%BB%96/10.%E6%9B%B4%E5%A4%9A/100.%E6%B5%8B%E8%AF%95%E9%A1%B5%E9%9D%A2.html",relativePath:"04.其他/10.更多/100.测试页面.md",key:"v-3ee66df2",path:"/pages/d3b34e/",headers:[{level:2,title:"RText",slug:"rtext"},{level:2,title:"Badge",slug:"badge"},{level:2,title:"TODO",slug:"todo"},{level:2,title:"代码块选项卡",slug:"代码块选项卡"},{level:2,title:"链接",slug:"链接"}],lastUpdated:"2023/09/14, 01:08:35",lastUpdatedTimestamp:1694624915e3},{title:"沟通的艺术",frontmatter:{title:"沟通的艺术",date:"2023-09-06T23:27:58.000Z",permalink:"/pages/6cd2e1/",categories:["其他","更多"],tags:[null],author:{name:"Jacky",email:"jackdoson2011@gmail.com",link:"https://github.com/jacky1234"}},regularPath:"/04.%E5%85%B6%E4%BB%96/10.%E6%9B%B4%E5%A4%9A/101.%E6%B2%9F%E9%80%9A%E7%9A%84%E8%89%BA%E6%9C%AF.html",relativePath:"04.其他/10.更多/101.沟通的艺术.md",key:"v-0461446e",path:"/pages/6cd2e1/",headers:[{level:2,title:"常用",slug:"常用"},{level:3,title:"谢谢",slug:"谢谢"},{level:2,title:"链接",slug:"链接"}],lastUpdated:"2023/09/07, 09:06:36",lastUpdatedTimestamp:1694048796e3},{title:"工作效率",frontmatter:{title:"工作效率",date:"2023-06-05T22:17:58.000Z",permalink:"/pages/d9fade/",categories:["其他","更多"],tags:["rss"],author:{name:"Jacky",email:"jackdoson2011@gmail.com",link:"https://github.com/jacky1234"}},regularPath:"/04.%E5%85%B6%E4%BB%96/10.%E6%9B%B4%E5%A4%9A/12.%E6%95%88%E7%8E%87.html",relativePath:"04.其他/10.更多/12.效率.md",key:"v-ab0b636a",path:"/pages/d9fade/",headers:[{level:2,title:"高效获取信息-RSS 订阅服务",slug:"高效获取信息-rss-订阅服务"},{level:3,title:"什么是 RSS",slug:"什么是-rss"},{level:3,title:"订阅程序简介",slug:"订阅程序简介"},{level:2,title:"通过 GitHub 订阅 Hacker News 每日 top 10",slug:"通过-github-订阅-hacker-news-每日-top-10"}],lastUpdated:"2023/06/15, 21:49:15",lastUpdatedTimestamp:1686836955e3},{title:"技术专业词汇",frontmatter:{title:"技术专业词汇",date:"2023-06-02T09:13:28.000Z",permalink:"/pages/f7262c/",categories:["其他","更多"],tags:["术语"],author:{name:"Jacky",email:"jackdoson2011@gmail.com",link:"https://github.com/jacky1234"}},regularPath:"/04.%E5%85%B6%E4%BB%96/10.%E6%9B%B4%E5%A4%9A/13.%E6%8A%80%E6%9C%AF%E4%B8%93%E4%B8%9A%E8%AF%8D%E6%B1%87.html",relativePath:"04.其他/10.更多/13.技术专业词汇.md",key:"v-033ef56a",path:"/pages/f7262c/",headers:[{level:2,title:"概念",slug:"概念"},{level:3,title:"全双工/半双工/单工",slug:"全双工-半双工-单工"},{level:2,title:"前端",slug:"前端"},{level:3,title:"LDS",slug:"lds"},{level:3,title:"html 中的 SSR",slug:"html-中的-ssr"},{level:2,title:"后端",slug:"后端"},{level:3,title:"反向/正向代理",slug:"反向-正向代理"},{level:3,title:"wlan0",slug:"wlan0"},{level:3,title:"DevOps",slug:"devops"},{level:3,title:"数据库系统",slug:"数据库系统"},{level:3,title:"服务熔断",slug:"服务熔断"},{level:3,title:"uv/vv/pv/dau/gmv",slug:"uv-vv-pv-dau-gmv"},{level:3,title:"FaaS",slug:"faas"},{level:3,title:"URL 编码",slug:"url-编码"},{level:3,title:"ASCII",slug:"ascii"},{level:3,title:"染色概念",slug:"染色概念"},{level:2,title:"websocket VS socket",slug:"websocket-vs-socket"},{level:3,title:"Dao(Data Access Object)",slug:"dao-data-access-object"},{level:3,title:"mapper",slug:"mapper"},{level:3,title:"JDBC(Java Database Connectivity)",slug:"jdbc-java-database-connectivity"},{level:3,title:"JPA(Java Persistence API)",slug:"jpa-java-persistence-api"},{level:3,title:"jwt",slug:"jwt"},{level:3,title:"CORS",slug:"cors"},{level:3,title:"Swagger3",slug:"swagger3"},{level:3,title:"RESTful API",slug:"restful-api"},{level:3,title:"AspectJ 实现 AOP",slug:"aspectj-实现-aop"},{level:2,title:"常用依赖",slug:"常用依赖"},{level:3,title:"lombok",slug:"lombok"},{level:3,title:"logback",slug:"logback"},{level:3,title:"mybatis",slug:"mybatis"},{level:2,title:"其他",slug:"其他"},{level:3,title:"nginx",slug:"nginx"},{level:3,title:"kibana",slug:"kibana"},{level:3,title:"Kubernetes",slug:"kubernetes"}],lastUpdated:"2023/09/15, 19:13:10",lastUpdatedTimestamp:169477639e4},{title:"设计模式和思想",frontmatter:{title:"设计模式和思想",date:"2021-04-28T07:22:13.000Z",permalink:"/pages/db8380/",sidebar:"auto",categories:["其他","更多"],tags:["设计模式"],author:{name:"Jacky",email:"jackdoson2011@gmail.com",link:"https://github.com/jacky1234"}},regularPath:"/04.%E5%85%B6%E4%BB%96/10.%E6%9B%B4%E5%A4%9A/14.%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E5%92%8C%E6%80%9D%E6%83%B3.html",relativePath:"04.其他/10.更多/14.设计模式和思想.md",key:"v-6f79c7d0",path:"/pages/db8380/",headers:[{level:2,title:"看懂 UML 类图和时序图",slug:"看懂-uml-类图和时序图"},{level:3,title:"聚合与组合",slug:"聚合与组合"},{level:2,title:"设计模式的六大原则",slug:"设计模式的六大原则"},{level:2,title:"SPI",slug:"spi"},{level:2,title:"AOP",slug:"aop"},{level:2,title:"结构型设计模式",slug:"结构型设计模式"},{level:3,title:"MVC MVP MVVM",slug:"mvc-mvp-mvvm"},{level:4,title:"MVC",slug:"mvc"},{level:5,title:"优缺点",slug:"优缺点"},{level:4,title:"MVP",slug:"mvp"},{level:5,title:"优缺点",slug:"优缺点-2"},{level:4,title:"MVVM",slug:"mvvm"},{level:3,title:"桥接模式",slug:"桥接模式"},{level:3,title:"适配器模式",slug:"适配器模式"},{level:3,title:"装饰模式",slug:"装饰模式"},{level:3,title:"代理模式",slug:"代理模式"},{level:4,title:"静态代理",slug:"静态代理"},{level:4,title:"动态代理",slug:"动态代理"},{level:2,title:"创建型设计模式",slug:"创建型设计模式"},{level:3,title:"单例模式",slug:"单例模式"},{level:3,title:"建造者模式",slug:"建造者模式"},{level:3,title:"工厂方法模式",slug:"工厂方法模式"},{level:2,title:"行为设计模式",slug:"行为设计模式"},{level:3,title:"观察者模式",slug:"观察者模式"},{level:3,title:"迭代器模式",slug:"迭代器模式"},{level:3,title:"备忘录模式",slug:"备忘录模式"},{level:2,title:"模式对比",slug:"模式对比"},{level:3,title:"代理模式和装饰模式区别",slug:"代理模式和装饰模式区别"},{level:2,title:"链接",slug:"链接"}],lastUpdated:"2023/08/17, 21:58:02",lastUpdatedTimestamp:1692280682e3},{title:"frida",frontmatter:{title:"frida",date:"2023-05-26T17:10:40.000Z",permalink:"/pages/0fe5d6/",categories:["其他","安全"],tags:["逆向","frida","apm","安全"],author:{name:"Jacky",email:"jackdoson2011@gmail.com",link:"https://github.com/jacky1234"}},regularPath:"/04.%E5%85%B6%E4%BB%96/10.%E6%9B%B4%E5%A4%9A/20.frida.html",relativePath:"04.其他/10.更多/20.frida.md",key:"v-718a15ee",path:"/pages/0fe5d6/",headers:[{level:2,title:"环境准备",slug:"环境准备"},{level:3,title:"magisk",slug:"magisk"},{level:4,title:"modules 介绍",slug:"modules-介绍"},{level:4,title:"MagiskHidePropsConf 使用",slug:"magiskhidepropsconf-使用"},{level:4,title:"MagiskFrida",slug:"magiskfrida"},{level:2,title:"frida",slug:"frida"},{level:3,title:"Gadget",slug:"gadget"},{level:3,title:"stalker",slug:"stalker"},{level:3,title:"Tutorials",slug:"tutorials"},{level:4,title:"Founctions",slug:"founctions"},{level:4,title:"Message",slug:"message"},{level:4,title:"IOS",slug:"ios"},{level:4,title:"Android",slug:"android"},{level:3,title:"Tools",slug:"tools"},{level:4,title:"frida cli",slug:"frida-cli"},{level:4,title:"frida-ps",slug:"frida-ps"},{level:4,title:"frida-trace",slug:"frida-trace"},{level:4,title:"frida-ls-devices",slug:"frida-ls-devices"},{level:4,title:"frida-kill",slug:"frida-kill"},{level:4,title:"gum-graft",slug:"gum-graft"},{level:2,title:"objection",slug:"objection"},{level:3,title:"常用命令",slug:"常用命令"},{level:3,title:"memory",slug:"memory"},{level:3,title:"android",slug:"android-2"},{level:4,title:"内存堆搜索与执行",slug:"内存堆搜索与执行"},{level:3,title:"file",slug:"file"},{level:3,title:"import",slug:"import"},{level:3,title:"plugin",slug:"plugin"},{level:4,title:"Wallbreaker",slug:"wallbreaker"},{level:4,title:"FRIDA-DEXDump",slug:"frida-dexdump"},{level:2,title:"最佳实践",slug:"最佳实践"},{level:2,title:"APM",slug:"apm"},{level:2,title:"其他",slug:"其他"},{level:3,title:"对象的比较",slug:"对象的比较"},{level:3,title:"$handle",slug:"handle"},{level:3,title:"访问修改静态属性字段",slug:"访问修改静态属性字段"},{level:3,title:"$符号",slug:"符号"},{level:3,title:"根据特征搜索类",slug:"根据特征搜索类"},{level:3,title:"破解方法论",slug:"破解方法论"},{level:3,title:"破解思想",slug:"破解思想"},{level:2,title:"链接",slug:"链接"}],lastUpdated:"2023/08/23, 17:58:27",lastUpdatedTimestamp:1692784707e3},{title:"Android密钥系统",frontmatter:{title:"Android密钥系统",date:"2023-08-10T21:38:36.000Z",permalink:"/pages/10e7db/",categories:["其他","更多"],tags:["安全","android"],author:{name:"Jacky",email:"jackdoson2011@gmail.com",link:"https://github.com/jacky1234"}},regularPath:"/04.%E5%85%B6%E4%BB%96/10.%E6%9B%B4%E5%A4%9A/21.Android%E5%AF%86%E9%92%A5%E5%BA%93%E7%B3%BB%E7%BB%9F.html",relativePath:"04.其他/10.更多/21.Android密钥库系统.md",key:"v-1519562b",path:"/pages/10e7db/",lastUpdated:"2023/08/11, 13:54:15",lastUpdatedTimestamp:1691733255e3},{title:"使用腾讯云服务器",frontmatter:{title:"使用腾讯云服务器",date:"2023-06-14T07:37:02.000Z",permalink:"/pages/03456e/",categories:["其他","更多"],tags:[null],author:{name:"Jacky",email:"jackdoson2011@gmail.com",link:"https://github.com/jacky1234"}},regularPath:"/04.%E5%85%B6%E4%BB%96/10.%E6%9B%B4%E5%A4%9A/30.%E4%BD%BF%E7%94%A8%E8%85%BE%E8%AE%AF%E4%BA%91%E6%9C%8D%E5%8A%A1%E5%99%A8.html",relativePath:"04.其他/10.更多/30.使用腾讯云服务器.md",key:"v-8685c0b6",path:"/pages/03456e/",lastUpdated:"2023/06/15, 21:49:15",lastUpdatedTimestamp:1686836955e3},{title:"正则",frontmatter:{title:"正则",date:"2023-09-13T12:47:35.000Z",permalink:"/pages/3d30c9/",categories:["其他","更多"],tags:[null],author:{name:"Jacky",email:"jackdoson2011@gmail.com",link:"https://github.com/jacky1234"}},regularPath:"/04.%E5%85%B6%E4%BB%96/10.%E6%9B%B4%E5%A4%9A/5.%E6%AD%A3%E5%88%99.html",relativePath:"04.其他/10.更多/5.正则.md",key:"v-37fae6a5",path:"/pages/3d30c9/",headers:[{level:2,title:"基本",slug:"基本"},{level:2,title:"复合",slug:"复合"},{level:2,title:"其他",slug:"其他"},{level:3,title:"$n,引用捕获组索引",slug:"n-引用捕获组索引"},{level:2,title:"链接",slug:"链接"}],lastUpdated:"2023/09/15, 11:57:23",lastUpdatedTimestamp:1694750243e3},{title:"读kk大神聊房价",frontmatter:{title:"读kk大神聊房价",date:"2023-07-06T14:42:29.000Z",permalink:"/pages/7c68cb/",categories:["其他","更多"],tags:[null],author:{name:"Jacky",email:"jackdoson2011@gmail.com",link:"https://github.com/jacky1234"}},regularPath:"/04.%E5%85%B6%E4%BB%96/10.%E6%9B%B4%E5%A4%9A/96.%E8%AF%BBkk%E5%A4%A7%E7%A5%9E%E8%81%8A%E6%88%BF%E4%BB%B7.html",relativePath:"04.其他/10.更多/96.读kk大神聊房价.md",key:"v-a106e244",path:"/pages/7c68cb/",lastUpdated:"2023/07/06, 18:13:54",lastUpdatedTimestamp:1688638434e3},{title:"效率秘籍",frontmatter:{title:"效率秘籍",date:"2023-04-28T19:33:35.000Z",permalink:"/pages/2af3e9/",sidebar:"auto",categories:["成长"],tags:[null],author:{name:"Jacky",email:"jackdoson2011@gmail.com",link:"https://github.com/jacky1234"}},regularPath:"/04.%E5%85%B6%E4%BB%96/10.%E6%9B%B4%E5%A4%9A/97.%E6%95%88%E7%8E%87%E7%A7%98%E7%B1%8D.html",relativePath:"04.其他/10.更多/97.效率秘籍.md",key:"v-e5a14ea8",path:"/pages/2af3e9/",headers:[{level:2,title:"5 个关键点",slug:"_5-个关键点"},{level:3,title:"一、输出倒逼输入",slug:"一、输出倒逼输入"},{level:3,title:"二、提炼模型",slug:"二、提炼模型"},{level:3,title:"三、利用工具:解放自己的大脑",slug:"三、利用工具-解放自己的大脑"},{level:3,title:"四、研究自己运行规律,找到让自己学习工作、效率更高的方法",slug:"四、研究自己运行规律-找到让自己学习工作、效率更高的方法"},{level:3,title:"五、成本可控,释放善意",slug:"五、成本可控-释放善意"}],lastUpdated:"2023/06/15, 21:49:15",lastUpdatedTimestamp:1686836955e3},{title:"mac常用工具使用",frontmatter:{title:"mac常用工具使用",date:"2023-06-16T22:11:12.000Z",permalink:"/pages/3adccf/",categories:["其他","更多"],tags:["mac"],author:{name:"Jacky",email:"jackdoson2011@gmail.com",link:"https://github.com/jacky1234"}},regularPath:"/04.%E5%85%B6%E4%BB%96/10.%E6%9B%B4%E5%A4%9A/98.mac%E5%B8%B8%E7%94%A8%E5%B7%A5%E5%85%B7%E4%BD%BF%E7%94%A8.html",relativePath:"04.其他/10.更多/98.mac常用工具使用.md",key:"v-f28180c4",path:"/pages/3adccf/",headers:[{level:2,title:"Sublime Text",slug:"sublime-text"},{level:3,title:"选择",slug:"选择"},{level:3,title:"批量插入",slug:"批量插入"},{level:3,title:"插件",slug:"插件"},{level:4,title:"Compare Side-By-Side",slug:"compare-side-by-side"},{level:2,title:"常用网址",slug:"常用网址"}],lastUpdated:"2023/07/26, 21:28:31",lastUpdatedTimestamp:1690378111e3},{title:"财经基础",frontmatter:{title:"财经基础",date:"2023-06-10T09:54:25.000Z",permalink:"/pages/c76462/",categories:["其他","更多"],tags:["术语"],author:{name:"Jacky",email:"jackdoson2011@gmail.com",link:"https://github.com/jacky1234"}},regularPath:"/04.%E5%85%B6%E4%BB%96/10.%E6%9B%B4%E5%A4%9A/99.%E8%B4%A2%E7%BB%8F%E5%9F%BA%E7%A1%80.html",relativePath:"04.其他/10.更多/99.财经基础.md",key:"v-6c8e6ac8",path:"/pages/c76462/",headers:[{level:2,title:"美国非农数据",slug:"美国非农数据"},{level:3,title:"非农数据对加息决策的影响",slug:"非农数据对加息决策的影响"},{level:3,title:"非农数据对贵金属的影响",slug:"非农数据对贵金属的影响"},{level:2,title:"降息对黄金的影响",slug:"降息对黄金的影响"},{level:2,title:"除权除息",slug:"除权除息"},{level:2,title:"tradingView",slug:"tradingview"},{level:2,title:"LPR",slug:"lpr"},{level:2,title:"2023",slug:"_2023"}],lastUpdated:"2023/08/16, 08:36:44",lastUpdatedTimestamp:1692146204e3},{title:"tiktok在国内使用",frontmatter:{title:"tiktok在国内使用",date:"2023-08-24T19:34:12.000Z",permalink:"/pages/79c121/",categories:["其他","生活方式.md"],tags:[null],author:{name:"Jacky",email:"jackdoson2011@gmail.com",link:"https://github.com/jacky1234"}},regularPath:"/04.%E5%85%B6%E4%BB%96/11.%E7%94%9F%E6%B4%BB%E6%96%B9%E5%BC%8F/01.tiktok%E5%9C%A8%E5%9B%BD%E5%86%85%E4%BD%BF%E7%94%A8.html",relativePath:"04.其他/11.生活方式/01.tiktok在国内使用.md",key:"v-5a42538e",path:"/pages/79c121/",headers:[{level:2,title:"手机设置",slug:"手机设置"},{level:2,title:"科学上网",slug:"科学上网"},{level:2,title:"ip查询验证",slug:"ip查询验证"},{level:2,title:"验证手机伪装程度",slug:"验证手机伪装程度"}],lastUpdated:"2023/08/25, 19:30:51",lastUpdatedTimestamp:1692963051e3},{title:"网站",frontmatter:{title:"网站",date:"2023-05-30T00:02:06.000Z",permalink:"/pages/5a96b7/",categories:["收藏夹"],tags:[null],author:{name:"Jacky",email:"jackdoson2011@gmail.com",link:"https://github.com/jacky1234"}},regularPath:"/05.%E6%94%B6%E8%97%8F%E5%A4%B9/01.%E7%BD%91%E7%AB%99.html",relativePath:"05.收藏夹/01.网站.md",key:"v-1cd3a514",path:"/pages/5a96b7/",headers:[{level:2,title:"推荐",slug:"推荐"},{level:2,title:"成长规范",slug:"成长规范"},{level:2,title:"chatgpt",slug:"chatgpt"},{level:2,title:"github 主页",slug:"github-主页"},{level:2,title:"Android",slug:"android"},{level:2,title:"文档",slug:"文档"},{level:2,title:"社区",slug:"社区"},{level:3,title:"社区互动",slug:"社区互动"},{level:2,title:"技巧",slug:"技巧"},{level:2,title:"博客",slug:"博客"},{level:2,title:"电子书",slug:"电子书"},{level:2,title:"优秀文章",slug:"优秀文章"},{level:2,title:"视频",slug:"视频"},{level:2,title:"Github",slug:"github"},{level:2,title:"评论系统",slug:"评论系统"},{level:2,title:"前端小工具",slug:"前端小工具"},{level:2,title:"代码编辑",slug:"代码编辑"},{level:2,title:"Emoji 表情",slug:"emoji-表情"},{level:2,title:"图片工具",slug:"图片工具"},{level:2,title:"SVG",slug:"svg"},{level:2,title:"音视频工具",slug:"音视频工具"},{level:2,title:"思维导图",slug:"思维导图"},{level:2,title:"CSS",slug:"css"},{level:2,title:"CDN 加速",slug:"cdn-加速"},{level:2,title:"网站托管",slug:"网站托管"},{level:2,title:"正则",slug:"正则"},{level:2,title:"其他",slug:"其他"},{level:2,title:"设计",slug:"设计"},{level:2,title:"图库",slug:"图库"},{level:2,title:"3D",slug:"_3d"},{level:2,title:"交互",slug:"交互"},{level:2,title:"有趣",slug:"有趣"},{level:2,title:"生成器",slug:"生成器"},{level:2,title:"元宇宙",slug:"元宇宙"},{level:2,title:"教程",slug:"教程"},{level:2,title:"产品",slug:"产品"},{level:2,title:"实用",slug:"实用"},{level:2,title:"Talk",slug:"talk"},{level:2,title:"算法",slug:"算法"},{level:2,title:"nginx",slug:"nginx"},{level:2,title:"生活",slug:"生活"},{level:2,title:"营销",slug:"营销"}],excerpt:'

# 推荐

\n\n',lastUpdated:"2023/07/04, 19:58:05",lastUpdatedTimestamp:1688471885e3},{title:"归档",frontmatter:{archivesPage:!0,title:"归档",permalink:"/archives/",article:!1},regularPath:"/@pages/archivesPage.html",relativePath:"@pages/archivesPage.md",key:"v-f470e9b6",path:"/archives/",lastUpdated:"2023/05/20, 20:55:13",lastUpdatedTimestamp:1684587313e3},{title:"分类",frontmatter:{categoriesPage:!0,title:"分类",permalink:"/categories/",article:!1},regularPath:"/@pages/categoriesPage.html",relativePath:"@pages/categoriesPage.md",key:"v-5f92b685",path:"/categories/",lastUpdated:"2023/05/20, 20:55:13",lastUpdatedTimestamp:1684587313e3},{title:"标签",frontmatter:{tagsPage:!0,title:"标签",permalink:"/tags/",article:!1},regularPath:"/@pages/tagsPage.html",relativePath:"@pages/tagsPage.md",key:"v-6b12deb6",path:"/tags/",lastUpdated:"2023/05/20, 20:55:13",lastUpdatedTimestamp:1684587313e3},{title:"Home",frontmatter:{home:!0,heroText:"Jacky's blog",heroImage:"logo.png",tagline:"扯淡集",features:[{title:"前端",link:"/fe/",imgUrl:"https://cdn.jsdelivr.net/gh/jacky1234/picArchieve@master/uPic/20230522_164539_kGo3QV.png",details:"前端扯淡模块"},{title:"更多内容",link:"/other/",imgUrl:"https://cdn.jsdelivr.net/gh/jacky1234/picArchieve@master/uPic/20230521_202721_0YoPV0.png",details:"不局限于技术"}],footer:"Made by Jacky"},regularPath:"/",relativePath:"index.md",key:"v-5cfab93e",path:"/",lastUpdated:"2023/06/15, 21:49:15",lastUpdatedTimestamp:1686836955e3},{title:"switch",frontmatter:{title:"switch",date:"2023-06-29T23:54:52.000Z",permalink:"/pages/1bc90b/",categories:["其他","更多"],tags:[null],author:{name:"Jacky",email:"jackdoson2011@gmail.com",link:"https://github.com/jacky1234"}},regularPath:"/mine/1000.switch.html",relativePath:"mine/1000.switch.md",key:"v-11478c3a",path:"/pages/1bc90b/",headers:[{level:2,title:"资源",slug:"资源"},{level:3,title:"游戏下载",slug:"游戏下载"},{level:4,title:"安装",slug:"安装"},{level:2,title:"安装游戏",slug:"安装游戏"},{level:2,title:"破解",slug:"破解"}],lastUpdated:"2023/06/30, 18:08:57",lastUpdatedTimestamp:1688119737e3},{title:"小伟和小娟",frontmatter:{title:"小伟和小娟",date:"2023-07-31T00:08:23.000Z",permalink:"/pages/6c1d02/",categories:["mine","小说"],tags:[null],author:{name:"Jacky",email:"jackdoson2011@gmail.com",link:"https://github.com/jacky1234"}},regularPath:"/mine/900.%E5%B0%8F%E4%BC%9F%E5%B0%8F%E5%A8%9F/100.%E5%B0%8F%E4%BC%9F%E5%92%8C%E5%B0%8F%E5%A8%9F.html",relativePath:"mine/900.小伟小娟/100.小伟和小娟.md",key:"v-352e8304",path:"/pages/6c1d02/",headers:[{level:2,title:"大纲",slug:"大纲"},{level:3,title:"第一章:初遇",slug:"第一章-初遇"},{level:3,title:"第二章:心动时刻",slug:"第二章-心动时刻"},{level:3,title:"第三章:情窦初开",slug:"第三章-情窦初开"},{level:3,title:"第四章:秘密的表白",slug:"第四章-秘密的表白"},{level:3,title:"第五章:青涩初恋",slug:"第五章-青涩初恋"},{level:3,title:"第六章:挑战与成长",slug:"第六章-挑战与成长"},{level:3,title:"第七章:距离的考验",slug:"第七章-距离的考验"},{level:3,title:"第八章:短暂的分别",slug:"第八章-短暂的分别"},{level:3,title:"第九章:新的朋友",slug:"第九章-新的朋友"},{level:3,title:"第十章:意外的邂逅",slug:"第十章-意外的邂逅"},{level:3,title:"第十一章:思念的夜晚",slug:"第十一章-思念的夜晚"},{level:3,title:"第十二章:苏雪的心结",slug:"第十二章-苏雪的心结"},{level:3,title:"第十三章:选择与放手",slug:"第十三章-选择与放手"},{level:3,title:"第十四章:重逢的喜悦",slug:"第十四章-重逢的喜悦"},{level:3,title:"第十五章:爱的坚持",slug:"第十五章-爱的坚持"},{level:3,title:"第十六章:牙医的助力",slug:"第十六章-牙医的助力"},{level:3,title:"第十七章:幸福的时光",slug:"第十七章-幸福的时光"},{level:3,title:"第十八章:职业与家庭的平衡",slug:"第十八章-职业与家庭的平衡"},{level:3,title:"第十九章:挑战与困惑",slug:"第十九章-挑战与困惑"},{level:3,title:"第二十章:成长的友情",slug:"第二十章-成长的友情"},{level:3,title:"第二十一章:家庭的温暖",slug:"第二十一章-家庭的温暖"},{level:3,title:"第二十二章:职业与家庭的平衡",slug:"第二十二章-职业与家庭的平衡"},{level:3,title:"第二十三章:挑战与困惑",slug:"第二十三章-挑战与困惑"},{level:3,title:"第二十四章:成长的友情",slug:"第二十四章-成长的友情"},{level:3,title:"第二十五章:家族的团聚",slug:"第二十五章-家族的团聚"},{level:3,title:"第二十六章:新的起点",slug:"第二十六章-新的起点"},{level:3,title:"第二十七章:梦想成真",slug:"第二十七章-梦想成真"},{level:3,title:"第二十八章:爱的传承",slug:"第二十八章-爱的传承"},{level:3,title:"第二十九章:美好的未来",slug:"第二十九章-美好的未来"},{level:3,title:"第三十章:永恒的爱",slug:"第三十章-永恒的爱"}],lastUpdated:"2023/07/31, 00:34:38",lastUpdatedTimestamp:1690734878e3},{title:"gradle鉴权脚本",frontmatter:{title:"gradle鉴权脚本",date:"2023-07-21T14:28:41.000Z",permalink:"/pages/aaf954/",categories:["mine"],tags:[null],author:{name:"Jacky",email:"jackdoson2011@gmail.com",link:"https://github.com/jacky1234"}},regularPath:"/mine/999.gradle%E9%89%B4%E6%9D%83%E8%84%9A%E6%9C%AC.html",relativePath:"mine/999.gradle鉴权脚本.md",key:"v-823cdc00",path:"/pages/aaf954/",lastUpdated:"2023/07/21, 19:24:08",lastUpdatedTimestamp:1689938648e3},{title:"概述",frontmatter:{title:"概述",date:"2023-05-24T11:35:59.000Z",permalink:"/pages/dd1044/",categories:["《android》"],tags:[null],author:{name:"Jacky",email:"jackdoson2011@gmail.com",link:"https://github.com/jacky1234"}},regularPath:"/%E3%80%8Aandroid%E3%80%8B/00.Android%E6%A6%82%E8%BF%B0.html",relativePath:"《android》/00.Android概述.md",key:"v-31f4e97c",path:"/pages/dd1044/",headers:[{level:2,title:"相关链接",slug:"相关链接"},{level:3,title:"工具",slug:"工具"}],lastUpdated:"2023/07/14, 19:05:50",lastUpdatedTimestamp:168933275e4},{title:"android图形系统",frontmatter:{title:"android图形系统",date:"2023-05-28T16:18:10.000Z",permalink:"/pages/420ab6/",categories:["《android》"],tags:["android","graphics"],author:{name:"Jacky",email:"jackdoson2011@gmail.com",link:"https://github.com/jacky1234"}},regularPath:"/%E3%80%8Aandroid%E3%80%8B/01.android%E5%9B%BE%E5%BD%A2%E7%B3%BB%E7%BB%9F.html",relativePath:"《android》/01.android图形系统.md",key:"v-3694ce14",path:"/pages/420ab6/",headers:[{level:2,title:"Android 图形组件",slug:"android-图形组件"},{level:3,title:"Surface and SurfaceHolder",slug:"surface-and-surfaceholder"},{level:2,title:"链接",slug:"链接"}],lastUpdated:"2023/05/29, 22:19:46",lastUpdatedTimestamp:1685369986e3},{title:"生产环境Message分发处理设计",frontmatter:{title:"生产环境Message分发处理设计",date:"2023-08-06T16:37:53.000Z",permalink:"/pages/21df4f/",categories:["《android》","其他"],tags:[null],author:{name:"Jacky",email:"jackdoson2011@gmail.com",link:"https://github.com/jacky1234"}},regularPath:"/%E3%80%8Aandroid%E3%80%8B/1000.%E5%85%B6%E4%BB%96/01.%E7%94%9F%E4%BA%A7%E7%8E%AF%E5%A2%83Message%E5%88%86%E5%8F%91%E5%A4%84%E7%90%86%E8%AE%BE%E8%AE%A1.html",relativePath:"《android》/1000.其他/01.生产环境Message分发处理设计.md",key:"v-2aba85c9",path:"/pages/21df4f/",lastUpdated:"2023/08/09, 21:17:44",lastUpdatedTimestamp:1691587064e3},{title:"卡顿分析工具",frontmatter:{title:"卡顿分析工具",date:"2023-06-19T17:05:26.000Z",permalink:"/pages/eae245/",categories:["《android》"],tags:["Perfetto","Systrace","apm"],author:{name:"Jacky",email:"jackdoson2011@gmail.com",link:"https://github.com/jacky1234"}},regularPath:"/%E3%80%8Aandroid%E3%80%8B/1000.%E5%85%B6%E4%BB%96/50.%E5%8D%A1%E9%A1%BF%E5%88%86%E6%9E%90%E5%B7%A5%E5%85%B7.html",relativePath:"《android》/1000.其他/50.卡顿分析工具.md",key:"v-b57d7aaa",path:"/pages/eae245/",headers:[{level:2,title:"Perfetto",slug:"perfetto"},{level:2,title:"Systrace",slug:"systrace"}],lastUpdated:"2023/08/18, 09:50:12",lastUpdatedTimestamp:1692323412e3},{title:"perfetto",frontmatter:{title:"perfetto",date:"2023-08-01T20:27:39.000Z",permalink:"/pages/29a4de/",categories:["《android》"],tags:["perfetto","sql"],author:{name:"Jacky",email:"jackdoson2011@gmail.com",link:"https://github.com/jacky1234"}},regularPath:"/%E3%80%8Aandroid%E3%80%8B/1000.%E5%85%B6%E4%BB%96/51.perfetto.html",relativePath:"《android》/1000.其他/51.perfetto.md",key:"v-555c4ccc",path:"/pages/29a4de/",headers:[{level:2,title:"custom-events",slug:"custom-events"},{level:2,title:"trace config",slug:"trace-config"},{level:4,title:"gfx",slug:"gfx"},{level:2,title:"analysis",slug:"analysis"},{level:3,title:"sql",slug:"sql"},{level:4,title:"示例",slug:"示例"},{level:2,title:"问一问",slug:"问一问"}],lastUpdated:"2023/08/18, 09:50:12",lastUpdatedTimestamp:1692323412e3},{title:"提升UI加载速度的几点思考",frontmatter:{title:"提升UI加载速度的几点思考",date:"2023-08-15T11:50:08.000Z",permalink:"/pages/cd0789/",categories:["《android》"],tags:[null],author:{name:"Jacky",email:"jackdoson2011@gmail.com",link:"https://github.com/jacky1234"}},regularPath:"/%E3%80%8Aandroid%E3%80%8B/1000.%E5%85%B6%E4%BB%96/52.%E6%8F%90%E5%8D%87UI%E5%8A%A0%E8%BD%BD%E9%80%9F%E5%BA%A6%E7%9A%84%E5%87%A0%E7%82%B9%E6%80%9D%E8%80%83.html",relativePath:"《android》/1000.其他/52.提升UI加载速度的几点思考.md",key:"v-17f021f1",path:"/pages/cd0789/",headers:[{level:2,title:"背景",slug:"背景"},{level:2,title:"AsyncLayoutInflater",slug:"asynclayoutinflater"},{level:2,title:"链接",slug:"链接"}],lastUpdated:"2023/08/18, 09:50:12",lastUpdatedTimestamp:1692323412e3},{title:"Android零耗时首帧体验",frontmatter:{title:"Android零耗时首帧体验",date:"2023-08-21T21:55:21.000Z",permalink:"/pages/5d8ba8/",categories:["《android》"],tags:[null],author:{name:"Jacky",email:"jackdoson2011@gmail.com",link:"https://github.com/jacky1234"}},regularPath:"/%E3%80%8Aandroid%E3%80%8B/1000.%E5%85%B6%E4%BB%96/53.Android%E9%9B%B6%E8%80%97%E6%97%B6%E9%A6%96%E5%B8%A7%E4%BD%93%E9%AA%8C%E6%95%B4%E7%90%86.html",relativePath:"《android》/1000.其他/53.Android零耗时首帧体验整理.md",key:"v-29c2a9a6",path:"/pages/5d8ba8/",headers:[{level:2,title:"预热内容",slug:"预热内容"},{level:3,title:"HTML 的预渲染原理",slug:"html-的预渲染原理"},{level:2,title:"播放质量指标",slug:"播放质量指标"},{level:2,title:"“零耗时”首帧优化实践",slug:"零耗时-首帧优化实践"},{level:3,title:"业务耗时优化:预渲染",slug:"业务耗时优化-预渲染"},{level:3,title:"网络耗时优化——节点优选",slug:"网络耗时优化-节点优选"},{level:3,title:"网络耗时优化——解码耗时",slug:"网络耗时优化-解码耗时"},{level:4,title:"解码初始化耗时",slug:"解码初始化耗时"},{level:4,title:"解码器复用",slug:"解码器复用"},{level:5,title:"适合短视频场景的解码器复用方案",slug:"适合短视频场景的解码器复用方案"},{level:5,title:"跨播放器解码器复用方案",slug:"跨播放器解码器复用方案"},{level:4,title:"机型能力大数据择优",slug:"机型能力大数据择优"},{level:2,title:"链接",slug:"链接"}],lastUpdated:"2023/08/22, 22:10:19",lastUpdatedTimestamp:1692713419e3},{title:"jsbridge",frontmatter:{title:"jsbridge",date:"2023-08-25T16:21:13.000Z",permalink:"/pages/d2d3e5/",categories:["《android》","其他"],tags:["jsbridge","混合开发"],author:{name:"Jacky",email:"jackdoson2011@gmail.com",link:"https://github.com/jacky1234"}},regularPath:"/%E3%80%8Aandroid%E3%80%8B/1000.%E5%85%B6%E4%BB%96/54.jsbridge.html",relativePath:"《android》/1000.其他/54.jsbridge.md",key:"v-4450a94c",path:"/pages/d2d3e5/",headers:[{level:2,title:"前置内容",slug:"前置内容"},{level:3,title:"jsbridge 的起源",slug:"jsbridge-的起源"},{level:3,title:"内联框架 iFrame",slug:"内联框架-iframe"},{level:3,title:"js 中的 eval 函数",slug:"js-中的-eval-函数"},{level:3,title:"什么是双向通道",slug:"什么是双向通道"},{level:2,title:"实现原理",slug:"实现原理"},{level:3,title:"js 通信原理",slug:"js-通信原理"},{level:4,title:"JavaScript 调用 Native",slug:"javascript-调用-native"},{level:4,title:"Native 调用 JavaScript",slug:"native-调用-javascript"},{level:3,title:"JSBridge 接口实现",slug:"jsbridge-接口实现"},{level:2,title:"TODO",slug:"todo"},{level:2,title:"参考",slug:"参考"}],lastUpdated:"2023/08/29, 00:30:54",lastUpdatedTimestamp:1693240254e3},{title:"Android稳定性治理",frontmatter:{title:"Android稳定性治理",date:"2023-08-18T08:05:41.000Z",permalink:"/pages/b6bad0/",categories:["《android》"],tags:[null],author:{name:"Jacky",email:"jackdoson2011@gmail.com",link:"https://github.com/jacky1234"}},regularPath:"/%E3%80%8Aandroid%E3%80%8B/5.%E6%80%A7%E8%83%BD/1.Android%E7%A8%B3%E5%AE%9A%E6%80%A7%E6%B2%BB%E7%90%86.html",relativePath:"《android》/5.性能/1.Android稳定性治理.md",key:"v-4933d72d",path:"/pages/b6bad0/",headers:[{level:2,title:"参考",slug:"参考"}],lastUpdated:"2023/08/31, 22:25:36",lastUpdatedTimestamp:1693491936e3},{title:"apm相关概念",frontmatter:{title:"apm相关概念",date:"2023-08-31T22:11:15.000Z",permalink:"/pages/9b0a57/",categories:["《android》","性能"],tags:["apm","android"],author:{name:"Jacky",email:"jackdoson2011@gmail.com",link:"https://github.com/jacky1234"}},regularPath:"/%E3%80%8Aandroid%E3%80%8B/5.%E6%80%A7%E8%83%BD/100.apm%E7%9B%B8%E5%85%B3%E6%A6%82%E5%BF%B5.html",relativePath:"《android》/5.性能/100.apm相关概念.md",key:"v-ea3f7700",path:"/pages/9b0a57/",headers:[{level:2,title:"Runtime getMemory 与 ActivityManager.MemoryInfo",slug:"runtime-getmemory-与-activitymanager-memoryinfo"}],lastUpdated:"2023/08/31, 22:25:36",lastUpdatedTimestamp:1693491936e3},{title:"Android低端机性能优化",frontmatter:{title:"Android低端机性能优化",date:"2023-08-28T14:50:33.000Z",permalink:"/pages/a0d7dc/",categories:["《android》"],tags:[null],author:{name:"Jacky",email:"jackdoson2011@gmail.com",link:"https://github.com/jacky1234"}},regularPath:"/%E3%80%8Aandroid%E3%80%8B/5.%E6%80%A7%E8%83%BD/12.Android%E4%BD%8E%E7%AB%AF%E6%9C%BA%E6%80%A7%E8%83%BD%E4%BC%98%E5%8C%96.html",relativePath:"《android》/5.性能/12.Android低端机性能优化.md",key:"v-42978a06",path:"/pages/a0d7dc/",headers:[{level:2,title:"参考",slug:"参考"}],lastUpdated:"2023/08/31, 22:25:36",lastUpdatedTimestamp:1693491936e3},{title:"retrofit动态代理设计",frontmatter:{title:"retrofit动态代理设计",date:"2023-09-05T15:20:59.000Z",permalink:"/pages/c8fb65/",categories:["《android》","三方库解析"],tags:[null],author:{name:"Jacky",email:"jackdoson2011@gmail.com",link:"https://github.com/jacky1234"}},regularPath:"/%E3%80%8Aandroid%E3%80%8B/6.%E4%B8%89%E6%96%B9%E5%BA%93%E8%A7%A3%E6%9E%90/01.retrofit%E5%8A%A8%E6%80%81%E4%BB%A3%E7%90%86%E8%AE%BE%E8%AE%A1.html",relativePath:"《android》/6.三方库解析/01.retrofit动态代理设计.md",key:"v-31aad69b",path:"/pages/c8fb65/",lastUpdated:"2023/09/05, 17:44:27",lastUpdatedTimestamp:1693907067e3},{title:"tutorial",frontmatter:{title:"tutorial",date:"2023-06-25T21:58:10.000Z",permalink:"/pages/12d86f/",categories:["《iOS》"],tags:["iOS"],author:{name:"Jacky",email:"jackdoson2011@gmail.com",link:"https://github.com/jacky1234"}},regularPath:"/%E3%80%8AiOS%E3%80%8B/01.tutorial.html",relativePath:"《iOS》/01.tutorial.md",key:"v-57119e11",path:"/pages/12d86f/",headers:[{level:2,title:"链接",slug:"链接"}],lastUpdated:"2023/06/25, 22:33:08",lastUpdatedTimestamp:1687703588e3},{title:"python学习",frontmatter:{title:"python学习",date:"2023-06-01T17:10:43.000Z",permalink:"/pages/4595e1/",categories:["《python》"],tags:["python"],author:{name:"Jacky",email:"jackdoson2011@gmail.com",link:"https://github.com/jacky1234"}},regularPath:"/%E3%80%8Apython%E3%80%8B/00.python%E5%AD%A6%E4%B9%A0.html",relativePath:"《python》/00.python学习.md",key:"v-7b614492",path:"/pages/4595e1/",headers:[{level:2,title:"setuptools 打包",slug:"setuptools-打包"},{level:3,title:"打包",slug:"打包"},{level:3,title:"安装",slug:"安装"},{level:2,title:"概念",slug:"概念"},{level:3,title:"__init__.py文件",slug:"init-py文件"},{level:2,title:"链接",slug:"链接"}],lastUpdated:"2023/06/11, 23:27:06",lastUpdatedTimestamp:1686497226e3},{title:"字符串",frontmatter:{title:"字符串",date:"2023-06-01T16:58:18.000Z",permalink:"/pages/02f88a/",categories:["《python》","语法"],tags:["python"],author:{name:"Jacky",email:"jackdoson2011@gmail.com",link:"https://github.com/jacky1234"}},regularPath:"/%E3%80%8Apython%E3%80%8B/01.%E8%AF%AD%E6%B3%95/10.%E5%AD%97%E7%AC%A6%E4%B8%B2.html",relativePath:"《python》/01.语法/10.字符串.md",key:"v-e91b9212",path:"/pages/02f88a/",headers:[{level:2,title:"格式化",slug:"格式化"},{level:3,title:"f-strings",slug:"f-strings"},{level:3,title:"str.format()",slug:"str-format"},{level:3,title:"Old string formatting",slug:"old-string-formatting"}],lastUpdated:"2023/07/01, 08:43:39",lastUpdatedTimestamp:1688172219e3},{title:"python snippet code",frontmatter:{title:"python snippet code",date:"2023-08-09T17:55:20.000Z",permalink:"/pages/140cb3/",categories:["《python》","其他"],tags:["python"],author:{name:"Jacky",email:"jackdoson2011@gmail.com",link:"https://github.com/jacky1234"}},regularPath:"/%E3%80%8Apython%E3%80%8B/10.%E5%85%B6%E4%BB%96/01.python%20snippet%20code.html",relativePath:"《python》/10.其他/01.python snippet code.md",key:"v-491acd04",path:"/pages/140cb3/",headers:[{level:2,title:"断言",slug:"断言"}],lastUpdated:"2023/08/10, 08:23:37",lastUpdatedTimestamp:1691627017e3},{title:"python3命令",frontmatter:{title:"python3命令",date:"2023-09-17T21:45:36.000Z",permalink:"/pages/dc1698/",categories:["《python》","其他"],tags:["python3"],author:{name:"Jacky",email:"jackdoson2011@gmail.com",link:"https://github.com/jacky1234"}},regularPath:"/%E3%80%8Apython%E3%80%8B/10.%E5%85%B6%E4%BB%96/02.python%E7%89%88%E6%9C%AC%E7%AE%A1%E7%90%86.html",relativePath:"《python》/10.其他/02.python版本管理.md",key:"v-54256f98",path:"/pages/dc1698/",headers:[{level:2,title:"通过 homebrew 安装 pyenv",slug:"通过-homebrew-安装-pyenv"},{level:2,title:"修改 zsh profile",slug:"修改-zsh-profile"},{level:2,title:"常用命令",slug:"常用命令"}],lastUpdated:"2023/09/17, 22:27:30",lastUpdatedTimestamp:169496085e4},{title:"beautysoup",frontmatter:{title:"beautysoup",date:"2023-06-13T13:03:04.000Z",permalink:"/pages/3aeda3/",categories:["《python》"],tags:[null],author:{name:"Jacky",email:"jackdoson2011@gmail.com",link:"https://github.com/jacky1234"}},regularPath:"/%E3%80%8Apython%E3%80%8B/100.BeautifulSoup%E7%9A%84%E4%BD%BF%E7%94%A8.html",relativePath:"《python》/100.BeautifulSoup的使用.md",key:"v-9e089f2c",path:"/pages/3aeda3/",headers:[{level:2,title:"获取子元素",slug:"获取子元素"},{level:3,title:"href 正则",slug:"href-正则"},{level:2,title:"获取父元素",slug:"获取父元素"},{level:2,title:"获取兄弟节点",slug:"获取兄弟节点"}],lastUpdated:"2023/06/13, 21:40:39",lastUpdatedTimestamp:1686663639e3},{title:"Hooks",frontmatter:{title:"Hooks",date:"2023-05-24T20:46:06.000Z",permalink:"/pages/f85f1b/",categories:["《react》"],tags:["react","hooks"],author:{name:"Jacky",email:"jackdoson2011@gmail.com",link:"https://github.com/jacky1234"}},regularPath:"/%E3%80%8Areact%E3%80%8B/02.hooks.html",relativePath:"《react》/02.hooks.md",key:"v-0d3d092a",path:"/pages/f85f1b/",headers:[{level:2,title:"useContext",slug:"usecontext"},{level:2,title:"useImperativeHandle",slug:"useimperativehandle"}],lastUpdated:"2023/06/27, 22:05:00",lastUpdatedTimestamp:16878747e5},{title:"components",frontmatter:{title:"components",date:"2023-06-08T22:15:15.000Z",permalink:"/pages/82e5d7/",categories:["《react》"],tags:[null],author:{name:"Jacky",email:"jackdoson2011@gmail.com",link:"https://github.com/jacky1234"}},regularPath:"/%E3%80%8Areact%E3%80%8B/03.components.html",relativePath:"《react》/03.components.md",key:"v-6f103bde",path:"/pages/82e5d7/",lastUpdated:"2023/07/19, 21:58:25",lastUpdatedTimestamp:1689775105e3},{title:"apis",frontmatter:{title:"apis",date:"2023-06-08T22:15:27.000Z",permalink:"/pages/0c11ea/",categories:["《react》"],tags:[null],author:{name:"Jacky",email:"jackdoson2011@gmail.com",link:"https://github.com/jacky1234"}},regularPath:"/%E3%80%8Areact%E3%80%8B/04.apis.html",relativePath:"《react》/04.apis.md",key:"v-1f42625e",path:"/pages/0c11ea/",headers:[{level:2,title:"使用 Legacy React APIS 定义组件",slug:"使用-legacy-react-apis-定义组件"}],lastUpdated:"2023/07/20, 19:12:58",lastUpdatedTimestamp:1689851578e3},{title:"记录-在已有的项目基础上扩展回调",frontmatter:{title:"记录-在已有的项目基础上扩展回调",date:"2023-07-19T19:54:53.000Z",permalink:"/pages/4db36a/",categories:["《react》"],tags:[null],author:{name:"Jacky",email:"jackdoson2011@gmail.com",link:"https://github.com/jacky1234"}},regularPath:"/%E3%80%8Areact%E3%80%8B/50.%E8%AE%B0%E4%B8%80%E6%AC%A1React%E5%9B%9E%E8%B0%83%E5%87%BD%E6%95%B0.html",relativePath:"《react》/50.记一次React回调函数.md",key:"v-3ae19d8b",path:"/pages/4db36a/",headers:[{level:2,title:"背景",slug:"背景"},{level:2,title:"剖析",slug:"剖析"},{level:3,title:"设计 show 方法",slug:"设计-show-方法"},{level:3,title:"调用",slug:"调用"},{level:2,title:"总结",slug:"总结"}],lastUpdated:"2023/07/20, 19:12:58",lastUpdatedTimestamp:1689851578e3},{title:"服务器tutorial",frontmatter:{title:"服务器tutorial",date:"2023-06-25T23:26:05.000Z",categories:["《server》"],tags:["server"],author:{name:"Jacky",email:"jackdoson2011@gmail.com",link:"https://github.com/jacky1234"},permalink:"/pages/0d7cc1/"},regularPath:"/%E3%80%8Aserver%E3%80%8B/00.tutorial.html",relativePath:"《server》/00.tutorial.md",key:"v-0792688a",path:"/pages/0d7cc1/",lastUpdated:"2023/09/08, 17:31:42",lastUpdatedTimestamp:1694165502e3},{title:"spring",frontmatter:{title:"spring",date:"2023-09-08T00:42:12.000Z",permalink:"/pages/6ab0a7/",categories:["《server》","spring"],tags:[null],author:{name:"Jacky",email:"jackdoson2011@gmail.com",link:"https://github.com/jacky1234"}},regularPath:"/%E3%80%8Aserver%E3%80%8B/01.spring/01.spring.html",relativePath:"《server》/01.spring/01.spring.md",key:"v-267e6c49",path:"/pages/6ab0a7/",headers:[{level:2,title:"注解",slug:"注解"},{level:3,title:"Spring MVC 和 REST 注解",slug:"spring-mvc-和-rest-注解"},{level:4,title:"@RestController",slug:"restcontroller"},{level:2,title:"相关概念",slug:"相关概念"},{level:3,title:"Actuator",slug:"actuator"},{level:2,title:"其他",slug:"其他"},{level:3,title:"微服务",slug:"微服务"},{level:3,title:"autowired 原理",slug:"autowired-原理"},{level:2,title:"链接",slug:"链接"}],lastUpdated:"2023/09/08, 17:52:43",lastUpdatedTimestamp:1694166763e3},{title:"了解spring",frontmatter:{title:"了解spring",date:"2023-09-13T07:47:07.000Z",permalink:"/pages/39870b/",categories:["《server》","spring"],tags:[null],author:{name:"Jacky",email:"jackdoson2011@gmail.com",link:"https://github.com/jacky1234"}},regularPath:"/%E3%80%8Aserver%E3%80%8B/01.spring/02.%E4%BA%86%E8%A7%A3spring.html",relativePath:"《server》/01.spring/02.了解spring.md",key:"v-99fa62a6",path:"/pages/39870b/",headers:[{level:2,title:"ConfigurableApplicationContext接口",slug:"configurableapplicationcontext接口"},{level:2,title:"BeanDefinition",slug:"beandefinition"},{level:2,title:"AttributeAccessor",slug:"attributeaccessor"},{level:2,title:"lazy 注解",slug:"lazy-注解"}],lastUpdated:"2023/09/13, 12:48:52",lastUpdatedTimestamp:1694580532e3},{title:"Database",frontmatter:{title:"Database",date:"2023-09-02T18:10:13.000Z",permalink:"/pages/233ea5/",categories:["《server》"],tags:[null],author:{name:"Jacky",email:"jackdoson2011@gmail.com",link:"https://github.com/jacky1234"}},regularPath:"/%E3%80%8Aserver%E3%80%8B/02.%E6%95%B0%E6%8D%AE%E5%BA%93/01.database.html",relativePath:"《server》/02.数据库/01.database.md",key:"v-15bcd010",path:"/pages/233ea5/",headers:[{level:2,title:"数据库",slug:"数据库"},{level:3,title:"Redius",slug:"redius"},{level:3,title:"MySQL",slug:"mysql"},{level:2,title:"其他",slug:"其他"}],lastUpdated:"2023/09/08, 17:52:43",lastUpdatedTimestamp:1694166763e3},{title:"mysql",frontmatter:{title:"mysql",date:"2023-09-02T18:13:40.000Z",permalink:"/pages/e9db87/",categories:["《server》","数据库"],tags:[null],author:{name:"Jacky",email:"jackdoson2011@gmail.com",link:"https://github.com/jacky1234"}},regularPath:"/%E3%80%8Aserver%E3%80%8B/02.%E6%95%B0%E6%8D%AE%E5%BA%93/02.mysql%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0.html",relativePath:"《server》/02.数据库/02.mysql学习笔记.md",key:"v-518d82c3",path:"/pages/e9db87/",headers:[{level:2,title:"环境及使用",slug:"环境及使用"},{level:2,title:"命令",slug:"命令"},{level:3,title:"通用",slug:"通用"},{level:3,title:"GURD",slug:"gurd"},{level:2,title:"建表约束",slug:"建表约束"},{level:3,title:"主键约束",slug:"主键约束"},{level:3,title:"唯一主键",slug:"唯一主键"},{level:3,title:"非空约束",slug:"非空约束"},{level:3,title:"默认约束",slug:"默认约束"},{level:3,title:"外键约束",slug:"外键约束"},{level:2,title:"数据库的三大设计范式",slug:"数据库的三大设计范式"},{level:3,title:"1NF",slug:"_1nf"},{level:3,title:"2NF",slug:"_2nf"},{level:3,title:"3NF",slug:"_3nf"},{level:2,title:"查询练习",slug:"查询练习"},{level:3,title:"准备数据",slug:"准备数据"},{level:3,title:"1 到 10",slug:"_1-到-10"},{level:3,title:"分组计算平均成绩",slug:"分组计算平均成绩"},{level:3,title:"分组条件与模糊查询",slug:"分组条件与模糊查询"},{level:3,title:"多表查询 - 1",slug:"多表查询-1"},{level:3,title:"多表查询 - 2",slug:"多表查询-2"},{level:3,title:"三表关联查询",slug:"三表关联查询"},{level:3,title:"子查询加分组求平均分",slug:"子查询加分组求平均分"},{level:3,title:"子查询 - 1",slug:"子查询-1"},{level:3,title:"子查询 - 2",slug:"子查询-2"},{level:3,title:"YEAR 函数与带 IN 关键字查询",slug:"year-函数与带-in-关键字查询"},{level:3,title:"多层嵌套子查询",slug:"多层嵌套子查询"},{level:3,title:"多表查询",slug:"多表查询"},{level:3,title:"子查询 - 3",slug:"子查询-3"},{level:3,title:"UNION 和 NOTIN 的使用",slug:"union-和-notin-的使用"},{level:3,title:"ANY 表示至少一个 - DESC ( 降序 )",slug:"any-表示至少一个-desc-降序"},{level:3,title:"表示所有的 ALL",slug:"表示所有的-all"},{level:3,title:"复制表的数据作为条件查询",slug:"复制表的数据作为条件查询"},{level:3,title:"子查询 - 4",slug:"子查询-4"},{level:3,title:"条件加组筛选",slug:"条件加组筛选"},{level:3,title:"NOTLIKE 模糊查询取反",slug:"notlike-模糊查询取反"},{level:3,title:"YEAR 与 NOW 函数",slug:"year-与-now-函数"},{level:3,title:"MAX 与 MIN 函数",slug:"max-与-min-函数"},{level:3,title:"多段排序",slug:"多段排序"},{level:3,title:"子查询 - 5",slug:"子查询-5"},{level:3,title:"MAX 函数与子查询",slug:"max-函数与子查询"},{level:3,title:"子查询 - 6",slug:"子查询-6"},{level:3,title:"子查询 - 7",slug:"子查询-7"},{level:3,title:"子查询 - 8",slug:"子查询-8"},{level:3,title:"按等级查询",slug:"按等级查询"},{level:3,title:"连接查询",slug:"连接查询"},{level:4,title:"内连接",slug:"内连接"},{level:4,title:"左外连接",slug:"左外连接"},{level:4,title:"右外链接",slug:"右外链接"},{level:4,title:"全外链接",slug:"全外链接"},{level:2,title:"事务",slug:"事务"},{level:3,title:"如何控制事务 - COMMIT / ROLLBACK",slug:"如何控制事务-commit-rollback"},{level:3,title:"手动开启事务 - BEGIN / START TRANSACTION",slug:"手动开启事务-begin-start-transaction"},{level:3,title:"事务的 ACID 特征与使用",slug:"事务的-acid-特征与使用"},{level:3,title:"事务的隔离性",slug:"事务的隔离性"},{level:4,title:"脏读",slug:"脏读"},{level:4,title:"读取已提交",slug:"读取已提交"},{level:4,title:"幻读",slug:"幻读"},{level:4,title:"串行化",slug:"串行化"},{level:2,title:"其他",slug:"其他"},{level:3,title:"导出 sql 数据",slug:"导出-sql-数据"},{level:3,title:"执行 sql shell",slug:"执行-sql-shell"},{level:3,title:"用户及权限",slug:"用户及权限"},{level:3,title:"sql shell",slug:"sql-shell"},{level:2,title:"链接",slug:"链接"}],lastUpdated:"2023/09/11, 00:43:03",lastUpdatedTimestamp:1694364183e3},{title:"sql",frontmatter:{title:"sql",date:"2023-07-23T17:21:13.000Z",permalink:"/pages/e4a24e/",categories:["其他","更多"],tags:["sql"],author:{name:"Jacky",email:"jackdoson2011@gmail.com",link:"https://github.com/jacky1234"}},regularPath:"/%E3%80%8Aserver%E3%80%8B/02.%E6%95%B0%E6%8D%AE%E5%BA%93/05.sql.html",relativePath:"《server》/02.数据库/05.sql.md",key:"v-40ca211c",path:"/pages/e4a24e/",headers:[{level:2,title:"解释说明 sql 语句的作用",slug:"解释说明-sql-语句的作用"},{level:3,title:"perfetto 查询",slug:"perfetto-查询"},{level:4,title:"查询 slice 名字中包含固定字符串",slug:"查询-slice-名字中包含固定字符串"}],lastUpdated:"2023/09/03, 17:51:05",lastUpdatedTimestamp:1693734665e3},{title:"elasticsearch",frontmatter:{title:"elasticsearch",date:"2023-09-11T10:43:53.000Z",permalink:"/pages/d8cbeb/",categories:["《server》","其他"],tags:[null],author:{name:"Jacky",email:"jackdoson2011@gmail.com",link:"https://github.com/jacky1234"}},regularPath:"/%E3%80%8Aserver%E3%80%8B/10.%E5%85%B6%E4%BB%96%20/10.elasticsearch.html",relativePath:"《server》/10.其他 /10.elasticsearch.md",key:"v-375d6f79",path:"/pages/d8cbeb/",headers:[{level:2,title:"介绍",slug:"介绍"},{level:2,title:"安装及使用",slug:"安装及使用"},{level:2,title:"链接",slug:"链接"}],lastUpdated:"2023/09/13, 10:10:55",lastUpdatedTimestamp:1694571055e3},{title:"服务器面试题整理",frontmatter:{title:"服务器面试题整理",date:"2023-09-10T23:54:12.000Z",permalink:"/pages/22d48b/",categories:["《server》","其他"],tags:["面试"],author:{name:"Jacky",email:"jackdoson2011@gmail.com",link:"https://github.com/jacky1234"}},regularPath:"/%E3%80%8Aserver%E3%80%8B/10.%E5%85%B6%E4%BB%96%20/100.%E9%9D%A2%E8%AF%95%E9%A2%98%E6%95%B4%E7%90%86.html",relativePath:"《server》/10.其他 /100.面试题整理.md",key:"v-8ad6e996",path:"/pages/22d48b/",headers:[{level:2,title:"spring",slug:"spring"},{level:3,title:"IOC 的实现机制",slug:"ioc-的实现机制"},{level:3,title:"Spring AOP 与 AspectJ AOP",slug:"spring-aop-与-aspectj-aop"},{level:2,title:"其他",slug:"其他"},{level:3,title:"docker 与传统虚拟机的区别",slug:"docker-与传统虚拟机的区别"}],lastUpdated:"2023/09/13, 11:56:57",lastUpdatedTimestamp:1694577417e3},{title:"websocket",frontmatter:{title:"websocket",date:"2023-09-15T18:55:21.000Z",permalink:"/pages/c65eb4/",categories:["《server》","其他"],tags:["websocket"],author:{name:"Jacky",email:"jackdoson2011@gmail.com",link:"https://github.com/jacky1234"}},regularPath:"/%E3%80%8Aserver%E3%80%8B/10.%E5%85%B6%E4%BB%96%20/50.websocket.html",relativePath:"《server》/10.其他 /50.websocket.md",key:"v-4c298fed",path:"/pages/c65eb4/",headers:[{level:2,title:"websocket 原理",slug:"websocket-原理"},{level:3,title:"连接过程",slug:"连接过程"},{level:2,title:"WebSocket 和 HTTP 的关系?",slug:"websocket-和-http-的关系"},{level:2,title:"链接",slug:"链接"}],lastUpdated:"2023/09/17, 11:55:13",lastUpdatedTimestamp:1694922913e3},{title:"tutorial",frontmatter:{title:"tutorial",date:"2023-06-10T13:47:20.000Z",permalink:"/pages/9f55fd/",categories:["《spring-boot》"],tags:[null],author:{name:"Jacky",email:"jackdoson2011@gmail.com",link:"https://github.com/jacky1234"}},regularPath:"/%E3%80%8Aspring-boot%E3%80%8B/01.tutorial.html",relativePath:"《spring-boot》/01.tutorial.md",key:"v-08eab131",path:"/pages/9f55fd/",lastUpdated:"2023/06/10, 14:25:28",lastUpdatedTimestamp:1686378328e3},{title:"tutorial",frontmatter:{title:"tutorial",date:"2023-09-18T09:00:23.000Z",permalink:"/pages/ce4afc/",categories:["《vue》"],tags:["vue"],author:{name:"Jacky",email:"jackdoson2011@gmail.com",link:"https://github.com/jacky1234"}},regularPath:"/%E3%80%8Avue%E3%80%8B/01.tutorial.html",relativePath:"《vue》/01.tutorial.md",key:"v-08afd4b1",path:"/pages/ce4afc/",headers:[{level:2,title:"介绍",slug:"介绍"},{level:3,title:"element-ui",slug:"element-ui"},{level:2,title:"链接",slug:"链接"}],lastUpdated:"2023/09/18, 10:04:38",lastUpdatedTimestamp:1695002678e3},{title:"事件",frontmatter:{title:"事件",date:"2023-04-28T07:22:13.000Z",permalink:"/pages/86683c/",sidebar:"auto",categories:["跨平台","vue","极客时间"],tags:[null],author:{name:"Jacky",email:"jackdoson2011@gmail.com",link:"https://github.com/jacky1234"}},regularPath:"/%E3%80%8Avue%E3%80%8B/10.%E6%9E%81%E5%AE%A2%E8%AF%BE%E5%A0%82/01.%E4%BA%8B%E4%BB%B6.html",relativePath:"《vue》/10.极客课堂/01.事件.md",key:"v-e2fc03e2",path:"/pages/86683c/",headers:[{level:2,title:"分类",slug:"分类"}],lastUpdated:"2023/06/04, 22:05:57",lastUpdatedTimestamp:1685887557e3},{title:"属性",frontmatter:{title:"属性",date:"2023-04-28T07:22:13.000Z",permalink:"/pages/4f9b39/",sidebar:"auto",categories:["跨平台","vue","极客时间"],tags:[null],author:{name:"Jacky",email:"jackdoson2011@gmail.com",link:"https://github.com/jacky1234"}},regularPath:"/%E3%80%8Avue%E3%80%8B/10.%E6%9E%81%E5%AE%A2%E8%AF%BE%E5%A0%82/02.%E5%B1%9E%E6%80%A7.html",relativePath:"《vue》/10.极客课堂/02.属性.md",key:"v-415cd298",path:"/pages/4f9b39/",headers:[{level:2,title:"分类",slug:"分类"},{level:2,title:"链接",slug:"链接"}],lastUpdated:"2023/06/04, 22:05:57",lastUpdatedTimestamp:1685887557e3},{title:"指令",frontmatter:{title:"指令",date:"2023-04-28T07:22:13.000Z",permalink:"/pages/f23ed2/",sidebar:"auto",categories:["跨平台","vue","极客时间"],tags:[null],author:{name:"Jacky",email:"jackdoson2011@gmail.com",link:"https://github.com/jacky1234"}},regularPath:"/%E3%80%8Avue%E3%80%8B/10.%E6%9E%81%E5%AE%A2%E8%AF%BE%E5%A0%82/04.%E6%8C%87%E4%BB%A4.html",relativePath:"《vue》/10.极客课堂/04.指令.md",key:"v-7ec4ede6",path:"/pages/f23ed2/",headers:[{level:2,title:"内置指令",slug:"内置指令"},{level:2,title:"自定义指令",slug:"自定义指令"}],lastUpdated:"2023/06/04, 22:05:57",lastUpdatedTimestamp:1685887557e3},{title:"双向绑定和单项数据流不冲突",frontmatter:{title:"双向绑定和单项数据流不冲突",date:"2023-04-28T07:22:13.000Z",permalink:"/pages/cb9380/",sidebar:"auto",categories:["跨平台","vue","极客时间"],tags:[null],author:{name:"Jacky",email:"jackdoson2011@gmail.com",link:"https://github.com/jacky1234"}},regularPath:"/%E3%80%8Avue%E3%80%8B/10.%E6%9E%81%E5%AE%A2%E8%AF%BE%E5%A0%82/03.%E5%8F%8C%E5%90%91%E7%BB%91%E5%AE%9A%E5%92%8C%E5%8D%95%E9%A1%B9%E6%95%B0%E6%8D%AE%E6%B5%81%E4%B8%8D%E5%86%B2%E7%AA%81.html",relativePath:"《vue》/10.极客课堂/03.双向绑定和单项数据流不冲突.md",key:"v-3e23eb06",path:"/pages/cb9380/",lastUpdated:"2023/06/04, 22:05:57",lastUpdatedTimestamp:1685887557e3},{title:"理解虚拟Dom和key属性的作用",frontmatter:{title:"理解虚拟Dom和key属性的作用",date:"2023-04-28T07:22:13.000Z",permalink:"/pages/651b48/",sidebar:"auto",categories:["跨平台","vue","极客时间"],tags:[null],author:{name:"Jacky",email:"jackdoson2011@gmail.com",link:"https://github.com/jacky1234"}},regularPath:"/%E3%80%8Avue%E3%80%8B/10.%E6%9E%81%E5%AE%A2%E8%AF%BE%E5%A0%82/10.%E7%90%86%E8%A7%A3%E8%99%9A%E6%8B%9FDom%E5%92%8Ckey%E5%B1%9E%E6%80%A7%E7%9A%84%E4%BD%9C%E7%94%A8.html",relativePath:"《vue》/10.极客课堂/10.理解虚拟Dom和key属性的作用.md",key:"v-427b9d2c",path:"/pages/651b48/",lastUpdated:"2023/06/04, 22:05:57",lastUpdatedTimestamp:1685887557e3},{title:"vue传递数据-slot",frontmatter:{title:"vue传递数据-slot",date:"2023-04-28T07:22:13.000Z",permalink:"/pages/f9b0df/",sidebar:"auto",categories:["跨平台","vue","极客时间"],tags:[null],author:{name:"Jacky",email:"jackdoson2011@gmail.com",link:"https://github.com/jacky1234"}},regularPath:"/%E3%80%8Avue%E3%80%8B/10.%E6%9E%81%E5%AE%A2%E8%AF%BE%E5%A0%82/05.vue%E4%BC%A0%E9%80%92%E6%95%B0%E6%8D%AE-slot.html",relativePath:"《vue》/10.极客课堂/05.vue传递数据-slot.md",key:"v-642f49fb",path:"/pages/f9b0df/",headers:[{level:4,title:"App.vue 调用组件TodoItem.vue. 并产生回调",slug:"app-vue-调用组件todoitem-vue-并产生回调"}],lastUpdated:"2023/06/04, 22:05:57",lastUpdatedTimestamp:1685887557e3},{title:"如何触发组件更新",frontmatter:{title:"如何触发组件更新",date:"2023-04-28T07:22:13.000Z",permalink:"/pages/6570ab/",sidebar:"auto",categories:["跨平台","vue","极客时间"],tags:[null],author:{name:"Jacky",email:"jackdoson2011@gmail.com",link:"https://github.com/jacky1234"}},regularPath:"/%E3%80%8Avue%E3%80%8B/10.%E6%9E%81%E5%AE%A2%E8%AF%BE%E5%A0%82/11.%E5%A6%82%E4%BD%95%E8%A7%A6%E5%8F%91%E7%BB%84%E4%BB%B6%E6%9B%B4%E6%96%B0.html",relativePath:"《vue》/10.极客课堂/11.如何触发组件更新.md",key:"v-93da6800",path:"/pages/6570ab/",lastUpdated:"2023/06/04, 22:05:57",lastUpdatedTimestamp:1685887557e3},{title:"如何优雅地获取跨层级实例",frontmatter:{title:"如何优雅地获取跨层级实例",date:"2023-04-28T07:22:13.000Z",permalink:"/pages/59f768/",sidebar:"auto",categories:["跨平台","vue","极客时间"],tags:[null],author:{name:"Jacky",email:"jackdoson2011@gmail.com",link:"https://github.com/jacky1234"}},regularPath:"/%E3%80%8Avue%E3%80%8B/10.%E6%9E%81%E5%AE%A2%E8%AF%BE%E5%A0%82/16.%E5%A6%82%E4%BD%95%E4%BC%98%E9%9B%85%E5%9C%B0%E8%8E%B7%E5%8F%96%E8%B7%A8%E5%B1%82%E7%BA%A7%E5%AE%9E%E4%BE%8B.html",relativePath:"《vue》/10.极客课堂/16.如何优雅地获取跨层级实例.md",key:"v-02ac7740",path:"/pages/59f768/",lastUpdated:"2023/06/04, 22:05:57",lastUpdatedTimestamp:1685887557e3},{title:"技巧记录",frontmatter:{title:"技巧记录",date:"2023-08-25T11:31:19.000Z",permalink:"/pages/9c451e/",categories:["《web》","javascript"],tags:["javascript"],author:{name:"Jacky",email:"jackdoson2011@gmail.com",link:"https://github.com/jacky1234"}},regularPath:"/%E3%80%8Aweb%E3%80%8B/01.javascript/50.%E6%8A%80%E5%B7%A7%E8%AE%B0%E5%BD%95.html",relativePath:"《web》/01.javascript/50.技巧记录.md",key:"v-668a7bff",path:"/pages/9c451e/",headers:[{level:2,title:"给对象赋值简写",slug:"给对象赋值简写"}],lastUpdated:"2023/09/18, 10:04:38",lastUpdatedTimestamp:1695002678e3},{title:"tutorial",frontmatter:{title:"tutorial",date:"2023-07-05T23:44:34.000Z",categories:["《web》"],tags:["web"],author:{name:"Jacky",email:"jackdoson2011@gmail.com",link:"https://github.com/jacky1234"},permalink:"/pages/d8c80d/"},regularPath:"/%E3%80%8Aweb%E3%80%8B/01.tutorial.html",relativePath:"《web》/01.tutorial.md",key:"v-adf4c11e",path:"/pages/d8c80d/",headers:[{level:2,title:"Base",slug:"base"},{level:3,title:"javascript",slug:"javascript"},{level:2,title:"react",slug:"react"},{level:2,title:"微信小程序",slug:"微信小程序"}],lastUpdated:"2023/07/14, 19:05:50",lastUpdatedTimestamp:168933275e4},{title:"javascript",frontmatter:{title:"javascript",date:"2023-06-26T23:51:25.000Z",permalink:"/pages/548959/",categories:["其他","更多"],tags:["javascript","web"],author:{name:"Jacky",email:"jackdoson2011@gmail.com",link:"https://github.com/jacky1234"}},regularPath:"/%E3%80%8Aweb%E3%80%8B/02.javascript.html",relativePath:"《web》/02.javascript.md",key:"v-be2e851e",path:"/pages/548959/",headers:[{level:2,title:"Function",slug:"function"},{level:3,title:"methods",slug:"methods"},{level:4,title:"bind",slug:"bind"},{level:2,title:"links",slug:"links"}],lastUpdated:"2023/08/05, 14:56:28",lastUpdatedTimestamp:1691218588e3},{title:"web 术语",frontmatter:{title:"web 术语",date:"2023-06-04T15:52:41.000Z",permalink:"/pages/4f876a/",categories:["其他","工具"],tags:["术语","web"],author:{name:"Jacky",email:"jackdoson2011@gmail.com",link:"https://github.com/jacky1234"}},regularPath:"/%E3%80%8Aweb%E3%80%8B/10.web%E6%9C%AF%E8%AF%AD%E6%A6%82%E5%BF%B5.html",relativePath:"《web》/10.web术语概念.md",key:"v-590e6280",path:"/pages/4f876a/",headers:[{level:2,title:"概念篇",slug:"概念篇"},{level:3,title:"CORS",slug:"cors"},{level:3,title:"ES5 与 ES6",slug:"es5-与-es6"},{level:3,title:"react vs vue",slug:"react-vs-vue"}],lastUpdated:"2023/07/15, 08:27:55",lastUpdatedTimestamp:1689380875e3},{title:"node版本管理",frontmatter:{title:"node版本管理",date:"2023-09-18T08:52:39.000Z",permalink:"/pages/411579/",categories:["《web》","其他"],tags:[null],author:{name:"Jacky",email:"jackdoson2011@gmail.com",link:"https://github.com/jacky1234"}},regularPath:"/%E3%80%8Aweb%E3%80%8B/10.%E5%85%B6%E4%BB%96/01.node%E7%89%88%E6%9C%AC%E7%AE%A1%E7%90%86.html",relativePath:"《web》/10.其他/01.node版本管理.md",key:"v-416ea53c",path:"/pages/411579/",headers:[{level:2,title:"安装",slug:"安装"}],lastUpdated:"2023/09/18, 10:04:38",lastUpdatedTimestamp:1695002678e3},{title:"nextjs",frontmatter:{title:"nextjs",date:"2023-08-16T08:05:33.000Z",permalink:"/pages/d2a447/",categories:["《web》"],tags:["nextjs"],author:{name:"Jacky",email:"jackdoson2011@gmail.com",link:"https://github.com/jacky1234"}},regularPath:"/%E3%80%8Aweb%E3%80%8B/50.nextjs.html",relativePath:"《web》/50.nextjs.md",key:"v-5fe14fb1",path:"/pages/d2a447/",headers:[{level:2,title:"介绍",slug:"介绍"},{level:2,title:"Get start",slug:"get-start"},{level:3,title:"App Router vs Pages Router",slug:"app-router-vs-pages-router"},{level:3,title:"Server and Client Components",slug:"server-and-client-components"},{level:4,title:"为什么要使用服务器组件?",slug:"为什么要使用服务器组件"},{level:2,title:"链接",slug:"链接"}],lastUpdated:"2023/09/02, 18:15:33",lastUpdatedTimestamp:1693649733e3},{title:"前言",frontmatter:{title:"前言",date:"2023-04-28T07:22:13.000Z",permalink:"/pages/7e542a/",sidebar:"auto",categories:["跨平台","vue","极客时间"],tags:["vue"],author:{name:"Jacky",email:"jackdoson2011@gmail.com",link:"https://github.com/jacky1234"}},regularPath:"/%E3%80%8Avue%E3%80%8B/10.%E6%9E%81%E5%AE%A2%E8%AF%BE%E5%A0%82/00.%E5%89%8D%E8%A8%80.html",relativePath:"《vue》/10.极客课堂/00.前言.md",key:"v-28c38e47",path:"/pages/7e542a/",lastUpdated:"2023/06/04, 22:05:57",lastUpdatedTimestamp:1685887557e3},{title:"原理",frontmatter:{title:"原理",date:"2023-06-04T22:00:26.000Z",permalink:"/pages/8fbdb4/",categories:["《vue》"],tags:["vue"],author:{name:"Jacky",email:"jackdoson2011@gmail.com",link:"https://github.com/jacky1234"}},regularPath:"/%E3%80%8Avue%E3%80%8B/01.%E7%AC%94%E8%AE%B0/02.%E5%8E%9F%E7%90%86.html",relativePath:"《vue》/01.笔记/02.原理.md",key:"v-7082d399",path:"/pages/8fbdb4/",headers:[{level:2,title:"vue2",slug:"vue2"},{level:3,title:"概述",slug:"概述"},{level:3,title:"虚拟 DOM",slug:"虚拟-dom"},{level:3,title:"template 函数",slug:"template-函数"},{level:2,title:"vue3",slug:"vue3"}],lastUpdated:"2023/06/04, 22:21:12",lastUpdatedTimestamp:1685888472e3}],themeConfig:{repo:"https://github.com/jacky1234",editLinks:!1,editLinkText:"编辑",lastUpdated:"上次更新",sidebar:{"/00.目录页/":[["01.前端.md","前端","/fe/"],["0400.其他.md","other","/other/"],["0401.工具.md","工具","/tool/"],["0405.博客.md","博客","/blog/"],["0408.python.md","python","/python/"],["0410.more.md","more","/more/"],["0500.mine.md","mime","/mime/"]],catalogue:{"前端":"/fe/","其他":"/other/",server:"/server/","工具":"/tool/","博客":"/blog/",java:"/java/",python:"/python/",more:"/more/",mine:"/mime/",web:"/web/",android:"/android/",iOS:"/iOS/",react:"/react/",vue:"/vue/"},"/01.前端/":[["02.web.md","web","/web/"],["05.android.md","android","/android/"],["06.iOS.md","iOS","/iOS/"],["11.react.md","《react》笔记","/react/"],["12.vue.md","《vue》笔记","/vue/"]],"/04.其他/":[{title:"工具",collapsable:!0,children:[["01.工具/00.shell.md","shell","/pages/0140a0/"],["01.工具/01.git.md","git","/pages/7071e6/"],["01.工具/02.web工具.md","web工具","/pages/3869be/"],["01.工具/03.npm.md","npm","/pages/669dfc/"],["01.工具/05.adb.md","adb","/pages/37f363/"],["01.工具/06.aapt.md","aapt","/pages/907793/"],["01.工具/07.c++工具.md","c++工具","/pages/977efe/"],["01.工具/08.pip3.md","pip3","/pages/7ee6cc/"],["01.工具/09.vim.md","vim","/pages/89d231/"],["01.工具/12.docker.md","docker","/pages/1c262c/"],["01.工具/13.unbuntuOnWindows.md","unbuntuOnWindows","/pages/8cb2e1/"],["01.工具/14.ides.md","ides","/pages/bd17b5/"],["01.工具/15.zsh高效的shell.md","zsh高效的shell","/pages/f9c14d/"],["01.工具/16.github.md","github","/pages/514538/"],["01.工具/20.gradle.md","gradle","/pages/0cdfba/"],["01.工具/21.mvn.md","mvn","/pages/c80e98/"],["01.工具/50.jadx.md","jadx","/pages/79f386/"]]},{title:"网络",collapsable:!0,children:[["02.网络/00.网络.md","网络","/pages/cb9d0f/"],["02.网络/01.HTTP.md","HTTP","/pages/2a8b7b/"],["02.网络/02.HTTPS.md","HTTPS","/pages/3dd4b2/"],["02.网络/03.CDN-DNS-httpDNS.md","CDN-DNS-httpDNS","/pages/59b0a9/"],["02.网络/04.okhttp.md","okhttp","/pages/f1d871/"],["02.网络/05.移动端的网络优化.md","移动端的网络优化","/pages/109caf/"],["02.网络/06.websocket-socket.md","websocket-socket","/pages/10a997/"]]},{title:"语言",collapsable:!0,children:[{title:"C&C++",collapsable:!0,children:[["03.语言/01.C&C++/01.前言.md","前言","/pages/6ea216/"],["03.语言/01.C&C++/05.C++面试突击.md","C++面试突击","/pages/ca8e7a/"]]}]},{title:"博客",collapsable:!0,children:[["05.博客/01.写博客的那些事.md","博客指南","/pages/df7642/"],["05.博客/02.vuepress简单记录.md","vuepress的简单记录","/pages/30ec1d/"],["05.博客/03.GitHub Actions 实现自动部署静态博客.md","GitHub Actions 实现自动部署静态博客","/pages/a96c0f/"]]},{title:"side-project",collapsable:!0,children:[["06.side-project/02.快速实现.md","快速实现","/pages/857c89/"]]},{title:"成长",collapsable:!0,children:[["07.成长/02.管理说.md","管理学","/pages/186356/"],["07.成长/03.coding.md","技术规范等整理","/pages/bea5e2/"],["07.成长/10.如何睡觉.md","如何睡觉","/pages/b21fed/"]]},{title:"java",collapsable:!0,children:[["08.java/01.tutorial.md","Java tutorial","/pages/c38a8f/"],["08.java/50.使用 Jenv 实现 Jdk 多版本管理.md","使用 Jenv 实现 Jdk 多版本管理","/pages/935419/"],["08.java/100.UnSafe.md","UnSafe","/pages/c3229c/"],["08.java/101.集合.md","集合","/pages/55dc87/"],["08.java/102.Class类.md","Class类","/pages/ed7a6a/"]]},{title:"linux",collapsable:!0,children:[["09.linux/01.tutorial.md","tutorial","/pages/18abfe/"]]},{title:"更多",collapsable:!0,children:[["10.更多/5.正则.md","正则","/pages/3d30c9/"],["10.更多/10.音视频概述.md","音视频概述","/pages/086701/"],["10.更多/12.效率.md","工作效率","/pages/d9fade/"],["10.更多/13.技术专业词汇.md","技术专业词汇","/pages/f7262c/"],["10.更多/14.设计模式和思想.md","设计模式和思想","/pages/db8380/"],["10.更多/20.frida.md","frida","/pages/0fe5d6/"],["10.更多/21.Android密钥库系统.md","Android密钥系统","/pages/10e7db/"],["10.更多/30.使用腾讯云服务器.md","使用腾讯云服务器","/pages/03456e/"],["10.更多/96.读kk大神聊房价.md","读kk大神聊房价","/pages/7c68cb/"],["10.更多/97.效率秘籍.md","效率秘籍","/pages/2af3e9/"],["10.更多/98.mac常用工具使用.md","mac常用工具使用","/pages/3adccf/"],["10.更多/99.财经基础.md","财经基础","/pages/c76462/"],["10.更多/100.测试页面.md","测试页面","/pages/d3b34e/"],["10.更多/101.沟通的艺术.md","沟通的艺术","/pages/6cd2e1/"]]},{title:"生活方式",collapsable:!0,children:[["11.生活方式/01.tiktok在国内使用.md","tiktok在国内使用","/pages/79c121/"]]}],"/05.收藏夹/":[["01.网站.md","网站","/pages/5a96b7/"]],"/mine/":[{title:"小伟小娟",collapsable:!0,children:[["900.小伟小娟/100.小伟和小娟.md","小伟和小娟","/pages/6c1d02/"]]},["999.gradle鉴权脚本.md","gradle鉴权脚本","/pages/aaf954/"],["1000.switch.md","switch","/pages/1bc90b/"]],"/《android》/":[["00.Android概述.md","概述","/pages/dd1044/"],["01.android图形系统.md","android图形系统","/pages/420ab6/"],{title:"性能",collapsable:!0,children:[["5.性能/1.Android稳定性治理.md","Android稳定性治理","/pages/b6bad0/"],["5.性能/12.Android低端机性能优化.md","Android低端机性能优化","/pages/a0d7dc/"],["5.性能/100.apm相关概念.md","apm相关概念","/pages/9b0a57/"]]},{title:"三方库解析",collapsable:!0,children:[["6.三方库解析/01.retrofit动态代理设计.md","retrofit动态代理设计","/pages/c8fb65/"]]},{title:"其他",collapsable:!0,children:[["1000.其他/01.生产环境Message分发处理设计.md","生产环境Message分发处理设计","/pages/21df4f/"],["1000.其他/50.卡顿分析工具.md","卡顿分析工具","/pages/eae245/"],["1000.其他/51.perfetto.md","perfetto","/pages/29a4de/"],["1000.其他/52.提升UI加载速度的几点思考.md","提升UI加载速度的几点思考","/pages/cd0789/"],["1000.其他/53.Android零耗时首帧体验整理.md","Android零耗时首帧体验","/pages/5d8ba8/"],["1000.其他/54.jsbridge.md","jsbridge","/pages/d2d3e5/"]]}],"/《iOS》/":[["01.tutorial.md","tutorial","/pages/12d86f/"]],"/《python》/":[["00.python学习.md","python学习","/pages/4595e1/"],{title:"语法",collapsable:!0,children:[["01.语法/10.字符串.md","字符串","/pages/02f88a/"]]},{title:"其他",collapsable:!0,children:[["10.其他/01.python snippet code.md","python snippet code","/pages/140cb3/"],["10.其他/02.python版本管理.md","python3命令","/pages/dc1698/"]]},["100.BeautifulSoup的使用.md","beautysoup","/pages/3aeda3/"]],"/《react》/":[["02.hooks.md","Hooks","/pages/f85f1b/"],["03.components.md","components","/pages/82e5d7/"],["04.apis.md","apis","/pages/0c11ea/"],["50.记一次React回调函数.md","记录-在已有的项目基础上扩展回调","/pages/4db36a/"]],"/《server》/":[["00.tutorial.md","服务器tutorial","/pages/0d7cc1/"],{title:"spring",collapsable:!0,children:[["01.spring/01.spring.md","spring","/pages/6ab0a7/"],["01.spring/02.了解spring.md","了解spring","/pages/39870b/"]]},{title:"数据库",collapsable:!0,children:[["02.数据库/01.database.md","Database","/pages/233ea5/"],["02.数据库/02.mysql学习笔记.md","mysql","/pages/e9db87/"],["02.数据库/05.sql.md","sql","/pages/e4a24e/"]]},{title:"其他 ",collapsable:!0,children:[["10.其他 /10.elasticsearch.md","elasticsearch","/pages/d8cbeb/"],["10.其他 /50.websocket.md","websocket","/pages/c65eb4/"],["10.其他 /100.面试题整理.md","服务器面试题整理","/pages/22d48b/"]]}],"/《spring-boot》/":[["01.tutorial.md","tutorial","/pages/9f55fd/"]],"/《vue》/":[{title:"笔记",collapsable:!0,children:[["01.笔记/02.原理.md","原理","/pages/8fbdb4/"]]},{title:"极客课堂",collapsable:!0,children:[["10.极客课堂/00.前言.md","前言","/pages/7e542a/"],["10.极客课堂/01.事件.md","事件","/pages/86683c/"],["10.极客课堂/02.属性.md","属性","/pages/4f9b39/"],["10.极客课堂/03.双向绑定和单项数据流不冲突.md","双向绑定和单项数据流不冲突","/pages/cb9380/"],["10.极客课堂/04.指令.md","指令","/pages/f23ed2/"],["10.极客课堂/05.vue传递数据-slot.md","vue传递数据-slot","/pages/f9b0df/"],["10.极客课堂/10.理解虚拟Dom和key属性的作用.md","理解虚拟Dom和key属性的作用","/pages/651b48/"],["10.极客课堂/11.如何触发组件更新.md","如何触发组件更新","/pages/6570ab/"],["10.极客课堂/16.如何优雅地获取跨层级实例.md","如何优雅地获取跨层级实例","/pages/59f768/"]]}],"/《web》/":[["01.tutorial.md","tutorial","/pages/d8c80d/"],["02.javascript.md","javascript","/pages/548959/"],{title:"其他",collapsable:!0,children:[["10.其他/01.node版本管理.md","node版本管理","/pages/411579/"]]},["50.nextjs.md","nextjs","/pages/d2a447/"]]},sidebarDepth:2,docsDir:"docs",docsBranch:"main",searchMaxSuggestions:10,nav:[{text:"首页",link:"/"},{text:"前端",link:"/fe/",items:[{text:"学习笔记",items:[{text:"web",link:"/web/"},{text:"react",link:"/react/"},{text:"android",link:"/android/"},{text:"iOS",link:"/iOS/"},{text:"vue",link:"/vue/"}]}]},{text:"索引",link:"/archives/",items:[{text:"分类",link:"/categories/"},{text:"标签",link:"/tags/"},{text:"归档",link:"/archives/"}]},{text:"收藏",link:"/pages/5a96b7/"},{text:"其他",link:"/other/",items:[{text:"工具",link:"/tool/"},{text:"博客",link:"/blog/"},{text:"python",link:"/python/"},{text:"java",link:"/java/"},{text:"成长",link:"/pages/7ffeb0/"},{text:"frida",link:"/pages/0fe5d6/"},{text:"server",link:"/server/"},{text:"更多",link:"/more/"}]}],author:{name:"Jacky",link:"https://github.com/jacky1234",email:"jackdoson2011@gmail.com"},blogger:{avatar:"https://raw.githubusercontent.com/jacky1234/picArchieve/master/uPic/dUmDI0.jpg",name:"Jack Yang",slogan:"编程; 随笔"},social:{icons:[{iconClass:"icon-youjian",title:"发邮件",link:"mailto:jackdoson2011@gmail.com"},{iconClass:"icon-github",title:"Github",link:"https://github.com/jacky1234"},{iconClass:"icon-erji",title:"听音乐",link:"https://music.163.com/#/my/m/music/playlist?id=317363436"}]},footer:{createYear:2019,copyrightInfo:'Jacky | MIT License'},extendFrontmatter:{author:{name:"Jacky",email:"jackdoson2011@gmail.com",link:"https://github.com/jacky1234"}}},locales:{"/":{lang:"zh-CN",title:"Jacky's blog",description:"勤学如春起之苗,不见其增,日有所长;辍学如磨刀之石,不见其损,日有所亏。",path:"/"}}};var ks=n(95),Es=n(96),_s=n(11);var xs={computed:{$filterPosts(){return this.$site.pages.filter(e=>{const{frontmatter:{pageComponent:t,article:n,home:a}}=e;return!(t||!1===n||!0===a)})},$sortPosts(){return(e=this.$filterPosts).sort((e,t)=>{const n=e.frontmatter.sticky,a=t.frontmatter.sticky;return n&&a?n==a?Object(_s.a)(e,t):n-a:n&&!a?-1:!n&&a?1:Object(_s.a)(e,t)}),e;var e},$sortPostsByDate(){return(e=this.$filterPosts).sort((e,t)=>Object(_s.a)(e,t)),e;var e},$groupPosts(){return function(e){const t={},n={};for(let a=0,r=e.length;a{n&&(t[n]||(t[n]=[]),t[n].push(e[a]))}),"array"===Object(_s.n)(i)&&i.forEach(t=>{t&&(n[t]||(n[t]=[]),n[t].push(e[a]))})}return{categories:t,tags:n}}(this.$sortPosts)},$categoriesAndTags(){return function(e){const t=[],n=[];for(let n in e.categories)t.push({key:n,length:e.categories[n].length});for(let t in e.tags)n.push({key:t,length:e.tags[t].length});return{categories:t,tags:n}}(this.$groupPosts)}}};qn.component(ks.default),qn.component(Es.default);function ws(e){return e.toString().padStart(2,"0")}n(245);qn.component("RText",()=>n.e(36).then(n.bind(null,362))),qn.component("Badge",()=>Promise.all([n.e(0),n.e(5)]).then(n.bind(null,363))),qn.component("CodeBlock",()=>Promise.resolve().then(n.bind(null,95))),qn.component("CodeGroup",()=>Promise.resolve().then(n.bind(null,96)));n(246);var As={name:"BackToTop",props:{threshold:{type:Number,default:300}},data:()=>({scrollTop:null}),computed:{show(){return this.scrollTop>this.threshold}},mounted(){this.scrollTop=this.getScrollTop(),window.addEventListener("scroll",_l()(()=>{this.scrollTop=this.getScrollTop()},100))},methods:{getScrollTop:()=>window.pageYOffset||document.documentElement.scrollTop||document.body.scrollTop||0,scrollToTop(){window.scrollTo({top:0,behavior:"smooth"}),this.scrollTop=0}}},js=(n(247),Object(gs.a)(As,(function(){var e=this._self._c;return e("transition",{attrs:{name:"fade"}},[this.show?e("svg",{staticClass:"go-to-top",attrs:{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 49.484 28.284"},on:{click:this.scrollToTop}},[e("g",{attrs:{transform:"translate(-229 -126.358)"}},[e("rect",{attrs:{fill:"currentColor",width:"35",height:"5",rx:"2",transform:"translate(229 151.107) rotate(-45)"}}),this._v(" "),e("rect",{attrs:{fill:"currentColor",width:"35",height:"5",rx:"2",transform:"translate(274.949 154.642) rotate(-135)"}})])]):this._e()])}),[],!1,null,"5fd4ef0c",null).exports),Bs=[({Vue:e,options:t,router:n,siteData:a})=>{},({Vue:e,options:t,router:n,siteData:a})=>{a.pages.map(e=>{const{frontmatter:{date:t,author:n}}=e;"string"==typeof t&&"Z"===t.charAt(t.length-1)&&(e.frontmatter.date=function(e){e instanceof Date||(e=new Date(e));return`${e.getUTCFullYear()}-${ws(e.getUTCMonth()+1)}-${ws(e.getUTCDate())} ${ws(e.getUTCHours())}:${ws(e.getUTCMinutes())}:${ws(e.getUTCSeconds())}`}(t)),n?e.author=n:a.themeConfig.author&&(e.author=a.themeConfig.author)}),e.mixin(xs)},{},({Vue:e})=>{e.mixin({computed:{$dataBlock(){return this.$options.__data__block__}}})},{},{},({Vue:e})=>{e.component("BackToTop",js)}],Ts=["BackToTop"];class Ps extends class{constructor(){this.store=new qn({data:{state:{}}})}$get(e){return this.store.state[e]}$set(e,t){qn.set(this.store.state,e,t)}$emit(...e){this.store.$emit(...e)}$on(...e){this.store.$on(...e)}}{}Object.assign(Ps.prototype,{getPageAsyncComponent:ol,getLayoutAsyncComponent:ll,getAsyncComponent:sl,getVueComponent:cl});var Cs={install(e){const t=new Ps;e.$vuepress=t,e.prototype.$vuepress=t}};function Os(e,t){const n=t.toLowerCase();return e.options.routes.some(e=>e.path.toLowerCase()===n)}var Ss={props:{pageKey:String,slotKey:{type:String,default:"default"}},render(e){const t=this.pageKey||this.$parent.$page.key;return pl("pageKey",t),qn.component(t)||qn.component(t,ol(t)),qn.component(t)?e(t):e("")}},Us={functional:!0,props:{slotKey:String,required:!0},render:(e,{props:t,slots:n})=>e("div",{class:["content__"+t.slotKey]},n()[t.slotKey])},$s={computed:{openInNewWindowTitle(){return this.$themeLocaleConfig.openNewWindowText||"(opens new window)"}}},Ls=(n(248),n(249),Object(gs.a)($s,(function(){var e=this._self._c;return e("span",[e("svg",{staticClass:"icon outbound",attrs:{xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",focusable:"false",x:"0px",y:"0px",viewBox:"0 0 100 100",width:"15",height:"15"}},[e("path",{attrs:{fill:"currentColor",d:"M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"}}),this._v(" "),e("polygon",{attrs:{fill:"currentColor",points:"45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"}})]),this._v(" "),e("span",{staticClass:"sr-only"},[this._v(this._s(this.openInNewWindowTitle))])])}),[],!1,null,null,null).exports),Ds={functional:!0,render(e,{parent:t,children:n}){if(t._isMounted)return n;t.$once("hook:mounted",()=>{t.$forceUpdate()})}};qn.config.productionTip=!1,qn.use(Zo),qn.use(Cs),qn.mixin(function(e,t,n=qn){!function(e){e.locales&&Object.keys(e.locales).forEach(t=>{e.locales[t].path=t});Object.freeze(e)}(t),n.$vuepress.$set("siteData",t);const a=new(e(n.$vuepress.$get("siteData"))),r=Object.getOwnPropertyDescriptors(Object.getPrototypeOf(a)),i={};return Object.keys(r).reduce((e,t)=>(t.startsWith("$")&&(e[t]=r[t].get),e),i),{computed:i}}(e=>class{setPage(e){this.__page=e}get $site(){return e}get $themeConfig(){return this.$site.themeConfig}get $frontmatter(){return this.$page.frontmatter}get $localeConfig(){const{locales:e={}}=this.$site;let t,n;for(const a in e)"/"===a?n=e[a]:0===this.$page.path.indexOf(a)&&(t=e[a]);return t||n||{}}get $siteTitle(){return this.$localeConfig.title||this.$site.title||""}get $canonicalUrl(){const{canonicalUrl:e}=this.$page.frontmatter;return"string"==typeof e&&e}get $title(){const e=this.$page,{metaTitle:t}=this.$page.frontmatter;if("string"==typeof t)return t;const n=this.$siteTitle,a=e.frontmatter.home?null:e.frontmatter.title||e.title;return n?a?a+" | "+n:n:a||"VuePress"}get $description(){const e=function(e){if(e){const t=e.filter(e=>"description"===e.name)[0];if(t)return t.content}}(this.$page.frontmatter.meta);return e||(this.$page.frontmatter.description||this.$localeConfig.description||this.$site.description||"")}get $lang(){return this.$page.frontmatter.lang||this.$localeConfig.lang||"en-US"}get $localePath(){return this.$localeConfig.path||"/"}get $themeLocaleConfig(){return(this.$site.themeConfig.locales||{})[this.$localePath]||{}}get $page(){return this.__page?this.__page:function(e,t){for(let n=0;nn||(e.hash?!qn.$vuepress.$get("disableScrollBehavior")&&{selector:decodeURIComponent(e.hash)}:{x:0,y:0})});!function(e){e.beforeEach((t,n,a)=>{if(Os(e,t.path))a();else if(/(\/|\.html)$/.test(t.path))if(/\/$/.test(t.path)){const n=t.path.replace(/\/$/,"")+".html";Os(e,n)?a(n):a()}else a();else{const n=t.path+"/",r=t.path+".html";Os(e,r)?a(r):Os(e,n)?a(n):a()}})}(n);const a={};try{await Promise.all(Bs.filter(e=>"function"==typeof e).map(t=>t({Vue:qn,options:a,router:n,siteData:ys,isServer:e})))}catch(e){console.error(e)}return{app:new qn(Object.assign(a,{router:n,render:e=>e("div",{attrs:{id:"app"}},[e("RouterView",{ref:"layout"}),e("div",{class:"global-ui"},Ts.map(t=>e(t)))])})),router:n}}(!1).then(({app:e,router:t})=>{t.onReady(()=>{e.$mount("#app")})})}]); \ No newline at end of file diff --git a/assets/js/vendors~docsearch.32565523.js b/assets/js/vendors~docsearch.32565523.js new file mode 100644 index 0000000000..fa6b64cc35 --- /dev/null +++ b/assets/js/vendors~docsearch.32565523.js @@ -0,0 +1,3 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[8],{357:function(t,e,n){ +/*! docsearch 2.6.3 | © Algolia | github.com/algolia/docsearch */ +var r;"undefined"!=typeof self&&self,r=function(){return function(t){var e={};function n(r){if(e[r])return e[r].exports;var i=e[r]={i:r,l:!1,exports:{}};return t[r].call(i.exports,i,i.exports,n),i.l=!0,i.exports}return n.m=t,n.c=e,n.d=function(t,e,r){n.o(t,e)||Object.defineProperty(t,e,{configurable:!1,enumerable:!0,get:r})},n.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return n.d(e,"a",e),e},n.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},n.p="",n(n.s=22)}([function(t,e,n){"use strict";var r,i=n(1);function s(t){return t.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g,"\\$&")}t.exports={isArray:null,isFunction:null,isObject:null,bind:null,each:null,map:null,mixin:null,isMsie:function(t){if(void 0===t&&(t=navigator.userAgent),/(msie|trident)/i.test(t)){var e=t.match(/(msie |rv:)(\d+(.\d+)?)/i);if(e)return e[2]}return!1},escapeRegExChars:function(t){return t.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g,"\\$&")},isNumber:function(t){return"number"==typeof t},toStr:function(t){return null==t?"":t+""},cloneDeep:function(t){var e=this.mixin({},t),n=this;return this.each(e,(function(t,r){t&&(n.isArray(t)?e[r]=[].concat(t):n.isObject(t)&&(e[r]=n.cloneDeep(t)))})),e},error:function(t){throw new Error(t)},every:function(t,e){var n=!0;return t?(this.each(t,(function(r,i){n&&(n=e.call(null,r,i,t)&&n)})),!!n):n},any:function(t,e){var n=!1;return t?(this.each(t,(function(r,i){if(e.call(null,r,i,t))return n=!0,!1})),n):n},getUniqueId:(r=0,function(){return r++}),templatify:function(t){if(this.isFunction(t))return t;var e=i.element(t);return"SCRIPT"===e.prop("tagName")?function(){return e.text()}:function(){return String(t)}},defer:function(t){setTimeout(t,0)},noop:function(){},formatPrefix:function(t,e){return e?"":t+"-"},className:function(t,e,n){return(n?"":".")+t+e},escapeHighlightedString:function(t,e,n){e=e||"";var r=document.createElement("div");r.appendChild(document.createTextNode(e)),n=n||"";var i=document.createElement("div");i.appendChild(document.createTextNode(n));var o=document.createElement("div");return o.appendChild(document.createTextNode(t)),o.innerHTML.replace(RegExp(s(r.innerHTML),"g"),e).replace(RegExp(s(i.innerHTML),"g"),n)}}},function(t,e,n){"use strict";t.exports={element:null}},function(t,e){var n=Object.prototype.hasOwnProperty,r=Object.prototype.toString;t.exports=function(t,e,i){if("[object Function]"!==r.call(e))throw new TypeError("iterator must be a function");var s=t.length;if(s===+s)for(var o=0;o was loaded but did not call our provided callback"),JSONPScriptError:s("JSONPScriptError"," + + diff --git a/categories/index.html b/categories/index.html new file mode 100644 index 0000000000..f5f4a704ea --- /dev/null +++ b/categories/index.html @@ -0,0 +1,209 @@ + + + + + + 分类 | Jacky's blog + + + + + + + + + + + +
+ + + diff --git a/fe/index.html b/fe/index.html new file mode 100644 index 0000000000..ccbfeff001 --- /dev/null +++ b/fe/index.html @@ -0,0 +1,49 @@ + + + + + + 前端 | Jacky's blog + + + + + + + + + + + + + + + diff --git a/iOS/index.html b/iOS/index.html new file mode 100644 index 0000000000..d0729b5076 --- /dev/null +++ b/iOS/index.html @@ -0,0 +1,47 @@ + + + + + + iOS | Jacky's blog + + + + + + + + + + + + + + + diff --git a/index.html b/index.html new file mode 100644 index 0000000000..c97cb7f8b3 --- /dev/null +++ b/index.html @@ -0,0 +1,81 @@ + + + + + + Jacky's blog + + + + + + + + + + + +
+ + + diff --git a/java/index.html b/java/index.html new file mode 100644 index 0000000000..59f3e412a5 --- /dev/null +++ b/java/index.html @@ -0,0 +1,48 @@ + + + + + + Java | Jacky's blog + + + + + + + + + + + + + + + diff --git a/logo.png b/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..b3c7efca3ac4ac17d939450aa853b1fcadb963bd GIT binary patch literal 88018 zcmd42g;Sls(>{D~_u_5^io3f*ad#{3?pC0b7A>v^cXxL`xVs+Z9Szyydub@A=?0 z5L+-)d)5zeDVc5op6Ig9oL=0t2rk=rnzbe%9&>MX>XVC1jxHR=&{^UdlJ?DNfX z=J5&L!Cu^e9|SQpAXt$$m}4EuSG(aneTCoLbjH=#yKZno{Labup0_oKa|HWC+ZE+W4d{FX{?x(?pyPO00xaRt; zIR2OzCQVdRvu5B)MN&wiXF90~z@v4WZE-@QqOIXR5Ki1P`}UfN(QIRE^X2??^8Mvi zb6V!3ZA@|a6N7?-(=tGZ-2qLf<5F1w{aV~1BO)DA%a16se=x+vj=30Y#iphC!TGRh z^O$==!2gF3rT|Yxj5gZH*M{HLH>#S}_t`vruEiqyHj$m}#@%lMHxsAZ_jWO93DZv4 z1BX92a|qRJJSdE~Pq$ir34@wMN3yF#bK0pMT0^KMR{Ax@OF-efIStqW#i7H2blx?r z*A)DM;bb9a3F=?Y6~iIydCKE0QHTpqXEF45^rff1M2>y==)(^ZZJa-m-OMI zr(JFWgaA}Q*r2O@=FD;VN3U||Eg3i?a(dMhCvX^`SOiW;u+k)@MbcS-^`eyp_HsLkpF)DAY1+otwQD+=NOClgHtui zPV_hq7$-iAuqQARu_i@A(J?H)2lXe1V-CP6eKuWF%seWUH%;Y6kQRlLO>ITjN>m|s zGPQ1ng(&50PMiu54%7Fx1abuVOvUDm|wAK5$fR0 zL*;rsdPRG!A35&OH_#&_zD@@pLIDRkOi`Uto$;M1ozbp%YT}m^h{)n(zEa_;lF>!? zQ)2%cl_8XAlO2-Lk`c`J{J~gDy&OU$sz@V0{C6aA&tNZakA9D4PxKGdK=h7ML>@eC z9UVRGDs4pqD1l^@Oe5x41SS8gifi%TVvRYeW9wtVV|qqLMq5VV3Rzv#iZERbUEhWY zYr#1mrP(6hS)Te54j6l0d$=>6Gp;l2OvR?6@Tu9Ouv_r0&$H|^)HA>RuX{ZE%0?02 zV2>z|_wa+z;@$?nf?bglQTLA1(_vv)gkNH zX_A!vasM;#Xl{XRUQoSaI`6<~b!MDt*RkXibLUT38dar`G_IS@l^&oczZ%i#YENi) zv7~b9cP8O+ayGHj(coFF)bKIUx%^%dQUkS^)1T9`okh9Mx>VC$GjWxMH9fLOw`iTG z7S4Wr3TAMrbnZO;+3MBy+kmUpE&6NZJs~5$0rztu{dnS;?%vAQvlFuG_py`#v$P=r zQd@p5|I^YM%b@^|8yAr4>b}RK!KVMu7t;sLhh&lo62BON7~3qjN%%>aEXFM6!Ins@ z=v9vMB-}pR+(l1AdqZHmf4lic)JBI;qY%DOgAlhrir=n(@>A9g)t*PfK|io?U5NW^CwWaG8gmjxIWU zA4_9LrtUUZTAZ%$$^_J#JOggAn{0%tP1hgxA08h{vre$qrYuAp_9I{|es9OM#ift1 zkA`wyYvy!**d^XU+6hdR$oL{$VllG|{SexMV2Onv!H(%k-6@Nxpd07Lz09f;x0aL} z&&F9G1h%))K0cnS95JJrO!s3Q=TOL4_@^kRB)gd<#6s;i+Da#=)=`+G(7`%xqI*?; zGpkT^pdid9ZVBr+_>L?lWiwbA8Pm>VNbE=!pRSX>Jb7@rcmqTbgSLg~=oQ(v*^V#o zE}z#?s)MRq{PFPTr(|NT5UaF4V?Z2MVjb^+y@URF^jc2)T)W`Y-fQHmIHtdB<=))) zzo`T4`~^%iY}Q)AfjzB119a-`+KA$m;+wt@bfdgbhvn_)4fN$^=ceU))~Q;YF)z?3 zeKATq6YxDcrJ=^47M|!ixICyIZ%AviI`8v7_14>`ykS3RVyxCtZq2qd+3U^xTm07r z_pNow{_1$3s!R5*uwky<&BXelDQ=T1!8&B@>;MF7(c}(+fkZs*Ra%(+@+>XN9Zuje#rV%hL_)CI=-xz~^TJ zi#AP;Y?MF0HrCZVJzu}vtI6lt?j{M231a*97!GV~22MOa4R#*-+rRifaFbN?EBnSe zSGOZrr>)OzGT5Bk$l4wWaBM5<*@~R>7!AJG?pDulr&0cr)+8z*VHD(ZE8kn{c0Ri5 z#9F3lUA3rR7vz1~Yfy_9$kX~+mC;P#aW}?!-tc$PtjcpkrqlUke=gmi3A!n3 zW1{VCM{zo{rw!=><2-S5vBT)8`&4wjE91SP2-J2m+*ci*OhPTxx;lOlaG(C#6eCy= za}+}l)D|iUJifYha+Gi!x=;(a@c!!0wWM_)zCqeBNem=?WZ#>Ve~W+dH5@iX?$Ey< z-J6eI+%;@M=|>arivO^qKRHm)s)addtre7Zo$#7 zJf~!ZJ#8*!SzjQPl_ukIFuaqB!qfi3DhY&oii=l`L69{-UdnQDa5Otx9nNy4oZ17T zaf>ID<;Z*MdeA21+`QXI#4ZzG2~P(D;IP6S*0kK9c^yEw_u z(c?`2UsHmuCfEP{tz(?2oelBMXMLzS{(ntBha&p_<4{7*oVaCsY9EDfbH5vsq~~dK zX5^>*)S!I+av^ab`B5`W0Y2zW!0bXX&m1YxgS&vvxtb+ra|`9ZL^mFwvp>`}j{T=t zyn+~5UI0h-Hj6u9{}LiWzv?kXrNn~e zR5pHYy~2Hq(Vg30Y;D%^%g)Qtr={XLdDyw$ufkvcmvJ~)*az-z9Y=zITE63XbIbkl4=d`xuZe`iDq@h@L@F0<8iv4751cd(?)oKPBHtZWN4+a3(i(Q0-T=E4}W@ zMw7w?%NfQGdlLlyj|Im6SYULmAlWa;3kMAaTo;WN3O{3s9;&t+4ErrJ2U#AO!$M~r zCn@q7b6G*<%?6L^Xj$B{*5SbKCTSPOA&Z>p1QzZA;#9r$kxv(DWAMgeE?D#@aI;v8 zb`%Sn#Ld6 z*17iT!2!+ns-qxGnlCIDf~p;=_RIAU1u4f&yjoY9aK`$$Lo$$EqGf{jf)8tqoS16ppal^Ac( zTJr_Y-Gz0NIMBBQlqK_t|6`*U66I3sDFVR4eAZd!cdG}~Yg}*ZBI5CBUu#qDp=Gy$ z*!yWQ25?MdGjxrj7<-zwG-L(=TE|XNI$>V{4kkQ*1)G0+Y9aS$CPM@k@U(mEQ!54l z+HY>QRBu9wwyJy__&lXsUM~U-QUgx&M*9LT=L_uk<+W(m6C>HJ0_wW?8bzR9HI^UK zwh`w%yWY;g(SdKX;O3yKi9Tu5aej;L()h*Uk}S&!*tK{KUVuh7F^Jm~cH)FScq$xo za*ltBn=C%mj3kEPHAfuUirx9d_-U&z2&26et#!L#Y;3_vM45#2JWs(A>vc{?+S z;Rq?+5|jtL-*dT*Q2G|*eP;`rNvfmz`%@9W^ixH&E&ns5qXd37&N=!o;==kk?|bXI z@kX?slcXm>)leSW`0TeU-co+0K^G9Fp@piNAij0>fa}tpECWG^VFR75p?P`Ue%mM1 zU1m*5>wchm7-=ha5FrxQMX}w-)EYCDVqS+k2(j z9P}}N8)9zD_j^kZEMjn2;oB*@YjmpX)@}G4p1s4oLFjEdxwAauE-ogq?Kc0!q{j{= z4c5FA0svQxS)5_{7}OM8BbS8-%~SEBZvK@{4DA}?*fiU!L1@PmA4Q$vq1sLDhSobb z9mjFlH8!1!o!-3V%Nz=HPe}o(AhF+eJc&W&W87lm_@s9h7vp%OfituoKL=7d>wo)G zjZl57{Uzq3dF_hwqm*b~tcB_xid#K zdXLNX;PD40v{b^Y3BfkVYBAphnHiRbp}2_XF(ex~d-I;mf7I%~uQSgl4qkSMJd}7T z6zgn7*8ex*LLKB_-RPx;GQU^+P5u37#)Q>q5{%f)R`%|BOjg@p-7Bs8vqgwou=8r* zs+;z%zRF}!K8UE}IVaG|7IO($jBJgNDlt6iBNUjd-&&{tn6{XJWOOyjraO@iteK1oGU}bKrF%Gvo!JBlvfIE8rLo&|o9|aoq4YJ=?Zs7He&q z#I&(X009pi&MX&-3%@;Yx3X+G1T!<@ejLWImuASA|JSj`e;pTcEOIU;Om=NanostK zgGoAu?U36|-ypVxTln#dGi5>?=dykul%>LU4j%TLuOpeP zMQRLCDF;nOP|tL$w$;(IBOd|Vf>EMTY_;Hj%R(3LW~PC))R`$AwoRy}hPjZ>u1z0a zD5lC72pu+2E(c;&qaB0oTWfs(f%9JIFA9rvw%+SS+7vs4E4&F>9bUr%jVc4L zgc-Ou+v&T7lIZ~(@%)Vh1og{dSn{lxP(f$M5D?nuJ^pxgp>HGT=MZ7)7PCDCP+%cq zZo^9Fk?I~EYtu*@$jj4;D$7%>RHb!Z%p`21S2J zHzpnGIpddIkc=oIlYzH=;3VKj*JuOjN5TR{bj*4i_~P-@1+o%?5lt`zy}e*H%@xk=@fJAIB+P!gfHf7#LU+#rCj`3+juq} z*k*d?8G5SnqR!{s=)XJC4pQ$)XRD*LRqx+*R=Rzkx`>c?n)bQ>gF040AKgow^^na1 z?;isnFSwu`I3abRk0#*ZmN75K*Vlav6R69PKimlLEjc6eVpaC~@<3d2fQ`2UiI>d? zSl_?&3G4iNsVGZM1})UtT-2M71sk%=ihiEL{f|bsughEf>5r25j)|PC^_OpBwU7D0 z0>YMy#L&<^#K^vuf z6?KZeNEQbI=jhtDuVGTD&}7oU!J5gbUS~F$G&_Xx5$!qfhcM?1vwQsSbCMG+-^Sr2=i0n;$HX0y^Pk2cjl4gt zYG9Dv1XFZO$6nj${oBjv9k7MZ1i` zSnjErh;H*F$Ls2N7yCfM0-= zPc9hAQ7(n>n;|S9hBJHlP6ZTU?=LfHNk`)*V$)fN@>SR%hO(uJr|8zGOWZ&d_lW3hb zeu_g=5Kdlp^Ewd?=COA7NyuSm(xTM&4y)agG_5s@0{*+0)>wVXx{dhmyXxiYK8N&oY+CoB{QC|C_-jbzcrwpkt z7Tq16octm$zSH-ICuW7G*8i3RSL)-$2FRP;HUy34T(K<_5GFfU&Rw|Oh+x@c^5q*- zKP4Wz%WgpoXfaujuZM2~r?cDdY)OnduO>gfBOWImKk0tDMSAm3fcg+$V1|G2#LO^s zD|*H6unr>>deXzFEPWe)A&{z`PtL*{{jR1{CrsSzl3D^awb^6wtGm-CNf`PWAT9en zH)eL2y5b9O#*eAu6WcA$ipIrQoFFA{o5EStBFT)4h<;yNx=E&+$BFZT;HnKB=(gQ`ivx(4 z9-KW+_G~CQ^p_arNK|4(WvgKSW(D^Dtf$a@|Hr-FaW~`bzH(k?DR@tbMeaYSlI~%4 zvR~NJay^z_KgKQS3%s%Y48)D1VO9v_m@O(<9ezbjYG5DfimpoQi zOghLANNUd6tjoDJwfwVGJcyj%2uH>#cnmoib~e9lACv-J%gdr&&h*08K=C8h?NnsN zMZ9Z4e1%15uWDCE*Dl9MWN(ek=a-!vSPuT?6ak6Zno8mQ?Leg1FVA9`AQOGL^E z1NQIC!#7L<*BgLHjLXa6%8QohZ^EIzD-mK=*PF;zQv$he+lcmqGh5#` zWSeoHE9A%qAY*UFkZ+c3!+BxYer!{Pa{}6k@O`%9AR+UHWwd5op6Kqhe8iEo;7TTj z5=T>cy#@u*Yn{MocRVE7#COFha6QG2Q)~(5<@P)p_wqwV!jBjQhk3W3akL*b<7Y}i zNSknM;{~Dv_w9|8Y0>|^jyMRCN<_Z5L=^k3h+SMiV)LatbK~I47gQ)MC_NV%sO=3E zt}d!^Fme!KM9hueOnY<@P)zX9T^xc^zPRU`rd>zBLRkZ~U<=Q4vOxdWj{Tsy5%YLh zgo=bDU0F}7HP1|&OVWcwGd~*KZ0WBc8EbaOYns2}d;ucali#~qEP|^NU{(}XXB+GJ zPO}8TzmnU_^h6d2?b;1 z8!bFE6ebl~NH?jIq`WjWb?@+PHvX6_0rB>!OT>Z(kx@QiiD}$;DI}mUX09AvWFn}{ z6gE3A4^$JMyOt_NJZJ<^Nn~!0tFQ0Fmlk#?(G8$*;M>M(A?T)D6FkdcOAw#Xp|?th z?%)p{&kfKSV#w+1=M(G^Hf)O1(2v1DgJ6h{<`QD44t&TX$@^QSYcw>~ZV~)4@@d4B zreg!&#y3?bW}w&?Kb0FA)?$3xeEn#>tgi1X%S>WCNjHl2HEyP^TMeu>lQ>JW6H&#c z$?TQ$Nb0tL2lWWYKYnz4!7-}T;U+BVv0C|{+@-U;@jJ3eq!ytNs^b(tgZj}rW?wFugI|r0p)Dvh(>sh#8YpQ73n0o{FaBTH)&@0?tNXS%zZ1H zJuix3^N;OEq|S2PKN6*|Qi7nXPRGZW+$d@ffpJ@$$Ls&hMn0E51NX;k7jv==`#_~Z z)9<#ENQfD?y-?uc)OzP7Ky#)owPah*YB|D_{o%aO@=H(gy!(5n_PWCMkK>U%bY5o9 zJXK!#BZD0&FfAzz{q(fL_Yyg$1m=6_$3JoAadP3VznBd(?b_7@PVB`{Oheg8?oS#s zOqsujg08XtC8eZdDTZ%MO+i?vBs$To9oR;cOYbiqtRFxs;J2ljq%Z(Ek8 zL~e6VhL#b;Ozdo8y)k2(~+-8dMsj;pq%6u*hOFhl_;Gr!H zs6027>^hQwOq8viyO(>o|eS z$!Zi(cVwpi==it^OkD5!_|S;#bJ3J#Tw-t{z_D6oQ!*|uS@leu6gW!<4QApdoOF7H z@IX+zUjW8uk3u0KmLM>t{sF#Neuo_9o3q@47iCx4D*N{p)>e=OT}k`c^*fp3<@l}P zd_GS}hufrH__LpQUopYknqWON+26cI*-KraW}5*6p88U*BX(t8y9h(5zjXfIt|`ZA zC#_TsN@WGg+rc$V%Gb9U34I~r<7gGpi+nsaJ9F7Wh>nS^MMecmriMWw)Qg$2XYKze=6eO zsh?k|VFk3aZ)C%#3BrZ!E|=y_tY+{-W?~g}kB=>LQ??7>b&{PMQ=}eq>G87hMxyCMujjok56nG6)4Vp7jVGWgjx+^ zSLeP$m$PJt-_d-f#Qv$v0`J4q3NMw2ybz6)puG5p)uru%zPxZsButNg4$SFQcu}{BJCHiRFzrYMy>M%(y7)3~FI17o=A)b@^+vEn;62 z9N{I|C&U&W)iWH3G0!=#4)ht=+KOAU`_aH$$ z92NS}-aC(nvt2jM4o|>7S#1b)E(RszJeA>XreGVdX`G7F0ffP;+i3`f zQ9!lbvH6Z6R5>W2(_1C&wWE_f%FWtT{kA^Ir}~k|VR$pHZ0<@xR%Ea%npMEcW8va) z^xZ0(cz(dVb`xyTPf|h=!$*2UW8Xf4pP)7cCA!pPn?llGK@_9};jyC(8U1>^uHvLe zYO#s|kyTLXbrVQi8@#FdsAsQ@5)iaumQ<7Xkr6C2BzjM8 zJfInBcSv_7dkT#^;_zT2mA@G9J$*S)=dDDG4!qLq60EU!iFP@7?=auo?h7V`Cj zP?oWoO+>Gz;+aw%D&I-AIthKx$IZ8v5&-L5mDG;~!I4Gy#s~zLi6mI}i|>PoCC_^* znVfOhXw5>D#@Q>Y7O+jIr4z+93YhzkuglA^7OGXc?lERWwZ8fS{D6;@nJkZms|F%_irI^klE^ITeW0 zn}8Zw{=`)~B=l1%7o0 zK`&*InVMRB4<};xDZ49tk&m$tC*oORn%`I2rLfg5*5*C?f!p#M!c|0E`)o@Y9h8iL z|I00{AOdlh|4GWXo0o^=j*ne?xu(kKhR;n@WEJer-3RB{qB{sfcI@g3^yxPPN$m&8 zrLTHuws>EhyGZc6lQ9g?N4KHkY?V5VEu?Ond!jISe&pW_JuB>QQ;zg3-aS;pE8o>s zx6n-YQ#TUydxJ&FA(Zq<{t#7MLVHIZNJiN>xdlMj71v+&Qu((GHT-BiJc1aP#CO3Q zx@%=~5GpE~ob3g1VHJoF)t!!VmO3scy6H`M^JWFe*nYWmnTR~@w9=EOZam^-Kk*2N zzq>o?P@f@EYMClS%x`oibjZx2n{2&mt*tlN^)mTP&u)ETs6H=594xDj>fQ~B2{c_M zTGwB ztdl~^JD%O4WJY5F%9khz;e;Q{d1D<*WOL?x*%ouwB|{84!d9YnJkS7kZLkrDk2OG-wA5Bfrk5o&ONz2P9;MNY$zmmlM06EqHRAtD+ zT0N;vWDbOgNRKz3R>qVW2ptbIVhq%5)x~+eI?Uf|*6~PZ&ILhIGL)8`7$#z5?)iA= zI&FLw1H2-v!;%)xP;5^;U#nF}&c*W`Y=4~ceO2yq4(ME~pox#6GjLpqIA(NLbGEo( z==+XzS)vwj3nKvT5Vy`!ct#)9AwXtYe8a-|W}*{(limF2Z1CvKWLimJ$o+J%q^;51!}}%H`$HQuQ%CI5`#_(jiLpe> zBY7Qp_BtG!&*Mp1#%d;rkH=&O25x~}?;4V}>?}#6%=xs#@rO0~sodm}3)qzAGIJWe z>9pVZ+SP!ZtD0C;hN;bxdApYIpL6E|6l&X&Oq-F{km2AUpz~BITWBzTYd0)yXq{(? zFd!f5lrO{Ya!%1l9d$IL&NFP_r$V&#V8BVuQ>{E8kjg6P-Hn&QxJ&v$92IFTCL*RH z^h?BbKIr7@C|90n*d~sFiv1$n3fG9EdcZ7e@fhu9L9K#3F0SL6GSd`&33s(aOj>2M zyX;Wk1X8KJNVLAA+b?8@BKMiYhFQUM6{M(X6TD%aeW91VbiO==>O@(#0DYBz)ngH| zwrFOHsl@)fJ` zgG!?d8`jqnp;%^E2W*@UEpEx}(kRTh18J-(Wpl88im*Uv4XE;1#&8z(YLMiAhdGp% zvF-;;;zQUUDW~|3W_tq=x4XrTDcA%=p{!(Nx|bQ9I=2tEUDWG$b?3VD?px1(cfJ@wqKu;IG=rWlUlQuRp+PuMW;a7WUA0xK+Ev4s;4)0R#z7F6jO9duSM zOfN6P9MuV${N~#!j(@AROnigIKGLh|C}qg>SG@c$dol895&<85N?xYC7h7?Fo_3Vt zXeO4`GROJz*>cY0&(Fs(7R!iRt~W^Z*?I&V)Y%qxBI$1JAgfr}jmQHL74}6wz;tLd zfV+men%X|04{+LJ2@89lp%x2Xk^V;y2U&z!{)qa5lGd=v*fB)q+;-|(=E2Om(bFSU zNV12u6pd6pq80D44)7djg_1G@%w9(`x#EC*(+e3E%D6Dw#hOEQ&G`Y;8mF07TYi9gij-Lyu+%DL?0q{7$ z-JX-t_ThB;0H9yL1I+tEKLW(ZocMk3Kme8#=@=~Lm?3FpR?jIwiXti+>Lqy&vIE$H ze1=g*&h4Hj@-Pw$g6;8=@Volu@4ptfk|%CM*ui)iiS7rW4K_5;UBCiOCA7qkq*rQ$ z^M%{zVgT3`?miLfo5)yJfma+dzYvw0B3f1Ok;~ppi2r^|%AoR&+ZvTL6xK`g5hL-H zweTvo5weU+`~zRZxV!WLNQ%yXIGWgeH~I{G8J${d@Bq_zwyf7kv`hSES}z_eA2NZ+ z%KnuIDi#)D6*C}gJL6QjRNdQ}eBw)Q$2pNP9G@&{CNp9##b|g25si@nY#f_l%FhDk z#GBFfHVN<4A;DUZf#Y)(xL2!F^~vqow-Cn$2k-OhL+W-}+i_0fq~NwKR6WO#dZ7Bn zB1Zy~i^L|@dIdNl1A8IUVN6qQQpe^er{8ht@sIQJ(})m`@twc{#LJV0JA zZF#P=5!;2%d~@bTsX>Kh+VETDLDV0Yg6I+?M0**wm$2k?3307fe56bI$=HVchr#RF z4dvX_0ZE39#R8Lor+FZYM8`ZYuJz6~J5}%L^k|V}ena5YEIC%Zjfa`Zy7S^mcG?nc zM!PbCf=|mcl4OYjLr2ElfM6W0xXhnOAd{;ipM55szfYB8G54C+Nw{;7a#-?oWFhq>n62qJ zanW-zohcM)zDoD)8+mk`vfG#wO&Z)|Xp(Fmq|}gqxw5!utERu}CRAD&;^n1uuc`6q zH{w)dj1{^id1j}pmRoj!vu{y-y6Ih-O86Jk#gIWmwaKrv|2T#e97Z?idze2=wI)>Y z>Int-2tBNb@8N?c72akN)YjG(S`k!HeP%ADR zvki@!bL=cCN?gB$9II`s_)}&f$5qyEso>AJq%O#Q`#Jva*LtgR^cF9{T{+kNu#&@` zcQA>~Gq^`_o-O9PKIUuvBwHgBnq1&AsIyGqUHCN|%n&uhpsZtT0C>m!hzZo&4?M7M zT`rC$v^|Do3xnWuSUKl&VzF=>D;^47VmH_MZjE&8fZvF0lK89%|^zoH*??BemiVXiCfiT?xTEK23(%hMkupuw8W-DJa zcsj(4`JqlICfY*(gX0u`E#E-rtD?ttw&j&v`yyLA%6LoD%|2V`kV_9W=?B3^{UeO+ zrP$1|DB21Q{6)Dj#bnwD)jz>rMa!VFZMp7t>0eLSKo-YPWRl0e`uoMpa}_<|kG~3t zO8)OYB?UO&Jhd2Lz+Vo8LSV=1aqXq~uS0@Kp<*oVb+0X1OJd`YP)Ow}-9={RmYFk1QN8!L!muk#kh3%%AXqC`B=1G(RAjwqOlM^Lmk+g5@1Wo{zZUUQq&yM2>yLZ0z zjP*RXN`;hhsME(5Cg5}JbAl3#s4V)76DyV5pE3$q(yei(Vp>OwOld;RC#ZduhcT*^ zucaziP#aH5v~cM<^E9xK)Z4%c!b@iFQ7lk7qOj{pC7bW0kOr)tS~&c%RP}KX1##Yb zV&DogYH!1?eyqiCPDpnwje=;2fYT5euFj0rH_DKd$PsMw-)f!-zs7C+4O)&VB$^BR zjDUXLoeu5BmfjPVLM8RXUa7zSbNhKg7rzX?1^Nz{fw;~NjfZ62T=?2VU@nK&0}hov z_#`2=WdSI{(Y(|K5u1@gUwtd1<(h~@Qcd`}w7=m#tH200dK7M8Aep1X1Bf6bF0bmw zeq*Sz&hD$|lV#YHzN@V`3+3NxXbIG}~*K>-WWe~0J+ zzQFW`kn2mdI)Pi(u&rHKf^GTS(0CHU&*bC)-=6aLcdTtM2}Huiwu+IGKJR`AvJ$w9era7a?%^YlN={q6MDrLfqdj z9wxXc&PUSN2D6f&Q;yzH+W_7}uD||!BUX8jkc??4_tBC! zSqTpf$ML4;8w&VLE1+=fq^B}$$Oxm#U8bP}*#pE*p_U7Q{R4qs{cqwn_puy5Eu)>m zJjx4OcCf~wGA z(N#OEv}_K(flCLTTw)e*gna#kUMGesbI;H?+q z)!{R^P!F^ZwGxF5RwQ;nGJ?rTwyQ(69?Dl)sK+QI6Ff!57CYD(Y=FISIArzSTeK&! z7nfre+5w3GW5sKf`ZpXpg1qJh^xV8}PMMDrkqB2;Ieb^^V;Q&Dhp#xdp(Gby`<0-V z>XHzt`cE}X#HO9=0wn^uX}@;6fr6<&xOTcGfVL6OUF5f;=&KA@ zo5&G2I+J=fJzHmYc=mww?M zncA*2G|R!}#hV{v^I)d4dExi$zo2QPNo?Ph(R(!X^Q6$JM6SI2T`(nRrBRSMN0F(! zGkN?ADV#{&OSB9r>vjs_uw&otoB0;Zt04SNlO->ks=OcZXn3-ag<= z>zRgb8yaBSBGsb6tq$P-B)^j7t$!=H;;U5jE2e;e51)8c`=5B&;W|O3W$U^4;TU1L zaxEo2I+LjQ+>~X9n}dt|J7E0$I#^M@^L#2v$$m<9GDF9l#&A=*TJcdW+{^4@AwE-dD>VB0iQu#>T zw%O*xTky0Se0LT#y2Z0w{N;S|Id3kr?#O{g#|8-k^fx{iZyhGF&um+kIqZ{a3P6IO z@O0)IHEi*v8839!X>~`XN)oMl|M<+2xGQv=n&2LUy9dH$Dl8)?m(AU$cyazl8e|~W z$!s+=rqXRF2Y7M%Qx^ia71a5~7d)-R(?cS(IG{aVi>8T!-%O`%RQ?@F^blbyAC9CK zq{Or>02U9odW&IWRytlZKw|j8dXd;UCr->1!B6I1gdRI82cWY6_LW)koW< z(MvOT29<-=nW9x35R zo~}hl7scgu?^r}c5^Mjq*m#LKa>whsBBW5qzwc$Nk7lgipZHDJQR>;Z>Hqzp(^#T| z=Q)^w=b5Ub+_kVyp2^2Zx(I85n3d0I5y;NySu@275%G#Z6>1t9(lx75hPr&1wOo?d z#>5hi^2L1b{e0_n1mV1#g=S0$cM!h> zfd5!2EwDon57P<3YNsM8IwfkTwTph{DrXWk>aRwo!jNYw%Elbsb&lY0ky^Z4qUe$Q z;hzE~4k$-n5KvOn(gPq|`^pNHgmxHsT-gDxHpF-SLBmW;$w_Q4^ZxC-^vOvU*RQ$* zB?2m&RO3}^Ip%0OESjNV90T*UG3=%g)@-yH>8Dg#p@N?C4OAOjqbH=UFL%Y-deu6{ zX9^G-50RFVi+MwA>B1zjXk-T&2teFmNi7u~F=CkkJM`+qolDHy9KF;bACPle~VzN6{zZAczGr&bS zf&m}0xKeE*jJRZYh{#lXwsKQ#$X?^NT4{$xZ~xxf)SZ^L&E6*bFwwRnMU_bokoHGW z&P$)7TXOMKW;f6udrsJo#scBS&A1;|VzE0>3135YR_;>ZZiydM@cSKpe}kyV^edtg zDA>n-&_<%lc1KpJ?6gyXBtD!MPp&_FjQe~rd71URT3`6?S&PJN+4r?nE`hL9QGxVd zA|HhawmiS?aWHJ-_21?EQIRF4UPzx=Q-q&de} zmnZd=8&==b%lyQ?C$WnuhM8FHl<2*AK5#EdrJuZ9j@dYEjTaA-re)DDk_xEbJFaWr z+YgH>5EO)&{rq+?Ic)O(csdKWroVWPj|NFmq(c!ANoh7xR8&$>I;C4$U?bIu3Me4m zEj2m^3=xR|qkHtmVC2Y=m*0J!d;f#;J?DEqeO_;lUr~=%#qpf1>IpPWUzKK~s&nto zb~i7pRm40u`EzOGsijnS|LO9w$9*>oXQ(_lKJ3ju#%tzGVUwX}nt?5`4CRA+14w^msTyQhUlY4@yB$uD$ zRF!-uHA-eh51E6Cgg;a-E7Ax`6hICIv;nMsk!Z+UY~0k=yFJ>hBGSNv<0+DGJ_HWQnFzvpDe!8g zw2_Snx9HGX9q11f{Z;Lj6i^k)vsf!IAmuKOu?hbX(tDdv^&TIeq~J}VTWhgd75JLzsX=CvIRkd8{L~(;o)bz zV1uOa#{gc)4V3e5XH(dn%<*ZjCV%&V_4O6anEq}Bb);9w5YM#a*W&(k;aW%nFXXGP zw;$(Eo$;GBW;}wds%WltK}2j8Nnm+mZ30Kq`u(@t1=W7|2|^hj#zHgbr4*mf;qGo` zt({KNFSbS!9CUN7F1@2*)@`aQiTo%vEh={M{!j;Q>hUPcRwDq20Se?$#iUyZ@fCTH zhs7JMQFkpedoeQP$N=6Q_`+xfl_NQ%o~@!$79Jd*B{V7Pe1Ot%fHR8mPt$JjI(_?= z*Kz_XWwD>(=iQ-Ya3fy(tMXXzeYFz9163$RwaTGzyS_5q)06lk1O=H!-qYw~uX*cI zcGbm3clL+6uSTromZtn}w|JuM-)_S9?~xbFf}Bs$RpHDIU%zToq2F4g_7j^>HUhdd*YuR@|mfkN&Ij(KH*v}IB3 zmp^qwOTgRD7Pz^iFK=YldOldG;{<$PG6{{t5HhA<()*R_GYj#2{b@`o@AxS?~ORWObJld!*)Wm zWzA_cD#$c&ocHo>FTX}gia=-`ntRg1%JSULs)$=Th$smPdsFx!HeG}XV=K!ufzVU< z=6Gfw7RXvuK^gdGFNEKTgW7?7TQXoMPM7SX`7f};VQP-%BZIx# zt!|=(Iv}LiUSdV9|2B7q26k;

||3)r7p%_+pcgO_lk{A5UScV|+W0>5L7;%$go> zsUO%rpHib8JGiD#&8=Mop0uJCe^2Np^yxRXn6}3r!!@YzAlAht6PXOuAmRo!!a}^& zPSBpHTK$R)vHtO6uZntE9j!~kopXd*nUCZAgfRA}I&b9<)4Q~E2hhteLTF6x98`MQ zJnta125%^!Ar!fz1=72+O$}5&Q)7Ho1D8zx$!z8%%H91W%J_En_Q$&O5%$|mX|IF- z&4a7@{dA}P5wydaPGnw@ZuF1aW-~ELfhX36X+TA`FEV3td{|D`*Iy_MODAp<>{eh%7+?!YrZc;(rvhP zdug+XY={U54!g<3l8HNyyq-&)EUH5Jh)Rd z{e_@WG_GT>Q!tvAK@loJRz=#<4sr5f0$}dHzpV&R5lx++sZ>BIL^xT3$H?a8!u*H4 zCqsjCg$0*2X0l0)o6{Eafdk_-#lUxwCp6QQDc16qKN0wtx39aHi%HxP-AOm?Z!Y;q zG&+Ih!t8UBdxg0)flpQ{<9z>i8c#`6r*qxtj-EfC*#7B*64mGmP+hP3TU6F0xl*Xe zP)Yf5i<+>KzBEEw7x?jq7y|wM-Fqg`kVm>^jym!Ebxlln^2KPl;)@!7aY~YdzY4$V zzBiLxdX4jCP%+|J?wuZ$qgaq~p%*5L{m(ubxP4;;&(bcFuOZ)(9L43G4T6J4xH?agbM1pcd~Xi{;KW<Nocku58}QfU_572?JhW-8)WAZgNF&o_byC$T*9n2fRc7h#TU6 zm@B1&R?KhGuP1-Vmf&g&iFvM7fV?T{OW45cUi?8BbYUl&C=9pabO6~u4m^3ho~4Yx zgAB&u?oSJ?w><_tb$koG8L`8%IJu_Co!;pD*K1m!hH?0DihBfCN3hBvM;|Xz=4Vr1 zxuRmQ=8rv*$!y+d1`6H-?cWLnXJj57>TWih)V#gJ`bJO!!J=6qMZifu4;;@#1rOQV z8^X#N0JhOq1q{Y9Ce6#Fr{8HSN!(|iy~0K`ka>MDuKy`&$3aiE{F?ur(aCVsMN^gL zY<1jIg?n=DXbjD=d%(Pj*qdcy&sRZ!sbsnVj%M^xf0KTe#>Zb}(|(Dr9Q|RI=wop ztz6)SMFoGda7ecsB{u!j;>kD8|)lcdM$LS=FIlnG-1;CgVlY^hIR$uR(oDDE*PwC%){p_^(qE z{-^K9vt_@lg~6Y8E1SQTSfZ2<^Z>NfMBR}ZKj`rj7t+>K&oJ-4|0@YEd`&J8>06FzC~9S6C?&Nt%@hx_xA!5LvIR z*#P*C1h*JHBF`JarTb3YY66gvdnY;@l(mvyM>J1ka9Oc1wOW(25HqGmTsfRSG5pGXh5>sHJ;~+iB#acP zy5P)!htBbU;O7iY4gMRN4Z;+Fx;`rXrC*KT!gxbu6q1S@S>&n9N0m>(z zt=I$_5T~_aDCk?Gvq+;5pu=->`RYUu$qn*q+QGun=x!gA>? zt#kDdA8_ZP-7kj`qsX18lO#X+$7%I$d~6RTdAS2{8^Yf>lz-&79eX5;E}V|4prcGi z^^hB1$votbO4>6-3w<~bt}|c-(%_3m5+ol}+lO~i8X~tQni0EtZ4zq3 zvII;7>Q-uX^v-&OuLl|plMPynN@#`txP4X*(Q>?mZMN|P`B_L)6wu>CmM8l%nvXgZwU%2#1*uu zWa?yQp6I;)${~hV$yD5bbhJ~I&-J)}E)PSZxc9d@`uSJ*P2oyMJp`A{9USSqaL^i* z?oQFoqnP5tlXTkt&G1+A4Sy5+jir(@%?@&op*UgvOaozw4uM@P5Rw>mE|ivm;wRXZ zMdgHhzoz>23G+~uR}Y4nV&3%0%LD*6+BkX&gfq_Kpkm>Tp4QLiZW#{=#}@^Tm@kkz zc|c69$19eu2Gn_f$MpWrka`rMD$7mrNUFu^&J=G{OlmZ(szh+!iu>)gNf(VC*@4X; z)7fnyiARsJU}AiBcr$wN~6c-K~;89ZkL7nN5 zF=GtXn&ssejbGX%8!k!7!=>2%UCc93F(fB)ZEmhSLy)-lvhM}cRO#>s84B@nelE}R z{8ox{c!jO0v)O^_f}PXaTra=)AZtkDR8=1Nd80L3f!%3uOagP|zb-(&gmfPZ zP+dHd>omi)viok`Q3PyfoI5__F{Bx*B$(L`5*R6ed2|nVv~8ZXZxw$;P(10Uq&E# zdjpPU(5%IReVE2q1H~-?27dfloi}vgTYb<#tH=X`hSy68j9pRs9n>(Ql4{msg<|J# z#>hx&!$@y%O z%G{bvi$?Y(+eUK5IXV14$(g>scQHoZWiM{%cub|0H zo&SUHB-J7{jQ(cQ{3^Ijc@uFiptB*LxBhXXbYnF%TTY5&^S7}t7^t>}<9bKCrlxAH zFUS*qL1It%Y0=<}4Rs}sp@Wf1%k4h+MDGlT3%RYSlDbfgu(Ru`B!^>p>mXn3i6rH= z@kjzj8B^Nig8mrDd@vO$Hmuog9*+S|h&(&G#IzHw0T1y{&d6*I~Pvtg?4;LeNJebwbD9e(j@+35y-@a@ z<;I{J=JhMa7@&}#&C5i0Go;MSmQPLFr@l^wx{yDQvx_4c(QH;&iFaO(ayi1o$sQx` zAf}fYGx--Vl@k&_EQV;@ZF(e!hsdeyo=!rQ08)wgTPMz)+YVxsi{`t!Tj{f6_7;h5 zs~;Xl`I~%oPd1&udBQs>$vEo@2o2$&@4JgpiP?**mMh`E?DGEg0~U8Ps&$M~CDT~ianbVtpP3*~+@V(}DXpERUW#rp>m zj=6^g(YY7Zru`=?Ebz!dHZqN&MNLa!K8QPmt6PWB$#;LYE`F`GVJ>%}f{@Z0e8@dE zO(>|T|K%!;Z+D)>ddpAzj8_S}Cw;K^gS)MzmXWJ(n)g(x=DQ+EabJ^`7%vDo<^HS_qnrWu*I<-8^9@5$ z`6_Sx&^dR&BVyYNSbp8G(Kia_EkjM`aiTJ@@XDyD-Jes1GeErOzJeS~`@ZCoa;}6Xz3udv`D8k(}=|`584C9y4zb%gQ0H_CfVYX7wJA zH0m6=UixCJiq{!vPI0SH8HInRK>&Sc|Jrn;{U|U zlt;p``}XKeE&KHwvJ#sNd+sKRfo+mw3dqR&C?opaY!9}pUwEsOYw!}z=bpM(5C>O{tmyv z`8>|*cK-$k5$+Em3R|R$Yg#wo_b}KjKHH)G@au1x3Kb& z4$@>F-@E{51)Z$3!;3ZU4R5Fp(BiS*(xk^N+WeZ^%r1-r^!u2SSh8kDuN8;~r`SBN%@;M!4ZA!la8DrZEX);3xzUc?$tVrxR zp+5|N={KP{QCEseOAWE=>_&k~;ZJ#UJv}Z=tluhq=z{h&-CE;x+&6trgax20EEQu;(iOrwb;KQ9<5OY02m^ubFv} zU%eEukKAkVcP&qyR#5k%+8)+%(M9KDAV>Y%wl{ys@@uQ|inH2EB+|3zSNYMk-q_EW zQ-uf+W~$&CgNSmlj#q>l=ymQdt{?)}*YpU{S!Mf;-B&=vT-`VU6&^{qBGfBGv)O~U z6en_UjA&rHHe{($;?hXE#wwlqNSebUdBGWo$lmz4J>_c}Fu$44@j`l0!iPM>#A+`Z zI57>IsWFl!sSD9504l?Z=YRf0NaS86LRbDZpR zn37o7Ya6><_Y@2gUi)N@bmD%bLoQ@78giL<%Uys8chS8%zKJc|{mThmEJ)fd) z;Jista_V03w|$NT(Y}f~IcI`b#AB!G<>wZ+?pWWbahdydwP!@(Kl3Yx`AVaFdf$eM zYhQNmcbRj`tntgGp^0&vLegHLPs;{%^5Tg>+<5;Qbcf0ytK0|^I2kd13ajVho; z`N`#K=*c}gmKtBxkXL8eBJ#^B-#iRw8x$eNy^u|@sSq4A|AtLdWhCBA!KYsLhPZQ{ zb__;{wO`p0taAdstHYMf8=x07^92SfS}Y%<5)7JqxfEb|)P0yG|51FU-`|0HX?>*s4_&RGE1%BkOw-B~Z=sYc6~eYckg?5p z-iF=+!WyDV#hP?#VKN8%d8jH4a}C#>3!!R!T~Dpb<1-(KX+(s^CWc_iRo8gOQ`>>> z=B>35)=X+U@Cv(n<;!6bV2T;&^FRysJTr?pO$hKji}aw(l5`%A-4P8TM>Y1xbyg2+ni-{w!oMD?9;V9E zZzTKtu=>evZZ7Ae_fH)>nF4EfCLNwTtwxlPfaeP&OBqgOTLmGo`Pf@hpt`r|C)|q@ z+EhK>-jnz}zaVaZ4f-$~A`E%-VdqB3@u?!@-qVzO7U3s7eQl5eoIu1txj1cEss#|P zvgVhhQfvNu%Xj0GcLbqrA=+VB-IQCSWc$ruSE|KHhG`op9fH+*C`HMKk!Ru^F*1hd za@}s@LpTL)1IWKGW+C|3`l+d}%j@Ea>C_7)OR1|lf!sqwcNVxR;<~8@0uN}*jd!^& zg;O}ecp)d9wuz`;Srap)t2VTijxPl_%VlX)-=qzTxztQCWvfLtDx$5HW}BxUP@Yq{ zTF>9hn7I(&dPkSV-;uxfe&X5Ha#o__`KoT>GjxrKev22sLb`J0y(gd5pGrQ`NSAt@ zsTJ`LlIB&kZ-Lpf?$X8yDY2ah!a}qa4p>8f3j@4jeW`IR5`I-amVdL3jY2JDm9Snq zE|~z3Ed${&%R$qx0=zVeh#nHTZ{kjgrA+&ZAQ-iw!iKKIfTAJRPA*n zQI>NX)&o!uBALOKCL`bWotU?GySb8}6@PxqINf44Su+CtYeHCSr+uXgTXlW?^YKR_|C+{TGxn>XD@mn~cc^;9XycL;5C@x;mk@ zXL+F4Xb*sJm<0&`cz_A1Wsb6l@w@GNPvy5kPyj>FBCQn_AmZ+)X^_WQRf`0IR0Z=z z?K4nFk;C{e>rA%m%SA}DXNOT%DyWKLdF}_d6=WJ?A5-LDZz~@D)OeXL6K?jvV@Q&E zA6ZCS2@Utx!#i_Z9Y-fCet~Y)v94RZnthrz?8AftBVkDysE~RN*63EwOhLc7wJ%Nh zlOM2{w9q(}6kYqtw*#}8mu1z&e`&tVek`l-{B4397%A1aA9{TJ;I~_?j9d7%w-2e*?2Y&#xGys3M=2CFUG|M!UmL==WKc_o2 z9)P@EiejhPjr%*TZwLBvOHz_P4hEPGo&K>}$V-9X*v9)dQrjaa<`4Re5=$5M1_5$2 zq##FOO;t?=XOvrLcE;MnN+kz}jC4omCT9?*zmc)Da@vO~z?HMgnP(rr<=)o{^j{Rm z4=&=^8m)A9MvQ0D+6%&1bv|eSUdJ=)(yqh1kveLJYp649*G>b-56JT_HLZ=%B2_L| z1zlxC;S3^`4uA#sXHcd0YukisPq3-N`)+p&xxqK61BIpagZ||)3TB3<*(+?jG%YJP z>qSz-VqfGP`^KmtB1xTvVs(alBNY!>k+N}1$|MZ*s`Qxa#w}~zQ@~U#CB>J4j5vxD z#6_%A3xE9zRS%Tgd3$hJ*(G%7_>_$yWt#f@a zZph7w{poDVe8bfV-{R3Hlp=E`t{?vt|G;DVr6N{}@qBDc-14x```|hwc4`a`$TVoX zDk!pHHp%I8lNY}02~e=zNnp)Irez{1=xwd zVX5l8vpT$SUq$+~P@I5^8Z2T8V-(0yF&5;B(H%%+oNE#6lf35j>b?svAc%`M=l54? zYHW=+_DR3QD(5tBM8q; ztKO9EHsVlJ>An|7NQUEp0WziSb@2JsZf~e~Vi7}Tdmebl5mxcGZWmaIn6VO+UxO3Y zT0F#dW&=El<*^s;CS$>yb?P9{51_&IuzIFRQjk(jGe*kqRtsZxr;{D49J9xP*;#0 zeS6h&RD>SSTwa2%C?-#G>RDZV5>HTfxizC=RnQN}k_vMANc?FCeYubFJ%1@#INoMo zBTcjUQMhSxEkaKlNltQKC+0#Owfm{!s& ztDs2`^6`9U=a`PiK@3Y5NdEzjO_j?)4QQ@$M{=lxl;gfCG{ST0=2Fb0Y$+hWOH!>! zc(hCp93-)(WcoRxv`M_1bQF`;c14xTZStK{Nk+KEHniSi*|@Yw=-!>IuYU<(Mey(R zi!slKDrf7$NceNAhV}ake0b^Ztu&pGP6_G#X(+TZa0`TPBR<#z4pg7;{9ssDh)psN zEpMBvck#EgEyQkLcfl_NGUD03qB%k@VgeGbE?BNaEIqA73gZ{)mcx0JWW`5al(9P^ zvx|C_&3=md$d2wx?-{Zt}m@zLH#(|0{L8n*}Bqvg#p9h%;P{*B$s}x zq_)m*{?vUZcm=d@cLI~KKp0TbrY#n|Ivk`8JGds-1yR(M@y7U%m^TMgR2x5alpA#Q z!!!`9Vkd$iA#K$jy3p5)NAybE@6!?$%D}!Y*XXdU5j4$k(WE{9wX7_vM{9TbJw8MmMbAf}s%H*ooskU#2cI?lk| zOL)>%9$}^ZDC@S1wP(wmc-!WcElAw3<$D8}yQ_rX+2e=S7rY^}I|=2wfqm2;porX$S*s^&AZ}E2QBGF1N!|Kik)_w3MAZezBH%`L5}pX+d9Bh1g3nV`oa{ z(CWbe8EICKMt0PUpsHnd^xF52nu9aeel$$1C~9{$l#Z57HZ$-jI@M!gUbMCBm(H@g zaXc2G`>58O^JBTT#}2Uya#{kE{z@zCpeJFsu;=Pj@T<|u_BQZNY@0{&*z$26MF^&) ztz|C9=>6^;yLzK#fHKOzN$p!&AWpq6_HzB|ownczIwpVIW?5L_;F?YpS9;Cg{za%9 z{B@8L11`^-ppPBhG^^0zheKK{N9X2J|6|#XdRT_>gJgK8uZ2GjQweL=@4}k~v|sW7 zsuu#l{CqE_Lyr@$EHjVdb`-bL(-7+>i{c?mtVpX10;l?yg7h5Qn9w(|qn8IoDlCl6 zlL0niDts$aT~+ zEL5dVc=77i!qr#8uu4dhwH>_1;ZE4q8)B<&2;BVSi^g?@sk*$lz?~;~Wjyp$5EF2i z+xo%Qjw&Slj3xQ1ICEf;UwU_uE=267+K6v=hGnF;HYdTP4eK=pmr*tI)RtP%V+~4o z$T)%$>NfR0pFC*g56x5V`L9=^I{Q6Xr4AoAUqkrTeqpwUxNW5$gzZX76l$%Oov-0R zTxWS+=sNrEXRLk-vX$*wS}L#UrA~e7#{KGNS-Myzsn2iQ$Oa!tWm#h7+`jlhLX+nd z)w2#g($@zQPVUR)gBXfUC!u|UVi zwK}%$gOc@02w`VAv7%$3jbzxX_NFX^P44}SU@OBdtKJUBd7#Qk&SZ>yn39O*fB{r+ zowILJF@HJ(ax~2#8%l4IJ+RBW_;0R|F&Ta}VUcGfpk=BV685dqV;r^qTi<_)x?;bN zcIY3+Ov(POP~x`tDmm|c_J|Tk3}w$zurv7Dqy$7hOwEhYKTqYjq;z-NVIP@7%v0mAN1p2wf%yUvvcfrWRW9vV- z{ERcwFg~1OyUpH6FHGEl*r>jiVaDL{8@hugC`m@9kuWYGoJ^@17_e1Vf|JsCe)Q>v z?`VcYmNz{W+bUfTr5kd^OkA1KDCM(fYoeTcGIaf|uc8!(&}7+!PbfZ@?2p~v6H*7zAi626 zPvBxr2wo=EZ>r(@sHo!th9BLWJ$?Y%f!CN93shn!{^N_lqW#_KlC8t>D*No=NeC@D z_rRf}-Ay+IW;yTpX@nDRiQ~Dd1dl9MJWtf9ix)ijs~grmBbpl^@Jj9&3vju zAQ(9&4RyVkSb;BkO*Qw<`d7tZVLJa&l`^&_UO{f$Y1|vl5}R$tP^(^Hf^?qfv4uGR zo<)=Vs0^R4z5X%%u`*6^4wYP|b#oGKmZMRV($K9=jj1qm=u4@L-TPGSBy-ifH?hzf zhVxm^_EvN6UI8^v=(zj!7L~SKn6B$uhern=-I(`rC{u7rX}X?pJfd)la<+}51b(3e zjlwfMnkk}I`W=CLciow@h`L?88$RGbuf)KDhr|>Aa9QMg5_P+zj ztalMmqNm*z5LVVgahtXBmMgAVT^K9mW(ZsM6?fEAK0{PcDnj>Mm01f4LENF#Q!-h8 zxsjDCN9Dmdsom@r|HP^t=_H#TT_AjjsPNqi|2}nJG3Wrt*1qq2x$z&0dwkroy!IOD zaUnOCjp16f=t7h)x>GCY*9GO>8atOKlJ(SHXr=1pilUCQS)dy-T`r4*s4$)_dN&lE&~b$|9UQs9GL zMkGjzUtP9gI~Qz_<;HjMs3b)~JuS=$#WNTm@H9XIJI5gZ~poT@aFgNu#} z&Xn5STX_r3T>c!&(mNq{J(R?Zv^hVQqa=0Y&|ctCm)4=J^zBB7uhey@vfqraXz4R? z%#f+h3B0aZUQ1Gh`qdf;V}wk?(!OhAwizM$xI-t>f&xMUYpA2bRPO`=QwfQ*;)c~o zqibyTIkmW@cn$^W+j*-rkd^pjYPB1wAppJbF$?|&{;Kh14{j!B)lX}I4PtYSe+Fiw(I3a)qj_H)UZ5XunN&)b@=FLIbr27ejNY9L-Mt0<3)I)+gZ+lA9T*AVD{(V4nsks2%mNj-2%-HBq9Tm8M>k=@w_Ia~f$ zzA|8?bWMA151J|Ye&>szwJd9BZX56h{SJDt&bE4!$6rL=9EQsSc*x1c?qXXxs zuyWX(6;2X#pbl*|K(GBJv)Fy#IdJ@WY6C;(x3s5ePhmuAMp%UL^;5C{PqOpMjSbMX zX@$5?yi#-sC!bS+jF+knRA(=EO>AON9xB1L7e9%m9k=;P)qJ(kH*TJY8b#jQRJZ7q z&!*8!wZsz!hF-d^VqxFjjG8kPO*;GW__4dPPjmUtC$5M7zNPezgdUF6S( zF81cbq<@wqA&aWh`>dhtyuwyYQ@YO2Rr1&`Db_ZJ0DP6>-Z5(QVdakH>JmH-c42=T z=9sAI)9cFirC`VCw8?{@G=6Dhj;ry+%hQ~3Aou5OMe3Ce>17?*`bQ)01Za@4hd|qN z6`%jei2d$qhSdg@h+4pgTqfbTudLo;katqVT(w=T9eS;DvOS*I?~G2eDB)?A+?~jl zAt&6$jl+dmdb6E*+j8b4JS>EVjhdY|2zR?tUf{_BF)E_G<(c1QA!A@pngd$+*W_tx zDE2>!XUeQ>xm}TUxXQ5p;M_G9Jvl6vvz}8XFZAz(JEqtnw_)R(k)yEKId2mO9~5Cf zB!%{(ovc>paE>2wRfZZ7ejb;#QJS8-tnry5Y7?M}bt295^A)yR@z`@$G)@A2n%e&V zSH#^uJW>vvGj~{V_1i*$^r7f%dOG)1Cq+E?T3Tks=b~BRoeVWI6`T$nGYg$O zAKKJ;%DGXaMIWagSk%NtX?9WuJJN`+^nT_w_y3#pJ>^KNx77WZakb0AZ|#?51bE{9=)t7BksChD~vSo+;*A2 zqrCsWhvk{)XZ6G~Abs|lY0Q+s3o;DZzZn}vRr0}cu(RH6*n3dF$$8=K9?8*q{TD;B ztnfa>+oHRV$+ebc$_+RzMKv2^(meH*C**|a74SJ_9|iYPu;5LzMBmlG0xt{4KY|=D zhHTLj_8h*W^&aRAk+k-{|BTKrnW-R=?Oa2q>va3<6On+0Dn9{v-9bJeSym@Mg0jXW zff%^&n$(=FMjxKr(%RO1AbS|XUD4qd2N}RiFRMFdm#ts>|FPO%A9B)AAp>~dHD@%o z>U+T0*x`P(^=MgMBKOE=;$D6K|9dktqXM1EYgrtSX~;@WtjH)Sffnn4B>He7xlLyj z;Cuj>NcCSjqwIct)OU}09)r0->lfgH_XDoGQZUH=BB!Ej>iRVTefrnQfZ18%R)x_VQN@(4=h3Jk{@=KOc<{yaCcdPdn-SL=<_BMxXNH@le|i!h?= zWf158$f!(eqkP@skjgi|+H>nW#E9dtTW)lK{3&`hPiAfoB%cf}1$G2g#8N%o;;Pse z81Op7TJ;`Re;;*iov`5<`D`EgkI@o@f6vuksNi-n+u#W^G5f&spX|aTm$E~XHzcFs z7np(AAh+qVlymh4H!+P`;k81tvdP(dG-Wjr#2dD@63G+Du{-|TbYW!Yn{<{jv#@Zc z)Q-UrZ7FeQ1~b@7Vkc}8m2n-wDPkKkZJJ(aP%d2itF!A!dZuB}6pFXcz&_5X?o=6j zylLXAQ@hhlGO8?%m!?*)k@|5RB$dzZ znNms0kESPG00$KBW=95Ub;}K02VyPef@Wt8TKgzB+FJTLNB^_3ypiZa{OdI#lHs>k z>ngt%ARAYx`7}hZe}dnt()^a+QI zu_jG=r7vZ?er@$SdD!GV3CmOZTXyk(ZNk1hrPd6){{ym~AAc~vemDu_i4rxL=wC4$PyP>Hxny zP$u0=6}J2>vCnwL1T)&D*K)fS)ku;mzbxeeUeGsP*z>L&^w)&qTNutOO;EKkPY_3U z;Mx1>`h6n)tp8|Q0~;@B4_pA;{Mza9vH>B{X*E)`ws+f{;tm#P5HyA*g9Z9c?=|p> ztij9-{MUQawObCgS{>4@fgc97x)3_T;hKs$x7gW!9w28Srz0$$$b<;TQA+VQbRKWp zx23X`(mfJwqPP_e&iaE)C>I{v2hS=n%#!s%GLch_9nUwL40=5Pp|&EDZ7_05}D*) zw$kjA0^f3rM`BY<9eDMSJ!T#}WAJ^H3h%GG+D^1|VJbO-+s1Uk8;Ed1eNnoZ7|_En zWjOUhRPhtpM8n!H$(}v9>y@g?K#!_P_REyN%(~ijTx8+ZW)nhmfb35U0LmZs zdanO6GBK1OeD2z`Y?!+OIBD3Ad)M6+E#mm2GUkHPHZucaoR05RT(e+3Jh%Xf*&W$l z71kGl|FJtxZK(=YQcxnY5b^$HpSWuFsJ6v-T5-#S{_)a2GSjx{5?+I@gf^STDtH8{ zn1aqYVl2kQZzkB+E_7kx0-|tX1vcu@IL!#^hWY1l{$k(N%l#e$Nj63Clsmd8pRQB@ zPHVt;l*ZYi{@~*ua+PMRR`9PW34Rv!ArEUUjx^`Z7L;e{hy`d;vPJQ&{r$!-+Z&Tt zS|)*Azc6$Io1W-4&4t`?8>*1lFs%=_UK&4GRFJpQpxS2_C}BQzJrudzyMF)sds2Y2 zjP7GXhFtbr@v+fI%w$Tcj|Erj<(}ze+MSg-@|qN7?cf)Ym*uWkD<>vdicxIdT)Wlc zefPW5?FV6|buMMsJ9`vAM0)xusD&rDek{(x&agx3(&`llh&WGBQ(>=9-ac^KELk0aVaFNrm59-qfM{ zRsa`oromvE<4n>aaw76xO?q?24&L}UPE$;XQ`W6#`L2qMs6_v+;B{5rzmZZj{F|i} z7-M9iH^_>Q;SQ>|)KlzgJ{NKAW$9XrXbR6vc~nF25)HpNUq^l)X@3WtK^Kk29?b9BWpV4Jb$kok*>meaA@o*SmHy)q!T{JBzCL62q9OPE5 zyKe!*S9&H?2H?<%W9AMV(Fv5 z)a0;js&u~Zd4cubb`MC*2x_+H_iP*^yrRgCWbBgfDdE>$`|&)?<41brE~$dY#Gr+1 zH=}ZWxyf6dYk0TQVKiVKkVG;xd=Lmhd#O5GDphb41r{EuD`A@kl?S{DQ!{e*VJSv; z9kY(Y6=xkU8{vU^XPuYTNHO73KSsM3@o3Ucy3lIW0&}!w82OO22t(y$^r&!_pPIrB zLaWIDrZFY(W0~b&1Ph5i1*+w-9R$YkWKDH7VgEN+XQ+rS+4!WKy|;=qC=*; zc1{0jB75>cgGalY@@+HNq`@|xr$o0qjIoHd{iF+%V4&mWm3?dOzdec2osXk$wGrLv zB;qx#^fP_&+(B8|LJb>2T&i$V*?qs;6o#ZLLg=!$Vtsy-9Hk8-bzy6j!}bhoC}=}5Ky z!b17p+X_E`by(U~s%wQ%@DYw!;P2)%VS7+DPVz5gixILW^+`9vk$Y{cbId=NdWsbe7$pww9^ zpjbAK(V~xK&M`>{r5e^YF7uW*JgFmk+GU_ybeYmc@t0GJX;!BEG`udoGT3MuzR|ed z0y}c#+ca3NjdAP}J&DZCyAcK#7eRQm4h6{PnqFt zsT~Vo@JyC776Y!|+q)-t*On8}R^MG!&FgT|-Iroc+I^QzEOhTMDWPa%uNy;(;cW0= z@n&MPp3m`n%CSh>X!L2Z3dz^?R+VBJ*b-}>qO-rK1*gple{#>IY=x%&u$Ozuh$2*I za}1wobO8;O>!$HL4EKzAB0QG-JkH!-*#MDAFvvO`BjgJz355lHN=#_Hd4r;nBB8Ck@nGPyClghohYBV!x&$%)faxkzhto)vlSm7ZBe|hok8qpMD${G8y-!u@ zT#W)7+Fto(w!QFE3AiQ-e_r%Jje;KV2HerviBX5 z!|D5H@`}0JGrb{Qq(ALm*Up6312Tyx)=1UpOQh8$!FaoA`KxfBGWwe;6nHwTu$F!+ zlGf;dc=`&zroZq1jlmF!sep7SAPoXa3>Y9vypa+S=`QJR7^0NGP+D4~yBkJ1y1ToP z!C;L3;^*=B{r-d3ecgM{InTJ~5Knta%Pj3Y@e@9d*R|)=t+5s0zRFw+%qJ&FGW|sm zOmidPL`!wVjGvc&m2JoeX*p2s-PxOpXYk&kDODKueJ4W{%3RJUg+~i&aV${MdkBBC z3H&?#PFPO)Ww1=&ayVTHb%nj?pU1{7^vj`qJnncmGlrKF6Lvy&V7Em|opZ=2>z}@$N{Xs39ZsL3f!B}i_ic@hLD2! z0O`_g zM%OZ8*Hd>f*XRG?W#VagJD!GDY%bmW$B<_BT8|ZELNQzNM=x;HcTb~ceq3S*4O|*i zm6Ci5bcDz8f|@b?7o=C)8HWRKhudUfJFY|jv&OzD-+`&v7!@cdk}>*Bdeyt^kR7EO zv3``gw!a72xH~~WH2dWhufd7ojq`c>5{`Gnb3skgd|}oZg|#!!^?(1Sfcc%}K20oU zR5>92P`fE`c4%G*BcH(Tv-?O{w>?zG^zVuWKPW_o#1L03G?O^&0Zxs&DyqAh>x(mzx2Ed3`b&1!DK>?@oo~8gz)Bh6Gpg0naEd5N!w6%2V9N;{I=!tFY)d4 zF%-W=%^X>Jphoy&tI^%6e2&WX`r@?wJJV?S$iKf$w{=u5ejnIj*t(u=etK%igR*&C zZ(x|+puczObMl2m$P463n)kUf2;^%H6V?W^b^Rc&8t4Q*lMa6kgIQ8%kB|uj{pW#+ zZ^$G6#W3lXpFjIN`nBYvqN}8IKHbq|X8m;F!*402j9mOE%JS-&3cKZ`A^6J1;~)tv z9E#je5~C;^%zz9n+bs`Ox*v~s%))|*8_-32o{UjC@q{((u%ocD5Lc2aBmjp(D*D=z z$=J+Z%r6^CtbKNF?|0SCb=!196?2J5lxa&39sd{E4(FW@dp&dBD^}$Pw%k9MnjEK+ zzAt-j4`=3otRw}{x~!Qh@uH=xFBL|(6-31zpH#s+M9?*zZk8|^1edfd--S~u&C-}q&Jl2d{@32CYebPy&+My@OJ z#njGIFk0&+%{2IZD24`wXtnY1>@|N5Mxhh9pXob}kDG*Aw}?`r3-b(!-Xnus-Qp}d zThSO=))(9#q{oQRKWn4ZR8{J29YeP4V2nfcpuce6w6+*R^mpK~?Vv31mIOOUPVNOJ z*kaJlq3K`Q3hXP_Aq>CjQT2Boc9htER`IW>?;gWagL$9hvbOx}#O&6ty{QImXUg35 zwVR#aoR8*Qo||Mp)f6G^Sh zEW#a41rPG<$>M%6@9XqWLvPTf6~Hm`J>4nigv=yDIEEEsgM~}MAUttzpqnEP|v1qZU$6id9|8U zg;ul&_7mbx@h)HLR9adDNUII~yxx`+%}PX)f!qhPMjW$aI%1O5ALY^d+R|ktmEfsi zYN1a1$ds`5ZYsxwm0Yny7AXPI8sSJxOg=)m?}=p z52qVluSTLjeeDsql;<}A4v4qh(Df>MENa9PuT@EB%v`_Mu5?#EU;X3LS7p&Hoxb_U z1waq)MFL^q-=?j*yPn3?zKrb zE`Q;Dy1Tn;V~(>5cGo=I+4ekf=qPD6pK`cWNxI2T=kn1SuXYZ42}?OX5_fRSecNk} z`J?V>E1?>22c$cl0LLob07r{?+-oqkEGaIhDjm2O1gPj|XF8Z)b(LJ>I0azOmI7`? zkC4gm|CM}>KcWmm@oEx_iLXvtlB5E5$9ltd$0ah`iBXB9Dc;A58%k$(T#ePcsev98 zF?XW4M_cea|n~dM|lcCq5JVODo{$A1_w%3^Nr^ebSfnYtAdp*x)*qvRy+|xVP zGT;m%S>@U#AOq~=t=B8#H%>yDJtY(82G zoYFN3!v+rPzrnpx;BaBldEZJAogMO8)~~=n6>FvjZbYZGZ7J0#b)j2ut+)2sdT0%RXhbNs-VVwa9PU zQ!6d0T#nhOrxMIssnzyA_}e3eJt!GY+bUC<#3$&@CK`y)5_*{?}R9`J1K z-#t*3*b*BeO6Fp~#!UW$aifFN54(t6X);b!aH@UN6tV%>NN%L+CJ6t zV!qZn-shqP`FD)W_z8mMfwH>{5XVSFe5iv&XX|?tQ|WvVUNA7XmxHJ)*F=DEprG(! z-kX$@S2`Y)DYHgTE0KB}*nNt`05>}6|NQ7dv^{J`S%ce@?iAgQU!P{AKV&+MaX;i8 zYdxDh9^T;RoEr+z@$gOb&PTyX5$hG40^)`*cVU?CjU)uFUY|m=Xz9jDN7Jf7`|C*? zS!;pq^;2K=sZ*e)Mmd{loX71nO?x>8cD0;`n1O6p#d*AC@7ADG%AKvaH zB)zJ-%bog_?R&zD3%U*8xk9P(L<@c<)wFR+lcy@Yi&eERbAJ%{c~r02D4XF<2i5$+ zkW%cXb-if-(3E^_*Fu5h2H3NGGJ3996ioKS(zB0wo)7g?4=08Z_-*3wl+Kqczw$(f1Qb{SJ}T1<3+ug^ zWSh_|1#o%dy`_vT5X|JW6pji^K}Cr7ZwN(&T(FTR%G39_jRTpS@O*kZNqG|=vD@fB3hfztJ$uJCY=ZQw{!T0br%4^mG6sN6Z$N@%G{L3btZ z9+M)U@d4yF@vlcQ!9J%rw&lD4m$I5bQgw4JXAofLpY)MCH*)ST{@ zv8N1YmT-w=&^R6qNxeH&&WQ&;DP0J8HCKN1MFgC6Kh4ePl{oz6u2w33#s#S9jiUb5 zeDMaZop3R_t3{5bjGY9mm}aGe$=~a>p7N{dZ@Mr{7%0^GPpf)GD%)Qy4DT&V%^!SM zPI1O*zQ#zLCg0(daSg=Cr%&1;S|rbsMg*>3b4X7v@kshG7PCp}TA^bExaxr#%0D=; zJ@1CxC}`h)r2{R46ee{ba)#m!SBhQ=e(zkZ~(rO z=Cj?w*8>=gvNDPO%D?3ag2O98?P&HiD;`kSS3+b&B#`z21q=AMch(0!7B?uDKp3J^ zz)E;Er{fxyM~-&7FG-HyWijsBI&tb=N7KaYYRXn>n58nHetqhAo8zR(dO7p= zlTm@M`KI)Y&rtKm(sessZ|Uu3X`lN^9gF4$wabJ)1Fzg{1S!CsaTf@n?IRP1Ot9=T9vJe)(I)Xk|T;>c4y5brY80Z*!jS(Ztezd7d61d%m!Ay#UaQ zf7P_YvULR9#_Q&3OKg{g+{fu4B$fve<@>1E8A-v*Ali9l(siuOk_2#l`hwz?6^wYI z>`qLgy7Lx$?$fzldKGoZVIy_fH7w*gmRWCIZ#(1MoM+=#@3R+wyu2tmp=G2*(BI+$ zp+eJvyNaf~1*{3Nz&8`XJiy}mT1&B+n_tVFkG|u=AFkrg7a|a20kCTMl-l`bVVaxV z$09GbFo^nj-jKkT$BjA(tfZaEDkWN^ot6}hFFotCAJ6h$agy8ItafFkaUJT{H_aDW zjvJocoW-$A9-46dj9J9i)OHCHXAl{^BJBoyq&c0D%s0W9=Qv@*UcDM=kNiC|X|RB1 zkzTkIv%_vu3#Xt%(N?9CDsyY`7p6a<8MrN5o{=Zb%t}?yy#pgPCk-`XK zRGx?DNr1yk{F%)daOEVB^>SKhue6UFU`1e;*EZo+Sz*geL3WRXj=3Nn4b-?v+R+f< zGy49qz3r!{!n|G=%?Lr1QdY0yeXXlR^N@E01~b3Defya1aczPu1igAccV6MJ$|8Kw zA(G@hk3K;_o!Yl4y?e7dVPNK`KNK#D8;z)F zSYk~5JqEfbU9ADAzyHWO#85gn9w=wuR6uH-Dm|Cum20#(#ha@6iOsaYJaR2%VbfO);8X$L!i93OIEE*W_ApR}HK` z@bqvYTmIwA=luz3*s9#P#=i~Rvxp0z!|a0H{kjg28PLFDtACcXK@B7_jzS|rkXQ{> z$(Od}m5evj9EY>jg+=;}!mqLh?-B=i>0)}_te(?ND4N9DS@&Q3mGm%WA?zfZzcaSx zGx;e4-plgJeE2F!$KY}GvqGa%qeZ9dQ9nIFCY`>NKkwY@8ljg)1do1l_L_zp&mFBx zyLCRg2hg4JWHq0>k9G_1UB{FEB`ER+r1l;7Zge-|RhG6UO$NPUi%lv^wCxWuRycjs zRd5Rz^?7N5G+PHS%+Y?_`_L~sf%9-l5yP3p zE+Oi=V&&r7j768ueg>v)o*_51yOIeKLPXYRCakr(~8;z}^)0K}GR@H@?&MnECY3$31ljs;@D zBK{E3Mq!5{x+m1J70grV;(#uqN~*$W1_G&>PCW}BNjKkd@}7G+esy-Cf#y$2=VY7H z5D}!UxNi6m@%W(R*?g$bS3xuOjDKVXJjRvd$*vfp!q&US7j45Ax>FL;}!0}}gwHSb7P)Xo4QnhJP zhC8umi>?_5!liNu0T#UXijS~wFROerlp61rWjMRF6`iGXZi>MNX0X@=lZ64iktG z#&M^nH-}U|SDM9GG#h^=RPe;KrAh$)V@M&+Bj38m3|0gBfCNPRwZB<<1t;Wge37*4 zw0wBf=!MxVLs9wWVa6@XhFX9=5CGVR-Ynzy2|lDq-3P&??ldkFxUrFOU*8J}<25!G@I!c7BoyEak?RaKG!b4Ff5t@UUw2%G z85HmPCr)@;-WtE?%V<#eN2@%2dG+c;e{3O$rj7rE3jY;CpBGM$>GGrNd zBi&81_RW$U@LVGLPrMdD{=rpM{~~C%pFg8OL;m$;uT<0OC4s_)JYn3Md0NW*e{?xz zIshMzCY(eLXLv~ii5Tivw(dP&&pO)PUe5%3wz>3Ak{;u;J8iFU5AA;!YdcdOg~G=F zBjFf7gnZ3P7~`mUC{jW#IvoFkX@Y^oglT3HwcNadN(FYo*+BND~SGO_sv}RPR zYz!`pokQZqf7CY!C~*8YCtZ(sB>h6GG2TRNM8=$9_gj`d%3l1EL921^*VnR*ofMj8 zlT{1J0`FU=!rp)>rCy6uB{N$lyI%NzX#-&wiuJ`LHE5w}T`Cv|pdVS!X8{cGJ}4(#KodIVN6n$M)6!{)a%= z+@NIqiK;jILvd?g;r&R{&pO8ZDg6Mn&J++ANMm4KrnHn}?oN^?S0L9rsiJQkT=!Gn zuCw^200erB^_J5;?J8A282oR=&?$UK{MbcsyF)0CBSv#`z~f>x?_q?NBnN%Ic}8~4 zHQr@%PEH@j@VsN=GGI*^;r-$89_*}s$jxRItlF1Re*mybEZGd)>8uy{zvOn=koBf~H=ZD<$|YW+_NK8KvyAo{q3>NisdG-KXYg0X zLflqQO2Pr{!Z4VO-53uGSjTPM50VgZ_VTt=P%8Zw^}V;&ji2JN;@iJk<>vGE*H(2R z6DEo{<%c1|r4__k%=9votLJl46-78PKe~M>|4c|9Lz+C*Kcg76K@bL$ck+iPF{CY$ zjt?&9znGjpger%YidN+?o;{FWAxu1=*xqXuCVWha~po#K$IQ6SHI9_JEqEWhM6rL$x=LB9=gJS{Lpf z7n^%UF~EZG4Hs9ve6Q4*!UBUEJX1Sk?i#l&lQw3L-622zRF|WB-`_jpuZS3&r{S8? zCT-e-X#_-g6S^pLjf|!rh2t3+ZRCWwPbJrJ(N*bZS`ISe>($JsHbVg8QGD<#1!xx!If0f2{x?Z~53x`$e ziox&ez$TLR&i9DwKOu+n@z>6Vn;!v_JS+%9WCFhVCWJ}ftRDyTxBpu)scL(r&?k^& z(OSZgLorLc5 z>jYQlD-=os=;-qA&Jt}_;=6+fmbc>@)Zf<-GRTaf<@Oi}i4mdS+5hB0{z!~tx4PcZ zs#0Ti%FYf{oD5D?K+^<-!r#%4a5l3l@71o-WGLsq@G$Ge^)jS40V$0#c&<`nNbWuQ z1kXS0TiMMj6+tO{MJxLiAj`9aatAlRKo!8k$1|;nptX{3#P6abna*7GYj;$zk0t#u z@sVfUGyyj-s05?es-zG+EwJ8(uHHQ&XZ-O&zPrm@`x>=f$UK~62z9t7@J6nA`xl7m zKH>{~Qu+=dPJ4Gnj$4ZWUgb72bgJeqxqkHK)fNwFV$qDa|5fx=-81OC26fs9!b1CG z0f77Ff1gYe&RL8oX+Cft2%T6-j3qh(h_uSV<%JYoRb1hE4V%J}g@)&&k@Hqm4E2=d z?xI9Mip6z5_BsXTe-y}jAy%(~Qc9w${jHZE!<0_KbvEy!+T=la{e;*4PG@SZ zI|%q#-FoRY#7_r!q&y<2Boay+;iRxdT##S6xxRs9IT8BS@n4PW+e@TsY|y)c8<(wv z^&etP_n2ml;mjFzkiQ>#UR(}3Eq8?J5pJV(`_bB%Qn-r$e|_3-mXcHXmX4KL)mpA| z19aS3q_DLQ?z*9#mM{RVs{&1!RRyVk$ZxLojiZvhw#Abi9^~}PF@T+Wae;WV=;qUN zEHMsr1rRDV02JA+L5I5*1!f<6wc77Jq)L`auc5JDZP<8>AcMDh+65@Q^nkYnILu_o z3rrk7b@NT&wK9+`xq3YCx0x)eo1ry5H^K$##A?Mw_q5VaGiAv#z^fa+0^RQ$zsYFZ z8+g9e?UK3E5xyBZ3|usSQ_J3WU~;obYRFTl0&B48X)=ME3JuGOk=2Cq)>_(F)_&#m zUZ1hGq%j|A83EZU_hiYZu4}*h{L29y0<9;DcWDyP-BM(nT+l9fBIb|!am|8)AdD)C zWc^_7W+hTVH{^HTj@Pm}zyHa;-)V2u3eEkJPb{e4&TT^B%l@m zeUKev(tEF3D2!-$$j~C3Y<|B7wMRr-P|MXJou6QSL+(gE7v2ui?l>I zEE%&fVV*r3a?zsK@x_~dR;Q~Z3b}u>AoB$&R<-TR5C z9Fk`mevw{bxvVXxkNw&r;<;@(jEd53zJ6NCd-ac=YtjA2=-(_MI}_H1Pj@TnCl>8meoI;9VmWL7m_&=;CH8`@yrITk1-%x%JA@sc0PKI{| zNP+6T2OV(V(^Rq_{5xN!GBmX`AMY`4;zUv(KX?)<1QzEIpgR#UtV?N^qZlmD|R6VzmRy{(hppfJ5*=F>OAu8xf~bnRzpxjNf{1|P1< zk@NQ21Fqg!V`Yo0+LwI-a3Q__WmZpRmq#U6gr2@2VTBqWeb~KY_27bw?r?P_+(ZFk zcX!8cr)$oPC!al6lh;1#Q6;Y9s;VJKoh=^+F0_qzeZ|XQTxMTZm!He0i(_@&PCUX{ zM8RK@nO(4ztb`_n9%aUa=XRSj_q$2%o~GL4Y66Z>Z2N%wbA_U`Y__9$rrTFWg>`mw zN4ntF?_WZkrn%6j1zRnUO+}kq$2uXuBAi6j?#OG5>hok0eC4*rt`w@)NUg zH3=Q2+Y)BZj{1+r?_?U_+uOg*8FQxj86kGLjI$%&uIvoD@jF}4`Zy#n{2NtrSJedU z&t9lcxGt1lg(ImF9gw*M)d_`!?{0f6m+)vO_E@(hafikhLcbv{@?Wr%h2q=iK#eCn#hzVn z%e#wM!+j2JaitqH2?6Y@3MBY0Yqe&^);CYck#e@SzhMWnzk37$TTOGqDOQAPw9=B% z(^I0*C`-d``a7mv4p$P?Ga?fs?(yyc@A3;Y0dqRv5lRqU^O?`HOIKJ^JdYBte405n!A5t!x(Oa37vT-Mw_H?Q;ZV}`;dj>25yzQ zOXzunt>k`@JZw)J?AGof6}h$&Gmd~TR_Gy2+YqKtAV{CJx*m+DCCuIv8`rj|B#xsq zXq7IMa<>Ltp-PG&jX9jn4!)>^Y$ONB?B=XW!F+ z24Q$FkEiV?p)CM#rYmyb3mu$CjmiJs>pnS34z+^Q6)mbW(*;5y;M;N8)R)gwLWVfF zRg1pMzi|&;5xX<|gyA~N4Q;LrC;M-e6ZrX`E^_%eP%7OOa7Ey4Qwc|^`qipk$ zXT|&5BSIf_?US7-7==}8dL;S;+4xZ3&j-naOyv**5>YV{qiJkP~{9p=0C4IYSMhPWyx~%#w`_(C;%9bi) zW}PyWt6MOpMBzU5i188kK}8;IZfIfjHbYX&*kmn1T3bNUY2lj^*>q{b6DQ_5-A6kq6QeVyg84 z5wSDFedk4U2`nynZ&QbTew!Ia^=;S^B1{7-zUQHsA*VcPYdN;?TB-H%Hj5;}`$H$% zWNTEdO;}?E`P#c1CDm|nnb+)6>AoP@lr35I92q^+q!A!@a2#vVC=n$#N@82YJQE>A z|5~2xfju)n!$r+SuHXg#f3OQ5^nvyney5oj`&HNANTwkTnBsEnCxD2q0s#IM2Rlol z0b1nV4eaav0zu-z!Y&`6wf`jX8pbb{`X2wRSeeHZdOkdBiX1h9nA0)%NCKiJjJB{l zAtX|>uL()vKl)u@8e63Oe6otzH;YGREknSjl(N2_a_Jd*@>9HB7+=&}PY}@jV^6QjL$**p!SgwOV}hoTwm>*4nDgsI+*8Ct*N`v`sp7 zkrdBt=F81)NzZiwtP1ad5-stg0Os=%U2OhwzdDHZa#yt!UAw(Oh#QqHGr0qNei9;} zKgh6C5& z{$;P5;IzxA_%-&!3d~5$sw_~duO~(?>a+Xy#sG9PQ#B2LU}OJVQ=hgJNp)rF+Hzud zmd$Vt2^~DOBE2iuwiO%3K-6O1kM6XvufCyLu~1|M^hrbNyjbeINmxFiU6yOyX6)`UB*-(R$8R)w<;1K1ok}*Xgxxs; z7}=RXf_<4$sS=fLw-uAn?tH4trWHB{jeQPG-80oolAY~;9G-lxKBAjjL6V)!&l7Gib3C%AV%-DWUh@Zl+l(g)`8~q0_rKf1{B2LxapG(fKY=VYT zLtRfBZN+xfrID%}QV=>)ZTd~MpgdhHcE(pJv#@ESZ11RAhW{j|w-_(j#Q=M-@$2yB z?=nv|gB_#}Xrkr-pb`9$zb3btRB{SXe6;cQQrf|bQ1YZ-3Db?S0dp6$m z$)R(+7@sH1-*bEPasQRwVS_R$PR*f;P*_$6_n2D8ZDsD{p2UalrnTGK1$UMY3@VGr zaDdP8g;tw^BX#?IvSl9cUDNM)2DCxGrgx)!-*3r%({`oKGZX2Zl^6XaKDnz%f`0?l zDyp9ouuo3mQpou}#dlfV-*iu@@jlnb@#x*30mbXUz`>TvG&TQK#7*L`SOi;~XKw#p zV<3mkjtgn`!#v~jN`Tsk5?W6Wx=$2yuuqt?GS%-P1 z+`9e4Gt__-!r>kldbQG1OUZrCHPer?NnU( zPZ^+z7F)Y#PBAZ;YXXZN#CTou@p`!qsZYMlq~@8=WZ+~-9!F2_100Yr|G2rjOd@6x z$B;jz=K1BoGy1ZGR6;@=jzz{&EKz6ws!Q`5=_?lst<%=GOmtGrWvxo6L8B2ay9TAN zDXyc63}s_2;8z-`Fx&B)Dr4TWq3@RMYj8$G^rbMLY^r>M#Hksh?+?@b?C*T$(lf}Y zG*bac@A98QHqU0ki%BOEHB>lX4|aPkL2z6P)PGW+M2v=5ul%F0zS{H=9912RrB5-z z;6x-fzrQ_~{;;5$Y+-dTI_T=ZqrY^CR}LbtlfHKh|5t%-U0e@h=|I0>n6TW~^s9Rn z`be`oAsx3f-OHRq3nn!9`u6EAlt=N|2MIZvM?H=aKkpIwNPP-F|BtA?;hvWpmG>F_ zw3fli#Z=r3rHf&W<{C*HTeXlQ(8Md~FcO|B@|+f*v=`1Qkx=fmDC}pzC+zIxUY+r$;!U}Yv8<|qSI-qt6)$twE zPX=InnRqRUdUTi~lAPzuBHy@L$WsdJ{1V8eYT&!;T|^%AD%H}ISelUZdNzr3YA|m2 zMHI49>ZDV8$SQnkIKPI{idME$#Ex{e^L>EjPD6ox=O}%3d1e>Y#2Y;)SLHhob&o%= zJ^s!GWqx~D8o^~(zxbw2=D5p9;(AAw-w@YM_3IPz!LkX9>Qe`JP{l}2Qt)b`KGXZ1(z@uJk>L7?*0W=>kSdS`QGO6)p=WSY zdke|KYdV;+zun1=o6$tIr6uB9(aZyQrPCuV2a;dcj&iTG)F#7v6VEIeN0a4Ub}(mbvxsmD;a z;7l)j)BW!zve>i|R9NWyYuB#~v@V^~1xgy-uTWE8pihT@xPpYKuw z^@IUbaa<~i&hkIbQ`Vig)sw-&xRtnFQtFz|MW0YbM$0PU3|tc}yTjJNiVYr-mtt`j zRMp=T9(sQv7jcaXOKvM}Aw2!IvNT*&J{jC)#_I3ZXY&~-372Yp^Fw$oaRCNMCM4kS z^;G-e*2Cga!I+`2xP@1bQQI2GwY}!4G|b!Z^WMo$_#>dsUPDi3G~jeBL+-hF0dRl` zv-X0$k4uPYP)T#E*f|FTH`q)TTJev*?4EUyDcZ}5tK48(I-aaxM4AhHK~b4n7y!Tj zl`7PR6>^=H_qcaxY~cQeQLHjRU0GM~kW0^5j2d;vs0pz^$=LDF50cp+#Tl-OKel5xM`VC^T{M=fFK_~}6p5Tumdhi+H>3+-pN~XMjXIye zQzz;gb*>+@PhM>Cn^Z9>f^CUg0(n z%FH6un5+Va1r+l3fy`>jK=@20M`}U(pR!k7QpoT!v&TlN%(h&hSu!z$;b#V&Go^6n z$|rOPgJ*BPg+`jb@tC?F_~&PJo~oIN@|@5ZN$?;YT2wS@E*XfZz^H*FnUxtCp=qQY zTL~?{NlFHj-<4v(uD#QZwhVcgm5<^mg085K8Qb48I^!|jD>BV9QO?*M(}OWb(fz2p ze}QoInI1J^`el$*EQ=enef#Ge*6*{CI_lEX=;v?-dshWO<_!L@)~P2MqtB`G4)CHn zM%d}WX>BxO&D;?GGZRwmE0wv){RdR1ZeM^vw;y(<{rB19R3}kiB1R)hoCmKi9P;jy zHv}AgGt?`oTMZ{$2Go#*S3!EDw<}ILK;hHTL(&K`L1Y?@*x9}1^6wcqx5XEIJ!|Cu zF|1!wXfK8akuF7{jxx8PStbXe5SXxQzp^;@Z(Q7^}_ zH#1p)7+8D|*@?3cjWC>2783%*_TC2A8I<^X7oGJPn3!l=PmBN;4xFp>T0fEWEQYv0 zOOmH&1&LaD?<#az68z%uP;O|QnL44M`Nu+pX;0Mf6Bxrb3^=&I+v819>A|7?B4Y%+ z_~5R4jQF?<;Sf9l1K=k@3z-WK8JPsw%X82*bZ5XzHgFVPK^tz?K-_(Ti>3py(WdL7V^BM{ojRF_X(S6uy}rIqe|-f)%QsL&bE{K@g8ky zmpZSjAM}1%FE{zP(qL7@-pGYhx~IZ0@1aPa&Bo8wi`rcT2goTfORy?pQ)w5 zU{QnrSEv~AXDvGh784I#(S5{9xX(jNzXeRCl?f&{)m^9Q{9!ap5|jx=PpUhIUk^-{ zfXjbIUHBT9hRC-QdgY1C$*hPSd5{N)N6M#pXTW`P))mzp_(G)bW@)(T#24hH~-dCo)VY&s#58^(}k7Qb7xS3F(ID)G@tpb}k`7hiOU4E= z`Ae-pVB=v;BA)B|mXnqK>8nF16B>7Vp+k1s(e{6Um3S-)F-shCTa4|Gzb~Qw?tlMgHaP$Gfa#X6^qn)pJ#DPs(^*@OVhhbFkYeJSZb#3VN zsr$~fr1x}pLE($t`wo;3aQZUuX`2d4^Rmba4y0Qrn&ko6{}mEyjoY$E)=7pXyAOm_ zY=Gs~*S%zaCw%0n)MiSx!b}ctc2qKsL%Ro1lSD1#Uc!*KVhARjN==aJ=XMuAw4T)X zhCfLSgy3Mm<0g}Fc@TDKTS$6x?|*s17RmAwK~||DB@})m)UfU$-+N&i?2%ef6|2ewtS)g7W zc6PM~2-Uc>csi_hb3)Zp7RR1G91K>n0*j?Dk%aeed-ebL($w09LbQ?BU$<9Aw0*|s z-^14s5BkI>{=sT+ZR{eaMrh!uPDNwagVB#E26I=2-DhfC3FhT3cf8{l?_iGn22rB! zcffc6`Z`Hq5a^{gdYGIv$-+DK^XZ`!azN~hYuY)Z%-JJtWNW` z`i%uoQY}-{m_9urTyJ_J@=<51CBu)=yq5o5f_lB7*p%^w1K10bXVbDy?VNIrt0eIg z_Pl=W_j?~h!0#zzXve`M^N;AokE~_RNv`cBg_AyiAN^9gz;GO2EsuX#ah?<4!>n7F z;@xOAP}$INxl^uDdtb!$$$V7{#SIt!8{x?-O&{Je$c7Gy?tHX$m@kzUhnB7Y_LXL>=z43^YbH_c+|x_byWtl`Ab$^ZFTkpbaw}%)Ud*x=5eSwX2>FSbeurK9 ze4t-L!o&&+pqL$OP!l$!Oq5a)!E|pW(wCa1m-Y+%;6c2aQ?K>Yf%$GeuO0rrMfeYy zNIZqy;&dH;G(SnC%dab}th~4q?=t$Y_->vS#TA^>;sWpeG9$8I#8x|f%fkMnaP(tt zy$N}VLRdzhZF*;aI&^-gtSk8Sy_!;b>^)hfjCb`c&Ap}bBa1hllprnUOn!kND%I`S z4c}3+Ia3xIHL;&1`eIgWL6XaVMhV908YbmMwnlo0lG+48?qKh}N~XP6M?06`%`Irk z5EjjmoX{r0MCc2#P@7AfRV@Mi?~SkpscYcBcth~1TYhhoIKV?wtYt;lwF(S&O_V6i zb?J;?ymL=pl2N&Zy*2n8Jhb~h*5`n#>eDY5Y&_NNZ?IL z+p@##YPHgiL_hvl5E(9mCG|WmPv0;-S|+;s!_<0d1{z%c`i|f;lvr!a2KhjXVBpz{ z>1x3*zY-L8HQ}O<6+Vc&f`TpB-9h&Sen%nH3$o#^VZgvy>q0rB@b_?Tz=AdYs#5S{*jspnoq;)aDaF&jQL%Oov6-|`;2gGrBrQt{@m1s8fMt*chkmj%HiC* zzYegpw_*kcZ6q7_g9qSJe?3<+F&B3&i3_Ee`l6+d|A!Ce(CR*blgWbx{^#JwAfUL> zAI{WXBKjQi_HZ%|j*UOLiQb*>;9-R0)m(UUJ&Y1gIgIO0ZtX&Firj7 z(hj&}6amXuwbQsY*cFpTxp%w3`u6)^MK&$@8?k;QIbb)7Q-J8)>Gpbo)O2bD;ljbM_fOe(wDX!yvpCy-*ojfi zcXPcRISW8j2)Ull;DmWosrG+Y5{cW?0Byg0{(F$z(DsO>|95{JP{_CU?|jh$3h-Hk zz6SqA<@~SP>a=Bzr`jXt7!ED9^a-T}+zV4>x9_=>W-ud-|^t$$99TmK!;3PXJ%lO8H! zEZdSp?-`sm>{~2ebxcT>jxdWB{X05kKW&WTYW)jMpgzfvILZAo$SJge~pks(N;iATq?TC6cr_^YS12NVHDvqJqX+yhxZ!O zU9Ha724;vK!W^J9o92f0!hL_vU-Ad})dU@y!E^T|u-Dp>g2?})=}r8hdjJ1_OHo-S zDod8BR8p3ZotdPlY@xC*C6wJ*hnYc=WKWWHLXmyn8DyDkGuijCj4^h`n8A$YJFoZe z_xT6T?KM%~Qzu@|3g~I~KKb+#f&(w+Jo#)A`m8_nft#;7P%U|;q zgp6*s4aq(-`jO>99;FpZJ~$&7md=;G7{3r|VmN|0CHEG{Au-t`at5l1-Q=n{P=E^D1{c4nidPqGozFqw0p&1%v{W066jA%Bl9`BXNmvO;RU3Qrjp#IDt z#(S#N>z0f*hj5UFtE>gdXtbV$AA3lY^Bk<#&d1=a{Lnd-2}Bio-R)%F4mX^q}8O>M#9o=_R-E=c?N}803q@LNm8{Q@etJRpmd=ul&|c)*aOQ z$A9^1=06d6>((KrR4j1r%-w8O<;xGb8vZrapPftST1i1}6gi!gxPWF*ZnK$nTTD%wOAMUlTfng~(eF z;ca(}exx^MV@NxgPv_S+}1G zVB1M(jf(datY_!AB_GHH+>QvuADu9!b_5p{mD=qEIOzOeH!5o*rL9116uMnOD8{eK zS(HE2d9%u`7?LH?nW!Ao9f-)A^|^gNj`I%c`IT68igV%RR8ns&4EzH8SSOO(O7qW4 zbAwFg&zc`#Bl%mb3*ViaOX{O4&*qxR*dSbwBrY#AJ?3>Is=IaT>wf`a*M9RtT!ANu4szLw8l=$!&sY2jc<{)bz4OnVMPFcPNRXcAU(^u z@l}VocS9Pqo`6jpI2Dq|f}(8p20Vgnx>ob428R!{8q2c2CbgGk@qAE#=S_x63?!`8 zJ{qxY*I`nJJ}LjiEs<3`;PT~1jb(1=yX#uw>Ip^#SB&6BHA*|T^94xkQ-0aE+fxar z@6(bt%D*V*rEA^)@+K8~M@A2yE8SiBI?P@p_|hkD9HPuiG<9PsG3FSvG?@*ES5xs@ z6Iz#GUFSTOyhXs}wR|M%4yO*UhS>IN=nTvwF}QA%}d z^UwPTXl>AoRDkiuy&Jt=67X?om81JivGa^OzTo{MXK+(?c7w^9?)A$#W4vu0D^Hgo>Dr|PdG4Fg`py5D`zZ&MX^;j*#gncs>c zwJR_G>3BP~pIs19>z0QiO-xvUkRA2zogX&EnxYwp{gYbnVmSX%-PFd;R*QbEQ1bC+ z82VW=ohUXR19uXU!n#HsYk_di8UIvstz&&}&2jo^Qyz9K`;u?QWXIQjD~U6M!k6B!RpD#h+afi&Z!@TTepPH zK907nzs4V2dw-#{24q&V%trj`XiBdF+3u1qs9qdn>HS&twEn`b&B4s&i#5L!St{x* zOP-pZD>JmNE=aF{JW{dou)-IFc1T*ySW+sgzL;=aUmP6!djXd^qnRqT&CQfrTL%@2 zB^aJ);bK$psQp3R%ECy@tp6;WCwPoa)qu$3*_269Z9yE-D&TZ#eAZfuJVY@dm)fZ! zZq658qm}%D8=^?0SIKB?#{3d?+-sWsctaTcqT~J}h~6?$H3M*CW4le3>mA9`PMIUh zlbdPFuw{#NCdTr?-G2s!rCo6b{X=^2mzDd4wQf?jU*^Bs*sFI&+bruk-5BA%sp0Fh zbg*Z*7VfJ5F@0;SWGH5U68QP`*m@`goyq!VM)mQJ8qG#|g)`~DW1AjOIxn5pRhzf@ zF`(*GcPiwK$afZ2S01Ac>%2Tnm~rQibLw(89VcHo5_TZe8z;j27m(9SY%hACcqXoo zUWd-C*xfkr@qUFj5%Yb8yvPkx{BktOuRfMQpk^>2haRXu?V_T?s9S054&9MJeG*Qn zRkUR|0iT871zEL_W5WtF8J>yK+uZa=ZvRODejPaV)~LD52wBy(zOa6FV`)Wf8UG{` zd-eyo#?4ecZ4=|@?EPCU4VqJ-`dj;aCi{e_JfhXyE?d(+e3QFqB&ij3sjz31kwVHE z#L~*V@M3bbduf=_8G6!?-y=70>)z{&@7X_T>BxmKdp+c2dZ=VKta%m{{7NY9&AIj1 z@ZAG!FhWuQ;##FE?9U4AVY*i7(3&K8x3woxEd+eXS+-2%LNXOf$hp#d1^TjFhr`|3 z{D@NQ%P9kNv`NR3*>6CQI57+3B(gAH;KT&09bXvy@2-x_P5twD>?#~__v3E}?*N?X zg~e&T_iRH4O%y_luNKHls(vxS46Rs|h?I@8mLhDwgc`f^0(9ej|G6vZ?I6dKj^7=$$a;|)CHu&ZI!b#C1iH2 z(Q4WEa!BWUQP+bE0{iKP9c4aVml=@XWKm79hFo%v)ChM-q2|RO+Wff5Y8QKbFu2+t z`8T5$+_RXmet}V*{?57yl?Og^T49TK!ryL}9nV|)VPKq#X*9TnQc=WxQ~CcD#68e| zu6iPIk+L3*7k5rG(ng9Wc5U5o&;8Ck%VVN{Ta|$@e;oKFf6f2ynvq}6K~G`t{i6IF zKD#UdmZD$hjehquFKn1N!Jo-$vm~A#M&GGXXb3LTVcXjz9*2B^6~}KzUIrLgHD?!D z=F(X!i02-R@%-^;ZW@NQ{Ahfi&%E4D=;-yzR;Z6msb`+h(WJ++K45@h@|~7ySOcK? zZHyi}-cbVKy#rM^Z*tSHM{ddv>-a+)(CXy5*FWB5U}!~M!?)&q3j@?5bsEEEXl- z4gQsqTaqs}@cO z?7UDAioRM;TKUD#u+_c{_2x zh*%@Ayimg^gGCJ-r`1*&T-&}7Z&T}Uc(8v=6BGWEHB@&Yh1&iQeKy0&4+o=%Y{kB{ z3>ejNwCt59JPomM(@Lpr@E8$NtL^aTWA^zL{nWg;EhMc2kUunAhz}F0`Fn3JBUk*r z0Y6jcDcc{VSFWc_FXp*Uf6P7jM04Z#@nw#6`uhDrR^}_5@vOsaL5E-T;O-3bI64n* zWXR@2$Et4s3!B6ZqweKgaa_WnSm>nhhaVf;iApf$r6uT(P>)RV1OUni{z0?M%9<r+kBfp~p_VXeoVsZ*a` zoSbE@G)7R}_mx53Pha@xQpi#!{tlBDc>3XGz(P|0phC4RJ^dvN(EYmh8$4H`7fenk z_qZG{dHlit+>&GPp5dVBSZShtf5W$S*6UnFx%(tXAaz6TBA6O399+V#a-cU*J$*c{ zf|Mw)>yu5qMSOD-`-f+d=k!cbgMmg<-Sc5srlF>tN?w3xz+h%EYl1fxUl#{X}6)E0^z;oZ8E+OCf>5v@T0cFN$1Y`e5|UIx+}RN=}s@Szh3oRlDT+Q(hxd&n$Thm zb>O#VS~y6%ul>h?jA`=jI%?bVO&e)|{ihy)uq)0%1HC3^ok9y|=lq zs+OtBdU7H$!n!J-#X*@RyhzEu$O-t~D_`@ay^XoJjd$4Qx+ZHc7lBlH&vER}Fb(wl z4UyR7n((Dl*zN<+#*}fa_mzKr#}HBE*NJt25K(?P&B<8}_C|<2pP+Plx4V(EUjiM! zHW%?m%i{9?OmfPAIDtnY6*h&Q1B})ju0+b%uE(c-uV$*Zn!%!lP6Z#x5H@9S=UJJq zF}<`l&-gaMUw=-Od710F`q-xG@1krWUH3A7ou!6A1Q(fd9t2P<_NRte1DH)2m$F9btpO)Ds}^oADRPZ?mY$ zCG_V9t&OwR$78do(rNfqaTZEFG(yea#})DKg@|IyrK;(7_>WS_YkjnRO@X=dz9T`b zLl2+`*VFglYj;q!O{A6+CFbCVgKSLK)D%sskdxum-RR39yE|+;F$QdwwaqJ8ReJu? zytk&L=^vAORXl+InkE2ViJaR^%7OLkO>TMv-qy?e`&s{cvPJX%8FK`T?v;W6viy$W z`7tn1bbe$x`f7^AiBEM28*b;@PMoRji+!)JA6|72DZ_-rQ<^XMUH=wo_F(Wd{B+F{ zE<-rcW1rgF>v43TmYNU0PwX1J7%KtkR~Y;1HdWK9|CA}#+>K2=u9?;n7@!#R? zL|D?|6hm4wQK%KXt_76zfVB(tgf(1dn#c3E(u^*(?2L#}eT!STm;x7dRGAJcAl)qi zQ0Nfw#H(*{4T8xQ8O(kG8?*LL!mgsuT|qnkW9Q`haLOs(AIHp^&1S&5lJ(5B?1uTQ z0|SN&d5aO-)5FQZ$_^ZhLuX-Q^WU>T20Lu9$pwN;Fx1pG_T67F^}p9`Kf9#cq+`H?;==53BChnC^Uiv#l_z9#(oV%8}#fWRqJ{iPX!e1-0sfhSHs`Y_rYE!(D~JUl|z5 zbK~UO5y{Q#4$swo-uU;Qw<dgH3TjtjO z*3`JacHf~#O};+>$+ST8S-JI$2-Vy^`Pqviiec&(1*^clwOm!Urgx2xV3q!lb@NVt z%%2=o;n%u;0mlNnaqi!}^E6NOsf^NSl$#zyROTmG*B_QWmfThe&s}m_{XU<7t%S0I zV6(0L==OD-1HG@D>)_YOe~+%1Ec;M?UW)1N<@+iZTmOYDYq1JQg*6EG)yR8*oUIpK znPe!&$C(#a4!LBw+uKVZ8=u8B}3leuvyw8FB3G|Xl#MWS!{H@fl4@7G&!M?L@Bx| zRs0{H?ftTZ7iuy)aejh9$+>t zLO-*b7?_VuqhM6mBrCKm9{k7lPX5;|@Ib}Sg6ZxlCax+r9h2B$)q~&iZ&Mir0uXYi zy}QWcbBShVlM#v?l#Nt}xZ2d_t$zUY_6KizBV9=MlOO+AI(}%-F>p3a5ck_e zG((lG^oURSXm<#}0$vl~Wd57p7vVJ54`IEn&RX?uw09@HR(kkYzfx4aH8bw_7Oq*% zac_L_Yv_!ZlPD{T<*YPaU?=K-?oES6uy!>ha4N^Uht$1HBszyTg&hy`wgZv6V;Fe)PuLiuBE8(($-MeO%ZFj?jMG@r zZ4;MW9xp=P%L8kbN{6ZS&lR+F@7_wpzE02ZBkVw$Yy>!=UE`|DSjh&{CA-syOzj7) z)5lzY@IBNpS5R{w7E15ESg*tia=4FJ8!eVSvmIsrC3Kp>7+gH+wOBOQhCbFUJpB>Z zRE0tFXy*w2dg(=-4b-it1=$$I&emAZrlj6ZqXKX3t?(W>+W6%rXX=kVu{nJehX8uC zEgtPX{Zed0T7l5%;OCij)O|>cEA|kzCB=VyDD%}^!;3J_Zd&hEbCNbBaoh{Q0Cm>4x;Kjt* z3I%{Ys?8_IZ>-Nw2Td33q`H(!RSJzp$eEsRr~3?FwCA0zqx6maP|=oh9Nbm`To0qb zE^Z^PYlNxZ3u|Tw&5llS+hK*k=8fX+9&CX?U8G~ZgL)2@Yswp=lBbq=CU9ITkRv*+ zLMrf?7E{C^%cZ{q(^PcubI^%LFqf5#?O;VeLk2&xre_qT&|?}8U~0V|X(~FjqGfoS ziF>vngD2R+MuNmYn7s z7yO$MaV<{K{eE1Q+g~yHTTY+~uWp+8w+#qRb$i?jU z2i~3WB?9o)*|7n(SY0Xw1QAypX6U$5$^o39+P~`G8~rO)Ig4^hW2g)#wX$&nTCl=k^>~U?-@NF1;tpt?$wefPKaGsNUS+P6&6%X1`sg1g%~;Sm@lTREG}76uj{A;5){io{Xsv z*nfNv-$)BWmBQw_iQh&{kKpDl&W{d?La3N#`qUenJY&07r*lpVB;m$FCWE|P$FmnR z$L5puNAl#D;GU=Newu#}&J=VN+;GV!*XNN@k8})EaNy=p55iNh~9+c65a-(J0-kE?|UWK*zM)?<;L|KxgxVNW*VKqs3Ca)qcl@Q#E{2B|ai5sy-~f-`>nA^a&nt zZ}WXuGKl6lg%5}%J~28uLSl`wQvs0@!uFgSQm!v*ygrt z?4REm4$gtOhuz?opXm^~HG>rW!CEHXws!uM6cYQ*a3%DdQ?9IR}i7?S0Z}0jv?h=;L9G`u3vQwzGp{6;o?YO!KnfPqh6EofUkZm{w zbm1l|sOGP5OFleX?dLBB9&y5a*IS;&sqrQ$qd`%h`1i+? zUIFDw8;q0nZi4xy+&y|XccbZSkur9pZW=R#f)m^cMya z^_I=zP#YlknCc)S(_2cnQhAcx-b=a7s{INZpZ9WAdvzy?kSMgpV;47ABwD!M3hjs$ z)>UowJ#0PqGxn6(@79y?Ny!T;A*UR?c|%M?WLYhkBhd2DHy3n_`2G5J@D27g>emNY zx8T7O@FQYxDu;BmX09}taIRw3UdF?7kpWqB*e>2El)q6=h99{qA%Q*>@RD}wXebM9 zc{*sTd1g`rCEuEp-20dOF@2b51lp(?D)1bassHcf6Xo;Nab#sPn5fn}yON)#fNVw; zjSlvoQ+;74Bfq99W?S#5Uk|4%hB|I|awo@*7|uawzP5$>d=E|hhIPK15Dzq!H6Fgh zx=1m+k7GUcuYZom;oy~EWM_oM*7EAru5&Qw^H;P#UUpx0AI(8*!B_mhN;Dg0*neSZ zM8A*|XwX12dyRVG%>b!b@5~HKv|`F@dzG(TmNn~G=vy$dO?1{A?VG{~m_Y^#4-UFA zNSQ5Xh~d7pI~aNaB-_1jM^2v6u8w+;5Bw-?ClOv2M{a<7~5zFhMM#Sr3Wbss+(uSos!TObTgS552VoA49m$66xwK)l}Ms z?qrn@}~!WAYrIFZ3$+E%?%+79$n~QXevd#vtuqyR#y#fdu@RE%nf!w$7}}( z+}W~A={>aKywap-O0d^+-^u^{jdoonyDm(4E%#$n;II zZ(3=f4jcnXb+$eW{E^xkbLS9CYO7mOnuYHx$pm!Ir&NntEiC5W*-|BI^H1LpG#zj# zSBAVs5yXJ`7jT81d=rUUUENDh*qB`u#ckf9>6Fa)4ne!$iXfYM>ly4L_y=@*SoNp& zM1*U7*L#TfwB6-B`bzrbCkahhHfo3{0zUM20eQ!Y9Yc5G>6{t;SyI~XrXNkgOKelD z_FKE(#R@<59G&mC@LbBz`^pc*RtoP6Fa0b=Xn|^|tt&bEfc4trKpeWE#?GcbLWjI$ooMI{@>iuF6;Q&AyMhQN1~Xy%AJWm}lU4x9ORyxqX{s z!hDCe=b*dzZJAqE;d_soZ*^tIw=^k8m_5_35>=ic>UNpExr>$(S@`;U4T`uXaRRSC z8nmSgQC7ron4?2MIL~hQ1fKAo%fLD%=q&I%nXRs)=NGna@c8Q;1V3~wYU9iFZgHLa zzNk>pT-W;(6=iP85+FSvsoJz+$l!xYtm*g*D|B6J$>^OH19JFgOi$a?zvQ5^udOmX zTGE&~;*uC7JzDbIDWwuC;L>I5q}yF|wj4*zd|!xAo-hT%GG;Z*p~g${ma{ims{)pI zW%H}Ra>4_D#B|5Jv~7Pz-e)h}-^-#k2}&2~1#FJhYYiC|P3;Tg$Gh8Yx(WI&CuyK@fcf{A;R0+c4S+1ka9%@cKYD)q}AP}C&+`MZTqXgzu^1lo@VjcPg3Nbk>~v|guUTw-UKr7HkePKO z`(&P9{3ATVV}0y%RNL0$A}>;qfOkC1-+=lGQ2%c&42yi)w_0l6PU)l-+)z} z)ou#5>BaL}__^p4dn9UWyMYm;B1Iy}jK^*2I;q8)2(Fkau_@XLSbZSezsYCK{W{-X zZM(hq+jq9t(U^4;~ zOFos3a2*wP(>$^GFqw5P* z>#`e}$u$jwsfUm5@Hr?2$;S@sNNdr3OvS%>k$Nt4aBY-V{BK5dijlCk)E8DIG2zXq zp&ifa(cbcZV+-hOuwMqZY6`1wUBK5m9XR9zW^9qxvwYYIT+Ltm;cHm%ab>{g-o*8# zg;(>$7?TeIiViw=bsj z#b1q`@gWb!Bo4R#bKwMM8_+&q(+H9+Sw_pKjJ*Hr|IafNvmtU^BI)8aqc1|EG!(R0 zoS4Z0fAdF9{ppZEq|vSI}FQ zZ)Kr)c=neU;kJRK(%oSU7m%ZAHb1PtOsAZ-3wRdvA8am-`0>DO@_&<~Yv8w~3V2Us zwm-1%vKpuy@(X6_QcWC^l>C4%K)qgWGEysPS_|b5v$(BonrWtEE^A=3ZcLQQ2=EdR zNBr9P(;6dmS)hLIU2d!*wc8D8o`*W+FG)S%(O>515d$b_cXmf81g3l^5qUYZK|+rg z4hfQ=v!6lQo$l}-pc8A4%OG3?+EoGTC0P?MevmtP`8a^UnKx)fU+xOF)B< zNk%t=w8q#XHb*oRRmHrzl32?${$r0nA%8p;nELNVbVwo5jpDw)j$_AAev&`%_@t?8 z!NmsG`5?Hjgi)@j!x4+3(km{Ji=9kIp%xd{hBZb;lwX-Y)>+?;?Ei!5KI2%_-zm=* z#QD}4&q%p%8DuY+_D(=X?Z7VV{roAeRO@i1)$g~Z_wLI&iP}d6b3a{O1`}BO#JB28 z5m)EQc$qi#rPD+>@O9&l>?o658C!vuUNE?rI2lA6h|4Ts2e*Ure0Sb@2=3L1QSuP@ zZ3;$j0ldz8tf}MXN9)O?_IG7Lnp~_(5ur{pSFBM)R4yVw`2Cz zLqXQIjd%H}iI=>`!+wS^)_E+i%}rTDXOFSI)32n5C3nY9+Y^8)%dbnu3`HGyG-3t4 zua4X3-Tpi)06_unen&s}bLq(H)ZdgS)XxjHG665vwvI_#!$);VeaZNR?10gSGkLH7 zu7K?KXSTa#Y$R-;uvk|a++z8U##g=73mSKBiuOs>PQUIJ+L5hecZVfoa$wJJM`B<| zKp9Fb0-G79^h)WNbn|A^eW~W@uKDBrx|sGJGkl=+4cpsC=b|2V?mxtCR|+%+T?G+Q?VYBNE&uWX+cu{qy$U`4!lKz7dT49ZNuBqDNQNQaLa5Ht4ycehE76a1l? zB%&fOvrz@-9~t%={S$t(7V01X!8tV-a3|Tr5s0ejc6m zW>#%DiIyZze}UB^*tpY7)jPHrx!Wcm=BCetywaV`|8Q58ZE8AX<{2=IvE^Sn&Ix$t zUJx{7SaOHrMZgSpHE%2+O?M@GVZ{&3t6xIIei$*AOyzZsjohd=@Q?Zfj{bn}(_)61XbzcQ_HDr}`(HPM>uke#wqERP>$K(6^*A1jr zn^bzmy#gw!ZC;&Nox5u&_(93&*}ljXamZ3J^7F{GemE8X#KMC~ZCiF@RZh)fR3DT z;1oNiBY&!0J4j2NZLbwi=Uww|Y6n{d6IOQoPGjA8L6PzX?^p4Y`=9X*A4?M*q(60- zbGD7&@)NA~;_a6)Pt$beTQ9#4ys)ZYJ9wmgBX7CRY<3jy_4}UQY zNX4nK78SM|U3D_|40mV1u86+W`e9-a$)m&{nN@~_>N+X1f;reUtm`2Z&#f7t#xw*y zB;JPK^;!>(6$2l*axCMX$E1b5QS&JB^i0upJFd8d8oAkmY^w#_@bXnQ5&tL?EO*yn zy(?gSBUFgvILB9SwWFZ}zHgz8Ca$Wyib`v|CAm|*nB4D{R?md#L|C@EBy_5kjB%)< z;!v)o9cacm21Llg7Sc%Uo!t{>%*It#)aMT(v$Nwzez3^gZPHX~QWmdqg>l<_x(PV$ zL7ozli9$aNd@uh9ksUfB>clC2AZgbjzR=T5A@yMs=Rp?wWB8w^darH#D=i*I@@B-q zZUnSQa=8aR$+tx+G{gXLyE%CB>g=@8&VMJz=|Sk%*j`E;!quwWJ2>?bqDjS49JgOQ zX~BYa+A8FWI%(Q45qByMm;6Vrbz4LEXAsE_+26*>wcYQ$A%td#Pc~)yw>e1>aEHGd ziZEf_PnN$=Qk8iJ(5vdo^S%k0D(M{~YhE)cW{`cB>i4y>hO`wVt%%LlIj8H}-`<5V zWCQUc`;j9y@BIl_fd(7gq^Z|b*E)lLtGSf}bb9cH{PibmXS z{?+bO3wRNh3tPJjz(`l`w%k#(>yI^JBg35znSE@0_VMeo+8Eb+O>uyvdX<;rxuj|K zx$!~v2++aqJESl+^1lYPx^i^86Tm#VuEy*Q+HpN$wNN$g>zX!hnw5Vhucffo=cOS| zharL0FNvbwE&0RIN25f6cf+dx1>tk~;D^3{Ak|>$g0|$6 zVvT#-2Hu*>;P(%7($MU%dJamp;?M6ECc={sv<9~hTRgziFALS8l;Xx*Ivq%v9)p;~ zW188z5?q(v)~UyAy?(SM98B#me0Z>WFQxRX!=E0Gz9QWShv7LtOaQoUxBPFSU#M68 zKGgKpHdhnJb6g|Rtq&Y4S596_Z0V5Upo2hYc@LAdJm~tPp>KRHGkJmUk zyD%^WO0*EC`>HuwTJ94bZTa~jg;#W(G@U*r=%!t^D^h5sc=8BEr$Mb9t&S$J2)_ss zx4TMRP96ZyX_<;R;K2J}Q4*Ad#Z?)~+xm#7V;a6I5Cseu8b;bA{;n~3^g&+4flyiz z)q-!`iU>v1u*r{x^U+)7ZD2lI#DlpZ8o6VUKUDxv#l*J@10J%yX#RagWY`L6$*N(u z{gOQg7pvNfjjww=ydF^ zDwsG^j&xI7%gyxN7_*VD8SKn^Q@+K4q8NV(%K-V>H{bMfaahNwZRvU2EvjCsdv#c{ z5ekJ`5KP&(2bQ1O5ZVd5XA=)-m<5(#p6SnGF2xIXfWTLapARfHj7F9D;3y?Wt4GOk zr{OTYN&~)<-Fi6dx56EgQLn|R1Fjj;iU@4#y(-`Q;QZn_q{@Nr3raimw1L0L{AHVB z>|8qb45QEUhuV=LD{5UfuhM*S)A7730FO|YJe?UhdMS8tZru$-*#01Xb3|-V!@&B% zN32`ibW`)b7{wpw-kydUE{>Er3R2xyH%QqF1;Fk%c~ zsS2Px)RACYL#emb9Q2hyt+!%{m(Xu#VStUI(k>`&h>psB5f{FnM?)!rR=FZ!@S?XK3e9Bjaz zQ@TL!%)aU(O;OK%YCGj%t-5TR!xZqGlfI-&`RFEvz*my1iRg;JA%|&|9c#jjYeA`P48xgH<>N|60CJt5*e2)Z#Q`apTjwL|b$M*Riw=+weY zR|aZ?e3w4{HunAWy1s@AGv3e^EC20a)w-v4N66%J=xi$NRVwA{oZ!10mpf{X*WI9z z*oLKL`MfC_Fml~$@-gi}0kYG>2EBL~w4Pm~aUHc)*-Tq3+DTlKAHiB}t3hY4DvpW& zKpu)FnzW2#X1pfn0!zv@QUdPIfJzku_#-tWYdy@C(Jw$6v5(TH6bXx;cZ{25)piSP zHLP0lL0FsF8|~Sk5^8<3vB!9<;iL0+&PS=*`nDn^gim^O+^L4PlDJ)kWe(3~8?&yx zB~Hlz8;hkYW5vd?QI7R-;;3;6!)D&EQKw%A$rhXkp4DgECvbUkZppU0@Wn3u1UEYc zG2oyNMr|O*@}||eJAyccN;Z=ViG3>R5Bn8tL0*4{2}2RZnY`BYpOYO6wVCuEczILn zZlKx|bt`wOcyRJWX&@vkQ9iTK5)W}*BGujKGJ_PuI=tVSv`_Dbjwl*hO|I^|1slJM z`3hOlwalQwg9WuNn>emZYLG^CmXzypbbTQG7L{@KGlC*w|9anvQoN;CX$k*@zL~`jc!QRM(heh)fVRgEZ)i(!PxuCO znzNq8XsWv%(Z14>f{tyr)Gbj_Jhuv5%s-qCE)cz`VDE(`oT_tA%px)RGGNj zLXep3Dgte=lwQ3Z)hlZ41F>0%AHMdn@2bvTlsVzN<%qf0Uzypbo3G|9y>7CT)_<)< zR&!SnL*?BKY8%1O=&Ob=qvV*L42vhqp5+ZIkz!YdFWuTZ>`K@%6RPhSlEGM&b$wCt zHBcoF%cJtdWoV|y=wO)iVzmys8S1`L_KBaFx1+ zCrRS!S+A4WS?errq4Pr6>^IUjrUSOy0weQj+;z9JY;0GpL#2{zvtQfRZ5dE|pWvE+ zhH~`vT@(LaCtcyJi9;WaYDr(HkvRGpB7_%6FGpns8cLndRv1m6@t?o$!syQ$=Ak3MZ1(H6CSAO&sgU` zsX3tp^fn98Q;&B0NU2+Z=Sf~c&O3S-(u0?`Wu7DP9D~Z;4FLu2e^SN6rm$A5)sK<#1>8)pi z*NCV;;FsaopLo*r`;;35@IBF#^r}uq=pK42@xsY!H!FKu^PA(R?8&~S-*-c;M^1|w z9=R!ftM*E=sy7YY{Cs#*h-Y*9XS)J02| ztV~ks%u5&PUA&U3OS#m3emxQwm(gP}z_8?ep45;oFqDr($n#DDk{e?m`^y*^~;kU7GzMHLbB7#Wy6Co-Xn ze&sZs{&iH}c6Ggle0L##4Bay(J3jiXdA^ZUirJi-o97aC5%qkP1^AbM+jC}C2655;SP?xfRXirjQM+e6=VuepZdk^K2mn@y4ob$B}%L0 za&H|?w1iyZ>|;BrF&ik6QK@l-aMyMgx!(p%H{GfJ?RAoA`}49b@|o#4-bA%}+;*PY zXU4W>=S~lwZ50tJR~3edv}sJA~{TJXdC7gpsP<`xB=nSoh5zqBtQjp^pwP(6a?+&8td7V@f%$y z%g^rH=;I&n6u@Me4UYTEk4*V|e(N)_i}qvO5i zot=|$ex(@*`~AVvOk)l2B0^JZ-7k-Dv19h*Wnl5?68DMWNp!>C7aFyY!-fxDaj2Iz zn?Z5lFUB0#OgrogKODHFQHVS)@0MzfzyVv$6nV2FxtBAOB>u93oQbDrL0pR{lSy%5 zyl9|GT^=J;%z^YKUE`C!L>%1-W+|?6`Z8I%M7SxwY;*`{zb-ROYFcngY*;AnK0NYo zCI{$=79oA6OP@jnN3B<0cfQ@rglF>ZEdm#XTA(`uYYLRD`9&V5V@BcDIAUW*iw_Q6 zH_f+|h@*~gO?fBO&u@Dc$_R>%GUMFa`$>@0H0nm}Soo7y8ywuO z+O&`MLGd~gFQcJ7(Ri}5)66iz=w=)!=&NNkZ;Nl=)vocxLeVcCFHArx)d@%6g>*$> z+%6PQ8QMXRDbXaEDTTBf<)3FKA74M8n6ow>{lW_Idex4A5k7a!nVl)iv9HggT#D0<7DGH|cE?_vAOpjqm%>G%sWeVE(oVma48sO(P^l&YL zu8T7zqjq=mVs7}O0MAr9RZy|7(uSIpJp9Smg-j=n#%LxLS3H-+zxCAv4P0S_VvFk8 z-sYsql5O!=4OO#MaexnP;plxJ-4BKrm$?TlR)G=x56jy}#5L;Qdv9NeK1$!WQ=Twn zu(39$I#SkHa;3VkEl$$kNA8Z*snCKj(BoPZrI?)$7P!oDW13T?!m+gS&yAZZ|Ew?W zpVu6H!S4ZpyhGmD7|QHRN}Tk^L5WmhRTbOyCrw{0Mu)`t{YK?8kE8c43nrRKn7-bo z*i`Txc69UPeKoXX1U9Bhf=14U`jJ|%_2 zt2f8CL$#03@o{LFQpt~AbMRBHkpY2@GgeP~* z&-kt_>EOt?KxSdX$^tO|!e`M4x;xd1JkICB+#$HIduK>y^gHiKH|%Dz?63N#hxvQN zZ?e$x{~8Gi?eDj~MWMXcrx#T{d}?>Ih-|q4*l?M_YNUdxx@_6XY&)Kv=omL6!;heA zI(=6wt^_8EC+rh81dbxXhRIs>5sXHzBSGE~8Pv2mxh1MC{VTxj4WsUo;Mft znP+ZsvnsF5bL9$6g}PERcTQYrB50zN6GskEa4RT^4E^%{;rk!Fet5l}ujljmSi{yy z;E?y9gf-rqPamhLJrf@hU&K7%|MH1tyR#jwqX>-~nAHHrUCQ!F2|zE z??$TLv(4>%3Sni_Kz8I?JNFmyb}w4)+8%7*$t3eRorT5Uu`&HlgMUHPCI^ zBF4gaU$*y#z6R|#{ZN=_ox(Z3cNhlB2APYV5j#Go-K)s~-iZPCUEzgaWRxD=-wTR1*GmD*DXdS3>*JlRw-T48uxr^yS#f~>O^iSBMu#Mbkir9 zO|70V15p~6Mx7Ja4yC5=Qku#c*6+zbzUXh6G-RXyeEv_3l7t&Hr_ZUM2-d7Cp;gI> z>cZZfV+(o_Wg+^Qx?9kU=vsua?ERb+w5cPxk+H5r7$=b46&hU)G zkFWZ)|2twD{{Fcn zkIxqKdKc}1wBy)wMU$M_d`;e$=3DU0jrN%j6SfAsho1zPt?hRrq4N?UaDQp`OC~WU zhJ)XKvidK?DyM0Oop1*}YQ3{#t&yt&TRQu7aPzA~1=?2}N>5n-!6e?@db2q3XwR}d zt(iW3c8I)L?1dDjk|p>w8cq6wzWTm@=x%j3qa|5@$OZAPN<~!|$U`l1l#dvBaMDU< zcggec=`iTej-qv>+dN|TURR76Ol##10s&FF9JU&xWw@qcc<-f>wT>|HMWWke06WEP?HiY7QW?5jMU%^YY{~7|0-`a4`JK}p5@G0R(>*5Ru%Wbb-Ye;7+UDs zBq)pSZjJ8I1dlFV|I%<=qPaJ@qr3M`S7=0I%jJr@FB>dts3b%*0<%Rs55glAK+7sB z6TX~dz1*v5JtbN+BUL*oD#;?o9OSueQQtzX`o3~gYi~Hzi%L4}yTH&&!}BQ0z2<=( zHzp3^*1KLOUV`FA=ZA>-!mZw1G$mY-VnXIdwAH#WtRqlHNB7v6|da z;e&JA>*bjepmY-#C1h2K?DQb#HMbXH)c+MD>3-?vT%@u^KL(kbmfK|Zi96$-LLlbA z#dUDaq9ZTDSDIhj9>SfE z%<<7XBLP`7T&dHBev{C85J&ws?>YbC`Zb2z{h8Cn2;TB?tbeqpacnv_Wy(}IH`Xir zb7xjD*+#0Q6SVbC+oXT~0uc3$h`i(Qoq}wjl1ZL9pfGdA6-;?l{O9x9R7jYp&gI|B zA62-Tf5fu4*IRgMO1N!b_ytvoJPq?JR{YAhK<*YyTKJ^Ji+s6j*cx$Gf<9`uC`{AN74 z)oFijF$fKVUIGpm2VH4sxsgRA+RPM!L-)5u!<`sGw(|al`82X|!1+O1l6byMdeuIe zz{Uz>+)-!Sry!`J8aQw{FFR^!8}BjKUT02^e&XeT@g7bOY&)rL>THANuP?F)LJB}f zC+5x6RN9FppSjObsYYj}q)+<3I*)Av_$&6D?(=FksLqEEw3-o3M-A<%E^3)=Ly3d$ zHvcTrCp1||6j|Gq^c>6Zu0m+8aC50=Y?(zK1LRy%x&j;u(yS7CY3={<3IYzi9qj8P zFo*(TRYzi@6+G6CAk2$b&i{We03XJgJ?SkD zl}KzF;u}r1BiiGuz14+=Go+`w0YcZ-Uf5&aouhhm$OnMElx;vgs0(R3wuOl_ z*e&(lPr%Irwf2gqV@7A6IC@W$(%INSyjhrZK@pvdcJ{8U5^7WW(&KYtMFS&vt%caL zT?mA7ALY)$l<0)5lC^J|x5tHg94K3xOp~s2$p~9GzHeUf)Pu znjaMO;rGi_Ta56#Jgu1413>`kha1j2YW49X{kzFxg}k=~u_bwUW^4X&zwP_hq+57% zuDyhSS_2zDptKj>9u2{cpJk3Ojc-3Lu+!|>E}s^aCybK!1hjEF?fThWFf=I4QQBSe z+=GFd+DxT=!M*^&K*HhKYg&6#2+o?|B{%nITF#}!#3+;^|tft#zLirs-NV=+f}UdYx-HDAoaydD(_b0Q#=s-vIjmx zHTIa?X8tkwE-wd8uHRl7AyVUCnc%9#Geq$uS7)c0#9D1e zE;JMg36*evf(6%C%OP3ncOCg+*6+QNdl@Jw>}vfT8|0@Vh`t@czd-u?D;;L7=@Ixk zh`rPbkRUps1Nx@NO31y(ub`oBU&~a^k0hVDzgak#u$;nz!Ko$vZxF>sn zVLrG$oMcuOS2nwDB?-Z8hG>(7Yg(!S)H>cjb0 z`QUs_IiRPlnBu-Jit%iPTTObAg%K#vblk#{oZxe~G}LJr<IqI`b*l{!uxiiYWPyISr??;-|!-Av34_)tmI9!uU&@)V8 zcRo}%R~oAp(m}6c3wm?*=;lS0PP@E!&9>d9YPpl%8q^ej751CC!@uvPNn!i*vjJp* zyW+I?-;l@NlaSd*d6x?+Pgac#2M7*Js%P$2iCBJ59MyqJp<$00ar0bNI{L7>Yh&=o zE}eBxK~GBaQgkHk!;VsLYeesCPh{yzMfl|HB-Hm>jnSQKS)Zu%m{_6qGyobiFk81z zBU_?-)^Rkmj*GcYUXZUBRz94Cu)S!z|!uIi@~<~1F6!a@7%Lq#?_*}4&2D0 zsm3OO%a=-Eb*U@$o5r?&LhJ~Q(KcvXMBW;Q6f1JCSRKRr@XCQFo+JdVWY6;{kk&jFkR5(`?e+VqiF;)iy+xmXDJ|- z_$l5t5iM9AW!SWcfL`J}@DdG#D1JgXpA-J5(&Bi2>d4Ey-BJ!O?4ovfIv&fudVc$q z4i4utgNP{GP9{Lq`8SE_HtMEIB~WV!GE1oLQydwmbG+=Cu&9%a-WMzGFI4W;buME! zLXI+pWqXYo@^G85-siY2^L{_<4lP>Np3Gx`%5IKrblq4^QU2phNuwM6iJUqG~#^zO9n zY?Mv!e2#T0R%M43+CsWa*QX~YX1s&sZ_2b2lHS+4n`Homw3^R@-TZ>5JyY;YCK~OM z`AU1-PR0;aW521bk3Uw&+)UJ6Qdp@cmRaS8W=&rw#z;Mt@ifRNZGVr3@|C)AG0 z_IRqgu9X$anU*oJJa}n7c|XJp*LWMS1{V$DL>ou;xoM`=q^mG`SSz+?v8c(1%#li) z9ChnD4rqQ=k(2o|`$h*yeR#8Al-O zED1b--ANWL7j^f5L}Sto8Ug$X-jz%=AFT z<|gg&@nrPSI>xUpvYpu+7N`~rrkwoVzHF}Mh2;5agG9~eVEt;IIM%S~Lju^b+EL1R zqyqik7;ChMG^q|fpHa&FltvM_j{7wIn0cYPMh6tQSqlSmPSeg6M7*)O+JE>R_ph_3 zr&!}>RE(T+Ed;4h_iM7JEbe2vMVdVCH&oLSeH{!@==l||j#iY6JNmGAyt?lF)d0BF zS}9HvuWQl5No(P6lt3pv8{myUQ7}7APr1PNLrM?XDkj%r^P>HW?RP^yLRl?K&{oa{ zcaH_vl6^LA21bR#52NA*$j>V8f*Hj}2tm0r146iyy_ou8Ai;oRSJSd?Zc_l1)!_|MF~M7=ARWdA>)rDU+7CH6+uMR>Vwvh*l!K`E8-t!5z&6*j_t z{}wIP9^T&)x9x8L_G|WA+7kBo`I;oQR@qM<&qx0Ch&x*TpNNublXjXnqg7-3S*Wp= z*NSG#X({plI9$Tra~u9v{QkMLXBPR#a`T5%DZQ7Z`F5ORnY!P#^ff`UXJXu8NDxjP zQhP@eU>G}S#*3q0w-1bTXyv=ez-4DeOR*s)yilK@S?y;l9z%F>?#XF-+A^~XAjl4r z?#O*jmoG}r3Qb{Yq3Z%W{26)X5F9%@2fw}qHtd`xJrqOaOL$0pusP*hLY z)sPEu_7UVJMeOl^@A|tp7kUMmnAjV)I2fYjsoZd=?%Pgya?&M!t1)ZdaS=^7cqLs{ z^D7gl=oRP+G#n#P4!UvUGotgsdtTNgVP4(%Rk&pCsaye81>f|)mO6GJ@%n_iZs%6Z zK*EE^7XX`gHwP2`w4Z)p75ir@0JP8`lUg48yAM6}dcweA8>Rm<(F0YjgFix2>z$ex z#1^K|y{a>Tkv@J$t56qUdz+2(R!a8J#MQb~-QM3m{Fc*0eOY?n)W$wAt=M)s635L< z&{9jLsINl;+JRR*HFIOB>0k=)N57a17rTm~E`a?KXF(+`%f8k2rWg`RV9hEIpk52~Z@@OEo#IBi3xM_(+U!*29hYh*I~t}yIKBtjz0_+rqpXeX(vIj^i2dmcKqrIBf; zFyJc6(8Pr3S0GFt0^P`);hO>SYTvfPWClO9Ktwts)m{6t@CNd%Hhec z|E(XpcOJx1cX!y}sMDgWTH` z#H&;it|Zxtc>W}S6F<>=JTojJ;JvO6 zFZ@vwjd31o9ORQ|Gu7D;rhlODr;OXg4E1;|c@XvEK@io2poTn+YT14%$Q-VJ>7r~=)ptsOpAFBgflar6T^fuN^+dj5 z<0rJ(MiZ_agEZcqiaOJ1C2~T#Onc5)*P36o;6Bz(?u_HGY24UU92%c`fOvyR=w46& zEjhBsuWFje=USXs1dXFIrt)uW=L*Zx<7iA>Y}nNX9q2XgcugOuqCCR*dsOh8hRc__ zB_%lL-#bx?QqIY)_F=IewFsVTduk!Gd19!Y_Ns2qc`w;rZ}%>9%lD|P_D#LyA49Og z>w7Pa3Q0os?PnE0-_g1b(}5zjw1ZfLH05UKP$YKd>-P*;GN{^nBeCwTBhup^`9_^N zSBG87qom>f#-`S&2?*oMg+n9U9Baqj8Z{r$HF*y@F&hGFSgYi}xQI{XCGp^Vmi{T%XBMO<2e?@rE< zKCh!2Tb&yY=MutyTs{?q9KbiOMfZCTsbn^(@0Jzno^=-qVlUk{9>Bbe5%kByTeQLh z@{(=?UU@7istrt%-2l~`ZeIll$SqxFg`ai62Tfd;k=Ol_Q#IyVGnrNxQMR|XFdQ_h zY6SfOrc*mh9su%QIsaT^N&;DC4kPdueUg1GtaL$nvktGUl9r zUh~I*v(-I$ytzBJQv*GR)rS(YZu@tn4i{BHoiTj>b%$k*bu%pKCAf!jLS;g{XwBN_ zEJ?Wy;CxM}mB)B*72h^DhK>8Yy=_BVQX>^mI!Zp(wka@ zTYgyTa7q$vNj?EOVSz<6MV8KF3)=!cK*s(2-AG7~fpDm=%a1PoE1CC6X0ny@PAM7q zN;GGJ(;tn;1{KB*-DS9nYHXK8r@xU*?TvlY$^)xLGMaY`iF^HsN$KEj+)>^ctKvFJ zRobB6QT7=twdz!8#So0SCM$|Cq8XT)PBW6+K|aEL@rm1f7vt^r!3% zH*4t&9@{3E)zR%`9D{=5;OSo*%s0!Q^kErNK#{JgbfoJ!{t1I!T=C~xUY&5&&!DUL zM}R6$QKAr&{XdGwd1FJwVvREk=DL$sr(79)&A-5_voY2UT4sXi!CP8~S8ROu3+9X+ z;h!Q7xE*`X0Q}Yy$V?7&^rX9)kyu|fMsh}ao|c}|A)Odfv1?&h*>qET-1;u-6bfn! z+(pClcgOKj;afRc-pOu9h@F^1sQ;wa>RcyYn0mqfaQ&$1L*rY?kbov!9r%!U?fmBv zKSj_krNAI_6ieysyP7PZ{4VHx5^T&%z7M#P5BAT?gM?AkE3tyoV&yaz(sl-^)34Ig ztscdB+gzoBm|4!L1w88C442+D?>s@x+WzCvVYOCY&&|Z#%qBFU(q~I={$j(G@b`+( z@29qShd&_tqz5MF$H$H=dT<^)De{D-^2wODJFeq%CUc)gbRM?&2Yl|HjP1T+a3|wG z!ZX2{Lg!}lE7x?J>YU+?}4AlT-T{>}kZII)5u@VnqS(2JW^AX5|F zlri}Db{6Cl#V`%K)Cf<`t30QAcxtM>yfGz@h+fJ~AYc)W!lBiJR+xpEoFqZ^n7oXP z$a$0mJHd#fW>JitPTtUb2`Nm}a4MKQK4R_TcR#M8US89kcxx?7M!u+J$>6 zNs@7Q2{8c~qijMT1+v=%Rs5S@YIN{TK&g>zDE^bXyXK^|5)>-gZ9R2ggE7v#x+1IhM~Y?R$x|5 zv^4zJ-o`!3ThqB-OIAu`F0;o(7wNTVkKYs)l^@W&;Fj0ebabKDLttzQ)21(Zf0-`K z7uBUZcdOqbS|E&2&*Zt-8(-2hEHxPFaSfSj|6AA~Z;f(WYCC4ELLQr&^MsyntYDSt zTJ+o&f}A-hwg%`kCNrI5Duj>Cd`p;)TUeykn@eO*1cb)n zvEii8uMqlyO5WcAB9-F)kjkfsZs=KgERS!ZTi@~-sz}O^S0ruhSaRY)@Wqg^*WA4< zyR|v_-t%VVnf9Dk)*{%*8I8iCp3=B3>!&~)7F$LFJs5;tpjW*xR?3vo?|W-PsdvG` z)ak;^i^R|ae{;&@4jRf^C$}EffW1!YdlftGtxV=Ngs@oOb9;=4>Zoo&JmmeR{cFV0 zfTyM-VWl~)vF%^qp+)K2&h*{Ke(xDMV3n{>q24MJnjB4hvp8{r2>2Zm%3p>HPCHL! zE%7^h+Zmj_Z&x0s3?+iXj}37rU$Ec7!{_Zqt(W?L(p5)3|70^`US#ZrqXopjlbsf>izxm z5{8r#LMFe-iAMm1f*D6#IG{L|)m8YTT;+h5%;%Op_wbq(DpNOKe0MTi#9m+ODFMcQ zMQSFlcEmJU*^ew%=O@voz~t4S5KUwkr&vRu_Rpy+kf2B4uRLO1;+-!wpGu@7GVWPB zWKI*Zi%cG(;r69FX==9~4H#*v6P!XV+YwwykL&1af%T4(I=7XTt{1k@lidUYS8I5y zi|SV8CS378JioNuOv}hBQ((Y5Q@TSUZnyf{r331JA`Y$|WBM$`4!r2K#;~&2{z;C8 zkC(O(j3C_q!-={y?c*LNCthwkh9oT7(L# zsMP|k&sxCDWC9{d6iqp!G?Qu#d%udS=BUAG?(?H&g%Z(9&m`rY>5H53I$(&XI)#+; z6!AiX%IdKEr>vkV`Q87LSORNAyZ8>Xj3&O;8V;_GG$ z56O|`_BE%4)J|FG$$8b-w(EnhyG;oBNIOE^+_)FxTy9Qs3lO ziBZ=XL9~Mwy#KI!{w~CS%SimB+aprH;XusO|HMBoTh_hsZ9$X))G+V-6s_mZ4A?c-D-QoAvoPhLC4DZw_R z+C)LDG7@RL)p`7btHk)Po-~4-j+jz;?$E@2h1{kv6zwi|cUz`1^JbEO9o~b$TmAIo zc3P0l^tPYh+ahP#j^DWe7(XO#Fzs zcH@bo#U5dVJ22}M)0v+86&JdmfQnMjIV%PtU-kgoxB+^mYAr{ekQ}QN0w2xoeI>le zv?siu(U8u41Cj?;^5p?lG3+xo8XLZZDACIC!^I$Jxc`nteXB)rO;uupA3rV#-1WOk zF%bMs<4b@1blkR)l4~ki9G#ulR`wRYdmPR?K0t^Ip83%(*ii;Mi6_z^VhUryb(y|^ z{*(5TP7gK7eJ8O_Np%-4Dukb4L{}Ma%zYwG!bSv>pVz^IsAEn?_n34SqG;&gw@ONh zV*Ld5rHx|L9o$QboO)cgT#4c}uL!9l=ISA4^7Zu|1of+S$@;DdOyL%}PT;wH;Ahw4 z$C4lDQwyF>YdfS5p%m*=+I?3kZk;jXGg_kR;cVfG9(&PFK16X~iVh;=%)OFvR^$}q zAcYM>&+Ax*%n|E7|)EzO`3fwyMoWxW4sUaX=&Xwog-ef?gY3AB^ z4{B=0GD9p8W`-}S?OkP#Lvx&`lcicDlJ@7Dc^4^25<@mfBC*P3WN@n6cN z*Upm0fU%S@gl?|QS&OL*!aOXq4r$$ENWUjWgZbTxzU`imjLdOOKnuwuk&oF z?s(aIQH1_+H0^@=?#jWQm+_E}-#wYUCmrMy!jgms%PkyNKi?fve%F0l{_pbuJmjv$ z^2uRSsCNHQ2dCSW7KO@2y$bP|b!k6+Rhcz`IP03&G4eQYKFW zuXHBWqElV8H1pyVb>r}}0?A0dd8m+*Q+l1Al4CjWHdSBAxv-7W&4z3|IF*oYlV~ta zDv3uhOL?=C5=t@~dM(XgPb0TjiLAAKO0}n*7!%9SIbklFG6A+&zV^&mdqjRx)C@0^d%5$FH3*9FA#x}6~6o1bS{qW1tB|Bc5De)bWq` zVT&q6NTirjL_q%OY}^?q68Ksp_?8KDa{zDAC0ciNz6frN3D?5$zFe{HW{S?vy&rgG z!Aq?9we61APLh0H9OJrseq_2L!cns1*qCn~7NFwCrgs4Tge5=e z-SsxjNNZFlT2llDuq6$9cvntlKFd!Y0KhOh59J9dFGH?5O0QwuT`XIANPU`xUq{>5;@TiNkdB8#q9 zRJojs7Y6s+AkTUCg;TuRZ{%gl&7c8D;=JCYYX0}2I1J< zlpG*FOzOBs;_O^#K40_y$n^$DrRpgH;0-*QUjJRoBmy~AL-LvD)@ zg&X<|0H{ZVU1d|$nOk$-$Gr3LdNRu`e9o@h^a)3B6_VU|HM2MWW%AthJP)7kA9NH0 zRbwE|3;!2FVAzUpD+6rB)oqgPOGhDz|;NmCOYzEqqqXR%IY&Zsn-O+->;%6v1n^&YX;#Nu6I& z2QwSXN~S$lhE=|fb6yt@;f^`ra{Y)SUk~Xy`(Io6=;bq<9t=s$63!ndv(ymR1I;(l z|2<8&`Kx>&<(z6l7Jh2~A7!(M9QSVQH9jZq+( z+Z^c_3_$&laqdHO3tO8lZ1?r3$j2>te{UZk*JGkI$u{YBlc&rul=j{PnfBNyxvu?# zseEu!SaP^4K-ScmKkUcOjA7kUR(n@V{iWgGNSVHOm(uCyDYPucJeJ9=PHW^QIUCD% z!STIuHbC}5>WZB675*C+nodm-s4zeL_r8PN8|E;Dun04djeIkWpXi`vMXE-A`=PVD zX%NX@$cI`3Vj5QuDz?c29HP>J?74vAAD0aexqGF_gHU)~UAaI}hLUG$1;W&JZE;fy zX7qjcfa{t)=}Ps&v^8r?-e$%W$QG4{5L^Rg=tY=jDNx9o|7Hk? zT$$4w!D#4q#9dVs5KymzQqgXiah!463{1s$)KdMfC_OOredVaFK+v7>^T6GQgQAo0 zMd1K3-z*DF&E`Dva~9>li4os?YVc}z98zL>Xv!l@7`}CnvSHwr9IJDqu^g|CL_zzZ zI>?nUpfT2|1MyqP=fTsNU9&o(zlWb)Pb+__yPeAmqv1mjRV@wF41p&0t3q zWesWia6SB~!1dJpk`{C5I8waYkmi1C<7QH$=*DO0q(_8Bm8@RM7W0t-y+_RK)AE2< zy!1&kg8;=v>xFc+i)N7de^yVz6eUaruEAX#YhIpc8I?+SSD+pt?v7dVu4)D%zaby{ zGKshL|1eWtIt3DCZRCrxQV$kB%MyLB78bmCHZbDng{NBKb^yf}tY8iE3s{+l#iG>_ zS-sifj&2R5ngMI56$| zQqz{i3|!c1Z#R@DMmdIQKr#A3N};|Ljg$|5K+X$uLsjx*q63*}+=ImJF#njgOtkTu zWqTMHxY|T(fpfVBk2$UUhj^B)d8R?u>td_qUZ2cU8dIdH?YTT z%c;0C^YXns@976E$c$xjGr4N4-7*Bj3}l|^Vnu%_zAgVQ^+CLy4S4I6_QLiR zop@=_Wraa1wpZ@fg_0~7cmA@2y|EmceS#}LDgv1W@ zxv=nRBs}?ZW?l?Pl&?qb5OK`Ov1os_X<;|@oQ`UonHqo}2MjN|trnuoxn-UZgV`Pp z+HKVC0;DJxr_zrq269dw^0cb%AJpP8QPp%m9sk~U`u$0NE21GVw;8vM*qZI^O7#3= zU!{eSlM7mNri7?%J-o6O`V34JR)9;#zpxW7U!JtG zKv0Fp>%(nH5G{_|bd$f|_2ozp7K%=|^>I*+)N-+P_GpNDNk5cM_^tRy z8oD;!#vDOaL9{_Y!e)m0z-}{+xgRJo1SRd6W7+09xL$R1aD1cAhx^)vpqO&MGNku} zJ;&D=8=ECVL)6gE zmKt9XpUs^dgL4Yj^|M^MD4KL1w|g{k#3BNl;0!kABYKy#Zd~FYFD2y9)Ai6L81fce@eB7&u#=5n3_csi7nz zxF2^WGOyaQ5_csh2_77yK3cyuGK>HInzj~lG@(z%s)vBq){!C8?$*W^hfHa^CtdJ< zFNfvodD#qChLab+mh_qXZ_cxU6pTG2Pka+nSZ7njq?Cndm86mG!E6e5S?NM1{OY48 z_R((!&22C7K7WDUK`TL&C&;+or1B(dLgopdJ27ytJ`%x*! zsOuh7GdD*E@T!fH5peBH+oq2dC8DBs7C8g&+HixRStfALT#HCj`K6&DsVbM9`pzwA>ueGgrrd$5YnjPnyrzr*R zGWNbt5+@-Dp5Bg9%ZP(5=2yf6tqJe~jkZt^k@T3iubx6$dFB1K zlNM7LF+Q@~`mhazboq>Q`7V#X@mb-cO6Fhw3jS+iHf7mLV~t_#7RT zOyy)SN=SJSyyQ3kwD$xCn`>l@{Ny~^cLD0|(U575So(6O4P>Cs&1kDY)FftW=7J(+ zSa3CUp#P^Mw)J+}i-&ZN=tkks{v*uhgmy7B3#VB3zui9-&hrTlBvsw8#}TdS!%&x( z)5qRBVs^J=8Pa-) z5l1r5*ghQfYv%3}9SJnPo>qLFyk@(>PYi>EYm6QO)YIC3?IhYs8b34iBQt+wnHOdK zYGqFy?uxM5yrq^{FGcay$e4paprt?zIxt zBNA~{?U7hEt;JrAM0ULx)#(wOG~SFm8zjgIH!^)bCG{^3){!ac5i6QI++XbJ_k;1& z=HKvpJg_X>^4-}CY({Oia$(SBsVi$pC57g{cbvCY&od>fO%*QolwwGmt3ki4Ny>XS zfvTpworuq9NgZQ5+U_dE-7zf!G@f6)NP_BVa~cQGtRLjxA=#au|d@DM)Ed8m!?k-4=zIXF%G0w|(wFFlcA zF*HZRN=%`WCyoO!WG_Oko2uW6Ze9aa9Z0{-g zjLdr5UHYm-H2(>@yOF1-x(7)vv<2Ui&#adSVb(&8Id%JJy&`zUeq~*=d+MY`(*>=j zeXH$n1pGUDFGsoSj?)!CpRXB#tG>Ser{7tpJl*Nf!|dU%2hVt4?|AZB`^9lXl|*2W zjq@{@dtNIlW><&Lp$<3m1uu8blXVYBOS78M>Xhi+uiXu~g7URGGJlcZbX(y6_i}mH zz&7-k$X(pQo#KCGf#8KP!*bIo(us!;>sJ0~$z2^5qCL^@xk}*1pWz?Nhq(bE-zA|Z z@~w4VKk|tEQ-E3LM=i$AHshA=yZ5=3O@U|ECe99PEY=%GZ!V}#PqjoOg#hhRI&sqH zY0UG?=tw07JO+pjDO!S#J}kFi^AYs91xu5PTgB%CNPQcp&yh{l@O6UBDDFm}m-NxA zchL}(z@gbyy0#fKGQY9rCxzYO!hEZ0p5KHasl9`FOKx5oPpggMNFRXzkuINxB+tc^eVrgk_*>}Q)F zLL+(0*?6-xe#-`VTbiAEaQJ8w%Dh2T8p|@?9&GI#SVvE~_tl8LSNic#>tW4P{JZZ$ zt~eQn9KRwi;rBG%Lr%qrB6KWEF_yjk*P2aZ{DrG9ccsdu-oID9D!ul4H1p%T(`I8?d|d~A zoeTq?Q_|gGw)yt6s(>9t_~(1jNKoZq<_Nv=jqbx9WYKmU_#=`Dn?4VQo-k!wZa(U~ z7hXE0N6sZ9dCSv*qP}?E*kI0)=|J_>H8u7wae5;}cxa_V+u8HGOURqo4>t+cP-g!G zwr(D44wy23wO#%twPEX#U#$C|ya}s)!RJcIdN_v{5*5-Ns_I%th+Yx1MYBguPxHEjj0dvP+3$kb$QjHvSQ?!ej2p@r3+`%4h- z`?V%BR<_fu@V{BcA>`c&8n?JvK=5moSrUOi`QDaV4+dcdXh3J(`d%-=>#`!9O57l? za9aEiY&I`(f3CA|IE1Q8-a8Y&59!*w_UDR@Iza(I-($SMc?LUA|3xf%i1~%P(~cS# zpk(KcgB=|wx_mN{|J--fX7Y$Wm?bw&=-ECX`VGPSlh5L zu{_-Ol{RZG2c+%#*YkV7xL1C0g~mdiM#8J|$gks?lHmQMHKoyE@Vim4Zl%UU)`PPZ zv^(Y#gkZmadMe=8V@fwy|AViT;E!{~y#cQ@YF8T=PDt@~ZDVOy=dg{^b&ckkSRre+ z7Ow=ypa_3BA9c5G%{~N^)($jPMl54CgE&j%hY*_$?V|S8qs)s;=*P2yo|>@`OLHDI zgc@zS;R`wE_UQjLbR}GA7}&b!`6j*@O`N_=Vzfp(uctC?j3zEY6VW%#G8)b76v9s?rMEM z>#BAXG$roAyZz_y($}5!uE^>vlg$2-eu~BGNy&<42awDYyvOY|p+G&_eAOXKjll*) zAKjwcNbEzkAlr$Eai`0CR3qwCE}IDo=^A28Pz9>9(fxcVnRkr!?$rCIHR4j3*rvoL z)w*nov{QQ};ZJk7_vgGmFpImKFB1x&*cTJv*4o<^49Z2SmDqZ|9f(x}i{#>O`cr9h zMb;JnWI~XF`jO5COW(x?eWVdg$o3l1u_L!W+^d`lk^oF}`E-+ou&sz)o)9tTgsa$< zv>uk#8T!8FM9s+&1pIIx^L+onPw-&nCIlkz^XP=JDTizHeg63>JUyZOW1|Nc#w@|$ zFEPdTfew1>&@d_1{YdwBmfj-m=DQJc+0rkX6@QIWDeXYd!+D`~4Wf=ab9E`& zYbHyo+Xd)_&!i;tX;a0SmtA2o;jl%cIBWgLA%5yt+EWvg1(>WBPvsS)mao_lcfEI^ zj0{8e(mFc3xF_>CY*2n$(9(KUHcaPpSdn>B>7VORMc-d_83k`m^^(i(n53k0AsSJ9 z6ji>d5MXe!x7sCNNUSNtU=H1&Zg_ENEnT)9B38AH7!fC9nDK`8ZAYNdTxZJ27^*@~ zAbGoDZ~KWVyKaEtK3yH+(`3?Z3r{y)BEC7PmOi*n%~vyBWw8Ae*}~T*jV1WYFC!xk z(&VJ`C`Ze6v+8>lm$mgR=>0RFvIIEy*%^UPGzdN|NeVgQJ4#Nyl|1JMB%HBd%CA`0 z$ThL#6l`z$6_Wcl!_d`)#s_@XYawUd*w1@-PUGP~fqj1f=}CsE+6~i-72(l5wG#P@ zCOS~~Tqf1SYx(Z`^n3P?Z|;FDmsHdqy{>&hK%tmC*@L({tnr>ILAJSTpM26`Qmb}R zySU-CuUu&j_9zej%2gX-9e+3m? zW^wt8n@kU&I!n7lXSnkO9%Rsn;LIglEKQ51X8uTw`( zZT~aPrug5PI`(sG!K}Tw1p6{=bxo*DfL84k^mHok(}<4jJlT+}?EW~1qh<|EwYsw& z)*Wn^Hkn1=YkLW`J3jCfo$m*-Mwps_vl`5Osh^1C&@fp@=D}kA$d>LwjJD6bn1^66elB@5)v->U-bfhSWrU&8 zqrkuPqb$2HoG%DuHh@S@R3QAk!C-|^6cyI|vfOGM1kCN7rKGRxvge#i`zgt$7NcPR z0beK4re&h#kj*>uYN$A@|A`KX49`c$Cp!1e(Hmu4S4iW@1(#0v(>Kofzqo)`i2sGp z;?lG^LV**szpdp_t6iJ%U~a_g$K0{oR@Y3Ap<4_?7(fwm@^%f0N&W4?Zt<5?%=&as zY~_EoyDQ{Lk=*Qyv-Gu|`>q|a?UC-u0Cq{=bqlU_firB+bful8936hiULy|G#lw3t zQqK4@O`FPmW30fP0GNv##KQQSDQ1EHV{qZr*vRx2WPfeX`4aVPQu53sg?F#!qQ~c~ zXeqv)dRTKh5&S@r_Ph{hl^7t{7-IM=TTWOXCW!MHtt~te}=rCDyD=E3K1A-{# z_C-)4#WD1SmzP|Q~#%Gp_^^}cRX4G9t~Mpk3!fAC*iM%~(I zdV?IVefYVsGs^Ub{wNf~0UwO0(f- z^#OfB-6R)pgR_YB^s?>rX1L(U;ZS{J%Stfuw)s|P6CI|Z6eQOksWsVjmdj--@#6yf z`0ENO-&paR=)3*JcsPq*W8D%OfvDp_xoCL=btYIATY_5=T~5>LX53RoIlWmArjYRb z^wqGyMA1SIVo7dAe$Tm5^-S#p*r86Gv$6-fDQ&Ll$#|q~58h)n8+Hdn!BvS{OkQBP z(n^${=Ei>_YwgiOpUV5;ELgHuzwV)KZX$+a;+7*tIL%sD}Y^r;lwVp`eoIY z%4t?=`;T;O%E?|eN@BmgHt4|+omvJ~?-&+rDp4LF@AR>?Ejrir?4C5uHBd0(qs7H4 zRX!>bztp{v(43enY8FPLN7{Q&&mA#Iw}4*_@ld_lBaTs1XVl$aZI!L?F0(K7@~*h#EhT zCXLQAyBgP&Y<4j`JkTGmP^)rvspAa}J;a$$WG{nZUc_vPX(m|UcRU09>7nMBhyQIO z1e?X%)b4W{_Nt;+7$h#Pmo(`Yy%2b3!Xi#?SH)HJ2H_eWs@N9W30HMU&Q7M1%q6nKWgnf7MKAo$pS}jQU8ZK!aN{W!1D68 zQlXFtaAy~zeU7M0aFqb7cFYxn&E4j<3BX|sWj4gHfr=W)sH|i02?5HlfyUfSvtXlw z8kit;9fV{xAIURI9~Q9VDmLVT6+rus?Qi?@aUjMifJnR?`A=f~>x1}(eu#IAtr^NT zu*Qq+zYF-TF)?*mC*|LZ)GHJKI;(KVq zyT7YOJ8z;}8(2(GsZKgv@j5AA3t$(F9611p) zK}}Ir<~|+U0Pk!^qoAWZN;`+8t26SKYeQ<*SvhGBb&lvE1Nx}2$3@01c5Mhbu*{RK zQR;ya61t@g8q4*Yx^ZY=r_~6%Li#ZL-CG8yHV2jHeY$uqtp7KTo{r!f7ihSp2ZEeo zN5J>Kx&BzzzFqb;Io<9l~6?Y3aob@Zs41B}3F%~6(gvXZxH`H6X z!&GG8RjxY)dE45ztz)uq0nGFY{Qg0KA7j$1y#z^f*3;iWLKp8UB3G9y>L&<_&h(xV z<~qOV>=I-JDv0i%%eIU#=0I>Gg1T*fvF~Z%aLZ)6`cYtTXjblj1#J(Gx>KGiBC+&( zMgJT_u{BJFYsZp4Hu--eoo#SG-O=Y6`%pQ!DQ@c72pXz0s$ox1it0D1V}?ZMuFGc? ztX;gh8TWqMm>YI;t$ju)I9cAdu$xMSI~L!4#zGS3cm}CF+tNG_on@pH$2X*g8wX|= zOSJpP17K`91Z7bZxQD1;7Lp@a)5c5LhgFH;OVSq`=6tU-1@A`SK-+JA@J>22XOT1& zV#?$~jD1Lt9P2cww}d;KyDp>xyQ;b`qm8VVAYSlf&aL22);LQ2rv$A1am^D5yWDe5 zQ&}s>*yJaJGd@LZO;Q|2TjQ^T>9xs6$$x-&MK6P9#4})js76;}ChZHocMnP5Dq-oR z?i*uH@o-icET6g<@Vd~S1l}8=)==ILBJsc1U+4vdet*5IN^rofpCc(v4H7bexrOnO z5zi|()|`rRJV;zuPPjVH*Mz-$sn1BXH;`8|i#YT(ZkX}WL^P4jA<|UzqeAHVrdO$r zP9TG7JOU`mK5xy{v*gv#Q5T&-yDL>{;{{Oh%?2Ce;=Uo@qi@}=TRZdRcPS+DNRZ!{*_7nPB%kH8lx^Hl)q%M|vrvgvZZw zB7*r(bfZm_Y88zqTlnGR$o*phQ50eSTmyQIK7&dP9eqdAm8YtL;-uR`utF9BjMz&Q zk!f>wZ`z`E?XCMiSgytj`XZP}RPlJkkmX5p1Xa(Hv^Dh5@e9W{Dx1@QTS#rJ&9_3T zGbmB|Yil9205y3p-)UQ4gr>B){lPD*bX@l&MLVeF+-$fMsK1IxZF08h+09eKynw81 zd-j!d;WOGSWB1d2#X3x4W6Cdyo($~fU!|NC3RcK>A%qeMQmUyOu+G^~?e?aFN#d#V zY!z}tF~g?l(qPZ|k&_T^PQDo^;JNCZ`kLh0<5R=VlqpQFE5Wps4wQVM4v3r+e+sjRL|r?!QKFQ&6wcf`F%9Cm*=RQ!0s}|hh_PaO*Sp~9jRR+ zM8W({ljy{TZ+n||z9D0^wI>5R($|1C&9KU`#3B$(FS?nRi|an|b!sW=4v5iWq5u+5 z7Z0hgt)b}AhL5$Qv05lR2ee%^WZs{Dxbk@9C)&c|LpA(czm<@pu!CS2hy3Ol|99ra z39ck9Ce}5&*t$Nw*s`JB);G0&16S)$nq;|Va&xfJ4Wnj`ZaSY)H%m0QZyuX`=f)Rt zdpFI9U$9G7C}fV?7SyK!us@FCVz_68(OBo+&hXb=btWa~m!bBh>O{4s{6SD>242So zd`{yDQcP#p=Pc%)izvYX+VlDD4+YtLP9A0~K{M+p%4OhG(wr-eE+a$mG-RiS17^w3 zMENkt&M+O%+?y7v=Mv_xhl`~kuTfMjAm#?%*IL+fD0LjTr9I|2w8%7%mz?!KSr}N3 z8wNW!$)6i+Ymn3at_2g&=o%)E1!+X1P3u!bDUN%5FWLE348i`WPM#?*MDk+(iNRbx zz=WwZL*WbEvLPSCsj-S$q|bL4$-72D=12tg!W}**{y~n}8E|Z8-ZLt8FA&6T_jS(A muDr#`-Ceu{(P8!B`xd^98v0?r>5bhw_u<9AF+aHSkN*b%dWL%d literal 0 HcmV?d00001 diff --git a/mime/index.html b/mime/index.html new file mode 100644 index 0000000000..93f399260b --- /dev/null +++ b/mime/index.html @@ -0,0 +1,50 @@ + + + + + + mime | Jacky's blog + + + + + + + + + + + +

+ + + diff --git a/more/index.html b/more/index.html new file mode 100644 index 0000000000..092a7d2d8b --- /dev/null +++ b/more/index.html @@ -0,0 +1,60 @@ + + + + + + more | Jacky's blog + + + + + + + + + + + + + + + diff --git a/other/index.html b/other/index.html new file mode 100644 index 0000000000..371000a6bc --- /dev/null +++ b/other/index.html @@ -0,0 +1,124 @@ + + + + + + other | Jacky's blog + + + + + + + + + + + +
+ + + diff --git a/pages/0140a0/index.html b/pages/0140a0/index.html new file mode 100644 index 0000000000..87d7ef2a33 --- /dev/null +++ b/pages/0140a0/index.html @@ -0,0 +1,118 @@ + + + + + + shell | Jacky's blog + + + + + + + + + + + +
+ + + diff --git a/pages/02f88a/index.html b/pages/02f88a/index.html new file mode 100644 index 0000000000..9f4f2c3040 --- /dev/null +++ b/pages/02f88a/index.html @@ -0,0 +1,58 @@ + + + + + + 字符串 | Jacky's blog + + + + + + + + + + + +
+ + + diff --git a/pages/03456e/index.html b/pages/03456e/index.html new file mode 100644 index 0000000000..72bf37955f --- /dev/null +++ b/pages/03456e/index.html @@ -0,0 +1,46 @@ + + + + + + 使用腾讯云服务器 | Jacky's blog + + + + + + + + + + + + + + + diff --git a/pages/086701/index.html b/pages/086701/index.html new file mode 100644 index 0000000000..569c0c210e --- /dev/null +++ b/pages/086701/index.html @@ -0,0 +1,47 @@ + + + + + + 音视频概述 | Jacky's blog + + + + + + + + + + + +
+ + + diff --git a/pages/0c11ea/index.html b/pages/0c11ea/index.html new file mode 100644 index 0000000000..b766a71971 --- /dev/null +++ b/pages/0c11ea/index.html @@ -0,0 +1,46 @@ + + + + + + apis | Jacky's blog + + + + + + + + + + + + + + + diff --git a/pages/0cdfba/index.html b/pages/0cdfba/index.html new file mode 100644 index 0000000000..8ff4e7aa9a --- /dev/null +++ b/pages/0cdfba/index.html @@ -0,0 +1,61 @@ + + + + + + gradle | Jacky's blog + + + + + + + + + + + +
+ + + diff --git a/pages/0d7cc1/index.html b/pages/0d7cc1/index.html new file mode 100644 index 0000000000..80e7f9ec42 --- /dev/null +++ b/pages/0d7cc1/index.html @@ -0,0 +1,44 @@ + + + + + + 服务器tutorial | Jacky's blog + + + + + + + + + + + +
+ + + diff --git a/pages/0fe5d6/index.html b/pages/0fe5d6/index.html new file mode 100644 index 0000000000..97e75b2eea --- /dev/null +++ b/pages/0fe5d6/index.html @@ -0,0 +1,167 @@ + + + + + + frida | Jacky's blog + + + + + + + + + + + +
+ + + diff --git a/pages/109caf/index.html b/pages/109caf/index.html new file mode 100644 index 0000000000..5e69b19dd9 --- /dev/null +++ b/pages/109caf/index.html @@ -0,0 +1,45 @@ + + + + + + 移动端的网络优化 | Jacky's blog + + + + + + + + + + + +
+ + + diff --git a/pages/10a997/index.html b/pages/10a997/index.html new file mode 100644 index 0000000000..e95e2f723a --- /dev/null +++ b/pages/10a997/index.html @@ -0,0 +1,44 @@ + + + + + + websocket-socket | Jacky's blog + + + + + + + + + + + +
+ + + diff --git a/pages/10e7db/index.html b/pages/10e7db/index.html new file mode 100644 index 0000000000..de845b9a44 --- /dev/null +++ b/pages/10e7db/index.html @@ -0,0 +1,46 @@ + + + + + + Android密钥系统 | Jacky's blog + + + + + + + + + + + + + + + diff --git a/pages/12d86f/index.html b/pages/12d86f/index.html new file mode 100644 index 0000000000..a709b37f15 --- /dev/null +++ b/pages/12d86f/index.html @@ -0,0 +1,44 @@ + + + + + + tutorial | Jacky's blog + + + + + + + + + + + +
+ + + diff --git a/pages/140cb3/index.html b/pages/140cb3/index.html new file mode 100644 index 0000000000..10417df42f --- /dev/null +++ b/pages/140cb3/index.html @@ -0,0 +1,53 @@ + + + + + + python snippet code | Jacky's blog + + + + + + + + + + + +
+ + + diff --git a/pages/186356/index.html b/pages/186356/index.html new file mode 100644 index 0000000000..0b8d380fff --- /dev/null +++ b/pages/186356/index.html @@ -0,0 +1,50 @@ + + + + + + 管理学 | Jacky's blog + + + + + + + + + + + +
+ + + diff --git a/pages/18abfe/index.html b/pages/18abfe/index.html new file mode 100644 index 0000000000..4928d7ff3a --- /dev/null +++ b/pages/18abfe/index.html @@ -0,0 +1,46 @@ + + + + + + tutorial | Jacky's blog + + + + + + + + + + + +
+ + + diff --git a/pages/1bc90b/index.html b/pages/1bc90b/index.html new file mode 100644 index 0000000000..851a123e00 --- /dev/null +++ b/pages/1bc90b/index.html @@ -0,0 +1,47 @@ + + + + + + switch | Jacky's blog + + + + + + + + + + + +
+ + + diff --git a/pages/1c262c/index.html b/pages/1c262c/index.html new file mode 100644 index 0000000000..55679dd95d --- /dev/null +++ b/pages/1c262c/index.html @@ -0,0 +1,47 @@ + + + + + + docker | Jacky's blog + + + + + + + + + + + +
+ + + diff --git a/pages/21df4f/index.html b/pages/21df4f/index.html new file mode 100644 index 0000000000..f2febb8b07 --- /dev/null +++ b/pages/21df4f/index.html @@ -0,0 +1,95 @@ + + + + + + 生产环境Message分发处理设计 | Jacky's blog + + + + + + + + + + + +
+ + + diff --git a/pages/22d48b/index.html b/pages/22d48b/index.html new file mode 100644 index 0000000000..73b929faff --- /dev/null +++ b/pages/22d48b/index.html @@ -0,0 +1,53 @@ + + + + + + 服务器面试题整理 | Jacky's blog + + + + + + + + + + + +
+ + + diff --git a/pages/233ea5/index.html b/pages/233ea5/index.html new file mode 100644 index 0000000000..ec2b64004f --- /dev/null +++ b/pages/233ea5/index.html @@ -0,0 +1,46 @@ + + + + + + Database | Jacky's blog + + + + + + + + + + + +
+ + + diff --git a/pages/29a4de/index.html b/pages/29a4de/index.html new file mode 100644 index 0000000000..b36097624a --- /dev/null +++ b/pages/29a4de/index.html @@ -0,0 +1,108 @@ + + + + + + perfetto | Jacky's blog + + + + + + + + + + + +
+ + + diff --git a/pages/2a8b7b/index.html b/pages/2a8b7b/index.html new file mode 100644 index 0000000000..8d70192fd2 --- /dev/null +++ b/pages/2a8b7b/index.html @@ -0,0 +1,43 @@ + + + + + + HTTP | Jacky's blog + + + + + + + + + + + +
+ + + diff --git a/pages/2af3e9/index.html b/pages/2af3e9/index.html new file mode 100644 index 0000000000..60ca04149b --- /dev/null +++ b/pages/2af3e9/index.html @@ -0,0 +1,43 @@ + + + + + + 效率秘籍 | Jacky's blog + + + + + + + + + + + +
+ + + diff --git a/pages/30ec1d/index.html b/pages/30ec1d/index.html new file mode 100644 index 0000000000..b3a006e8a7 --- /dev/null +++ b/pages/30ec1d/index.html @@ -0,0 +1,49 @@ + + + + + + vuepress的简单记录 | Jacky's blog + + + + + + + + + + + +
+ + + diff --git a/pages/37f363/index.html b/pages/37f363/index.html new file mode 100644 index 0000000000..23836933da --- /dev/null +++ b/pages/37f363/index.html @@ -0,0 +1,74 @@ + + + + + + adb | Jacky's blog + + + + + + + + + + + +
+ + + diff --git a/pages/3869be/index.html b/pages/3869be/index.html new file mode 100644 index 0000000000..09146b64f8 --- /dev/null +++ b/pages/3869be/index.html @@ -0,0 +1,46 @@ + + + + + + web工具 | Jacky's blog + + + + + + + + + + + +
+ + + diff --git a/pages/39870b/index.html b/pages/39870b/index.html new file mode 100644 index 0000000000..12d5924210 --- /dev/null +++ b/pages/39870b/index.html @@ -0,0 +1,58 @@ + + + + + + 了解spring | Jacky's blog + + + + + + + + + + + +
+ + + diff --git a/pages/3adccf/index.html b/pages/3adccf/index.html new file mode 100644 index 0000000000..89bc30ad0f --- /dev/null +++ b/pages/3adccf/index.html @@ -0,0 +1,48 @@ + + + + + + mac常用工具使用 | Jacky's blog + + + + + + + + + + + +
+ + + diff --git a/pages/3aeda3/index.html b/pages/3aeda3/index.html new file mode 100644 index 0000000000..671d567a79 --- /dev/null +++ b/pages/3aeda3/index.html @@ -0,0 +1,63 @@ + + + + + + beautysoup | Jacky's blog + + + + + + + + + + + +
+ + + diff --git a/pages/3d30c9/index.html b/pages/3d30c9/index.html new file mode 100644 index 0000000000..6a67a9d2f3 --- /dev/null +++ b/pages/3d30c9/index.html @@ -0,0 +1,50 @@ + + + + + + 正则 | Jacky's blog + + + + + + + + + + + +
+ + + diff --git a/pages/3dd4b2/index.html b/pages/3dd4b2/index.html new file mode 100644 index 0000000000..a0dba27d9e --- /dev/null +++ b/pages/3dd4b2/index.html @@ -0,0 +1,101 @@ + + + + + + HTTPS | Jacky's blog + + + + + + + + + + + +
+ + + diff --git a/pages/411579/index.html b/pages/411579/index.html new file mode 100644 index 0000000000..b7fe6de179 --- /dev/null +++ b/pages/411579/index.html @@ -0,0 +1,46 @@ + + + + + + node版本管理 | Jacky's blog + + + + + + + + + + + +
+ + + diff --git a/pages/420ab6/index.html b/pages/420ab6/index.html new file mode 100644 index 0000000000..5b5ba9a462 --- /dev/null +++ b/pages/420ab6/index.html @@ -0,0 +1,46 @@ + + + + + + android图形系统 | Jacky's blog + + + + + + + + + + + +
+ + + diff --git a/pages/4595e1/index.html b/pages/4595e1/index.html new file mode 100644 index 0000000000..bbe54692ce --- /dev/null +++ b/pages/4595e1/index.html @@ -0,0 +1,74 @@ + + + + + + python学习 | Jacky's blog + + + + + + + + + + + +
+ + + diff --git a/pages/4db36a/index.html b/pages/4db36a/index.html new file mode 100644 index 0000000000..0660877a8e --- /dev/null +++ b/pages/4db36a/index.html @@ -0,0 +1,91 @@ + + + + + + 记录-在已有的项目基础上扩展回调 | Jacky's blog + + + + + + + + + + + +
+ + + diff --git a/pages/4f876a/index.html b/pages/4f876a/index.html new file mode 100644 index 0000000000..ce426dbccc --- /dev/null +++ b/pages/4f876a/index.html @@ -0,0 +1,46 @@ + + + + + + web 术语 | Jacky's blog + + + + + + + + + + + +
+ + + diff --git a/pages/4f9b39/index.html b/pages/4f9b39/index.html new file mode 100644 index 0000000000..1b1785f7b8 --- /dev/null +++ b/pages/4f9b39/index.html @@ -0,0 +1,43 @@ + + + + + + 属性 | Jacky's blog + + + + + + + + + + + + + + + diff --git a/pages/514538/index.html b/pages/514538/index.html new file mode 100644 index 0000000000..5386df2076 --- /dev/null +++ b/pages/514538/index.html @@ -0,0 +1,60 @@ + + + + + + github | Jacky's blog + + + + + + + + + + + +
+ + + diff --git a/pages/548959/index.html b/pages/548959/index.html new file mode 100644 index 0000000000..a845f36e0d --- /dev/null +++ b/pages/548959/index.html @@ -0,0 +1,61 @@ + + + + + + javascript | Jacky's blog + + + + + + + + + + + +
+ + + diff --git a/pages/55dc87/index.html b/pages/55dc87/index.html new file mode 100644 index 0000000000..581fc00843 --- /dev/null +++ b/pages/55dc87/index.html @@ -0,0 +1,47 @@ + + + + + + 集合 | Jacky's blog + + + + + + + + + + + +
+ + + diff --git a/pages/59b0a9/index.html b/pages/59b0a9/index.html new file mode 100644 index 0000000000..05f65f729e --- /dev/null +++ b/pages/59b0a9/index.html @@ -0,0 +1,47 @@ + + + + + + CDN-DNS-httpDNS | Jacky's blog + + + + + + + + + + + +
+ + + diff --git a/pages/59f768/index.html b/pages/59f768/index.html new file mode 100644 index 0000000000..f07ec7e667 --- /dev/null +++ b/pages/59f768/index.html @@ -0,0 +1,43 @@ + + + + + + 如何优雅地获取跨层级实例 | Jacky's blog + + + + + + + + + + + +
+ + + diff --git a/pages/5a96b7/index.html b/pages/5a96b7/index.html new file mode 100644 index 0000000000..cac2288727 --- /dev/null +++ b/pages/5a96b7/index.html @@ -0,0 +1,47 @@ + + + + + + 网站 | Jacky's blog + + + + + + + + + + + +
+ + + diff --git a/pages/5d8ba8/index.html b/pages/5d8ba8/index.html new file mode 100644 index 0000000000..e14c8a8c5f --- /dev/null +++ b/pages/5d8ba8/index.html @@ -0,0 +1,47 @@ + + + + + + Android零耗时首帧体验 | Jacky's blog + + + + + + + + + + + +
+ + + diff --git a/pages/651b48/index.html b/pages/651b48/index.html new file mode 100644 index 0000000000..8dc2928861 --- /dev/null +++ b/pages/651b48/index.html @@ -0,0 +1,43 @@ + + + + + + 理解虚拟Dom和key属性的作用 | Jacky's blog + + + + + + + + + + + +
+ + + diff --git a/pages/6570ab/index.html b/pages/6570ab/index.html new file mode 100644 index 0000000000..cefccf47ca --- /dev/null +++ b/pages/6570ab/index.html @@ -0,0 +1,63 @@ + + + + + + 如何触发组件更新 | Jacky's blog + + + + + + + + + + + +
+ + + diff --git a/pages/669dfc/index.html b/pages/669dfc/index.html new file mode 100644 index 0000000000..fb3f3094df --- /dev/null +++ b/pages/669dfc/index.html @@ -0,0 +1,47 @@ + + + + + + npm | Jacky's blog + + + + + + + + + + + +
+ + + diff --git a/pages/6ab0a7/index.html b/pages/6ab0a7/index.html new file mode 100644 index 0000000000..24a30c583b --- /dev/null +++ b/pages/6ab0a7/index.html @@ -0,0 +1,48 @@ + + + + + + spring | Jacky's blog + + + + + + + + + + + +
+ + + diff --git a/pages/6c1d02/index.html b/pages/6c1d02/index.html new file mode 100644 index 0000000000..ba72734624 --- /dev/null +++ b/pages/6c1d02/index.html @@ -0,0 +1,44 @@ + + + + + + 小伟和小娟 | Jacky's blog + + + + + + + + + + + +
+ + + diff --git a/pages/6cd2e1/index.html b/pages/6cd2e1/index.html new file mode 100644 index 0000000000..e72bf566c8 --- /dev/null +++ b/pages/6cd2e1/index.html @@ -0,0 +1,46 @@ + + + + + + 沟通的艺术 | Jacky's blog + + + + + + + + + + + +
+ + + diff --git a/pages/6ea216/index.html b/pages/6ea216/index.html new file mode 100644 index 0000000000..59c0404a95 --- /dev/null +++ b/pages/6ea216/index.html @@ -0,0 +1,46 @@ + + + + + + 前言 | Jacky's blog + + + + + + + + + + + +
+ + + diff --git a/pages/7071e6/index.html b/pages/7071e6/index.html new file mode 100644 index 0000000000..9784323ec0 --- /dev/null +++ b/pages/7071e6/index.html @@ -0,0 +1,50 @@ + + + + + + git | Jacky's blog + + + + + + + + + + + +
+ + + diff --git a/pages/79c121/index.html b/pages/79c121/index.html new file mode 100644 index 0000000000..b9b971776c --- /dev/null +++ b/pages/79c121/index.html @@ -0,0 +1,45 @@ + + + + + + tiktok在国内使用 | Jacky's blog + + + + + + + + + + + +
+ + + diff --git a/pages/79f386/index.html b/pages/79f386/index.html new file mode 100644 index 0000000000..46bf634463 --- /dev/null +++ b/pages/79f386/index.html @@ -0,0 +1,46 @@ + + + + + + jadx | Jacky's blog + + + + + + + + + + + +
+ + + diff --git a/pages/7c68cb/index.html b/pages/7c68cb/index.html new file mode 100644 index 0000000000..2e927a4c62 --- /dev/null +++ b/pages/7c68cb/index.html @@ -0,0 +1,46 @@ + + + + + + 读kk大神聊房价 | Jacky's blog + + + + + + + + + + + + + + + diff --git a/pages/7e542a/index.html b/pages/7e542a/index.html new file mode 100644 index 0000000000..e5869520d5 --- /dev/null +++ b/pages/7e542a/index.html @@ -0,0 +1,44 @@ + + + + + + 前言 | Jacky's blog + + + + + + + + + + + +
+ + + diff --git a/pages/7ee6cc/index.html b/pages/7ee6cc/index.html new file mode 100644 index 0000000000..6667e94f92 --- /dev/null +++ b/pages/7ee6cc/index.html @@ -0,0 +1,52 @@ + + + + + + pip3 | Jacky's blog + + + + + + + + + + + +
+ + + diff --git a/pages/82e5d7/index.html b/pages/82e5d7/index.html new file mode 100644 index 0000000000..8b9a7c226e --- /dev/null +++ b/pages/82e5d7/index.html @@ -0,0 +1,46 @@ + + + + + + components | Jacky's blog + + + + + + + + + + + + + + + diff --git a/pages/857c89/index.html b/pages/857c89/index.html new file mode 100644 index 0000000000..b88819c5e1 --- /dev/null +++ b/pages/857c89/index.html @@ -0,0 +1,46 @@ + + + + + + 快速实现 | Jacky's blog + + + + + + + + + + + +
+ + + diff --git a/pages/86683c/index.html b/pages/86683c/index.html new file mode 100644 index 0000000000..e18bd3a04b --- /dev/null +++ b/pages/86683c/index.html @@ -0,0 +1,43 @@ + + + + + + 事件 | Jacky's blog + + + + + + + + + + + +
+ + + diff --git a/pages/89d231/index.html b/pages/89d231/index.html new file mode 100644 index 0000000000..7d1dd65928 --- /dev/null +++ b/pages/89d231/index.html @@ -0,0 +1,51 @@ + + + + + + vim | Jacky's blog + + + + + + + + + + + +
+ + + diff --git a/pages/8cb2e1/index.html b/pages/8cb2e1/index.html new file mode 100644 index 0000000000..5beaef6173 --- /dev/null +++ b/pages/8cb2e1/index.html @@ -0,0 +1,46 @@ + + + + + + unbuntuOnWindows | Jacky's blog + + + + + + + + + + + +
+ + + diff --git a/pages/8fbdb4/index.html b/pages/8fbdb4/index.html new file mode 100644 index 0000000000..36dac690ef --- /dev/null +++ b/pages/8fbdb4/index.html @@ -0,0 +1,44 @@ + + + + + + 原理 | Jacky's blog + + + + + + + + + + + +
+ + + diff --git a/pages/907793/index.html b/pages/907793/index.html new file mode 100644 index 0000000000..94e18491dd --- /dev/null +++ b/pages/907793/index.html @@ -0,0 +1,46 @@ + + + + + + aapt | Jacky's blog + + + + + + + + + + + +
+ + + diff --git a/pages/935419/index.html b/pages/935419/index.html new file mode 100644 index 0000000000..ec5c0afb7a --- /dev/null +++ b/pages/935419/index.html @@ -0,0 +1,46 @@ + + + + + + 使用 Jenv 实现 Jdk 多版本管理 | Jacky's blog + + + + + + + + + + + +
+ + + diff --git a/pages/977efe/index.html b/pages/977efe/index.html new file mode 100644 index 0000000000..87bf3b531b --- /dev/null +++ b/pages/977efe/index.html @@ -0,0 +1,47 @@ + + + + + + c++工具 | Jacky's blog + + + + + + + + + + + +
+ + + diff --git a/pages/9b0a57/index.html b/pages/9b0a57/index.html new file mode 100644 index 0000000000..4fe61c9535 --- /dev/null +++ b/pages/9b0a57/index.html @@ -0,0 +1,46 @@ + + + + + + apm相关概念 | Jacky's blog + + + + + + + + + + + +
+ + + diff --git a/pages/9c451e/index.html b/pages/9c451e/index.html new file mode 100644 index 0000000000..3f2830026e --- /dev/null +++ b/pages/9c451e/index.html @@ -0,0 +1,66 @@ + + + + + + 技巧记录 | Jacky's blog + + + + + + + + + + + +
+ + + diff --git a/pages/9f55fd/index.html b/pages/9f55fd/index.html new file mode 100644 index 0000000000..5f6c8deafb --- /dev/null +++ b/pages/9f55fd/index.html @@ -0,0 +1,43 @@ + + + + + + tutorial | Jacky's blog + + + + + + + + + + + +
+ + + diff --git a/pages/a0d7dc/index.html b/pages/a0d7dc/index.html new file mode 100644 index 0000000000..d66add0051 --- /dev/null +++ b/pages/a0d7dc/index.html @@ -0,0 +1,46 @@ + + + + + + Android低端机性能优化 | Jacky's blog + + + + + + + + + + + + + + + diff --git a/pages/a96c0f/index.html b/pages/a96c0f/index.html new file mode 100644 index 0000000000..e7573dd61f --- /dev/null +++ b/pages/a96c0f/index.html @@ -0,0 +1,126 @@ + + + + + + GitHub Actions 实现自动部署静态博客 | Jacky's blog + + + + + + + + + + + +
+ + + diff --git a/pages/aaf954/index.html b/pages/aaf954/index.html new file mode 100644 index 0000000000..8edd4253e8 --- /dev/null +++ b/pages/aaf954/index.html @@ -0,0 +1,112 @@ + + + + + + gradle鉴权脚本 | Jacky's blog + + + + + + + + + + + +
+ + + diff --git a/pages/b21fed/index.html b/pages/b21fed/index.html new file mode 100644 index 0000000000..d63b94be32 --- /dev/null +++ b/pages/b21fed/index.html @@ -0,0 +1,46 @@ + + + + + + 如何睡觉 | Jacky's blog + + + + + + + + + + + +
+ + + diff --git a/pages/b6bad0/index.html b/pages/b6bad0/index.html new file mode 100644 index 0000000000..8107deef31 --- /dev/null +++ b/pages/b6bad0/index.html @@ -0,0 +1,46 @@ + + + + + + Android稳定性治理 | Jacky's blog + + + + + + + + + + + + + + + diff --git a/pages/bd17b5/index.html b/pages/bd17b5/index.html new file mode 100644 index 0000000000..f869189bc4 --- /dev/null +++ b/pages/bd17b5/index.html @@ -0,0 +1,48 @@ + + + + + + ides | Jacky's blog + + + + + + + + + + + +
+ + + diff --git a/pages/bea5e2/index.html b/pages/bea5e2/index.html new file mode 100644 index 0000000000..643a087905 --- /dev/null +++ b/pages/bea5e2/index.html @@ -0,0 +1,46 @@ + + + + + + 技术规范等整理 | Jacky's blog + + + + + + + + + + + +
+ + + diff --git a/pages/c3229c/index.html b/pages/c3229c/index.html new file mode 100644 index 0000000000..06200f9b47 --- /dev/null +++ b/pages/c3229c/index.html @@ -0,0 +1,79 @@ + + + + + + UnSafe | Jacky's blog + + + + + + + + + + + +
+ + + diff --git a/pages/c38a8f/index.html b/pages/c38a8f/index.html new file mode 100644 index 0000000000..82a1a357f6 --- /dev/null +++ b/pages/c38a8f/index.html @@ -0,0 +1,46 @@ + + + + + + Java tutorial | Jacky's blog + + + + + + + + + + + + + + + diff --git a/pages/c65eb4/index.html b/pages/c65eb4/index.html new file mode 100644 index 0000000000..ef4e4479e3 --- /dev/null +++ b/pages/c65eb4/index.html @@ -0,0 +1,46 @@ + + + + + + websocket | Jacky's blog + + + + + + + + + + + +
+ + + diff --git a/pages/c76462/index.html b/pages/c76462/index.html new file mode 100644 index 0000000000..bfcd76dab3 --- /dev/null +++ b/pages/c76462/index.html @@ -0,0 +1,46 @@ + + + + + + 财经基础 | Jacky's blog + + + + + + + + + + + +
+ + + diff --git a/pages/c80e98/index.html b/pages/c80e98/index.html new file mode 100644 index 0000000000..2f59173c08 --- /dev/null +++ b/pages/c80e98/index.html @@ -0,0 +1,46 @@ + + + + + + mvn | Jacky's blog + + + + + + + + + + + +
+ + + diff --git a/pages/c8fb65/index.html b/pages/c8fb65/index.html new file mode 100644 index 0000000000..0c96094de7 --- /dev/null +++ b/pages/c8fb65/index.html @@ -0,0 +1,46 @@ + + + + + + retrofit动态代理设计 | Jacky's blog + + + + + + + + + + + +
+ + + diff --git a/pages/ca8e7a/index.html b/pages/ca8e7a/index.html new file mode 100644 index 0000000000..da952b53d7 --- /dev/null +++ b/pages/ca8e7a/index.html @@ -0,0 +1,3278 @@ + + + + + + C++面试突击 | Jacky's blog + + + + + + + + + + + +
+ + + diff --git a/pages/cb9380/index.html b/pages/cb9380/index.html new file mode 100644 index 0000000000..1e1609932b --- /dev/null +++ b/pages/cb9380/index.html @@ -0,0 +1,54 @@ + + + + + + 双向绑定和单项数据流不冲突 | Jacky's blog + + + + + + + + + + + +
+ + + diff --git a/pages/cb9d0f/index.html b/pages/cb9d0f/index.html new file mode 100644 index 0000000000..f654821ea9 --- /dev/null +++ b/pages/cb9d0f/index.html @@ -0,0 +1,47 @@ + + + + + + 网络 | Jacky's blog + + + + + + + + + + + +
+ + + diff --git a/pages/cd0789/index.html b/pages/cd0789/index.html new file mode 100644 index 0000000000..3bea3be96a --- /dev/null +++ b/pages/cd0789/index.html @@ -0,0 +1,46 @@ + + + + + + 提升UI加载速度的几点思考 | Jacky's blog + + + + + + + + + + + +
+ + + diff --git a/pages/ce4afc/index.html b/pages/ce4afc/index.html new file mode 100644 index 0000000000..db51cdd710 --- /dev/null +++ b/pages/ce4afc/index.html @@ -0,0 +1,44 @@ + + + + + + tutorial | Jacky's blog + + + + + + + + + + + + + + + diff --git a/pages/d2a447/index.html b/pages/d2a447/index.html new file mode 100644 index 0000000000..b6534639d3 --- /dev/null +++ b/pages/d2a447/index.html @@ -0,0 +1,48 @@ + + + + + + nextjs | Jacky's blog + + + + + + + + + + + +
+ + + diff --git a/pages/d2d3e5/index.html b/pages/d2d3e5/index.html new file mode 100644 index 0000000000..1b7d67de51 --- /dev/null +++ b/pages/d2d3e5/index.html @@ -0,0 +1,168 @@ + + + + + + jsbridge | Jacky's blog + + + + + + + + + + + +
+ + + diff --git a/pages/d3b34e/index.html b/pages/d3b34e/index.html new file mode 100644 index 0000000000..5a3026324b --- /dev/null +++ b/pages/d3b34e/index.html @@ -0,0 +1,67 @@ + + + + + + 测试页面 | Jacky's blog + + + + + + + + + + + +
+ + + diff --git a/pages/d8c80d/index.html b/pages/d8c80d/index.html new file mode 100644 index 0000000000..4b1913a224 --- /dev/null +++ b/pages/d8c80d/index.html @@ -0,0 +1,45 @@ + + + + + + tutorial | Jacky's blog + + + + + + + + + + + +
+ + + diff --git a/pages/d8cbeb/index.html b/pages/d8cbeb/index.html new file mode 100644 index 0000000000..c5356fadeb --- /dev/null +++ b/pages/d8cbeb/index.html @@ -0,0 +1,48 @@ + + + + + + elasticsearch | Jacky's blog + + + + + + + + + + + +
+ + + diff --git a/pages/d9fade/index.html b/pages/d9fade/index.html new file mode 100644 index 0000000000..95524c3c44 --- /dev/null +++ b/pages/d9fade/index.html @@ -0,0 +1,48 @@ + + + + + + 工作效率 | Jacky's blog + + + + + + + + + + + +
+ + + diff --git a/pages/db8380/index.html b/pages/db8380/index.html new file mode 100644 index 0000000000..1338bbcc5b --- /dev/null +++ b/pages/db8380/index.html @@ -0,0 +1,194 @@ + + + + + + 设计模式和思想 | Jacky's blog + + + + + + + + + + + +
+ + + diff --git a/pages/dc1698/index.html b/pages/dc1698/index.html new file mode 100644 index 0000000000..e31b4232d1 --- /dev/null +++ b/pages/dc1698/index.html @@ -0,0 +1,58 @@ + + + + + + python3命令 | Jacky's blog + + + + + + + + + + + +
+ + + diff --git a/pages/dd1044/index.html b/pages/dd1044/index.html new file mode 100644 index 0000000000..29be2691f9 --- /dev/null +++ b/pages/dd1044/index.html @@ -0,0 +1,44 @@ + + + + + + 概述 | Jacky's blog + + + + + + + + + + + + + + + diff --git a/pages/df7642/index.html b/pages/df7642/index.html new file mode 100644 index 0000000000..c754b16753 --- /dev/null +++ b/pages/df7642/index.html @@ -0,0 +1,53 @@ + + + + + + 博客指南 | Jacky's blog + + + + + + + + + + + +
+ + + diff --git a/pages/e4a24e/index.html b/pages/e4a24e/index.html new file mode 100644 index 0000000000..a795c3465e --- /dev/null +++ b/pages/e4a24e/index.html @@ -0,0 +1,51 @@ + + + + + + sql | Jacky's blog + + + + + + + + + + + +
+ + + diff --git a/pages/e9db87/index.html b/pages/e9db87/index.html new file mode 100644 index 0000000000..1f912e9b27 --- /dev/null +++ b/pages/e9db87/index.html @@ -0,0 +1,1361 @@ + + + + + + mysql | Jacky's blog + + + + + + + + + + + +
+ + + diff --git a/pages/eae245/index.html b/pages/eae245/index.html new file mode 100644 index 0000000000..dbcdfa83a3 --- /dev/null +++ b/pages/eae245/index.html @@ -0,0 +1,46 @@ + + + + + + 卡顿分析工具 | Jacky's blog + + + + + + + + + + + + + + + diff --git a/pages/ed7a6a/index.html b/pages/ed7a6a/index.html new file mode 100644 index 0000000000..17c7066d2f --- /dev/null +++ b/pages/ed7a6a/index.html @@ -0,0 +1,47 @@ + + + + + + Class类 | Jacky's blog + + + + + + + + + + + +
+ + + diff --git a/pages/f1d871/index.html b/pages/f1d871/index.html new file mode 100644 index 0000000000..f01a3837df --- /dev/null +++ b/pages/f1d871/index.html @@ -0,0 +1,43 @@ + + + + + + okhttp | Jacky's blog + + + + + + + + + + + +
+ + + diff --git a/pages/f23ed2/index.html b/pages/f23ed2/index.html new file mode 100644 index 0000000000..28cb287ce8 --- /dev/null +++ b/pages/f23ed2/index.html @@ -0,0 +1,44 @@ + + + + + + 指令 | Jacky's blog + + + + + + + + + + + +
+ + + diff --git a/pages/f7262c/index.html b/pages/f7262c/index.html new file mode 100644 index 0000000000..083e5203cb --- /dev/null +++ b/pages/f7262c/index.html @@ -0,0 +1,226 @@ + + + + + + 技术专业词汇 | Jacky's blog + + + + + + + + + + + +
+ + + diff --git a/pages/f85f1b/index.html b/pages/f85f1b/index.html new file mode 100644 index 0000000000..ccc9f2e38a --- /dev/null +++ b/pages/f85f1b/index.html @@ -0,0 +1,63 @@ + + + + + + Hooks | Jacky's blog + + + + + + + + + + + +
+ + + diff --git a/pages/f9b0df/index.html b/pages/f9b0df/index.html new file mode 100644 index 0000000000..fc30d96b85 --- /dev/null +++ b/pages/f9b0df/index.html @@ -0,0 +1,60 @@ + + + + + + vue传递数据-slot | Jacky's blog + + + + + + + + + + + +
+ + + diff --git a/pages/f9c14d/index.html b/pages/f9c14d/index.html new file mode 100644 index 0000000000..8d160200fc --- /dev/null +++ b/pages/f9c14d/index.html @@ -0,0 +1,48 @@ + + + + + + zsh高效的shell | Jacky's blog + + + + + + + + + + + +
+ + + diff --git a/python/index.html b/python/index.html new file mode 100644 index 0000000000..36dd14d2b1 --- /dev/null +++ b/python/index.html @@ -0,0 +1,55 @@ + + + + + + python | Jacky's blog + + + + + + + + + + + + + + + diff --git a/react/index.html b/react/index.html new file mode 100644 index 0000000000..29efd6e2f3 --- /dev/null +++ b/react/index.html @@ -0,0 +1,50 @@ + + + + + + 《react》笔记 | Jacky's blog + + + + + + + + + + + +
+ + + diff --git a/server/index.html b/server/index.html new file mode 100644 index 0000000000..30a7a9e914 --- /dev/null +++ b/server/index.html @@ -0,0 +1,58 @@ + + + + + + server | Jacky's blog + + + + + + + + + + + + + + + diff --git a/tags/index.html b/tags/index.html new file mode 100644 index 0000000000..fa70bb483b --- /dev/null +++ b/tags/index.html @@ -0,0 +1,57 @@ + + + + + + 标签 | Jacky's blog + + + + + + + + + + + +
+ + + diff --git a/tool/index.html b/tool/index.html new file mode 100644 index 0000000000..90b557309c --- /dev/null +++ b/tool/index.html @@ -0,0 +1,63 @@ + + + + + + 工具 | Jacky's blog + + + + + + + + + + + + + + + diff --git a/vue/index.html b/vue/index.html new file mode 100644 index 0000000000..afd6fd25b1 --- /dev/null +++ b/vue/index.html @@ -0,0 +1,59 @@ + + + + + + 《vue》笔记 | Jacky's blog + + + + + + + + + + + + + + + diff --git a/web/index.html b/web/index.html new file mode 100644 index 0000000000..b76e0d5ffc --- /dev/null +++ b/web/index.html @@ -0,0 +1,50 @@ + + + + + + web | Jacky's blog + + + + + + + + + + + + + + +

# GitHub Actions 实现自动部署静态博客