From 5cb202d465e31ac07fb6c4fee6f02b623aefd682 Mon Sep 17 00:00:00 2001 From: itwanger Date: Sat, 11 Jun 2022 20:21:21 +0800 Subject: [PATCH] =?UTF-8?q?2022=E5=B9=B406=E6=9C=8811=E6=97=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- dist/404.html | 6 +- dist/about-the-author/bzhan-10wan.html | 6 +- dist/about-the-author/csdn-1000wan.html | 6 +- dist/about-the-author/index.html | 6 +- dist/about-the-author/zhihu-1000wan.html | 6 +- dist/array/array.html | 6 +- dist/array/print.html | 6 +- ...d8841.js => 100-budiushi.html.281fc989.js} | 2 +- ...5b0a.js => 4-debug-skill.html.0c72ed75.js} | 2 +- ...b99de.js => 40-interview.html.e460eeeb.js} | 2 +- .../{404.5ae72665.js => 404.c61acaed.js} | 2 +- ....html.5c274669.js => 404.html.6cb935de.js} | 2 +- ...eb30fe.js => 48-keywords.html.c30c9b30.js} | 2 +- ...27d4fa22.js => BIONIOAIO.html.4c184e72.js} | 2 +- ...Nruhegaoxiaodixuexijishu.html.665a0cbe.js} | 2 +- ...f03a.js => BlockingQueue.html.76b31f3c.js} | 2 +- ...s => Chocolatey-Homebrew.html.5637171d.js} | 2 +- ....js => ConcurrentHashMap.html.77d65cc9.js} | 2 +- ...=> ConcurrentLinkedQueue.html.f8564dd9.js} | 2 +- ... => CopyOnWriteArrayList.html.2fa1badd.js} | 2 +- ...e87.js => CountDownLatch.html.79c0b80e.js} | 2 +- ...l.8a022161.js => DBeaver.html.16c02541.js} | 2 +- ...lter-Interceptor-Listener.html.3a5897a3.js | 1 + ...ter-Interceptor-Listener.html.7803e9df.js} | 6 +- ...lter-Interceptor-Listener.html.d4211e38.js | 1 - ...ml.16e88b8a.js => Lambda.html.bd1566d3.js} | 2 +- ...{Layout.fbcb8daf.js => Layout.2f241dd5.js} | 2 +- ...f27ea8.js => LockSupport.html.5ea98b89.js} | 2 +- ...0ccdfe1.js => Overriding.html.d8235770.js} | 2 +- ...> ReentrantReadWriteLock.html.140f1c3e.js} | 2 +- ...eduledThreadPoolExecutor.html.73744e7a.js} | 2 +- ...pLink.e761490e.js => SkipLink.a2c3a90f.js} | 2 +- .../{Slide.a2a8944b.js => Slide.39e63deb.js} | 2 +- ...4cf60c.js => ThreadLocal.html.2993d4fd.js} | 2 +- ...uokeyizhaodiyifengongzuo.html.ef1e0c27.js} | 2 +- ....60b3966f.js => abstract.html.e17df797.js} | 2 +- ...66d3e273.js => algorithm.html.8d44122f.js} | 2 +- ...1d8a.js => ali-executors.html.3e2ae653.js} | 2 +- ...un-shuaiguo-gongchengshi.html.af9a0166.js} | 2 +- ...0fc1ba0.js => annotation.html.3a9fcfe1.js} | 2 +- ...l.f3df7d62.js => aop-log.html.ec10c829.js} | 2 +- ...edd64.js => api-wangguan.html.ec8dd3f1.js} | 2 +- dist/assets/app.615e41d8.js | 25 +++ dist/assets/app.a0271b9c.js | 25 --- ....html.e6bd9611.js => aqs.html.58976faa.js} | 2 +- ...tml.97a807b4.js => array.html.19972859.js} | 2 +- ...804615c1.js => arraylist.html.f57cbfa7.js} | 2 +- ...ml.13de83ef.js => arrays.html.ea4b1150.js} | 2 +- ....html.deedcff5.js => asm.html.43e7fd57.js} | 2 +- ...ml.1dc322e5.js => atomic.html.08ec5c1f.js} | 2 +- ...c06.js => auto-generator.html.341a868e.js} | 8 +- ...e0d.js => auto-generator.html.7efe2473.js} | 2 +- ...d3.js => basic-data-type.html.20d3399e.js} | 2 +- dist/assets/bat-shuati.html.01dded07.js | 1 + dist/assets/bat-shuati.html.214e49f5.js | 1 + dist/assets/bat-shuati.html.adba9635.js | 1 - dist/assets/bat-shuati.html.bf129827.js | 1 - dist/assets/beijing.html.5436f34b.js | 1 - dist/assets/beijing.html.78adaacf.js | 1 + dist/assets/beijing.html.a011f671.js | 1 + dist/assets/beijing.html.ac5b087b.js | 1 - ...difangwenquanxiankongzhi.html.5212785d.js} | 2 +- ...-ruhegaoxiaodixuexijishu.html.e50696a0.js} | 2 +- ....html.9c8b69db.js => box.html.03f96a13.js} | 2 +- ...c.js => buy-cloud-server.html.5057ae50.js} | 2 +- ...406ff12.js => buy-domain.html.e087e5aa.js} | 2 +- ....09a0585c.js => bytecode.html.568c5a04.js} | 2 +- ...906807.js => bzhan-10wan.html.e0ad4af0.js} | 2 +- ...{c.html.1f2463e6.js => c.html.6387955f.js} | 2 +- ....html.ff0123d4.js => cas.html.68e07dc8.js} | 2 +- ....html.0a777341.js => ccc.html.bf391d30.js} | 2 +- ...cde9.js => chadiansanhuo.html.fc173db8.js} | 2 +- dist/assets/chengdu.html.09b27f2f.js | 1 - dist/assets/chengdu.html.7221dfab.js | 1 + dist/assets/chengdu.html.8c0a9616.js | 1 - dist/assets/chengdu.html.c9264a1d.js | 1 + ...ngxuyuannv-chonghui-java.html.01f1b5cf.js} | 2 +- ...ml.5580190e.js => chiner.html.daf0adff.js} | 2 +- ...tml.8857968e.js => choco.html.2c7d8900.js} | 2 +- ....js => class-file-jiegou.html.3aa9524b.js} | 2 +- ...c3b08f8.js => class-load.html.07c5abca.js} | 2 +- ...0dbd5.js => class-object.html.a22a09d8.js} | 2 +- ...16081b84.js => code-init.html.58676afd.js} | 2 +- ...1a47d1f.js => collection.html.e1c47b4b.js} | 2 +- ...f2022a.js => collections.html.37777ec8.js} | 2 +- ... => comparable-omparator.html.1a3bff07.js} | 2 +- ...638e51.js => compile-jdk.html.fddb4940.js} | 2 +- ...0f7c.js => computer-base.html.ca77cdaf.js} | 2 +- ...dcd667af.js => condition.html.4a44859a.js} | 2 +- ...5914.js => constant-pool.html.81e697ea.js} | 2 +- ...ebfac9f1.js => construct.html.0a38a577.js} | 2 +- ...html.32e975b9.js => cors.html.b1e575b3.js} | 2 +- ...8e.js => cpu-percent-100.html.30d9234e.js} | 2 +- ...2cd37.js => csdn-1000wan.html.22ddf17a.js} | 2 +- ...s => daxue-nuli-jisuanji.html.ad13ab16.js} | 2 +- ...b6383852.js => deep-copy.html.1b203746.js} | 2 +- ...tedb-binlog-weiguanjishu.html.0dd5fe85.js} | 2 +- ...n-information-engineering.html.16bd5754.js | 1 + ...-information-engineering.html.6411b062.js} | 2 +- ...n-information-engineering.html.b3d4a3e7.js | 1 - ...html.e72022eb.js => enum.html.637c7ac9.js} | 2 +- ...22.js => equals-hashcode.html.033e729f.js} | 2 +- ...ml.b49827b6.js => equals.html.f7e52978.js} | 2 +- ...613c56f6.js => fail-fast.html.dca676b6.js} | 2 +- ...ml.c9e51464.js => fanshe.html.e42ba18d.js} | 2 +- ....ac85dfcc.js => fastjson.html.bf5a0ad8.js} | 2 +- ...tml.de436e22.js => final.html.e625665e.js} | 2 +- ...19486.js => flow-control.html.5046ff0c.js} | 2 +- ...ml.18099f01.js => forest.html.3141000b.js} | 2 +- ...148dd105.js => fork-join.html.e8674cdb.js} | 2 +- ...5b695cc.js => fumutuanju.html.ca0f5d88.js} | 2 +- ...ml.89a0a128.js => gailan.html.0ea3f7da.js} | 2 +- ...ml.a5bab427.js => gailan.html.50f82bf5.js} | 2 +- ...c.html.10f470a0.js => gc.html.714d0f7b.js} | 2 +- ...l.47649dca.js => generic.html.df9c6eb8.js} | 2 +- ...b827703.js => git-qiyuan.html.085fb4bc.js} | 2 +- ...o.html.712c93cd.js => go.html.dbab658a.js} | 2 +- ...html.da4ecf62.js => gson.html.a359eddd.js} | 2 +- dist/assets/guangzhou.html.14bc2637.js | 1 - dist/assets/guangzhou.html.58700f92.js | 1 + dist/assets/guangzhou.html.c44755f8.js | 1 + dist/assets/guangzhou.html.ce1033cd.js | 1 - ...tml.1f12859a.js => guava.html.bbc48258.js} | 2 +- ...atisplusshoubashoujiaoni.html.6feacfb3.js} | 2 +- dist/assets/hangzhou.html.52f2ce43.js | 1 + dist/assets/hangzhou.html.9719a0ea.js | 1 - dist/assets/hangzhou.html.a9b39480.js | 1 + dist/assets/hangzhou.html.b80d450d.js | 1 - ....94e85992.js => hashcode.html.6a0e81d9.js} | 2 +- ....js => hashmap-interview.html.36f118fd.js} | 2 +- ...l.cd5a497b.js => hashmap.html.e3590cbb.js} | 2 +- ...4deafe.js => hello-world.html.26946542.js} | 2 +- ...l.6bcd3b59.js => history.html.57bb6aeb.js} | 2 +- dist/assets/home.html.1fffdb8f.js | 1 + dist/assets/home.html.25268b5b.js | 1 + dist/assets/home.html.4301cc35.js | 1 - dist/assets/home.html.c8d9ace7.js | 1 - ...-jvm-run-zijiema-zhiling.html.f5dbcd2c.js} | 2 +- ....js => how-run-java-code.html.5154cace.js} | 2 +- ...html.18e11779.js => hsdb.html.4b8d1063.js} | 2 +- ...a1a27.js => https-domain.html.81185a29.js} | 2 +- ...ml.3a80c8b8.js => hutool.html.5bf70ca7.js} | 2 +- ...e70eaf.js => image-yasuo.html.0e3ff54c.js} | 2 +- ...e7e4c546.js => immutable.html.aab5b4ed.js} | 2 +- ...923c43ef.js => immutable.html.acff64d4.js} | 2 +- dist/assets/index.html.2971f84c.js | 1 - ...tml.8360409e.js => index.html.96eac070.js} | 2 +- dist/assets/index.html.9c1a7487.js | 1 + dist/assets/index.html.9ee0e417.js | 1 + dist/assets/index.html.af7b50d7.js | 1 - ...tml.ece7c54d.js => index.html.b90a750c.js} | 2 +- dist/assets/index.html.bb2bcc18.js | 1 - dist/assets/index.html.bc31ce34.js | 1 + ...tml.17715b69.js => index.html.c95125a9.js} | 2 +- ...tml.23006160.js => index.html.efbaa943.js} | 2 +- ...e05e8c2.js => initializr.html.47ddf572.js} | 2 +- dist/assets/initializr.html.8afcbffb.js | 22 +++ dist/assets/initializr.html.8cd24dbb.js | 22 --- ...071786.js => inner-class.html.858a9fd0.js} | 2 +- ...=> install-baota-mianban.html.fc940506.js} | 2 +- ...080.js => instanceof-jvm.html.84099ac1.js} | 2 +- ...3f5b0d7.js => instanceof.html.edc709c7.js} | 2 +- ...c609a3a6.js => int-cache.html.bb142a51.js} | 2 +- ...60cd9cd7.js => interface.html.de30e51e.js} | 2 +- ...ml.57f3b131.js => intern.html.cb5b47c3.js} | 2 +- ....html.00ef348c.js => ioc.html.a79e951b.js} | 2 +- ....js => iterator-iterable.html.7a5374e3.js} | 2 +- ...l.f9f2bbfc.js => jackson.html.f4471baf.js} | 2 +- ...f0e4.js => java-basic-34.html.c0108ee7.js} | 2 +- ...b10b00c.js => java-basic.html.34b72317.js} | 2 +- ...s => java-mianshi-zhinan.html.9c0ece4d.js} | 2 +- ...154c6b.js => java-naming.html.1100d2ca.js} | 2 +- ...bdf4b1.js => java-thread.html.87abce4b.js} | 2 +- ...ea1e9.js => java-unicode.html.c63853a0.js} | 2 +- dist/assets/java.html.74ed2cc3.js | 1 - dist/assets/java.html.8cfce3ac.js | 1 + dist/assets/java.html.9104a10d.js | 1 + dist/assets/java.html.c5bee727.js | 1 - ...l.6c8ace88.js => javadoc.html.435ee8ec.js} | 2 +- ...ml.d7cb534c.js => javase.html.4c6f74ba.js} | 2 +- ...f11e6a6.js => javathread.html.9fc70ce0.js} | 2 +- ...uokeyizhaodiyifengongzuo.html.6e4f2abd.js} | 2 +- ...while-for-wuxian-xunhuan.html.a5707bd9.js} | 2 +- ...=> jdk9-char-byte-string.html.884765a3.js} | 2 +- ...ghuizhijitongjiagoulantu.html.aafe265c.js} | 2 +- dist/assets/jianli.html.28361c8b.js | 1 + dist/assets/jianli.html.2cde4ea0.js | 1 + dist/assets/jianli.html.5f109d9a.js | 1 - dist/assets/jianli.html.75854f37.js | 1 - ...7aaac.js => jibenjieshao.html.6a5f31db.js} | 2 +- ...jielehenduosihuodiganchu.html.576b64a2.js} | 2 +- dist/assets/jinan.html.95982728.js | 1 + dist/assets/jinan.html.d4c22f59.js | 1 + ...shuzongjianbeikaichuliao.html.6397e62a.js} | 2 +- ....html.4cb31299.js => jit.html.cd04156f.js} | 2 +- ....html.6df91381.js => jmm.html.2560457a.js} | 2 +- ...html.18a0e9f8.js => join.html.50d59b6e.js} | 2 +- ....html.8adce5f1.js => jpa.html.c491ef74.js} | 10 +- ....html.c4109873.js => jpa.html.cb4e1f80.js} | 2 +- ...tml.a79d9c04.js => junit.html.9c832cdc.js} | 2 +- ....html.e2246150.js => jvm.html.375475cb.js} | 2 +- ....html.86668e04.js => jvm.html.c049e00d.js} | 2 +- ....html.d7d28727.js => jvm.html.cb0eace1.js} | 2 +- ....html.e910af0e.js => jwt.html.2aed3523.js} | 2 +- ...l.44253ad0.js => knife4j.html.4fbb94b8.js} | 6 +- ...l.fe2f8e7d.js => knife4j.html.a18b3a85.js} | 2 +- ...89bde40.js => lanqiaobei.html.e24944e8.js} | 2 +- ...bb02b.js => learn-jianyi.html.2486d715.js} | 2 +- ...b75cd4d.js => linkedlist.html.e021186b.js} | 2 +- .../linux-codingmore-run.html.6ac5d933.js | 1 + .../linux-codingmore-run.html.d96d85b1.js | 77 +++++++++ ...6808d02.js => list-war-2.html.4306ceaf.js} | 2 +- ...html.a13afff5.js => lock.html.707d5244.js} | 2 +- ...tml.dbbf9c72.js => log4j.html.0b4fd542.js} | 2 +- ...ml.17000ac4.js => log4j2.html.066d10f7.js} | 2 +- ...ml.f846d981.js => log4j2.html.d1682823.js} | 2 +- ...l.65200f68.js => logback.html.28ab1df5.js} | 2 +- ...l.869073f6.js => logback.html.806b8b11.js} | 2 +- ...l.bd3bc959.js => logback.html.ce19f5e4.js} | 8 +- ... => macos-codingmore-run.html.100361aa.js} | 2 +- ....html.61b4c4d9.js => map.html.6ee85b94.js} | 2 +- ...tml.9abc8500.js => maven.html.d13a0dbf.js} | 2 +- ...85c28.js => meituan-9-gc.html.7173ffd4.js} | 2 +- ...ml.67a1e169.js => method.html.1f147cbd.js} | 2 +- ...l.a18a9ce2.js => mybatis.html.41ff93f4.js} | 2 +- ...232591.js => mysql-druid.html.1c47eb57.js} | 2 +- ...b4afdf.js => mysql-druid.html.9707dc06.js} | 6 +- ...tml.ecb0e241.js => mysql.html.1afcd596.js} | 2 +- dist/assets/nanjing.html.0381e4b6.js | 1 - dist/assets/nanjing.html.099e9844.js | 1 + dist/assets/nanjing.html.44d630fa.js | 1 + dist/assets/nanjing.html.df603525.js | 1 - ...2a53.js => neicun-jiegou.html.fee2587a.js} | 2 +- dist/assets/nginx-setting.html.3934a533.js | 108 ++++++++++++ dist/assets/nginx-setting.html.68b3250b.js | 1 + ...tml.30b3f8bd.js => nginx.html.25ed8525.js} | 2 +- ...656631.js => nicearticle.html.4730077f.js} | 2 +- ...html.8b48857f.js => nixi.html.de6f9361.js} | 2 +- ....html.01d29f9c.js => npe.html.297684ef.js} | 2 +- ...d3d4e.js => object-class.html.698d849f.js} | 2 +- ....html.d0512b48.js => oom.html.cbfa1fb6.js} | 2 +- ....783e87f0.js => operator.html.152cf4bc.js} | 2 +- ....d38ec385.js => optional.html.775157f3.js} | 2 +- ...s.html.e10e307f.js => os.html.1d208877.js} | 2 +- ...s.html.2d6bc714.js => os.html.781c26b2.js} | 2 +- ....html.977b34d5.js => oss.html.8b1ce1ec.js} | 2 +- ....html.b690f015.js => oss.html.e3216442.js} | 4 +- ...ml.214194b1.js => others.html.63b5af1f.js} | 2 +- ....js => override-overload.html.1c9aaf26.js} | 2 +- ...64be.js => pass-by-value.html.cf8023d5.js} | 2 +- ....html.0610fb03.js => pdf.html.79c228f5.js} | 2 +- ...html.79813894.js => pool.html.7274870a.js} | 2 +- ...tml.f0b4f56c.js => print.html.4135561a.js} | 2 +- ...a786.js => problem-tools.html.c0e0819e.js} | 2 +- ...ml.66c47307.js => progit.html.284a6498.js} | 2 +- dist/assets/progit.html.3b6ba984.js | 1 - ...ml.de3011f5.js => progit.html.95158ac7.js} | 2 +- dist/assets/progit.html.df477a55.js | 1 + ...ml.e5ae48ee.js => python.html.6ba47e37.js} | 2 +- ....60a6bdee.js => qianduan.html.ef57d5d5.js} | 2 +- dist/assets/qingdao.html.026cf757.js | 1 - dist/assets/qingdao.html.08ca70e9.js | 1 - dist/assets/qingdao.html.826f4cb2.js | 1 + dist/assets/qingdao.html.c4a4c2c4.js | 1 + ...bed.js => rabbitmq-rumen.html.5bf7bc58.js} | 2 +- dist/assets/read-csapp.html.23c82cf4.js | 1 - dist/assets/read-csapp.html.768012b7.js | 1 + dist/assets/read-csapp.html.c0e758ea.js | 1 + dist/assets/read-csapp.html.f8f796e3.js | 1 - dist/assets/record-domain.html.19eb33ac.js | 1 - ...d780.js => record-domain.html.3a82f73e.js} | 2 +- dist/assets/record-domain.html.667d7982.js | 1 + ...=> redis-shuju-yizhixing.html.480d5fea.js} | 2 +- ...9.js => redis-springboot.html.3faa6adc.js} | 62 +++---- ...d.js => redis-springboot.html.44044d02.js} | 2 +- ...tml.7543ed9c.js => redis.html.bcbe4235.js} | 2 +- ...b9.js => redis12question.html.f0270e84.js} | 2 +- ...7dd6.js => reentrantLock.html.8b519bdc.js} | 2 +- ...tml.f241efd5.js => rumen.html.27e01d35.js} | 2 +- ...tml.4002e397.js => rumen.html.3f2b5ec9.js} | 2 +- ...tml.439110fe.js => rumen.html.ee21a790.js} | 2 +- ...e761.js => shanganaliyun.html.802605a1.js} | 2 +- ....fc7b3e84.js => shangtou.html.d25e4bab.js} | 2 +- ... shengchanzhe-xiaofeizhe.html.b76e11fd.js} | 2 +- dist/assets/shenzhen.html.037e48a5.js | 1 - dist/assets/shenzhen.html.48307e94.js | 1 - dist/assets/shenzhen.html.61178979.js | 1 + dist/assets/shenzhen.html.98e7f6e9.js | 1 + ...l.84eb0eab.js => shijian.html.d1dfaaba.js} | 2 +- ...tml.a17cdf5a.js => slf4j.html.f772534d.js} | 2 +- ...tml.dbaed6aa.js => split.html.b69d2cd1.js} | 2 +- ...ml.26f406c7.js => spring.html.40b7b2ff.js} | 2 +- ...06633ab.js => springtask.html.04deb6a0.js} | 2 +- ...afe6499.js => springtask.html.6f8efcf6.js} | 4 +- ...ml.8ee519bc.js => static.html.c9732093.js} | 2 +- ...ml.db791f6b.js => stream.html.02d08777.js} | 2 +- dist/assets/suzhou.html.1f658a4a.js | 1 - dist/assets/suzhou.html.428c3730.js | 1 + dist/assets/suzhou.html.b2ed5bbc.js | 1 + dist/assets/suzhou.html.e601b996.js | 1 - ...l.03ed15b7.js => swagger.html.1142f08f.js} | 2 +- ...l.d41c975f.js => swagger.html.e13d1880.js} | 6 +- ...681cb.js => synchronized.html.0249091e.js} | 2 +- ...tml.5c93d604.js => tabby.html.c3b44c08.js} | 2 +- ...e8e4dee.js => this-super.html.ff84e809.js} | 2 +- ...hread-bring-some-problem.html.891141f3.js} | 2 +- ...roup-and-thread-priority.html.777c962b.js} | 2 +- ... thread-state-and-method.html.a816be26.js} | 2 +- ...ml.a2ddbdf4.js => thread.html.4fcef02c.js} | 2 +- ...be244969.js => thymeleaf.html.943910b5.js} | 4 +- ...1a24ed99.js => thymeleaf.html.b2ef505e.js} | 2 +- ...avaer-wangzhan-shangxian.html.eb4a3068.js} | 2 +- ...ml.3d86b543.js => tomcat.html.af3e6ee8.js} | 2 +- ...ea47a0.js => transaction.html.1d6a1548.js} | 2 +- ...e3579f.js => transaction.html.9982a65f.js} | 16 +- ...aca38.js => true-generic.html.a683e7b2.js} | 2 +- ....js => try-with-resouces.html.52a831d4.js} | 2 +- ....70c281f0.js => tujie-gc.html.3ec6a37b.js} | 2 +- ...c.js => tupian-zhuanlian.html.cc248511.js} | 2 +- ....html.d8139bc5.js => var.html.6e7f16a9.js} | 2 +- ....4e32dd4f.js => varables.html.3f84ac76.js} | 2 +- ....e6448db8.js => volatile.html.4f34c8de.js} | 2 +- ...2375.js => waibao-1geyue.html.31a36346.js} | 2 +- ...l.bd9e0045.js => wangluo.html.bf2e0885.js} | 2 +- ...220.js => wangzhe-thread.html.752a4836.js} | 2 +- ...html.f8427955.js => warp.html.8ae8cc83.js} | 2 +- dist/assets/weixin-bagwpdf.html.a32b4b3a.js | 1 + dist/assets/weixin-bagwpdf.html.e485fe14.js | 1 + ...weixin-chengxwjdwzhqcgxm.html.5c788b1b.js} | 2 +- ...ixin-githubxbkdjavajccjyh.html.11c03a69.js | 1 + ...ixin-githubxbkdjavajccjyh.html.be4183ae.js | 1 + ...> weixin-liaoliaoxianliu.html.fa1a5a6a.js} | 2 +- dist/assets/weixin-likbj.html.4138e613.js | 1 + dist/assets/weixin-likbj.html.a9767504.js | 1 + ...mozdsdzfjavableetcodetxxk.html.10059c85.js | 1 + ...mozdsdzfjavableetcodetxxk.html.62ab0a25.js | 1 + ...in-piaolwzjztqdtskwlzfpdf.html.0792de0c.js | 1 + ...in-piaolwzjztqdtskwlzfpdf.html.ef3235a6.js | 1 + .../weixin-quoppomspwml.html.03c9aa24.js | 49 ++++++ .../weixin-quoppomspwml.html.27944449.js | 1 + dist/assets/weixin-shejmsnb.html.1f9c172b.js | 67 ++++++++ dist/assets/weixin-shejmsnb.html.5a6a099f.js | 1 + ...xin-shenrjcjavabfbchwjdhl.html.8fda2ac2.js | 1 + ...xin-shenrjcjavabfbchwjdhl.html.ca182283.js | 1 + ...jszzpojozsyjbsjlxyhjfyll.html.b7b8ec57.js} | 2 +- ...dnavicatzkkydsjkglgjjmgxk.html.ad8c7107.js | 1 + ...dnavicatzkkydsjkglgjjmgxk.html.bcbd11eb.js | 1 + ...-zhongxcwbztashjjavahdmj.html.2296ba72.js} | 2 +- ...nbujiabandigongsimingdan.html.d0426aa9.js} | 2 +- ...> what-happen-when-javac.html.a24cf79e.js} | 2 +- ...8650c.js => what-is-java.html.efbb701f.js} | 2 +- ...353155.js => what-is-jvm.html.3177cd0e.js} | 2 +- ...js => whereis-the-object.html.5fa8d65e.js} | 2 +- ...e1.js => why-need-thread.html.8e1db849.js} | 2 +- ...> windows-codingmore-run.html.225f6c56.js} | 4 +- ...> windows-codingmore-run.html.6d49b8aa.js} | 2 +- dist/assets/xian.html.4603b6ae.js | 1 - dist/assets/xian.html.4a14941e.js | 1 - dist/assets/xian.html.b0d9fb64.js | 1 + dist/assets/xian.html.badb133a.js | 1 + ...xuebeng-chuantou-jichuan.html.ffa86b85.js} | 2 +- ...3d.js => yanjiusuo-20wan.html.4b71b495.js} | 2 +- ...c191a66.js => yitiaolong.html.277dddb2.js} | 2 +- .../yuanyifeng-c-language.html.1d18c5bc.js | 1 - .../yuanyifeng-c-language.html.869263b3.js | 1 - .../yuanyifeng-c-language.html.90250cb3.js | 1 + .../yuanyifeng-c-language.html.dbcc3d40.js | 1 + ... yuneban-wangyiyunyinyue.html.83ef1711.js} | 2 +- dist/assets/zhengzhou.html.43c30f38.js | 1 - dist/assets/zhengzhou.html.5cf8ec33.js | 1 - dist/assets/zhengzhou.html.bee29209.js | 1 + dist/assets/zhengzhou.html.c309c263.js | 1 + ...965a.js => zhihu-1000wan.html.51362a9b.js} | 2 +- .../zhihu-jisjkyynxzdtjdyj.html.468f166c.js | 1 + .../zhihu-jisjkyynxzdtjdyj.html.8094217b.js | 1 + ...-weismyrsyxkjgscxyzhdjyxz.html.98987909.js | 1 + ...-weismyrsyxkjgscxyzhdjyxz.html.ec5fcad9.js | 1 + ...zhihu-younxzdjsjzyxsjrdgq.html.c66976c6.js | 1 + ...zhihu-younxzdjsjzyxsjrdgq.html.e644f706.js | 1 + ...e9.js => zijiema-zhiling.html.60db7eb3.js} | 2 +- ...l.0af46efc.js => zongjie.html.1ee2edb6.js} | 2 +- dist/baguwen/java-basic-34.html | 6 +- dist/baguwen/java-basic.html | 6 +- dist/baguwen/java-thread.html | 6 +- dist/baguwen/jvm.html | 6 +- dist/basic-extra-meal/48-keywords.html | 6 +- dist/basic-extra-meal/Overriding.html | 6 +- dist/basic-extra-meal/annotation.html | 6 +- dist/basic-extra-meal/box.html | 6 +- dist/basic-extra-meal/class-object.html | 6 +- .../comparable-omparator.html | 6 +- dist/basic-extra-meal/deep-copy.html | 6 +- dist/basic-extra-meal/enum.html | 6 +- dist/basic-extra-meal/equals-hashcode.html | 6 +- dist/basic-extra-meal/fanshe.html | 6 +- dist/basic-extra-meal/generic.html | 6 +- dist/basic-extra-meal/hashcode.html | 6 +- dist/basic-extra-meal/immutable.html | 6 +- dist/basic-extra-meal/instanceof-jvm.html | 6 +- dist/basic-extra-meal/int-cache.html | 6 +- dist/basic-extra-meal/java-naming.html | 6 +- dist/basic-extra-meal/java-unicode.html | 6 +- .../jdk-while-for-wuxian-xunhuan.html | 6 +- .../jdk9-char-byte-string.html | 6 +- dist/basic-extra-meal/override-overload.html | 6 +- dist/basic-extra-meal/pass-by-value.html | 6 +- dist/basic-extra-meal/true-generic.html | 6 +- dist/basic-extra-meal/varables.html | 6 +- dist/basic-grammar/basic-data-type.html | 6 +- dist/basic-grammar/flow-control.html | 6 +- dist/basic-grammar/javadoc.html | 6 +- dist/basic-grammar/operator.html | 6 +- dist/cityselect/beijing.html | 10 +- dist/cityselect/chengdu.html | 10 +- dist/cityselect/guangzhou.html | 10 +- dist/cityselect/hangzhou.html | 10 +- dist/cityselect/jinan.html | 48 ++++++ dist/cityselect/nanjing.html | 10 +- dist/cityselect/qingdao.html | 10 +- dist/cityselect/shenzhen.html | 10 +- dist/cityselect/suzhou.html | 10 +- dist/cityselect/xian.html | 10 +- dist/cityselect/zhengzhou.html | 10 +- dist/collection/arraylist.html | 6 +- dist/collection/fail-fast.html | 6 +- dist/collection/gailan.html | 6 +- dist/collection/hashmap-interview.html | 6 +- dist/collection/hashmap.html | 6 +- dist/collection/iterator-iterable.html | 6 +- dist/collection/linkedlist.html | 6 +- dist/collection/list-war-2.html | 6 +- dist/common-tool/arrays.html | 6 +- dist/common-tool/collections.html | 6 +- dist/common-tool/guava.html | 6 +- dist/common-tool/hutool.html | 6 +- dist/cs/os.html | 6 +- dist/cs/wangluo.html | 6 +- dist/download/bat-shuati.html | 10 +- dist/download/history.html | 6 +- dist/download/java.html | 10 +- dist/download/jianli.html | 10 +- dist/download/learn-jianyi.html | 6 +- dist/download/nicearticle.html | 6 +- dist/download/pdf.html | 6 +- dist/download/progit.html | 10 +- dist/download/yuanyifeng-c-language.html | 10 +- dist/elasticsearch/rumen.html | 6 +- dist/exception/gailan.html | 6 +- dist/exception/npe.html | 6 +- dist/exception/shijian.html | 6 +- dist/exception/try-with-resouces.html | 6 +- dist/git/git-qiyuan.html | 6 +- dist/git/progit.html | 6 +- dist/gongju/Chocolatey-Homebrew.html | 6 +- dist/gongju/DBeaver.html | 6 +- dist/gongju/chiner.html | 6 +- dist/gongju/choco.html | 6 +- dist/gongju/fastjson.html | 6 +- dist/gongju/forest.html | 6 +- dist/gongju/gson.html | 6 +- dist/gongju/jackson.html | 6 +- dist/gongju/junit.html | 6 +- dist/gongju/knife4j.html | 10 +- dist/gongju/log4j.html | 6 +- dist/gongju/log4j2.html | 6 +- dist/gongju/logback.html | 6 +- dist/gongju/others.html | 6 +- dist/gongju/slf4j.html | 6 +- dist/gongju/tabby.html | 6 +- dist/gongju/warp.html | 6 +- dist/home.html | 8 +- dist/ide/4-debug-skill.html | 6 +- dist/index.html | 8 +- dist/io/BIONIOAIO.html | 6 +- dist/io/shangtou.html | 6 +- dist/java8/Lambda.html | 6 +- dist/java8/optional.html | 6 +- dist/java8/stream.html | 6 +- dist/jvm/asm.html | 6 +- dist/jvm/bytecode.html | 6 +- dist/jvm/class-file-jiegou.html | 6 +- dist/jvm/class-load.html | 6 +- dist/jvm/compile-jdk.html | 6 +- dist/jvm/cpu-percent-100.html | 6 +- dist/jvm/gc.html | 6 +- dist/jvm/how-jvm-run-zijiema-zhiling.html | 6 +- dist/jvm/how-run-java-code.html | 6 +- dist/jvm/hsdb.html | 6 +- dist/jvm/jit.html | 6 +- dist/jvm/meituan-9-gc.html | 6 +- dist/jvm/neicun-jiegou.html | 6 +- dist/jvm/oom.html | 6 +- dist/jvm/problem-tools.html | 6 +- dist/jvm/tujie-gc.html | 6 +- dist/jvm/what-happen-when-javac.html | 6 +- dist/jvm/what-is-jvm.html | 6 +- dist/jvm/whereis-the-object.html | 6 +- dist/jvm/zijiema-zhiling.html | 6 +- dist/jvm/zongjie.html | 6 +- dist/kaiyuan/auto-generator.html | 12 +- dist/kaiyuan/index.html | 6 +- dist/kaiyuan/yuneban-wangyiyunyinyue.html | 6 +- dist/manongshenghuo/waibao-1geyue.html | 6 +- dist/manongshenghuo/yanjiusuo-20wan.html | 6 +- dist/maven/maven.html | 6 +- dist/mianjing/redis12question.html | 6 +- dist/mianjing/shanganaliyun.html | 6 +- dist/microservice/api-wangguan.html | 6 +- dist/mongodb/rumen.html | 6 +- dist/mq/100-budiushi.html | 6 +- dist/mq/rabbitmq-rumen.html | 6 +- dist/mysql/deletedb-binlog-weiguanjishu.html | 6 +- dist/mysql/redis-shuju-yizhixing.html | 6 +- dist/nginx/40-interview.html | 6 +- dist/nginx/nginx.html | 6 +- .../BOKEYUANruhegaoxiaodixuexijishu.html | 6 +- ...aoshemechengduokeyizhaodiyifengongzuo.html | 6 +- ...anxijavazhongdifangwenquanxiankongzhi.html | 6 +- .../bokeyuan-ruhegaoxiaodixuexijishu.html | 6 +- ...bukuaiyongmybatisplusshoubashoujiaoni.html | 6 +- ...aoshemechengduokeyizhaodiyifengongzuo.html | 6 +- ...agoushizenyanghuizhijitongjiagoulantu.html | 6 +- .../jielehenduosihuodiganchu.html | 6 +- .../jishuzongjianbeikaichuliao.html | 6 +- dist/nice-article/nginx-setting.html | 155 ++++++++++++++++++ dist/nice-article/weixin-bagwpdf.html | 48 ++++++ .../weixin-chengxwjdwzhqcgxm.html | 6 +- .../weixin-githubxbkdjavajccjyh.html | 48 ++++++ dist/nice-article/weixin-liaoliaoxianliu.html | 6 +- dist/nice-article/weixin-likbj.html | 48 ++++++ .../weixin-mozdsdzfjavableetcodetxxk.html | 48 ++++++ .../weixin-piaolwzjztqdtskwlzfpdf.html | 48 ++++++ dist/nice-article/weixin-quoppomspwml.html | 96 +++++++++++ dist/nice-article/weixin-shejmsnb.html | 114 +++++++++++++ .../weixin-shenrjcjavabfbchwjdhl.html | 48 ++++++ ...xin-xinllgjszjszzpojozsyjbsjlxyhjfyll.html | 6 +- ...eixin-zaixsfdnavicatzkkydsjkglgjjmgxk.html | 48 ++++++ .../weixin-zhongxcwbztashjjavahdmj.html | 6 +- .../weixin-zuixinbujiabandigongsimingdan.html | 6 +- dist/nice-article/zhihu-jisjkyynxzdtjdyj.html | 48 ++++++ .../zhihu-weismyrsyxkjgscxyzhdjyxz.html | 48 ++++++ .../zhihu-younxzdjsjzyxsjrdgq.html | 48 ++++++ dist/oo/abstract.html | 6 +- dist/oo/code-init.html | 6 +- dist/oo/construct.html | 6 +- dist/oo/final.html | 6 +- dist/oo/inner-class.html | 6 +- dist/oo/instanceof.html | 6 +- dist/oo/interface.html | 6 +- dist/oo/method.html | 6 +- dist/oo/object-class.html | 6 +- dist/oo/static.html | 6 +- dist/oo/this-super.html | 6 +- dist/oo/var.html | 6 +- dist/overview/hello-world.html | 6 +- dist/overview/what-is-java.html | 6 +- dist/redis/redis-springboot.html | 68 ++++---- dist/redis/rumen.html | 6 +- dist/redis/xuebeng-chuantou-jichuan.html | 6 +- dist/service-worker.js | 2 +- dist/service-worker.js.map | 2 +- dist/shigu/image-yasuo.html | 6 +- dist/shigu/log4j2.html | 6 +- dist/sidebar/computer-base.html | 6 +- dist/sidebar/herongwei/mysql.html | 6 +- dist/sidebar/sanfene/collection.html | 6 +- dist/sidebar/sanfene/javase.html | 6 +- dist/sidebar/sanfene/javathread.html | 6 +- dist/sidebar/sanfene/jvm.html | 6 +- dist/sidebar/sanfene/mybatis.html | 6 +- dist/sidebar/sanfene/nixi.html | 6 +- dist/sidebar/sanfene/redis.html | 6 +- dist/sidebar/sanfene/spring.html | 6 +- dist/sitemap.xml | 2 +- .../Filter-Interceptor-Listener.html | 14 +- dist/springboot/aop-log.html | 6 +- dist/springboot/cors.html | 6 +- dist/springboot/initializr.html | 14 +- dist/springboot/ioc.html | 6 +- dist/springboot/jpa.html | 12 +- dist/springboot/jwt.html | 6 +- dist/springboot/linux-codingmore-run.html | 124 ++++++++++++++ dist/springboot/logback.html | 14 +- dist/springboot/macos-codingmore-run.html | 6 +- dist/springboot/mysql-druid.html | 12 +- dist/springboot/oss.html | 10 +- dist/springboot/springtask.html | 10 +- dist/springboot/swagger.html | 12 +- dist/springboot/thymeleaf.html | 10 +- dist/springboot/tomcat.html | 6 +- dist/springboot/transaction.html | 22 +-- dist/springboot/windows-codingmore-run.html | 10 +- dist/string/constant-pool.html | 6 +- dist/string/equals.html | 6 +- dist/string/immutable.html | 6 +- dist/string/intern.html | 6 +- dist/string/join.html | 6 +- dist/string/split.html | 6 +- dist/szjy/buy-cloud-server.html | 6 +- dist/szjy/buy-domain.html | 6 +- dist/szjy/https-domain.html | 8 +- dist/szjy/install-baota-mianban.html | 6 +- dist/szjy/record-domain.html | 10 +- .../tobebetterjavaer-wangzhan-shangxian.html | 6 +- dist/szjy/tupian-zhuanlian.html | 6 +- dist/thread/BlockingQueue.html | 6 +- dist/thread/ConcurrentHashMap.html | 6 +- dist/thread/ConcurrentLinkedQueue.html | 6 +- dist/thread/CopyOnWriteArrayList.html | 6 +- dist/thread/CountDownLatch.html | 6 +- dist/thread/LockSupport.html | 6 +- dist/thread/ReentrantReadWriteLock.html | 6 +- dist/thread/ScheduledThreadPoolExecutor.html | 6 +- dist/thread/ThreadLocal.html | 6 +- dist/thread/ali-executors.html | 6 +- dist/thread/aqs.html | 6 +- dist/thread/atomic.html | 6 +- dist/thread/cas.html | 6 +- dist/thread/condition.html | 6 +- dist/thread/fork-join.html | 6 +- dist/thread/jmm.html | 6 +- dist/thread/lock.html | 6 +- dist/thread/map.html | 6 +- dist/thread/pool.html | 6 +- dist/thread/reentrantLock.html | 6 +- dist/thread/shengchanzhe-xiaofeizhe.html | 6 +- dist/thread/synchronized.html | 6 +- dist/thread/thread-bring-some-problem.html | 6 +- .../thread-group-and-thread-priority.html | 6 +- dist/thread/thread-state-and-method.html | 6 +- dist/thread/volatile.html | 6 +- dist/thread/wangzhe-thread.html | 6 +- dist/thread/why-need-thread.html | 6 +- .../aliyun-shuaiguo-gongchengshi.html | 6 +- dist/xianliaolaoke/chadiansanhuo.html | 6 +- .../chengxuyuannv-chonghui-java.html | 6 +- dist/xianliaolaoke/daxue-nuli-jisuanji.html | 6 +- dist/xianliaolaoke/fumutuanju.html | 6 +- .../electron-information-engineering.html | 8 +- dist/xuexijianyi/read-csapp.html | 8 +- dist/xuexiluxian/algorithm.html | 6 +- dist/xuexiluxian/c.html | 6 +- dist/xuexiluxian/ccc.html | 6 +- dist/xuexiluxian/go.html | 6 +- dist/xuexiluxian/index.html | 6 +- dist/xuexiluxian/java/jvm.html | 6 +- dist/xuexiluxian/java/thread.html | 6 +- dist/xuexiluxian/java/yitiaolong.html | 6 +- dist/xuexiluxian/lanqiaobei.html | 6 +- dist/xuexiluxian/os.html | 6 +- dist/xuexiluxian/python.html | 6 +- dist/xuexiluxian/qianduan.html | 6 +- dist/zhishixingqiu/index.html | 10 +- dist/zhishixingqiu/java-mianshi-zhinan.html | 6 +- dist/zookeeper/jibenjieshao.html | 6 +- 655 files changed, 2655 insertions(+), 1311 deletions(-) rename dist/assets/{100-budiushi.html.f74d8841.js => 100-budiushi.html.281fc989.js} (99%) rename dist/assets/{4-debug-skill.html.1e235b0a.js => 4-debug-skill.html.0c72ed75.js} (99%) rename dist/assets/{40-interview.html.cb9b99de.js => 40-interview.html.e460eeeb.js} (99%) rename dist/assets/{404.5ae72665.js => 404.c61acaed.js} (98%) rename dist/assets/{404.html.5c274669.js => 404.html.6cb935de.js} (71%) rename dist/assets/{48-keywords.html.34eb30fe.js => 48-keywords.html.c30c9b30.js} (98%) rename dist/assets/{BIONIOAIO.html.27d4fa22.js => BIONIOAIO.html.4c184e72.js} (99%) rename dist/assets/{BOKEYUANruhegaoxiaodixuexijishu.html.bdd4e19a.js => BOKEYUANruhegaoxiaodixuexijishu.html.665a0cbe.js} (99%) rename dist/assets/{BlockingQueue.html.5fa0f03a.js => BlockingQueue.html.76b31f3c.js} (99%) rename dist/assets/{Chocolatey-Homebrew.html.a0b23720.js => Chocolatey-Homebrew.html.5637171d.js} (99%) rename dist/assets/{ConcurrentHashMap.html.127182e6.js => ConcurrentHashMap.html.77d65cc9.js} (99%) rename dist/assets/{ConcurrentLinkedQueue.html.ad944043.js => ConcurrentLinkedQueue.html.f8564dd9.js} (99%) rename dist/assets/{CopyOnWriteArrayList.html.375356c8.js => CopyOnWriteArrayList.html.2fa1badd.js} (99%) rename dist/assets/{CountDownLatch.html.db5e5e87.js => CountDownLatch.html.79c0b80e.js} (99%) rename dist/assets/{DBeaver.html.8a022161.js => DBeaver.html.16c02541.js} (99%) create mode 100644 dist/assets/Filter-Interceptor-Listener.html.3a5897a3.js rename dist/assets/{Filter-Interceptor-Listener.html.61c686d0.js => Filter-Interceptor-Listener.html.7803e9df.js} (85%) delete mode 100644 dist/assets/Filter-Interceptor-Listener.html.d4211e38.js rename dist/assets/{Lambda.html.16e88b8a.js => Lambda.html.bd1566d3.js} (99%) rename dist/assets/{Layout.fbcb8daf.js => Layout.2f241dd5.js} (80%) rename dist/assets/{LockSupport.html.55f27ea8.js => LockSupport.html.5ea98b89.js} (99%) rename dist/assets/{Overriding.html.e0ccdfe1.js => Overriding.html.d8235770.js} (99%) rename dist/assets/{ReentrantReadWriteLock.html.b8dcb20a.js => ReentrantReadWriteLock.html.140f1c3e.js} (99%) rename dist/assets/{ScheduledThreadPoolExecutor.html.e216d19d.js => ScheduledThreadPoolExecutor.html.73744e7a.js} (99%) rename dist/assets/{SkipLink.e761490e.js => SkipLink.a2c3a90f.js} (89%) rename dist/assets/{Slide.a2a8944b.js => Slide.39e63deb.js} (94%) rename dist/assets/{ThreadLocal.html.284cf60c.js => ThreadLocal.html.2993d4fd.js} (99%) rename dist/assets/{ZHIHUjavaxuexidaoshemechengduokeyizhaodiyifengongzuo.html.9b7b6461.js => ZHIHUjavaxuexidaoshemechengduokeyizhaodiyifengongzuo.html.ef1e0c27.js} (98%) rename dist/assets/{abstract.html.60b3966f.js => abstract.html.e17df797.js} (99%) rename dist/assets/{algorithm.html.66d3e273.js => algorithm.html.8d44122f.js} (99%) rename dist/assets/{ali-executors.html.e9951d8a.js => ali-executors.html.3e2ae653.js} (99%) rename dist/assets/{aliyun-shuaiguo-gongchengshi.html.80a83c0a.js => aliyun-shuaiguo-gongchengshi.html.af9a0166.js} (99%) rename dist/assets/{annotation.html.b0fc1ba0.js => annotation.html.3a9fcfe1.js} (99%) rename dist/assets/{aop-log.html.f3df7d62.js => aop-log.html.ec10c829.js} (99%) rename dist/assets/{api-wangguan.html.9f0edd64.js => api-wangguan.html.ec8dd3f1.js} (99%) create mode 100644 dist/assets/app.615e41d8.js delete mode 100644 dist/assets/app.a0271b9c.js rename dist/assets/{aqs.html.e6bd9611.js => aqs.html.58976faa.js} (99%) rename dist/assets/{array.html.97a807b4.js => array.html.19972859.js} (99%) rename dist/assets/{arraylist.html.804615c1.js => arraylist.html.f57cbfa7.js} (99%) rename dist/assets/{arrays.html.13de83ef.js => arrays.html.ea4b1150.js} (99%) rename dist/assets/{asm.html.deedcff5.js => asm.html.43e7fd57.js} (99%) rename dist/assets/{atomic.html.1dc322e5.js => atomic.html.08ec5c1f.js} (99%) rename dist/assets/{auto-generator.html.79ba5c06.js => auto-generator.html.341a868e.js} (79%) rename dist/assets/{auto-generator.html.edd07e0d.js => auto-generator.html.7efe2473.js} (74%) rename dist/assets/{basic-data-type.html.52152cd3.js => basic-data-type.html.20d3399e.js} (99%) create mode 100644 dist/assets/bat-shuati.html.01dded07.js create mode 100644 dist/assets/bat-shuati.html.214e49f5.js delete mode 100644 dist/assets/bat-shuati.html.adba9635.js delete mode 100644 dist/assets/bat-shuati.html.bf129827.js delete mode 100644 dist/assets/beijing.html.5436f34b.js create mode 100644 dist/assets/beijing.html.78adaacf.js create mode 100644 dist/assets/beijing.html.a011f671.js delete mode 100644 dist/assets/beijing.html.ac5b087b.js rename dist/assets/{bokeyuan-jianxijavazhongdifangwenquanxiankongzhi.html.95de7e08.js => bokeyuan-jianxijavazhongdifangwenquanxiankongzhi.html.5212785d.js} (99%) rename dist/assets/{bokeyuan-ruhegaoxiaodixuexijishu.html.b64706b8.js => bokeyuan-ruhegaoxiaodixuexijishu.html.e50696a0.js} (99%) rename dist/assets/{box.html.9c8b69db.js => box.html.03f96a13.js} (99%) rename dist/assets/{buy-cloud-server.html.d200b8bc.js => buy-cloud-server.html.5057ae50.js} (96%) rename dist/assets/{buy-domain.html.4406ff12.js => buy-domain.html.e087e5aa.js} (98%) rename dist/assets/{bytecode.html.09a0585c.js => bytecode.html.568c5a04.js} (99%) rename dist/assets/{bzhan-10wan.html.b3906807.js => bzhan-10wan.html.e0ad4af0.js} (99%) rename dist/assets/{c.html.1f2463e6.js => c.html.6387955f.js} (99%) rename dist/assets/{cas.html.ff0123d4.js => cas.html.68e07dc8.js} (99%) rename dist/assets/{ccc.html.0a777341.js => ccc.html.bf391d30.js} (98%) rename dist/assets/{chadiansanhuo.html.78becde9.js => chadiansanhuo.html.fc173db8.js} (99%) delete mode 100644 dist/assets/chengdu.html.09b27f2f.js create mode 100644 dist/assets/chengdu.html.7221dfab.js delete mode 100644 dist/assets/chengdu.html.8c0a9616.js create mode 100644 dist/assets/chengdu.html.c9264a1d.js rename dist/assets/{chengxuyuannv-chonghui-java.html.b2dd4108.js => chengxuyuannv-chonghui-java.html.01f1b5cf.js} (98%) rename dist/assets/{chiner.html.5580190e.js => chiner.html.daf0adff.js} (99%) rename dist/assets/{choco.html.8857968e.js => choco.html.2c7d8900.js} (99%) rename dist/assets/{class-file-jiegou.html.63f6ec81.js => class-file-jiegou.html.3aa9524b.js} (99%) rename dist/assets/{class-load.html.ac3b08f8.js => class-load.html.07c5abca.js} (99%) rename dist/assets/{class-object.html.2cd0dbd5.js => class-object.html.a22a09d8.js} (99%) rename dist/assets/{code-init.html.16081b84.js => code-init.html.58676afd.js} (99%) rename dist/assets/{collection.html.d1a47d1f.js => collection.html.e1c47b4b.js} (99%) rename dist/assets/{collections.html.b7f2022a.js => collections.html.37777ec8.js} (99%) rename dist/assets/{comparable-omparator.html.c8fb7fdb.js => comparable-omparator.html.1a3bff07.js} (99%) rename dist/assets/{compile-jdk.html.2e638e51.js => compile-jdk.html.fddb4940.js} (99%) rename dist/assets/{computer-base.html.1ca00f7c.js => computer-base.html.ca77cdaf.js} (96%) rename dist/assets/{condition.html.dcd667af.js => condition.html.4a44859a.js} (99%) rename dist/assets/{constant-pool.html.e2d85914.js => constant-pool.html.81e697ea.js} (99%) rename dist/assets/{construct.html.ebfac9f1.js => construct.html.0a38a577.js} (99%) rename dist/assets/{cors.html.32e975b9.js => cors.html.b1e575b3.js} (99%) rename dist/assets/{cpu-percent-100.html.3a56db8e.js => cpu-percent-100.html.30d9234e.js} (99%) rename dist/assets/{csdn-1000wan.html.2e52cd37.js => csdn-1000wan.html.22ddf17a.js} (99%) rename dist/assets/{daxue-nuli-jisuanji.html.5d9f6906.js => daxue-nuli-jisuanji.html.ad13ab16.js} (99%) rename dist/assets/{deep-copy.html.b6383852.js => deep-copy.html.1b203746.js} (99%) rename dist/assets/{deletedb-binlog-weiguanjishu.html.114e51d7.js => deletedb-binlog-weiguanjishu.html.0dd5fe85.js} (99%) create mode 100644 dist/assets/electron-information-engineering.html.16bd5754.js rename dist/assets/{electron-information-engineering.html.365eb9fa.js => electron-information-engineering.html.6411b062.js} (99%) delete mode 100644 dist/assets/electron-information-engineering.html.b3d4a3e7.js rename dist/assets/{enum.html.e72022eb.js => enum.html.637c7ac9.js} (99%) rename dist/assets/{equals-hashcode.html.6e080022.js => equals-hashcode.html.033e729f.js} (99%) rename dist/assets/{equals.html.b49827b6.js => equals.html.f7e52978.js} (99%) rename dist/assets/{fail-fast.html.613c56f6.js => fail-fast.html.dca676b6.js} (99%) rename dist/assets/{fanshe.html.c9e51464.js => fanshe.html.e42ba18d.js} (99%) rename dist/assets/{fastjson.html.ac85dfcc.js => fastjson.html.bf5a0ad8.js} (99%) rename dist/assets/{final.html.de436e22.js => final.html.e625665e.js} (99%) rename dist/assets/{flow-control.html.1f719486.js => flow-control.html.5046ff0c.js} (99%) rename dist/assets/{forest.html.18099f01.js => forest.html.3141000b.js} (99%) rename dist/assets/{fork-join.html.148dd105.js => fork-join.html.e8674cdb.js} (99%) rename dist/assets/{fumutuanju.html.d5b695cc.js => fumutuanju.html.ca0f5d88.js} (99%) rename dist/assets/{gailan.html.89a0a128.js => gailan.html.0ea3f7da.js} (99%) rename dist/assets/{gailan.html.a5bab427.js => gailan.html.50f82bf5.js} (99%) rename dist/assets/{gc.html.10f470a0.js => gc.html.714d0f7b.js} (99%) rename dist/assets/{generic.html.47649dca.js => generic.html.df9c6eb8.js} (99%) rename dist/assets/{git-qiyuan.html.1b827703.js => git-qiyuan.html.085fb4bc.js} (99%) rename dist/assets/{go.html.712c93cd.js => go.html.dbab658a.js} (99%) rename dist/assets/{gson.html.da4ecf62.js => gson.html.a359eddd.js} (99%) delete mode 100644 dist/assets/guangzhou.html.14bc2637.js create mode 100644 dist/assets/guangzhou.html.58700f92.js create mode 100644 dist/assets/guangzhou.html.c44755f8.js delete mode 100644 dist/assets/guangzhou.html.ce1033cd.js rename dist/assets/{guava.html.1f12859a.js => guava.html.bbc48258.js} (99%) rename dist/assets/{haibukuaiyongmybatisplusshoubashoujiaoni.html.5f5e650f.js => haibukuaiyongmybatisplusshoubashoujiaoni.html.6feacfb3.js} (99%) create mode 100644 dist/assets/hangzhou.html.52f2ce43.js delete mode 100644 dist/assets/hangzhou.html.9719a0ea.js create mode 100644 dist/assets/hangzhou.html.a9b39480.js delete mode 100644 dist/assets/hangzhou.html.b80d450d.js rename dist/assets/{hashcode.html.94e85992.js => hashcode.html.6a0e81d9.js} (99%) rename dist/assets/{hashmap-interview.html.2609e519.js => hashmap-interview.html.36f118fd.js} (99%) rename dist/assets/{hashmap.html.cd5a497b.js => hashmap.html.e3590cbb.js} (99%) rename dist/assets/{hello-world.html.504deafe.js => hello-world.html.26946542.js} (99%) rename dist/assets/{history.html.6bcd3b59.js => history.html.57bb6aeb.js} (99%) create mode 100644 dist/assets/home.html.1fffdb8f.js create mode 100644 dist/assets/home.html.25268b5b.js delete mode 100644 dist/assets/home.html.4301cc35.js delete mode 100644 dist/assets/home.html.c8d9ace7.js rename dist/assets/{how-jvm-run-zijiema-zhiling.html.4c09b054.js => how-jvm-run-zijiema-zhiling.html.f5dbcd2c.js} (99%) rename dist/assets/{how-run-java-code.html.5a48d5a6.js => how-run-java-code.html.5154cace.js} (99%) rename dist/assets/{hsdb.html.18e11779.js => hsdb.html.4b8d1063.js} (99%) rename dist/assets/{https-domain.html.86fa1a27.js => https-domain.html.81185a29.js} (98%) rename dist/assets/{hutool.html.3a80c8b8.js => hutool.html.5bf70ca7.js} (99%) rename dist/assets/{image-yasuo.html.d1e70eaf.js => image-yasuo.html.0e3ff54c.js} (99%) rename dist/assets/{immutable.html.e7e4c546.js => immutable.html.aab5b4ed.js} (99%) rename dist/assets/{immutable.html.923c43ef.js => immutable.html.acff64d4.js} (99%) delete mode 100644 dist/assets/index.html.2971f84c.js rename dist/assets/{index.html.8360409e.js => index.html.96eac070.js} (95%) create mode 100644 dist/assets/index.html.9c1a7487.js create mode 100644 dist/assets/index.html.9ee0e417.js delete mode 100644 dist/assets/index.html.af7b50d7.js rename dist/assets/{index.html.ece7c54d.js => index.html.b90a750c.js} (89%) delete mode 100644 dist/assets/index.html.bb2bcc18.js create mode 100644 dist/assets/index.html.bc31ce34.js rename dist/assets/{index.html.17715b69.js => index.html.c95125a9.js} (95%) rename dist/assets/{index.html.23006160.js => index.html.efbaa943.js} (98%) rename dist/assets/{initializr.html.ae05e8c2.js => initializr.html.47ddf572.js} (65%) create mode 100644 dist/assets/initializr.html.8afcbffb.js delete mode 100644 dist/assets/initializr.html.8cd24dbb.js rename dist/assets/{inner-class.html.5b071786.js => inner-class.html.858a9fd0.js} (99%) rename dist/assets/{install-baota-mianban.html.4c7a95c4.js => install-baota-mianban.html.fc940506.js} (98%) rename dist/assets/{instanceof-jvm.html.c9e8e080.js => instanceof-jvm.html.84099ac1.js} (99%) rename dist/assets/{instanceof.html.d3f5b0d7.js => instanceof.html.edc709c7.js} (99%) rename dist/assets/{int-cache.html.c609a3a6.js => int-cache.html.bb142a51.js} (99%) rename dist/assets/{interface.html.60cd9cd7.js => interface.html.de30e51e.js} (99%) rename dist/assets/{intern.html.57f3b131.js => intern.html.cb5b47c3.js} (99%) rename dist/assets/{ioc.html.00ef348c.js => ioc.html.a79e951b.js} (99%) rename dist/assets/{iterator-iterable.html.df321c38.js => iterator-iterable.html.7a5374e3.js} (99%) rename dist/assets/{jackson.html.f9f2bbfc.js => jackson.html.f4471baf.js} (99%) rename dist/assets/{java-basic-34.html.ff9af0e4.js => java-basic-34.html.c0108ee7.js} (99%) rename dist/assets/{java-basic.html.0b10b00c.js => java-basic.html.34b72317.js} (99%) rename dist/assets/{java-mianshi-zhinan.html.e2de50f8.js => java-mianshi-zhinan.html.9c0ece4d.js} (99%) rename dist/assets/{java-naming.html.cc154c6b.js => java-naming.html.1100d2ca.js} (99%) rename dist/assets/{java-thread.html.52bdf4b1.js => java-thread.html.87abce4b.js} (99%) rename dist/assets/{java-unicode.html.17dea1e9.js => java-unicode.html.c63853a0.js} (99%) delete mode 100644 dist/assets/java.html.74ed2cc3.js create mode 100644 dist/assets/java.html.8cfce3ac.js create mode 100644 dist/assets/java.html.9104a10d.js delete mode 100644 dist/assets/java.html.c5bee727.js rename dist/assets/{javadoc.html.6c8ace88.js => javadoc.html.435ee8ec.js} (99%) rename dist/assets/{javase.html.d7cb534c.js => javase.html.4c6f74ba.js} (99%) rename dist/assets/{javathread.html.7f11e6a6.js => javathread.html.9fc70ce0.js} (99%) rename dist/assets/{javaxuexidaoshemechengduokeyizhaodiyifengongzuo.html.2958c9b6.js => javaxuexidaoshemechengduokeyizhaodiyifengongzuo.html.6e4f2abd.js} (98%) rename dist/assets/{jdk-while-for-wuxian-xunhuan.html.a0c2087a.js => jdk-while-for-wuxian-xunhuan.html.a5707bd9.js} (99%) rename dist/assets/{jdk9-char-byte-string.html.27d20839.js => jdk9-char-byte-string.html.884765a3.js} (99%) rename dist/assets/{jiagoushizenyanghuizhijitongjiagoulantu.html.964131a6.js => jiagoushizenyanghuizhijitongjiagoulantu.html.aafe265c.js} (99%) create mode 100644 dist/assets/jianli.html.28361c8b.js create mode 100644 dist/assets/jianli.html.2cde4ea0.js delete mode 100644 dist/assets/jianli.html.5f109d9a.js delete mode 100644 dist/assets/jianli.html.75854f37.js rename dist/assets/{jibenjieshao.html.98a7aaac.js => jibenjieshao.html.6a5f31db.js} (99%) rename dist/assets/{jielehenduosihuodiganchu.html.fa573110.js => jielehenduosihuodiganchu.html.576b64a2.js} (99%) create mode 100644 dist/assets/jinan.html.95982728.js create mode 100644 dist/assets/jinan.html.d4c22f59.js rename dist/assets/{jishuzongjianbeikaichuliao.html.1774b950.js => jishuzongjianbeikaichuliao.html.6397e62a.js} (99%) rename dist/assets/{jit.html.4cb31299.js => jit.html.cd04156f.js} (99%) rename dist/assets/{jmm.html.6df91381.js => jmm.html.2560457a.js} (99%) rename dist/assets/{join.html.18a0e9f8.js => join.html.50d59b6e.js} (99%) rename dist/assets/{jpa.html.8adce5f1.js => jpa.html.c491ef74.js} (88%) rename dist/assets/{jpa.html.c4109873.js => jpa.html.cb4e1f80.js} (72%) rename dist/assets/{junit.html.a79d9c04.js => junit.html.9c832cdc.js} (99%) rename dist/assets/{jvm.html.e2246150.js => jvm.html.375475cb.js} (99%) rename dist/assets/{jvm.html.86668e04.js => jvm.html.c049e00d.js} (99%) rename dist/assets/{jvm.html.d7d28727.js => jvm.html.cb0eace1.js} (99%) rename dist/assets/{jwt.html.e910af0e.js => jwt.html.2aed3523.js} (99%) rename dist/assets/{knife4j.html.44253ad0.js => knife4j.html.4fbb94b8.js} (75%) rename dist/assets/{knife4j.html.fe2f8e7d.js => knife4j.html.a18b3a85.js} (72%) rename dist/assets/{lanqiaobei.html.489bde40.js => lanqiaobei.html.e24944e8.js} (99%) rename dist/assets/{learn-jianyi.html.453bb02b.js => learn-jianyi.html.2486d715.js} (88%) rename dist/assets/{linkedlist.html.4b75cd4d.js => linkedlist.html.e021186b.js} (99%) create mode 100644 dist/assets/linux-codingmore-run.html.6ac5d933.js create mode 100644 dist/assets/linux-codingmore-run.html.d96d85b1.js rename dist/assets/{list-war-2.html.96808d02.js => list-war-2.html.4306ceaf.js} (99%) rename dist/assets/{lock.html.a13afff5.js => lock.html.707d5244.js} (99%) rename dist/assets/{log4j.html.dbbf9c72.js => log4j.html.0b4fd542.js} (99%) rename dist/assets/{log4j2.html.17000ac4.js => log4j2.html.066d10f7.js} (99%) rename dist/assets/{log4j2.html.f846d981.js => log4j2.html.d1682823.js} (99%) rename dist/assets/{logback.html.65200f68.js => logback.html.28ab1df5.js} (79%) rename dist/assets/{logback.html.869073f6.js => logback.html.806b8b11.js} (99%) rename dist/assets/{logback.html.bd3bc959.js => logback.html.ce19f5e4.js} (79%) rename dist/assets/{macos-codingmore-run.html.984613a6.js => macos-codingmore-run.html.100361aa.js} (99%) rename dist/assets/{map.html.61b4c4d9.js => map.html.6ee85b94.js} (99%) rename dist/assets/{maven.html.9abc8500.js => maven.html.d13a0dbf.js} (99%) rename dist/assets/{meituan-9-gc.html.26985c28.js => meituan-9-gc.html.7173ffd4.js} (99%) rename dist/assets/{method.html.67a1e169.js => method.html.1f147cbd.js} (99%) rename dist/assets/{mybatis.html.a18a9ce2.js => mybatis.html.41ff93f4.js} (99%) rename dist/assets/{mysql-druid.html.bf232591.js => mysql-druid.html.1c47eb57.js} (71%) rename dist/assets/{mysql-druid.html.adb4afdf.js => mysql-druid.html.9707dc06.js} (67%) rename dist/assets/{mysql.html.ecb0e241.js => mysql.html.1afcd596.js} (99%) delete mode 100644 dist/assets/nanjing.html.0381e4b6.js create mode 100644 dist/assets/nanjing.html.099e9844.js create mode 100644 dist/assets/nanjing.html.44d630fa.js delete mode 100644 dist/assets/nanjing.html.df603525.js rename dist/assets/{neicun-jiegou.html.e6842a53.js => neicun-jiegou.html.fee2587a.js} (99%) create mode 100644 dist/assets/nginx-setting.html.3934a533.js create mode 100644 dist/assets/nginx-setting.html.68b3250b.js rename dist/assets/{nginx.html.30b3f8bd.js => nginx.html.25ed8525.js} (99%) rename dist/assets/{nicearticle.html.aa656631.js => nicearticle.html.4730077f.js} (99%) rename dist/assets/{nixi.html.8b48857f.js => nixi.html.de6f9361.js} (93%) rename dist/assets/{npe.html.01d29f9c.js => npe.html.297684ef.js} (99%) rename dist/assets/{object-class.html.96fd3d4e.js => object-class.html.698d849f.js} (99%) rename dist/assets/{oom.html.d0512b48.js => oom.html.cbfa1fb6.js} (99%) rename dist/assets/{operator.html.783e87f0.js => operator.html.152cf4bc.js} (99%) rename dist/assets/{optional.html.d38ec385.js => optional.html.775157f3.js} (99%) rename dist/assets/{os.html.e10e307f.js => os.html.1d208877.js} (99%) rename dist/assets/{os.html.2d6bc714.js => os.html.781c26b2.js} (99%) rename dist/assets/{oss.html.977b34d5.js => oss.html.8b1ce1ec.js} (86%) rename dist/assets/{oss.html.b690f015.js => oss.html.e3216442.js} (98%) rename dist/assets/{others.html.214194b1.js => others.html.63b5af1f.js} (96%) rename dist/assets/{override-overload.html.853755f9.js => override-overload.html.1c9aaf26.js} (99%) rename dist/assets/{pass-by-value.html.c65b64be.js => pass-by-value.html.cf8023d5.js} (99%) rename dist/assets/{pdf.html.0610fb03.js => pdf.html.79c228f5.js} (95%) rename dist/assets/{pool.html.79813894.js => pool.html.7274870a.js} (99%) rename dist/assets/{print.html.f0b4f56c.js => print.html.4135561a.js} (99%) rename dist/assets/{problem-tools.html.c2bda786.js => problem-tools.html.c0e0819e.js} (99%) rename dist/assets/{progit.html.66c47307.js => progit.html.284a6498.js} (98%) delete mode 100644 dist/assets/progit.html.3b6ba984.js rename dist/assets/{progit.html.de3011f5.js => progit.html.95158ac7.js} (98%) create mode 100644 dist/assets/progit.html.df477a55.js rename dist/assets/{python.html.e5ae48ee.js => python.html.6ba47e37.js} (98%) rename dist/assets/{qianduan.html.60a6bdee.js => qianduan.html.ef57d5d5.js} (99%) delete mode 100644 dist/assets/qingdao.html.026cf757.js delete mode 100644 dist/assets/qingdao.html.08ca70e9.js create mode 100644 dist/assets/qingdao.html.826f4cb2.js create mode 100644 dist/assets/qingdao.html.c4a4c2c4.js rename dist/assets/{rabbitmq-rumen.html.719aebed.js => rabbitmq-rumen.html.5bf7bc58.js} (99%) delete mode 100644 dist/assets/read-csapp.html.23c82cf4.js create mode 100644 dist/assets/read-csapp.html.768012b7.js create mode 100644 dist/assets/read-csapp.html.c0e758ea.js delete mode 100644 dist/assets/read-csapp.html.f8f796e3.js delete mode 100644 dist/assets/record-domain.html.19eb33ac.js rename dist/assets/{record-domain.html.9b78d780.js => record-domain.html.3a82f73e.js} (98%) create mode 100644 dist/assets/record-domain.html.667d7982.js rename dist/assets/{redis-shuju-yizhixing.html.7e461ea4.js => redis-shuju-yizhixing.html.480d5fea.js} (99%) rename dist/assets/{redis-springboot.html.7783ee99.js => redis-springboot.html.3faa6adc.js} (86%) rename dist/assets/{redis-springboot.html.5e59844d.js => redis-springboot.html.44044d02.js} (73%) rename dist/assets/{redis.html.7543ed9c.js => redis.html.bcbe4235.js} (99%) rename dist/assets/{redis12question.html.bab032b9.js => redis12question.html.f0270e84.js} (99%) rename dist/assets/{reentrantLock.html.d3a77dd6.js => reentrantLock.html.8b519bdc.js} (99%) rename dist/assets/{rumen.html.f241efd5.js => rumen.html.27e01d35.js} (99%) rename dist/assets/{rumen.html.4002e397.js => rumen.html.3f2b5ec9.js} (99%) rename dist/assets/{rumen.html.439110fe.js => rumen.html.ee21a790.js} (99%) rename dist/assets/{shanganaliyun.html.fc60e761.js => shanganaliyun.html.802605a1.js} (99%) rename dist/assets/{shangtou.html.fc7b3e84.js => shangtou.html.d25e4bab.js} (99%) rename dist/assets/{shengchanzhe-xiaofeizhe.html.920a9bd9.js => shengchanzhe-xiaofeizhe.html.b76e11fd.js} (99%) delete mode 100644 dist/assets/shenzhen.html.037e48a5.js delete mode 100644 dist/assets/shenzhen.html.48307e94.js create mode 100644 dist/assets/shenzhen.html.61178979.js create mode 100644 dist/assets/shenzhen.html.98e7f6e9.js rename dist/assets/{shijian.html.84eb0eab.js => shijian.html.d1dfaaba.js} (99%) rename dist/assets/{slf4j.html.a17cdf5a.js => slf4j.html.f772534d.js} (99%) rename dist/assets/{split.html.dbaed6aa.js => split.html.b69d2cd1.js} (99%) rename dist/assets/{spring.html.26f406c7.js => spring.html.40b7b2ff.js} (99%) rename dist/assets/{springtask.html.406633ab.js => springtask.html.04deb6a0.js} (85%) rename dist/assets/{springtask.html.0afe6499.js => springtask.html.6f8efcf6.js} (91%) rename dist/assets/{static.html.8ee519bc.js => static.html.c9732093.js} (99%) rename dist/assets/{stream.html.db791f6b.js => stream.html.02d08777.js} (99%) delete mode 100644 dist/assets/suzhou.html.1f658a4a.js create mode 100644 dist/assets/suzhou.html.428c3730.js create mode 100644 dist/assets/suzhou.html.b2ed5bbc.js delete mode 100644 dist/assets/suzhou.html.e601b996.js rename dist/assets/{swagger.html.03ed15b7.js => swagger.html.1142f08f.js} (71%) rename dist/assets/{swagger.html.d41c975f.js => swagger.html.e13d1880.js} (73%) rename dist/assets/{synchronized.html.2e0681cb.js => synchronized.html.0249091e.js} (99%) rename dist/assets/{tabby.html.5c93d604.js => tabby.html.c3b44c08.js} (99%) rename dist/assets/{this-super.html.5e8e4dee.js => this-super.html.ff84e809.js} (99%) rename dist/assets/{thread-bring-some-problem.html.b2f11eb4.js => thread-bring-some-problem.html.891141f3.js} (99%) rename dist/assets/{thread-group-and-thread-priority.html.041c72b9.js => thread-group-and-thread-priority.html.777c962b.js} (99%) rename dist/assets/{thread-state-and-method.html.a628789d.js => thread-state-and-method.html.a816be26.js} (99%) rename dist/assets/{thread.html.a2ddbdf4.js => thread.html.4fcef02c.js} (99%) rename dist/assets/{thymeleaf.html.be244969.js => thymeleaf.html.943910b5.js} (54%) rename dist/assets/{thymeleaf.html.1a24ed99.js => thymeleaf.html.b2ef505e.js} (73%) rename dist/assets/{tobebetterjavaer-wangzhan-shangxian.html.88c8d82b.js => tobebetterjavaer-wangzhan-shangxian.html.eb4a3068.js} (99%) rename dist/assets/{tomcat.html.3d86b543.js => tomcat.html.af3e6ee8.js} (99%) rename dist/assets/{transaction.html.c6ea47a0.js => transaction.html.1d6a1548.js} (51%) rename dist/assets/{transaction.html.89e3579f.js => transaction.html.9982a65f.js} (90%) rename dist/assets/{true-generic.html.dbcaca38.js => true-generic.html.a683e7b2.js} (99%) rename dist/assets/{try-with-resouces.html.c242816c.js => try-with-resouces.html.52a831d4.js} (99%) rename dist/assets/{tujie-gc.html.70c281f0.js => tujie-gc.html.3ec6a37b.js} (99%) rename dist/assets/{tupian-zhuanlian.html.7e57c89c.js => tupian-zhuanlian.html.cc248511.js} (99%) rename dist/assets/{var.html.d8139bc5.js => var.html.6e7f16a9.js} (99%) rename dist/assets/{varables.html.4e32dd4f.js => varables.html.3f84ac76.js} (99%) rename dist/assets/{volatile.html.e6448db8.js => volatile.html.4f34c8de.js} (99%) rename dist/assets/{waibao-1geyue.html.1edb2375.js => waibao-1geyue.html.31a36346.js} (99%) rename dist/assets/{wangluo.html.bd9e0045.js => wangluo.html.bf2e0885.js} (99%) rename dist/assets/{wangzhe-thread.html.6222c220.js => wangzhe-thread.html.752a4836.js} (99%) rename dist/assets/{warp.html.f8427955.js => warp.html.8ae8cc83.js} (99%) create mode 100644 dist/assets/weixin-bagwpdf.html.a32b4b3a.js create mode 100644 dist/assets/weixin-bagwpdf.html.e485fe14.js rename dist/assets/{weixin-chengxwjdwzhqcgxm.html.63b423d3.js => weixin-chengxwjdwzhqcgxm.html.5c788b1b.js} (99%) create mode 100644 dist/assets/weixin-githubxbkdjavajccjyh.html.11c03a69.js create mode 100644 dist/assets/weixin-githubxbkdjavajccjyh.html.be4183ae.js rename dist/assets/{weixin-liaoliaoxianliu.html.3a09df17.js => weixin-liaoliaoxianliu.html.fa1a5a6a.js} (99%) create mode 100644 dist/assets/weixin-likbj.html.4138e613.js create mode 100644 dist/assets/weixin-likbj.html.a9767504.js create mode 100644 dist/assets/weixin-mozdsdzfjavableetcodetxxk.html.10059c85.js create mode 100644 dist/assets/weixin-mozdsdzfjavableetcodetxxk.html.62ab0a25.js create mode 100644 dist/assets/weixin-piaolwzjztqdtskwlzfpdf.html.0792de0c.js create mode 100644 dist/assets/weixin-piaolwzjztqdtskwlzfpdf.html.ef3235a6.js create mode 100644 dist/assets/weixin-quoppomspwml.html.03c9aa24.js create mode 100644 dist/assets/weixin-quoppomspwml.html.27944449.js create mode 100644 dist/assets/weixin-shejmsnb.html.1f9c172b.js create mode 100644 dist/assets/weixin-shejmsnb.html.5a6a099f.js create mode 100644 dist/assets/weixin-shenrjcjavabfbchwjdhl.html.8fda2ac2.js create mode 100644 dist/assets/weixin-shenrjcjavabfbchwjdhl.html.ca182283.js rename dist/assets/{weixin-xinllgjszjszzpojozsyjbsjlxyhjfyll.html.5d76cb3c.js => weixin-xinllgjszjszzpojozsyjbsjlxyhjfyll.html.b7b8ec57.js} (98%) create mode 100644 dist/assets/weixin-zaixsfdnavicatzkkydsjkglgjjmgxk.html.ad8c7107.js create mode 100644 dist/assets/weixin-zaixsfdnavicatzkkydsjkglgjjmgxk.html.bcbd11eb.js rename dist/assets/{weixin-zhongxcwbztashjjavahdmj.html.c99fcea1.js => weixin-zhongxcwbztashjjavahdmj.html.2296ba72.js} (99%) rename dist/assets/{weixin-zuixinbujiabandigongsimingdan.html.4000ddf4.js => weixin-zuixinbujiabandigongsimingdan.html.d0426aa9.js} (98%) rename dist/assets/{what-happen-when-javac.html.a3ce0b44.js => what-happen-when-javac.html.a24cf79e.js} (99%) rename dist/assets/{what-is-java.html.e968650c.js => what-is-java.html.efbb701f.js} (99%) rename dist/assets/{what-is-jvm.html.0a353155.js => what-is-jvm.html.3177cd0e.js} (99%) rename dist/assets/{whereis-the-object.html.f6879982.js => whereis-the-object.html.5fa8d65e.js} (99%) rename dist/assets/{why-need-thread.html.08014ce1.js => why-need-thread.html.8e1db849.js} (99%) rename dist/assets/{windows-codingmore-run.html.4fb12f5d.js => windows-codingmore-run.html.225f6c56.js} (94%) rename dist/assets/{windows-codingmore-run.html.dcfb09e6.js => windows-codingmore-run.html.6d49b8aa.js} (87%) delete mode 100644 dist/assets/xian.html.4603b6ae.js delete mode 100644 dist/assets/xian.html.4a14941e.js create mode 100644 dist/assets/xian.html.b0d9fb64.js create mode 100644 dist/assets/xian.html.badb133a.js rename dist/assets/{xuebeng-chuantou-jichuan.html.37293204.js => xuebeng-chuantou-jichuan.html.ffa86b85.js} (99%) rename dist/assets/{yanjiusuo-20wan.html.a3e5343d.js => yanjiusuo-20wan.html.4b71b495.js} (99%) rename dist/assets/{yitiaolong.html.6c191a66.js => yitiaolong.html.277dddb2.js} (99%) delete mode 100644 dist/assets/yuanyifeng-c-language.html.1d18c5bc.js delete mode 100644 dist/assets/yuanyifeng-c-language.html.869263b3.js create mode 100644 dist/assets/yuanyifeng-c-language.html.90250cb3.js create mode 100644 dist/assets/yuanyifeng-c-language.html.dbcc3d40.js rename dist/assets/{yuneban-wangyiyunyinyue.html.df2c1c62.js => yuneban-wangyiyunyinyue.html.83ef1711.js} (99%) delete mode 100644 dist/assets/zhengzhou.html.43c30f38.js delete mode 100644 dist/assets/zhengzhou.html.5cf8ec33.js create mode 100644 dist/assets/zhengzhou.html.bee29209.js create mode 100644 dist/assets/zhengzhou.html.c309c263.js rename dist/assets/{zhihu-1000wan.html.6f71965a.js => zhihu-1000wan.html.51362a9b.js} (99%) create mode 100644 dist/assets/zhihu-jisjkyynxzdtjdyj.html.468f166c.js create mode 100644 dist/assets/zhihu-jisjkyynxzdtjdyj.html.8094217b.js create mode 100644 dist/assets/zhihu-weismyrsyxkjgscxyzhdjyxz.html.98987909.js create mode 100644 dist/assets/zhihu-weismyrsyxkjgscxyzhdjyxz.html.ec5fcad9.js create mode 100644 dist/assets/zhihu-younxzdjsjzyxsjrdgq.html.c66976c6.js create mode 100644 dist/assets/zhihu-younxzdjsjzyxsjrdgq.html.e644f706.js rename dist/assets/{zijiema-zhiling.html.9c4d95e9.js => zijiema-zhiling.html.60db7eb3.js} (99%) rename dist/assets/{zongjie.html.0af46efc.js => zongjie.html.1ee2edb6.js} (99%) create mode 100644 dist/cityselect/jinan.html create mode 100644 dist/nice-article/nginx-setting.html create mode 100644 dist/nice-article/weixin-bagwpdf.html create mode 100644 dist/nice-article/weixin-githubxbkdjavajccjyh.html create mode 100644 dist/nice-article/weixin-likbj.html create mode 100644 dist/nice-article/weixin-mozdsdzfjavableetcodetxxk.html create mode 100644 dist/nice-article/weixin-piaolwzjztqdtskwlzfpdf.html create mode 100644 dist/nice-article/weixin-quoppomspwml.html create mode 100644 dist/nice-article/weixin-shejmsnb.html create mode 100644 dist/nice-article/weixin-shenrjcjavabfbchwjdhl.html create mode 100644 dist/nice-article/weixin-zaixsfdnavicatzkkydsjkglgjjmgxk.html create mode 100644 dist/nice-article/zhihu-jisjkyynxzdtjdyj.html create mode 100644 dist/nice-article/zhihu-weismyrsyxkjgscxyzhdjyxz.html create mode 100644 dist/nice-article/zhihu-younxzdjsjzyxsjrdgq.html create mode 100644 dist/springboot/linux-codingmore-run.html diff --git a/dist/404.html b/dist/404.html index c19fa88c..a1fa2264 100644 --- a/dist/404.html +++ b/dist/404.html @@ -39,10 +39,10 @@ } - + -
这里什么也没有
- +
看起来你访问了一个失效的链接
+ diff --git a/dist/about-the-author/bzhan-10wan.html b/dist/about-the-author/bzhan-10wan.html index 6069a59c..3fc2cde7 100644 --- a/dist/about-the-author/bzhan-10wan.html +++ b/dist/about-the-author/bzhan-10wan.html @@ -39,10 +39,10 @@ } - + -

我的第一个,10 万(B站视频播放)

沉默王二2022年3月18日
  • 联系作者
  • 心路历程
大约 12 分钟

我的第一个,10 万(B站视频播放)

恭喜这个 B。。。。。。站上的 UP,上一期视频播放量突破了 10 万!这也是二哥人生当中的第一次,凭借单条视频突破 10 万播放,必须得纪念下。

从众多的宫斗剧中我得出了一条宝贵的人生经验:“母凭子贵”。这条经验同样适用于二哥本人,可能会因为这一期视频,吹这辈子最多的牛逼:这不,荣获哔哩哔哩第 3 周【校园优秀奖&校园新星奖】。

我已经按捺不住激动的心情,在两万人的朋友圈大肆炫耀了。十万播放,对于百大 UP 来说,可能就是分分钟的事,可对于我这个(未来的) B站百大来说,苦苦等了 149 天!!!!!!!

这真是一个漫长的日子,鬼知道这些天我经历了什么。

我一度怀疑自己到底适不适合拍视频,表情的僵硬,普通话的塑料,甚至连自己一项引以为荣的台本,都觉得拉胯。

可就因为这个视频,让我重获新生,亢奋的心情一直在持续。我知道,一条视频的播放突破 10 万,并不意味着下一个视频也会有 10 万的播放,但好歹能让我感到幸福会,至少可以“厚颜无耻”地再吹一次牛皮吧!

昨天的文章里,承诺新的一年 2022 年把肝重新交给大家,我就会说到做到:这年头,职场就流行这个“沙雕”文化,你有没有能力不重要,重要的是领导交代你的有没有去执行

二哥打算豁出去了!

新一期视频也上传到 B 站了,希望能借英雄哥的吉言,再爆一次。链接我放这里了:

https://www.bilibili.com/video/BV1za411q79U/

三不三连没关系,有关系的是不三连可能会对不起二哥的肝,所以还是三连吧,哈哈哈哈,瞧瞧我们这该死的生物钟,起这么早。。。

接下来,上干货,我把这期 10万+ 播放的视频台本重新整理了一下,本来不想发的,很多小伙伴私信说二哥偏爱 B 站,同步都懒得同步了吗?

这不,赶紧发到公众号上来,希望学生党们现在立刻马上收藏起来,这个寒假你会过得非常充实;至于工作党嘛,像二哥这样的,既要工作,又要读书写作照顾家庭的,忙都忙死了,就算了吧!

啊,不,还是要稍微卷一卷吧,免得被那群还有半年就毕业的家伙们拍死在沙滩上。。。。


二哥的读者当中有不少大学生,所以当知乎上刷到这个题目时:

“学校课程规划的比较奇怪,大一上学期学c++,下学期学python,在寒假我是应该复习或预习课内内容(python,c++),还是自己对外拓展呢(c,数据结构)?”

立马就冲上去答了一波。

就冲这份爱学习的决心,三年后绝对互联网公司的 offer 拿到手软

讲真,小伙伴学校安排的课程和我当年非常相似,也是大一上来就搞 Java,隔壁班上来就搞 C++,完全没有安排 C语言来过渡下。

所以我的建议是,趁寒假打打王者上上分吧

啊,不!趁寒假刷一波清华在 GitHub 上 20k+ star 的开源课程吧

一、清华大学在 GitHub 上的开源课程

地址:https://github.com/PKUanonym/REKCARC-TSC-UHT

我来带小伙伴们过一下清华的课程安排哈,主要是针对计算机专业的。

大一上的计算机基础课程有:计算机科学导论、程序设计基础

大一下有:面向对象程序设计基础

大二上有:数据结构

大二下有:人工智能导论、计算机图形学基础、高性能计算导论

大三上有:计算机组成原理、计算机网络原理、编译原理、软件工程、数据库系统概论、人工神经网络、计算机网络安全技术、人机交互理论与技术

大三下有:操作系统、计算机系统结构、机器学习概论、数据挖掘、搜索引擎技术基础、存储技术基础、数据库专题训练、计算机网络专题训练。

大四主要是实践、实习、毕设等,剩下的计算机课程主要有网络安全工程与实践、嵌入式系统。

可以看得出,大一大二基本上是在摸鱼状态,大三突然开始发力,各种计算机基础课程,非常疯狂!

不过:

有志者事竟成,破釜沉舟,百二秦关终属楚;
苦心人天不负,卧薪尝胆,三千越甲可吞吴!

二、学习 C语言

推荐一本书,两门视频课

书是电子书,书名叫《阮一峰的 C语言入门课》,我第一时间就拜读了一遍,受益匪浅!可以说目前我见到的最好的 C语言入门教程了,没有之一!国内的绝大多数高校,大一都会安排 C 语言这门课,阮一峰了老师的这份《C语言入门教程》,绝对是福音。

视频课是浙江大学翁恺教授的,一门《C语言程序设计入门》,一门《C语言程序设计进阶》。

学完这些,大家至少能学会下面这幅思维导图中列出来的内容。

更多 C 语言的学习内容,可以戳下面这个链接,之前在公众号上发过了,这里就不再复制粘贴了:

大一新生应该如何学习C语言,书上代码看不懂理解不了怎么办?open in new window

三、学习数据结构

什么是数据结构?

数据结构是一种具有一定逻辑关系,在计算机中应用某种存储结构,并且封装了相应操作的数据元素集合。它包含三方面的内容,逻辑关系、存储关系及操作。不同种类的数据结构适合于不同种类的应用,而部分甚至专门用于特定的作业任务。例如,计算机网络依赖于路由表运作,B 树高度适用于数据库的封装。

菜鸟教程上对数据结构的定义我觉得还是蛮正式(官方)的,说人话就是,数据结构就是把一堆数据,按照某种格式揉成一坨

大家喜欢吃宫保鸡丁吗?

反正我挺喜欢这道菜的。我就以宫保鸡丁为例,来讲一讲数据结构吧。维基百科上是这样定义的。

宫保鸡丁(英语:Kung Pao chicken或Kung-Pao Chicken),又称宫爆鸡丁,呈糊辣荔枝味,源于黔菜、流传至鲁而后成于川菜的一道川味名菜。贵州、山东和四川三地对这道菜的做法不完全一样,称呼也有差异。贵州称为糊辣子鸡丁,山东则名为酱爆鸡丁,而四川是以宫保鸡丁为名的。

来,抽象下宫保鸡丁。

struct KungPaoChicken {
+    

我的第一个,10 万(B站视频播放)

沉默王二2022年3月18日
  • 联系作者
  • 心路历程
大约 12 分钟

我的第一个,10 万(B站视频播放)

恭喜这个 B。。。。。。站上的 UP,上一期视频播放量突破了 10 万!这也是二哥人生当中的第一次,凭借单条视频突破 10 万播放,必须得纪念下。

从众多的宫斗剧中我得出了一条宝贵的人生经验:“母凭子贵”。这条经验同样适用于二哥本人,可能会因为这一期视频,吹这辈子最多的牛逼:这不,荣获哔哩哔哩第 3 周【校园优秀奖&校园新星奖】。

我已经按捺不住激动的心情,在两万人的朋友圈大肆炫耀了。十万播放,对于百大 UP 来说,可能就是分分钟的事,可对于我这个(未来的) B站百大来说,苦苦等了 149 天!!!!!!!

这真是一个漫长的日子,鬼知道这些天我经历了什么。

我一度怀疑自己到底适不适合拍视频,表情的僵硬,普通话的塑料,甚至连自己一项引以为荣的台本,都觉得拉胯。

可就因为这个视频,让我重获新生,亢奋的心情一直在持续。我知道,一条视频的播放突破 10 万,并不意味着下一个视频也会有 10 万的播放,但好歹能让我感到幸福会,至少可以“厚颜无耻”地再吹一次牛皮吧!

昨天的文章里,承诺新的一年 2022 年把肝重新交给大家,我就会说到做到:这年头,职场就流行这个“沙雕”文化,你有没有能力不重要,重要的是领导交代你的有没有去执行

二哥打算豁出去了!

新一期视频也上传到 B 站了,希望能借英雄哥的吉言,再爆一次。链接我放这里了:

https://www.bilibili.com/video/BV1za411q79U/

三不三连没关系,有关系的是不三连可能会对不起二哥的肝,所以还是三连吧,哈哈哈哈,瞧瞧我们这该死的生物钟,起这么早。。。

接下来,上干货,我把这期 10万+ 播放的视频台本重新整理了一下,本来不想发的,很多小伙伴私信说二哥偏爱 B 站,同步都懒得同步了吗?

这不,赶紧发到公众号上来,希望学生党们现在立刻马上收藏起来,这个寒假你会过得非常充实;至于工作党嘛,像二哥这样的,既要工作,又要读书写作照顾家庭的,忙都忙死了,就算了吧!

啊,不,还是要稍微卷一卷吧,免得被那群还有半年就毕业的家伙们拍死在沙滩上。。。。


二哥的读者当中有不少大学生,所以当知乎上刷到这个题目时:

“学校课程规划的比较奇怪,大一上学期学c++,下学期学python,在寒假我是应该复习或预习课内内容(python,c++),还是自己对外拓展呢(c,数据结构)?”

立马就冲上去答了一波。

就冲这份爱学习的决心,三年后绝对互联网公司的 offer 拿到手软

讲真,小伙伴学校安排的课程和我当年非常相似,也是大一上来就搞 Java,隔壁班上来就搞 C++,完全没有安排 C语言来过渡下。

所以我的建议是,趁寒假打打王者上上分吧

啊,不!趁寒假刷一波清华在 GitHub 上 20k+ star 的开源课程吧

一、清华大学在 GitHub 上的开源课程

地址:https://github.com/PKUanonym/REKCARC-TSC-UHT

我来带小伙伴们过一下清华的课程安排哈,主要是针对计算机专业的。

大一上的计算机基础课程有:计算机科学导论、程序设计基础

大一下有:面向对象程序设计基础

大二上有:数据结构

大二下有:人工智能导论、计算机图形学基础、高性能计算导论

大三上有:计算机组成原理、计算机网络原理、编译原理、软件工程、数据库系统概论、人工神经网络、计算机网络安全技术、人机交互理论与技术

大三下有:操作系统、计算机系统结构、机器学习概论、数据挖掘、搜索引擎技术基础、存储技术基础、数据库专题训练、计算机网络专题训练。

大四主要是实践、实习、毕设等,剩下的计算机课程主要有网络安全工程与实践、嵌入式系统。

可以看得出,大一大二基本上是在摸鱼状态,大三突然开始发力,各种计算机基础课程,非常疯狂!

不过:

有志者事竟成,破釜沉舟,百二秦关终属楚;
苦心人天不负,卧薪尝胆,三千越甲可吞吴!

二、学习 C语言

推荐一本书,两门视频课

书是电子书,书名叫《阮一峰的 C语言入门课》,我第一时间就拜读了一遍,受益匪浅!可以说目前我见到的最好的 C语言入门教程了,没有之一!国内的绝大多数高校,大一都会安排 C 语言这门课,阮一峰了老师的这份《C语言入门教程》,绝对是福音。

视频课是浙江大学翁恺教授的,一门《C语言程序设计入门》,一门《C语言程序设计进阶》。

学完这些,大家至少能学会下面这幅思维导图中列出来的内容。

更多 C 语言的学习内容,可以戳下面这个链接,之前在公众号上发过了,这里就不再复制粘贴了:

大一新生应该如何学习C语言,书上代码看不懂理解不了怎么办?open in new window

三、学习数据结构

什么是数据结构?

数据结构是一种具有一定逻辑关系,在计算机中应用某种存储结构,并且封装了相应操作的数据元素集合。它包含三方面的内容,逻辑关系、存储关系及操作。不同种类的数据结构适合于不同种类的应用,而部分甚至专门用于特定的作业任务。例如,计算机网络依赖于路由表运作,B 树高度适用于数据库的封装。

菜鸟教程上对数据结构的定义我觉得还是蛮正式(官方)的,说人话就是,数据结构就是把一堆数据,按照某种格式揉成一坨

大家喜欢吃宫保鸡丁吗?

反正我挺喜欢这道菜的。我就以宫保鸡丁为例,来讲一讲数据结构吧。维基百科上是这样定义的。

宫保鸡丁(英语:Kung Pao chicken或Kung-Pao Chicken),又称宫爆鸡丁,呈糊辣荔枝味,源于黔菜、流传至鲁而后成于川菜的一道川味名菜。贵州、山东和四川三地对这道菜的做法不完全一样,称呼也有差异。贵州称为糊辣子鸡丁,山东则名为酱爆鸡丁,而四川是以宫保鸡丁为名的。

来,抽象下宫保鸡丁。

struct KungPaoChicken {
   鸡肉 = []
   花生 = []
   葱段 = []
@@ -58,6 +58,6 @@
   }
 }
 

伪代码不是很严谨哈,大家理解这个意思就行了。

说到底,数据结构不过是一种抽象后的封装。像 Java,它之所以流行的一个很重要的原因,就是它提供了多种多样的、方便开发者调用的数据结构,比如说对数组的封装 ArrayList、对链表的封装 LinkedList、对哈希表的封装 HashMap、ConcurrentHashMap 等等。C 语言就没有这些,想用的话,就得自己封装。但 Java 和 C 语言的基本数据类型是一致的,int、float 这些都是相通的。

对于初学者来说,平常敲代码都是直接去调用数据结构的,是很少去想这些数据结构是怎么实现的。

当一个初学者向高级程序员迈进的时候,就必须得静下心来,去搞清楚 ArrayList 和 LinkedList 的内部实现,搞清楚之后就会明白,之所以它们在增删改查的时候性能上有差异,就是因为它们的内部使用了不同的数据结构所导致的。

有一说一,我在 2008 年刚学 Java 的那会,真的是不理解,为什么明明有了 ArrayList,Java 还要设计 LinkedList,不都是集合嘛!

害!

数据结构为什么这么重要?

我直接放大招吧,甩一段清华大学计算机系教授邓俊辉老师话吧。

数据结构是计算机科学的关键内容,也是构建高效算法的必要基础。其中涉及的知识,在相关专业的课程系统中始终处于核心位置。以 ACM/IEEE Computing Curricula(计算机教学大纲)为例,其中对于几个相关专业(计算机科学、计算机工程、信息系统、信息技术、软件工程)的共同要求中,数据结构与算法作为程序设计概念与技能的核心,紧随在数学之后,排在第二位。

数据结构说复杂也不复杂,说简单也不简单,这不重要,重要的是必须得学!

有小伙伴可能会问,“我数学学的不好,学数据结构能学会吗?”

说句实在话,数据结构和数学之间没有必然的关系。我上小学的时候,参加过洛阳市的奥林匹克数学竞赛,还得了三等奖(偷偷地加个粗);初中的时候,数学成绩也一直保持得不错,但上了高中之后,由于贪玩,数学成绩一落千丈,成了瘸腿课。大学的时候对离散数学、微积分这些更是头大。

但这并不妨碍我学习数据结构,真的。数据结构中,树算是最难的一块了,像数组、链表、栈、哈希表这些相对来说,计算机专业的,只要稍微下点功夫,都是能掌握的。

说了这么多,数据结构到底该怎么学呢?

如果你有 C/C++ 的底子,我给推荐两本书。

第一本,《趣学数据结构》

说到这,多说一嘴。2018 年的时候,人民邮电出版社的张老师邀请我出一本 Java 方面的书,我当时想命名为《趣学 Java》。张老师说,刚好之前和陈小玉老师合作出了一本《趣学算法》的书,要不发一本你看看吧。

你别说,这本书还挺适合拿来作为算法的入门书呢。后来,陈小玉老师又出了一本新书,叫《趣学数据结构》,我看了,虽然离“趣”字有点距离,但很适合作为一门数据结构方面的入门书。

第二本,《数据结构(C++语言版)》

对,清华大学邓俊辉教授编著的,豆瓣评分也蛮高的。这本书还配套了视频课程,是免费的,可以在学堂在线上看,我之前也有推荐过。

课程质量木得说,算是国家级精品课了。大家有时间的话,一定要刷一遍。

视频地址:https://www.xuetangx.com/course/THU08091000384/7755489

对了,还有浙江大学陈越姥姥的视频课:

视频地址:https://www.bilibili.com/video/BV1JW411i731

如果你有 Java 的底子,我也给推荐两本书。

第一本,《数据结构与算法分析(Java 语言描述)》

虽然翻译得不怎么样,但内容很全面,适合拿来作为一本数据结构的入门书。

第二本,《算法(第 4 版)》

虽然名为算法,但大家都知道,算法是基于数据结构的,数组、队列、栈、堆、二叉树、哈希表等等,这些数据结构都讲到了。

如果时间比较紧的话,C/C++ 程序员只看《数据结构(C++语言版)》就行了,Java 程序员只看《算法(第 4 版)》就行了。如果一遍没看懂的话,再看一遍就好了。

有网友“三色院堇子的老公”说得好。

数据结构就是你已经写了几百万行,然后数据结构减到 90 万行,性能还翻倍,嗯,终于学会了!

四、走心总结

2022 年 1 月份,很有必要开个好头。

那么趁寒假刷一波清华在 GitHub 上的开源课程,还有 C语言和数据结构,寒假过后,绝壁是卷王中的卷王。

悄悄地告诉大家一声,很多说放假了一定要打打游戏,一定要放松下,这些人都在悄悄地卷。

所以说,如果你是正在放松的那个,可要小心了!

不要一个寒假就被甩开了差距。

工作党其实也一样,适当放松,时刻警惕,该学的时候还是要能支棱起来。

- + diff --git a/dist/about-the-author/csdn-1000wan.html b/dist/about-the-author/csdn-1000wan.html index 6dd10c56..397411d5 100644 --- a/dist/about-the-author/csdn-1000wan.html +++ b/dist/about-the-author/csdn-1000wan.html @@ -39,10 +39,10 @@ } - + -

我的第二个,一千万!CSDN阅读

沉默王二2022年3月18日
  • 联系作者
  • 心路历程
大约 10 分钟

我的第二个,一千万!CSDN阅读

大家好,我是二哥呀!

上一个一千万open in new window,还是上一次。

我努力的回想着,回想自己在 2021 年做出了哪些耀眼的成绩,正襟危坐,回想良久,也只想到这最后一件:CSDN 的博文访问量也突破了一千万

但这算不算得上是成绩,很难说,因为喜欢这个平台的人有很多,不喜欢这个平台的也有很多。也许,GitHub 上有 110k+ star 的 JavaGuide 的话最具有说服力了,这个平台不规范转载的很多,垃圾资源下载的很多,但也有几个优秀的作者撑起了 CSDN 的半边天,二哥就是其中一个。

老读者都知道,我是从2014 年,开始坚持写技术博客的。一开始,还没敢在 CSDN 上写,只敢在 JavaEye 上写(估计很多新读者都不太知道这个平台)。

那时候的 JavaEye 真的是非常非常非常的纯粹(比博客园更纯粹),没有任何商业广告,还时不时送送书,头部作者有 fastjson 的作者温少,《亿级流量网站架构核心技术》作者开涛,想必做技术的大家应该都知道他们俩。

后来胆子大了,就开始在 CSDN 上写,当时认识的头部作者有安晓辉、浅墨(毛星云)、杨秀璋等等。

就这样写着写着,我成了 CSDN 的博客专家,出版了一本技术图书,成为了两届博客之星。

就这样写着写着,我遇到了越来越多的读者,给他们提供帮助的同时,也成为了他们前进的动力。

据我自己的不完全统计,2021 年,我在朋友圈和公众号送出去了超过 200 本技术图书,每次我都会留个小心机,问中奖的读者是怎么认识二哥的,有没有什么建议,留言中竟然很多都来自 CSDN,这让我又惊又喜。

经常有读者夸赞二哥好有写作的天赋啊,其实哪里是有天赋,纯粹是因为写得多,所以才写得好。我现在的文笔,讲真,还不如上高中那会,那会才是真的笔下生花,诗都能写得出来,情书就更不用说了。

等过年的时候吧,我把那些尘封多年的文字贴出来给大家瞧瞧。

一、追忆往事

借这个机会,和大家一起坐上时光机重温一下往事吧。翻看相册,2021 年,还真有不少令人感动的瞬间,太多太多了,我就每个月挑一件吧。

1 月 13 日,我和妹妹在小叔家的房顶上自拍。

2 月 15 日,我和奶奶的合影。

3 月 26 日,读者考上研究生了,特意发来祝贺。

4 月 3 日,和教练小姐姐在健身房合影。

5 月 25 日,二哥的读者群体扩大了台湾省。

6 月 13 日,和家人畅游青岛。

7 月 20 日,被某某女粉追着要联系方式。

8 月 21 日,在十八线县城的老家砸核桃吃。

9 月 23 日,收到掘金和 CSDN 寄来的月饼。

10 月 11 日,收到《Java 程序员进阶之路》专栏在 GitHub 上开源以来的两笔大额打赏。

11 月 6 日,和四位河科大的学弟撸完串后在校园里的合影。

12 月 27 日,CSDN 生成的年度报告。

不知道大家的 2021 过得怎么样?

  • 充实?
  • 落魄?
  • 上进?
  • 消极?
  • 幸福?
  • 悲伤?

我个人的感受是平淡中有一点点小确幸,平凡中有一点点小进步,这也许就是普通人最真实的写照了吧?

二、有点遗憾

一年时间过得可真快,有很多想做好的事情,到最后都差了点意思。就说一件吧,B 站的视频播放量没有达到预期。

8 月份还能坚持一周输出一个,从一开始面对镜头时的恐惧,到慢慢接纳自己。但好景不长,9 月份的时候,视频播放量呈现下降趋势,我就开始胡思乱想了。

  • 是不是自己不适合拍视频啊?
  • 是不是自己表达的不够有趣啊?
  • 是不是剪辑没剪好啊?

这种心态其实很正常,但往往这种心态又会影响下一个视频的创作,就失去了正向的反馈。

于是后面就渐渐变成了一个月一个视频,但视频播放并没有任何的起色。

读者群体里有不少爱好写作的小伙伴,应该都能感受到这种困惑,当你辛辛苦苦创作出来的作品得不到认可的时候,就容易陷入自我怀疑当中,对于这一点,二哥也不例外。

所以,这里就拜托大家了,如果你是二哥的铁粉,看到二哥发了 B 站的视频,赶紧跑去三连支持下,火钳刘明。三连也是鼓励二哥创作出更多优质视频的最强动力了。

不管怎么样,2022 年,我会改变心态,继续坚持录制视频,因为普通人想要闯出一片天地,唯有坚持不懈和不断改进

有志者,事竟成,破釜沉舟,百二秦关终属楚; 苦心人,天不负,卧薪尝胆,三千越甲可吞吴。

B 站我一定做到一万粉——这个 flag 不能到。

人这一辈子,很难事事顺心,也很难做什么事都成什么事。总是会遇到一些挫折,重要的是,遇到挫折的时候,如何破局走出来,这才是最重要的。

俗称抗压能力。

时不时会有一些读者问我:

  • “我秋招失败了,怎么办?”
  • “我考研失败了,怎么办?”
  • “我被公司裁了,怎么办?”
  • “我无法晋升了,怎么办?”

大局观上来说,最好的办法就是接纳自己,接纳自己的失败。

  • 秋招失败了,就准备春招,总结一波秋招发挥失误的点是什么,然后在春招前补上。
  • 考研失败了,要么二战,要么就找一份工作,开辟新的战场。
  • 被公司裁了就所要赔偿,然后赶紧准备简历,找新的工作,不要在过去的失意中沉沦。
  • 找一找没办法晋升的原因是什么,是因为得罪了领导,是因为技术没跟上,职场遇到瓶颈了,要么降低预期,要么猥琐发育等下一波机会,要么跳槽。

拿我自己的 B 站视频来说,应对办法有两个,第一个就是加量,在不断的试错中找出观众喜欢的点和角度;第二个就是提高视频的质量,包括创意、表达方式、后期剪辑等。

有点遗憾不要紧,要紧的是被遗憾击垮!

如果你在 2021 年遇到了不开心,遇到了挫折,请给自己多一点时间。像二哥,不也一样有做不成功的时候嘛,我们都是平凡人,不卑不亢地接纳自己就会有新的起色。

三、新的憧憬

展望 2022 年,有太多的期待了。

这不,新的惊喜就是《Java 程序员进阶之路》专栏第一次上了 GitHub 的 trending 榜单!

正应了那句话,功夫不负有心人。

对于这个开源专栏,我投入了大量的心血,一开始的名字叫《教妹学 Java》,主打 Java 的入门级路线,一直连载了近 100篇原创内容。

后来有朋友建议我,要想走国际化的话,就必须得换个名字,得和国际接轨,于是我就想破脑袋,征求了很多朋友的建议,改成这个《Java 程序员进阶之路》了,因为我之前出版过一本技术书《Web 全栈开发进阶之路》,叫这个名字刚好也非常适合。

英文名字叫 toBeBetterJavaer, 前后呼应,一气呵成。

立个 flag 吧,2022 年,冲 5000 star

这个 flag 绝不能倒!

还有一件事,就是我打算共建一个知识星球,因为每天过来咨询二哥问题的读者实在是太多了,导致回复速度变得很慢,效率不高。

如果能建一个知识星球,把这些问题的答案全部沉淀下来,隔断时间整理一波 PDF,就美滋滋了。

目前规划的方向有:

  • offer 咨询
  • 职业规划
  • 简历优化
  • 资源分享
  • 打卡共进
  • 助学活动

打算趁过年的这段时间好好的规划一下,列一个详细的清单出来,到时候如果有意愿加入的话,到时候可以来参与一波。

俗话说,一个好汉三个帮,一个篱笆三个桩,大家在一起学习沉淀的话,效率也会比较高,信息差也会被抹平。

最后一件事就是,我希望有更多的时间陪陪家人。虽然二哥在三线城市,但业余时间基本上全部用来输入输出了。

当然了,比起在一线城市打拼的大家伙,二哥陪家人的时间肯定会多一些,但我总觉得不够。毕竟我们无论处于什么阶段,挣多少钱,终归是希望我们家人能过上更好一点的生活。

否则,我们奋斗拼搏加班卖命的工作,又图什么呢?

这恐怕也是二哥宁愿在三线城市待着的最大原因了,人活着只有一次,而最亲的人,就是家人,二哥还是一个比较腻在家人身边的人。

我也希望,大家能在 2022 年找到心爱的人,找到的就更进一步,有家就有烟火味,你奋斗的一切都会显得很值得。

四、最后的祝福

如果你是学生党,希望课堂上的你,能够认认真真听讲;如果老师的课实在没意思,网上有很多优质的公开资源,可参考该死!B 站上这些 Java 视频真香!open in new window

还有就是逢考必过,追 TA 必到手。

如果你是工作党,希望工作中的你,不被甩锅,蒸蒸日上;如果事业上遇到瓶颈了,不妨拓展一门副业,给自己打开一扇窗。

还有就是绩效必 A,跳槽涨薪美滋滋。

就这吧!

如果可以的话,大家可以在评论区刷一波,二哥牛逼,2022 我们一起飞~~

- +

我的第二个,一千万!CSDN阅读

沉默王二2022年3月18日
  • 联系作者
  • 心路历程
大约 10 分钟

我的第二个,一千万!CSDN阅读

大家好,我是二哥呀!

上一个一千万open in new window,还是上一次。

我努力的回想着,回想自己在 2021 年做出了哪些耀眼的成绩,正襟危坐,回想良久,也只想到这最后一件:CSDN 的博文访问量也突破了一千万

但这算不算得上是成绩,很难说,因为喜欢这个平台的人有很多,不喜欢这个平台的也有很多。也许,GitHub 上有 110k+ star 的 JavaGuide 的话最具有说服力了,这个平台不规范转载的很多,垃圾资源下载的很多,但也有几个优秀的作者撑起了 CSDN 的半边天,二哥就是其中一个。

老读者都知道,我是从2014 年,开始坚持写技术博客的。一开始,还没敢在 CSDN 上写,只敢在 JavaEye 上写(估计很多新读者都不太知道这个平台)。

那时候的 JavaEye 真的是非常非常非常的纯粹(比博客园更纯粹),没有任何商业广告,还时不时送送书,头部作者有 fastjson 的作者温少,《亿级流量网站架构核心技术》作者开涛,想必做技术的大家应该都知道他们俩。

后来胆子大了,就开始在 CSDN 上写,当时认识的头部作者有安晓辉、浅墨(毛星云)、杨秀璋等等。

就这样写着写着,我成了 CSDN 的博客专家,出版了一本技术图书,成为了两届博客之星。

就这样写着写着,我遇到了越来越多的读者,给他们提供帮助的同时,也成为了他们前进的动力。

据我自己的不完全统计,2021 年,我在朋友圈和公众号送出去了超过 200 本技术图书,每次我都会留个小心机,问中奖的读者是怎么认识二哥的,有没有什么建议,留言中竟然很多都来自 CSDN,这让我又惊又喜。

经常有读者夸赞二哥好有写作的天赋啊,其实哪里是有天赋,纯粹是因为写得多,所以才写得好。我现在的文笔,讲真,还不如上高中那会,那会才是真的笔下生花,诗都能写得出来,情书就更不用说了。

等过年的时候吧,我把那些尘封多年的文字贴出来给大家瞧瞧。

一、追忆往事

借这个机会,和大家一起坐上时光机重温一下往事吧。翻看相册,2021 年,还真有不少令人感动的瞬间,太多太多了,我就每个月挑一件吧。

1 月 13 日,我和妹妹在小叔家的房顶上自拍。

2 月 15 日,我和奶奶的合影。

3 月 26 日,读者考上研究生了,特意发来祝贺。

4 月 3 日,和教练小姐姐在健身房合影。

5 月 25 日,二哥的读者群体扩大了台湾省。

6 月 13 日,和家人畅游青岛。

7 月 20 日,被某某女粉追着要联系方式。

8 月 21 日,在十八线县城的老家砸核桃吃。

9 月 23 日,收到掘金和 CSDN 寄来的月饼。

10 月 11 日,收到《Java 程序员进阶之路》专栏在 GitHub 上开源以来的两笔大额打赏。

11 月 6 日,和四位河科大的学弟撸完串后在校园里的合影。

12 月 27 日,CSDN 生成的年度报告。

不知道大家的 2021 过得怎么样?

  • 充实?
  • 落魄?
  • 上进?
  • 消极?
  • 幸福?
  • 悲伤?

我个人的感受是平淡中有一点点小确幸,平凡中有一点点小进步,这也许就是普通人最真实的写照了吧?

二、有点遗憾

一年时间过得可真快,有很多想做好的事情,到最后都差了点意思。就说一件吧,B 站的视频播放量没有达到预期。

8 月份还能坚持一周输出一个,从一开始面对镜头时的恐惧,到慢慢接纳自己。但好景不长,9 月份的时候,视频播放量呈现下降趋势,我就开始胡思乱想了。

  • 是不是自己不适合拍视频啊?
  • 是不是自己表达的不够有趣啊?
  • 是不是剪辑没剪好啊?

这种心态其实很正常,但往往这种心态又会影响下一个视频的创作,就失去了正向的反馈。

于是后面就渐渐变成了一个月一个视频,但视频播放并没有任何的起色。

读者群体里有不少爱好写作的小伙伴,应该都能感受到这种困惑,当你辛辛苦苦创作出来的作品得不到认可的时候,就容易陷入自我怀疑当中,对于这一点,二哥也不例外。

所以,这里就拜托大家了,如果你是二哥的铁粉,看到二哥发了 B 站的视频,赶紧跑去三连支持下,火钳刘明。三连也是鼓励二哥创作出更多优质视频的最强动力了。

不管怎么样,2022 年,我会改变心态,继续坚持录制视频,因为普通人想要闯出一片天地,唯有坚持不懈和不断改进

有志者,事竟成,破釜沉舟,百二秦关终属楚; 苦心人,天不负,卧薪尝胆,三千越甲可吞吴。

B 站我一定做到一万粉——这个 flag 不能到。

人这一辈子,很难事事顺心,也很难做什么事都成什么事。总是会遇到一些挫折,重要的是,遇到挫折的时候,如何破局走出来,这才是最重要的。

俗称抗压能力。

时不时会有一些读者问我:

  • “我秋招失败了,怎么办?”
  • “我考研失败了,怎么办?”
  • “我被公司裁了,怎么办?”
  • “我无法晋升了,怎么办?”

大局观上来说,最好的办法就是接纳自己,接纳自己的失败。

  • 秋招失败了,就准备春招,总结一波秋招发挥失误的点是什么,然后在春招前补上。
  • 考研失败了,要么二战,要么就找一份工作,开辟新的战场。
  • 被公司裁了就所要赔偿,然后赶紧准备简历,找新的工作,不要在过去的失意中沉沦。
  • 找一找没办法晋升的原因是什么,是因为得罪了领导,是因为技术没跟上,职场遇到瓶颈了,要么降低预期,要么猥琐发育等下一波机会,要么跳槽。

拿我自己的 B 站视频来说,应对办法有两个,第一个就是加量,在不断的试错中找出观众喜欢的点和角度;第二个就是提高视频的质量,包括创意、表达方式、后期剪辑等。

有点遗憾不要紧,要紧的是被遗憾击垮!

如果你在 2021 年遇到了不开心,遇到了挫折,请给自己多一点时间。像二哥,不也一样有做不成功的时候嘛,我们都是平凡人,不卑不亢地接纳自己就会有新的起色。

三、新的憧憬

展望 2022 年,有太多的期待了。

这不,新的惊喜就是《Java 程序员进阶之路》专栏第一次上了 GitHub 的 trending 榜单!

正应了那句话,功夫不负有心人。

对于这个开源专栏,我投入了大量的心血,一开始的名字叫《教妹学 Java》,主打 Java 的入门级路线,一直连载了近 100篇原创内容。

后来有朋友建议我,要想走国际化的话,就必须得换个名字,得和国际接轨,于是我就想破脑袋,征求了很多朋友的建议,改成这个《Java 程序员进阶之路》了,因为我之前出版过一本技术书《Web 全栈开发进阶之路》,叫这个名字刚好也非常适合。

英文名字叫 toBeBetterJavaer, 前后呼应,一气呵成。

立个 flag 吧,2022 年,冲 5000 star

这个 flag 绝不能倒!

还有一件事,就是我打算共建一个知识星球,因为每天过来咨询二哥问题的读者实在是太多了,导致回复速度变得很慢,效率不高。

如果能建一个知识星球,把这些问题的答案全部沉淀下来,隔断时间整理一波 PDF,就美滋滋了。

目前规划的方向有:

  • offer 咨询
  • 职业规划
  • 简历优化
  • 资源分享
  • 打卡共进
  • 助学活动

打算趁过年的这段时间好好的规划一下,列一个详细的清单出来,到时候如果有意愿加入的话,到时候可以来参与一波。

俗话说,一个好汉三个帮,一个篱笆三个桩,大家在一起学习沉淀的话,效率也会比较高,信息差也会被抹平。

最后一件事就是,我希望有更多的时间陪陪家人。虽然二哥在三线城市,但业余时间基本上全部用来输入输出了。

当然了,比起在一线城市打拼的大家伙,二哥陪家人的时间肯定会多一些,但我总觉得不够。毕竟我们无论处于什么阶段,挣多少钱,终归是希望我们家人能过上更好一点的生活。

否则,我们奋斗拼搏加班卖命的工作,又图什么呢?

这恐怕也是二哥宁愿在三线城市待着的最大原因了,人活着只有一次,而最亲的人,就是家人,二哥还是一个比较腻在家人身边的人。

我也希望,大家能在 2022 年找到心爱的人,找到的就更进一步,有家就有烟火味,你奋斗的一切都会显得很值得。

四、最后的祝福

如果你是学生党,希望课堂上的你,能够认认真真听讲;如果老师的课实在没意思,网上有很多优质的公开资源,可参考该死!B 站上这些 Java 视频真香!open in new window

还有就是逢考必过,追 TA 必到手。

如果你是工作党,希望工作中的你,不被甩锅,蒸蒸日上;如果事业上遇到瓶颈了,不妨拓展一门副业,给自己打开一扇窗。

还有就是绩效必 A,跳槽涨薪美滋滋。

就这吧!

如果可以的话,大家可以在评论区刷一波,二哥牛逼,2022 我们一起飞~~

+ diff --git a/dist/about-the-author/index.html b/dist/about-the-author/index.html index 0484fb85..3a05e7c2 100644 --- a/dist/about-the-author/index.html +++ b/dist/about-the-author/index.html @@ -39,10 +39,10 @@ } - + -

个人介绍 Q&A

沉默王二2022年3月18日
  • 联系作者
大约 4 分钟

大家好,我是二哥呀!这篇文章会通过 QA 的形式简单介绍一下我自己。

一、我取得了哪些成绩?

又到了晒成绩的环节,真让人迫不及待啊(瞧我这该死的自信)!

01、公众号

目前我的原创公众号“沉默王二”有 10.5 万+ 读者关注,专注于分享硬核的 Java 后端技术文章。平均阅读 5500 左右,综合排名能排在全国开发者中的前 50 名左右(数据来源于二十次幂)。

可以微信搜索 沉默王二 关键字或者扫码直接关注,关注后回复 00 还可以拉取我为你精心准备的学习资料。

学习资料有 BAT 大佬的刷题笔记,有《Java 程序员进阶之路》的 PDF 版电子书等等。

02、CSDN

两届博客之星,总榜前 10 选手,访问量 1100 万+,粉丝 34 万+,妥妥的裆部博主,哦,不,头部博主。

访问地址:https://blog.csdn.net/qing_gee

03、知乎

LV9 选手,阅读总数超 1590 万,今年卷一卷的话,破 2000 万阅读没什么问题。

访问地址:https://www.zhihu.com/people/cmower

04、B 站

B 站还比较菜,目前只有一个 10 万+播放量的视频,等我的开源项目编程喵喵🐱开发完第一个版本后,开始重新卷视频。

访问地址:https://space.bilibili.com/513340480

05、GitHub

目前主要维护的《Java 程序员进阶之路》开源版在 GitHub 上有 1.8k+ 的 star,和出版社约定的是,超过 1 万 star 就出书,小伙伴们可以来点赞支持下。

访问地址:https://github.com/itwanger/toBeBetterJavaer

05、知识星球

目前还处在试运营阶段,正在筹备星球用户专属的 5 份小册,质量高的一笔。

内容涵盖实战项目开发笔记、面试指南、Java学习、LeetCode Java 版刷题笔记等优质内容,价值远超门票!

  • 编程喵喵开源 Spring Boot+Vue 的前后端分离项目实战笔记
  • Java 面试指南,今年重点更新内容,涵盖面试准备篇、技术面试题篇、面经篇、职场修炼篇等等硬核内容。
  • Java 程序员进阶之路优化重构版(星球专属)
  • GitHub 上星标 147k+ 的 Java 教程(更多优质教程持续更新)
  • LeetCode 题解 Java 版(持续更新 300 道)

这是《Java 面试指南》专栏目前已经更新的内容,讲真,就这一个专栏就值回票价(新人优惠价只有 69 元)。

还有星球内部我也在坚持每天更新优质的内容。

喜欢的小伙伴可以直接扫码加入。

二、为什么叫沉默王二

其实原因很简单,我个人比较喜欢王小波,小波是个程序员,还是个作家,写的小说和杂文我都特别喜欢,有一本叫《沉默的大多数》,我就取了沉默二字,《黄金时代》里和陈清扬搞破鞋的男主就叫王二,加上小波在家排行老二,上面有个哥哥,下面有个弟弟,所以综合到一起就叫“沉默王二”了。

三、为什么做这个开源知识库

[!NOTE] 知识库取名 toBeBetterJavaer,即 To Be Better Javaer,意为「成为一名更好的 Java 程序员」,是自学 Java 以来所有原创文章和学习资料的大聚合。内容包括 Java 基础、Java 并发编程、Java 虚拟机、Java 企业级开发、Java 面试等核心知识点。据说每一个优秀的 Java 程序员都喜欢她,风趣幽默、通俗易懂。学 Java,就认准 Java 程序员进阶之路😄。

知识库旨在为学习 Java 的小伙伴提供一系列:

  • 优质的原创 Java 教程
  • 全面清晰的 Java 学习路线
  • 免费但靠谱的 Java 学习资料
  • 精选的 Java 岗求职面试指南
  • Java 企业级开发所需的必备技术

赠人玫瑰手有余香。知识库会持续保持更新,欢迎收藏品鉴!

访问地址:https://tobebetterjavaer.comopen in new window

四、未完待续

- +

个人介绍 Q&A

沉默王二2022年3月18日
  • 联系作者
大约 4 分钟

大家好,我是二哥呀!这篇文章会通过 QA 的形式简单介绍一下我自己。

一、我取得了哪些成绩?

又到了晒成绩的环节,真让人迫不及待啊(瞧我这该死的自信)!

01、公众号

目前我的原创公众号“沉默王二”有 10.5 万+ 读者关注,专注于分享硬核的 Java 后端技术文章。平均阅读 5500 左右,综合排名能排在全国开发者中的前 50 名左右(数据来源于二十次幂)。

可以微信搜索 沉默王二 关键字或者扫码直接关注,关注后回复 00 还可以拉取我为你精心准备的学习资料。

学习资料有 BAT 大佬的刷题笔记,有《Java 程序员进阶之路》的 PDF 版电子书等等。

02、CSDN

两届博客之星,总榜前 10 选手,访问量 1100 万+,粉丝 34 万+,妥妥的裆部博主,哦,不,头部博主。

访问地址:https://blog.csdn.net/qing_gee

03、知乎

LV9 选手,阅读总数超 1590 万,今年卷一卷的话,破 2000 万阅读没什么问题。

访问地址:https://www.zhihu.com/people/cmower

04、B 站

B 站还比较菜,目前只有一个 10 万+播放量的视频,等我的开源项目编程喵喵🐱开发完第一个版本后,开始重新卷视频。

访问地址:https://space.bilibili.com/513340480

05、GitHub

目前主要维护的《Java 程序员进阶之路》开源版在 GitHub 上有 1.8k+ 的 star,和出版社约定的是,超过 1 万 star 就出书,小伙伴们可以来点赞支持下。

访问地址:https://github.com/itwanger/toBeBetterJavaer

05、知识星球

目前还处在试运营阶段,正在筹备星球用户专属的 5 份小册,质量高的一笔。

内容涵盖实战项目开发笔记、面试指南、Java学习、LeetCode Java 版刷题笔记等优质内容,价值远超门票!

  • 编程喵喵开源 Spring Boot+Vue 的前后端分离项目实战笔记
  • Java 面试指南,今年重点更新内容,涵盖面试准备篇、技术面试题篇、面经篇、职场修炼篇等等硬核内容。
  • Java 程序员进阶之路优化重构版(星球专属)
  • GitHub 上星标 147k+ 的 Java 教程(更多优质教程持续更新)
  • LeetCode 题解 Java 版(持续更新 300 道)

这是《Java 面试指南》专栏目前已经更新的内容,讲真,就这一个专栏就值回票价(新人优惠价只有 69 元)。

还有星球内部我也在坚持每天更新优质的内容。

喜欢的小伙伴可以直接扫码加入。

二、为什么叫沉默王二

其实原因很简单,我个人比较喜欢王小波,小波是个程序员,还是个作家,写的小说和杂文我都特别喜欢,有一本叫《沉默的大多数》,我就取了沉默二字,《黄金时代》里和陈清扬搞破鞋的男主就叫王二,加上小波在家排行老二,上面有个哥哥,下面有个弟弟,所以综合到一起就叫“沉默王二”了。

三、为什么做这个开源知识库

[!NOTE] 知识库取名 toBeBetterJavaer,即 To Be Better Javaer,意为「成为一名更好的 Java 程序员」,是自学 Java 以来所有原创文章和学习资料的大聚合。内容包括 Java 基础、Java 并发编程、Java 虚拟机、Java 企业级开发、Java 面试等核心知识点。据说每一个优秀的 Java 程序员都喜欢她,风趣幽默、通俗易懂。学 Java,就认准 Java 程序员进阶之路😄。

知识库旨在为学习 Java 的小伙伴提供一系列:

  • 优质的原创 Java 教程
  • 全面清晰的 Java 学习路线
  • 免费但靠谱的 Java 学习资料
  • 精选的 Java 岗求职面试指南
  • Java 企业级开发所需的必备技术

赠人玫瑰手有余香。知识库会持续保持更新,欢迎收藏品鉴!

访问地址:https://tobebetterjavaer.comopen in new window

四、未完待续

+ diff --git a/dist/about-the-author/zhihu-1000wan.html b/dist/about-the-author/zhihu-1000wan.html index 4aaf4f35..7ec43542 100644 --- a/dist/about-the-author/zhihu-1000wan.html +++ b/dist/about-the-author/zhihu-1000wan.html @@ -39,10 +39,10 @@ } - + -

我的第一个,一千万!知乎阅读

沉默王二2022年3月18日
  • 联系作者
  • 心路历程
大约 4 分钟

我的第一个,一千万!知乎阅读

大家好,我是二哥呀!

前几天,偷偷摸摸过了自己的第 N 个 18 岁,本来不想过生日的,就想当做是平常的一天。结果我妹非要提醒我,大家伙瞧瞧,这像妹妹该说的话吗?

呜呜呜~

求安慰。

不想安慰就想偷着乐是吧?那我自己安慰下自己吧。

经营了近一年的知乎,阅读总数突破了一千万,这也是我人生当中的第一个

其实早在 11 月就破了千万,当时就想记录一下,但细想一下,好像这点成绩也算不上什么。毕竟逼乎上人均 985、年薪百万、刚下飞机的大佬多的是。

为什么放在 12 月说呢,大家都懂的,毕竟再过几天 2021 年就要结束了,总得记录点啥。

况且一千万的阅读量,放在技术圈,确实不算少了。况且我这些分享确实实打实的帮助了不少的小伙伴。

这不,前几天一个帖子莫名其妙被知乎删除了,我是无感知的。一个小伙伴为了看这个帖子,还特意发起了一次 9.8 元的付费咨询。

这足以说明这个帖子的内容是足够硬核的。

写知乎这近一年时间里,有一个帖子无声无息地爆了:60 万+的阅读,7000+赞同,2.3 万+次的收藏

不对啊,收藏竟然是点赞的 3 倍还多。。嗯,此时此刻天空飘出来了四个字:白票真香。

不过,有一说一,大家好,才是真的好,这么多人点赞收藏,确实是干货无疑了。

讲真,这个帖子说实在的,属于无心插柳柳成荫了,就是一个即兴作品。

我只不过是把自己写过的公众号文章做了一个梳理总结。不过我过了一把导演的梦,加上了一点电影拍摄的手法。

相信大家去看完后也会有一种:卧槽,牛逼啊。

并且是拍着大腿的那种。

地址我贴出来了,没看过的小伙伴可以去欣赏一下。

https://www.zhihu.com/question/66535555/answer/1799868707

不知不觉,我已经回洛阳 8 年了!加上在苏州的 3 年半,正儿八经做程序员的时间已经超过 10 年了,时间过得可真快!

为了体现出我的文学修养,此时必须加上几个成语:真的是光阴似箭、日月如梭、白驹过隙啊。

按照网上的说法,我这种人要么飞黄腾达财务自由了,要么被无情辞退转行跑滴滴了。

无奈我既不是前一种,也不是后一种。

既不卷,也不躺平。

有焦虑,也有幸福。

对未来,有期待,也有担忧。

对当下,有满足,也有不满。

。。。。。。

完蛋,一不小心上升到哲学的层面上了,收收收收。

这么说吧,我一直觉得自己比较幸运。

大学原本选的不是计算机专业,却一不小心做了程序员,没想到,这个职业还挺适合自己。

大学过得一塌糊涂,却不经意间去了一家外企,做到了 work-life-balance。

身处三线城市,按理说这里是一片互联网的荒漠,我却在这里开荒拓土出了一片绿洲。

再加上公众号的恰饭,确实让我的生活变得不再那么窘迫了。不管是输入还是输出,也都有了更强的动力。

毕竟只靠爱来发电,很难坚持。

如果你觉得有些饭不错,感兴趣,不妨试试,给自己的投资永远都是值得的,并且回报率极高。

反正我自己私底下是买了不少课,毕竟学习是永远不能落下的,不管你是在一线城市,还是二三线城市。

给大家看一下,这只是我书柜的一角。

纸质书虽然已经不流行了,但它会让你感觉踏实,日子过得有奔头。

对恰的饭不感兴趣的,忽略就好,多看看干货给个三连也是非常不错的体验。

我在知乎上还有不少硬核输出,尤其是这些千赞以上的帖子,真心推荐给大家看看,看完后绝壁是有收获的。

虽然有些埋没的帖子我觉得价值也很高。不过,埋没就埋没吧。

定个小目标吧:2022 年,知乎阅读破 5000 万阅读(好像注定完不成)。

这个 flag 我立这了哈,欢迎大家监督。。

要是完不成,我把知乎上的全部收入拿出来给大家分成,怎么样?

明年底我会在这里公布结果,大家敬请期待。

好了,就聊这么多吧,继续加班回答帖子去了。

我是二哥,我们下期见~

- +

我的第一个,一千万!知乎阅读

沉默王二2022年3月18日
  • 联系作者
  • 心路历程
大约 4 分钟

我的第一个,一千万!知乎阅读

大家好,我是二哥呀!

前几天,偷偷摸摸过了自己的第 N 个 18 岁,本来不想过生日的,就想当做是平常的一天。结果我妹非要提醒我,大家伙瞧瞧,这像妹妹该说的话吗?

呜呜呜~

求安慰。

不想安慰就想偷着乐是吧?那我自己安慰下自己吧。

经营了近一年的知乎,阅读总数突破了一千万,这也是我人生当中的第一个

其实早在 11 月就破了千万,当时就想记录一下,但细想一下,好像这点成绩也算不上什么。毕竟逼乎上人均 985、年薪百万、刚下飞机的大佬多的是。

为什么放在 12 月说呢,大家都懂的,毕竟再过几天 2021 年就要结束了,总得记录点啥。

况且一千万的阅读量,放在技术圈,确实不算少了。况且我这些分享确实实打实的帮助了不少的小伙伴。

这不,前几天一个帖子莫名其妙被知乎删除了,我是无感知的。一个小伙伴为了看这个帖子,还特意发起了一次 9.8 元的付费咨询。

这足以说明这个帖子的内容是足够硬核的。

写知乎这近一年时间里,有一个帖子无声无息地爆了:60 万+的阅读,7000+赞同,2.3 万+次的收藏

不对啊,收藏竟然是点赞的 3 倍还多。。嗯,此时此刻天空飘出来了四个字:白票真香。

不过,有一说一,大家好,才是真的好,这么多人点赞收藏,确实是干货无疑了。

讲真,这个帖子说实在的,属于无心插柳柳成荫了,就是一个即兴作品。

我只不过是把自己写过的公众号文章做了一个梳理总结。不过我过了一把导演的梦,加上了一点电影拍摄的手法。

相信大家去看完后也会有一种:卧槽,牛逼啊。

并且是拍着大腿的那种。

地址我贴出来了,没看过的小伙伴可以去欣赏一下。

https://www.zhihu.com/question/66535555/answer/1799868707

不知不觉,我已经回洛阳 8 年了!加上在苏州的 3 年半,正儿八经做程序员的时间已经超过 10 年了,时间过得可真快!

为了体现出我的文学修养,此时必须加上几个成语:真的是光阴似箭、日月如梭、白驹过隙啊。

按照网上的说法,我这种人要么飞黄腾达财务自由了,要么被无情辞退转行跑滴滴了。

无奈我既不是前一种,也不是后一种。

既不卷,也不躺平。

有焦虑,也有幸福。

对未来,有期待,也有担忧。

对当下,有满足,也有不满。

。。。。。。

完蛋,一不小心上升到哲学的层面上了,收收收收。

这么说吧,我一直觉得自己比较幸运。

大学原本选的不是计算机专业,却一不小心做了程序员,没想到,这个职业还挺适合自己。

大学过得一塌糊涂,却不经意间去了一家外企,做到了 work-life-balance。

身处三线城市,按理说这里是一片互联网的荒漠,我却在这里开荒拓土出了一片绿洲。

再加上公众号的恰饭,确实让我的生活变得不再那么窘迫了。不管是输入还是输出,也都有了更强的动力。

毕竟只靠爱来发电,很难坚持。

如果你觉得有些饭不错,感兴趣,不妨试试,给自己的投资永远都是值得的,并且回报率极高。

反正我自己私底下是买了不少课,毕竟学习是永远不能落下的,不管你是在一线城市,还是二三线城市。

给大家看一下,这只是我书柜的一角。

纸质书虽然已经不流行了,但它会让你感觉踏实,日子过得有奔头。

对恰的饭不感兴趣的,忽略就好,多看看干货给个三连也是非常不错的体验。

我在知乎上还有不少硬核输出,尤其是这些千赞以上的帖子,真心推荐给大家看看,看完后绝壁是有收获的。

虽然有些埋没的帖子我觉得价值也很高。不过,埋没就埋没吧。

定个小目标吧:2022 年,知乎阅读破 5000 万阅读(好像注定完不成)。

这个 flag 我立这了哈,欢迎大家监督。。

要是完不成,我把知乎上的全部收入拿出来给大家分成,怎么样?

明年底我会在这里公布结果,大家敬请期待。

好了,就聊这么多吧,继续加班回答帖子去了。

我是二哥,我们下期见~

+ diff --git a/dist/array/array.html b/dist/array/array.html index 14dbe3d1..10c59812 100644 --- a/dist/array/array.html +++ b/dist/array/array.html @@ -39,10 +39,10 @@ } - + -

深入理解Java数组

沉默王二2021年10月22日
  • Java核心
  • Java
大约 7 分钟

深入理解Java数组

“哥,我看你之前的文章里提到,ArrayList 的内部是用数组实现的,我就对数组非常感兴趣,想深入地了解一下,今天终于到这个环节了,好期待呀!”三妹的语气里显得很兴奋。

“的确是的,看 ArrayList 的源码就一清二楚了。”我一边说,一边打开 Intellij IDEA,并找到了 ArrayList 的源码。

/**
+    

深入理解Java数组

沉默王二2021年10月22日
  • Java核心
  • Java
大约 7 分钟

深入理解Java数组

“哥,我看你之前的文章里提到,ArrayList 的内部是用数组实现的,我就对数组非常感兴趣,想深入地了解一下,今天终于到这个环节了,好期待呀!”三妹的语气里显得很兴奋。

“的确是的,看 ArrayList 的源码就一清二楚了。”我一边说,一边打开 Intellij IDEA,并找到了 ArrayList 的源码。

/**
  * The array buffer into which the elements of the ArrayList are stored.
  * The capacity of the ArrayList is the length of this array buffer. Any
  * empty ArrayList with elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA
@@ -113,6 +113,6 @@ demo.varargs
 

上例中从数组中查询元素 4,找到后通过 break 关键字退出循环。

如果数组提前进行了排序,就可以使用二分查找法,这样效率就会更高一些。Arrays.binarySearch() 方法可供我们使用,它需要传递一个数组,和要查找的元素。

int[] anArray = new int[] {1, 2, 3, 4, 5};
 int index = Arrays.binarySearch(anArray, 4);
 

“除了一维数组,还有二维数组,三妹你可以去研究下,比如说用二维数组打印一下杨辉三角。”说完,我就去阳台上休息了,留三妹在那里学习,不能打扰她。

- + diff --git a/dist/array/print.html b/dist/array/print.html index 9794d05e..9dc12fde 100644 --- a/dist/array/print.html +++ b/dist/array/print.html @@ -39,10 +39,10 @@ } - + -

如何优雅地打印Java数组?

沉默王二2021年6月5日
  • Java核心
  • Java
大约 4 分钟

如何优雅地打印Java数组?

“哥,之前听你说,数组也是一个对象,但 Java 中并未明确的定义这样一个类。”看来三妹有在用心地学习。

“是的,因此数组也就没有机会覆盖 Object.toString() 方法。如果尝试直接打印数组的话,输出的结果并不是我们预期的结果。”我接着三妹的话继续说。

“那怎么打印数组呢?”三妹心有灵犀地把今天的核心问题提了出来。

“首先,我们来看一下,为什么不能直接打印数组,直接打印的话,会出现什么问题。”

来看这样一个例子。

String [] cmowers = {"沉默","王二","一枚有趣的程序员"};
+    

如何优雅地打印Java数组?

沉默王二2021年6月5日
  • Java核心
  • Java
大约 4 分钟

如何优雅地打印Java数组?

“哥,之前听你说,数组也是一个对象,但 Java 中并未明确的定义这样一个类。”看来三妹有在用心地学习。

“是的,因此数组也就没有机会覆盖 Object.toString() 方法。如果尝试直接打印数组的话,输出的结果并不是我们预期的结果。”我接着三妹的话继续说。

“那怎么打印数组呢?”三妹心有灵犀地把今天的核心问题提了出来。

“首先,我们来看一下,为什么不能直接打印数组,直接打印的话,会出现什么问题。”

来看这样一个例子。

String [] cmowers = {"沉默","王二","一枚有趣的程序员"};
 System.out.println(cmowers);
 

程序打印的结果是:

[Ljava.lang.String;@3d075dc0
 

[Ljava.lang.String; 表示字符串数组的 Class 名,@ 后面的是十六进制的 hashCode——这样的打印结果太“人性化”了,一般人表示看不懂!为什么会这样显示呢?查看一下 java.lang.Object 类的 toString() 方法就明白了。

public String toString() {
@@ -73,6 +73,6 @@ System.out.println(cmowers);
 System.out.println(Arrays.deepToString(deepArray));
 

打印结果如下所示。

[[沉默, 王二], [一枚有趣的程序员]]
 

“说到打印,三妹,哥给你提醒一点。阿里巴巴的 Java 开发手册上有这样一条规约,你看。”

“什么是 POJO 呢,就是 Plain Ordinary Java Object 的缩写,一般在 Web 应用程序中建立一个数据库的映射对象时,我们称它为 POJO,这类对象不继承或不实现任何其它 Java 框架的类或接口。”

“对于这样的类,最好是重写一下它的 toString() 方法,方便查看这个对象到底包含了什么字段,好排查问题。”

“如果不重写的话,打印出来的 Java 对象就像直接打印数组的那样,一串谁也看不懂的字符序列。”

“可以借助 Intellij IDEA 生成重写的 toString() 方法,特别方便。”

“好的,哥,我记住了。以后遇到的话,我注意下。你去休息吧,我来敲一下你提到的这些代码,练一练。”

“OK,我走,我走。”

- + diff --git a/dist/assets/100-budiushi.html.f74d8841.js b/dist/assets/100-budiushi.html.281fc989.js similarity index 99% rename from dist/assets/100-budiushi.html.f74d8841.js rename to dist/assets/100-budiushi.html.281fc989.js index b9e498eb..5fba248f 100644 --- a/dist/assets/100-budiushi.html.f74d8841.js +++ b/dist/assets/100-budiushi.html.281fc989.js @@ -1 +1 @@ -import{_ as e}from"./plugin-vue_export-helper.21dcd24c.js";import{o as p,c as t,e as a}from"./app.a0271b9c.js";const r={},i=a('

MQ\uFF1A\u600E\u4E48\u786E\u4FDD\u6D88\u606F100%\u4E0D\u4E22\u5931\uFF1F

\u9762\u8BD5\u5B98\u5728\u9762\u8BD5\u5019\u9009\u4EBA\u65F6\uFF0C\u5982\u679C\u53D1\u73B0\u5019\u9009\u4EBA\u7684\u7B80\u5386\u4E2D\u5199\u4E86\u5728\u9879\u76EE\u4E2D\u4F7F\u7528\u4E86 MQ \u6280\u672F\uFF08\u5982 Kafka\u3001RabbitMQ\u3001RocketMQ\uFF09\uFF0C\u57FA\u672C\u90FD\u4F1A\u629B\u51FA\u4E00\u4E2A\u95EE\u9898\uFF1A\u5728\u4F7F\u7528 MQ \u7684\u65F6\u5019\uFF0C\u600E\u4E48\u786E\u4FDD\u6D88\u606F 100% \u4E0D\u4E22\u5931\uFF1F

\u8FD9\u4E2A\u95EE\u9898\u5728\u5B9E\u9645\u5DE5\u4F5C\u4E2D\u5F88\u5E38\u89C1\uFF0C\u65E2\u80FD\u8003\u5BDF\u5019\u9009\u8005\u5BF9\u4E8E MQ \u4E2D\u95F4\u4EF6\u6280\u672F\u7684\u638C\u63E1\u7A0B\u5EA6\uFF0C\u53C8\u80FD\u5F88\u597D\u5730\u533A\u5206\u5019\u9009\u4EBA\u7684\u80FD\u529B\u6C34\u5E73\u3002\u63A5\u4E0B\u6765\uFF0C\u6211\u4EEC\u5C31\u4ECE\u8FD9\u4E2A\u95EE\u9898\u51FA\u53D1\uFF0C\u63A2\u8BA8\u4F60\u5E94\u8BE5\u638C\u63E1\u7684\u57FA\u7840\u77E5\u8BC6\u548C\u7B54\u9898\u601D\u8DEF\uFF0C\u4EE5\u53CA\u5EF6\u4F38\u7684\u9762\u8BD5\u8003\u70B9\u3002

\u6848\u4F8B\u80CC\u666F

\u4EE5\u4EAC\u4E1C\u7CFB\u7EDF\u4E3A\u4F8B\uFF0C\u7528\u6237\u5728\u8D2D\u4E70\u5546\u54C1\u65F6\uFF0C\u901A\u5E38\u4F1A\u9009\u62E9\u7528\u4EAC\u8C46\u62B5\u6263\u4E00\u90E8\u5206\u7684\u91D1\u989D\uFF0C\u5728\u8FD9\u4E2A\u8FC7\u7A0B\u4E2D\uFF0C\u4EA4\u6613\u670D\u52A1\u548C\u4EAC\u8C46\u670D\u52A1\u901A\u8FC7 MQ \u6D88\u606F\u961F\u5217\u8FDB\u884C\u901A\u4FE1\u3002\u5728\u4E0B\u5355\u65F6\uFF0C\u4EA4\u6613\u670D\u52A1\u53D1\u9001\u201C\u6263\u51CF\u8D26\u6237 X 100 \u4E2A\u4EAC\u8C46\u201D\u7684\u6D88\u606F\u7ED9 MQ \u6D88\u606F\u961F\u5217\uFF0C\u800C\u4EAC\u8C46\u670D\u52A1\u5219\u5728\u6D88\u8D39\u7AEF\u6D88\u8D39\u8FD9\u6761\u547D\u4EE4\uFF0C\u5B9E\u73B0\u771F\u6B63\u7684\u6263\u51CF\u64CD\u4F5C\u3002

\u90A3\u5728\u8FD9\u4E2A\u8FC7\u7A0B\u4E2D\u4F60\u4F1A\u9047\u5230\u4EC0\u4E48\u95EE\u9898\u5462\uFF1F

\u6848\u4F8B\u5206\u6790

\u8981\u77E5\u9053\uFF0C\u5728\u4E92\u8054\u7F51\u9762\u8BD5\u4E2D\uFF0C\u5F15\u5165 MQ \u6D88\u606F\u4E2D\u95F4\u4EF6\u6700\u76F4\u63A5\u7684\u76EE\u7684\u662F\uFF1A\u505A\u7CFB\u7EDF\u89E3\u8026\u5408\u6D41\u91CF\u63A7\u5236\uFF0C\u8FFD\u5176\u6839\u6E90\u8FD8\u662F\u4E3A\u4E86\u89E3\u51B3\u4E92\u8054\u7F51\u7CFB\u7EDF\u7684\u9AD8\u53EF\u7528\u548C\u9AD8\u6027\u80FD\u95EE\u9898\u3002

  • \u7CFB\u7EDF\u89E3\u8026\uFF1A \u7528 MQ \u6D88\u606F\u961F\u5217\uFF0C\u53EF\u4EE5\u9694\u79BB\u7CFB\u7EDF\u4E0A\u4E0B\u6E38\u73AF\u5883\u53D8\u5316\u5E26\u6765\u7684\u4E0D\u7A33\u5B9A\u56E0\u7D20\uFF0C\u6BD4\u5982\u4EAC\u8C46\u670D\u52A1\u7684\u7CFB\u7EDF\u9700\u6C42\u65E0\u8BBA\u5982\u4F55\u53D8\u5316\uFF0C\u4EA4\u6613\u670D\u52A1\u4E0D\u7528\u505A\u4EFB\u4F55\u6539\u53D8\uFF0C\u5373\u4F7F\u5F53\u4EAC\u8C46\u670D\u52A1\u51FA\u73B0\u6545\u969C\uFF0C\u4E3B\u4EA4\u6613\u6D41\u7A0B\u4E5F\u53EF\u4EE5\u5C06\u4EAC\u8C46\u670D\u52A1\u964D\u7EA7\uFF0C\u5B9E\u73B0\u4EA4\u6613\u670D\u52A1\u548C\u4EAC\u8C46\u670D\u52A1\u7684\u89E3\u8026\uFF0C\u505A\u5230\u4E86\u7CFB\u7EDF\u7684\u9AD8\u53EF\u7528\u3002
  • \u6D41\u91CF\u63A7\u5236\uFF1A \u9047\u5230\u79D2\u6740\u7B49\u6D41\u91CF\u7A81\u589E\u7684\u573A\u666F\uFF0C\u901A\u8FC7 MQ \u8FD8\u53EF\u4EE5\u5B9E\u73B0\u6D41\u91CF\u7684\u201C\u524A\u5CF0\u586B\u8C37\u201D\u7684\u4F5C\u7528\uFF0C\u53EF\u4EE5\u6839\u636E\u4E0B\u6E38\u7684\u5904\u7406\u80FD\u529B\u81EA\u52A8\u8C03\u8282\u6D41\u91CF\u3002 \u4E0D\u8FC7\u5F15\u5165 MQ \u867D\u7136\u5B9E\u73B0\u4E86\u7CFB\u7EDF\u89E3\u8026\u5408\u6D41\u91CF\u63A7\u5236\uFF0C\u4E5F\u4F1A\u5E26\u6765\u5176\u4ED6\u95EE\u9898\u3002

\u5F15\u5165 MQ \u6D88\u606F\u4E2D\u95F4\u4EF6\u5B9E\u73B0\u7CFB\u7EDF\u89E3\u8026\uFF0C\u4F1A\u5F71\u54CD\u7CFB\u7EDF\u4E4B\u95F4\u6570\u636E\u4F20\u8F93\u7684\u4E00\u81F4\u6027\u3002 \u5728\u5206\u5E03\u5F0F\u7CFB\u7EDF\u4E2D\uFF0C\u5982\u679C\u4E24\u4E2A\u8282\u70B9\u4E4B\u95F4\u5B58\u5728\u6570\u636E\u540C\u6B65\uFF0C\u5C31\u4F1A\u5E26\u6765\u6570\u636E\u4E00\u81F4\u6027\u7684\u95EE\u9898\u3002\u540C\u7406\uFF0C\u5728\u8FD9\u4E00\u8BB2\u4F60\u8981\u89E3\u51B3\u7684\u5C31\u662F\uFF1A\u6D88\u606F\u751F\u4EA7\u7AEF\u548C\u6D88\u606F\u6D88\u8D39\u7AEF\u7684\u6D88\u606F\u6570\u636E\u4E00\u81F4\u6027\u95EE\u9898\uFF08\u4E5F\u5C31\u662F\u5982\u4F55\u786E\u4FDD\u6D88\u606F\u4E0D\u4E22\u5931\uFF09\u3002

\u800C\u5F15\u5165 MQ \u6D88\u606F\u4E2D\u95F4\u4EF6\u89E3\u51B3\u6D41\u91CF\u63A7\u5236\uFF0C \u4F1A\u4F7F\u6D88\u8D39\u7AEF\u5904\u7406\u80FD\u529B\u4E0D\u8DB3\u4ECE\u800C\u5BFC\u81F4\u6D88\u606F\u79EF\u538B\uFF0C\u8FD9\u4E5F\u662F\u4F60\u8981\u89E3\u51B3\u7684\u95EE\u9898\u3002

\u6240\u4EE5\u4F60\u80FD\u53D1\u73B0\uFF0C\u95EE\u9898\u4E0E\u95EE\u9898\u4E4B\u95F4\u5F80\u5F80\u662F\u73AF\u73AF\u76F8\u6263\u7684\uFF0C\u9762\u8BD5\u5B98\u4F1A\u501F\u673A\u8003\u5BDF\u4F60\u89E3\u51B3\u95EE\u9898\u601D\u8DEF\u7684\u8FDE\u8D2F\u6027\u548C\u77E5\u8BC6\u4F53\u7CFB\u7684\u638C\u63E1\u7A0B\u5EA6\u3002

\u90A3\u9762\u5BF9\u201C\u5728\u4F7F\u7528 MQ \u6D88\u606F\u961F\u5217\u65F6\uFF0C\u5982\u4F55\u786E\u4FDD\u6D88\u606F\u4E0D\u4E22\u5931\u201D\u8FD9\u4E2A\u95EE\u9898\u65F6\uFF0C\u4F60\u8981\u600E\u4E48\u56DE\u7B54\u5462\uFF1F\u9996\u5148\uFF0C\u4F60\u8981\u5206\u6790\u5176\u4E2D\u6709\u51E0\u4E2A\u8003\u70B9\uFF0C\u6BD4\u5982\uFF1A

  • \u5982\u4F55\u77E5\u9053\u6709\u6D88\u606F\u4E22\u5931\uFF1F
  • \u54EA\u4E9B\u73AF\u8282\u53EF\u80FD\u4E22\u6D88\u606F\uFF1F
  • \u5982\u4F55\u786E\u4FDD\u6D88\u606F\u4E0D\u4E22\u5931\uFF1F

\u5019\u9009\u4EBA\u5728\u56DE\u7B54\u65F6\uFF0C\u8981\u5148\u8BA9\u9762\u8BD5\u5B98\u77E5\u9053\u4F60\u7684\u5206\u6790\u601D\u8DEF\uFF0C\u7136\u540E\u518D\u63D0\u4F9B\u89E3\u51B3\u65B9\u6848\uFF1A\u7F51\u7EDC\u4E2D\u7684\u6570\u636E\u4F20\u8F93\u4E0D\u53EF\u9760\uFF0C\u60F3\u8981\u89E3\u51B3\u5982\u4F55\u4E0D\u4E22\u6D88\u606F\u7684\u95EE\u9898\uFF0C\u9996\u5148\u8981\u77E5\u9053\u54EA\u4E9B\u73AF\u8282\u53EF\u80FD\u4E22\u6D88\u606F\uFF0C\u4EE5\u53CA\u6211\u4EEC\u5982\u4F55\u77E5\u9053\u6D88\u606F\u662F\u5426\u4E22\u5931\u4E86\uFF0C\u6700\u540E\u624D\u662F\u89E3\u51B3\u65B9\u6848\uFF08\u800C\u4E0D\u662F\u4E0A\u6765\u5C31\u76F4\u63A5\u8BF4\u81EA\u5DF1\u7684\u89E3\u51B3\u65B9\u6848\uFF09\u3002\u5C31\u597D\u6BD4\u201C\u67B6\u6784\u8BBE\u8BA1\u201D\u201C\u67B6\u6784\u201D\u4F53\u73B0\u4E86\u67B6\u6784\u5E08\u7684\u601D\u8003\u8FC7\u7A0B\uFF0C\u800C\u201C\u8BBE\u8BA1\u201D\u624D\u662F\u6700\u540E\u7684\u89E3\u51B3\u65B9\u6848\uFF0C\u4E24\u8005\u7F3A\u4E00\u4E0D\u53EF\u3002

\u6848\u4F8B\u89E3\u7B54

\u6211\u4EEC\u9996\u5148\u6765\u770B\u6D88\u606F\u4E22\u5931\u7684\u73AF\u8282\uFF0C\u4E00\u6761\u6D88\u606F\u4ECE\u751F\u4EA7\u5230\u6D88\u8D39\u5B8C\u6210\u8FD9\u4E2A\u8FC7\u7A0B\uFF0C\u53EF\u4EE5\u5212\u5206\u4E09\u4E2A\u9636\u6BB5\uFF0C\u5206\u522B\u4E3A\u6D88\u606F\u751F\u4EA7\u9636\u6BB5\uFF0C\u6D88\u606F\u5B58\u50A8\u9636\u6BB5\u548C\u6D88\u606F\u6D88\u8D39\u9636\u6BB5\u3002

\u6D88\u606F\u751F\u4EA7\u9636\u6BB5\uFF1A \u4ECE\u6D88\u606F\u88AB\u751F\u4EA7\u51FA\u6765\uFF0C\u7136\u540E\u63D0\u4EA4\u7ED9 MQ \u7684\u8FC7\u7A0B\u4E2D\uFF0C\u53EA\u8981\u80FD\u6B63\u5E38\u6536\u5230 MQ Broker \u7684 ack \u786E\u8BA4\u54CD\u5E94\uFF0C\u5C31\u8868\u793A\u53D1\u9001\u6210\u529F\uFF0C\u6240\u4EE5\u53EA\u8981\u5904\u7406\u597D\u8FD4\u56DE\u503C\u548C\u5F02\u5E38\uFF0C\u8FD9\u4E2A\u9636\u6BB5\u662F\u4E0D\u4F1A\u51FA\u73B0\u6D88\u606F\u4E22\u5931\u7684\u3002

\u6D88\u606F\u5B58\u50A8\u9636\u6BB5\uFF1A \u8FD9\u4E2A\u9636\u6BB5\u4E00\u822C\u4F1A\u76F4\u63A5\u4EA4\u7ED9 MQ \u6D88\u606F\u4E2D\u95F4\u4EF6\u6765\u4FDD\u8BC1\uFF0C\u4F46\u662F\u4F60\u8981\u4E86\u89E3\u5B83\u7684\u539F\u7406\uFF0C\u6BD4\u5982 Broker \u4F1A\u505A\u526F\u672C\uFF0C\u4FDD\u8BC1\u4E00\u6761\u6D88\u606F\u81F3\u5C11\u540C\u6B65\u4E24\u4E2A\u8282\u70B9\u518D\u8FD4\u56DE ack\u3002

\u6D88\u606F\u6D88\u8D39\u9636\u6BB5\uFF1A \u6D88\u8D39\u7AEF\u4ECE Broker \u4E0A\u62C9\u53D6\u6D88\u606F\uFF0C\u53EA\u8981\u6D88\u8D39\u7AEF\u5728\u6536\u5230\u6D88\u606F\u540E\uFF0C\u4E0D\u7ACB\u5373\u53D1\u9001\u6D88\u8D39\u786E\u8BA4\u7ED9 Broker\uFF0C\u800C\u662F\u7B49\u5230\u6267\u884C\u5B8C\u4E1A\u52A1\u903B\u8F91\u540E\uFF0C\u518D\u53D1\u9001\u6D88\u8D39\u786E\u8BA4\uFF0C\u4E5F\u80FD\u4FDD\u8BC1\u6D88\u606F\u7684\u4E0D\u4E22\u5931\u3002

\u65B9\u6848\u770B\u4F3C\u4E07\u65E0\u4E00\u5931\uFF0C\u6BCF\u4E2A\u9636\u6BB5\u90FD\u80FD\u4FDD\u8BC1\u6D88\u606F\u7684\u4E0D\u4E22\u5931\uFF0C\u4F46\u5728\u5206\u5E03\u5F0F\u7CFB\u7EDF\u4E2D\uFF0C\u6545\u969C\u4E0D\u53EF\u907F\u514D\uFF0C\u4F5C\u4E3A\u6D88\u606F\u751F\u4EA7\u7AEF\uFF0C\u4F60\u5E76\u4E0D\u80FD\u4FDD\u8BC1 MQ \u662F\u4E0D\u662F\u5F04\u4E22\u4E86\u4F60\u7684\u6D88\u606F\uFF0C\u6D88\u8D39\u8005\u662F\u5426\u6D88\u8D39\u4E86\u4F60\u7684\u6D88\u606F\uFF0C\u6240\u4EE5\uFF0C\u672C\u7740 Design for Failure \u7684\u8BBE\u8BA1\u539F\u5219\uFF0C\u4F60\u8FD8\u662F\u9700\u8981\u4E00\u79CD\u673A\u5236\uFF0C\u6765 Check \u6D88\u606F\u662F\u5426\u4E22\u5931\u4E86\u3002

\u7D27\u63A5\u7740\uFF0C\u4F60\u8FD8\u53EF\u4EE5\u5411\u9762\u8BD5\u5B98\u9610\u8FF0\u600E\u4E48\u8FDB\u884C\u6D88\u606F\u68C0\u6D4B\uFF1F \u603B\u4F53\u65B9\u6848\u89E3\u51B3\u601D\u8DEF\u4E3A\uFF1A\u5728\u6D88\u606F\u751F\u4EA7\u7AEF\uFF0C\u7ED9\u6BCF\u4E2A\u53D1\u51FA\u7684\u6D88\u606F\u90FD\u6307\u5B9A\u4E00\u4E2A\u5168\u5C40\u552F\u4E00 ID\uFF0C\u6216\u8005\u9644\u52A0\u4E00\u4E2A\u8FDE\u7EED\u9012\u589E\u7684\u7248\u672C\u53F7\uFF0C\u7136\u540E\u5728\u6D88\u8D39\u7AEF\u505A\u5BF9\u5E94\u7684\u7248\u672C\u6821\u9A8C\u3002

\u5177\u4F53\u600E\u4E48\u843D\u5730\u5B9E\u73B0\u5462\uFF1F\u4F60\u53EF\u4EE5\u5229\u7528\u62E6\u622A\u5668\u673A\u5236\u3002 \u5728\u751F\u4EA7\u7AEF\u53D1\u9001\u6D88\u606F\u4E4B\u524D\uFF0C\u901A\u8FC7\u62E6\u622A\u5668\u5C06\u6D88\u606F\u7248\u672C\u53F7\u6CE8\u5165\u6D88\u606F\u4E2D\uFF08\u7248\u672C\u53F7\u53EF\u4EE5\u91C7\u7528\u8FDE\u7EED\u9012\u589E\u7684 ID \u751F\u6210\uFF0C\u4E5F\u53EF\u4EE5\u901A\u8FC7\u5206\u5E03\u5F0F\u5168\u5C40\u552F\u4E00 ID\u751F\u6210\uFF09\u3002\u7136\u540E\u5728\u6D88\u8D39\u7AEF\u6536\u5230\u6D88\u606F\u540E\uFF0C\u518D\u901A\u8FC7\u62E6\u622A\u5668\u68C0\u6D4B\u7248\u672C\u53F7\u7684\u8FDE\u7EED\u6027\u6216\u6D88\u8D39\u72B6\u6001\uFF0C\u8FD9\u6837\u5B9E\u73B0\u7684\u597D\u5904\u662F\u6D88\u606F\u68C0\u6D4B\u7684\u4EE3\u7801\u4E0D\u4F1A\u4FB5\u5165\u5230\u4E1A\u52A1\u4EE3\u7801\u4E2D\uFF0C\u53EF\u4EE5\u901A\u8FC7\u5355\u72EC\u7684\u4EFB\u52A1\u6765\u5B9A\u4F4D\u4E22\u5931\u7684\u6D88\u606F\uFF0C\u505A\u8FDB\u4E00\u6B65\u7684\u6392\u67E5\u3002

\u8FD9\u91CC\u9700\u8981\u4F60\u6CE8\u610F\uFF1A\u5982\u679C\u540C\u65F6\u5B58\u5728\u591A\u4E2A\u6D88\u606F\u751F\u4EA7\u7AEF\u548C\u6D88\u606F\u6D88\u8D39\u7AEF\uFF0C\u901A\u8FC7\u7248\u672C\u53F7\u9012\u589E\u7684\u65B9\u5F0F\u5C31\u5F88\u96BE\u5B9E\u73B0\u4E86\uFF0C\u56E0\u4E3A\u4E0D\u80FD\u4FDD\u8BC1\u7248\u672C\u53F7\u7684\u552F\u4E00\u6027\uFF0C\u6B64\u65F6\u53EA\u80FD\u901A\u8FC7\u5168\u5C40\u552F\u4E00 ID \u7684\u65B9\u6848\u6765\u8FDB\u884C\u6D88\u606F\u68C0\u6D4B\uFF0C\u5177\u4F53\u7684\u5B9E\u73B0\u539F\u7406\u548C\u7248\u672C\u53F7\u9012\u589E\u7684\u65B9\u5F0F\u4E00\u81F4\u3002

\u73B0\u5728\uFF0C\u4F60\u5DF2\u7ECF\u77E5\u9053\u4E86\u54EA\u4E9B\u73AF\u8282\uFF08\u6D88\u606F\u5B58\u50A8\u9636\u6BB5\u3001\u6D88\u606F\u6D88\u8D39\u9636\u6BB5\uFF09\u53EF\u80FD\u4F1A\u51FA\u95EE\u9898\uFF0C\u5E76\u6709\u4E86\u5982\u4F55\u68C0\u6D4B\u6D88\u606F\u4E22\u5931\u7684\u65B9\u6848\uFF0C\u7136\u540E\u5C31\u8981\u7ED9\u51FA\u89E3\u51B3\u9632\u6B62\u6D88\u606F\u4E22\u5931\u7684\u8BBE\u8BA1\u65B9\u6848\u3002

\u56DE\u7B54\u5B8C\u201C\u5982\u4F55\u786E\u4FDD\u6D88\u606F\u4E0D\u4F1A\u4E22\u5931\uFF1F\u201D \u4E4B\u540E\uFF0C\u9762\u8BD5\u5B98\u901A\u5E38\u4F1A\u8FFD\u95EE\u201C\u600E\u4E48\u89E3\u51B3\u6D88\u606F\u88AB\u91CD\u590D\u6D88\u8D39\u7684\u95EE\u9898\uFF1F\u201D

\u6BD4\u5982\uFF1A\u5728\u6D88\u606F\u6D88\u8D39\u7684\u8FC7\u7A0B\u4E2D\uFF0C\u5982\u679C\u51FA\u73B0\u5931\u8D25\u7684\u60C5\u51B5\uFF0C\u901A\u8FC7\u8865\u507F\u7684\u673A\u5236\u53D1\u9001\u65B9\u4F1A\u6267\u884C\u91CD\u8BD5\uFF0C\u91CD\u8BD5\u7684\u8FC7\u7A0B\u5C31\u6709\u53EF\u80FD\u4EA7\u751F\u91CD\u590D\u7684\u6D88\u606F\uFF0C\u90A3\u4E48\u5982\u4F55\u89E3\u51B3\u8FD9\u4E2A\u95EE\u9898\uFF1F

\u8FD9\u4E2A\u95EE\u9898\u5176\u5B9E\u53EF\u4EE5\u6362\u4E00\u79CD\u8BF4\u6CD5\uFF0C\u5C31\u662F\u5982\u4F55\u89E3\u51B3\u6D88\u8D39\u7AEF\u5E42\u7B49\u6027\u95EE\u9898\uFF08\u5E42\u7B49\u6027\uFF0C\u5C31\u662F\u4E00\u6761\u547D\u4EE4\uFF0C\u4EFB\u610F\u591A\u6B21\u6267\u884C\u6240\u4EA7\u751F\u7684\u5F71\u54CD\u5747\u4E0E\u4E00\u6B21\u6267\u884C\u7684\u5F71\u54CD\u76F8\u540C\uFF09\uFF0C\u53EA\u8981\u6D88\u8D39\u7AEF\u5177\u5907\u4E86\u5E42\u7B49\u6027\uFF0C\u90A3\u4E48\u91CD\u590D\u6D88\u8D39\u6D88\u606F\u7684\u95EE\u9898\u4E5F\u5C31\u89E3\u51B3\u4E86\u3002

\u6211\u4EEC\u8FD8\u662F\u6765\u770B\u6263\u51CF\u4EAC\u8C46\u7684\u4F8B\u5B50\uFF0C\u5C06\u8D26\u6237 X \u7684\u91D1\u8C46\u4E2A\u6570\u6263\u51CF 100 \u4E2A\uFF0C\u5728\u8FD9\u4E2A\u4F8B\u5B50\u4E2D\uFF0C\u6211\u4EEC\u53EF\u4EE5\u901A\u8FC7\u6539\u9020\u4E1A\u52A1\u903B\u8F91\uFF0C\u8BA9\u5B83\u5177\u5907\u5E42\u7B49\u6027\u3002

\u6700\u7B80\u5355\u7684\u5B9E\u73B0\u65B9\u6848\uFF0C\u5C31\u662F\u5728\u6570\u636E\u5E93\u4E2D\u5EFA\u4E00\u5F20\u6D88\u606F\u65E5\u5FD7\u8868\uFF0C \u8FD9\u4E2A\u8868\u6709\u4E24\u4E2A\u5B57\u6BB5\uFF1A\u6D88\u606F ID \u548C\u6D88\u606F\u6267\u884C\u72B6\u6001\u3002\u8FD9\u6837\uFF0C\u6211\u4EEC\u6D88\u8D39\u6D88\u606F\u7684\u903B\u8F91\u53EF\u4EE5\u53D8\u4E3A\uFF1A\u5728\u6D88\u606F\u65E5\u5FD7\u8868\u4E2D\u589E\u52A0\u4E00\u6761\u6D88\u606F\u8BB0\u5F55\uFF0C\u7136\u540E\u518D\u6839\u636E\u6D88\u606F\u8BB0\u5F55\uFF0C\u5F02\u6B65\u64CD\u4F5C\u66F4\u65B0\u7528\u6237\u4EAC\u8C46\u4F59\u989D\u3002

\u56E0\u4E3A\u6211\u4EEC\u6BCF\u6B21\u90FD\u4F1A\u5728\u63D2\u5165\u4E4B\u524D\u68C0\u67E5\u662F\u5426\u6D88\u606F\u5DF2\u5B58\u5728\uFF0C\u6240\u4EE5\u5C31\u4E0D\u4F1A\u51FA\u73B0\u4E00\u6761\u6D88\u606F\u88AB\u6267\u884C\u591A\u6B21\u7684\u60C5\u51B5\uFF0C\u8FD9\u6837\u5C31\u5B9E\u73B0\u4E86\u4E00\u4E2A\u5E42\u7B49\u7684\u64CD\u4F5C\u3002\u5F53\u7136\uFF0C\u57FA\u4E8E\u8FD9\u4E2A\u601D\u8DEF\uFF0C\u4E0D\u4EC5\u53EF\u4EE5\u4F7F\u7528\u5173\u7CFB\u578B\u6570\u636E\u5E93\uFF0C\u4E5F\u53EF\u4EE5\u901A\u8FC7 Redis \u6765\u4EE3\u66FF\u6570\u636E\u5E93\u5B9E\u73B0\u552F\u4E00\u7EA6\u675F\u7684\u65B9\u6848\u3002

\u5728\u8FD9\u91CC\u6211\u591A\u8BF4\u4E00\u53E5\uFF0C\u60F3\u8981\u89E3\u51B3\u201C\u6D88\u606F\u4E22\u5931\u201D\u548C\u201C\u6D88\u606F\u91CD\u590D\u6D88\u8D39\u201D\u7684\u95EE\u9898\uFF0C\u6709\u4E00\u4E2A\u524D\u63D0\u6761\u4EF6\u5C31\u662F\u8981\u5B9E\u73B0\u4E00\u4E2A\u5168\u5C40\u552F\u4E00 ID \u751F\u6210\u7684\u6280\u672F\u65B9\u6848\u3002\u8FD9\u4E5F\u662F\u9762\u8BD5\u5B98\u559C\u6B22\u8003\u5BDF\u7684\u95EE\u9898\uFF0C\u4F60\u4E5F\u8981\u638C\u63E1\u3002

\u5728\u5206\u5E03\u5F0F\u7CFB\u7EDF\u4E2D\uFF0C\u5168\u5C40\u552F\u4E00 ID \u751F\u6210\u7684\u5B9E\u73B0\u65B9\u6CD5\u6709\u6570\u636E\u5E93\u81EA\u589E\u4E3B\u952E\u3001UUID\u3001Redis\uFF0CTwitter-Snowflake \u7B97\u6CD5\uFF0C\u6211\u603B\u7ED3\u4E86\u51E0\u79CD\u65B9\u6848\u7684\u7279\u70B9\uFF0C\u4F60\u53EF\u4EE5\u53C2\u8003\u4E0B\u3002

\u6211\u63D0\u9192\u4F60\u6CE8\u610F\uFF0C\u65E0\u8BBA\u54EA\u79CD\u65B9\u6CD5\uFF0C\u5982\u679C\u4F60\u60F3\u540C\u65F6\u6EE1\u8DB3\u7B80\u5355\u3001\u9AD8\u53EF\u7528\u548C\u9AD8\u6027\u80FD\uFF0C\u5C31\u8981\u6709\u53D6\u820D\uFF0C\u6240\u4EE5\u4F60\u8981\u7AD9\u5728\u5B9E\u9645\u7684\u4E1A\u52A1\u4E2D\uFF0C\u8BF4\u660E\u4F60\u7684\u9009\u578B\u6240\u8003\u8651\u7684\u5E73\u8861\u70B9\u662F\u4EC0\u4E48\u3002\u6211\u4E2A\u4EBA\u5728\u4E1A\u52A1\u4E2D\u6BD4\u8F83\u503E\u5411\u4E8E\u9009\u62E9 Snowflake \u7B97\u6CD5\uFF0C\u5728\u9879\u76EE\u4E2D\u4E5F\u8FDB\u884C\u4E86\u4E00\u5B9A\u7684\u6539\u9020\uFF0C\u4E3B\u8981\u662F\u8BA9\u7B97\u6CD5\u4E2D\u7684 ID \u751F\u6210\u89C4\u5219\u66F4\u52A0\u7B26\u5408\u4E1A\u52A1\u7279\u70B9\uFF0C\u4EE5\u53CA\u4F18\u5316\u8BF8\u5982\u65F6\u949F\u56DE\u62E8\u7B49\u95EE\u9898\u3002

\u5F53\u7136\uFF0C\u9664\u4E86\u201C\u600E\u4E48\u89E3\u51B3\u6D88\u606F\u88AB\u91CD\u590D\u6D88\u8D39\u7684\u95EE\u9898\uFF1F\u201D\u4E4B\u5916\uFF0C\u9762\u8BD5\u5B98\u8FD8\u4F1A\u95EE\u5230\u4F60\u201C\u6D88\u606F\u79EF\u538B\u201D\u3002 \u539F\u56E0\u5728\u4E8E\u6D88\u606F\u79EF\u538B\u53CD\u6620\u7684\u662F\u6027\u80FD\u95EE\u9898\uFF0C\u89E3\u51B3\u6D88\u606F\u79EF\u538B\u95EE\u9898\uFF0C\u53EF\u4EE5\u8BF4\u660E\u5019\u9009\u8005\u6709\u80FD\u529B\u5904\u7406\u9AD8\u5E76\u53D1\u573A\u666F\u4E0B\u7684\u6D88\u8D39\u80FD\u529B\u95EE\u9898\u3002

\u4F60\u5728\u89E3\u7B54\u8FD9\u4E2A\u95EE\u9898\u65F6\uFF0C\u4F9D\u65E7\u8981\u4F20\u9012\u7ED9\u9762\u8BD5\u5B98\u4E00\u4E2A\u8FD9\u6837\u7684\u601D\u8003\u8FC7\u7A0B\uFF1A \u5982\u679C\u51FA\u73B0\u79EF\u538B\uFF0C\u90A3\u4E00\u5B9A\u662F\u6027\u80FD\u95EE\u9898\uFF0C\u60F3\u8981\u89E3\u51B3\u6D88\u606F\u4ECE\u751F\u4EA7\u5230\u6D88\u8D39\u4E0A\u7684\u6027\u80FD\u95EE\u9898\uFF0C\u5C31\u9996\u5148\u8981\u77E5\u9053\u54EA\u4E9B\u73AF\u8282\u53EF\u80FD\u51FA\u73B0\u6D88\u606F\u79EF\u538B\uFF0C\u7136\u540E\u5728\u8003\u8651\u5982\u4F55\u89E3\u51B3\u3002

\u56E0\u4E3A\u6D88\u606F\u53D1\u9001\u4E4B\u540E\u624D\u4F1A\u51FA\u73B0\u79EF\u538B\u7684\u95EE\u9898\uFF0C\u6240\u4EE5\u548C\u6D88\u606F\u751F\u4EA7\u7AEF\u6CA1\u6709\u5173\u7CFB\uFF0C\u53C8\u56E0\u4E3A\u7EDD\u5927\u90E8\u5206\u7684\u6D88\u606F\u961F\u5217\u5355\u8282\u70B9\u90FD\u80FD\u8FBE\u5230\u6BCF\u79D2\u949F\u51E0\u4E07\u7684\u5904\u7406\u80FD\u529B\uFF0C\u76F8\u5BF9\u4E8E\u4E1A\u52A1\u903B\u8F91\u6765\u8BF4\uFF0C\u6027\u80FD\u4E0D\u4F1A\u51FA\u73B0\u5728\u4E2D\u95F4\u4EF6\u7684\u6D88\u606F\u5B58\u50A8\u4E0A\u9762\u3002\u6BEB\u65E0\u7591\u95EE\uFF0C\u51FA\u95EE\u9898\u7684\u80AF\u5B9A\u662F\u6D88\u606F\u6D88\u8D39\u9636\u6BB5\uFF0C\u90A3\u4E48\u4ECE\u6D88\u8D39\u7AEF\u5165\u624B\uFF0C\u5982\u4F55\u56DE\u7B54\u5462\uFF1F

\u5982\u679C\u662F\u7EBF\u4E0A\u7A81\u53D1\u95EE\u9898\uFF0C\u8981\u4E34\u65F6\u6269\u5BB9\uFF0C\u589E\u52A0\u6D88\u8D39\u7AEF\u7684\u6570\u91CF\uFF0C\u4E0E\u6B64\u540C\u65F6\uFF0C\u964D\u7EA7\u4E00\u4E9B\u975E\u6838\u5FC3\u7684\u4E1A\u52A1\u3002\u901A\u8FC7\u6269\u5BB9\u548C\u964D\u7EA7\u627F\u62C5\u6D41\u91CF\uFF0C\u8FD9\u662F\u4E3A\u4E86\u8868\u660E\u4F60\u5BF9\u5E94\u6025\u95EE\u9898\u7684\u5904\u7406\u80FD\u529B\u3002

\u5176\u6B21\uFF0C\u624D\u662F\u6392\u67E5\u89E3\u51B3\u5F02\u5E38\u95EE\u9898\uFF0C\u5982\u901A\u8FC7\u76D1\u63A7\uFF0C\u65E5\u5FD7\u7B49\u624B\u6BB5\u5206\u6790\u662F\u5426\u6D88\u8D39\u7AEF\u7684\u4E1A\u52A1\u903B\u8F91\u4EE3\u7801\u51FA\u73B0\u4E86\u95EE\u9898\uFF0C\u4F18\u5316\u6D88\u8D39\u7AEF\u7684\u4E1A\u52A1\u5904\u7406\u903B\u8F91\u3002

\u6700\u540E\uFF0C\u5982\u679C\u662F\u6D88\u8D39\u7AEF\u7684\u5904\u7406\u80FD\u529B\u4E0D\u8DB3\uFF0C\u53EF\u4EE5\u901A\u8FC7\u6C34\u5E73\u6269\u5BB9\u6765\u63D0\u4F9B\u6D88\u8D39\u7AEF\u7684\u5E76\u53D1\u5904\u7406\u80FD\u529B\uFF0C\u4F46\u8FD9\u91CC\u6709\u4E00\u4E2A\u8003\u70B9\u9700\u8981\u7279\u522B\u6CE8\u610F\uFF0C \u90A3\u5C31\u662F\u5728\u6269\u5BB9\u6D88\u8D39\u8005\u7684\u5B9E\u4F8B\u6570\u7684\u540C\u65F6\uFF0C\u5FC5\u987B\u540C\u6B65\u6269\u5BB9\u4E3B\u9898 Topic \u7684\u5206\u533A\u6570\u91CF\uFF0C\u786E\u4FDD\u6D88\u8D39\u8005\u7684\u5B9E\u4F8B\u6570\u548C\u5206\u533A\u6570\u76F8\u7B49\u3002\u5982\u679C\u6D88\u8D39\u8005\u7684\u5B9E\u4F8B\u6570\u8D85\u8FC7\u4E86\u5206\u533A\u6570\uFF0C\u7531\u4E8E\u5206\u533A\u662F\u5355\u7EBF\u7A0B\u6D88\u8D39\uFF0C\u6240\u4EE5\u8FD9\u6837\u7684\u6269\u5BB9\u5C31\u6CA1\u6709\u6548\u679C\u3002

\u6BD4\u5982\u5728 Kafka \u4E2D\uFF0C\u4E00\u4E2A Topic \u53EF\u4EE5\u914D\u7F6E\u591A\u4E2A Partition\uFF08\u5206\u533A\uFF09\uFF0C\u6570\u636E\u4F1A\u88AB\u5199\u5165\u5230\u591A\u4E2A\u5206\u533A\u4E2D\uFF0C\u4F46\u5728\u6D88\u8D39\u7684\u65F6\u5019\uFF0CKafka \u7EA6\u5B9A\u4E00\u4E2A\u5206\u533A\u53EA\u80FD\u88AB\u4E00\u4E2A\u6D88\u8D39\u8005\u6D88\u8D39\uFF0CTopic \u7684\u5206\u533A\u6570\u91CF\u51B3\u5B9A\u4E86\u6D88\u8D39\u7684\u80FD\u529B\uFF0C\u6240\u4EE5\uFF0C\u53EF\u4EE5\u901A\u8FC7\u589E\u52A0\u5206\u533A\u6765\u63D0\u9AD8\u6D88\u8D39\u8005\u7684\u5904\u7406\u80FD\u529B\u3002

\u603B\u7ED3

\u81F3\u6B64\uFF0C\u6211\u4EEC\u8BB2\u89E3\u4E86 MQ \u6D88\u606F\u961F\u5217\u7684\u70ED\u95E8\u95EE\u9898\u7684\u89E3\u51B3\u65B9\u6848\uFF0C\u65E0\u8BBA\u662F\u521D\u4E2D\u7EA7\u8FD8\u662F\u9AD8\u7EA7\u7814\u53D1\u5DE5\u7A0B\u5E08\uFF0C\u672C\u7BC7\u6587\u7AE0\u7684\u5185\u5BB9\u90FD\u662F\u4F60\u9700\u8981\u638C\u63E1\u7684\uFF0C\u4F60\u90FD\u53EF\u4EE5\u4ECE\u8FD9\u51E0\u70B9\u51FA\u53D1\uFF0C\u4E0E\u9762\u8BD5\u5B98\u8FDB\u884C\u53CB\u597D\u7684\u4EA4\u6D41\u3002\u6211\u6765\u603B\u7ED3\u4E00\u4E0B\u4ECA\u5929\u7684\u91CD\u70B9\u5185\u5BB9\u3002

  • \u5982\u4F55\u786E\u4FDD\u6D88\u606F\u4E0D\u4F1A\u4E22\u5931\uFF1F \u4F60\u8981\u77E5\u9053\u4E00\u6761\u6D88\u606F\u4ECE\u53D1\u9001\u5230\u6D88\u8D39\u7684\u6BCF\u4E2A\u9636\u6BB5\uFF0C\u662F\u5426\u5B58\u5728\u4E22\u6D88\u606F\uFF0C\u4EE5\u53CA\u5982\u4F55\u76D1\u63A7\u6D88\u606F\u662F\u5426\u4E22\u5931\uFF0C\u6700\u540E\u624D\u662F\u5982\u4F55\u89E3\u51B3\u95EE\u9898\uFF0C\u65B9\u6848\u53EF\u4EE5\u57FA\u4E8E\u201C MQ \u7684\u53EF\u9760\u6D88\u606F\u6295\u9012 \u201D\u7684\u65B9\u5F0F\u3002

  • \u5982\u4F55\u4FDD\u8BC1\u6D88\u606F\u4E0D\u88AB\u91CD\u590D\u6D88\u8D39\uFF1F \u5728\u8FDB\u884C\u6D88\u606F\u8865\u507F\u7684\u65F6\u5019\uFF0C\u4E00\u5B9A\u4F1A\u5B58\u5728\u91CD\u590D\u6D88\u606F\u7684\u60C5\u51B5\uFF0C\u90A3\u4E48\u5982\u4F55\u5B9E\u73B0\u6D88\u8D39\u7AEF\u7684\u5E42\u7B49\u6027\u5C31\u8FD9\u9053\u9898\u7684\u8003\u70B9\u3002

  • \u5982\u4F55\u5904\u7406\u6D88\u606F\u79EF\u538B\u95EE\u9898\uFF1F \u8FD9\u9053\u9898\u7684\u8003\u70B9\u5C31\u662F\u5982\u4F55\u901A\u8FC7 MQ \u5B9E\u73B0\u771F\u6B63\u7684\u9AD8\u6027\u80FD\uFF0C\u56DE\u7B54\u7684\u601D\u8DEF\u662F\uFF0C\u672C\u7740\u89E3\u51B3\u7EBF\u4E0A\u5F02\u5E38\u4E3A\u6700\u9AD8\u4F18\u5148\u7EA7\uFF0C\u7136\u540E\u901A\u8FC7\u76D1\u63A7\u548C\u65E5\u5FD7\u8FDB\u884C\u6392\u67E5\u5E76\u4F18\u5316\u4E1A\u52A1\u903B\u8F91\uFF0C\u6700\u540E\u662F\u6269\u5BB9\u6D88\u8D39\u7AEF\u548C\u5206\u7247\u7684\u6570\u91CF\u3002

\u5728\u56DE\u7B54\u95EE\u9898\u7684\u65F6\u5019\uFF0C\u4F60\u9700\u8981\u7279\u522B\u6CE8\u610F\u7684\u662F\uFF0C\u8BA9\u9762\u8BD5\u5B98\u4E86\u89E3\u5230\u4F60\u7684\u601D\u7EF4\u8FC7\u7A0B\uFF0C\u8FD9\u79CD\u89E3\u51B3\u95EE\u9898\u7684\u80FD\u529B\u662F\u9762\u8BD5\u5B98\u66F4\u4E3A\u770B\u4E2D\u7684\uFF0C\u6BD4\u4F60\u76F4\u63A5\u56DE\u7B54\u4E00\u9053\u9762\u8BD5\u9898\u66F4\u6709\u4EF7\u503C\u3002

\u53E6\u5916\uFF0C\u5982\u679C\u4F60\u5E94\u8058\u7684\u90E8\u95E8\u662F\u57FA\u7840\u67B6\u6784\u90E8\uFF0C\u90A3\u4E48\u9664\u4E86\u8981\u638C\u63E1\u672C\u8BB2\u4E2D\u7684\u5E38\u89C1\u95EE\u9898\u7684\u4E3B\u7EBF\u77E5\u8BC6\u4EE5\u5916\uFF0C\u8FD8\u8981\u638C\u63E1\u6D88\u606F\u4E2D\u95F4\u4EF6\u7684\u5176\u4ED6\u77E5\u8BC6\u4F53\u7CFB\uFF0C\u5982\uFF1A

  • \u5982\u4F55\u9009\u578B\u6D88\u606F\u4E2D\u95F4\u4EF6\uFF1F
  • \u6D88\u606F\u4E2D\u95F4\u4EF6\u4E2D\u7684\u961F\u5217\u6A21\u578B\u4E0E\u53D1\u5E03\u8BA2\u9605\u6A21\u578B\u7684\u533A\u522B\uFF1F
  • \u4E3A\u4EC0\u4E48\u6D88\u606F\u961F\u5217\u80FD\u5B9E\u73B0\u9AD8\u541E\u5410\uFF1F
  • \u5E8F\u5217\u5316\u3001\u4F20\u8F93\u534F\u8BAE\uFF0C\u4EE5\u53CA\u5185\u5B58\u7BA1\u7406\u7B49\u95EE\u9898
  • \u2026 >

\u539F\u6587\u94FE\u63A5\uFF1Ahttp://t.hk.uy/Ue6

',54),o=[i];function n(s,c){return p(),t("div",null,o)}var h=e(r,[["render",n],["__file","100-budiushi.html.vue"]]);export{h as default}; +import{_ as e}from"./plugin-vue_export-helper.21dcd24c.js";import{o as p,c as t,e as a}from"./app.615e41d8.js";const r={},i=a('

MQ\uFF1A\u600E\u4E48\u786E\u4FDD\u6D88\u606F100%\u4E0D\u4E22\u5931\uFF1F

\u9762\u8BD5\u5B98\u5728\u9762\u8BD5\u5019\u9009\u4EBA\u65F6\uFF0C\u5982\u679C\u53D1\u73B0\u5019\u9009\u4EBA\u7684\u7B80\u5386\u4E2D\u5199\u4E86\u5728\u9879\u76EE\u4E2D\u4F7F\u7528\u4E86 MQ \u6280\u672F\uFF08\u5982 Kafka\u3001RabbitMQ\u3001RocketMQ\uFF09\uFF0C\u57FA\u672C\u90FD\u4F1A\u629B\u51FA\u4E00\u4E2A\u95EE\u9898\uFF1A\u5728\u4F7F\u7528 MQ \u7684\u65F6\u5019\uFF0C\u600E\u4E48\u786E\u4FDD\u6D88\u606F 100% \u4E0D\u4E22\u5931\uFF1F

\u8FD9\u4E2A\u95EE\u9898\u5728\u5B9E\u9645\u5DE5\u4F5C\u4E2D\u5F88\u5E38\u89C1\uFF0C\u65E2\u80FD\u8003\u5BDF\u5019\u9009\u8005\u5BF9\u4E8E MQ \u4E2D\u95F4\u4EF6\u6280\u672F\u7684\u638C\u63E1\u7A0B\u5EA6\uFF0C\u53C8\u80FD\u5F88\u597D\u5730\u533A\u5206\u5019\u9009\u4EBA\u7684\u80FD\u529B\u6C34\u5E73\u3002\u63A5\u4E0B\u6765\uFF0C\u6211\u4EEC\u5C31\u4ECE\u8FD9\u4E2A\u95EE\u9898\u51FA\u53D1\uFF0C\u63A2\u8BA8\u4F60\u5E94\u8BE5\u638C\u63E1\u7684\u57FA\u7840\u77E5\u8BC6\u548C\u7B54\u9898\u601D\u8DEF\uFF0C\u4EE5\u53CA\u5EF6\u4F38\u7684\u9762\u8BD5\u8003\u70B9\u3002

\u6848\u4F8B\u80CC\u666F

\u4EE5\u4EAC\u4E1C\u7CFB\u7EDF\u4E3A\u4F8B\uFF0C\u7528\u6237\u5728\u8D2D\u4E70\u5546\u54C1\u65F6\uFF0C\u901A\u5E38\u4F1A\u9009\u62E9\u7528\u4EAC\u8C46\u62B5\u6263\u4E00\u90E8\u5206\u7684\u91D1\u989D\uFF0C\u5728\u8FD9\u4E2A\u8FC7\u7A0B\u4E2D\uFF0C\u4EA4\u6613\u670D\u52A1\u548C\u4EAC\u8C46\u670D\u52A1\u901A\u8FC7 MQ \u6D88\u606F\u961F\u5217\u8FDB\u884C\u901A\u4FE1\u3002\u5728\u4E0B\u5355\u65F6\uFF0C\u4EA4\u6613\u670D\u52A1\u53D1\u9001\u201C\u6263\u51CF\u8D26\u6237 X 100 \u4E2A\u4EAC\u8C46\u201D\u7684\u6D88\u606F\u7ED9 MQ \u6D88\u606F\u961F\u5217\uFF0C\u800C\u4EAC\u8C46\u670D\u52A1\u5219\u5728\u6D88\u8D39\u7AEF\u6D88\u8D39\u8FD9\u6761\u547D\u4EE4\uFF0C\u5B9E\u73B0\u771F\u6B63\u7684\u6263\u51CF\u64CD\u4F5C\u3002

\u90A3\u5728\u8FD9\u4E2A\u8FC7\u7A0B\u4E2D\u4F60\u4F1A\u9047\u5230\u4EC0\u4E48\u95EE\u9898\u5462\uFF1F

\u6848\u4F8B\u5206\u6790

\u8981\u77E5\u9053\uFF0C\u5728\u4E92\u8054\u7F51\u9762\u8BD5\u4E2D\uFF0C\u5F15\u5165 MQ \u6D88\u606F\u4E2D\u95F4\u4EF6\u6700\u76F4\u63A5\u7684\u76EE\u7684\u662F\uFF1A\u505A\u7CFB\u7EDF\u89E3\u8026\u5408\u6D41\u91CF\u63A7\u5236\uFF0C\u8FFD\u5176\u6839\u6E90\u8FD8\u662F\u4E3A\u4E86\u89E3\u51B3\u4E92\u8054\u7F51\u7CFB\u7EDF\u7684\u9AD8\u53EF\u7528\u548C\u9AD8\u6027\u80FD\u95EE\u9898\u3002

  • \u7CFB\u7EDF\u89E3\u8026\uFF1A \u7528 MQ \u6D88\u606F\u961F\u5217\uFF0C\u53EF\u4EE5\u9694\u79BB\u7CFB\u7EDF\u4E0A\u4E0B\u6E38\u73AF\u5883\u53D8\u5316\u5E26\u6765\u7684\u4E0D\u7A33\u5B9A\u56E0\u7D20\uFF0C\u6BD4\u5982\u4EAC\u8C46\u670D\u52A1\u7684\u7CFB\u7EDF\u9700\u6C42\u65E0\u8BBA\u5982\u4F55\u53D8\u5316\uFF0C\u4EA4\u6613\u670D\u52A1\u4E0D\u7528\u505A\u4EFB\u4F55\u6539\u53D8\uFF0C\u5373\u4F7F\u5F53\u4EAC\u8C46\u670D\u52A1\u51FA\u73B0\u6545\u969C\uFF0C\u4E3B\u4EA4\u6613\u6D41\u7A0B\u4E5F\u53EF\u4EE5\u5C06\u4EAC\u8C46\u670D\u52A1\u964D\u7EA7\uFF0C\u5B9E\u73B0\u4EA4\u6613\u670D\u52A1\u548C\u4EAC\u8C46\u670D\u52A1\u7684\u89E3\u8026\uFF0C\u505A\u5230\u4E86\u7CFB\u7EDF\u7684\u9AD8\u53EF\u7528\u3002
  • \u6D41\u91CF\u63A7\u5236\uFF1A \u9047\u5230\u79D2\u6740\u7B49\u6D41\u91CF\u7A81\u589E\u7684\u573A\u666F\uFF0C\u901A\u8FC7 MQ \u8FD8\u53EF\u4EE5\u5B9E\u73B0\u6D41\u91CF\u7684\u201C\u524A\u5CF0\u586B\u8C37\u201D\u7684\u4F5C\u7528\uFF0C\u53EF\u4EE5\u6839\u636E\u4E0B\u6E38\u7684\u5904\u7406\u80FD\u529B\u81EA\u52A8\u8C03\u8282\u6D41\u91CF\u3002 \u4E0D\u8FC7\u5F15\u5165 MQ \u867D\u7136\u5B9E\u73B0\u4E86\u7CFB\u7EDF\u89E3\u8026\u5408\u6D41\u91CF\u63A7\u5236\uFF0C\u4E5F\u4F1A\u5E26\u6765\u5176\u4ED6\u95EE\u9898\u3002

\u5F15\u5165 MQ \u6D88\u606F\u4E2D\u95F4\u4EF6\u5B9E\u73B0\u7CFB\u7EDF\u89E3\u8026\uFF0C\u4F1A\u5F71\u54CD\u7CFB\u7EDF\u4E4B\u95F4\u6570\u636E\u4F20\u8F93\u7684\u4E00\u81F4\u6027\u3002 \u5728\u5206\u5E03\u5F0F\u7CFB\u7EDF\u4E2D\uFF0C\u5982\u679C\u4E24\u4E2A\u8282\u70B9\u4E4B\u95F4\u5B58\u5728\u6570\u636E\u540C\u6B65\uFF0C\u5C31\u4F1A\u5E26\u6765\u6570\u636E\u4E00\u81F4\u6027\u7684\u95EE\u9898\u3002\u540C\u7406\uFF0C\u5728\u8FD9\u4E00\u8BB2\u4F60\u8981\u89E3\u51B3\u7684\u5C31\u662F\uFF1A\u6D88\u606F\u751F\u4EA7\u7AEF\u548C\u6D88\u606F\u6D88\u8D39\u7AEF\u7684\u6D88\u606F\u6570\u636E\u4E00\u81F4\u6027\u95EE\u9898\uFF08\u4E5F\u5C31\u662F\u5982\u4F55\u786E\u4FDD\u6D88\u606F\u4E0D\u4E22\u5931\uFF09\u3002

\u800C\u5F15\u5165 MQ \u6D88\u606F\u4E2D\u95F4\u4EF6\u89E3\u51B3\u6D41\u91CF\u63A7\u5236\uFF0C \u4F1A\u4F7F\u6D88\u8D39\u7AEF\u5904\u7406\u80FD\u529B\u4E0D\u8DB3\u4ECE\u800C\u5BFC\u81F4\u6D88\u606F\u79EF\u538B\uFF0C\u8FD9\u4E5F\u662F\u4F60\u8981\u89E3\u51B3\u7684\u95EE\u9898\u3002

\u6240\u4EE5\u4F60\u80FD\u53D1\u73B0\uFF0C\u95EE\u9898\u4E0E\u95EE\u9898\u4E4B\u95F4\u5F80\u5F80\u662F\u73AF\u73AF\u76F8\u6263\u7684\uFF0C\u9762\u8BD5\u5B98\u4F1A\u501F\u673A\u8003\u5BDF\u4F60\u89E3\u51B3\u95EE\u9898\u601D\u8DEF\u7684\u8FDE\u8D2F\u6027\u548C\u77E5\u8BC6\u4F53\u7CFB\u7684\u638C\u63E1\u7A0B\u5EA6\u3002

\u90A3\u9762\u5BF9\u201C\u5728\u4F7F\u7528 MQ \u6D88\u606F\u961F\u5217\u65F6\uFF0C\u5982\u4F55\u786E\u4FDD\u6D88\u606F\u4E0D\u4E22\u5931\u201D\u8FD9\u4E2A\u95EE\u9898\u65F6\uFF0C\u4F60\u8981\u600E\u4E48\u56DE\u7B54\u5462\uFF1F\u9996\u5148\uFF0C\u4F60\u8981\u5206\u6790\u5176\u4E2D\u6709\u51E0\u4E2A\u8003\u70B9\uFF0C\u6BD4\u5982\uFF1A

  • \u5982\u4F55\u77E5\u9053\u6709\u6D88\u606F\u4E22\u5931\uFF1F
  • \u54EA\u4E9B\u73AF\u8282\u53EF\u80FD\u4E22\u6D88\u606F\uFF1F
  • \u5982\u4F55\u786E\u4FDD\u6D88\u606F\u4E0D\u4E22\u5931\uFF1F

\u5019\u9009\u4EBA\u5728\u56DE\u7B54\u65F6\uFF0C\u8981\u5148\u8BA9\u9762\u8BD5\u5B98\u77E5\u9053\u4F60\u7684\u5206\u6790\u601D\u8DEF\uFF0C\u7136\u540E\u518D\u63D0\u4F9B\u89E3\u51B3\u65B9\u6848\uFF1A\u7F51\u7EDC\u4E2D\u7684\u6570\u636E\u4F20\u8F93\u4E0D\u53EF\u9760\uFF0C\u60F3\u8981\u89E3\u51B3\u5982\u4F55\u4E0D\u4E22\u6D88\u606F\u7684\u95EE\u9898\uFF0C\u9996\u5148\u8981\u77E5\u9053\u54EA\u4E9B\u73AF\u8282\u53EF\u80FD\u4E22\u6D88\u606F\uFF0C\u4EE5\u53CA\u6211\u4EEC\u5982\u4F55\u77E5\u9053\u6D88\u606F\u662F\u5426\u4E22\u5931\u4E86\uFF0C\u6700\u540E\u624D\u662F\u89E3\u51B3\u65B9\u6848\uFF08\u800C\u4E0D\u662F\u4E0A\u6765\u5C31\u76F4\u63A5\u8BF4\u81EA\u5DF1\u7684\u89E3\u51B3\u65B9\u6848\uFF09\u3002\u5C31\u597D\u6BD4\u201C\u67B6\u6784\u8BBE\u8BA1\u201D\u201C\u67B6\u6784\u201D\u4F53\u73B0\u4E86\u67B6\u6784\u5E08\u7684\u601D\u8003\u8FC7\u7A0B\uFF0C\u800C\u201C\u8BBE\u8BA1\u201D\u624D\u662F\u6700\u540E\u7684\u89E3\u51B3\u65B9\u6848\uFF0C\u4E24\u8005\u7F3A\u4E00\u4E0D\u53EF\u3002

\u6848\u4F8B\u89E3\u7B54

\u6211\u4EEC\u9996\u5148\u6765\u770B\u6D88\u606F\u4E22\u5931\u7684\u73AF\u8282\uFF0C\u4E00\u6761\u6D88\u606F\u4ECE\u751F\u4EA7\u5230\u6D88\u8D39\u5B8C\u6210\u8FD9\u4E2A\u8FC7\u7A0B\uFF0C\u53EF\u4EE5\u5212\u5206\u4E09\u4E2A\u9636\u6BB5\uFF0C\u5206\u522B\u4E3A\u6D88\u606F\u751F\u4EA7\u9636\u6BB5\uFF0C\u6D88\u606F\u5B58\u50A8\u9636\u6BB5\u548C\u6D88\u606F\u6D88\u8D39\u9636\u6BB5\u3002

\u6D88\u606F\u751F\u4EA7\u9636\u6BB5\uFF1A \u4ECE\u6D88\u606F\u88AB\u751F\u4EA7\u51FA\u6765\uFF0C\u7136\u540E\u63D0\u4EA4\u7ED9 MQ \u7684\u8FC7\u7A0B\u4E2D\uFF0C\u53EA\u8981\u80FD\u6B63\u5E38\u6536\u5230 MQ Broker \u7684 ack \u786E\u8BA4\u54CD\u5E94\uFF0C\u5C31\u8868\u793A\u53D1\u9001\u6210\u529F\uFF0C\u6240\u4EE5\u53EA\u8981\u5904\u7406\u597D\u8FD4\u56DE\u503C\u548C\u5F02\u5E38\uFF0C\u8FD9\u4E2A\u9636\u6BB5\u662F\u4E0D\u4F1A\u51FA\u73B0\u6D88\u606F\u4E22\u5931\u7684\u3002

\u6D88\u606F\u5B58\u50A8\u9636\u6BB5\uFF1A \u8FD9\u4E2A\u9636\u6BB5\u4E00\u822C\u4F1A\u76F4\u63A5\u4EA4\u7ED9 MQ \u6D88\u606F\u4E2D\u95F4\u4EF6\u6765\u4FDD\u8BC1\uFF0C\u4F46\u662F\u4F60\u8981\u4E86\u89E3\u5B83\u7684\u539F\u7406\uFF0C\u6BD4\u5982 Broker \u4F1A\u505A\u526F\u672C\uFF0C\u4FDD\u8BC1\u4E00\u6761\u6D88\u606F\u81F3\u5C11\u540C\u6B65\u4E24\u4E2A\u8282\u70B9\u518D\u8FD4\u56DE ack\u3002

\u6D88\u606F\u6D88\u8D39\u9636\u6BB5\uFF1A \u6D88\u8D39\u7AEF\u4ECE Broker \u4E0A\u62C9\u53D6\u6D88\u606F\uFF0C\u53EA\u8981\u6D88\u8D39\u7AEF\u5728\u6536\u5230\u6D88\u606F\u540E\uFF0C\u4E0D\u7ACB\u5373\u53D1\u9001\u6D88\u8D39\u786E\u8BA4\u7ED9 Broker\uFF0C\u800C\u662F\u7B49\u5230\u6267\u884C\u5B8C\u4E1A\u52A1\u903B\u8F91\u540E\uFF0C\u518D\u53D1\u9001\u6D88\u8D39\u786E\u8BA4\uFF0C\u4E5F\u80FD\u4FDD\u8BC1\u6D88\u606F\u7684\u4E0D\u4E22\u5931\u3002

\u65B9\u6848\u770B\u4F3C\u4E07\u65E0\u4E00\u5931\uFF0C\u6BCF\u4E2A\u9636\u6BB5\u90FD\u80FD\u4FDD\u8BC1\u6D88\u606F\u7684\u4E0D\u4E22\u5931\uFF0C\u4F46\u5728\u5206\u5E03\u5F0F\u7CFB\u7EDF\u4E2D\uFF0C\u6545\u969C\u4E0D\u53EF\u907F\u514D\uFF0C\u4F5C\u4E3A\u6D88\u606F\u751F\u4EA7\u7AEF\uFF0C\u4F60\u5E76\u4E0D\u80FD\u4FDD\u8BC1 MQ \u662F\u4E0D\u662F\u5F04\u4E22\u4E86\u4F60\u7684\u6D88\u606F\uFF0C\u6D88\u8D39\u8005\u662F\u5426\u6D88\u8D39\u4E86\u4F60\u7684\u6D88\u606F\uFF0C\u6240\u4EE5\uFF0C\u672C\u7740 Design for Failure \u7684\u8BBE\u8BA1\u539F\u5219\uFF0C\u4F60\u8FD8\u662F\u9700\u8981\u4E00\u79CD\u673A\u5236\uFF0C\u6765 Check \u6D88\u606F\u662F\u5426\u4E22\u5931\u4E86\u3002

\u7D27\u63A5\u7740\uFF0C\u4F60\u8FD8\u53EF\u4EE5\u5411\u9762\u8BD5\u5B98\u9610\u8FF0\u600E\u4E48\u8FDB\u884C\u6D88\u606F\u68C0\u6D4B\uFF1F \u603B\u4F53\u65B9\u6848\u89E3\u51B3\u601D\u8DEF\u4E3A\uFF1A\u5728\u6D88\u606F\u751F\u4EA7\u7AEF\uFF0C\u7ED9\u6BCF\u4E2A\u53D1\u51FA\u7684\u6D88\u606F\u90FD\u6307\u5B9A\u4E00\u4E2A\u5168\u5C40\u552F\u4E00 ID\uFF0C\u6216\u8005\u9644\u52A0\u4E00\u4E2A\u8FDE\u7EED\u9012\u589E\u7684\u7248\u672C\u53F7\uFF0C\u7136\u540E\u5728\u6D88\u8D39\u7AEF\u505A\u5BF9\u5E94\u7684\u7248\u672C\u6821\u9A8C\u3002

\u5177\u4F53\u600E\u4E48\u843D\u5730\u5B9E\u73B0\u5462\uFF1F\u4F60\u53EF\u4EE5\u5229\u7528\u62E6\u622A\u5668\u673A\u5236\u3002 \u5728\u751F\u4EA7\u7AEF\u53D1\u9001\u6D88\u606F\u4E4B\u524D\uFF0C\u901A\u8FC7\u62E6\u622A\u5668\u5C06\u6D88\u606F\u7248\u672C\u53F7\u6CE8\u5165\u6D88\u606F\u4E2D\uFF08\u7248\u672C\u53F7\u53EF\u4EE5\u91C7\u7528\u8FDE\u7EED\u9012\u589E\u7684 ID \u751F\u6210\uFF0C\u4E5F\u53EF\u4EE5\u901A\u8FC7\u5206\u5E03\u5F0F\u5168\u5C40\u552F\u4E00 ID\u751F\u6210\uFF09\u3002\u7136\u540E\u5728\u6D88\u8D39\u7AEF\u6536\u5230\u6D88\u606F\u540E\uFF0C\u518D\u901A\u8FC7\u62E6\u622A\u5668\u68C0\u6D4B\u7248\u672C\u53F7\u7684\u8FDE\u7EED\u6027\u6216\u6D88\u8D39\u72B6\u6001\uFF0C\u8FD9\u6837\u5B9E\u73B0\u7684\u597D\u5904\u662F\u6D88\u606F\u68C0\u6D4B\u7684\u4EE3\u7801\u4E0D\u4F1A\u4FB5\u5165\u5230\u4E1A\u52A1\u4EE3\u7801\u4E2D\uFF0C\u53EF\u4EE5\u901A\u8FC7\u5355\u72EC\u7684\u4EFB\u52A1\u6765\u5B9A\u4F4D\u4E22\u5931\u7684\u6D88\u606F\uFF0C\u505A\u8FDB\u4E00\u6B65\u7684\u6392\u67E5\u3002

\u8FD9\u91CC\u9700\u8981\u4F60\u6CE8\u610F\uFF1A\u5982\u679C\u540C\u65F6\u5B58\u5728\u591A\u4E2A\u6D88\u606F\u751F\u4EA7\u7AEF\u548C\u6D88\u606F\u6D88\u8D39\u7AEF\uFF0C\u901A\u8FC7\u7248\u672C\u53F7\u9012\u589E\u7684\u65B9\u5F0F\u5C31\u5F88\u96BE\u5B9E\u73B0\u4E86\uFF0C\u56E0\u4E3A\u4E0D\u80FD\u4FDD\u8BC1\u7248\u672C\u53F7\u7684\u552F\u4E00\u6027\uFF0C\u6B64\u65F6\u53EA\u80FD\u901A\u8FC7\u5168\u5C40\u552F\u4E00 ID \u7684\u65B9\u6848\u6765\u8FDB\u884C\u6D88\u606F\u68C0\u6D4B\uFF0C\u5177\u4F53\u7684\u5B9E\u73B0\u539F\u7406\u548C\u7248\u672C\u53F7\u9012\u589E\u7684\u65B9\u5F0F\u4E00\u81F4\u3002

\u73B0\u5728\uFF0C\u4F60\u5DF2\u7ECF\u77E5\u9053\u4E86\u54EA\u4E9B\u73AF\u8282\uFF08\u6D88\u606F\u5B58\u50A8\u9636\u6BB5\u3001\u6D88\u606F\u6D88\u8D39\u9636\u6BB5\uFF09\u53EF\u80FD\u4F1A\u51FA\u95EE\u9898\uFF0C\u5E76\u6709\u4E86\u5982\u4F55\u68C0\u6D4B\u6D88\u606F\u4E22\u5931\u7684\u65B9\u6848\uFF0C\u7136\u540E\u5C31\u8981\u7ED9\u51FA\u89E3\u51B3\u9632\u6B62\u6D88\u606F\u4E22\u5931\u7684\u8BBE\u8BA1\u65B9\u6848\u3002

\u56DE\u7B54\u5B8C\u201C\u5982\u4F55\u786E\u4FDD\u6D88\u606F\u4E0D\u4F1A\u4E22\u5931\uFF1F\u201D \u4E4B\u540E\uFF0C\u9762\u8BD5\u5B98\u901A\u5E38\u4F1A\u8FFD\u95EE\u201C\u600E\u4E48\u89E3\u51B3\u6D88\u606F\u88AB\u91CD\u590D\u6D88\u8D39\u7684\u95EE\u9898\uFF1F\u201D

\u6BD4\u5982\uFF1A\u5728\u6D88\u606F\u6D88\u8D39\u7684\u8FC7\u7A0B\u4E2D\uFF0C\u5982\u679C\u51FA\u73B0\u5931\u8D25\u7684\u60C5\u51B5\uFF0C\u901A\u8FC7\u8865\u507F\u7684\u673A\u5236\u53D1\u9001\u65B9\u4F1A\u6267\u884C\u91CD\u8BD5\uFF0C\u91CD\u8BD5\u7684\u8FC7\u7A0B\u5C31\u6709\u53EF\u80FD\u4EA7\u751F\u91CD\u590D\u7684\u6D88\u606F\uFF0C\u90A3\u4E48\u5982\u4F55\u89E3\u51B3\u8FD9\u4E2A\u95EE\u9898\uFF1F

\u8FD9\u4E2A\u95EE\u9898\u5176\u5B9E\u53EF\u4EE5\u6362\u4E00\u79CD\u8BF4\u6CD5\uFF0C\u5C31\u662F\u5982\u4F55\u89E3\u51B3\u6D88\u8D39\u7AEF\u5E42\u7B49\u6027\u95EE\u9898\uFF08\u5E42\u7B49\u6027\uFF0C\u5C31\u662F\u4E00\u6761\u547D\u4EE4\uFF0C\u4EFB\u610F\u591A\u6B21\u6267\u884C\u6240\u4EA7\u751F\u7684\u5F71\u54CD\u5747\u4E0E\u4E00\u6B21\u6267\u884C\u7684\u5F71\u54CD\u76F8\u540C\uFF09\uFF0C\u53EA\u8981\u6D88\u8D39\u7AEF\u5177\u5907\u4E86\u5E42\u7B49\u6027\uFF0C\u90A3\u4E48\u91CD\u590D\u6D88\u8D39\u6D88\u606F\u7684\u95EE\u9898\u4E5F\u5C31\u89E3\u51B3\u4E86\u3002

\u6211\u4EEC\u8FD8\u662F\u6765\u770B\u6263\u51CF\u4EAC\u8C46\u7684\u4F8B\u5B50\uFF0C\u5C06\u8D26\u6237 X \u7684\u91D1\u8C46\u4E2A\u6570\u6263\u51CF 100 \u4E2A\uFF0C\u5728\u8FD9\u4E2A\u4F8B\u5B50\u4E2D\uFF0C\u6211\u4EEC\u53EF\u4EE5\u901A\u8FC7\u6539\u9020\u4E1A\u52A1\u903B\u8F91\uFF0C\u8BA9\u5B83\u5177\u5907\u5E42\u7B49\u6027\u3002

\u6700\u7B80\u5355\u7684\u5B9E\u73B0\u65B9\u6848\uFF0C\u5C31\u662F\u5728\u6570\u636E\u5E93\u4E2D\u5EFA\u4E00\u5F20\u6D88\u606F\u65E5\u5FD7\u8868\uFF0C \u8FD9\u4E2A\u8868\u6709\u4E24\u4E2A\u5B57\u6BB5\uFF1A\u6D88\u606F ID \u548C\u6D88\u606F\u6267\u884C\u72B6\u6001\u3002\u8FD9\u6837\uFF0C\u6211\u4EEC\u6D88\u8D39\u6D88\u606F\u7684\u903B\u8F91\u53EF\u4EE5\u53D8\u4E3A\uFF1A\u5728\u6D88\u606F\u65E5\u5FD7\u8868\u4E2D\u589E\u52A0\u4E00\u6761\u6D88\u606F\u8BB0\u5F55\uFF0C\u7136\u540E\u518D\u6839\u636E\u6D88\u606F\u8BB0\u5F55\uFF0C\u5F02\u6B65\u64CD\u4F5C\u66F4\u65B0\u7528\u6237\u4EAC\u8C46\u4F59\u989D\u3002

\u56E0\u4E3A\u6211\u4EEC\u6BCF\u6B21\u90FD\u4F1A\u5728\u63D2\u5165\u4E4B\u524D\u68C0\u67E5\u662F\u5426\u6D88\u606F\u5DF2\u5B58\u5728\uFF0C\u6240\u4EE5\u5C31\u4E0D\u4F1A\u51FA\u73B0\u4E00\u6761\u6D88\u606F\u88AB\u6267\u884C\u591A\u6B21\u7684\u60C5\u51B5\uFF0C\u8FD9\u6837\u5C31\u5B9E\u73B0\u4E86\u4E00\u4E2A\u5E42\u7B49\u7684\u64CD\u4F5C\u3002\u5F53\u7136\uFF0C\u57FA\u4E8E\u8FD9\u4E2A\u601D\u8DEF\uFF0C\u4E0D\u4EC5\u53EF\u4EE5\u4F7F\u7528\u5173\u7CFB\u578B\u6570\u636E\u5E93\uFF0C\u4E5F\u53EF\u4EE5\u901A\u8FC7 Redis \u6765\u4EE3\u66FF\u6570\u636E\u5E93\u5B9E\u73B0\u552F\u4E00\u7EA6\u675F\u7684\u65B9\u6848\u3002

\u5728\u8FD9\u91CC\u6211\u591A\u8BF4\u4E00\u53E5\uFF0C\u60F3\u8981\u89E3\u51B3\u201C\u6D88\u606F\u4E22\u5931\u201D\u548C\u201C\u6D88\u606F\u91CD\u590D\u6D88\u8D39\u201D\u7684\u95EE\u9898\uFF0C\u6709\u4E00\u4E2A\u524D\u63D0\u6761\u4EF6\u5C31\u662F\u8981\u5B9E\u73B0\u4E00\u4E2A\u5168\u5C40\u552F\u4E00 ID \u751F\u6210\u7684\u6280\u672F\u65B9\u6848\u3002\u8FD9\u4E5F\u662F\u9762\u8BD5\u5B98\u559C\u6B22\u8003\u5BDF\u7684\u95EE\u9898\uFF0C\u4F60\u4E5F\u8981\u638C\u63E1\u3002

\u5728\u5206\u5E03\u5F0F\u7CFB\u7EDF\u4E2D\uFF0C\u5168\u5C40\u552F\u4E00 ID \u751F\u6210\u7684\u5B9E\u73B0\u65B9\u6CD5\u6709\u6570\u636E\u5E93\u81EA\u589E\u4E3B\u952E\u3001UUID\u3001Redis\uFF0CTwitter-Snowflake \u7B97\u6CD5\uFF0C\u6211\u603B\u7ED3\u4E86\u51E0\u79CD\u65B9\u6848\u7684\u7279\u70B9\uFF0C\u4F60\u53EF\u4EE5\u53C2\u8003\u4E0B\u3002

\u6211\u63D0\u9192\u4F60\u6CE8\u610F\uFF0C\u65E0\u8BBA\u54EA\u79CD\u65B9\u6CD5\uFF0C\u5982\u679C\u4F60\u60F3\u540C\u65F6\u6EE1\u8DB3\u7B80\u5355\u3001\u9AD8\u53EF\u7528\u548C\u9AD8\u6027\u80FD\uFF0C\u5C31\u8981\u6709\u53D6\u820D\uFF0C\u6240\u4EE5\u4F60\u8981\u7AD9\u5728\u5B9E\u9645\u7684\u4E1A\u52A1\u4E2D\uFF0C\u8BF4\u660E\u4F60\u7684\u9009\u578B\u6240\u8003\u8651\u7684\u5E73\u8861\u70B9\u662F\u4EC0\u4E48\u3002\u6211\u4E2A\u4EBA\u5728\u4E1A\u52A1\u4E2D\u6BD4\u8F83\u503E\u5411\u4E8E\u9009\u62E9 Snowflake \u7B97\u6CD5\uFF0C\u5728\u9879\u76EE\u4E2D\u4E5F\u8FDB\u884C\u4E86\u4E00\u5B9A\u7684\u6539\u9020\uFF0C\u4E3B\u8981\u662F\u8BA9\u7B97\u6CD5\u4E2D\u7684 ID \u751F\u6210\u89C4\u5219\u66F4\u52A0\u7B26\u5408\u4E1A\u52A1\u7279\u70B9\uFF0C\u4EE5\u53CA\u4F18\u5316\u8BF8\u5982\u65F6\u949F\u56DE\u62E8\u7B49\u95EE\u9898\u3002

\u5F53\u7136\uFF0C\u9664\u4E86\u201C\u600E\u4E48\u89E3\u51B3\u6D88\u606F\u88AB\u91CD\u590D\u6D88\u8D39\u7684\u95EE\u9898\uFF1F\u201D\u4E4B\u5916\uFF0C\u9762\u8BD5\u5B98\u8FD8\u4F1A\u95EE\u5230\u4F60\u201C\u6D88\u606F\u79EF\u538B\u201D\u3002 \u539F\u56E0\u5728\u4E8E\u6D88\u606F\u79EF\u538B\u53CD\u6620\u7684\u662F\u6027\u80FD\u95EE\u9898\uFF0C\u89E3\u51B3\u6D88\u606F\u79EF\u538B\u95EE\u9898\uFF0C\u53EF\u4EE5\u8BF4\u660E\u5019\u9009\u8005\u6709\u80FD\u529B\u5904\u7406\u9AD8\u5E76\u53D1\u573A\u666F\u4E0B\u7684\u6D88\u8D39\u80FD\u529B\u95EE\u9898\u3002

\u4F60\u5728\u89E3\u7B54\u8FD9\u4E2A\u95EE\u9898\u65F6\uFF0C\u4F9D\u65E7\u8981\u4F20\u9012\u7ED9\u9762\u8BD5\u5B98\u4E00\u4E2A\u8FD9\u6837\u7684\u601D\u8003\u8FC7\u7A0B\uFF1A \u5982\u679C\u51FA\u73B0\u79EF\u538B\uFF0C\u90A3\u4E00\u5B9A\u662F\u6027\u80FD\u95EE\u9898\uFF0C\u60F3\u8981\u89E3\u51B3\u6D88\u606F\u4ECE\u751F\u4EA7\u5230\u6D88\u8D39\u4E0A\u7684\u6027\u80FD\u95EE\u9898\uFF0C\u5C31\u9996\u5148\u8981\u77E5\u9053\u54EA\u4E9B\u73AF\u8282\u53EF\u80FD\u51FA\u73B0\u6D88\u606F\u79EF\u538B\uFF0C\u7136\u540E\u5728\u8003\u8651\u5982\u4F55\u89E3\u51B3\u3002

\u56E0\u4E3A\u6D88\u606F\u53D1\u9001\u4E4B\u540E\u624D\u4F1A\u51FA\u73B0\u79EF\u538B\u7684\u95EE\u9898\uFF0C\u6240\u4EE5\u548C\u6D88\u606F\u751F\u4EA7\u7AEF\u6CA1\u6709\u5173\u7CFB\uFF0C\u53C8\u56E0\u4E3A\u7EDD\u5927\u90E8\u5206\u7684\u6D88\u606F\u961F\u5217\u5355\u8282\u70B9\u90FD\u80FD\u8FBE\u5230\u6BCF\u79D2\u949F\u51E0\u4E07\u7684\u5904\u7406\u80FD\u529B\uFF0C\u76F8\u5BF9\u4E8E\u4E1A\u52A1\u903B\u8F91\u6765\u8BF4\uFF0C\u6027\u80FD\u4E0D\u4F1A\u51FA\u73B0\u5728\u4E2D\u95F4\u4EF6\u7684\u6D88\u606F\u5B58\u50A8\u4E0A\u9762\u3002\u6BEB\u65E0\u7591\u95EE\uFF0C\u51FA\u95EE\u9898\u7684\u80AF\u5B9A\u662F\u6D88\u606F\u6D88\u8D39\u9636\u6BB5\uFF0C\u90A3\u4E48\u4ECE\u6D88\u8D39\u7AEF\u5165\u624B\uFF0C\u5982\u4F55\u56DE\u7B54\u5462\uFF1F

\u5982\u679C\u662F\u7EBF\u4E0A\u7A81\u53D1\u95EE\u9898\uFF0C\u8981\u4E34\u65F6\u6269\u5BB9\uFF0C\u589E\u52A0\u6D88\u8D39\u7AEF\u7684\u6570\u91CF\uFF0C\u4E0E\u6B64\u540C\u65F6\uFF0C\u964D\u7EA7\u4E00\u4E9B\u975E\u6838\u5FC3\u7684\u4E1A\u52A1\u3002\u901A\u8FC7\u6269\u5BB9\u548C\u964D\u7EA7\u627F\u62C5\u6D41\u91CF\uFF0C\u8FD9\u662F\u4E3A\u4E86\u8868\u660E\u4F60\u5BF9\u5E94\u6025\u95EE\u9898\u7684\u5904\u7406\u80FD\u529B\u3002

\u5176\u6B21\uFF0C\u624D\u662F\u6392\u67E5\u89E3\u51B3\u5F02\u5E38\u95EE\u9898\uFF0C\u5982\u901A\u8FC7\u76D1\u63A7\uFF0C\u65E5\u5FD7\u7B49\u624B\u6BB5\u5206\u6790\u662F\u5426\u6D88\u8D39\u7AEF\u7684\u4E1A\u52A1\u903B\u8F91\u4EE3\u7801\u51FA\u73B0\u4E86\u95EE\u9898\uFF0C\u4F18\u5316\u6D88\u8D39\u7AEF\u7684\u4E1A\u52A1\u5904\u7406\u903B\u8F91\u3002

\u6700\u540E\uFF0C\u5982\u679C\u662F\u6D88\u8D39\u7AEF\u7684\u5904\u7406\u80FD\u529B\u4E0D\u8DB3\uFF0C\u53EF\u4EE5\u901A\u8FC7\u6C34\u5E73\u6269\u5BB9\u6765\u63D0\u4F9B\u6D88\u8D39\u7AEF\u7684\u5E76\u53D1\u5904\u7406\u80FD\u529B\uFF0C\u4F46\u8FD9\u91CC\u6709\u4E00\u4E2A\u8003\u70B9\u9700\u8981\u7279\u522B\u6CE8\u610F\uFF0C \u90A3\u5C31\u662F\u5728\u6269\u5BB9\u6D88\u8D39\u8005\u7684\u5B9E\u4F8B\u6570\u7684\u540C\u65F6\uFF0C\u5FC5\u987B\u540C\u6B65\u6269\u5BB9\u4E3B\u9898 Topic \u7684\u5206\u533A\u6570\u91CF\uFF0C\u786E\u4FDD\u6D88\u8D39\u8005\u7684\u5B9E\u4F8B\u6570\u548C\u5206\u533A\u6570\u76F8\u7B49\u3002\u5982\u679C\u6D88\u8D39\u8005\u7684\u5B9E\u4F8B\u6570\u8D85\u8FC7\u4E86\u5206\u533A\u6570\uFF0C\u7531\u4E8E\u5206\u533A\u662F\u5355\u7EBF\u7A0B\u6D88\u8D39\uFF0C\u6240\u4EE5\u8FD9\u6837\u7684\u6269\u5BB9\u5C31\u6CA1\u6709\u6548\u679C\u3002

\u6BD4\u5982\u5728 Kafka \u4E2D\uFF0C\u4E00\u4E2A Topic \u53EF\u4EE5\u914D\u7F6E\u591A\u4E2A Partition\uFF08\u5206\u533A\uFF09\uFF0C\u6570\u636E\u4F1A\u88AB\u5199\u5165\u5230\u591A\u4E2A\u5206\u533A\u4E2D\uFF0C\u4F46\u5728\u6D88\u8D39\u7684\u65F6\u5019\uFF0CKafka \u7EA6\u5B9A\u4E00\u4E2A\u5206\u533A\u53EA\u80FD\u88AB\u4E00\u4E2A\u6D88\u8D39\u8005\u6D88\u8D39\uFF0CTopic \u7684\u5206\u533A\u6570\u91CF\u51B3\u5B9A\u4E86\u6D88\u8D39\u7684\u80FD\u529B\uFF0C\u6240\u4EE5\uFF0C\u53EF\u4EE5\u901A\u8FC7\u589E\u52A0\u5206\u533A\u6765\u63D0\u9AD8\u6D88\u8D39\u8005\u7684\u5904\u7406\u80FD\u529B\u3002

\u603B\u7ED3

\u81F3\u6B64\uFF0C\u6211\u4EEC\u8BB2\u89E3\u4E86 MQ \u6D88\u606F\u961F\u5217\u7684\u70ED\u95E8\u95EE\u9898\u7684\u89E3\u51B3\u65B9\u6848\uFF0C\u65E0\u8BBA\u662F\u521D\u4E2D\u7EA7\u8FD8\u662F\u9AD8\u7EA7\u7814\u53D1\u5DE5\u7A0B\u5E08\uFF0C\u672C\u7BC7\u6587\u7AE0\u7684\u5185\u5BB9\u90FD\u662F\u4F60\u9700\u8981\u638C\u63E1\u7684\uFF0C\u4F60\u90FD\u53EF\u4EE5\u4ECE\u8FD9\u51E0\u70B9\u51FA\u53D1\uFF0C\u4E0E\u9762\u8BD5\u5B98\u8FDB\u884C\u53CB\u597D\u7684\u4EA4\u6D41\u3002\u6211\u6765\u603B\u7ED3\u4E00\u4E0B\u4ECA\u5929\u7684\u91CD\u70B9\u5185\u5BB9\u3002

  • \u5982\u4F55\u786E\u4FDD\u6D88\u606F\u4E0D\u4F1A\u4E22\u5931\uFF1F \u4F60\u8981\u77E5\u9053\u4E00\u6761\u6D88\u606F\u4ECE\u53D1\u9001\u5230\u6D88\u8D39\u7684\u6BCF\u4E2A\u9636\u6BB5\uFF0C\u662F\u5426\u5B58\u5728\u4E22\u6D88\u606F\uFF0C\u4EE5\u53CA\u5982\u4F55\u76D1\u63A7\u6D88\u606F\u662F\u5426\u4E22\u5931\uFF0C\u6700\u540E\u624D\u662F\u5982\u4F55\u89E3\u51B3\u95EE\u9898\uFF0C\u65B9\u6848\u53EF\u4EE5\u57FA\u4E8E\u201C MQ \u7684\u53EF\u9760\u6D88\u606F\u6295\u9012 \u201D\u7684\u65B9\u5F0F\u3002

  • \u5982\u4F55\u4FDD\u8BC1\u6D88\u606F\u4E0D\u88AB\u91CD\u590D\u6D88\u8D39\uFF1F \u5728\u8FDB\u884C\u6D88\u606F\u8865\u507F\u7684\u65F6\u5019\uFF0C\u4E00\u5B9A\u4F1A\u5B58\u5728\u91CD\u590D\u6D88\u606F\u7684\u60C5\u51B5\uFF0C\u90A3\u4E48\u5982\u4F55\u5B9E\u73B0\u6D88\u8D39\u7AEF\u7684\u5E42\u7B49\u6027\u5C31\u8FD9\u9053\u9898\u7684\u8003\u70B9\u3002

  • \u5982\u4F55\u5904\u7406\u6D88\u606F\u79EF\u538B\u95EE\u9898\uFF1F \u8FD9\u9053\u9898\u7684\u8003\u70B9\u5C31\u662F\u5982\u4F55\u901A\u8FC7 MQ \u5B9E\u73B0\u771F\u6B63\u7684\u9AD8\u6027\u80FD\uFF0C\u56DE\u7B54\u7684\u601D\u8DEF\u662F\uFF0C\u672C\u7740\u89E3\u51B3\u7EBF\u4E0A\u5F02\u5E38\u4E3A\u6700\u9AD8\u4F18\u5148\u7EA7\uFF0C\u7136\u540E\u901A\u8FC7\u76D1\u63A7\u548C\u65E5\u5FD7\u8FDB\u884C\u6392\u67E5\u5E76\u4F18\u5316\u4E1A\u52A1\u903B\u8F91\uFF0C\u6700\u540E\u662F\u6269\u5BB9\u6D88\u8D39\u7AEF\u548C\u5206\u7247\u7684\u6570\u91CF\u3002

\u5728\u56DE\u7B54\u95EE\u9898\u7684\u65F6\u5019\uFF0C\u4F60\u9700\u8981\u7279\u522B\u6CE8\u610F\u7684\u662F\uFF0C\u8BA9\u9762\u8BD5\u5B98\u4E86\u89E3\u5230\u4F60\u7684\u601D\u7EF4\u8FC7\u7A0B\uFF0C\u8FD9\u79CD\u89E3\u51B3\u95EE\u9898\u7684\u80FD\u529B\u662F\u9762\u8BD5\u5B98\u66F4\u4E3A\u770B\u4E2D\u7684\uFF0C\u6BD4\u4F60\u76F4\u63A5\u56DE\u7B54\u4E00\u9053\u9762\u8BD5\u9898\u66F4\u6709\u4EF7\u503C\u3002

\u53E6\u5916\uFF0C\u5982\u679C\u4F60\u5E94\u8058\u7684\u90E8\u95E8\u662F\u57FA\u7840\u67B6\u6784\u90E8\uFF0C\u90A3\u4E48\u9664\u4E86\u8981\u638C\u63E1\u672C\u8BB2\u4E2D\u7684\u5E38\u89C1\u95EE\u9898\u7684\u4E3B\u7EBF\u77E5\u8BC6\u4EE5\u5916\uFF0C\u8FD8\u8981\u638C\u63E1\u6D88\u606F\u4E2D\u95F4\u4EF6\u7684\u5176\u4ED6\u77E5\u8BC6\u4F53\u7CFB\uFF0C\u5982\uFF1A

  • \u5982\u4F55\u9009\u578B\u6D88\u606F\u4E2D\u95F4\u4EF6\uFF1F
  • \u6D88\u606F\u4E2D\u95F4\u4EF6\u4E2D\u7684\u961F\u5217\u6A21\u578B\u4E0E\u53D1\u5E03\u8BA2\u9605\u6A21\u578B\u7684\u533A\u522B\uFF1F
  • \u4E3A\u4EC0\u4E48\u6D88\u606F\u961F\u5217\u80FD\u5B9E\u73B0\u9AD8\u541E\u5410\uFF1F
  • \u5E8F\u5217\u5316\u3001\u4F20\u8F93\u534F\u8BAE\uFF0C\u4EE5\u53CA\u5185\u5B58\u7BA1\u7406\u7B49\u95EE\u9898
  • \u2026 >

\u539F\u6587\u94FE\u63A5\uFF1Ahttp://t.hk.uy/Ue6

',54),o=[i];function n(s,c){return p(),t("div",null,o)}var h=e(r,[["render",n],["__file","100-budiushi.html.vue"]]);export{h as default}; diff --git a/dist/assets/4-debug-skill.html.1e235b0a.js b/dist/assets/4-debug-skill.html.0c72ed75.js similarity index 99% rename from dist/assets/4-debug-skill.html.1e235b0a.js rename to dist/assets/4-debug-skill.html.0c72ed75.js index d7439722..77c9c1a3 100644 --- a/dist/assets/4-debug-skill.html.1e235b0a.js +++ b/dist/assets/4-debug-skill.html.0c72ed75.js @@ -1,4 +1,4 @@ -import{_ as s}from"./plugin-vue_export-helper.21dcd24c.js";import{r as t,o as i,c as o,a as e,b as c,e as p,d as n}from"./app.a0271b9c.js";const d={},l=p(`

4\u4E2A\u9AD8\u7EA7\u7684IntelliJ IDEA\u8C03\u8BD5\u6280\u5DE7

\u5927\u5BB6\u597D\uFF0C\u6211\u662F\u4E8C\u54E5\uFF01

\u4ECA\u5929\u7ED9\u5927\u5BB6\u5E26\u6765\u51E0\u4E2A\u6211\u65E5\u5E38\u5DE5\u4F5C\u4EE5\u53CA\u9605\u8BFB\u6E90\u7801\u5FC5\u5907\u7684 IntelliJ IDEA \u9AD8\u7EA7\u8C03\u8BD5\u6280\u5DE7\uFF0C\u5206\u5206\u949F\u8981\u8D77\u98DE\u7684\u8282\u594F\u3002

\u65AD\u70B9\u5904\u6DFB\u52A0 log

\u5F88\u591A\u7A0B\u5E8F\u5458\u5728\u8C03\u8BD5\u4EE3\u7801\u65F6\u90FD\u559C\u6B22\xA0print\xA0\u4E00\u4E9B\u5185\u5BB9\uFF0C\u8FD9\u6837\u770B\u8D77\u6765\u66F4\u76F4\u89C2\uFF0Cprint \u5B8C\u4E4B\u540E\u53C8\u5F88\u5BB9\u6613\u5FD8\u8BB0\u5220\u9664\u6389\u8FD9\u4E9B\u6CA1\u7528\u7684\u5185\u5BB9\uFF0C\u6700\u7EC8\u5C06\u4EE3\u7801\u63D0\u4EA4\u5230\xA0remote\uFF0Ccode review \u65F6\u53C8\u4E0D\u5F97\u4E0D\u5220\u51CF\u8FD9\u4E9B\u5185\u5BB9\u91CD\u65B0\u63D0\u4EA4\uFF0C\u4E0D\u4F46\u589E\u52A0\u4E0D\u5FC5\u8981\u7684\u5DE5\u4F5C\u91CF\uFF0C\u8FD8\u8BA9\xA0log tree\xA0\u7684\u4E00\u4E9B\u8282\u70B9\u6CA1\u6709\u4EFB\u4F55\u4EF7\u503C

IntelliJ IDEA \u63D0\u4F9B\xA0Evaluate and Log at Breakpoints\xA0\u529F\u80FD\u6070\u5DE7\u53EF\u4EE5\u5E2E\u52A9\u6211\u4EEC\u89E3\u51B3\u8FD9\u4E2A\u95EE\u9898, \u6765\u770B\u4E0B\u9762\u4EE3\u7801\uFF1A

public static void main(String[] args) {
+import{_ as s}from"./plugin-vue_export-helper.21dcd24c.js";import{r as t,o as i,c as o,a as e,b as c,e as p,d as n}from"./app.615e41d8.js";const d={},l=p(`

4\u4E2A\u9AD8\u7EA7\u7684IntelliJ IDEA\u8C03\u8BD5\u6280\u5DE7

\u5927\u5BB6\u597D\uFF0C\u6211\u662F\u4E8C\u54E5\uFF01

\u4ECA\u5929\u7ED9\u5927\u5BB6\u5E26\u6765\u51E0\u4E2A\u6211\u65E5\u5E38\u5DE5\u4F5C\u4EE5\u53CA\u9605\u8BFB\u6E90\u7801\u5FC5\u5907\u7684 IntelliJ IDEA \u9AD8\u7EA7\u8C03\u8BD5\u6280\u5DE7\uFF0C\u5206\u5206\u949F\u8981\u8D77\u98DE\u7684\u8282\u594F\u3002

\u65AD\u70B9\u5904\u6DFB\u52A0 log

\u5F88\u591A\u7A0B\u5E8F\u5458\u5728\u8C03\u8BD5\u4EE3\u7801\u65F6\u90FD\u559C\u6B22\xA0print\xA0\u4E00\u4E9B\u5185\u5BB9\uFF0C\u8FD9\u6837\u770B\u8D77\u6765\u66F4\u76F4\u89C2\uFF0Cprint \u5B8C\u4E4B\u540E\u53C8\u5F88\u5BB9\u6613\u5FD8\u8BB0\u5220\u9664\u6389\u8FD9\u4E9B\u6CA1\u7528\u7684\u5185\u5BB9\uFF0C\u6700\u7EC8\u5C06\u4EE3\u7801\u63D0\u4EA4\u5230\xA0remote\uFF0Ccode review \u65F6\u53C8\u4E0D\u5F97\u4E0D\u5220\u51CF\u8FD9\u4E9B\u5185\u5BB9\u91CD\u65B0\u63D0\u4EA4\uFF0C\u4E0D\u4F46\u589E\u52A0\u4E0D\u5FC5\u8981\u7684\u5DE5\u4F5C\u91CF\uFF0C\u8FD8\u8BA9\xA0log tree\xA0\u7684\u4E00\u4E9B\u8282\u70B9\u6CA1\u6709\u4EFB\u4F55\u4EF7\u503C

IntelliJ IDEA \u63D0\u4F9B\xA0Evaluate and Log at Breakpoints\xA0\u529F\u80FD\u6070\u5DE7\u53EF\u4EE5\u5E2E\u52A9\u6211\u4EEC\u89E3\u51B3\u8FD9\u4E2A\u95EE\u9898, \u6765\u770B\u4E0B\u9762\u4EE3\u7801\uFF1A

public static void main(String[] args) {
   ThreadLocalRandom random = ThreadLocalRandom.current();
   int count = 0;
   for (int i = 0; i < 5; i++) {
diff --git a/dist/assets/40-interview.html.cb9b99de.js b/dist/assets/40-interview.html.e460eeeb.js
similarity index 99%
rename from dist/assets/40-interview.html.cb9b99de.js
rename to dist/assets/40-interview.html.e460eeeb.js
index 9253cbc4..4ba2f4cc 100644
--- a/dist/assets/40-interview.html.cb9b99de.js
+++ b/dist/assets/40-interview.html.e460eeeb.js
@@ -1,4 +1,4 @@
-import{_ as e}from"./plugin-vue_export-helper.21dcd24c.js";import{o as i,c as n,e as a}from"./app.a0271b9c.js";const d={},s=a(`

Nginx\uFF1A40\u9053\u7CBE\u9009\u9762\u8BD5\u9898\u5FC5\u770B\u{1F44D}

\u5927\u5BB6\u597D\uFF0C\u6211\u662F\u4E8C\u54E5\u5440\uFF01\u90A3\u5929\uFF0C\u6211\u5F92\u5F1F\u5C0F\u4E8C\u5077\u5077\u6478\u6478\u8DD1\u53BB\u4E86\u4E00\u5BB6\u516C\u53F8\u9762\u8BD5\uFF0C\u7ED3\u679C\u56DE\u6765\u7ED9\u6211\u8BF4\u5728 Nginx \u4E0A\u8DEA\u4E86\uFF0C\u95EE\u6211\u8BE5\u600E\u4E48\u529E\uFF1F

\u6211\u5148\u662F\u6BEB\u4E0D\u7559\u60C5\u5730\u6279\u8BC4\u4E86\u4ED6\uFF0C\u600E\u4E48\u80FD\u80CC\u7740\u9886\u5BFC\u53BB\u9762\u8BD5\u5462\uFF1F\u4E0D\u8FC7\uFF0C\u770B\u7740\u5C0F\u4E8C\u96BE\u8FC7\u7684\u8868\u60C5\uFF0C\u6211\u8FD8\u662F\u4E8E\u5FC3\u4E0D\u5FCD\uFF0C\u4E8E\u662F\u7ED9\u4ED6\u6574\u7406\u4E86 40 \u9053 Nginx \u7684\u9762\u8BD5\u9898\uFF0C\u5E0C\u671B\u80FD\u5E2E\u4ED6\u4E00\u628A\u3002

  • \u4EC0\u4E48\u662FNginx\uFF1F
  • Nginx \u6709\u54EA\u4E9B\u4F18\u70B9\uFF1F
  • Nginx\u5E94\u7528\u573A\u666F\uFF1F
  • Nginx\u600E\u4E48\u5904\u7406\u8BF7\u6C42\u7684\uFF1F
  • Nginx \u662F\u5982\u4F55\u5B9E\u73B0\u9AD8\u5E76\u53D1\u7684\uFF1F
  • \u4EC0\u4E48\u662F\u6B63\u5411\u4EE3\u7406\uFF1F
  • \u4EC0\u4E48\u662F\u53CD\u5411\u4EE3\u7406\uFF1F
  • \u53CD\u5411\u4EE3\u7406\u670D\u52A1\u5668\u7684\u4F18\u70B9\u662F\u4EC0\u4E48?
  • Nginx\u76EE\u5F55\u7ED3\u6784\u6709\u54EA\u4E9B\uFF1F
  • Nginx\u914D\u7F6E\u6587\u4EF6nginx.conf\u6709\u54EA\u4E9B\u5C5E\u6027\u6A21\u5757?
  • cookie\u548Csession\u533A\u522B\uFF1F
  • \u4E3A\u4EC0\u4E48 Nginx \u4E0D\u4F7F\u7528\u591A\u7EBF\u7A0B\uFF1F
  • nginx\u548Capache\u7684\u533A\u522B
  • \u4EC0\u4E48\u662F\u52A8\u6001\u8D44\u6E90\u3001\u9759\u6001\u8D44\u6E90\u5206\u79BB\uFF1F
  • \u4E3A\u4EC0\u4E48\u8981\u505A\u52A8\u3001\u9759\u5206\u79BB\uFF1F
  • \u4EC0\u4E48\u53EB CDN \u670D\u52A1\uFF1F
  • Nginx\u600E\u4E48\u505A\u7684\u52A8\u9759\u5206\u79BB\uFF1F
  • Nginx\u8D1F\u8F7D\u5747\u8861\u7684\u7B97\u6CD5\u600E\u4E48\u5B9E\u73B0\u7684?\u7B56\u7565\u6709\u54EA\u4E9B?
  • \u5982\u4F55\u7528Nginx\u89E3\u51B3\u524D\u7AEF\u8DE8\u57DF\u95EE\u9898\uFF1F
  • Nginx\u865A\u62DF\u4E3B\u673A\u600E\u4E48\u914D\u7F6E?
  • location\u7684\u4F5C\u7528\u662F\u4EC0\u4E48\uFF1F
  • \u9650\u6D41\u600E\u4E48\u505A\u7684\uFF1F
  • \u6F0F\u6876\u6D41\u7B97\u6CD5\u548C\u4EE4\u724C\u6876\u7B97\u6CD5\u77E5\u9053\uFF1F
  • Nginx\u914D\u7F6E\u9AD8\u53EF\u7528\u6027\u600E\u4E48\u914D\u7F6E\uFF1F
  • Nginx\u600E\u4E48\u5224\u65AD\u522BIP\u4E0D\u53EF\u8BBF\u95EE\uFF1F
  • \u5728nginx\u4E2D\uFF0C\u5982\u4F55\u4F7F\u7528\u672A\u5B9A\u4E49\u7684\u670D\u52A1\u5668\u540D\u79F0\u6765\u963B\u6B62\u5904\u7406\u8BF7\u6C42\uFF1F
  • \u600E\u4E48\u9650\u5236\u6D4F\u89C8\u5668\u8BBF\u95EE\uFF1F
  • Rewrite\u5168\u5C40\u53D8\u91CF\u662F\u4EC0\u4E48\uFF1F
  • Nginx \u5982\u4F55\u5B9E\u73B0\u540E\u7AEF\u670D\u52A1\u7684\u5065\u5EB7\u68C0\u67E5\uFF1F
  • Nginx \u5982\u4F55\u5F00\u542F\u538B\u7F29\uFF1F
  • ngx_http_upstream_module\u7684\u4F5C\u7528\u662F\u4EC0\u4E48?
  • \u4EC0\u4E48\u662FC10K\u95EE\u9898?
  • Nginx\u662F\u5426\u652F\u6301\u5C06\u8BF7\u6C42\u538B\u7F29\u5230\u4E0A\u6E38?
  • \u5982\u4F55\u5728Nginx\u4E2D\u83B7\u5F97\u5F53\u524D\u7684\u65F6\u95F4?
  • \u7528Nginx\u670D\u52A1\u5668\u89E3\u91CA-s\u7684\u76EE\u7684\u662F\u4EC0\u4E48?
  • \u5982\u4F55\u5728Nginx\u670D\u52A1\u5668\u4E0A\u6DFB\u52A0\u6A21\u5757?
  • \u751F\u4EA7\u4E2D\u5982\u4F55\u8BBE\u7F6Eworker\u8FDB\u7A0B\u7684\u6570\u91CF\u5462\uFF1F
  • nginx\u72B6\u6001\u7801


\u4EC0\u4E48\u662FNginx\uFF1F

Nginx\u662F\u4E00\u4E2A \u8F7B\u91CF\u7EA7/\u9AD8\u6027\u80FD\u7684\u53CD\u5411\u4EE3\u7406Web\u670D\u52A1\u5668\uFF0C\u7528\u4E8E HTTP\u3001HTTPS\u3001SMTP\u3001POP3 \u548C IMAP \u534F\u8BAE\u3002\u4ED6\u5B9E\u73B0\u975E\u5E38\u9AD8\u6548\u7684\u53CD\u5411\u4EE3\u7406\u3001\u8D1F\u8F7D\u5E73\u8861\uFF0C\u4ED6\u53EF\u4EE5\u5904\u74062-3\u4E07\u5E76\u53D1\u8FDE\u63A5\u6570\uFF0C\u5B98\u65B9\u76D1\u6D4B\u80FD\u652F\u63015\u4E07\u5E76\u53D1\uFF0C\u73B0\u5728\u4E2D\u56FD\u4F7F\u7528nginx\u7F51\u7AD9\u7528\u6237\u6709\u5F88\u591A\uFF0C\u4F8B\u5982\uFF1A\u65B0\u6D6A\u3001\u7F51\u6613\u3001 \u817E\u8BAF\u7B49\u3002

Nginx \u6709\u54EA\u4E9B\u4F18\u70B9\uFF1F

  • \u8DE8\u5E73\u53F0\u3001\u914D\u7F6E\u7B80\u5355\u3002
  • \u975E\u963B\u585E\u3001\u9AD8\u5E76\u53D1\u8FDE\u63A5\uFF1A\u5904\u7406 2-3 \u4E07\u5E76\u53D1\u8FDE\u63A5\u6570\uFF0C\u5B98\u65B9\u76D1\u6D4B\u80FD\u652F\u6301 5 \u4E07\u5E76\u53D1\u3002
  • \u5185\u5B58\u6D88\u8017\u5C0F\uFF1A\u5F00\u542F 10 \u4E2A Nginx \u624D\u5360 150M \u5185\u5B58\u3002
  • \u6210\u672C\u4F4E\u5EC9\uFF0C\u4E14\u5F00\u6E90\u3002
  • \u7A33\u5B9A\u6027\u9AD8\uFF0C\u5B95\u673A\u7684\u6982\u7387\u975E\u5E38\u5C0F\u3002
  • \u5185\u7F6E\u7684\u5065\u5EB7\u68C0\u67E5\u529F\u80FD\uFF1A\u5982\u679C\u6709\u4E00\u4E2A\u670D\u52A1\u5668\u5B95\u673A\uFF0C\u4F1A\u505A\u4E00\u4E2A\u5065\u5EB7\u68C0\u67E5\uFF0C\u518D\u53D1\u9001\u7684\u8BF7\u6C42\u5C31\u4E0D\u4F1A\u53D1\u9001\u5230\u5B95\u673A\u7684\u670D\u52A1\u5668\u4E86\u3002\u91CD\u65B0\u5C06\u8BF7\u6C42\u63D0\u4EA4\u5230\u5176\u4ED6\u7684\u8282\u70B9\u4E0A

Nginx\u5E94\u7528\u573A\u666F\uFF1F

  • http\u670D\u52A1\u5668\u3002Nginx\u662F\u4E00\u4E2Ahttp\u670D\u52A1\u53EF\u4EE5\u72EC\u7ACB\u63D0\u4F9Bhttp\u670D\u52A1\u3002\u53EF\u4EE5\u505A\u7F51\u9875\u9759\u6001\u670D\u52A1\u5668\u3002
  • \u865A\u62DF\u4E3B\u673A\u3002\u53EF\u4EE5\u5B9E\u73B0\u5728\u4E00\u53F0\u670D\u52A1\u5668\u865A\u62DF\u51FA\u591A\u4E2A\u7F51\u7AD9\uFF0C\u4F8B\u5982\u4E2A\u4EBA\u7F51\u7AD9\u4F7F\u7528\u7684\u865A\u62DF\u673A\u3002
  • \u53CD\u5411\u4EE3\u7406\uFF0C\u8D1F\u8F7D\u5747\u8861\u3002\u5F53\u7F51\u7AD9\u7684\u8BBF\u95EE\u91CF\u8FBE\u5230\u4E00\u5B9A\u7A0B\u5EA6\u540E\uFF0C\u5355\u53F0\u670D\u52A1\u5668\u4E0D\u80FD\u6EE1\u8DB3\u7528\u6237\u7684\u8BF7\u6C42\u65F6\uFF0C\u9700\u8981\u7528\u591A\u53F0\u670D\u52A1\u5668\u96C6\u7FA4\u53EF\u4EE5\u4F7F\u7528nginx\u505A\u53CD\u5411\u4EE3\u7406\u3002\u5E76\u4E14\u591A\u53F0\u670D\u52A1\u5668\u53EF\u4EE5\u5E73\u5747\u5206\u62C5\u8D1F\u8F7D\uFF0C\u4E0D\u4F1A\u5E94\u4E3A\u67D0\u53F0\u670D\u52A1\u5668\u8D1F\u8F7D\u9AD8\u5B95\u673A\u800C\u67D0\u53F0\u670D\u52A1\u5668\u95F2\u7F6E\u7684\u60C5\u51B5\u3002
  • nginz \u4E2D\u4E5F\u53EF\u4EE5\u914D\u7F6E\u5B89\u5168\u7BA1\u7406\u3001\u6BD4\u5982\u53EF\u4EE5\u4F7F\u7528Nginx\u642D\u5EFAAPI\u63A5\u53E3\u7F51\u5173,\u5BF9\u6BCF\u4E2A\u63A5\u53E3\u670D\u52A1\u8FDB\u884C\u62E6\u622A\u3002

Nginx\u600E\u4E48\u5904\u7406\u8BF7\u6C42\u7684\uFF1F

server {         # \u7B2C\u4E00\u4E2AServer\u533A\u5757\u5F00\u59CB\uFF0C\u8868\u793A\u4E00\u4E2A\u72EC\u7ACB\u7684\u865A\u62DF\u4E3B\u673A\u7AD9\u70B9
+import{_ as e}from"./plugin-vue_export-helper.21dcd24c.js";import{o as i,c as n,e as a}from"./app.615e41d8.js";const d={},s=a(`

Nginx\uFF1A40\u9053\u7CBE\u9009\u9762\u8BD5\u9898\u5FC5\u770B\u{1F44D}

\u5927\u5BB6\u597D\uFF0C\u6211\u662F\u4E8C\u54E5\u5440\uFF01\u90A3\u5929\uFF0C\u6211\u5F92\u5F1F\u5C0F\u4E8C\u5077\u5077\u6478\u6478\u8DD1\u53BB\u4E86\u4E00\u5BB6\u516C\u53F8\u9762\u8BD5\uFF0C\u7ED3\u679C\u56DE\u6765\u7ED9\u6211\u8BF4\u5728 Nginx \u4E0A\u8DEA\u4E86\uFF0C\u95EE\u6211\u8BE5\u600E\u4E48\u529E\uFF1F

\u6211\u5148\u662F\u6BEB\u4E0D\u7559\u60C5\u5730\u6279\u8BC4\u4E86\u4ED6\uFF0C\u600E\u4E48\u80FD\u80CC\u7740\u9886\u5BFC\u53BB\u9762\u8BD5\u5462\uFF1F\u4E0D\u8FC7\uFF0C\u770B\u7740\u5C0F\u4E8C\u96BE\u8FC7\u7684\u8868\u60C5\uFF0C\u6211\u8FD8\u662F\u4E8E\u5FC3\u4E0D\u5FCD\uFF0C\u4E8E\u662F\u7ED9\u4ED6\u6574\u7406\u4E86 40 \u9053 Nginx \u7684\u9762\u8BD5\u9898\uFF0C\u5E0C\u671B\u80FD\u5E2E\u4ED6\u4E00\u628A\u3002

  • \u4EC0\u4E48\u662FNginx\uFF1F
  • Nginx \u6709\u54EA\u4E9B\u4F18\u70B9\uFF1F
  • Nginx\u5E94\u7528\u573A\u666F\uFF1F
  • Nginx\u600E\u4E48\u5904\u7406\u8BF7\u6C42\u7684\uFF1F
  • Nginx \u662F\u5982\u4F55\u5B9E\u73B0\u9AD8\u5E76\u53D1\u7684\uFF1F
  • \u4EC0\u4E48\u662F\u6B63\u5411\u4EE3\u7406\uFF1F
  • \u4EC0\u4E48\u662F\u53CD\u5411\u4EE3\u7406\uFF1F
  • \u53CD\u5411\u4EE3\u7406\u670D\u52A1\u5668\u7684\u4F18\u70B9\u662F\u4EC0\u4E48?
  • Nginx\u76EE\u5F55\u7ED3\u6784\u6709\u54EA\u4E9B\uFF1F
  • Nginx\u914D\u7F6E\u6587\u4EF6nginx.conf\u6709\u54EA\u4E9B\u5C5E\u6027\u6A21\u5757?
  • cookie\u548Csession\u533A\u522B\uFF1F
  • \u4E3A\u4EC0\u4E48 Nginx \u4E0D\u4F7F\u7528\u591A\u7EBF\u7A0B\uFF1F
  • nginx\u548Capache\u7684\u533A\u522B
  • \u4EC0\u4E48\u662F\u52A8\u6001\u8D44\u6E90\u3001\u9759\u6001\u8D44\u6E90\u5206\u79BB\uFF1F
  • \u4E3A\u4EC0\u4E48\u8981\u505A\u52A8\u3001\u9759\u5206\u79BB\uFF1F
  • \u4EC0\u4E48\u53EB CDN \u670D\u52A1\uFF1F
  • Nginx\u600E\u4E48\u505A\u7684\u52A8\u9759\u5206\u79BB\uFF1F
  • Nginx\u8D1F\u8F7D\u5747\u8861\u7684\u7B97\u6CD5\u600E\u4E48\u5B9E\u73B0\u7684?\u7B56\u7565\u6709\u54EA\u4E9B?
  • \u5982\u4F55\u7528Nginx\u89E3\u51B3\u524D\u7AEF\u8DE8\u57DF\u95EE\u9898\uFF1F
  • Nginx\u865A\u62DF\u4E3B\u673A\u600E\u4E48\u914D\u7F6E?
  • location\u7684\u4F5C\u7528\u662F\u4EC0\u4E48\uFF1F
  • \u9650\u6D41\u600E\u4E48\u505A\u7684\uFF1F
  • \u6F0F\u6876\u6D41\u7B97\u6CD5\u548C\u4EE4\u724C\u6876\u7B97\u6CD5\u77E5\u9053\uFF1F
  • Nginx\u914D\u7F6E\u9AD8\u53EF\u7528\u6027\u600E\u4E48\u914D\u7F6E\uFF1F
  • Nginx\u600E\u4E48\u5224\u65AD\u522BIP\u4E0D\u53EF\u8BBF\u95EE\uFF1F
  • \u5728nginx\u4E2D\uFF0C\u5982\u4F55\u4F7F\u7528\u672A\u5B9A\u4E49\u7684\u670D\u52A1\u5668\u540D\u79F0\u6765\u963B\u6B62\u5904\u7406\u8BF7\u6C42\uFF1F
  • \u600E\u4E48\u9650\u5236\u6D4F\u89C8\u5668\u8BBF\u95EE\uFF1F
  • Rewrite\u5168\u5C40\u53D8\u91CF\u662F\u4EC0\u4E48\uFF1F
  • Nginx \u5982\u4F55\u5B9E\u73B0\u540E\u7AEF\u670D\u52A1\u7684\u5065\u5EB7\u68C0\u67E5\uFF1F
  • Nginx \u5982\u4F55\u5F00\u542F\u538B\u7F29\uFF1F
  • ngx_http_upstream_module\u7684\u4F5C\u7528\u662F\u4EC0\u4E48?
  • \u4EC0\u4E48\u662FC10K\u95EE\u9898?
  • Nginx\u662F\u5426\u652F\u6301\u5C06\u8BF7\u6C42\u538B\u7F29\u5230\u4E0A\u6E38?
  • \u5982\u4F55\u5728Nginx\u4E2D\u83B7\u5F97\u5F53\u524D\u7684\u65F6\u95F4?
  • \u7528Nginx\u670D\u52A1\u5668\u89E3\u91CA-s\u7684\u76EE\u7684\u662F\u4EC0\u4E48?
  • \u5982\u4F55\u5728Nginx\u670D\u52A1\u5668\u4E0A\u6DFB\u52A0\u6A21\u5757?
  • \u751F\u4EA7\u4E2D\u5982\u4F55\u8BBE\u7F6Eworker\u8FDB\u7A0B\u7684\u6570\u91CF\u5462\uFF1F
  • nginx\u72B6\u6001\u7801


\u4EC0\u4E48\u662FNginx\uFF1F

Nginx\u662F\u4E00\u4E2A \u8F7B\u91CF\u7EA7/\u9AD8\u6027\u80FD\u7684\u53CD\u5411\u4EE3\u7406Web\u670D\u52A1\u5668\uFF0C\u7528\u4E8E HTTP\u3001HTTPS\u3001SMTP\u3001POP3 \u548C IMAP \u534F\u8BAE\u3002\u4ED6\u5B9E\u73B0\u975E\u5E38\u9AD8\u6548\u7684\u53CD\u5411\u4EE3\u7406\u3001\u8D1F\u8F7D\u5E73\u8861\uFF0C\u4ED6\u53EF\u4EE5\u5904\u74062-3\u4E07\u5E76\u53D1\u8FDE\u63A5\u6570\uFF0C\u5B98\u65B9\u76D1\u6D4B\u80FD\u652F\u63015\u4E07\u5E76\u53D1\uFF0C\u73B0\u5728\u4E2D\u56FD\u4F7F\u7528nginx\u7F51\u7AD9\u7528\u6237\u6709\u5F88\u591A\uFF0C\u4F8B\u5982\uFF1A\u65B0\u6D6A\u3001\u7F51\u6613\u3001 \u817E\u8BAF\u7B49\u3002

Nginx \u6709\u54EA\u4E9B\u4F18\u70B9\uFF1F

  • \u8DE8\u5E73\u53F0\u3001\u914D\u7F6E\u7B80\u5355\u3002
  • \u975E\u963B\u585E\u3001\u9AD8\u5E76\u53D1\u8FDE\u63A5\uFF1A\u5904\u7406 2-3 \u4E07\u5E76\u53D1\u8FDE\u63A5\u6570\uFF0C\u5B98\u65B9\u76D1\u6D4B\u80FD\u652F\u6301 5 \u4E07\u5E76\u53D1\u3002
  • \u5185\u5B58\u6D88\u8017\u5C0F\uFF1A\u5F00\u542F 10 \u4E2A Nginx \u624D\u5360 150M \u5185\u5B58\u3002
  • \u6210\u672C\u4F4E\u5EC9\uFF0C\u4E14\u5F00\u6E90\u3002
  • \u7A33\u5B9A\u6027\u9AD8\uFF0C\u5B95\u673A\u7684\u6982\u7387\u975E\u5E38\u5C0F\u3002
  • \u5185\u7F6E\u7684\u5065\u5EB7\u68C0\u67E5\u529F\u80FD\uFF1A\u5982\u679C\u6709\u4E00\u4E2A\u670D\u52A1\u5668\u5B95\u673A\uFF0C\u4F1A\u505A\u4E00\u4E2A\u5065\u5EB7\u68C0\u67E5\uFF0C\u518D\u53D1\u9001\u7684\u8BF7\u6C42\u5C31\u4E0D\u4F1A\u53D1\u9001\u5230\u5B95\u673A\u7684\u670D\u52A1\u5668\u4E86\u3002\u91CD\u65B0\u5C06\u8BF7\u6C42\u63D0\u4EA4\u5230\u5176\u4ED6\u7684\u8282\u70B9\u4E0A

Nginx\u5E94\u7528\u573A\u666F\uFF1F

  • http\u670D\u52A1\u5668\u3002Nginx\u662F\u4E00\u4E2Ahttp\u670D\u52A1\u53EF\u4EE5\u72EC\u7ACB\u63D0\u4F9Bhttp\u670D\u52A1\u3002\u53EF\u4EE5\u505A\u7F51\u9875\u9759\u6001\u670D\u52A1\u5668\u3002
  • \u865A\u62DF\u4E3B\u673A\u3002\u53EF\u4EE5\u5B9E\u73B0\u5728\u4E00\u53F0\u670D\u52A1\u5668\u865A\u62DF\u51FA\u591A\u4E2A\u7F51\u7AD9\uFF0C\u4F8B\u5982\u4E2A\u4EBA\u7F51\u7AD9\u4F7F\u7528\u7684\u865A\u62DF\u673A\u3002
  • \u53CD\u5411\u4EE3\u7406\uFF0C\u8D1F\u8F7D\u5747\u8861\u3002\u5F53\u7F51\u7AD9\u7684\u8BBF\u95EE\u91CF\u8FBE\u5230\u4E00\u5B9A\u7A0B\u5EA6\u540E\uFF0C\u5355\u53F0\u670D\u52A1\u5668\u4E0D\u80FD\u6EE1\u8DB3\u7528\u6237\u7684\u8BF7\u6C42\u65F6\uFF0C\u9700\u8981\u7528\u591A\u53F0\u670D\u52A1\u5668\u96C6\u7FA4\u53EF\u4EE5\u4F7F\u7528nginx\u505A\u53CD\u5411\u4EE3\u7406\u3002\u5E76\u4E14\u591A\u53F0\u670D\u52A1\u5668\u53EF\u4EE5\u5E73\u5747\u5206\u62C5\u8D1F\u8F7D\uFF0C\u4E0D\u4F1A\u5E94\u4E3A\u67D0\u53F0\u670D\u52A1\u5668\u8D1F\u8F7D\u9AD8\u5B95\u673A\u800C\u67D0\u53F0\u670D\u52A1\u5668\u95F2\u7F6E\u7684\u60C5\u51B5\u3002
  • nginz \u4E2D\u4E5F\u53EF\u4EE5\u914D\u7F6E\u5B89\u5168\u7BA1\u7406\u3001\u6BD4\u5982\u53EF\u4EE5\u4F7F\u7528Nginx\u642D\u5EFAAPI\u63A5\u53E3\u7F51\u5173,\u5BF9\u6BCF\u4E2A\u63A5\u53E3\u670D\u52A1\u8FDB\u884C\u62E6\u622A\u3002

Nginx\u600E\u4E48\u5904\u7406\u8BF7\u6C42\u7684\uFF1F

server {         # \u7B2C\u4E00\u4E2AServer\u533A\u5757\u5F00\u59CB\uFF0C\u8868\u793A\u4E00\u4E2A\u72EC\u7ACB\u7684\u865A\u62DF\u4E3B\u673A\u7AD9\u70B9
    listen       80\uFF1B # \u63D0\u4F9B\u670D\u52A1\u7684\u7AEF\u53E3\uFF0C\u9ED8\u8BA480
    server_name  localhost; # \u63D0\u4F9B\u670D\u52A1\u7684\u57DF\u540D\u4E3B\u673A\u540D
    location / { # \u7B2C\u4E00\u4E2Alocation\u533A\u5757\u5F00\u59CB
diff --git a/dist/assets/404.5ae72665.js b/dist/assets/404.c61acaed.js
similarity index 98%
rename from dist/assets/404.5ae72665.js
rename to dist/assets/404.c61acaed.js
index b15ce64d..e376579c 100644
--- a/dist/assets/404.5ae72665.js
+++ b/dist/assets/404.c61acaed.js
@@ -1 +1 @@
-import{h as t,f as s,u as i,g as f,i as c,r as p}from"./app.a0271b9c.js";import{S as d}from"./SkipLink.e761490e.js";const h=()=>t("svg",{xmlns:"http://www.w3.org/2000/svg",class:"page-404-icon",viewBox:"0 0 178 130",innerHTML:''});var u=s({name:"404",setup(){var a;const l=i(),o=f(),n=()=>{const e=o.value.routeLocales["404msg"];return e[Math.floor(Math.random()*e.length)]},{navigate:r}=c({to:(a=o.value.home)!=null?a:l.value});return()=>[t(d),t(p("CommonWrapper"),{sidebar:!1},()=>t("main",{class:"page not-found",id:"main-content"},[t(h),t("blockquote",n()),t("button",{class:"action-button",onClick:()=>{window.history.go(-1)}},o.value.routeLocales.back),t("button",{class:"action-button",onClick:()=>r()},o.value.routeLocales.home)]))]}});export{u as default};
+import{h as t,f as s,u as i,g as f,i as c,r as p}from"./app.615e41d8.js";import{S as d}from"./SkipLink.a2c3a90f.js";const h=()=>t("svg",{xmlns:"http://www.w3.org/2000/svg",class:"page-404-icon",viewBox:"0 0 178 130",innerHTML:''});var u=s({name:"404",setup(){var a;const l=i(),o=f(),n=()=>{const e=o.value.routeLocales["404msg"];return e[Math.floor(Math.random()*e.length)]},{navigate:r}=c({to:(a=o.value.home)!=null?a:l.value});return()=>[t(d),t(p("CommonWrapper"),{sidebar:!1},()=>t("main",{class:"page not-found",id:"main-content"},[t(h),t("blockquote",n()),t("button",{class:"action-button",onClick:()=>{window.history.go(-1)}},o.value.routeLocales.back),t("button",{class:"action-button",onClick:()=>r()},o.value.routeLocales.home)]))]}});export{u as default};
diff --git a/dist/assets/404.html.5c274669.js b/dist/assets/404.html.6cb935de.js
similarity index 71%
rename from dist/assets/404.html.5c274669.js
rename to dist/assets/404.html.6cb935de.js
index a365e3c8..795a0132 100644
--- a/dist/assets/404.html.5c274669.js
+++ b/dist/assets/404.html.6cb935de.js
@@ -1 +1 @@
-import{_ as e}from"./plugin-vue_export-helper.21dcd24c.js";import{o as r,c as t}from"./app.a0271b9c.js";const _={};function c(o,a){return r(),t("div")}var m=e(_,[["render",c],["__file","404.html.vue"]]);export{m as default};
+import{_ as e}from"./plugin-vue_export-helper.21dcd24c.js";import{o as r,c as t}from"./app.615e41d8.js";const _={};function c(o,a){return r(),t("div")}var m=e(_,[["render",c],["__file","404.html.vue"]]);export{m as default};
diff --git a/dist/assets/48-keywords.html.34eb30fe.js b/dist/assets/48-keywords.html.c30c9b30.js
similarity index 98%
rename from dist/assets/48-keywords.html.34eb30fe.js
rename to dist/assets/48-keywords.html.c30c9b30.js
index c798242b..2ab1a67e 100644
--- a/dist/assets/48-keywords.html.34eb30fe.js
+++ b/dist/assets/48-keywords.html.c30c9b30.js
@@ -1 +1 @@
-import{_ as i}from"./plugin-vue_export-helper.21dcd24c.js";import{r as l,o as r,c as p,a as t,b as e,d as o,e as n}from"./app.a0271b9c.js";const g={},a=t("h1",{id:"java\u4E2D\u5E38\u7528\u768448\u4E2A\u5173\u952E\u5B57",tabindex:"-1"},[t("a",{class:"header-anchor",href:"#java\u4E2D\u5E38\u7528\u768448\u4E2A\u5173\u952E\u5B57","aria-hidden":"true"},"#"),o(" Java\u4E2D\u5E38\u7528\u768448\u4E2A\u5173\u952E\u5B57")],-1),c=t("p",null,"\u201C\u4E8C\u54E5\uFF0C\u5C31\u6211\u4E4B\u524D\u5B66\u8FC7\u7684\u8FD9\u4E9B Java \u4EE3\u7801\u4E2D\uFF0C\u6709 public\u3001static\u3001void\u3001main \u7B49\u7B49\uFF0C\u5B83\u4EEC\u5E94\u8BE5\u90FD\u662F\u5173\u952E\u5B57\u5427\uFF1F\u201D\u4E09\u59B9\u7684\u8138\u4E0A\u6CDB\u7740\u751C\u751C\u7684\u7B11\u5BB9\uFF0C\u6211\u60F3\u5979\u5728\u5B66\u4E60 Java \u65B9\u9762\u5DF2\u7ECF\u53D8\u5F97\u8D8A\u6765\u8D8A\u81EA\u4FE1\u4E86\u3002",-1),d=t("p",null,"\u201C\u662F\u7684\uFF0C\u4E09\u59B9\u3002Java \u4E2D\u7684\u5173\u952E\u5B57\u53EF\u4E0D\u5C11\u5462\uFF01\u4F60\u4E00\u4E0B\u5B50\u53EF\u80FD\u8BB0\u4E0D\u4E86\u90A3\u4E48\u591A\uFF0C\u4E0D\u8FC7\uFF0C\u5148\u4FDD\u7559\u4E2A\u5370\u8C61\u5427\uFF0C\u5BF9\u4EE5\u540E\u7684\u5B66\u4E60\u4F1A\u5F88\u6709\u5E2E\u52A9\u3002\u201D",-1),_=t("p",null,"PS\uFF1A\u6309\u7167\u9996\u5B57\u6BCD\u7684\u81EA\u7136\u987A\u5E8F\u6392\u5217\u3002",-1),h=n("
  • abstract\uFF1A \u7528\u4E8E\u58F0\u660E\u62BD\u8C61\u7C7B\uFF0C\u4EE5\u53CA\u62BD\u8C61\u65B9\u6CD5\u3002

  • boolean\uFF1A \u7528\u4E8E\u5C06\u53D8\u91CF\u58F0\u660E\u4E3A\u5E03\u5C14\u503C\u7C7B\u578B\uFF0C\u53EA\u6709 true \u548C false \u4E24\u4E2A\u503C\u3002

  • break\uFF1A \u7528\u4E8E\u4E2D\u65AD\u5FAA\u73AF\u6216 switch \u8BED\u53E5\u3002

  • byte\uFF1A \u7528\u4E8E\u58F0\u660E\u4E00\u4E2A\u53EF\u4EE5\u5BB9\u7EB3 8 \u4E2A\u6BD4\u7279\u7684\u53D8\u91CF\u3002

  • case\uFF1A \u7528\u4E8E\u5728 switch \u8BED\u53E5\u4E2D\u6807\u8BB0\u6761\u4EF6\u7684\u503C\u3002

  • catch\uFF1A \u7528\u4E8E\u6355\u83B7 try \u8BED\u53E5\u4E2D\u7684\u5F02\u5E38\u3002

  • ",6),u=t("strong",null,"char\uFF1A",-1),f=o(" \u7528\u4E8E\u58F0\u660E\u4E00\u4E2A\u53EF\u4EE5\u5BB9\u7EB3\u65E0\u7B26\u53F7 16 \u4F4D\u6BD4\u7279\u7684 "),m={href:"https://mp.weixin.qq.com/s/pNQjlXOivIgO3pbYc0GnpA",target:"_blank",rel:"noopener noreferrer"},v=o("Unicode \u5B57\u7B26"),b=o("\u7684\u53D8\u91CF\u3002"),w=n("
  • class\uFF1A \u7528\u4E8E\u58F0\u660E\u4E00\u4E2A\u7C7B\u3002

  • continue\uFF1A \u7528\u4E8E\u7EE7\u7EED\u4E0B\u4E00\u4E2A\u5FAA\u73AF\uFF0C\u53EF\u4EE5\u5728\u6307\u5B9A\u6761\u4EF6\u4E0B\u8DF3\u8FC7\u5176\u4F59\u4EE3\u7801\u3002

  • default\uFF1A \u7528\u4E8E\u6307\u5B9A switch \u8BED\u53E5\u4E2D\u9664\u53BB case \u6761\u4EF6\u4E4B\u5916\u7684\u9ED8\u8BA4\u4EE3\u7801\u5757\u3002

  • do\uFF1A \u901A\u5E38\u548C while \u5173\u952E\u5B57\u914D\u5408\u4F7F\u7528\uFF0Cdo \u540E\u7D27\u8DDF\u5FAA\u73AF\u4F53\u3002

  • double\uFF1A \u7528\u4E8E\u58F0\u660E\u4E00\u4E2A\u53EF\u4EE5\u5BB9\u7EB3 64 \u4F4D\u6D6E\u70B9\u6570\u7684\u53D8\u91CF\u3002

  • else\uFF1A \u7528\u4E8E\u6307\u793A if \u8BED\u53E5\u4E2D\u7684\u5907\u7528\u5206\u652F\u3002

  • enum\uFF1A \u7528\u4E8E\u5B9A\u4E49\u4E00\u7EC4\u56FA\u5B9A\u7684\u5E38\u91CF\uFF08\u679A\u4E3E\uFF09\u3002

  • extends\uFF1A \u7528\u4E8E\u6307\u793A\u4E00\u4E2A\u7C7B\u662F\u4ECE\u53E6\u4E00\u4E2A\u7C7B\u6216\u63A5\u53E3\u7EE7\u627F\u7684\u3002

  • final\uFF1A \u7528\u4E8E\u6307\u793A\u8BE5\u53D8\u91CF\u662F\u4E0D\u53EF\u66F4\u6539\u7684\u3002

  • finally\uFF1A \u548C try-catch \u914D\u5408\u4F7F\u7528\uFF0C\u8868\u793A\u65E0\u8BBA\u662F\u5426\u5904\u7406\u5F02\u5E38\uFF0C\u603B\u662F\u6267\u884C finally \u5757\u4E2D\u7684\u4EE3\u7801\u3002

  • float\uFF1A \u7528\u4E8E\u58F0\u660E\u4E00\u4E2A\u53EF\u4EE5\u5BB9\u7EB3 32 \u4F4D\u6D6E\u70B9\u6570\u7684\u53D8\u91CF\u3002

  • for\uFF1A \u7528\u4E8E\u58F0\u660E\u4E00\u4E2A for \u5FAA\u73AF\uFF0C\u5982\u679C\u5FAA\u73AF\u6B21\u6570\u662F\u56FA\u5B9A\u7684\uFF0C\u5EFA\u8BAE\u4F7F\u7528 for \u5FAA\u73AF\u3002

  • if\uFF1A \u7528\u4E8E\u6307\u5B9A\u6761\u4EF6\uFF0C\u5982\u679C\u6761\u4EF6\u4E3A\u771F\uFF0C\u5219\u6267\u884C\u5BF9\u5E94\u4EE3\u7801\u3002

  • implements\uFF1A \u7528\u4E8E\u5B9E\u73B0\u63A5\u53E3\u3002

  • import\uFF1A \u7528\u4E8E\u5BFC\u5165\u5BF9\u5E94\u7684\u7C7B\u6216\u8005\u63A5\u53E3\u3002

  • instanceof\uFF1A \u7528\u4E8E\u5224\u65AD\u5BF9\u8C61\u662F\u5426\u5C5E\u4E8E\u67D0\u4E2A\u7C7B\u578B\uFF08class\uFF09\u3002

  • int\uFF1A \u7528\u4E8E\u58F0\u660E\u4E00\u4E2A\u53EF\u4EE5\u5BB9\u7EB3 32 \u4F4D\u5E26\u7B26\u53F7\u7684\u6574\u6570\u53D8\u91CF\u3002

  • interface\uFF1A \u7528\u4E8E\u58F0\u660E\u63A5\u53E3\u3002

  • long\uFF1A \u7528\u4E8E\u58F0\u660E\u4E00\u4E2A\u53EF\u4EE5\u5BB9\u7EB3 64 \u4F4D\u6574\u6570\u7684\u53D8\u91CF\u3002

  • native\uFF1A \u7528\u4E8E\u6307\u5B9A\u4E00\u4E2A\u65B9\u6CD5\u662F\u901A\u8FC7\u8C03\u7528\u672C\u673A\u63A5\u53E3\uFF08\u975E Java\uFF09\u5B9E\u73B0\u7684\u3002

  • new\uFF1A \u7528\u4E8E\u521B\u5EFA\u4E00\u4E2A\u65B0\u7684\u5BF9\u8C61\u3002

  • null\uFF1A \u5982\u679C\u4E00\u4E2A\u53D8\u91CF\u662F\u7A7A\u7684\uFF08\u4EC0\u4E48\u5F15\u7528\u4E5F\u6CA1\u6709\u6307\u5411\uFF09\uFF0C\u5C31\u53EF\u4EE5\u5C06\u5B83\u8D4B\u503C\u4E3A null\uFF0C\u548C\u7A7A\u6307\u9488\u5F02\u5E38\u606F\u606F\u76F8\u5173\u3002

  • package\uFF1A \u7528\u4E8E\u58F0\u660E\u7C7B\u6240\u5728\u7684\u5305\u3002

  • private\uFF1A \u4E00\u4E2A\u8BBF\u95EE\u6743\u9650\u4FEE\u9970\u7B26\uFF0C\u8868\u793A\u65B9\u6CD5\u6216\u53D8\u91CF\u53EA\u5BF9\u5F53\u524D\u7C7B\u53EF\u89C1\u3002

  • protected\uFF1A \u4E00\u4E2A\u8BBF\u95EE\u6743\u9650\u4FEE\u9970\u7B26\uFF0C\u8868\u793A\u65B9\u6CD5\u6216\u53D8\u91CF\u5BF9\u540C\u4E00\u5305\u5185\u7684\u7C7B\u548C\u6240\u6709\u5B50\u7C7B\u53EF\u89C1\u3002

  • public\uFF1A \u4E00\u4E2A\u8BBF\u95EE\u6743\u9650\u4FEE\u9970\u7B26\uFF0C\u9664\u4E86\u53EF\u4EE5\u58F0\u660E\u65B9\u6CD5\u548C\u53D8\u91CF\uFF08\u6240\u6709\u7C7B\u53EF\u89C1\uFF09\uFF0C\u8FD8\u53EF\u4EE5\u58F0\u660E\u7C7B\u3002main() \u65B9\u6CD5\u5FC5\u987B\u58F0\u660E\u4E3A public\u3002

  • return\uFF1A \u7528\u4E8E\u5728\u4EE3\u7801\u6267\u884C\u5B8C\u6210\u540E\u8FD4\u56DE\uFF08\u4E00\u4E2A\u503C\uFF09\u3002

  • short\uFF1A \u7528\u4E8E\u58F0\u660E\u4E00\u4E2A\u53EF\u4EE5\u5BB9\u7EB3 16 \u4F4D\u6574\u6570\u7684\u53D8\u91CF\u3002

  • static\uFF1A \u8868\u793A\u8BE5\u53D8\u91CF\u6216\u65B9\u6CD5\u662F\u9759\u6001\u53D8\u91CF\u6216\u9759\u6001\u65B9\u6CD5\u3002

  • strictfp\uFF1A \u5E76\u4E0D\u5E38\u89C1\uFF0C\u901A\u5E38\u7528\u4E8E\u4FEE\u9970\u4E00\u4E2A\u65B9\u6CD5\uFF0C\u786E\u4FDD\u65B9\u6CD5\u4F53\u5185\u7684\u6D6E\u70B9\u6570\u8FD0\u7B97\u5728\u6BCF\u4E2A\u5E73\u53F0\u4E0A\u6267\u884C\u7684\u7ED3\u679C\u76F8\u540C\u3002

  • super\uFF1A \u53EF\u7528\u4E8E\u8C03\u7528\u7236\u7C7B\u7684\u65B9\u6CD5\u6216\u8005\u5B57\u6BB5\u3002

  • switch\uFF1A \u901A\u5E38\u7528\u4E8E\u4E09\u4E2A\uFF08\u4EE5\u4E0A\uFF09\u7684\u6761\u4EF6\u5224\u65AD\u3002

  • synchronized\uFF1A \u7528\u4E8E\u6307\u5B9A\u591A\u7EBF\u7A0B\u4EE3\u7801\u4E2D\u7684\u540C\u6B65\u65B9\u6CD5\u3001\u53D8\u91CF\u6216\u8005\u4EE3\u7801\u5757\u3002

  • this\uFF1A \u53EF\u7528\u4E8E\u5728\u65B9\u6CD5\u6216\u6784\u9020\u51FD\u6570\u4E2D\u5F15\u7528\u5F53\u524D\u5BF9\u8C61\u3002

  • throw\uFF1A \u4E3B\u52A8\u629B\u51FA\u5F02\u5E38\u3002

  • throws\uFF1A \u7528\u4E8E\u58F0\u660E\u5F02\u5E38\u3002

  • transient\uFF1A \u4FEE\u9970\u7684\u5B57\u6BB5\u4E0D\u4F1A\u88AB\u5E8F\u5217\u5316\u3002

  • try\uFF1A \u4E8E\u5305\u88F9\u8981\u6355\u83B7\u5F02\u5E38\u7684\u4EE3\u7801\u5757\u3002

  • void\uFF1A \u7528\u4E8E\u6307\u5B9A\u65B9\u6CD5\u6CA1\u6709\u8FD4\u56DE\u503C\u3002

  • volatile\uFF1A \u4FDD\u8BC1\u4E0D\u540C\u7EBF\u7A0B\u5BF9\u5B83\u4FEE\u9970\u7684\u53D8\u91CF\u8FDB\u884C\u64CD\u4F5C\u65F6\u7684\u53EF\u89C1\u6027\uFF0C\u5373\u4E00\u4E2A\u7EBF\u7A0B\u4FEE\u6539\u4E86\u67D0\u4E2A\u53D8\u91CF\u7684\u503C\uFF0C\u65B0\u503C\u5BF9\u5176\u4ED6\u7EBF\u7A0B\u6765\u8BF4\u662F\u7ACB\u5373\u53EF\u89C1\u7684\u3002

  • while\uFF1A \u5982\u679C\u5FAA\u73AF\u6B21\u6570\u4E0D\u56FA\u5B9A\uFF0C\u5EFA\u8BAE\u4F7F\u7528 while \u5FAA\u73AF\u3002

  • ",41),x=t("p",null,"\u201C\u597D\u4E86\uFF0C\u4E09\u59B9\uFF0C\u5173\u4E8E Java \u4E2D\u7684\u5173\u952E\u5B57\u5C31\u5148\u8BF4\u8FD9 48 \u4E2A\u5427\uFF0C\u8FD9\u53EA\u662F\u4E00\u4E2A\u5927\u6982\u7684\u4ECB\u7ECD\uFF0C\u540E\u9762\u8FD8\u4F1A\u5BF9\u4E00\u4E9B\u7279\u6B8A\u7684\u5173\u952E\u5B57\u5355\u72EC\u62CE\u51FA\u6765\u8BE6\u7EC6\u5730\u8BB2\uFF0C\u6BD4\u5982\u8BF4\u91CD\u8981\u7684 static\u3001final \u7B49\u3002\u201D\u8F6C\u52A8\u4E86\u4E00\u4E0B\u50F5\u786C\u7684\u8116\u5B50\u540E\uFF0C\u6211\u5BF9\u4E09\u59B9\u8BF4\u3002",-1),y=t("p",null,"\u201C\u4E8C\u54E5\uFF0C\u4F60\u8F9B\u82E6\u4E86\uFF0C\u8DB3\u8DB3 48 \u4E2A\u554A\uFF0C\u5BB9\u6211\u597D\u597D\u6D88\u5316\u4E00\u4E0B\u3002\u201D",-1),k=t("p",null,[t("img",{src:"http://cdn.tobebetterjavaer.com/tobebetterjavaer/images/xingbiaogongzhonghao.png",alt:""})],-1);function J(j,N){const s=l("ExternalLinkIcon");return r(),p("div",null,[a,c,d,_,t("ol",null,[h,t("li",null,[t("p",null,[u,f,t("a",m,[v,e(s)]),b])]),w]),x,y,k])}var E=i(g,[["render",J],["__file","48-keywords.html.vue"]]);export{E as default}; +import{_ as i}from"./plugin-vue_export-helper.21dcd24c.js";import{r as l,o as r,c as p,a as t,b as e,d as o,e as n}from"./app.615e41d8.js";const g={},a=t("h1",{id:"java\u4E2D\u5E38\u7528\u768448\u4E2A\u5173\u952E\u5B57",tabindex:"-1"},[t("a",{class:"header-anchor",href:"#java\u4E2D\u5E38\u7528\u768448\u4E2A\u5173\u952E\u5B57","aria-hidden":"true"},"#"),o(" Java\u4E2D\u5E38\u7528\u768448\u4E2A\u5173\u952E\u5B57")],-1),c=t("p",null,"\u201C\u4E8C\u54E5\uFF0C\u5C31\u6211\u4E4B\u524D\u5B66\u8FC7\u7684\u8FD9\u4E9B Java \u4EE3\u7801\u4E2D\uFF0C\u6709 public\u3001static\u3001void\u3001main \u7B49\u7B49\uFF0C\u5B83\u4EEC\u5E94\u8BE5\u90FD\u662F\u5173\u952E\u5B57\u5427\uFF1F\u201D\u4E09\u59B9\u7684\u8138\u4E0A\u6CDB\u7740\u751C\u751C\u7684\u7B11\u5BB9\uFF0C\u6211\u60F3\u5979\u5728\u5B66\u4E60 Java \u65B9\u9762\u5DF2\u7ECF\u53D8\u5F97\u8D8A\u6765\u8D8A\u81EA\u4FE1\u4E86\u3002",-1),d=t("p",null,"\u201C\u662F\u7684\uFF0C\u4E09\u59B9\u3002Java \u4E2D\u7684\u5173\u952E\u5B57\u53EF\u4E0D\u5C11\u5462\uFF01\u4F60\u4E00\u4E0B\u5B50\u53EF\u80FD\u8BB0\u4E0D\u4E86\u90A3\u4E48\u591A\uFF0C\u4E0D\u8FC7\uFF0C\u5148\u4FDD\u7559\u4E2A\u5370\u8C61\u5427\uFF0C\u5BF9\u4EE5\u540E\u7684\u5B66\u4E60\u4F1A\u5F88\u6709\u5E2E\u52A9\u3002\u201D",-1),_=t("p",null,"PS\uFF1A\u6309\u7167\u9996\u5B57\u6BCD\u7684\u81EA\u7136\u987A\u5E8F\u6392\u5217\u3002",-1),h=n("
  • abstract\uFF1A \u7528\u4E8E\u58F0\u660E\u62BD\u8C61\u7C7B\uFF0C\u4EE5\u53CA\u62BD\u8C61\u65B9\u6CD5\u3002

  • boolean\uFF1A \u7528\u4E8E\u5C06\u53D8\u91CF\u58F0\u660E\u4E3A\u5E03\u5C14\u503C\u7C7B\u578B\uFF0C\u53EA\u6709 true \u548C false \u4E24\u4E2A\u503C\u3002

  • break\uFF1A \u7528\u4E8E\u4E2D\u65AD\u5FAA\u73AF\u6216 switch \u8BED\u53E5\u3002

  • byte\uFF1A \u7528\u4E8E\u58F0\u660E\u4E00\u4E2A\u53EF\u4EE5\u5BB9\u7EB3 8 \u4E2A\u6BD4\u7279\u7684\u53D8\u91CF\u3002

  • case\uFF1A \u7528\u4E8E\u5728 switch \u8BED\u53E5\u4E2D\u6807\u8BB0\u6761\u4EF6\u7684\u503C\u3002

  • catch\uFF1A \u7528\u4E8E\u6355\u83B7 try \u8BED\u53E5\u4E2D\u7684\u5F02\u5E38\u3002

  • ",6),u=t("strong",null,"char\uFF1A",-1),f=o(" \u7528\u4E8E\u58F0\u660E\u4E00\u4E2A\u53EF\u4EE5\u5BB9\u7EB3\u65E0\u7B26\u53F7 16 \u4F4D\u6BD4\u7279\u7684 "),m={href:"https://mp.weixin.qq.com/s/pNQjlXOivIgO3pbYc0GnpA",target:"_blank",rel:"noopener noreferrer"},v=o("Unicode \u5B57\u7B26"),b=o("\u7684\u53D8\u91CF\u3002"),w=n("
  • class\uFF1A \u7528\u4E8E\u58F0\u660E\u4E00\u4E2A\u7C7B\u3002

  • continue\uFF1A \u7528\u4E8E\u7EE7\u7EED\u4E0B\u4E00\u4E2A\u5FAA\u73AF\uFF0C\u53EF\u4EE5\u5728\u6307\u5B9A\u6761\u4EF6\u4E0B\u8DF3\u8FC7\u5176\u4F59\u4EE3\u7801\u3002

  • default\uFF1A \u7528\u4E8E\u6307\u5B9A switch \u8BED\u53E5\u4E2D\u9664\u53BB case \u6761\u4EF6\u4E4B\u5916\u7684\u9ED8\u8BA4\u4EE3\u7801\u5757\u3002

  • do\uFF1A \u901A\u5E38\u548C while \u5173\u952E\u5B57\u914D\u5408\u4F7F\u7528\uFF0Cdo \u540E\u7D27\u8DDF\u5FAA\u73AF\u4F53\u3002

  • double\uFF1A \u7528\u4E8E\u58F0\u660E\u4E00\u4E2A\u53EF\u4EE5\u5BB9\u7EB3 64 \u4F4D\u6D6E\u70B9\u6570\u7684\u53D8\u91CF\u3002

  • else\uFF1A \u7528\u4E8E\u6307\u793A if \u8BED\u53E5\u4E2D\u7684\u5907\u7528\u5206\u652F\u3002

  • enum\uFF1A \u7528\u4E8E\u5B9A\u4E49\u4E00\u7EC4\u56FA\u5B9A\u7684\u5E38\u91CF\uFF08\u679A\u4E3E\uFF09\u3002

  • extends\uFF1A \u7528\u4E8E\u6307\u793A\u4E00\u4E2A\u7C7B\u662F\u4ECE\u53E6\u4E00\u4E2A\u7C7B\u6216\u63A5\u53E3\u7EE7\u627F\u7684\u3002

  • final\uFF1A \u7528\u4E8E\u6307\u793A\u8BE5\u53D8\u91CF\u662F\u4E0D\u53EF\u66F4\u6539\u7684\u3002

  • finally\uFF1A \u548C try-catch \u914D\u5408\u4F7F\u7528\uFF0C\u8868\u793A\u65E0\u8BBA\u662F\u5426\u5904\u7406\u5F02\u5E38\uFF0C\u603B\u662F\u6267\u884C finally \u5757\u4E2D\u7684\u4EE3\u7801\u3002

  • float\uFF1A \u7528\u4E8E\u58F0\u660E\u4E00\u4E2A\u53EF\u4EE5\u5BB9\u7EB3 32 \u4F4D\u6D6E\u70B9\u6570\u7684\u53D8\u91CF\u3002

  • for\uFF1A \u7528\u4E8E\u58F0\u660E\u4E00\u4E2A for \u5FAA\u73AF\uFF0C\u5982\u679C\u5FAA\u73AF\u6B21\u6570\u662F\u56FA\u5B9A\u7684\uFF0C\u5EFA\u8BAE\u4F7F\u7528 for \u5FAA\u73AF\u3002

  • if\uFF1A \u7528\u4E8E\u6307\u5B9A\u6761\u4EF6\uFF0C\u5982\u679C\u6761\u4EF6\u4E3A\u771F\uFF0C\u5219\u6267\u884C\u5BF9\u5E94\u4EE3\u7801\u3002

  • implements\uFF1A \u7528\u4E8E\u5B9E\u73B0\u63A5\u53E3\u3002

  • import\uFF1A \u7528\u4E8E\u5BFC\u5165\u5BF9\u5E94\u7684\u7C7B\u6216\u8005\u63A5\u53E3\u3002

  • instanceof\uFF1A \u7528\u4E8E\u5224\u65AD\u5BF9\u8C61\u662F\u5426\u5C5E\u4E8E\u67D0\u4E2A\u7C7B\u578B\uFF08class\uFF09\u3002

  • int\uFF1A \u7528\u4E8E\u58F0\u660E\u4E00\u4E2A\u53EF\u4EE5\u5BB9\u7EB3 32 \u4F4D\u5E26\u7B26\u53F7\u7684\u6574\u6570\u53D8\u91CF\u3002

  • interface\uFF1A \u7528\u4E8E\u58F0\u660E\u63A5\u53E3\u3002

  • long\uFF1A \u7528\u4E8E\u58F0\u660E\u4E00\u4E2A\u53EF\u4EE5\u5BB9\u7EB3 64 \u4F4D\u6574\u6570\u7684\u53D8\u91CF\u3002

  • native\uFF1A \u7528\u4E8E\u6307\u5B9A\u4E00\u4E2A\u65B9\u6CD5\u662F\u901A\u8FC7\u8C03\u7528\u672C\u673A\u63A5\u53E3\uFF08\u975E Java\uFF09\u5B9E\u73B0\u7684\u3002

  • new\uFF1A \u7528\u4E8E\u521B\u5EFA\u4E00\u4E2A\u65B0\u7684\u5BF9\u8C61\u3002

  • null\uFF1A \u5982\u679C\u4E00\u4E2A\u53D8\u91CF\u662F\u7A7A\u7684\uFF08\u4EC0\u4E48\u5F15\u7528\u4E5F\u6CA1\u6709\u6307\u5411\uFF09\uFF0C\u5C31\u53EF\u4EE5\u5C06\u5B83\u8D4B\u503C\u4E3A null\uFF0C\u548C\u7A7A\u6307\u9488\u5F02\u5E38\u606F\u606F\u76F8\u5173\u3002

  • package\uFF1A \u7528\u4E8E\u58F0\u660E\u7C7B\u6240\u5728\u7684\u5305\u3002

  • private\uFF1A \u4E00\u4E2A\u8BBF\u95EE\u6743\u9650\u4FEE\u9970\u7B26\uFF0C\u8868\u793A\u65B9\u6CD5\u6216\u53D8\u91CF\u53EA\u5BF9\u5F53\u524D\u7C7B\u53EF\u89C1\u3002

  • protected\uFF1A \u4E00\u4E2A\u8BBF\u95EE\u6743\u9650\u4FEE\u9970\u7B26\uFF0C\u8868\u793A\u65B9\u6CD5\u6216\u53D8\u91CF\u5BF9\u540C\u4E00\u5305\u5185\u7684\u7C7B\u548C\u6240\u6709\u5B50\u7C7B\u53EF\u89C1\u3002

  • public\uFF1A \u4E00\u4E2A\u8BBF\u95EE\u6743\u9650\u4FEE\u9970\u7B26\uFF0C\u9664\u4E86\u53EF\u4EE5\u58F0\u660E\u65B9\u6CD5\u548C\u53D8\u91CF\uFF08\u6240\u6709\u7C7B\u53EF\u89C1\uFF09\uFF0C\u8FD8\u53EF\u4EE5\u58F0\u660E\u7C7B\u3002main() \u65B9\u6CD5\u5FC5\u987B\u58F0\u660E\u4E3A public\u3002

  • return\uFF1A \u7528\u4E8E\u5728\u4EE3\u7801\u6267\u884C\u5B8C\u6210\u540E\u8FD4\u56DE\uFF08\u4E00\u4E2A\u503C\uFF09\u3002

  • short\uFF1A \u7528\u4E8E\u58F0\u660E\u4E00\u4E2A\u53EF\u4EE5\u5BB9\u7EB3 16 \u4F4D\u6574\u6570\u7684\u53D8\u91CF\u3002

  • static\uFF1A \u8868\u793A\u8BE5\u53D8\u91CF\u6216\u65B9\u6CD5\u662F\u9759\u6001\u53D8\u91CF\u6216\u9759\u6001\u65B9\u6CD5\u3002

  • strictfp\uFF1A \u5E76\u4E0D\u5E38\u89C1\uFF0C\u901A\u5E38\u7528\u4E8E\u4FEE\u9970\u4E00\u4E2A\u65B9\u6CD5\uFF0C\u786E\u4FDD\u65B9\u6CD5\u4F53\u5185\u7684\u6D6E\u70B9\u6570\u8FD0\u7B97\u5728\u6BCF\u4E2A\u5E73\u53F0\u4E0A\u6267\u884C\u7684\u7ED3\u679C\u76F8\u540C\u3002

  • super\uFF1A \u53EF\u7528\u4E8E\u8C03\u7528\u7236\u7C7B\u7684\u65B9\u6CD5\u6216\u8005\u5B57\u6BB5\u3002

  • switch\uFF1A \u901A\u5E38\u7528\u4E8E\u4E09\u4E2A\uFF08\u4EE5\u4E0A\uFF09\u7684\u6761\u4EF6\u5224\u65AD\u3002

  • synchronized\uFF1A \u7528\u4E8E\u6307\u5B9A\u591A\u7EBF\u7A0B\u4EE3\u7801\u4E2D\u7684\u540C\u6B65\u65B9\u6CD5\u3001\u53D8\u91CF\u6216\u8005\u4EE3\u7801\u5757\u3002

  • this\uFF1A \u53EF\u7528\u4E8E\u5728\u65B9\u6CD5\u6216\u6784\u9020\u51FD\u6570\u4E2D\u5F15\u7528\u5F53\u524D\u5BF9\u8C61\u3002

  • throw\uFF1A \u4E3B\u52A8\u629B\u51FA\u5F02\u5E38\u3002

  • throws\uFF1A \u7528\u4E8E\u58F0\u660E\u5F02\u5E38\u3002

  • transient\uFF1A \u4FEE\u9970\u7684\u5B57\u6BB5\u4E0D\u4F1A\u88AB\u5E8F\u5217\u5316\u3002

  • try\uFF1A \u4E8E\u5305\u88F9\u8981\u6355\u83B7\u5F02\u5E38\u7684\u4EE3\u7801\u5757\u3002

  • void\uFF1A \u7528\u4E8E\u6307\u5B9A\u65B9\u6CD5\u6CA1\u6709\u8FD4\u56DE\u503C\u3002

  • volatile\uFF1A \u4FDD\u8BC1\u4E0D\u540C\u7EBF\u7A0B\u5BF9\u5B83\u4FEE\u9970\u7684\u53D8\u91CF\u8FDB\u884C\u64CD\u4F5C\u65F6\u7684\u53EF\u89C1\u6027\uFF0C\u5373\u4E00\u4E2A\u7EBF\u7A0B\u4FEE\u6539\u4E86\u67D0\u4E2A\u53D8\u91CF\u7684\u503C\uFF0C\u65B0\u503C\u5BF9\u5176\u4ED6\u7EBF\u7A0B\u6765\u8BF4\u662F\u7ACB\u5373\u53EF\u89C1\u7684\u3002

  • while\uFF1A \u5982\u679C\u5FAA\u73AF\u6B21\u6570\u4E0D\u56FA\u5B9A\uFF0C\u5EFA\u8BAE\u4F7F\u7528 while \u5FAA\u73AF\u3002

  • ",41),x=t("p",null,"\u201C\u597D\u4E86\uFF0C\u4E09\u59B9\uFF0C\u5173\u4E8E Java \u4E2D\u7684\u5173\u952E\u5B57\u5C31\u5148\u8BF4\u8FD9 48 \u4E2A\u5427\uFF0C\u8FD9\u53EA\u662F\u4E00\u4E2A\u5927\u6982\u7684\u4ECB\u7ECD\uFF0C\u540E\u9762\u8FD8\u4F1A\u5BF9\u4E00\u4E9B\u7279\u6B8A\u7684\u5173\u952E\u5B57\u5355\u72EC\u62CE\u51FA\u6765\u8BE6\u7EC6\u5730\u8BB2\uFF0C\u6BD4\u5982\u8BF4\u91CD\u8981\u7684 static\u3001final \u7B49\u3002\u201D\u8F6C\u52A8\u4E86\u4E00\u4E0B\u50F5\u786C\u7684\u8116\u5B50\u540E\uFF0C\u6211\u5BF9\u4E09\u59B9\u8BF4\u3002",-1),y=t("p",null,"\u201C\u4E8C\u54E5\uFF0C\u4F60\u8F9B\u82E6\u4E86\uFF0C\u8DB3\u8DB3 48 \u4E2A\u554A\uFF0C\u5BB9\u6211\u597D\u597D\u6D88\u5316\u4E00\u4E0B\u3002\u201D",-1),k=t("p",null,[t("img",{src:"http://cdn.tobebetterjavaer.com/tobebetterjavaer/images/xingbiaogongzhonghao.png",alt:""})],-1);function J(j,N){const s=l("ExternalLinkIcon");return r(),p("div",null,[a,c,d,_,t("ol",null,[h,t("li",null,[t("p",null,[u,f,t("a",m,[v,e(s)]),b])]),w]),x,y,k])}var E=i(g,[["render",J],["__file","48-keywords.html.vue"]]);export{E as default}; diff --git a/dist/assets/BIONIOAIO.html.27d4fa22.js b/dist/assets/BIONIOAIO.html.4c184e72.js similarity index 99% rename from dist/assets/BIONIOAIO.html.27d4fa22.js rename to dist/assets/BIONIOAIO.html.4c184e72.js index 4c671d45..d79c3a8f 100644 --- a/dist/assets/BIONIOAIO.html.27d4fa22.js +++ b/dist/assets/BIONIOAIO.html.4c184e72.js @@ -1,4 +1,4 @@ -import{_ as t}from"./plugin-vue_export-helper.21dcd24c.js";import{r as p,o as e,c as o,a as n,b as c,e as l,d as s}from"./app.a0271b9c.js";const i={},u=l(`

    \u5982\u4F55\u7ED9\u5973\u670B\u53CB\u89E3\u91CA\u6E05\u695ABIO\u3001NIO\u548CAIO\uFF1F

    \u5468\u672B\u5348\u540E\uFF0C\u5728\u5BB6\u91CC\u9762\u8FDB\u884C\u7535\u8BDD\u9762\u8BD5\uFF0C\u6211\u95EE\u4E86\u9762\u8BD5\u8005\u51E0\u4E2A\u5173\u4E8E IO \u7684\u95EE\u9898\uFF0C\u5176\u4E2D\u5305\u62EC\u4EC0\u4E48\u662F BIO\u3001NIO \u548C AIO\uFF1F\u4E09\u8005\u6709\u4EC0\u4E48\u533A\u522B\uFF1F\u5177\u4F53\u5982\u4F55\u4F7F\u7528\u7B49\u95EE\u9898\uFF0C\u4F46\u662F\u9762\u8BD5\u8005\u56DE\u7B54\u7684\u5E76\u4E0D\u662F\u5F88\u6EE1\u610F\u3002\u4E8E\u662F\u6211\u5728\u9762\u8BD5\u8BC4\u4EF7\u4E2D\u5199\u9053\uFF1A"\u5BF9 Java \u7684 IO \u63D0\u9192\u7406\u89E3\u4E0D\u591F\u6DF1\u5165"\u3002\u6070\u597D\u88AB\u5973\u670B\u53CB\u770B\u5230\u4E86\u3002

    Java IO

    IO\uFF0C\u5E38\u534F\u4F5C I/O\uFF0C\u662F Input/Output \u7684\u7B80\u79F0\uFF0C\u5373\u8F93\u5165/\u8F93\u51FA\u3002\u901A\u5E38\u6307\u6570\u636E\u5728\u5185\u90E8\u5B58\u50A8\u5668\uFF08\u5185\u5B58\uFF09\u548C\u5916\u90E8\u5B58\u50A8\u5668\uFF08\u786C\u76D8\u3001\u4F18\u76D8\u7B49\uFF09\u6216\u5176\u4ED6\u5468\u8FB9\u8BBE\u5907\u4E4B\u95F4\u7684\u8F93\u5165\u548C\u8F93\u51FA\u3002

    \u8F93\u5165/\u8F93\u51FA\u662F\u4FE1\u606F\u5904\u7406\u7CFB\u7EDF\uFF08\u4F8B\u5982\u8BA1\u7B97\u673A\uFF09\u4E0E\u5916\u90E8\u4E16\u754C\uFF08\u53EF\u80FD\u662F\u4EBA\u7C7B\u6216\u53E6\u4E00\u4FE1\u606F\u5904\u7406\u7CFB\u7EDF\uFF09\u4E4B\u95F4\u7684\u901A\u4FE1\u3002

    \u8F93\u5165\u662F\u7CFB\u7EDF\u63A5\u6536\u7684\u4FE1\u53F7\u6216\u6570\u636E\uFF0C\u8F93\u51FA\u5219\u662F\u4ECE\u5176\u53D1\u9001\u7684\u4FE1\u53F7\u6216\u6570\u636E\u3002

    \u5728 Java \u4E2D\uFF0C\u63D0\u4F9B\u4E86\u4E00\u7CFB\u5217 API\uFF0C\u53EF\u4EE5\u4F9B\u5F00\u53D1\u8005\u6765\u8BFB\u5199\u5916\u90E8\u6570\u636E\u6216\u6587\u4EF6\u3002\u6211\u4EEC\u79F0\u8FD9\u4E9B API \u4E3A Java IO\u3002

    IO \u662F Java \u4E2D\u6BD4\u8F83\u91CD\u8981\uFF0C\u4E14\u6BD4\u8F83\u96BE\u7684\u77E5\u8BC6\u70B9\uFF0C\u4E3B\u8981\u662F\u56E0\u4E3A\u968F\u7740 Java \u7684\u53D1\u5C55\uFF0C\u76EE\u524D\u6709\u4E09\u79CD IO \u5171\u5B58\u3002\u5206\u522B\u662F BIO\u3001NIO \u548C AIO\u3002

    Java BIO

    BIO \u5168\u79F0Block-IO \u662F\u4E00\u79CD\u540C\u6B65\u4E14\u963B\u585E\u7684\u901A\u4FE1\u6A21\u5F0F\u3002\u662F\u4E00\u4E2A\u6BD4\u8F83\u4F20\u7EDF\u7684\u901A\u4FE1\u65B9\u5F0F\uFF0C\u6A21\u5F0F\u7B80\u5355\uFF0C\u4F7F\u7528\u65B9\u4FBF\u3002\u4F46\u5E76\u53D1\u5904\u7406\u80FD\u529B\u4F4E\uFF0C\u901A\u4FE1\u8017\u65F6\uFF0C\u4F9D\u8D56\u7F51\u901F\u3002

    Java NIO

    Java NIO\uFF0C\u5168\u7A0B Non-Block IO \uFF0C\u662F Java SE 1.4 \u7248\u4EE5\u540E\uFF0C\u9488\u5BF9\u7F51\u7EDC\u4F20\u8F93\u6548\u80FD\u4F18\u5316\u7684\u65B0\u529F\u80FD\u3002\u662F\u4E00\u79CD\u975E\u963B\u585E\u540C\u6B65\u7684\u901A\u4FE1\u6A21\u5F0F\u3002

    NIO \u4E0E\u539F\u6765\u7684 I/O \u6709\u540C\u6837\u7684\u4F5C\u7528\u548C\u76EE\u7684, \u4ED6\u4EEC\u4E4B\u95F4\u6700\u91CD\u8981\u7684\u533A\u522B\u662F\u6570\u636E\u6253\u5305\u548C\u4F20\u8F93\u7684\u65B9\u5F0F\u3002\u539F\u6765\u7684 I/O \u4EE5\u6D41\u7684\u65B9\u5F0F\u5904\u7406\u6570\u636E\uFF0C\u800C NIO \u4EE5\u5757\u7684\u65B9\u5F0F\u5904\u7406\u6570\u636E\u3002

    \u9762\u5411\u6D41\u7684 I/O \u7CFB\u7EDF\u4E00\u6B21\u4E00\u4E2A\u5B57\u8282\u5730\u5904\u7406\u6570\u636E\u3002\u4E00\u4E2A\u8F93\u5165\u6D41\u4EA7\u751F\u4E00\u4E2A\u5B57\u8282\u7684\u6570\u636E\uFF0C\u4E00\u4E2A\u8F93\u51FA\u6D41\u6D88\u8D39\u4E00\u4E2A\u5B57\u8282\u7684\u6570\u636E\u3002

    \u9762\u5411\u5757\u7684 I/O \u7CFB\u7EDF\u4EE5\u5757\u7684\u5F62\u5F0F\u5904\u7406\u6570\u636E\u3002\u6BCF\u4E00\u4E2A\u64CD\u4F5C\u90FD\u5728\u4E00\u6B65\u4E2D\u4EA7\u751F\u6216\u8005\u6D88\u8D39\u4E00\u4E2A\u6570\u636E\u5757\u3002\u6309\u5757\u5904\u7406\u6570\u636E\u6BD4\u6309(\u6D41\u5F0F\u7684)\u5B57\u8282\u5904\u7406\u6570\u636E\u8981\u5FEB\u5F97\u591A\u3002\u4F46\u662F\u9762\u5411\u5757\u7684 I/O \u7F3A\u5C11\u4E00\u4E9B\u9762\u5411\u6D41\u7684 I/O \u6240\u5177\u6709\u7684\u4F18\u96C5\u6027\u548C\u7B80\u5355\u6027\u3002

    Java AIO

    Java AIO\uFF0C\u5168\u7A0B Asynchronous IO\uFF0C\u662F\u5F02\u6B65\u975E\u963B\u585E\u7684 IO\u3002\u662F\u4E00\u79CD\u975E\u963B\u585E\u5F02\u6B65\u7684\u901A\u4FE1\u6A21\u5F0F\u3002

    \u5728 NIO \u7684\u57FA\u7840\u4E0A\u5F15\u5165\u4E86\u65B0\u7684\u5F02\u6B65\u901A\u9053\u7684\u6982\u5FF5\uFF0C\u5E76\u63D0\u4F9B\u4E86\u5F02\u6B65\u6587\u4EF6\u901A\u9053\u548C\u5F02\u6B65\u5957\u63A5\u5B57\u901A\u9053\u7684\u5B9E\u73B0\u3002

    \u4E09\u79CD IO \u7684\u533A\u522B

    \u9996\u5148\uFF0C\u6211\u4EEC\u7AD9\u5728\u5B8F\u89C2\u7684\u89D2\u5EA6\uFF0C\u91CD\u65B0\u753B\u4E00\u4E0B\u91CD\u70B9\uFF1A

    BIO \uFF08Blocking I/O\uFF09\uFF1A\u540C\u6B65\u963B\u585E I/O \u6A21\u5F0F\u3002

    NIO \uFF08New I/O\uFF09\uFF1A\u540C\u6B65\u975E\u963B\u585E\u6A21\u5F0F\u3002

    AIO \uFF08Asynchronous I/O\uFF09\uFF1A\u5F02\u6B65\u975E\u963B\u585E I/O \u6A21\u578B\u3002

    \u540C\u6B65\u963B\u585E\u6A21\u5F0F\uFF1A\u8FD9\u79CD\u6A21\u5F0F\u4E0B\uFF0C\u6211\u4EEC\u7684\u5DE5\u4F5C\u6A21\u5F0F\u662F\u5148\u6765\u5230\u53A8\u623F\uFF0C\u5F00\u59CB\u70E7\u6C34\uFF0C\u5E76\u5750\u5728\u6C34\u58F6\u9762\u524D\u4E00\u76F4\u7B49\u7740\u6C34\u70E7\u5F00\u3002

    \u540C\u6B65\u975E\u963B\u585E\u6A21\u5F0F\uFF1A\u8FD9\u79CD\u6A21\u5F0F\u4E0B\uFF0C\u6211\u4EEC\u7684\u5DE5\u4F5C\u6A21\u5F0F\u662F\u5148\u6765\u5230\u53A8\u623F\uFF0C\u5F00\u59CB\u70E7\u6C34\uFF0C\u4F46\u662F\u6211\u4EEC\u4E0D\u4E00\u76F4\u5750\u5728\u6C34\u58F6\u524D\u9762\u7B49\uFF0C\u800C\u662F\u56DE\u5230\u5BA2\u5385\u770B\u7535\u89C6\uFF0C\u7136\u540E\u6BCF\u9694\u51E0\u5206\u949F\u5230\u53A8\u623F\u770B\u4E00\u4E0B\u6C34\u6709\u6CA1\u6709\u70E7\u5F00\u3002

    \u5F02\u6B65\u975E\u963B\u585E I/O \u6A21\u578B\uFF1A\u8FD9\u79CD\u6A21\u5F0F\u4E0B\uFF0C\u6211\u4EEC\u7684\u5DE5\u4F5C\u6A21\u5F0F\u662F\u5148\u6765\u5230\u53A8\u623F\uFF0C\u5F00\u59CB\u70E7\u6C34\uFF0C\u6211\u4EEC\u4E0D\u4E00\u76F4\u5750\u5728\u6C34\u58F6\u524D\u9762\u7B49\uFF0C\u4E5F\u4E0D\u9694\u4E00\u6BB5\u65F6\u95F4\u53BB\u770B\u4E00\u4E0B\uFF0C\u800C\u662F\u5728\u5BA2\u5385\u770B\u7535\u89C6\uFF0C\u6C34\u58F6\u4E0A\u9762\u6709\u4E2A\u5F00\u5173\uFF0C\u6C34\u70E7\u5F00\u4E4B\u540E\u4ED6\u4F1A\u901A\u77E5\u6211\u3002

    \u963B\u585E VS \u975E\u963B\u585E\uFF1A\u4EBA\u662F\u5426\u5750\u5728\u6C34\u58F6\u524D\u9762\u4E00\u76F4\u7B49\u3002

    \u540C\u6B65 VS \u5F02\u6B65\uFF1A\u6C34\u58F6\u662F\u4E0D\u662F\u5728\u6C34\u70E7\u5F00\u4E4B\u540E\u4E3B\u52A8\u901A\u77E5\u4EBA\u3002

    \u9002\u7528\u573A\u666F

    BIO \u65B9\u5F0F\u9002\u7528\u4E8E\u8FDE\u63A5\u6570\u76EE\u6BD4\u8F83\u5C0F\u4E14\u56FA\u5B9A\u7684\u67B6\u6784\uFF0C\u8FD9\u79CD\u65B9\u5F0F\u5BF9\u670D\u52A1\u5668\u8D44\u6E90\u8981\u6C42\u6BD4\u8F83\u9AD8\uFF0C\u5E76\u53D1\u5C40\u9650\u4E8E\u5E94\u7528\u4E2D\uFF0CJDK1.4 \u4EE5\u524D\u7684\u552F\u4E00\u9009\u62E9\uFF0C\u4F46\u7A0B\u5E8F\u76F4\u89C2\u7B80\u5355\u6613\u7406\u89E3\u3002

    NIO \u65B9\u5F0F\u9002\u7528\u4E8E\u8FDE\u63A5\u6570\u76EE\u591A\u4E14\u8FDE\u63A5\u6BD4\u8F83\u77ED\uFF08\u8F7B\u64CD\u4F5C\uFF09\u7684\u67B6\u6784\uFF0C\u6BD4\u5982\u804A\u5929\u670D\u52A1\u5668\uFF0C\u5E76\u53D1\u5C40\u9650\u4E8E\u5E94\u7528\u4E2D\uFF0C\u7F16\u7A0B\u6BD4\u8F83\u590D\u6742\uFF0CJDK1.4 \u5F00\u59CB\u652F\u6301\u3002

    AIO \u65B9\u5F0F\u9002\u7528\u4E8E\u8FDE\u63A5\u6570\u76EE\u591A\u4E14\u8FDE\u63A5\u6BD4\u8F83\u957F\uFF08\u91CD\u64CD\u4F5C\uFF09\u7684\u67B6\u6784\uFF0C\u6BD4\u5982\u76F8\u518C\u670D\u52A1\u5668\uFF0C\u5145\u5206\u8C03\u7528 OS \u53C2\u4E0E\u5E76\u53D1\u64CD\u4F5C\uFF0C\u7F16\u7A0B\u6BD4\u8F83\u590D\u6742\uFF0CJDK7 \u5F00\u59CB\u652F\u6301\u3002

    \u4F7F\u7528\u65B9\u5F0F

    \u4F7F\u7528 BIO \u5B9E\u73B0\u6587\u4EF6\u7684\u8BFB\u53D6\u548C\u5199\u5165\u3002

    //Initializes The Object
    +import{_ as t}from"./plugin-vue_export-helper.21dcd24c.js";import{r as p,o as e,c as o,a as n,b as c,e as l,d as s}from"./app.615e41d8.js";const i={},u=l(`

    \u5982\u4F55\u7ED9\u5973\u670B\u53CB\u89E3\u91CA\u6E05\u695ABIO\u3001NIO\u548CAIO\uFF1F

    \u5468\u672B\u5348\u540E\uFF0C\u5728\u5BB6\u91CC\u9762\u8FDB\u884C\u7535\u8BDD\u9762\u8BD5\uFF0C\u6211\u95EE\u4E86\u9762\u8BD5\u8005\u51E0\u4E2A\u5173\u4E8E IO \u7684\u95EE\u9898\uFF0C\u5176\u4E2D\u5305\u62EC\u4EC0\u4E48\u662F BIO\u3001NIO \u548C AIO\uFF1F\u4E09\u8005\u6709\u4EC0\u4E48\u533A\u522B\uFF1F\u5177\u4F53\u5982\u4F55\u4F7F\u7528\u7B49\u95EE\u9898\uFF0C\u4F46\u662F\u9762\u8BD5\u8005\u56DE\u7B54\u7684\u5E76\u4E0D\u662F\u5F88\u6EE1\u610F\u3002\u4E8E\u662F\u6211\u5728\u9762\u8BD5\u8BC4\u4EF7\u4E2D\u5199\u9053\uFF1A"\u5BF9 Java \u7684 IO \u63D0\u9192\u7406\u89E3\u4E0D\u591F\u6DF1\u5165"\u3002\u6070\u597D\u88AB\u5973\u670B\u53CB\u770B\u5230\u4E86\u3002

    Java IO

    IO\uFF0C\u5E38\u534F\u4F5C I/O\uFF0C\u662F Input/Output \u7684\u7B80\u79F0\uFF0C\u5373\u8F93\u5165/\u8F93\u51FA\u3002\u901A\u5E38\u6307\u6570\u636E\u5728\u5185\u90E8\u5B58\u50A8\u5668\uFF08\u5185\u5B58\uFF09\u548C\u5916\u90E8\u5B58\u50A8\u5668\uFF08\u786C\u76D8\u3001\u4F18\u76D8\u7B49\uFF09\u6216\u5176\u4ED6\u5468\u8FB9\u8BBE\u5907\u4E4B\u95F4\u7684\u8F93\u5165\u548C\u8F93\u51FA\u3002

    \u8F93\u5165/\u8F93\u51FA\u662F\u4FE1\u606F\u5904\u7406\u7CFB\u7EDF\uFF08\u4F8B\u5982\u8BA1\u7B97\u673A\uFF09\u4E0E\u5916\u90E8\u4E16\u754C\uFF08\u53EF\u80FD\u662F\u4EBA\u7C7B\u6216\u53E6\u4E00\u4FE1\u606F\u5904\u7406\u7CFB\u7EDF\uFF09\u4E4B\u95F4\u7684\u901A\u4FE1\u3002

    \u8F93\u5165\u662F\u7CFB\u7EDF\u63A5\u6536\u7684\u4FE1\u53F7\u6216\u6570\u636E\uFF0C\u8F93\u51FA\u5219\u662F\u4ECE\u5176\u53D1\u9001\u7684\u4FE1\u53F7\u6216\u6570\u636E\u3002

    \u5728 Java \u4E2D\uFF0C\u63D0\u4F9B\u4E86\u4E00\u7CFB\u5217 API\uFF0C\u53EF\u4EE5\u4F9B\u5F00\u53D1\u8005\u6765\u8BFB\u5199\u5916\u90E8\u6570\u636E\u6216\u6587\u4EF6\u3002\u6211\u4EEC\u79F0\u8FD9\u4E9B API \u4E3A Java IO\u3002

    IO \u662F Java \u4E2D\u6BD4\u8F83\u91CD\u8981\uFF0C\u4E14\u6BD4\u8F83\u96BE\u7684\u77E5\u8BC6\u70B9\uFF0C\u4E3B\u8981\u662F\u56E0\u4E3A\u968F\u7740 Java \u7684\u53D1\u5C55\uFF0C\u76EE\u524D\u6709\u4E09\u79CD IO \u5171\u5B58\u3002\u5206\u522B\u662F BIO\u3001NIO \u548C AIO\u3002

    Java BIO

    BIO \u5168\u79F0Block-IO \u662F\u4E00\u79CD\u540C\u6B65\u4E14\u963B\u585E\u7684\u901A\u4FE1\u6A21\u5F0F\u3002\u662F\u4E00\u4E2A\u6BD4\u8F83\u4F20\u7EDF\u7684\u901A\u4FE1\u65B9\u5F0F\uFF0C\u6A21\u5F0F\u7B80\u5355\uFF0C\u4F7F\u7528\u65B9\u4FBF\u3002\u4F46\u5E76\u53D1\u5904\u7406\u80FD\u529B\u4F4E\uFF0C\u901A\u4FE1\u8017\u65F6\uFF0C\u4F9D\u8D56\u7F51\u901F\u3002

    Java NIO

    Java NIO\uFF0C\u5168\u7A0B Non-Block IO \uFF0C\u662F Java SE 1.4 \u7248\u4EE5\u540E\uFF0C\u9488\u5BF9\u7F51\u7EDC\u4F20\u8F93\u6548\u80FD\u4F18\u5316\u7684\u65B0\u529F\u80FD\u3002\u662F\u4E00\u79CD\u975E\u963B\u585E\u540C\u6B65\u7684\u901A\u4FE1\u6A21\u5F0F\u3002

    NIO \u4E0E\u539F\u6765\u7684 I/O \u6709\u540C\u6837\u7684\u4F5C\u7528\u548C\u76EE\u7684, \u4ED6\u4EEC\u4E4B\u95F4\u6700\u91CD\u8981\u7684\u533A\u522B\u662F\u6570\u636E\u6253\u5305\u548C\u4F20\u8F93\u7684\u65B9\u5F0F\u3002\u539F\u6765\u7684 I/O \u4EE5\u6D41\u7684\u65B9\u5F0F\u5904\u7406\u6570\u636E\uFF0C\u800C NIO \u4EE5\u5757\u7684\u65B9\u5F0F\u5904\u7406\u6570\u636E\u3002

    \u9762\u5411\u6D41\u7684 I/O \u7CFB\u7EDF\u4E00\u6B21\u4E00\u4E2A\u5B57\u8282\u5730\u5904\u7406\u6570\u636E\u3002\u4E00\u4E2A\u8F93\u5165\u6D41\u4EA7\u751F\u4E00\u4E2A\u5B57\u8282\u7684\u6570\u636E\uFF0C\u4E00\u4E2A\u8F93\u51FA\u6D41\u6D88\u8D39\u4E00\u4E2A\u5B57\u8282\u7684\u6570\u636E\u3002

    \u9762\u5411\u5757\u7684 I/O \u7CFB\u7EDF\u4EE5\u5757\u7684\u5F62\u5F0F\u5904\u7406\u6570\u636E\u3002\u6BCF\u4E00\u4E2A\u64CD\u4F5C\u90FD\u5728\u4E00\u6B65\u4E2D\u4EA7\u751F\u6216\u8005\u6D88\u8D39\u4E00\u4E2A\u6570\u636E\u5757\u3002\u6309\u5757\u5904\u7406\u6570\u636E\u6BD4\u6309(\u6D41\u5F0F\u7684)\u5B57\u8282\u5904\u7406\u6570\u636E\u8981\u5FEB\u5F97\u591A\u3002\u4F46\u662F\u9762\u5411\u5757\u7684 I/O \u7F3A\u5C11\u4E00\u4E9B\u9762\u5411\u6D41\u7684 I/O \u6240\u5177\u6709\u7684\u4F18\u96C5\u6027\u548C\u7B80\u5355\u6027\u3002

    Java AIO

    Java AIO\uFF0C\u5168\u7A0B Asynchronous IO\uFF0C\u662F\u5F02\u6B65\u975E\u963B\u585E\u7684 IO\u3002\u662F\u4E00\u79CD\u975E\u963B\u585E\u5F02\u6B65\u7684\u901A\u4FE1\u6A21\u5F0F\u3002

    \u5728 NIO \u7684\u57FA\u7840\u4E0A\u5F15\u5165\u4E86\u65B0\u7684\u5F02\u6B65\u901A\u9053\u7684\u6982\u5FF5\uFF0C\u5E76\u63D0\u4F9B\u4E86\u5F02\u6B65\u6587\u4EF6\u901A\u9053\u548C\u5F02\u6B65\u5957\u63A5\u5B57\u901A\u9053\u7684\u5B9E\u73B0\u3002

    \u4E09\u79CD IO \u7684\u533A\u522B

    \u9996\u5148\uFF0C\u6211\u4EEC\u7AD9\u5728\u5B8F\u89C2\u7684\u89D2\u5EA6\uFF0C\u91CD\u65B0\u753B\u4E00\u4E0B\u91CD\u70B9\uFF1A

    BIO \uFF08Blocking I/O\uFF09\uFF1A\u540C\u6B65\u963B\u585E I/O \u6A21\u5F0F\u3002

    NIO \uFF08New I/O\uFF09\uFF1A\u540C\u6B65\u975E\u963B\u585E\u6A21\u5F0F\u3002

    AIO \uFF08Asynchronous I/O\uFF09\uFF1A\u5F02\u6B65\u975E\u963B\u585E I/O \u6A21\u578B\u3002

    \u540C\u6B65\u963B\u585E\u6A21\u5F0F\uFF1A\u8FD9\u79CD\u6A21\u5F0F\u4E0B\uFF0C\u6211\u4EEC\u7684\u5DE5\u4F5C\u6A21\u5F0F\u662F\u5148\u6765\u5230\u53A8\u623F\uFF0C\u5F00\u59CB\u70E7\u6C34\uFF0C\u5E76\u5750\u5728\u6C34\u58F6\u9762\u524D\u4E00\u76F4\u7B49\u7740\u6C34\u70E7\u5F00\u3002

    \u540C\u6B65\u975E\u963B\u585E\u6A21\u5F0F\uFF1A\u8FD9\u79CD\u6A21\u5F0F\u4E0B\uFF0C\u6211\u4EEC\u7684\u5DE5\u4F5C\u6A21\u5F0F\u662F\u5148\u6765\u5230\u53A8\u623F\uFF0C\u5F00\u59CB\u70E7\u6C34\uFF0C\u4F46\u662F\u6211\u4EEC\u4E0D\u4E00\u76F4\u5750\u5728\u6C34\u58F6\u524D\u9762\u7B49\uFF0C\u800C\u662F\u56DE\u5230\u5BA2\u5385\u770B\u7535\u89C6\uFF0C\u7136\u540E\u6BCF\u9694\u51E0\u5206\u949F\u5230\u53A8\u623F\u770B\u4E00\u4E0B\u6C34\u6709\u6CA1\u6709\u70E7\u5F00\u3002

    \u5F02\u6B65\u975E\u963B\u585E I/O \u6A21\u578B\uFF1A\u8FD9\u79CD\u6A21\u5F0F\u4E0B\uFF0C\u6211\u4EEC\u7684\u5DE5\u4F5C\u6A21\u5F0F\u662F\u5148\u6765\u5230\u53A8\u623F\uFF0C\u5F00\u59CB\u70E7\u6C34\uFF0C\u6211\u4EEC\u4E0D\u4E00\u76F4\u5750\u5728\u6C34\u58F6\u524D\u9762\u7B49\uFF0C\u4E5F\u4E0D\u9694\u4E00\u6BB5\u65F6\u95F4\u53BB\u770B\u4E00\u4E0B\uFF0C\u800C\u662F\u5728\u5BA2\u5385\u770B\u7535\u89C6\uFF0C\u6C34\u58F6\u4E0A\u9762\u6709\u4E2A\u5F00\u5173\uFF0C\u6C34\u70E7\u5F00\u4E4B\u540E\u4ED6\u4F1A\u901A\u77E5\u6211\u3002

    \u963B\u585E VS \u975E\u963B\u585E\uFF1A\u4EBA\u662F\u5426\u5750\u5728\u6C34\u58F6\u524D\u9762\u4E00\u76F4\u7B49\u3002

    \u540C\u6B65 VS \u5F02\u6B65\uFF1A\u6C34\u58F6\u662F\u4E0D\u662F\u5728\u6C34\u70E7\u5F00\u4E4B\u540E\u4E3B\u52A8\u901A\u77E5\u4EBA\u3002

    \u9002\u7528\u573A\u666F

    BIO \u65B9\u5F0F\u9002\u7528\u4E8E\u8FDE\u63A5\u6570\u76EE\u6BD4\u8F83\u5C0F\u4E14\u56FA\u5B9A\u7684\u67B6\u6784\uFF0C\u8FD9\u79CD\u65B9\u5F0F\u5BF9\u670D\u52A1\u5668\u8D44\u6E90\u8981\u6C42\u6BD4\u8F83\u9AD8\uFF0C\u5E76\u53D1\u5C40\u9650\u4E8E\u5E94\u7528\u4E2D\uFF0CJDK1.4 \u4EE5\u524D\u7684\u552F\u4E00\u9009\u62E9\uFF0C\u4F46\u7A0B\u5E8F\u76F4\u89C2\u7B80\u5355\u6613\u7406\u89E3\u3002

    NIO \u65B9\u5F0F\u9002\u7528\u4E8E\u8FDE\u63A5\u6570\u76EE\u591A\u4E14\u8FDE\u63A5\u6BD4\u8F83\u77ED\uFF08\u8F7B\u64CD\u4F5C\uFF09\u7684\u67B6\u6784\uFF0C\u6BD4\u5982\u804A\u5929\u670D\u52A1\u5668\uFF0C\u5E76\u53D1\u5C40\u9650\u4E8E\u5E94\u7528\u4E2D\uFF0C\u7F16\u7A0B\u6BD4\u8F83\u590D\u6742\uFF0CJDK1.4 \u5F00\u59CB\u652F\u6301\u3002

    AIO \u65B9\u5F0F\u9002\u7528\u4E8E\u8FDE\u63A5\u6570\u76EE\u591A\u4E14\u8FDE\u63A5\u6BD4\u8F83\u957F\uFF08\u91CD\u64CD\u4F5C\uFF09\u7684\u67B6\u6784\uFF0C\u6BD4\u5982\u76F8\u518C\u670D\u52A1\u5668\uFF0C\u5145\u5206\u8C03\u7528 OS \u53C2\u4E0E\u5E76\u53D1\u64CD\u4F5C\uFF0C\u7F16\u7A0B\u6BD4\u8F83\u590D\u6742\uFF0CJDK7 \u5F00\u59CB\u652F\u6301\u3002

    \u4F7F\u7528\u65B9\u5F0F

    \u4F7F\u7528 BIO \u5B9E\u73B0\u6587\u4EF6\u7684\u8BFB\u53D6\u548C\u5199\u5165\u3002

    //Initializes The Object
     User1 user = new User1();
     user.setName("wanger");
     user.setAge(23);
    diff --git a/dist/assets/BOKEYUANruhegaoxiaodixuexijishu.html.bdd4e19a.js b/dist/assets/BOKEYUANruhegaoxiaodixuexijishu.html.665a0cbe.js
    similarity index 99%
    rename from dist/assets/BOKEYUANruhegaoxiaodixuexijishu.html.bdd4e19a.js
    rename to dist/assets/BOKEYUANruhegaoxiaodixuexijishu.html.665a0cbe.js
    index 4a2e83a3..e9da7828 100644
    --- a/dist/assets/BOKEYUANruhegaoxiaodixuexijishu.html.bdd4e19a.js
    +++ b/dist/assets/BOKEYUANruhegaoxiaodixuexijishu.html.665a0cbe.js
    @@ -1 +1 @@
    -import{_ as h}from"./plugin-vue_export-helper.21dcd24c.js";import{r as l,o as t,c as n,a as e,b as o,e as i,d as a}from"./app.a0271b9c.js";const s={},d=i('

    \u6211\u4EEC\u76F8\u4FE1\u52AA\u529B\u5B66\u4E60\u4E00\u5B9A\u4F1A\u6709\u6536\u83B7\uFF0C\u4F46\u662F\u65B9\u6CD5\u4E0D\u5F53\uFF0C\u65E2\u8BA9\u4EBA\u8EAB\u5FC3\u75B2\u60EB\uFF0C\u4E5F\u6CA1\u6709\u5207\u5B9E\u7684\u56DE\u62A5\u3002\u9AD8\u4E2D\u65F6\u4EE3\uFF0C\u6211\u7684\u540C\u684C\u662F\u4E2A\u6F02\u4EAE\u5973\u540C\u5B66\u3002\u5979\u7684\u7269\u7406\u6210\u7EE9\u5F88\u5DEE\uFF0C\u867D\u7136\u5979\u975E\u5E38\u52E4\u594B\u7684\u5B66\u4E60\uFF0C\u4F46\u6210\u7EE9\u603B\u662F\u4E0D\u7406\u60F3\u3002\u4E3A\u4E86\u5DE9\u56FA\u7EAF\u6D01\u7684\u540C\u5B66\u5173\u7CFB\uFF0C\u6211\u4EB2\u5BC6\u65E0\u95F4\u5730\u8F85\u5BFC\u5979\u7684\u7269\u7406\uFF0C\u53D1\u73B0\u5979\u4E0D\u77E5\u9053\u9898\u76EE\u8003\u4EC0\u4E48\u3002\u6211\u4EEC\u7684\u6559\u79D1\u4E66\u4E0E\u8BD5\u9898\u90FD\u56F4\u7ED5\u7740\u8003\u8BD5\u5927\u7EB2\u5C55\u5F00\uFF0C\u770B\u5230\u4E00\u9053\u9898\uFF0C\u5E94\u8BE5\u5148\u60F3\u60F3\u5B83\u5728\u8003\u54EA\u4E9B\u5B9A\u7406\u548C\u516C\u5F0F\u7684\u8FD0\u7528\u3002
    \u2003\u2003\u4E0D\u5C11\u670B\u53CB\u6BCF\u5929\u90FD\u9605\u8BFB\u6280\u672F\u6587\u7AE0\uFF0C\u4F46\u662F\u7B2C\u4E8C\u5929\u5C31\u5FD8\u5E72\u51C0\u4E86\u3002\u5DE5\u4F5C\u4E2D\u9886\u5BFC\u548C\u540C\u4E8B\u90FD\u8BA4\u53EF\u4F60\u7684\u6C9F\u901A\u548C\u6280\u672F\u80FD\u529B\uFF0C\u4F46\u662F\u8DF3\u69FD\u9762\u8BD5\u5374\u5C61\u5C61\u78B0\u58C1\u3002\u9762\u8BD5\u5B98\u95EE\u6280\u672F\u65B9\u6848\uFF0C\u660E\u660E\u5FC3\u91CC\u6E05\u695A\uFF0C\u7528\u5634\u8BF4\u51FA\u6765\u5374\u524D\u8A00\u4E0D\u642D\u540E\u8BED\u3002\u9762\u8BD5\u5B98\u518D\u95EE\u5E95\u5C42\u7B97\u6CD5\uFF0C\u4F60\u8BF4\u770B\u8FC7\u4F46\u662F\u5FD8\u8BB0\u4E86\u3002\u4ED6\u4E0D\u5728\u4E4E\u4F60\u770B\u6CA1\u770B\u8FC7\uFF0C\u7B54\u4E0D\u4E0A\u5C31\u662F\u96F6\u5206\u3002\u6B63\u5982\u7537\u5973\u76F8\u4EB2\uFF0C\u7537\u65B9\u8C08\u5410\u6F47\u6D12\u624D\u80FD\u5438\u5F15\u59D1\u5A18\u3002\u53EF\u662F\u7537\u65B9\u7D27\u5F20\u4E86\uFF0C\u5E73\u65F6\u633A\u80FD\u8BF4\uFF0C\u5173\u952E\u65F6\u5019\u5374\u652F\u652F\u543E\u543E\uFF0C\u59D1\u5A18\u5FC5\u7136\u8BA4\u4E3A\u4ED6\u4E0D\u884C\u3002\u4EBA\u751F\u5145\u6EE1\u4E86\u8BB8\u591A\u8003\u8BD5\uFF0C\u6709\u5F62\u7684\u548C\u65E0\u5F62\u7684\uFF0C\u6BCF\u6B21\u8003\u8BD5\u7684\u673A\u4F1A\u53EA\u6709\u4E00\u6B21\u3002
    \u2003\u2003\u5DE5\u4F5C\u4E94\u5E74\u5341\u5E74\u540E\uFF0C\u522B\u4EBA\u6210\u4E86\u67B6\u6784\u5E08\uFF0C\u81EA\u5DF1\u8FD8\u5728\u57FA\u5C42\u6253\u6EDA\uFF0C\u539F\u56E0\u662F\u4EC0\u4E48\uFF1F\u804C\u573A\u4E0A\u65E0\u6CD5\u6210\u529F\u5347\u8FC1\u7684\u539F\u56E0\u6709\u5F88\u591A\uFF0C\u6CA1\u6709\u6301\u7EED\u5B66\u4E60\u3001\u5B66\u4E60\u6548\u679C\u4E0D\u597D\u3001\u65E0\u6CD5\u901A\u8FC7\u5FC3\u4EEA\u516C\u53F8\u7684\u7684\u9762\u8BD5\uFF0C\u4E00\u5B9A\u662F\u5F88\u91CD\u8981\u7684\u539F\u56E0\u3002
    \u2003\u2003\u628A\u81EA\u5DF1\u5F53\u6210\u4E00\u53F0\u8BA1\u7B97\u673A\uFF0C\u65E2\u6709\u8F93\u5165\uFF0C\u4E5F\u8981\u6709\u8F93\u51FA\uFF0C\u7528\u8F93\u51FA\u5012\u903C\u8F93\u5165\u3002

    \u5B66\u4EC0\u4E48

    \u57FA\u7840\u4E0E\u5E94\u7528

    \u8FD1\u4E9B\u5E74\u8BDE\u751F\u4E86\u8BB8\u591A\u65B0\u6280\u672F\uFF0C\u6BD4\u5982\u6700\u65F6\u9AE6\u7684AI(\u76EE\u524D\u8FD8\u5728\u667A\u969C\u9636\u6BB5)\uFF0C\u6570\u5B66\u57FA\u7840\u662F\u521D\u4E2D\u5C31\u63A5\u89E6\u8FC7\u7684\u6982\u7387\u7EDF\u8BA1\u3002\u4E07\u4E08\u9AD8\u697C\u4ECE\u5730\u8D77\uFF0C\u4E0D\u8981\u88AB\u65B0\u5DE5\u5177\u6216\u8005\u4E2D\u95F4\u4EF6\u8FF7\u4F4F\u53CC\u773C\uFF0C\u4E00\u5473\u5730\u8FFD\u65B0\u6C42\u5FEB\u3002\u57FA\u7840\u77E5\u8BC6\u662F\u6240\u6709\u6280\u672F\u7684\u57FA\u77F3\uFF0C\u5728\u672A\u6765\u5F88\u957F\u7684\u65F6\u95F4\u90FD\u4E0D\u4F1A\u53D8\u5316\uFF0C\u5E94\u8BE5\u82B1\u8D39\u8DB3\u591F\u7684\u65F6\u95F4\u5DE9\u56FA\u57FA\u7840\u3002
    \u2003\u2003\u4EE5\u6570\u636E\u7ED3\u6784\u548C\u7B97\u6CD5\u4E3A\u4F8B\uFF0C\u5927\u5BB6\u9605\u8BFB\u4E00\u4E0BJava\u7684BitSet\u7684\u6E90\u7801\uFF0C\u91CC\u9762\u6709\u5927\u91CF\u7684\u79FB\u4F4D\u64CD\u4F5C\uFF0C\u79FB\u4F4D\u8FD0\u7B97\u638C\u63E1\u7684\u597D\uFF0C\u770B\u8FD9\u4EFD\u6E90\u7801\u5C31\u6CA1\u95EE\u9898\u3002Java\u540C\u6B65\u5DE5\u5177\u7C7BAQS\u7528\u5230\u4E86\u53CC\u5411\u94FE\u8868\uFF0C\u94FE\u8868\u77E5\u8BC6\u4E0D\u8FC7\u5173\uFF0C\u80AF\u5B9A\u641E\u4E0D\u61C2\u5B83\u7684\u539F\u7406\u3002\u4E92\u8054\u7F51\u5927\u5382\u90FD\u559C\u6B22\u8003\u7B97\u6CD5\uFF0C\u4E3A\u4E86\u901A\u8FC7\u9762\u8BD5\u4E5F\u8981\u7CBE\u901A\u7B97\u6CD5\u3002
    \u2003\u2003\u4EE5Java\u5DE5\u7A0B\u5E08\u5E94\u8BE5\u638C\u63E1\u7684\u77E5\u8BC6\u4E3A\u4F8B\uFF0C\u6309\u91CD\u8981\u7A0B\u5EA6\u6392\u51FA\u516D\u4E2A\u68AF\u5EA6\uFF1A

    • \u7B2C\u4E00\u68AF\u5EA6\uFF1A\u8BA1\u7B97\u673A\u7EC4\u6210\u539F\u7406\u3001\u6570\u636E\u7ED3\u6784\u548C\u7B97\u6CD5\u3001\u7F51\u7EDC\u901A\u4FE1\u539F\u7406\u3001\u64CD\u4F5C\u7CFB\u7EDF\u539F\u7406\uFF1B
    • \u7B2C\u4E8C\u68AF\u5EA6\uFF1AJava\u57FA\u7840\u3001JVM\u5185\u5B58\u6A21\u578B\u548CGC\u7B97\u6CD5\u3001JVM\u6027\u80FD\u8C03\u4F18\u3001JDK\u5DE5\u5177\u3001\u8BBE\u8BA1\u6A21\u5F0F\uFF1B
    • \u7B2C\u4E09\u68AF\u5EA6\uFF1ASpring\u7CFB\u5217\u3001Mybatis\u3001Dubbo\u7B49\u4E3B\u6D41\u6846\u67B6\u7684\u8FD0\u7528\u548C\u539F\u7406\uFF1B
    • \u7B2C\u56DB\u68AF\u5EA6\uFF1AMySQL(\u542BSQL\u7F16\u7A0B)\u3001Redis\u3001RabbitMQ/RocketMQ/Kafka\u3001ZooKeeper\u7B49\u6570\u636E\u5E93\u6216\u8005\u4E2D\u95F4\u4EF6\u7684\u8FD0\u7528\u548C\u539F\u7406\uFF1B
    • \u7B2C\u4E94\u68AF\u5EA6\uFF1ACAP\u7406\u8BBA\u3001BASE\u7406\u8BBA\u3001Paxos\u548CRaft\u7B97\u6CD5\u7B49\u5176\u4ED6\u5206\u5E03\u5F0F\u7406\u8BBA\uFF1B
    • \u7B2C\u516D\u68AF\u5EA6\uFF1A\u5BB9\u5668\u5316\u3001\u5927\u6570\u636E\u3001AI\u3001\u533A\u5757\u94FE\u7B49\u7B49\u524D\u6CBF\u6280\u672F\u7406\u8BBA\uFF1B

    \u6709\u540C\u5B66\u8BA4\u4E3A\u7B2C\u4E94\u68AF\u5EA6\u5E94\u8BE5\u5728\u79FB\u5230\u7B2C\u4E00\u68AF\u5EA6\u3002\u5176\u5B9E\u5F88\u591A\u5C0F\u516C\u53F8\u7684\u65E5\u6D3B\u72B9\u5982\u53E4\u5929\u4E50\u4E00\u6837\u5E73\u5E73\u65E0\u5947\uFF0C\u79BB\u5927\u578B\u5206\u5E03\u5F0F\u67B6\u6784\u8FD8\u8FDC\u5F97\u5F88\u3002\u5B66\u4E60\u6846\u67B6\u548C\u4E2D\u95F4\u4EF6\u7684\u65F6\u5019\uFF0C\u987A\u624B\u638C\u63E1\u5206\u5E03\u5F0F\u7406\u8BBA\uFF0C\u6548\u679C\u66F4\u597D\u3002

    \u5E7F\u5EA6\u4E0E\u6DF1\u5EA6

    \u8BB8\u591A\u516C\u53F8\u7684\u62DB\u8058JD\u6CA1\u6709\u8BBE\u5B9A\u6280\u672F\u4EBA\u5458\u5E74\u9F84\u95E8\u69DB\uFF0C\u4F46\u662F\u4F1A\u52A0\u4E0A\u4E00\u53E5\u201C\u5177\u5907\u4E0E\u5E74\u9F84\u76F8\u5F53\u7684\u77E5\u8BC6\u7684\u5E7F\u5EA6\u4E0E\u6DF1\u5EA6\u201D\u3002\u591A\u5E7F\u624D\u7B97\u5E7F\uFF0C\u591A\u6DF1\u624D\u7B97\u6DF1\uFF1F\u8FD9\u662F\u5F88\u4E3B\u89C2\u7684\u8BDD\u9898\uFF0C\u8FD9\u91CC\u4E0D\u5C55\u5F00\u8BA8\u8BBA\u3002
    \u2003\u2003\u5982\u4F55\u53D8\u5F97\u66F4\u5E7F\u66F4\u6DF1\u5462\uFF1F\u7A81\u7834\u6536\u5165\u4E0A\u5347\u7684\u74F6\u9888\uFF0C\u53D1\u6398\u81EA\u5DF1\u771F\u6B63\u7684\u5174\u8DA3\u3002
    \u2003\u2003\u5927\u591A\u6570\u4EBA\u53EA\u662F\u516C\u53F8\u7684\u666E\u901A\u804C\u5458\uFF0C\u6536\u5165\u4E0A\u5347\u7684\u74F6\u9888\u5C31\u662F\u5347\u804C\u52A0\u85AA\u3002\u8BB8\u591AIT\u516C\u53F8\u4F1A\u5BF9\u6280\u672F\u4EBA\u5458\u6709\u4E2A\u8BC4\u7EA7\uFF0C\u5982\u679C\u4F60\u7684\u8BC4\u7EA7\u4E0D\u9AD8\uFF0C\u90A3\u5C31\u4F9D\u7167\u664B\u7EA7\u7AE0\u7A0B\u52AA\u529B\u5347\u7EA7\u3002\u5982\u679C\u4F60\u5728\u4E00\u4E2A\u5C0F\u516C\u53F8\uFF0C\u6536\u5165\u4E00\u822C\uFF0C\u53D1\u5C55\u524D\u666F\u4E0D\u660E\uFF0C\u51C6\u5907\u5927\u5382\u7684\u9762\u8BD5\u5C31\u662F\u6700\u597D\u7684\u5B66\u4E60\u8FC7\u7A0B\u3002\u5728\u8FD9\u4E9B\u8FC7\u7A0B\u4E2D\uFF0C\u4F60\u5FC5\u7136\u5B66\u4E60\u66F4\u591A\u77E5\u8BC6\uFF0C\u53D8\u5F97\u66F4\u5E7F\u66F4\u6DF1\u3002
    \u2003\u2003\u4E2A\u4EBA\u5174\u8DA3\u662F\u524D\u8FDB\u7684\u52A8\u529B\u4E4B\u4E00\uFF0C\u8BB8\u591A\u77E5\u540D\u5F00\u6E90\u9879\u76EE\u90FD\u6E90\u4E8E\u4F5C\u8005\u7684\u5174\u8DA3\u3002\u4E2A\u4EBA\u5174\u8DA3\u5E76\u4E0D\u5C40\u9650\u6280\u672F\u9886\u57DF\uFF0C\u53EF\u4EE5\u662F\u5176\u4ED6\u5B66\u79D1\u3002\u6211\u6709\u4E2A\u670B\u53CB\u559C\u6B22\u73A9\u5C71\u5730\u81EA\u884C\u8F66\uFF0C\u8FD8\u7ED9\u4E00\u4E9B\u505A\u81EA\u884C\u8F66\u8BDD\u9898\u7684\u81EA\u5A92\u4F53\u6295\u7A3F\u3002\u4E45\u800C\u4E45\u4E4B\uFF0C\u5C45\u7136\u80FD\u591F\u5199\u4E00\u624B\u597D\u6587\u7AE0\u4E86\uFF0C\u6211\u76F8\u4FE1\u4ED6\u4E5F\u80FD\u5199\u597D\u6280\u672F\u6587\u6863\u3002

    \u54F2\u5B66

    ',10),p=a("\u54F2\u5B66\u4E0D\u662F\u6545\u4F5C\u9AD8\u6DF1\u7684\u5B66\u79D1\uFF0C\u5B83\u7684\u73B0\u5B9E\u610F\u4E49\u5C31\u662F\u89E3\u51B3\u95EE\u9898\u3002\u5E74\u8F7B\u5C0F\u4F19\u662F\u600E\u4E48\u6CE1\u599E\u7684\uFF1F\u4E09\u5929\u4E24\u5934\u82B1\u4E0D\u65AD\uFF0C\u5927\u5EAD\u5E7F\u4F17\u8DEA\u6C42\u7231\u3002\u8FD9\u7C7B\u5957\u8DEF\u4E3A\u4EC0\u4E48\u603B\u662F\u80FD\u6210\u529F\u5462\uFF1F\u793C\u7269\u6EE1\u8DB3\u5973\u4EBA\u7684\u7269\u6B32\uFF0C\u5F53\u4F17\u6C42\u7231\u6EE1\u8DB3\u5973\u4EBA\u7684\u865A\u8363\u5FC3\uFF0C\u6295\u5176\u6240\u597D\u3002\u98DF\u5802\u5927\u5988\u6253\u83DC\u7684\u624B\u8D8A\u6765\u8D8A\u6296\uFF0C\u8FA3\u5B50\u9E21\u4E01\u53D8\u6210\u8FA3\u5B50\u8FA3\u4E01\uFF0C\u4E3A\u4EC0\u4E48\u5462\uFF1F\u98DF\u5802\u8981\u63A7\u5236\u6210\u672C\uFF0C\u76F4\u63A5\u63D0\u4EF7\u4F1A\u60F9\u4F17\u6012\u3002"),c=e("br",null,null,-1),f=a(" \u2003\u2003\u79D1\u5B66\u4E0A\u7684\u54F2\u5B66\uFF0C\u4E00\u822C\u6307\u7814\u7A76\u4E8B\u7269\u53D1\u5C55\u7684\u89C4\u5F8B\uFF0C\u5F52\u7EB3\u7EC8\u6781\u7684\u89E3\u51B3\u65B9\u6848\u3002\u8F6F\u4EF6\u884C\u4E1A\u5145\u6EE1\u54F2\u5B66\u5473\u9053\u7684\u4F5C\u54C1\u975E\u5E38\u591A\uFF0C\u6BD4\u5982"),u={href:"https://item.jd.com/12401749.html",target:"_blank",rel:"noopener noreferrer"},b=a("\u300A\u4EBA\u6708\u795E\u8BDD\u300B"),_=a("\u3002\u4E3E\u4E2A\u4F8B\u5B50\uFF0C\u5F53\u8F6F\u4EF6\u7CFB\u7EDF\u9047\u5230\u6027\u80FD\u95EE\u9898\uFF0C\u5C1D\u8BD5\u4E0B\u9762\u4E24\u79CD\u54F2\u5B66\u601D\u60F3\u63D0\u5347\u6027\u80FD\uFF1A"),g=i('
    • \u7A7A\u95F4\u6362\u65F6\u95F4\uFF1A\u6BD4\u5982\u5F15\u5165\u7F13\u5B58\uFF0C\u6D88\u8017\u989D\u5916\u7684\u5B58\u50A8\u63D0\u9AD8\u54CD\u5E94\u901F\u5EA6\u3002
    • \u65F6\u95F4\u6362\u7A7A\u95F4\uFF1A\u6BD4\u5982\u5927\u6587\u4EF6\u7684\u5206\u7247\u5904\u7406\uFF0C\u5206\u6BB5\u5904\u7406\u540E\u518D\u6C47\u603B\u7ED3\u679C\u3002

    \u8BBE\u8BA1\u7A33\u5065\u9AD8\u53EF\u7528\u7684\u7CFB\u7EDF\uFF0C\u5C1D\u8BD5\u4ECE\u4E09\u4E2A\u65B9\u9762\u8003\u8651\u95EE\u9898\uFF1A

    • \u5B58\u50A8\uFF1A\u6570\u636E\u4F1A\u4E22\u5931\u5417\uFF0C\u6570\u636E\u4E00\u81F4\u6027\u600E\u4E48\u89E3\u51B3\u3002
    • \u8BA1\u7B97\uFF1A\u8BA1\u7B97\u600E\u4E48\u6269\u5BB9\uFF0C\u5E94\u7528\u5141\u8BB8\u4EFB\u610F\u589E\u52A0\u8282\u70B9\u5417\u3002
    • \u4F20\u8F93\uFF1A\u7F51\u7EDC\u4E2D\u65AD\u6216\u62E5\u585E\u600E\u4E48\u529E\u3002

    \u4ECE\u65E0\u6570\u7684\u5931\u8D25\u6216\u8005\u6210\u529F\u7684\u7ECF\u9A8C\u4E2D\uFF0C\u603B\u7ED3\u51FA\u9AD8\u5EA6\u6982\u62EC\u6027\u7684\u65B9\u6848\uFF0C\u8BA9\u6211\u4EEC\u4E0B\u4E00\u6B65\u505A\u7684\u66F4\u597D\u3002

    \u82F1\u8BED

    \u82F1\u8BED\u662F\u6781\u4E3A\u91CD\u8981\u7684\u57FA\u7840\uFF0C\u5B66\u597D\u82F1\u8BED\u4E0E\u638C\u63E1\u7F16\u7A0B\u8BED\u8A00\u4E00\u6837\u91CD\u8981\u3002\u4E14\u4E0D\u8BF4\u5916\u4F01\u5BF9\u82F1\u8BED\u7684\u8981\u6C42\uFF0C\u8BB8\u591A\u77E5\u540D\u535A\u5BA2\u5C31\u662F\u628A\u82F1\u6587\u7FFB\u8BD1\u6210\u4E2D\u6587\uFF0C\u5145\u5F53\u77E5\u8BC6\u7684\u642C\u8FD0\u5DE5\u3002\u5982\u679C\u82F1\u8BED\u8DB3\u591F\u597D\uFF0C\u76F4\u63A5\u9605\u8BFB\u4E00\u624B\u82F1\u8BED\u8D44\u6599\uFF0C\u907F\u514D\u4ED6\u4EBA\u7FFB\u8BD1\u5B58\u5728\u7684\u8C2C\u8BEF\u3002

    \u600E\u4E48\u5B66

    \u77E5\u8BC6\u4F53\u7CFB

    \u4F53\u7CFB\u5316\u7684\u77E5\u8BC6\u6BD4\u96F6\u6563\u7684\u66F4\u5BB9\u6613\u8BB0\u5FC6\u548C\u7406\u89E3\uFF0C\u8FD9\u6B63\u5982\u4E00\u90E8\u597D\u7684\u7535\u89C6\u5267\uFF0C\u5267\u60C5\u73AF\u73AF\u76F8\u6263\u624D\u80FD\u5438\u5F15\u89C2\u4F17\u3002\u5EFA\u8BAE\u5927\u5BB6\u4F7F\u7528\u601D\u7EF4\u5BFC\u56FE\u7F57\u5217\u77E5\u8BC6\u70B9\uFF0C\u6784\u5EFA\u4F53\u7CFB\u7ED3\u6784\uFF0C\u5982\u4E0B\u56FE\u6240\u793A\uFF1A

    \u514B\u670D\u9057\u5FD8

    \u9AD8\u4E2D\u662F\u6211\u4EEC\u77E5\u8BC6\u7684\u5DC5\u5CF0\u65F6\u523B\uFF0C\u6BCF\u5468\u5C0F\u8003\u6BCF\u6708\u5927\u8003\uFF0C\u6559\u8F85\u8D44\u6599\u5806\u6210\u5C71\uFF0C\u5730\u72F1\u5F0F\u7684\u53CD\u590D\u64CD\u7EC3\u5F3A\u5316\u8BB0\u5FC6\u3002\u590D\u4E60\u662F\u5BF9\u6297\u9057\u5FD8\u7684\u552F\u4E00\u529E\u6CD5\u3002\u5927\u8111\u7684\u9057\u5FD8\u662F\u6709\u89C4\u5F8B\u7684\uFF0C\u5148\u5FEB\u540E\u6162\u3002\u4E00\u5929\u540E\uFF0C\u5B66\u5230\u7684\u77E5\u8BC6\u53EA\u5269\u4E0B\u539F\u6765\u768425%\uFF0C\u751A\u81F3\u66F4\u4F4E\u3002\u968F\u7740\u65F6\u95F4\u7684\u63A8\u79FB\uFF0C\u9057\u5FD8\u7684\u901F\u5EA6\u51CF\u6162\uFF0C\u9057\u5FD8\u7684\u6570\u91CF\u4E5F\u5C31\u51CF\u5C11\u3002

    \u65F6\u95F4\u95F4\u9694

    \u8BB0\u5FC6\u91CF

    \u521A\u770B\u5B8C

    100%

    20\u5206\u949F\u540E

    60%

    1\u5C0F\u65F6\u540E

    40%

    1\u5929\u540E

    30%

    2\u5929\u540E

    27%

    \u6BCF\u4E2A\u4EBA\u7684\u9057\u5FD8\u7A0B\u5EA6\u90FD\u4E0D\u4E00\u6837\uFF0C\u5EFA\u8BAE\u7B2C\u4E8C\u5929\u590D\u4E60\u524D\u4E00\u5929\u7684\u5185\u5BB9\uFF0C\u4E03\u5929\u540E\u590D\u4E60\u8FD9\u6BB5\u65F6\u95F4\u7684\u6240\u6709\u5185\u5BB9\u3002

    \u788E\u7247\u65F6\u95F4

    \u4E0D\u5C11\u670B\u53CB\u5229\u7528\u788E\u7247\u65F6\u95F4\u5B66\u4E60\uFF0C\u6BD4\u5982\u5728\u516C\u4EA4\u4E0A\u770B\u516C\u4F17\u53F7\u7684\u63A8\u9001\u3002\u5176\u5B9E\u6211\u4EEC\u90FD\u9AD8\u4F30\u4E86\u81EA\u5DF1\u7684\u6297\u5E72\u6270\u80FD\u529B\uFF0C\u5982\u679C\u5904\u5728\u5608\u6742\u7684\u73AF\u5883\uFF0C\u6CE8\u610F\u529B\u5BB9\u6613\u88AB\u6253\u65AD\uFF0C\u8BB0\u5FC6\u7559\u5B58\u5EA6\u4E5F\u5F88\u4F4E\u3002\u788E\u7247\u65F6\u95F4\u9002\u5408\u5B66\u4E60\u7B80\u5355\u5B64\u7ACB\u7684\u77E5\u8BC6\u70B9\uFF0C\u6BD4\u5982\u94FE\u8868\u7684\u5B9A\u4E49\u4E0E\u5B9E\u73B0\u3002
    \u2003\u2003\u5B66\u4E60\u590D\u6742\u7684\u77E5\u8BC6\uFF0C\u9700\u8981\u5927\u6BB5\u7684\u8FDE\u7EED\u65F6\u95F4\u3002\u56FE\u4E66\u9986\u662F\u4E2A\u597D\u5730\u65B9\uFF0C\u5B89\u9759\u6C1B\u56F4\u597D\u3002\u624B\u673A\u653E\u4E00\u8FB9\uFF0C\u4E0D\u8981\u7406\u4F1AQQ\u5FAE\u4FE1\uFF0C\u6700\u597D\u9605\u8BFB\u7EB8\u8D28\u4E66\uFF0C\u6CE1\u4E0A\u4E00\u6574\u5929\u3002\u6709\u4E9B\u57CE\u5E02\u51FA\u73B0\u4E86\u4ED8\u8D39\u81EA\u4E60\u5BA4\uFF0C\u63D0\u4F9B\u683C\u5B50\u95F4\u3001\u8336\u6C34\u7B49\u7B49\uFF0C\u4E5F\u662F\u975E\u5E38\u597D\u7684\u9009\u62E9\u3002

    \u7528\u8D77\u6765

    \u6280\u672F\u5206\u4EAB

    \u4ECE\u4E0B\u9762\u8FD9\u5F20\u56FE\u6211\u4EEC\u53EF\u4EE5\u770B\u5230\uFF0C\u6559\u6388\u4ED6\u4EBA\u662F\u77E5\u8BC6\u7559\u5B58\u7387\u6700\u9AD8\u7684\u65B9\u5F0F\u3002

    \u51C6\u5907PPT\u548C\u6F14\u8BB2\u5185\u5BB9\uFF0C\u7ED9\u540C\u4E8B\u6765\u4E00\u573A\u6280\u672F\u5206\u4EAB\u3002\u4E0D\u5149\u590D\u4E60\u77E5\u8BC6\uFF0C\u8FD8\u953B\u70BC\u53E3\u624D\u3002\u66FE\u7ECF\u6709\u4E2A\u540C\u4E8B\u8BF4\u8BDD\u53C8\u5FEB\u53C8\u6025\uFF0C\u53E3\u5934\u7985\u4E5F\u591A\uFF0C\u6BD4\u5982"\u5BF9\u5427\u3001\u662F\u4E0D\u662F\u201D\uFF0C\u522B\u4EBA\u7ECF\u5E38\u542C\u4E0D\u6E05\uFF0C\u4F46\u662F\u4ED6\u672C\u4EBA\u4E0D\u4EE5\u4E3A\u7136\u3002\u9886\u5BFC\u8BA9\u4ED6\u505A\u4E86\u51E0\u6B21\u6280\u672F\u5206\u4EAB\uFF0C\u542C\u4F17\u7684\u53CD\u5E94\u53EF\u60F3\u800C\u77E5\uFF0C\u4ED6\u624D\u5F7B\u5E95\u8BA4\u6E05\u7F3A\u70B9\u3002
    \u2003\u2003\u575A\u6301\u5199\u6280\u672F\u535A\u5BA2\uFF0C\u522B\u5728\u610F\u4F60\u5199\u7684\u4E1C\u897F\u5728\u7F51\u4E0A\u5DF2\u7ECF\u91CD\u590D\u5343\u767E\u904D\u3002\u5F53\u81EA\u5DF1\u52A8\u624B\u7684\u65F6\u5019\uFF0C\u624D\u4F1A\u610F\u8BC6\u5230\u773C\u9AD8\u624B\u4F4E\u3002\u8BA9\u6587\u7AE0\u8BFB\u8D77\u6765\u6D41\u7545\u6E05\u6670\uFF0C\u9700\u8981\u5455\u5FC3\u6CA5\u8840\u7684\u5220\u6539\u3002\u5199\u4F5C\u662F\u5BF9\u5927\u8111\u7684\u957F\u671F\u8003\u9A8C\uFF0C\u60F3\u4E0D\u5230\u80AF\u5B9A\u5199\u4E0D\u51FA\uFF0C\u60F3\u4E0D\u6E05\u695A\u80AF\u5B9A\u5199\u4E0D\u6E05\u695A\u3002

    \u9020\u4E2A\u8F6E\u5B50

    \u6211\u4EEC\u7ECF\u5E38\u8BF4\u4E0D\u8981\u91CD\u590D\u9020\u8F6E\u5B50\u3002\u4E3A\u4E86\u5F00\u53D1\u6548\u7387\uFF0C\u53EF\u4EE5\u4E0D\u9020\u8F6E\u5B50\uFF0C\u4F46\u662F\u5FC5\u987B\u5177\u5907\u9020\u8F6E\u5B50\u7684\u80FD\u529B\u3002\u5EFA\u8BAE\u9020\u4E00\u4E2A\u7B80\u5355\u7684MQ\uFF0C\u4F60\u80FD\u7528\u5230\u901A\u4FE1\u534F\u8BAE\u3001\u8BBE\u8BA1\u6A21\u5F0F\u3001\u961F\u5217\u7B49\u8BB8\u591A\u77E5\u8BC6\u3002\u5728\u9020\u8F6E\u5B50\u7684\u8FC7\u7A0B\u4E2D\uFF0C\u4F60\u4F1A\u9891\u7E41\u7684\u7FFB\u9605\u5404\u79CD\u624B\u518C\u6216\u8005\u535A\u5BA2\uFF0C\u8FD9\u5C31\u662F\u7528\u8F93\u51FA\u5012\u903C\u8F93\u5165\u3002

    ',33);function x(m,v){const r=l("ExternalLinkIcon");return t(),n("div",null,[d,e("p",null,[p,c,f,e("a",u,[b,o(r)]),_]),g])}var k=h(s,[["render",x],["__file","BOKEYUANruhegaoxiaodixuexijishu.html.vue"]]);export{k as default}; +import{_ as h}from"./plugin-vue_export-helper.21dcd24c.js";import{r as l,o as t,c as n,a as e,b as o,e as i,d as a}from"./app.615e41d8.js";const s={},d=i('

    \u6211\u4EEC\u76F8\u4FE1\u52AA\u529B\u5B66\u4E60\u4E00\u5B9A\u4F1A\u6709\u6536\u83B7\uFF0C\u4F46\u662F\u65B9\u6CD5\u4E0D\u5F53\uFF0C\u65E2\u8BA9\u4EBA\u8EAB\u5FC3\u75B2\u60EB\uFF0C\u4E5F\u6CA1\u6709\u5207\u5B9E\u7684\u56DE\u62A5\u3002\u9AD8\u4E2D\u65F6\u4EE3\uFF0C\u6211\u7684\u540C\u684C\u662F\u4E2A\u6F02\u4EAE\u5973\u540C\u5B66\u3002\u5979\u7684\u7269\u7406\u6210\u7EE9\u5F88\u5DEE\uFF0C\u867D\u7136\u5979\u975E\u5E38\u52E4\u594B\u7684\u5B66\u4E60\uFF0C\u4F46\u6210\u7EE9\u603B\u662F\u4E0D\u7406\u60F3\u3002\u4E3A\u4E86\u5DE9\u56FA\u7EAF\u6D01\u7684\u540C\u5B66\u5173\u7CFB\uFF0C\u6211\u4EB2\u5BC6\u65E0\u95F4\u5730\u8F85\u5BFC\u5979\u7684\u7269\u7406\uFF0C\u53D1\u73B0\u5979\u4E0D\u77E5\u9053\u9898\u76EE\u8003\u4EC0\u4E48\u3002\u6211\u4EEC\u7684\u6559\u79D1\u4E66\u4E0E\u8BD5\u9898\u90FD\u56F4\u7ED5\u7740\u8003\u8BD5\u5927\u7EB2\u5C55\u5F00\uFF0C\u770B\u5230\u4E00\u9053\u9898\uFF0C\u5E94\u8BE5\u5148\u60F3\u60F3\u5B83\u5728\u8003\u54EA\u4E9B\u5B9A\u7406\u548C\u516C\u5F0F\u7684\u8FD0\u7528\u3002
    \u2003\u2003\u4E0D\u5C11\u670B\u53CB\u6BCF\u5929\u90FD\u9605\u8BFB\u6280\u672F\u6587\u7AE0\uFF0C\u4F46\u662F\u7B2C\u4E8C\u5929\u5C31\u5FD8\u5E72\u51C0\u4E86\u3002\u5DE5\u4F5C\u4E2D\u9886\u5BFC\u548C\u540C\u4E8B\u90FD\u8BA4\u53EF\u4F60\u7684\u6C9F\u901A\u548C\u6280\u672F\u80FD\u529B\uFF0C\u4F46\u662F\u8DF3\u69FD\u9762\u8BD5\u5374\u5C61\u5C61\u78B0\u58C1\u3002\u9762\u8BD5\u5B98\u95EE\u6280\u672F\u65B9\u6848\uFF0C\u660E\u660E\u5FC3\u91CC\u6E05\u695A\uFF0C\u7528\u5634\u8BF4\u51FA\u6765\u5374\u524D\u8A00\u4E0D\u642D\u540E\u8BED\u3002\u9762\u8BD5\u5B98\u518D\u95EE\u5E95\u5C42\u7B97\u6CD5\uFF0C\u4F60\u8BF4\u770B\u8FC7\u4F46\u662F\u5FD8\u8BB0\u4E86\u3002\u4ED6\u4E0D\u5728\u4E4E\u4F60\u770B\u6CA1\u770B\u8FC7\uFF0C\u7B54\u4E0D\u4E0A\u5C31\u662F\u96F6\u5206\u3002\u6B63\u5982\u7537\u5973\u76F8\u4EB2\uFF0C\u7537\u65B9\u8C08\u5410\u6F47\u6D12\u624D\u80FD\u5438\u5F15\u59D1\u5A18\u3002\u53EF\u662F\u7537\u65B9\u7D27\u5F20\u4E86\uFF0C\u5E73\u65F6\u633A\u80FD\u8BF4\uFF0C\u5173\u952E\u65F6\u5019\u5374\u652F\u652F\u543E\u543E\uFF0C\u59D1\u5A18\u5FC5\u7136\u8BA4\u4E3A\u4ED6\u4E0D\u884C\u3002\u4EBA\u751F\u5145\u6EE1\u4E86\u8BB8\u591A\u8003\u8BD5\uFF0C\u6709\u5F62\u7684\u548C\u65E0\u5F62\u7684\uFF0C\u6BCF\u6B21\u8003\u8BD5\u7684\u673A\u4F1A\u53EA\u6709\u4E00\u6B21\u3002
    \u2003\u2003\u5DE5\u4F5C\u4E94\u5E74\u5341\u5E74\u540E\uFF0C\u522B\u4EBA\u6210\u4E86\u67B6\u6784\u5E08\uFF0C\u81EA\u5DF1\u8FD8\u5728\u57FA\u5C42\u6253\u6EDA\uFF0C\u539F\u56E0\u662F\u4EC0\u4E48\uFF1F\u804C\u573A\u4E0A\u65E0\u6CD5\u6210\u529F\u5347\u8FC1\u7684\u539F\u56E0\u6709\u5F88\u591A\uFF0C\u6CA1\u6709\u6301\u7EED\u5B66\u4E60\u3001\u5B66\u4E60\u6548\u679C\u4E0D\u597D\u3001\u65E0\u6CD5\u901A\u8FC7\u5FC3\u4EEA\u516C\u53F8\u7684\u7684\u9762\u8BD5\uFF0C\u4E00\u5B9A\u662F\u5F88\u91CD\u8981\u7684\u539F\u56E0\u3002
    \u2003\u2003\u628A\u81EA\u5DF1\u5F53\u6210\u4E00\u53F0\u8BA1\u7B97\u673A\uFF0C\u65E2\u6709\u8F93\u5165\uFF0C\u4E5F\u8981\u6709\u8F93\u51FA\uFF0C\u7528\u8F93\u51FA\u5012\u903C\u8F93\u5165\u3002

    \u5B66\u4EC0\u4E48

    \u57FA\u7840\u4E0E\u5E94\u7528

    \u8FD1\u4E9B\u5E74\u8BDE\u751F\u4E86\u8BB8\u591A\u65B0\u6280\u672F\uFF0C\u6BD4\u5982\u6700\u65F6\u9AE6\u7684AI(\u76EE\u524D\u8FD8\u5728\u667A\u969C\u9636\u6BB5)\uFF0C\u6570\u5B66\u57FA\u7840\u662F\u521D\u4E2D\u5C31\u63A5\u89E6\u8FC7\u7684\u6982\u7387\u7EDF\u8BA1\u3002\u4E07\u4E08\u9AD8\u697C\u4ECE\u5730\u8D77\uFF0C\u4E0D\u8981\u88AB\u65B0\u5DE5\u5177\u6216\u8005\u4E2D\u95F4\u4EF6\u8FF7\u4F4F\u53CC\u773C\uFF0C\u4E00\u5473\u5730\u8FFD\u65B0\u6C42\u5FEB\u3002\u57FA\u7840\u77E5\u8BC6\u662F\u6240\u6709\u6280\u672F\u7684\u57FA\u77F3\uFF0C\u5728\u672A\u6765\u5F88\u957F\u7684\u65F6\u95F4\u90FD\u4E0D\u4F1A\u53D8\u5316\uFF0C\u5E94\u8BE5\u82B1\u8D39\u8DB3\u591F\u7684\u65F6\u95F4\u5DE9\u56FA\u57FA\u7840\u3002
    \u2003\u2003\u4EE5\u6570\u636E\u7ED3\u6784\u548C\u7B97\u6CD5\u4E3A\u4F8B\uFF0C\u5927\u5BB6\u9605\u8BFB\u4E00\u4E0BJava\u7684BitSet\u7684\u6E90\u7801\uFF0C\u91CC\u9762\u6709\u5927\u91CF\u7684\u79FB\u4F4D\u64CD\u4F5C\uFF0C\u79FB\u4F4D\u8FD0\u7B97\u638C\u63E1\u7684\u597D\uFF0C\u770B\u8FD9\u4EFD\u6E90\u7801\u5C31\u6CA1\u95EE\u9898\u3002Java\u540C\u6B65\u5DE5\u5177\u7C7BAQS\u7528\u5230\u4E86\u53CC\u5411\u94FE\u8868\uFF0C\u94FE\u8868\u77E5\u8BC6\u4E0D\u8FC7\u5173\uFF0C\u80AF\u5B9A\u641E\u4E0D\u61C2\u5B83\u7684\u539F\u7406\u3002\u4E92\u8054\u7F51\u5927\u5382\u90FD\u559C\u6B22\u8003\u7B97\u6CD5\uFF0C\u4E3A\u4E86\u901A\u8FC7\u9762\u8BD5\u4E5F\u8981\u7CBE\u901A\u7B97\u6CD5\u3002
    \u2003\u2003\u4EE5Java\u5DE5\u7A0B\u5E08\u5E94\u8BE5\u638C\u63E1\u7684\u77E5\u8BC6\u4E3A\u4F8B\uFF0C\u6309\u91CD\u8981\u7A0B\u5EA6\u6392\u51FA\u516D\u4E2A\u68AF\u5EA6\uFF1A

    • \u7B2C\u4E00\u68AF\u5EA6\uFF1A\u8BA1\u7B97\u673A\u7EC4\u6210\u539F\u7406\u3001\u6570\u636E\u7ED3\u6784\u548C\u7B97\u6CD5\u3001\u7F51\u7EDC\u901A\u4FE1\u539F\u7406\u3001\u64CD\u4F5C\u7CFB\u7EDF\u539F\u7406\uFF1B
    • \u7B2C\u4E8C\u68AF\u5EA6\uFF1AJava\u57FA\u7840\u3001JVM\u5185\u5B58\u6A21\u578B\u548CGC\u7B97\u6CD5\u3001JVM\u6027\u80FD\u8C03\u4F18\u3001JDK\u5DE5\u5177\u3001\u8BBE\u8BA1\u6A21\u5F0F\uFF1B
    • \u7B2C\u4E09\u68AF\u5EA6\uFF1ASpring\u7CFB\u5217\u3001Mybatis\u3001Dubbo\u7B49\u4E3B\u6D41\u6846\u67B6\u7684\u8FD0\u7528\u548C\u539F\u7406\uFF1B
    • \u7B2C\u56DB\u68AF\u5EA6\uFF1AMySQL(\u542BSQL\u7F16\u7A0B)\u3001Redis\u3001RabbitMQ/RocketMQ/Kafka\u3001ZooKeeper\u7B49\u6570\u636E\u5E93\u6216\u8005\u4E2D\u95F4\u4EF6\u7684\u8FD0\u7528\u548C\u539F\u7406\uFF1B
    • \u7B2C\u4E94\u68AF\u5EA6\uFF1ACAP\u7406\u8BBA\u3001BASE\u7406\u8BBA\u3001Paxos\u548CRaft\u7B97\u6CD5\u7B49\u5176\u4ED6\u5206\u5E03\u5F0F\u7406\u8BBA\uFF1B
    • \u7B2C\u516D\u68AF\u5EA6\uFF1A\u5BB9\u5668\u5316\u3001\u5927\u6570\u636E\u3001AI\u3001\u533A\u5757\u94FE\u7B49\u7B49\u524D\u6CBF\u6280\u672F\u7406\u8BBA\uFF1B

    \u6709\u540C\u5B66\u8BA4\u4E3A\u7B2C\u4E94\u68AF\u5EA6\u5E94\u8BE5\u5728\u79FB\u5230\u7B2C\u4E00\u68AF\u5EA6\u3002\u5176\u5B9E\u5F88\u591A\u5C0F\u516C\u53F8\u7684\u65E5\u6D3B\u72B9\u5982\u53E4\u5929\u4E50\u4E00\u6837\u5E73\u5E73\u65E0\u5947\uFF0C\u79BB\u5927\u578B\u5206\u5E03\u5F0F\u67B6\u6784\u8FD8\u8FDC\u5F97\u5F88\u3002\u5B66\u4E60\u6846\u67B6\u548C\u4E2D\u95F4\u4EF6\u7684\u65F6\u5019\uFF0C\u987A\u624B\u638C\u63E1\u5206\u5E03\u5F0F\u7406\u8BBA\uFF0C\u6548\u679C\u66F4\u597D\u3002

    \u5E7F\u5EA6\u4E0E\u6DF1\u5EA6

    \u8BB8\u591A\u516C\u53F8\u7684\u62DB\u8058JD\u6CA1\u6709\u8BBE\u5B9A\u6280\u672F\u4EBA\u5458\u5E74\u9F84\u95E8\u69DB\uFF0C\u4F46\u662F\u4F1A\u52A0\u4E0A\u4E00\u53E5\u201C\u5177\u5907\u4E0E\u5E74\u9F84\u76F8\u5F53\u7684\u77E5\u8BC6\u7684\u5E7F\u5EA6\u4E0E\u6DF1\u5EA6\u201D\u3002\u591A\u5E7F\u624D\u7B97\u5E7F\uFF0C\u591A\u6DF1\u624D\u7B97\u6DF1\uFF1F\u8FD9\u662F\u5F88\u4E3B\u89C2\u7684\u8BDD\u9898\uFF0C\u8FD9\u91CC\u4E0D\u5C55\u5F00\u8BA8\u8BBA\u3002
    \u2003\u2003\u5982\u4F55\u53D8\u5F97\u66F4\u5E7F\u66F4\u6DF1\u5462\uFF1F\u7A81\u7834\u6536\u5165\u4E0A\u5347\u7684\u74F6\u9888\uFF0C\u53D1\u6398\u81EA\u5DF1\u771F\u6B63\u7684\u5174\u8DA3\u3002
    \u2003\u2003\u5927\u591A\u6570\u4EBA\u53EA\u662F\u516C\u53F8\u7684\u666E\u901A\u804C\u5458\uFF0C\u6536\u5165\u4E0A\u5347\u7684\u74F6\u9888\u5C31\u662F\u5347\u804C\u52A0\u85AA\u3002\u8BB8\u591AIT\u516C\u53F8\u4F1A\u5BF9\u6280\u672F\u4EBA\u5458\u6709\u4E2A\u8BC4\u7EA7\uFF0C\u5982\u679C\u4F60\u7684\u8BC4\u7EA7\u4E0D\u9AD8\uFF0C\u90A3\u5C31\u4F9D\u7167\u664B\u7EA7\u7AE0\u7A0B\u52AA\u529B\u5347\u7EA7\u3002\u5982\u679C\u4F60\u5728\u4E00\u4E2A\u5C0F\u516C\u53F8\uFF0C\u6536\u5165\u4E00\u822C\uFF0C\u53D1\u5C55\u524D\u666F\u4E0D\u660E\uFF0C\u51C6\u5907\u5927\u5382\u7684\u9762\u8BD5\u5C31\u662F\u6700\u597D\u7684\u5B66\u4E60\u8FC7\u7A0B\u3002\u5728\u8FD9\u4E9B\u8FC7\u7A0B\u4E2D\uFF0C\u4F60\u5FC5\u7136\u5B66\u4E60\u66F4\u591A\u77E5\u8BC6\uFF0C\u53D8\u5F97\u66F4\u5E7F\u66F4\u6DF1\u3002
    \u2003\u2003\u4E2A\u4EBA\u5174\u8DA3\u662F\u524D\u8FDB\u7684\u52A8\u529B\u4E4B\u4E00\uFF0C\u8BB8\u591A\u77E5\u540D\u5F00\u6E90\u9879\u76EE\u90FD\u6E90\u4E8E\u4F5C\u8005\u7684\u5174\u8DA3\u3002\u4E2A\u4EBA\u5174\u8DA3\u5E76\u4E0D\u5C40\u9650\u6280\u672F\u9886\u57DF\uFF0C\u53EF\u4EE5\u662F\u5176\u4ED6\u5B66\u79D1\u3002\u6211\u6709\u4E2A\u670B\u53CB\u559C\u6B22\u73A9\u5C71\u5730\u81EA\u884C\u8F66\uFF0C\u8FD8\u7ED9\u4E00\u4E9B\u505A\u81EA\u884C\u8F66\u8BDD\u9898\u7684\u81EA\u5A92\u4F53\u6295\u7A3F\u3002\u4E45\u800C\u4E45\u4E4B\uFF0C\u5C45\u7136\u80FD\u591F\u5199\u4E00\u624B\u597D\u6587\u7AE0\u4E86\uFF0C\u6211\u76F8\u4FE1\u4ED6\u4E5F\u80FD\u5199\u597D\u6280\u672F\u6587\u6863\u3002

    \u54F2\u5B66

    ',10),p=a("\u54F2\u5B66\u4E0D\u662F\u6545\u4F5C\u9AD8\u6DF1\u7684\u5B66\u79D1\uFF0C\u5B83\u7684\u73B0\u5B9E\u610F\u4E49\u5C31\u662F\u89E3\u51B3\u95EE\u9898\u3002\u5E74\u8F7B\u5C0F\u4F19\u662F\u600E\u4E48\u6CE1\u599E\u7684\uFF1F\u4E09\u5929\u4E24\u5934\u82B1\u4E0D\u65AD\uFF0C\u5927\u5EAD\u5E7F\u4F17\u8DEA\u6C42\u7231\u3002\u8FD9\u7C7B\u5957\u8DEF\u4E3A\u4EC0\u4E48\u603B\u662F\u80FD\u6210\u529F\u5462\uFF1F\u793C\u7269\u6EE1\u8DB3\u5973\u4EBA\u7684\u7269\u6B32\uFF0C\u5F53\u4F17\u6C42\u7231\u6EE1\u8DB3\u5973\u4EBA\u7684\u865A\u8363\u5FC3\uFF0C\u6295\u5176\u6240\u597D\u3002\u98DF\u5802\u5927\u5988\u6253\u83DC\u7684\u624B\u8D8A\u6765\u8D8A\u6296\uFF0C\u8FA3\u5B50\u9E21\u4E01\u53D8\u6210\u8FA3\u5B50\u8FA3\u4E01\uFF0C\u4E3A\u4EC0\u4E48\u5462\uFF1F\u98DF\u5802\u8981\u63A7\u5236\u6210\u672C\uFF0C\u76F4\u63A5\u63D0\u4EF7\u4F1A\u60F9\u4F17\u6012\u3002"),c=e("br",null,null,-1),f=a(" \u2003\u2003\u79D1\u5B66\u4E0A\u7684\u54F2\u5B66\uFF0C\u4E00\u822C\u6307\u7814\u7A76\u4E8B\u7269\u53D1\u5C55\u7684\u89C4\u5F8B\uFF0C\u5F52\u7EB3\u7EC8\u6781\u7684\u89E3\u51B3\u65B9\u6848\u3002\u8F6F\u4EF6\u884C\u4E1A\u5145\u6EE1\u54F2\u5B66\u5473\u9053\u7684\u4F5C\u54C1\u975E\u5E38\u591A\uFF0C\u6BD4\u5982"),u={href:"https://item.jd.com/12401749.html",target:"_blank",rel:"noopener noreferrer"},b=a("\u300A\u4EBA\u6708\u795E\u8BDD\u300B"),_=a("\u3002\u4E3E\u4E2A\u4F8B\u5B50\uFF0C\u5F53\u8F6F\u4EF6\u7CFB\u7EDF\u9047\u5230\u6027\u80FD\u95EE\u9898\uFF0C\u5C1D\u8BD5\u4E0B\u9762\u4E24\u79CD\u54F2\u5B66\u601D\u60F3\u63D0\u5347\u6027\u80FD\uFF1A"),g=i('
    • \u7A7A\u95F4\u6362\u65F6\u95F4\uFF1A\u6BD4\u5982\u5F15\u5165\u7F13\u5B58\uFF0C\u6D88\u8017\u989D\u5916\u7684\u5B58\u50A8\u63D0\u9AD8\u54CD\u5E94\u901F\u5EA6\u3002
    • \u65F6\u95F4\u6362\u7A7A\u95F4\uFF1A\u6BD4\u5982\u5927\u6587\u4EF6\u7684\u5206\u7247\u5904\u7406\uFF0C\u5206\u6BB5\u5904\u7406\u540E\u518D\u6C47\u603B\u7ED3\u679C\u3002

    \u8BBE\u8BA1\u7A33\u5065\u9AD8\u53EF\u7528\u7684\u7CFB\u7EDF\uFF0C\u5C1D\u8BD5\u4ECE\u4E09\u4E2A\u65B9\u9762\u8003\u8651\u95EE\u9898\uFF1A

    • \u5B58\u50A8\uFF1A\u6570\u636E\u4F1A\u4E22\u5931\u5417\uFF0C\u6570\u636E\u4E00\u81F4\u6027\u600E\u4E48\u89E3\u51B3\u3002
    • \u8BA1\u7B97\uFF1A\u8BA1\u7B97\u600E\u4E48\u6269\u5BB9\uFF0C\u5E94\u7528\u5141\u8BB8\u4EFB\u610F\u589E\u52A0\u8282\u70B9\u5417\u3002
    • \u4F20\u8F93\uFF1A\u7F51\u7EDC\u4E2D\u65AD\u6216\u62E5\u585E\u600E\u4E48\u529E\u3002

    \u4ECE\u65E0\u6570\u7684\u5931\u8D25\u6216\u8005\u6210\u529F\u7684\u7ECF\u9A8C\u4E2D\uFF0C\u603B\u7ED3\u51FA\u9AD8\u5EA6\u6982\u62EC\u6027\u7684\u65B9\u6848\uFF0C\u8BA9\u6211\u4EEC\u4E0B\u4E00\u6B65\u505A\u7684\u66F4\u597D\u3002

    \u82F1\u8BED

    \u82F1\u8BED\u662F\u6781\u4E3A\u91CD\u8981\u7684\u57FA\u7840\uFF0C\u5B66\u597D\u82F1\u8BED\u4E0E\u638C\u63E1\u7F16\u7A0B\u8BED\u8A00\u4E00\u6837\u91CD\u8981\u3002\u4E14\u4E0D\u8BF4\u5916\u4F01\u5BF9\u82F1\u8BED\u7684\u8981\u6C42\uFF0C\u8BB8\u591A\u77E5\u540D\u535A\u5BA2\u5C31\u662F\u628A\u82F1\u6587\u7FFB\u8BD1\u6210\u4E2D\u6587\uFF0C\u5145\u5F53\u77E5\u8BC6\u7684\u642C\u8FD0\u5DE5\u3002\u5982\u679C\u82F1\u8BED\u8DB3\u591F\u597D\uFF0C\u76F4\u63A5\u9605\u8BFB\u4E00\u624B\u82F1\u8BED\u8D44\u6599\uFF0C\u907F\u514D\u4ED6\u4EBA\u7FFB\u8BD1\u5B58\u5728\u7684\u8C2C\u8BEF\u3002

    \u600E\u4E48\u5B66

    \u77E5\u8BC6\u4F53\u7CFB

    \u4F53\u7CFB\u5316\u7684\u77E5\u8BC6\u6BD4\u96F6\u6563\u7684\u66F4\u5BB9\u6613\u8BB0\u5FC6\u548C\u7406\u89E3\uFF0C\u8FD9\u6B63\u5982\u4E00\u90E8\u597D\u7684\u7535\u89C6\u5267\uFF0C\u5267\u60C5\u73AF\u73AF\u76F8\u6263\u624D\u80FD\u5438\u5F15\u89C2\u4F17\u3002\u5EFA\u8BAE\u5927\u5BB6\u4F7F\u7528\u601D\u7EF4\u5BFC\u56FE\u7F57\u5217\u77E5\u8BC6\u70B9\uFF0C\u6784\u5EFA\u4F53\u7CFB\u7ED3\u6784\uFF0C\u5982\u4E0B\u56FE\u6240\u793A\uFF1A

    \u514B\u670D\u9057\u5FD8

    \u9AD8\u4E2D\u662F\u6211\u4EEC\u77E5\u8BC6\u7684\u5DC5\u5CF0\u65F6\u523B\uFF0C\u6BCF\u5468\u5C0F\u8003\u6BCF\u6708\u5927\u8003\uFF0C\u6559\u8F85\u8D44\u6599\u5806\u6210\u5C71\uFF0C\u5730\u72F1\u5F0F\u7684\u53CD\u590D\u64CD\u7EC3\u5F3A\u5316\u8BB0\u5FC6\u3002\u590D\u4E60\u662F\u5BF9\u6297\u9057\u5FD8\u7684\u552F\u4E00\u529E\u6CD5\u3002\u5927\u8111\u7684\u9057\u5FD8\u662F\u6709\u89C4\u5F8B\u7684\uFF0C\u5148\u5FEB\u540E\u6162\u3002\u4E00\u5929\u540E\uFF0C\u5B66\u5230\u7684\u77E5\u8BC6\u53EA\u5269\u4E0B\u539F\u6765\u768425%\uFF0C\u751A\u81F3\u66F4\u4F4E\u3002\u968F\u7740\u65F6\u95F4\u7684\u63A8\u79FB\uFF0C\u9057\u5FD8\u7684\u901F\u5EA6\u51CF\u6162\uFF0C\u9057\u5FD8\u7684\u6570\u91CF\u4E5F\u5C31\u51CF\u5C11\u3002

    \u65F6\u95F4\u95F4\u9694

    \u8BB0\u5FC6\u91CF

    \u521A\u770B\u5B8C

    100%

    20\u5206\u949F\u540E

    60%

    1\u5C0F\u65F6\u540E

    40%

    1\u5929\u540E

    30%

    2\u5929\u540E

    27%

    \u6BCF\u4E2A\u4EBA\u7684\u9057\u5FD8\u7A0B\u5EA6\u90FD\u4E0D\u4E00\u6837\uFF0C\u5EFA\u8BAE\u7B2C\u4E8C\u5929\u590D\u4E60\u524D\u4E00\u5929\u7684\u5185\u5BB9\uFF0C\u4E03\u5929\u540E\u590D\u4E60\u8FD9\u6BB5\u65F6\u95F4\u7684\u6240\u6709\u5185\u5BB9\u3002

    \u788E\u7247\u65F6\u95F4

    \u4E0D\u5C11\u670B\u53CB\u5229\u7528\u788E\u7247\u65F6\u95F4\u5B66\u4E60\uFF0C\u6BD4\u5982\u5728\u516C\u4EA4\u4E0A\u770B\u516C\u4F17\u53F7\u7684\u63A8\u9001\u3002\u5176\u5B9E\u6211\u4EEC\u90FD\u9AD8\u4F30\u4E86\u81EA\u5DF1\u7684\u6297\u5E72\u6270\u80FD\u529B\uFF0C\u5982\u679C\u5904\u5728\u5608\u6742\u7684\u73AF\u5883\uFF0C\u6CE8\u610F\u529B\u5BB9\u6613\u88AB\u6253\u65AD\uFF0C\u8BB0\u5FC6\u7559\u5B58\u5EA6\u4E5F\u5F88\u4F4E\u3002\u788E\u7247\u65F6\u95F4\u9002\u5408\u5B66\u4E60\u7B80\u5355\u5B64\u7ACB\u7684\u77E5\u8BC6\u70B9\uFF0C\u6BD4\u5982\u94FE\u8868\u7684\u5B9A\u4E49\u4E0E\u5B9E\u73B0\u3002
    \u2003\u2003\u5B66\u4E60\u590D\u6742\u7684\u77E5\u8BC6\uFF0C\u9700\u8981\u5927\u6BB5\u7684\u8FDE\u7EED\u65F6\u95F4\u3002\u56FE\u4E66\u9986\u662F\u4E2A\u597D\u5730\u65B9\uFF0C\u5B89\u9759\u6C1B\u56F4\u597D\u3002\u624B\u673A\u653E\u4E00\u8FB9\uFF0C\u4E0D\u8981\u7406\u4F1AQQ\u5FAE\u4FE1\uFF0C\u6700\u597D\u9605\u8BFB\u7EB8\u8D28\u4E66\uFF0C\u6CE1\u4E0A\u4E00\u6574\u5929\u3002\u6709\u4E9B\u57CE\u5E02\u51FA\u73B0\u4E86\u4ED8\u8D39\u81EA\u4E60\u5BA4\uFF0C\u63D0\u4F9B\u683C\u5B50\u95F4\u3001\u8336\u6C34\u7B49\u7B49\uFF0C\u4E5F\u662F\u975E\u5E38\u597D\u7684\u9009\u62E9\u3002

    \u7528\u8D77\u6765

    \u6280\u672F\u5206\u4EAB

    \u4ECE\u4E0B\u9762\u8FD9\u5F20\u56FE\u6211\u4EEC\u53EF\u4EE5\u770B\u5230\uFF0C\u6559\u6388\u4ED6\u4EBA\u662F\u77E5\u8BC6\u7559\u5B58\u7387\u6700\u9AD8\u7684\u65B9\u5F0F\u3002

    \u51C6\u5907PPT\u548C\u6F14\u8BB2\u5185\u5BB9\uFF0C\u7ED9\u540C\u4E8B\u6765\u4E00\u573A\u6280\u672F\u5206\u4EAB\u3002\u4E0D\u5149\u590D\u4E60\u77E5\u8BC6\uFF0C\u8FD8\u953B\u70BC\u53E3\u624D\u3002\u66FE\u7ECF\u6709\u4E2A\u540C\u4E8B\u8BF4\u8BDD\u53C8\u5FEB\u53C8\u6025\uFF0C\u53E3\u5934\u7985\u4E5F\u591A\uFF0C\u6BD4\u5982"\u5BF9\u5427\u3001\u662F\u4E0D\u662F\u201D\uFF0C\u522B\u4EBA\u7ECF\u5E38\u542C\u4E0D\u6E05\uFF0C\u4F46\u662F\u4ED6\u672C\u4EBA\u4E0D\u4EE5\u4E3A\u7136\u3002\u9886\u5BFC\u8BA9\u4ED6\u505A\u4E86\u51E0\u6B21\u6280\u672F\u5206\u4EAB\uFF0C\u542C\u4F17\u7684\u53CD\u5E94\u53EF\u60F3\u800C\u77E5\uFF0C\u4ED6\u624D\u5F7B\u5E95\u8BA4\u6E05\u7F3A\u70B9\u3002
    \u2003\u2003\u575A\u6301\u5199\u6280\u672F\u535A\u5BA2\uFF0C\u522B\u5728\u610F\u4F60\u5199\u7684\u4E1C\u897F\u5728\u7F51\u4E0A\u5DF2\u7ECF\u91CD\u590D\u5343\u767E\u904D\u3002\u5F53\u81EA\u5DF1\u52A8\u624B\u7684\u65F6\u5019\uFF0C\u624D\u4F1A\u610F\u8BC6\u5230\u773C\u9AD8\u624B\u4F4E\u3002\u8BA9\u6587\u7AE0\u8BFB\u8D77\u6765\u6D41\u7545\u6E05\u6670\uFF0C\u9700\u8981\u5455\u5FC3\u6CA5\u8840\u7684\u5220\u6539\u3002\u5199\u4F5C\u662F\u5BF9\u5927\u8111\u7684\u957F\u671F\u8003\u9A8C\uFF0C\u60F3\u4E0D\u5230\u80AF\u5B9A\u5199\u4E0D\u51FA\uFF0C\u60F3\u4E0D\u6E05\u695A\u80AF\u5B9A\u5199\u4E0D\u6E05\u695A\u3002

    \u9020\u4E2A\u8F6E\u5B50

    \u6211\u4EEC\u7ECF\u5E38\u8BF4\u4E0D\u8981\u91CD\u590D\u9020\u8F6E\u5B50\u3002\u4E3A\u4E86\u5F00\u53D1\u6548\u7387\uFF0C\u53EF\u4EE5\u4E0D\u9020\u8F6E\u5B50\uFF0C\u4F46\u662F\u5FC5\u987B\u5177\u5907\u9020\u8F6E\u5B50\u7684\u80FD\u529B\u3002\u5EFA\u8BAE\u9020\u4E00\u4E2A\u7B80\u5355\u7684MQ\uFF0C\u4F60\u80FD\u7528\u5230\u901A\u4FE1\u534F\u8BAE\u3001\u8BBE\u8BA1\u6A21\u5F0F\u3001\u961F\u5217\u7B49\u8BB8\u591A\u77E5\u8BC6\u3002\u5728\u9020\u8F6E\u5B50\u7684\u8FC7\u7A0B\u4E2D\uFF0C\u4F60\u4F1A\u9891\u7E41\u7684\u7FFB\u9605\u5404\u79CD\u624B\u518C\u6216\u8005\u535A\u5BA2\uFF0C\u8FD9\u5C31\u662F\u7528\u8F93\u51FA\u5012\u903C\u8F93\u5165\u3002

    ',33);function x(m,v){const r=l("ExternalLinkIcon");return t(),n("div",null,[d,e("p",null,[p,c,f,e("a",u,[b,o(r)]),_]),g])}var k=h(s,[["render",x],["__file","BOKEYUANruhegaoxiaodixuexijishu.html.vue"]]);export{k as default}; diff --git a/dist/assets/BlockingQueue.html.5fa0f03a.js b/dist/assets/BlockingQueue.html.76b31f3c.js similarity index 99% rename from dist/assets/BlockingQueue.html.5fa0f03a.js rename to dist/assets/BlockingQueue.html.76b31f3c.js index 3c44a29c..18cb1e5b 100644 --- a/dist/assets/BlockingQueue.html.5fa0f03a.js +++ b/dist/assets/BlockingQueue.html.76b31f3c.js @@ -1,4 +1,4 @@ -import{_ as t}from"./plugin-vue_export-helper.21dcd24c.js";import{r as p,o,c,a as n,b as a,e as l,d as e}from"./app.a0271b9c.js";const i={},u=l(`

    \u6700\u5E38\u7528\u7684"\u751F\u4EA7\u8005-\u6D88\u8D39\u8005"\u95EE\u9898\u4E2D\uFF0C\u961F\u5217\u901A\u5E38\u88AB\u89C6\u4F5C\u7EBF\u7A0B\u95F4\u64CD\u4F5C\u7684\u6570\u636E\u5BB9\u5668\uFF0C\u8FD9\u6837\uFF0C\u53EF\u4EE5\u5BF9\u5404\u4E2A\u6A21\u5757\u7684\u4E1A\u52A1\u529F\u80FD\u8FDB\u884C\u89E3\u8026\uFF0C\u751F\u4EA7\u8005\u5C06\u201C\u751F\u4EA7\u201D\u51FA\u6765\u7684\u6570\u636E\u653E\u7F6E\u5728\u6570\u636E\u5BB9\u5668\u4E2D\uFF0C\u800C\u6D88\u8D39\u8005\u4EC5\u4EC5\u53EA\u9700\u8981\u5728\u201C\u6570\u636E\u5BB9\u5668\u201D\u4E2D\u8FDB\u884C\u83B7\u53D6\u6570\u636E\u5373\u53EF\uFF0C\u8FD9\u6837\u751F\u4EA7\u8005\u7EBF\u7A0B\u548C\u6D88\u8D39\u8005\u7EBF\u7A0B\u5C31\u80FD\u591F\u8FDB\u884C\u89E3\u8026\uFF0C\u53EA\u4E13\u6CE8\u4E8E\u81EA\u5DF1\u7684\u4E1A\u52A1\u529F\u80FD\u5373\u53EF\u3002

    \u963B\u585E\u961F\u5217\uFF08BlockingQueue\uFF09\u88AB\u5E7F\u6CDB\u4F7F\u7528\u5728\u201C\u751F\u4EA7\u8005-\u6D88\u8D39\u8005\u201D\u95EE\u9898\u4E2D\uFF0C\u5176\u539F\u56E0\u662FBlockingQueue\u63D0\u4F9B\u4E86\u53EF\u963B\u585E\u7684\u63D2\u5165\u548C\u79FB\u9664\u7684\u65B9\u6CD5\u3002\u5F53\u961F\u5217\u5BB9\u5668\u5DF2\u6EE1\uFF0C\u751F\u4EA7\u8005\u7EBF\u7A0B\u4F1A\u88AB\u963B\u585E\uFF0C\u76F4\u5230\u961F\u5217\u672A\u6EE1\uFF1B\u5F53\u961F\u5217\u5BB9\u5668\u4E3A\u7A7A\u65F6\uFF0C\u6D88\u8D39\u8005\u7EBF\u7A0B\u4F1A\u88AB\u963B\u585E\uFF0C\u76F4\u81F3\u961F\u5217\u975E\u7A7A\u65F6\u4E3A\u6B62\u3002

    \u57FA\u672C\u64CD\u4F5C

    BlockingQueue\u57FA\u672C\u64CD\u4F5C\u603B\u7ED3\u5982\u4E0B\uFF08\u6B64\u56FE\u6765\u6E90\u4E8EJAVA API\u6587\u6863\uFF09\uFF1A

    BlockingQueue\u7EE7\u627F\u4E8EQueue\u63A5\u53E3\uFF0C\u56E0\u6B64\uFF0C\u5BF9\u6570\u636E\u5143\u7D20\u7684\u57FA\u672C\u64CD\u4F5C\u6709\uFF1A

    1\uFF09\u63D2\u5165\u5143\u7D20

    1. add(E e) \uFF1A\u5F80\u961F\u5217\u63D2\u5165\u6570\u636E\uFF0C\u5F53\u961F\u5217\u6EE1\u65F6\uFF0C\u63D2\u5165\u5143\u7D20\u65F6\u4F1A\u629B\u51FAIllegalStateException\u5F02\u5E38\uFF1B
    2. offer(E e)\uFF1A\u5F53\u5F80\u961F\u5217\u63D2\u5165\u6570\u636E\u65F6\uFF0C\u63D2\u5165\u6210\u529F\u8FD4\u56DEtrue\uFF0C\u5426\u5219\u5219\u8FD4\u56DEfalse\u3002\u5F53\u961F\u5217\u6EE1\u65F6\u4E0D\u4F1A\u629B\u51FA\u5F02\u5E38\uFF1B

    2\uFF09\u5220\u9664\u5143\u7D20

    1. remove(Object o)\uFF1A\u4ECE\u961F\u5217\u4E2D\u5220\u9664\u6570\u636E\uFF0C\u6210\u529F\u5219\u8FD4\u56DEtrue\uFF0C\u5426\u5219\u4E3Afalse
    2. poll\uFF1A\u5220\u9664\u6570\u636E\uFF0C\u5F53\u961F\u5217\u4E3A\u7A7A\u65F6\uFF0C\u8FD4\u56DEnull\uFF1B

    3\uFF09\u67E5\u770B\u5143\u7D20

    1. element\uFF1A\u83B7\u53D6\u961F\u5934\u5143\u7D20\uFF0C\u5982\u679C\u961F\u5217\u4E3A\u7A7A\u65F6\u5219\u629B\u51FANoSuchElementException\u5F02\u5E38\uFF1B
    2. peek\uFF1A\u83B7\u53D6\u961F\u5934\u5143\u7D20\uFF0C\u5982\u679C\u961F\u5217\u4E3A\u7A7A\u5219\u629B\u51FANoSuchElementException\u5F02\u5E38

    BlockingQueue\u5177\u6709\u7684\u7279\u6B8A\u64CD\u4F5C\uFF1A

    1\uFF09\u63D2\u5165\u6570\u636E\uFF1A

    1. put\uFF1A\u5F53\u963B\u585E\u961F\u5217\u5BB9\u91CF\u5DF2\u7ECF\u6EE1\u65F6\uFF0C\u5F80\u963B\u585E\u961F\u5217\u63D2\u5165\u6570\u636E\u7684\u7EBF\u7A0B\u4F1A\u88AB\u963B\u585E\uFF0C\u76F4\u81F3\u963B\u585E\u961F\u5217\u5DF2\u7ECF\u6709\u7A7A\u4F59\u7684\u5BB9\u91CF\u53EF\u4F9B\u4F7F\u7528\uFF1B
    2. offer(E e, long timeout, TimeUnit unit)\uFF1A\u82E5\u963B\u585E\u961F\u5217\u5DF2\u7ECF\u6EE1\u65F6\uFF0C\u540C\u6837\u4F1A\u963B\u585E\u63D2\u5165\u6570\u636E\u7684\u7EBF\u7A0B\uFF0C\u76F4\u81F3\u963B\u585E\u961F\u5217\u5DF2\u7ECF\u6709\u7A7A\u4F59\u7684\u5730\u65B9\uFF0C\u4E0Eput\u65B9\u6CD5\u4E0D\u540C\u7684\u662F\uFF0C\u8BE5\u65B9\u6CD5\u4F1A\u6709\u4E00\u4E2A\u8D85\u65F6\u65F6\u95F4\uFF0C\u82E5\u8D85\u8FC7\u5F53\u524D\u7ED9\u5B9A\u7684\u8D85\u65F6\u65F6\u95F4\uFF0C\u63D2\u5165\u6570\u636E\u7684\u7EBF\u7A0B\u4F1A\u9000\u51FA\uFF1B

    2\uFF09\u5220\u9664\u6570\u636E

    1. take()\uFF1A\u5F53\u963B\u585E\u961F\u5217\u4E3A\u7A7A\u65F6\uFF0C\u83B7\u53D6\u961F\u5934\u6570\u636E\u7684\u7EBF\u7A0B\u4F1A\u88AB\u963B\u585E\uFF1B
    2. poll(long timeout, TimeUnit unit)\uFF1A\u5F53\u963B\u585E\u961F\u5217\u4E3A\u7A7A\u65F6\uFF0C\u83B7\u53D6\u6570\u636E\u7684\u7EBF\u7A0B\u4F1A\u88AB\u963B\u585E\uFF0C\u53E6\u5916\uFF0C\u5982\u679C\u88AB\u963B\u585E\u7684\u7EBF\u7A0B\u8D85\u8FC7\u4E86\u7ED9\u5B9A\u7684\u65F6\u957F\uFF0C\u8BE5\u7EBF\u7A0B\u4F1A\u9000\u51FA

    \u5E38\u7528\u7684BlockingQueue

    \u5B9E\u73B0BlockingQueue\u63A5\u53E3\u7684\u6709ArrayBlockingQueue, DelayQueue, LinkedBlockingDeque, LinkedBlockingQueue, LinkedTransferQueue, PriorityBlockingQueue, SynchronousQueue\uFF0C\u800C\u8FD9\u51E0\u79CD\u5E38\u89C1\u7684\u963B\u585E\u961F\u5217\u4E5F\u662F\u5728\u5B9E\u9645\u7F16\u7A0B\u4E2D\u4F1A\u5E38\u7528\u7684\uFF0C\u4E0B\u9762\u5BF9\u8FD9\u51E0\u79CD\u5E38\u89C1\u7684\u963B\u585E\u961F\u5217\u8FDB\u884C\u8BF4\u660E\uFF1A

    ArrayBlockingQueue

    ArrayBlockingQueue\u662F\u7531\u6570\u7EC4\u5B9E\u73B0\u7684\u6709\u754C\u963B\u585E\u961F\u5217\u3002\u8BE5\u961F\u5217\u547D\u4EE4\u5143\u7D20FIFO\uFF08\u5148\u8FDB\u5148\u51FA\uFF09\u3002\u56E0\u6B64\uFF0C\u5BF9\u5934\u5143\u7D20\u65F6\u961F\u5217\u4E2D\u5B58\u5728\u65F6\u95F4\u6700\u957F\u7684\u6570\u636E\u5143\u7D20\uFF0C\u800C\u5BF9\u5C3E\u6570\u636E\u5219\u662F\u5F53\u524D\u961F\u5217\u6700\u65B0\u7684\u6570\u636E\u5143\u7D20\u3002ArrayBlockingQueue\u53EF\u4F5C\u4E3A\u201C\u6709\u754C\u6570\u636E\u7F13\u51B2\u533A\u201D\uFF0C\u751F\u4EA7\u8005\u63D2\u5165\u6570\u636E\u5230\u961F\u5217\u5BB9\u5668\u4E2D\uFF0C\u5E76\u7531\u6D88\u8D39\u8005\u63D0\u53D6\u3002ArrayBlockingQueue\u4E00\u65E6\u521B\u5EFA\uFF0C\u5BB9\u91CF\u4E0D\u80FD\u6539\u53D8\u3002

    \u5F53\u961F\u5217\u5BB9\u91CF\u6EE1\u65F6\uFF0C\u5C1D\u8BD5\u5C06\u5143\u7D20\u653E\u5165\u961F\u5217\u5C06\u5BFC\u81F4\u64CD\u4F5C\u963B\u585E;\u5C1D\u8BD5\u4ECE\u4E00\u4E2A\u7A7A\u961F\u5217\u4E2D\u53D6\u4E00\u4E2A\u5143\u7D20\u4E5F\u4F1A\u540C\u6837\u963B\u585E\u3002

    ArrayBlockingQueue\u9ED8\u8BA4\u60C5\u51B5\u4E0B\u4E0D\u80FD\u4FDD\u8BC1\u7EBF\u7A0B\u8BBF\u95EE\u961F\u5217\u7684\u516C\u5E73\u6027\uFF0C\u6240\u8C13\u516C\u5E73\u6027\u662F\u6307\u4E25\u683C\u6309\u7167\u7EBF\u7A0B\u7B49\u5F85\u7684\u7EDD\u5BF9\u65F6\u95F4\u987A\u5E8F\uFF0C\u5373\u6700\u5148\u7B49\u5F85\u7684\u7EBF\u7A0B\u80FD\u591F\u6700\u5148\u8BBF\u95EE\u5230ArrayBlockingQueue\u3002\u800C\u975E\u516C\u5E73\u6027\u5219\u662F\u6307\u8BBF\u95EEArrayBlockingQueue\u7684\u987A\u5E8F\u4E0D\u662F\u9075\u5B88\u4E25\u683C\u7684\u65F6\u95F4\u987A\u5E8F\uFF0C\u6709\u53EF\u80FD\u5B58\u5728\uFF0C\u4E00\u65E6ArrayBlockingQueue\u53EF\u4EE5\u88AB\u8BBF\u95EE\u65F6\uFF0C\u957F\u65F6\u95F4\u963B\u585E\u7684\u7EBF\u7A0B\u4F9D\u7136\u65E0\u6CD5\u8BBF\u95EE\u5230ArrayBlockingQueue\u3002\u5982\u679C\u4FDD\u8BC1\u516C\u5E73\u6027\uFF0C\u901A\u5E38\u4F1A\u964D\u4F4E\u541E\u5410\u91CF\u3002\u5982\u679C\u9700\u8981\u83B7\u5F97\u516C\u5E73\u6027\u7684ArrayBlockingQueue\uFF0C\u53EF\u91C7\u7528\u5982\u4E0B\u4EE3\u7801\uFF1A

    private static ArrayBlockingQueue<Integer> blockingQueue = new ArrayBlockingQueue<Integer>(10,true);
    +import{_ as t}from"./plugin-vue_export-helper.21dcd24c.js";import{r as p,o,c,a as n,b as a,e as l,d as e}from"./app.615e41d8.js";const i={},u=l(`

    \u6700\u5E38\u7528\u7684"\u751F\u4EA7\u8005-\u6D88\u8D39\u8005"\u95EE\u9898\u4E2D\uFF0C\u961F\u5217\u901A\u5E38\u88AB\u89C6\u4F5C\u7EBF\u7A0B\u95F4\u64CD\u4F5C\u7684\u6570\u636E\u5BB9\u5668\uFF0C\u8FD9\u6837\uFF0C\u53EF\u4EE5\u5BF9\u5404\u4E2A\u6A21\u5757\u7684\u4E1A\u52A1\u529F\u80FD\u8FDB\u884C\u89E3\u8026\uFF0C\u751F\u4EA7\u8005\u5C06\u201C\u751F\u4EA7\u201D\u51FA\u6765\u7684\u6570\u636E\u653E\u7F6E\u5728\u6570\u636E\u5BB9\u5668\u4E2D\uFF0C\u800C\u6D88\u8D39\u8005\u4EC5\u4EC5\u53EA\u9700\u8981\u5728\u201C\u6570\u636E\u5BB9\u5668\u201D\u4E2D\u8FDB\u884C\u83B7\u53D6\u6570\u636E\u5373\u53EF\uFF0C\u8FD9\u6837\u751F\u4EA7\u8005\u7EBF\u7A0B\u548C\u6D88\u8D39\u8005\u7EBF\u7A0B\u5C31\u80FD\u591F\u8FDB\u884C\u89E3\u8026\uFF0C\u53EA\u4E13\u6CE8\u4E8E\u81EA\u5DF1\u7684\u4E1A\u52A1\u529F\u80FD\u5373\u53EF\u3002

    \u963B\u585E\u961F\u5217\uFF08BlockingQueue\uFF09\u88AB\u5E7F\u6CDB\u4F7F\u7528\u5728\u201C\u751F\u4EA7\u8005-\u6D88\u8D39\u8005\u201D\u95EE\u9898\u4E2D\uFF0C\u5176\u539F\u56E0\u662FBlockingQueue\u63D0\u4F9B\u4E86\u53EF\u963B\u585E\u7684\u63D2\u5165\u548C\u79FB\u9664\u7684\u65B9\u6CD5\u3002\u5F53\u961F\u5217\u5BB9\u5668\u5DF2\u6EE1\uFF0C\u751F\u4EA7\u8005\u7EBF\u7A0B\u4F1A\u88AB\u963B\u585E\uFF0C\u76F4\u5230\u961F\u5217\u672A\u6EE1\uFF1B\u5F53\u961F\u5217\u5BB9\u5668\u4E3A\u7A7A\u65F6\uFF0C\u6D88\u8D39\u8005\u7EBF\u7A0B\u4F1A\u88AB\u963B\u585E\uFF0C\u76F4\u81F3\u961F\u5217\u975E\u7A7A\u65F6\u4E3A\u6B62\u3002

    \u57FA\u672C\u64CD\u4F5C

    BlockingQueue\u57FA\u672C\u64CD\u4F5C\u603B\u7ED3\u5982\u4E0B\uFF08\u6B64\u56FE\u6765\u6E90\u4E8EJAVA API\u6587\u6863\uFF09\uFF1A

    BlockingQueue\u7EE7\u627F\u4E8EQueue\u63A5\u53E3\uFF0C\u56E0\u6B64\uFF0C\u5BF9\u6570\u636E\u5143\u7D20\u7684\u57FA\u672C\u64CD\u4F5C\u6709\uFF1A

    1\uFF09\u63D2\u5165\u5143\u7D20

    1. add(E e) \uFF1A\u5F80\u961F\u5217\u63D2\u5165\u6570\u636E\uFF0C\u5F53\u961F\u5217\u6EE1\u65F6\uFF0C\u63D2\u5165\u5143\u7D20\u65F6\u4F1A\u629B\u51FAIllegalStateException\u5F02\u5E38\uFF1B
    2. offer(E e)\uFF1A\u5F53\u5F80\u961F\u5217\u63D2\u5165\u6570\u636E\u65F6\uFF0C\u63D2\u5165\u6210\u529F\u8FD4\u56DEtrue\uFF0C\u5426\u5219\u5219\u8FD4\u56DEfalse\u3002\u5F53\u961F\u5217\u6EE1\u65F6\u4E0D\u4F1A\u629B\u51FA\u5F02\u5E38\uFF1B

    2\uFF09\u5220\u9664\u5143\u7D20

    1. remove(Object o)\uFF1A\u4ECE\u961F\u5217\u4E2D\u5220\u9664\u6570\u636E\uFF0C\u6210\u529F\u5219\u8FD4\u56DEtrue\uFF0C\u5426\u5219\u4E3Afalse
    2. poll\uFF1A\u5220\u9664\u6570\u636E\uFF0C\u5F53\u961F\u5217\u4E3A\u7A7A\u65F6\uFF0C\u8FD4\u56DEnull\uFF1B

    3\uFF09\u67E5\u770B\u5143\u7D20

    1. element\uFF1A\u83B7\u53D6\u961F\u5934\u5143\u7D20\uFF0C\u5982\u679C\u961F\u5217\u4E3A\u7A7A\u65F6\u5219\u629B\u51FANoSuchElementException\u5F02\u5E38\uFF1B
    2. peek\uFF1A\u83B7\u53D6\u961F\u5934\u5143\u7D20\uFF0C\u5982\u679C\u961F\u5217\u4E3A\u7A7A\u5219\u629B\u51FANoSuchElementException\u5F02\u5E38

    BlockingQueue\u5177\u6709\u7684\u7279\u6B8A\u64CD\u4F5C\uFF1A

    1\uFF09\u63D2\u5165\u6570\u636E\uFF1A

    1. put\uFF1A\u5F53\u963B\u585E\u961F\u5217\u5BB9\u91CF\u5DF2\u7ECF\u6EE1\u65F6\uFF0C\u5F80\u963B\u585E\u961F\u5217\u63D2\u5165\u6570\u636E\u7684\u7EBF\u7A0B\u4F1A\u88AB\u963B\u585E\uFF0C\u76F4\u81F3\u963B\u585E\u961F\u5217\u5DF2\u7ECF\u6709\u7A7A\u4F59\u7684\u5BB9\u91CF\u53EF\u4F9B\u4F7F\u7528\uFF1B
    2. offer(E e, long timeout, TimeUnit unit)\uFF1A\u82E5\u963B\u585E\u961F\u5217\u5DF2\u7ECF\u6EE1\u65F6\uFF0C\u540C\u6837\u4F1A\u963B\u585E\u63D2\u5165\u6570\u636E\u7684\u7EBF\u7A0B\uFF0C\u76F4\u81F3\u963B\u585E\u961F\u5217\u5DF2\u7ECF\u6709\u7A7A\u4F59\u7684\u5730\u65B9\uFF0C\u4E0Eput\u65B9\u6CD5\u4E0D\u540C\u7684\u662F\uFF0C\u8BE5\u65B9\u6CD5\u4F1A\u6709\u4E00\u4E2A\u8D85\u65F6\u65F6\u95F4\uFF0C\u82E5\u8D85\u8FC7\u5F53\u524D\u7ED9\u5B9A\u7684\u8D85\u65F6\u65F6\u95F4\uFF0C\u63D2\u5165\u6570\u636E\u7684\u7EBF\u7A0B\u4F1A\u9000\u51FA\uFF1B

    2\uFF09\u5220\u9664\u6570\u636E

    1. take()\uFF1A\u5F53\u963B\u585E\u961F\u5217\u4E3A\u7A7A\u65F6\uFF0C\u83B7\u53D6\u961F\u5934\u6570\u636E\u7684\u7EBF\u7A0B\u4F1A\u88AB\u963B\u585E\uFF1B
    2. poll(long timeout, TimeUnit unit)\uFF1A\u5F53\u963B\u585E\u961F\u5217\u4E3A\u7A7A\u65F6\uFF0C\u83B7\u53D6\u6570\u636E\u7684\u7EBF\u7A0B\u4F1A\u88AB\u963B\u585E\uFF0C\u53E6\u5916\uFF0C\u5982\u679C\u88AB\u963B\u585E\u7684\u7EBF\u7A0B\u8D85\u8FC7\u4E86\u7ED9\u5B9A\u7684\u65F6\u957F\uFF0C\u8BE5\u7EBF\u7A0B\u4F1A\u9000\u51FA

    \u5E38\u7528\u7684BlockingQueue

    \u5B9E\u73B0BlockingQueue\u63A5\u53E3\u7684\u6709ArrayBlockingQueue, DelayQueue, LinkedBlockingDeque, LinkedBlockingQueue, LinkedTransferQueue, PriorityBlockingQueue, SynchronousQueue\uFF0C\u800C\u8FD9\u51E0\u79CD\u5E38\u89C1\u7684\u963B\u585E\u961F\u5217\u4E5F\u662F\u5728\u5B9E\u9645\u7F16\u7A0B\u4E2D\u4F1A\u5E38\u7528\u7684\uFF0C\u4E0B\u9762\u5BF9\u8FD9\u51E0\u79CD\u5E38\u89C1\u7684\u963B\u585E\u961F\u5217\u8FDB\u884C\u8BF4\u660E\uFF1A

    ArrayBlockingQueue

    ArrayBlockingQueue\u662F\u7531\u6570\u7EC4\u5B9E\u73B0\u7684\u6709\u754C\u963B\u585E\u961F\u5217\u3002\u8BE5\u961F\u5217\u547D\u4EE4\u5143\u7D20FIFO\uFF08\u5148\u8FDB\u5148\u51FA\uFF09\u3002\u56E0\u6B64\uFF0C\u5BF9\u5934\u5143\u7D20\u65F6\u961F\u5217\u4E2D\u5B58\u5728\u65F6\u95F4\u6700\u957F\u7684\u6570\u636E\u5143\u7D20\uFF0C\u800C\u5BF9\u5C3E\u6570\u636E\u5219\u662F\u5F53\u524D\u961F\u5217\u6700\u65B0\u7684\u6570\u636E\u5143\u7D20\u3002ArrayBlockingQueue\u53EF\u4F5C\u4E3A\u201C\u6709\u754C\u6570\u636E\u7F13\u51B2\u533A\u201D\uFF0C\u751F\u4EA7\u8005\u63D2\u5165\u6570\u636E\u5230\u961F\u5217\u5BB9\u5668\u4E2D\uFF0C\u5E76\u7531\u6D88\u8D39\u8005\u63D0\u53D6\u3002ArrayBlockingQueue\u4E00\u65E6\u521B\u5EFA\uFF0C\u5BB9\u91CF\u4E0D\u80FD\u6539\u53D8\u3002

    \u5F53\u961F\u5217\u5BB9\u91CF\u6EE1\u65F6\uFF0C\u5C1D\u8BD5\u5C06\u5143\u7D20\u653E\u5165\u961F\u5217\u5C06\u5BFC\u81F4\u64CD\u4F5C\u963B\u585E;\u5C1D\u8BD5\u4ECE\u4E00\u4E2A\u7A7A\u961F\u5217\u4E2D\u53D6\u4E00\u4E2A\u5143\u7D20\u4E5F\u4F1A\u540C\u6837\u963B\u585E\u3002

    ArrayBlockingQueue\u9ED8\u8BA4\u60C5\u51B5\u4E0B\u4E0D\u80FD\u4FDD\u8BC1\u7EBF\u7A0B\u8BBF\u95EE\u961F\u5217\u7684\u516C\u5E73\u6027\uFF0C\u6240\u8C13\u516C\u5E73\u6027\u662F\u6307\u4E25\u683C\u6309\u7167\u7EBF\u7A0B\u7B49\u5F85\u7684\u7EDD\u5BF9\u65F6\u95F4\u987A\u5E8F\uFF0C\u5373\u6700\u5148\u7B49\u5F85\u7684\u7EBF\u7A0B\u80FD\u591F\u6700\u5148\u8BBF\u95EE\u5230ArrayBlockingQueue\u3002\u800C\u975E\u516C\u5E73\u6027\u5219\u662F\u6307\u8BBF\u95EEArrayBlockingQueue\u7684\u987A\u5E8F\u4E0D\u662F\u9075\u5B88\u4E25\u683C\u7684\u65F6\u95F4\u987A\u5E8F\uFF0C\u6709\u53EF\u80FD\u5B58\u5728\uFF0C\u4E00\u65E6ArrayBlockingQueue\u53EF\u4EE5\u88AB\u8BBF\u95EE\u65F6\uFF0C\u957F\u65F6\u95F4\u963B\u585E\u7684\u7EBF\u7A0B\u4F9D\u7136\u65E0\u6CD5\u8BBF\u95EE\u5230ArrayBlockingQueue\u3002\u5982\u679C\u4FDD\u8BC1\u516C\u5E73\u6027\uFF0C\u901A\u5E38\u4F1A\u964D\u4F4E\u541E\u5410\u91CF\u3002\u5982\u679C\u9700\u8981\u83B7\u5F97\u516C\u5E73\u6027\u7684ArrayBlockingQueue\uFF0C\u53EF\u91C7\u7528\u5982\u4E0B\u4EE3\u7801\uFF1A

    private static ArrayBlockingQueue<Integer> blockingQueue = new ArrayBlockingQueue<Integer>(10,true);
     

    ArrayBlockingQueue\u7684\u4E3B\u8981\u5C5E\u6027\u5982\u4E0B:

    /** The queued items */
     final Object[] items;
     
    diff --git a/dist/assets/Chocolatey-Homebrew.html.a0b23720.js b/dist/assets/Chocolatey-Homebrew.html.5637171d.js
    similarity index 99%
    rename from dist/assets/Chocolatey-Homebrew.html.a0b23720.js
    rename to dist/assets/Chocolatey-Homebrew.html.5637171d.js
    index bb99f670..bee33e1a 100644
    --- a/dist/assets/Chocolatey-Homebrew.html.a0b23720.js
    +++ b/dist/assets/Chocolatey-Homebrew.html.5637171d.js
    @@ -1,4 +1,4 @@
    -import{_ as c}from"./plugin-vue_export-helper.21dcd24c.js";import{r as l,o as d,c as n,a as e,b as a,e as r,d as t}from"./app.a0271b9c.js";const i={},p=r('

    \u5C0F\u4E8C\u662F\u516C\u53F8\u65B0\u6765\u7684\u5B9E\u4E60\u751F\uFF0C\u4E4B\u524D\u9762\u8BD5\u7684\u8FC7\u7A0B\u4E2D\u5BF9\u7B54\u5982\u6D41\uFF0C\u6240\u4EE5\u6211\u975E\u5E38\u770B\u597D\u4ED6\u3002\u7B2C\u4E00\u5929\uFF0C\u6211\u7ED9\u4ED6\u4E86\u4E00\u53F0\u65B0\u7535\u8111\uFF0C\u8981\u4ED6\u5148\u5728\u672C\u5730\u642D\u5EFA\u4E2A Java \u5F00\u53D1\u73AF\u5883\u3002

    \u4E8C\u8BDD\u4E0D\u8BF4\uFF0C\u4ED6\u5C31\u5F00\u59CB\u9A6C\u4E0D\u505C\u8E44\u5730\u884C\u52A8\u4E86\u3002\u771F\u6CA1\u60F3\u5230\uFF0C\u4ED6\u7ADF\u7136\u662F\u901A\u8FC7\u547D\u4EE4\u884C\u7684\u65B9\u5F0F\u5B89\u88C5\u7684 JDK\uFF0C\u8FD9\u8FDC\u8FDC\u8D85\u51FA\u4E86\u6211\u5BF9\u4ED6\u7684\u9884\u671F\u3002

    \u6211\u4EE5\u4E3A\uFF0C\u4ED6\u4F1A\u4F7F\u7528\u56FE\u5F62\u5316\u7684\u65B9\u5F0F\u6765\u5B89\u88C5 JDK \u7684\uFF0C\u5C31\u50CF\u8FD9\u6837\u3002

    \u8FD8\u6709\u8FD9\u6837\u3002

    \u7ED3\u679C\u4ED6\u662F\u8FD9\u6837\u7684\u3002

    \u5367\u69FD\uFF01\u725B\u903C\u9AD8\u5927\u4E0A\u554A\uFF01

    \u770B\u7740\u4ED6\u719F\u7EC3\u5730\u5728\u547D\u4EE4\u884C\u91CC\u5B89\u88C5 JDK \u7684\u6837\u5B50\uFF0C\u6211\u7684\u5634\u89D2\u5F00\u59CB\u5FAE\u5FAE\u4E0A\u626C\uFF0C\u771F\u4E0D\u9519\uFF01\u8FD9\u6B21\u603B\u7B97\u62DB\u5230\u4E86\u4E00\u4E2A\u9760\u8C31\u7684\u3002

    \u4E8E\u662F\u6211\u5C31\u5B89\u6392\u4ED6\u505A\u4E00\u4E2A\u8BB0\u5F55\uFF0C\u6253\u7B97\u53D1\u8868\u5728\u6211\u7684\u5C0F\u7834\u7AD9\u300AJava \u7A0B\u5E8F\u5458\u8FDB\u9636\u4E4B\u8DEF\u300B\u4E0A\u3002\u4ECE\u4ED6\u5634\u91CC\u4E86\u89E3\u5230\uFF0C\u4ED6\u7528\u7684\u547D\u4EE4\u884C\u8F6F\u4EF6\u7BA1\u7406\u5668\u53EB chocolatey\uFF0C\u8FD9\u662F\u4E00\u4E2AWindows\u4E0B\u7684\u547D\u4EE4\u884C\u8F6F\u4EF6\u7BA1\u7406\u5668\uFF0C\u53EF\u4EE5\u65B9\u4FBF\u5F00\u53D1\u8005\u50CF\u5728Linux\u4E0B\u4F7F\u7528yum\u547D\u4EE4\u6765\u5B89\u88C5\u8F6F\u4EF6\uFF0C\u6216\u8005\u50CF\u5728macOS\u4E0B\u4F7F\u7528brew \u547D\u4EE4\u6765\u5B89\u88C5\u8F6F\u4EF6\uFF0C\u6211\u611F\u89C9\u975E\u5E38\u9177\u70AB\u3002

    \u4EE5\u4E0B\u662F\u4ED6\u7684\u8BB0\u5F55\uFF0C\u4E00\u8D77\u6765\u6B23\u8D4F\u4E0B\u3002

    \u5173\u4E8Eshell

    \u5BF9\u4E8E\u4E00\u540D Java \u540E\u7AEF\u7A0B\u5E8F\u5458\u6765\u8BF4\uFF0C\u521D\u5B66\u9636\u6BB5\uFF0C\u4F60\u53EF\u4EE5\u9009\u62E9\u5728 IDE \u4E2D\u76F4\u63A5\u7F16\u8BD1\u8FD0\u884C Java \u4EE3\u7801\uFF0C\u4F46\u6709\u65F6\u5019\u4E5F\u9700\u8981\u5728 Shell \u4E0B\u7F16\u8BD1\u548C\u8FD0\u884C Java \u4EE3\u7801\u3002

    Windows \u4E0B\u81EA\u5E26\u7684 Shell \u53EB\u547D\u4EE4\u63D0\u793A\u7B26\uFF0C\u6216\u8005 cmd \u6216\u8005 powershell\uFF0CmacOS \u4E0B\u53EB\u7EC8\u7AEF terminal\u3002

    ',16),s={href:"https://mp.weixin.qq.com/s?__biz=MzIxNzQwNjM3NA==&mid=2247491253&idx=1&sn=9a46879174f7240267fe5b5205d16d22&scene=21#wechat_redirect",target:"_blank",rel:"noopener noreferrer"},b=t("\u7EC8\u7AEF\u4E0E Shell \u7684\u533A\u522B"),h={href:"https://mp.weixin.qq.com/s/oEo8N3nE0wR1zl7qD4nh3w",target:"_blank",rel:"noopener noreferrer"},m=t("\u521D\u6B21\u4F53\u9A8C macOS \u4E0B\u7684 Shell"),g=r('

    \u4F46\u5F53\u4F60\u9700\u8981\u5728\u751F\u4EA7\u73AF\u5883\u4E0B\u90E8\u7F72 Java\u9879\u76EE\u6216\u8005\u67E5\u770B\u65E5\u5FD7\u7684\u8BDD\uFF0C\u5C31\u5FC5\u7136\u4F1A\u7528\u5230 Shell\uFF0C\u8FD9\u4E2A\u9636\u6BB5\uFF0CShell \u7684\u4F7F\u7528\u9891\u7387\u9AD8\u5230\u53EF\u4EE5\u7528\u4E00\u4E2A\u6210\u8BED\u6765\u5F62\u5BB9\u2014\u2014\u671D\u5915\u76F8\u4F34\u3002

    \u4E00\u4E9B\u7B2C\u4E09\u65B9\u8F6F\u4EF6\u4F1A\u5728\u539F\u751F\u7684 Shell \u57FA\u7840\u4E0A\u63D0\u4F9B\u66F4\u5F3A\u5927\u7684\u529F\u80FD\uFF0C\u5E38\u89C1\u7684\u6709 tabby\u3001Warp\u3001xhsell\u3001FinalShell\u3001MobaXterm\u3001Aechoterm\u3001WindTerm\u3001termius\u3001iterm2 \u7B49\u7B49\uFF0C\u6709\u4E9B\u53EA\u80FD\u5728 Windows \u4E0A\u4F7F\u7528\uFF0C\u6709\u4E9B\u53EA\u80FD\u5728 macOS \u4E0A\u4F7F\u7528\uFF0C\u6709\u4E9B\u652F\u6301\u5168\u5E73\u53F0\u3002\u8FD8\u6709 ohmyzsh \u8FD9\u79CD\u8D85\u795E\u7684 Shell \u7F8E\u5316\u5DE5\u5177\u3002

    \u8FD9\u91CC\uFF0C\u6211\u4EEC\u5217\u4E3E\u4E00\u4E9B Shell \u7684\u57FA\u672C\u64CD\u4F5C\u547D\u4EE4\uFF08Windows \u548C macOS/Linux \u6709\u4E9B\u8BB8\u5DEE\u5F02\uFF09\uFF1A

    • \u5207\u6362\u76EE\u5F55\uFF0C\u53EF\u4EE5\u4F7F\u7528 cd \u547D\u4EE4\u5207\u6362\u76EE\u5F55\uFF0Ccd .. \u8FD4\u56DE\u4E0A\u7EA7\u76EE\u5F55\u3002

    • \u76EE\u5F55\u5217\u8868\uFF0Cmacos/linux \u4E0B\u53EF\u4EE5\u4F7F\u7528 ls \u547D\u4EE4\u5217\u51FA\u76EE\u5F55\u4E0B\u6240\u6709\u7684\u6587\u4EF6\u548C\u5B50\u76EE\u5F55\uFF08Windows \u4E0B\u4F7F\u7528 dir \u547D\u4EE4\uFF09\uFF0C\u4F7F\u7528\u901A\u914D\u7B26 * \u5BF9\u5C55\u793A\u7684\u5185\u5BB9\u8FDB\u884C\u8FC7\u6EE4\uFF0C\u6BD4\u5982 ls *.java \u5217\u51FA\u6240\u6709 .java\u540E\u7F00\u7684\u6587\u4EF6\uFF0C\u5982\u679C\u60F3\u66F4\u8FDB\u4E00\u6B65\u7684\u8BDD\uFF0C\u53EF\u4EE5\u4F7F\u7528 ls H*.java \u5217\u51FA\u6240\u6709\u4EE5 H \u5F00\u5934 .java \u540E\u7F00\u7684\u6587\u4EF6\u3002
    • \u65B0\u5EFA\u76EE\u5F55\uFF0CmacOS/Linux \u4E0B\u53EF\u4EE5\u4F7F\u7528 mkdir \u547D\u4EE4\u65B0\u5EFA\u4E00\u4E2A\u76EE\u5F55\uFF08\u6BD4\u5982 mkdir hello \u53EF\u4EE5\u65B0\u5EFA\u4E00\u4E2A hello \u7684\u76EE\u5F55\uFF09\uFF0CWindows \u4E0B\u53EF\u4EE5\u4F7F\u7528 md \u547D\u4EE4\u3002
    • \u5220\u9664\u6587\u4EF6\uFF0CmacOS/Linux \u4E0B\u53EF\u4EE5\u4F7F\u7528 rm \u547D\u4EE4\u5220\u9664\u6587\u4EF6\uFF08\u6BD4\u5982 rm hello.java \u5220\u9664 hello.java \u6587\u4EF6\uFF09\uFF0CWindows \u4E0B\u53EF\u4EE5\u4F7F\u7528 del \u547D\u4EE4\u3002
    • \u5220\u9664\u76EE\u5F55\uFF0CmacOS/Linux \u4E0B\u53EF\u4EE5\u4F7F\u7528 rm -r \u547D\u4EE4\u5220\u9664\u76EE\u5F55\u4EE5\u53CA\u5B83\u6240\u5305\u542B\u7684\u6240\u6709\u6587\u4EF6\uFF08\u6BD4\u5982\u8BF4 rm -r hello \u5220\u9664 hello \u76EE\u5F55\uFF09\u3002Windows \u4E0B\u53EF\u4EE5\u4F7F\u7528 deltree \u547D\u4EE4\u3002
    • \u91CD\u590D\u547D\u4EE4\uFF0CmacOS/Linux/Windows \u4E0B\u90FD\u53EF\u4EE5\u4F7F\u7528\u4E0A\u4E0B\u7BAD\u5934\u6765\u9009\u62E9\u4EE5\u5F80\u6267\u884C\u8FC7\u7684\u547D\u4EE4\u3002

    • \u547D\u4EE4\u5386\u53F2\uFF0CmacOS/Linux \u4E0B\u53EF\u4EE5\u4F7F\u7528 history \u547D\u4EE4\u67E5\u770B\u6240\u6709\u4F7F\u7528\u8FC7\u7684\u547D\u4EE4\u3002Windows \u53EF\u4EE5\u6309\u4E0B F7 \u952E\u3002

    • \u89E3\u538B\u6587\u4EF6\uFF0C\u540E\u7F00\u540D\u4E3A\u201C.zip\u201D\u7684\u6587\u4EF6\u662F\u4E00\u4E2A\u5305\u542B\u4E86\u5176\u4ED6\u6587\u4EF6\u7684\u538B\u7F29\u5305\uFF0CmacOS/Linux \u7CFB\u7EDF\u81EA\u8EAB\u5DF2\u7ECF\u63D0\u4F9B\u4E86\u7528\u4E8E\u89E3\u538B\u7684 unzip \u547D\u4EE4\uFF0C Windows \u7684\u8BDD\u9700\u8981\u624B\u52A8\u5B89\u88C5\u3002

    \u5B89\u88C5JDK

    1\uFF09Windows

    \u63A8\u8350\u5148\u5B89\u88C5 chocolatey\u3002\u8FD9\u662F\u4E00\u4E2AWindows\u4E0B\u7684\u547D\u4EE4\u884C\u8F6F\u4EF6\u7BA1\u7406\u5668\uFF0C\u53EF\u4EE5\u65B9\u4FBF\u5F00\u53D1\u8005\u50CF\u5728Linux\u4E0B\u4F7F\u7528yum\u547D\u4EE4\u6765\u5B89\u88C5\u8F6F\u4EF6\uFF0C\u6216\u8005\u50CF\u5728macOS\u4E0B\u4F7F\u7528brew \u547D\u4EE4\u6765\u5B89\u88C5\u8F6F\u4EF6\uFF0C\u975E\u5E38\u9177\u70AB\u3002

    The biggest challenge is reducing duplication of effort, so users turn to Chocolatey for simplicity

    \u4F20\u7EDF\u7684\u5B89\u88C5\u65B9\u5F0F\u8981\u4E48\u975E\u5E38\u8017\u65F6\uFF0C\u8981\u4E48\u975E\u5E38\u4F4E\u6548\uFF0C\u5728\u547D\u4EE4\u884C\u5B89\u88C5\u8F6F\u4EF6\u9664\u4E86\u7B80\u5355\u9AD8\u6548\uFF0C\u8FD8\u80FD\u81EA\u52A8\u5E2E\u6211\u4EEC\u914D\u7F6E\u73AF\u5883\u53D8\u91CF\u3002

    ',15),u=t("\u5B98\u65B9\u5730\u5740\uFF1A"),v={href:"https://chocolatey.org/",target:"_blank",rel:"noopener noreferrer"},w=t("https://chocolatey.org/"),_=t("\u5B89\u88C5\u6587\u6863\uFF1A"),j={href:"https://chocolatey.org/install#individual",target:"_blank",rel:"noopener noreferrer"},x=t("https://chocolatey.org/install#individual"),f=r('

    \u5B89\u88C5\u5B8C\u6210\u540E\u5982\u4E0B\u56FE\u6240\u793A\uFF1A

    \u5982\u679C\u4E0D\u786E\u5B9A\u662F\u5426\u5B89\u88C5\u6210\u529F\u7684\u8BDD\uFF0C\u53EF\u4EE5\u901A\u8FC7\u952E\u5165 choco \u547D\u4EE4\u6765\u786E\u8BA4\u3002

    \u8FD9\u91CC\u63A8\u8350\u51E0\u4E2A\u975E\u5E38\u9AD8\u6548\u7684\u64CD\u4F5C\u547D\u4EE4\uFF1A

    • choco search xxx\uFF0C\u67E5\u627E xxx \u5B89\u88C5\u5305
    • choco info xxx\uFF0C\u67E5\u770B xxx \u5B89\u88C5\u5305\u4FE1\u606F
    • choco install xxx\uFF0C\u5B89\u88C5 xxx \u8F6F\u4EF6
    • choco upgrade xxx\uFF0C\u5347\u7EA7 xxx \u8F6F\u4EF6
    • choco uninstall xxx\uFF0C \u5378\u8F7D xxx \u8F6F\u4EF6

    \u5982\u4F55\u77E5\u9053 chocolatey \u4ED3\u5E93\u4E2D\u90FD\u6709\u54EA\u4E9B\u5B89\u88C5\u5305\u53EF\u7528\u5462\uFF1F

    \u53EF\u4EE5\u901A\u8FC7\u4E0A\u9762\u63D0\u5230\u7684\u547D\u4EE4\u884C\u7684\u65B9\u5F0F\uFF0C\u4E5F\u53EF\u4EE5\u8BBF\u95EE\u5B98\u65B9\u4ED3\u5E93\u8FDB\u884C\u7B5B\u9009\u3002

    ',8),k={href:"https://community.chocolatey.org/packages",target:"_blank",rel:"noopener noreferrer"},y=t("https://community.chocolatey.org/packages"),S=r('

    \u6BD4\u5982\u8BF4\u6211\u4EEC\u6765\u67E5\u627E Java\u3002

    \u597D\uFF0C\u73B0\u5728\u53EF\u4EE5\u76F4\u63A5\u5728shell\u4E2D\u952E\u5165 choco install jdk8 \u6765\u5B89\u88C5 JDK8 \u4E86\uFF0C\u5E76\u4E14\u4F1A\u81EA\u52A8\u5C06Java\u52A0\u5165\u5230\u73AF\u5883\u53D8\u91CF\u4E2D\uFF0C\u4E0D\u7528\u518D\u53BB\u300C\u6211\u7684\u7535\u8111\u300D\u300C\u73AF\u5883\u53D8\u91CF\u300D\u4E2D\u65B0\u5EFA JAVA_HOME \u5E76\u590D\u5236 JDK \u5B89\u88C5\u8DEF\u5F84\u914D\u7F6E PATH \u53D8\u91CF\u4E86\uFF0C\u662F\u4E0D\u662F\u975E\u5E38 nice\uFF1F

    \u7A0D\u7B49\u7247\u523B\uFF0C\u952E\u5165 java -version \u5C31\u53EF\u4EE5\u786E\u8BA4Java\u662F\u5426\u5B89\u88C5\u6210\u529F\u4E86\u3002

    \u4E0D\u5F97\u4E0D\u627F\u8BA4\uFF01\u975E\u5E38nice\uFF01

    2\uFF09macOS

    \u9996\u5148\u63A8\u8350\u5B89\u88C5 homebrew\uFF0C\u8FD9\u662FmacOS\u4E0B\u7684\u547D\u4EE4\u884C\u8F6F\u4EF6\u7BA1\u7406\u5668\uFF0C\u7528\u6765\u7B80\u5316 macOS \u4E0A\u8F6F\u4EF6\u7684\u5B89\u88C5\u8FC7\u7A0B\u3002homebrew \u662F\u5F00\u6E90\u7684\uFF0C\u5728 GitHub \u5DF2\u6536\u83B7 32k star\u3002

    homebrew \u7684\u5B89\u88C5\u4E5F\u975E\u5E38\u7684\u7B80\u5355\uFF0C\u53EA\u9700\u8981\u4E00\u884C\u547D\u4EE4\u5373\u53EF\u3002

    ',10),H=t("\u5B98\u65B9\u7F51\u5740\uFF1A"),J={href:"https://brew.sh/index_zh-cn",target:"_blank",rel:"noopener noreferrer"},C=t("https://brew.sh/index_zh-cn"),O=r(`

    • \u4F7F\u7528 brew install xxx \u53EF\u4EE5\u5B89\u88C5 macOS \u4E0A\u6CA1\u6709\u9884\u88C5\u7684\u8F6F\u4EF6
    • \u4F7F\u7528 brew install --cask yyy \u53EF\u4EE5\u5B89\u88C5 macOS \u5176\u4ED6\u975E\u5F00\u6E90\u8F6F\u4EF6\u3002

    \u8FD9\u91CC\u662F homebrew \u5E38\u7528\u547D\u4EE4\u7684\u4E00\u4E2A\u6E05\u5355\uFF0C\u53EF\u4F9B\u53C2\u8003\u3002

    \u547D\u4EE4\u63CF\u8FF0
    brew update\u66F4\u65B0 Homebrew
    brew search package\u641C\u7D22\u8F6F\u4EF6\u5305
    brew install package\u5B89\u88C5\u8F6F\u4EF6\u5305
    brew uninstall package\u5378\u8F7D\u8F6F\u4EF6\u5305
    brew upgrade\u5347\u7EA7\u6240\u6709\u8F6F\u4EF6\u5305
    brew upgrade package\u5347\u7EA7\u6307\u5B9A\u8F6F\u4EF6\u5305
    brew list\u5217\u51FA\u5DF2\u5B89\u88C5\u7684\u8F6F\u4EF6\u5305\u5217\u8868
    brew services command package\u7BA1\u7406 brew \u5B89\u88C5\u8F6F\u4EF6\u5305
    brew services list\u5217\u51FA brew \u7BA1\u7406\u8FD0\u884C\u7684\u670D\u52A1
    brew info package\u67E5\u770B\u8F6F\u4EF6\u5305\u4FE1\u606F
    brew deps package\u5217\u51FA\u8F6F\u4EF6\u5305\u7684\u4F9D\u8D56\u5173\u7CFB
    brew help\u67E5\u770B\u5E2E\u52A9
    brew cleanup\u6E05\u9664\u8FC7\u65F6\u8F6F\u4EF6\u5305
    brew link package\u521B\u5EFA\u8F6F\u4EF6\u5305\u7B26\u53F7\u94FE\u63A5
    brew unlink package\u53D6\u6D88\u8F6F\u4EF6\u5305\u7B26\u53F7\u94FE\u63A5
    brew doctor\u68C0\u67E5\u7CFB\u7EDF\u662F\u5426\u5B58\u5728\u95EE\u9898

    \u5B89\u88C5\u5B8C homebrew \u540E\uFF0C\u5EFA\u8BAE\u66FF\u6362homebrew \u7684\u9ED8\u8BA4\u6E90\u4E3A\u4E2D\u79D1\u5927\u7684\uFF0C\u539F\u56E0\u5C31\u4E0D\u7528\u6211\u591A\u8BF4\u4E86\u5427\uFF1F\u66FF\u6362\u65B9\u6CD5\u5982\u4E0B\u6240\u793A\uFF1A

    \u66FF\u6362brew.git:
    +import{_ as c}from"./plugin-vue_export-helper.21dcd24c.js";import{r as l,o as d,c as n,a as e,b as a,e as r,d as t}from"./app.615e41d8.js";const i={},p=r('

    \u5C0F\u4E8C\u662F\u516C\u53F8\u65B0\u6765\u7684\u5B9E\u4E60\u751F\uFF0C\u4E4B\u524D\u9762\u8BD5\u7684\u8FC7\u7A0B\u4E2D\u5BF9\u7B54\u5982\u6D41\uFF0C\u6240\u4EE5\u6211\u975E\u5E38\u770B\u597D\u4ED6\u3002\u7B2C\u4E00\u5929\uFF0C\u6211\u7ED9\u4ED6\u4E86\u4E00\u53F0\u65B0\u7535\u8111\uFF0C\u8981\u4ED6\u5148\u5728\u672C\u5730\u642D\u5EFA\u4E2A Java \u5F00\u53D1\u73AF\u5883\u3002

    \u4E8C\u8BDD\u4E0D\u8BF4\uFF0C\u4ED6\u5C31\u5F00\u59CB\u9A6C\u4E0D\u505C\u8E44\u5730\u884C\u52A8\u4E86\u3002\u771F\u6CA1\u60F3\u5230\uFF0C\u4ED6\u7ADF\u7136\u662F\u901A\u8FC7\u547D\u4EE4\u884C\u7684\u65B9\u5F0F\u5B89\u88C5\u7684 JDK\uFF0C\u8FD9\u8FDC\u8FDC\u8D85\u51FA\u4E86\u6211\u5BF9\u4ED6\u7684\u9884\u671F\u3002

    \u6211\u4EE5\u4E3A\uFF0C\u4ED6\u4F1A\u4F7F\u7528\u56FE\u5F62\u5316\u7684\u65B9\u5F0F\u6765\u5B89\u88C5 JDK \u7684\uFF0C\u5C31\u50CF\u8FD9\u6837\u3002

    \u8FD8\u6709\u8FD9\u6837\u3002

    \u7ED3\u679C\u4ED6\u662F\u8FD9\u6837\u7684\u3002

    \u5367\u69FD\uFF01\u725B\u903C\u9AD8\u5927\u4E0A\u554A\uFF01

    \u770B\u7740\u4ED6\u719F\u7EC3\u5730\u5728\u547D\u4EE4\u884C\u91CC\u5B89\u88C5 JDK \u7684\u6837\u5B50\uFF0C\u6211\u7684\u5634\u89D2\u5F00\u59CB\u5FAE\u5FAE\u4E0A\u626C\uFF0C\u771F\u4E0D\u9519\uFF01\u8FD9\u6B21\u603B\u7B97\u62DB\u5230\u4E86\u4E00\u4E2A\u9760\u8C31\u7684\u3002

    \u4E8E\u662F\u6211\u5C31\u5B89\u6392\u4ED6\u505A\u4E00\u4E2A\u8BB0\u5F55\uFF0C\u6253\u7B97\u53D1\u8868\u5728\u6211\u7684\u5C0F\u7834\u7AD9\u300AJava \u7A0B\u5E8F\u5458\u8FDB\u9636\u4E4B\u8DEF\u300B\u4E0A\u3002\u4ECE\u4ED6\u5634\u91CC\u4E86\u89E3\u5230\uFF0C\u4ED6\u7528\u7684\u547D\u4EE4\u884C\u8F6F\u4EF6\u7BA1\u7406\u5668\u53EB chocolatey\uFF0C\u8FD9\u662F\u4E00\u4E2AWindows\u4E0B\u7684\u547D\u4EE4\u884C\u8F6F\u4EF6\u7BA1\u7406\u5668\uFF0C\u53EF\u4EE5\u65B9\u4FBF\u5F00\u53D1\u8005\u50CF\u5728Linux\u4E0B\u4F7F\u7528yum\u547D\u4EE4\u6765\u5B89\u88C5\u8F6F\u4EF6\uFF0C\u6216\u8005\u50CF\u5728macOS\u4E0B\u4F7F\u7528brew \u547D\u4EE4\u6765\u5B89\u88C5\u8F6F\u4EF6\uFF0C\u6211\u611F\u89C9\u975E\u5E38\u9177\u70AB\u3002

    \u4EE5\u4E0B\u662F\u4ED6\u7684\u8BB0\u5F55\uFF0C\u4E00\u8D77\u6765\u6B23\u8D4F\u4E0B\u3002

    \u5173\u4E8Eshell

    \u5BF9\u4E8E\u4E00\u540D Java \u540E\u7AEF\u7A0B\u5E8F\u5458\u6765\u8BF4\uFF0C\u521D\u5B66\u9636\u6BB5\uFF0C\u4F60\u53EF\u4EE5\u9009\u62E9\u5728 IDE \u4E2D\u76F4\u63A5\u7F16\u8BD1\u8FD0\u884C Java \u4EE3\u7801\uFF0C\u4F46\u6709\u65F6\u5019\u4E5F\u9700\u8981\u5728 Shell \u4E0B\u7F16\u8BD1\u548C\u8FD0\u884C Java \u4EE3\u7801\u3002

    Windows \u4E0B\u81EA\u5E26\u7684 Shell \u53EB\u547D\u4EE4\u63D0\u793A\u7B26\uFF0C\u6216\u8005 cmd \u6216\u8005 powershell\uFF0CmacOS \u4E0B\u53EB\u7EC8\u7AEF terminal\u3002

    ',16),s={href:"https://mp.weixin.qq.com/s?__biz=MzIxNzQwNjM3NA==&mid=2247491253&idx=1&sn=9a46879174f7240267fe5b5205d16d22&scene=21#wechat_redirect",target:"_blank",rel:"noopener noreferrer"},b=t("\u7EC8\u7AEF\u4E0E Shell \u7684\u533A\u522B"),h={href:"https://mp.weixin.qq.com/s/oEo8N3nE0wR1zl7qD4nh3w",target:"_blank",rel:"noopener noreferrer"},m=t("\u521D\u6B21\u4F53\u9A8C macOS \u4E0B\u7684 Shell"),g=r('

    \u4F46\u5F53\u4F60\u9700\u8981\u5728\u751F\u4EA7\u73AF\u5883\u4E0B\u90E8\u7F72 Java\u9879\u76EE\u6216\u8005\u67E5\u770B\u65E5\u5FD7\u7684\u8BDD\uFF0C\u5C31\u5FC5\u7136\u4F1A\u7528\u5230 Shell\uFF0C\u8FD9\u4E2A\u9636\u6BB5\uFF0CShell \u7684\u4F7F\u7528\u9891\u7387\u9AD8\u5230\u53EF\u4EE5\u7528\u4E00\u4E2A\u6210\u8BED\u6765\u5F62\u5BB9\u2014\u2014\u671D\u5915\u76F8\u4F34\u3002

    \u4E00\u4E9B\u7B2C\u4E09\u65B9\u8F6F\u4EF6\u4F1A\u5728\u539F\u751F\u7684 Shell \u57FA\u7840\u4E0A\u63D0\u4F9B\u66F4\u5F3A\u5927\u7684\u529F\u80FD\uFF0C\u5E38\u89C1\u7684\u6709 tabby\u3001Warp\u3001xhsell\u3001FinalShell\u3001MobaXterm\u3001Aechoterm\u3001WindTerm\u3001termius\u3001iterm2 \u7B49\u7B49\uFF0C\u6709\u4E9B\u53EA\u80FD\u5728 Windows \u4E0A\u4F7F\u7528\uFF0C\u6709\u4E9B\u53EA\u80FD\u5728 macOS \u4E0A\u4F7F\u7528\uFF0C\u6709\u4E9B\u652F\u6301\u5168\u5E73\u53F0\u3002\u8FD8\u6709 ohmyzsh \u8FD9\u79CD\u8D85\u795E\u7684 Shell \u7F8E\u5316\u5DE5\u5177\u3002

    \u8FD9\u91CC\uFF0C\u6211\u4EEC\u5217\u4E3E\u4E00\u4E9B Shell \u7684\u57FA\u672C\u64CD\u4F5C\u547D\u4EE4\uFF08Windows \u548C macOS/Linux \u6709\u4E9B\u8BB8\u5DEE\u5F02\uFF09\uFF1A

    • \u5207\u6362\u76EE\u5F55\uFF0C\u53EF\u4EE5\u4F7F\u7528 cd \u547D\u4EE4\u5207\u6362\u76EE\u5F55\uFF0Ccd .. \u8FD4\u56DE\u4E0A\u7EA7\u76EE\u5F55\u3002

    • \u76EE\u5F55\u5217\u8868\uFF0Cmacos/linux \u4E0B\u53EF\u4EE5\u4F7F\u7528 ls \u547D\u4EE4\u5217\u51FA\u76EE\u5F55\u4E0B\u6240\u6709\u7684\u6587\u4EF6\u548C\u5B50\u76EE\u5F55\uFF08Windows \u4E0B\u4F7F\u7528 dir \u547D\u4EE4\uFF09\uFF0C\u4F7F\u7528\u901A\u914D\u7B26 * \u5BF9\u5C55\u793A\u7684\u5185\u5BB9\u8FDB\u884C\u8FC7\u6EE4\uFF0C\u6BD4\u5982 ls *.java \u5217\u51FA\u6240\u6709 .java\u540E\u7F00\u7684\u6587\u4EF6\uFF0C\u5982\u679C\u60F3\u66F4\u8FDB\u4E00\u6B65\u7684\u8BDD\uFF0C\u53EF\u4EE5\u4F7F\u7528 ls H*.java \u5217\u51FA\u6240\u6709\u4EE5 H \u5F00\u5934 .java \u540E\u7F00\u7684\u6587\u4EF6\u3002
    • \u65B0\u5EFA\u76EE\u5F55\uFF0CmacOS/Linux \u4E0B\u53EF\u4EE5\u4F7F\u7528 mkdir \u547D\u4EE4\u65B0\u5EFA\u4E00\u4E2A\u76EE\u5F55\uFF08\u6BD4\u5982 mkdir hello \u53EF\u4EE5\u65B0\u5EFA\u4E00\u4E2A hello \u7684\u76EE\u5F55\uFF09\uFF0CWindows \u4E0B\u53EF\u4EE5\u4F7F\u7528 md \u547D\u4EE4\u3002
    • \u5220\u9664\u6587\u4EF6\uFF0CmacOS/Linux \u4E0B\u53EF\u4EE5\u4F7F\u7528 rm \u547D\u4EE4\u5220\u9664\u6587\u4EF6\uFF08\u6BD4\u5982 rm hello.java \u5220\u9664 hello.java \u6587\u4EF6\uFF09\uFF0CWindows \u4E0B\u53EF\u4EE5\u4F7F\u7528 del \u547D\u4EE4\u3002
    • \u5220\u9664\u76EE\u5F55\uFF0CmacOS/Linux \u4E0B\u53EF\u4EE5\u4F7F\u7528 rm -r \u547D\u4EE4\u5220\u9664\u76EE\u5F55\u4EE5\u53CA\u5B83\u6240\u5305\u542B\u7684\u6240\u6709\u6587\u4EF6\uFF08\u6BD4\u5982\u8BF4 rm -r hello \u5220\u9664 hello \u76EE\u5F55\uFF09\u3002Windows \u4E0B\u53EF\u4EE5\u4F7F\u7528 deltree \u547D\u4EE4\u3002
    • \u91CD\u590D\u547D\u4EE4\uFF0CmacOS/Linux/Windows \u4E0B\u90FD\u53EF\u4EE5\u4F7F\u7528\u4E0A\u4E0B\u7BAD\u5934\u6765\u9009\u62E9\u4EE5\u5F80\u6267\u884C\u8FC7\u7684\u547D\u4EE4\u3002

    • \u547D\u4EE4\u5386\u53F2\uFF0CmacOS/Linux \u4E0B\u53EF\u4EE5\u4F7F\u7528 history \u547D\u4EE4\u67E5\u770B\u6240\u6709\u4F7F\u7528\u8FC7\u7684\u547D\u4EE4\u3002Windows \u53EF\u4EE5\u6309\u4E0B F7 \u952E\u3002

    • \u89E3\u538B\u6587\u4EF6\uFF0C\u540E\u7F00\u540D\u4E3A\u201C.zip\u201D\u7684\u6587\u4EF6\u662F\u4E00\u4E2A\u5305\u542B\u4E86\u5176\u4ED6\u6587\u4EF6\u7684\u538B\u7F29\u5305\uFF0CmacOS/Linux \u7CFB\u7EDF\u81EA\u8EAB\u5DF2\u7ECF\u63D0\u4F9B\u4E86\u7528\u4E8E\u89E3\u538B\u7684 unzip \u547D\u4EE4\uFF0C Windows \u7684\u8BDD\u9700\u8981\u624B\u52A8\u5B89\u88C5\u3002

    \u5B89\u88C5JDK

    1\uFF09Windows

    \u63A8\u8350\u5148\u5B89\u88C5 chocolatey\u3002\u8FD9\u662F\u4E00\u4E2AWindows\u4E0B\u7684\u547D\u4EE4\u884C\u8F6F\u4EF6\u7BA1\u7406\u5668\uFF0C\u53EF\u4EE5\u65B9\u4FBF\u5F00\u53D1\u8005\u50CF\u5728Linux\u4E0B\u4F7F\u7528yum\u547D\u4EE4\u6765\u5B89\u88C5\u8F6F\u4EF6\uFF0C\u6216\u8005\u50CF\u5728macOS\u4E0B\u4F7F\u7528brew \u547D\u4EE4\u6765\u5B89\u88C5\u8F6F\u4EF6\uFF0C\u975E\u5E38\u9177\u70AB\u3002

    The biggest challenge is reducing duplication of effort, so users turn to Chocolatey for simplicity

    \u4F20\u7EDF\u7684\u5B89\u88C5\u65B9\u5F0F\u8981\u4E48\u975E\u5E38\u8017\u65F6\uFF0C\u8981\u4E48\u975E\u5E38\u4F4E\u6548\uFF0C\u5728\u547D\u4EE4\u884C\u5B89\u88C5\u8F6F\u4EF6\u9664\u4E86\u7B80\u5355\u9AD8\u6548\uFF0C\u8FD8\u80FD\u81EA\u52A8\u5E2E\u6211\u4EEC\u914D\u7F6E\u73AF\u5883\u53D8\u91CF\u3002

    ',15),u=t("\u5B98\u65B9\u5730\u5740\uFF1A"),v={href:"https://chocolatey.org/",target:"_blank",rel:"noopener noreferrer"},w=t("https://chocolatey.org/"),_=t("\u5B89\u88C5\u6587\u6863\uFF1A"),j={href:"https://chocolatey.org/install#individual",target:"_blank",rel:"noopener noreferrer"},x=t("https://chocolatey.org/install#individual"),f=r('

    \u5B89\u88C5\u5B8C\u6210\u540E\u5982\u4E0B\u56FE\u6240\u793A\uFF1A

    \u5982\u679C\u4E0D\u786E\u5B9A\u662F\u5426\u5B89\u88C5\u6210\u529F\u7684\u8BDD\uFF0C\u53EF\u4EE5\u901A\u8FC7\u952E\u5165 choco \u547D\u4EE4\u6765\u786E\u8BA4\u3002

    \u8FD9\u91CC\u63A8\u8350\u51E0\u4E2A\u975E\u5E38\u9AD8\u6548\u7684\u64CD\u4F5C\u547D\u4EE4\uFF1A

    • choco search xxx\uFF0C\u67E5\u627E xxx \u5B89\u88C5\u5305
    • choco info xxx\uFF0C\u67E5\u770B xxx \u5B89\u88C5\u5305\u4FE1\u606F
    • choco install xxx\uFF0C\u5B89\u88C5 xxx \u8F6F\u4EF6
    • choco upgrade xxx\uFF0C\u5347\u7EA7 xxx \u8F6F\u4EF6
    • choco uninstall xxx\uFF0C \u5378\u8F7D xxx \u8F6F\u4EF6

    \u5982\u4F55\u77E5\u9053 chocolatey \u4ED3\u5E93\u4E2D\u90FD\u6709\u54EA\u4E9B\u5B89\u88C5\u5305\u53EF\u7528\u5462\uFF1F

    \u53EF\u4EE5\u901A\u8FC7\u4E0A\u9762\u63D0\u5230\u7684\u547D\u4EE4\u884C\u7684\u65B9\u5F0F\uFF0C\u4E5F\u53EF\u4EE5\u8BBF\u95EE\u5B98\u65B9\u4ED3\u5E93\u8FDB\u884C\u7B5B\u9009\u3002

    ',8),k={href:"https://community.chocolatey.org/packages",target:"_blank",rel:"noopener noreferrer"},y=t("https://community.chocolatey.org/packages"),S=r('

    \u6BD4\u5982\u8BF4\u6211\u4EEC\u6765\u67E5\u627E Java\u3002

    \u597D\uFF0C\u73B0\u5728\u53EF\u4EE5\u76F4\u63A5\u5728shell\u4E2D\u952E\u5165 choco install jdk8 \u6765\u5B89\u88C5 JDK8 \u4E86\uFF0C\u5E76\u4E14\u4F1A\u81EA\u52A8\u5C06Java\u52A0\u5165\u5230\u73AF\u5883\u53D8\u91CF\u4E2D\uFF0C\u4E0D\u7528\u518D\u53BB\u300C\u6211\u7684\u7535\u8111\u300D\u300C\u73AF\u5883\u53D8\u91CF\u300D\u4E2D\u65B0\u5EFA JAVA_HOME \u5E76\u590D\u5236 JDK \u5B89\u88C5\u8DEF\u5F84\u914D\u7F6E PATH \u53D8\u91CF\u4E86\uFF0C\u662F\u4E0D\u662F\u975E\u5E38 nice\uFF1F

    \u7A0D\u7B49\u7247\u523B\uFF0C\u952E\u5165 java -version \u5C31\u53EF\u4EE5\u786E\u8BA4Java\u662F\u5426\u5B89\u88C5\u6210\u529F\u4E86\u3002

    \u4E0D\u5F97\u4E0D\u627F\u8BA4\uFF01\u975E\u5E38nice\uFF01

    2\uFF09macOS

    \u9996\u5148\u63A8\u8350\u5B89\u88C5 homebrew\uFF0C\u8FD9\u662FmacOS\u4E0B\u7684\u547D\u4EE4\u884C\u8F6F\u4EF6\u7BA1\u7406\u5668\uFF0C\u7528\u6765\u7B80\u5316 macOS \u4E0A\u8F6F\u4EF6\u7684\u5B89\u88C5\u8FC7\u7A0B\u3002homebrew \u662F\u5F00\u6E90\u7684\uFF0C\u5728 GitHub \u5DF2\u6536\u83B7 32k star\u3002

    homebrew \u7684\u5B89\u88C5\u4E5F\u975E\u5E38\u7684\u7B80\u5355\uFF0C\u53EA\u9700\u8981\u4E00\u884C\u547D\u4EE4\u5373\u53EF\u3002

    ',10),H=t("\u5B98\u65B9\u7F51\u5740\uFF1A"),J={href:"https://brew.sh/index_zh-cn",target:"_blank",rel:"noopener noreferrer"},C=t("https://brew.sh/index_zh-cn"),O=r(`

    • \u4F7F\u7528 brew install xxx \u53EF\u4EE5\u5B89\u88C5 macOS \u4E0A\u6CA1\u6709\u9884\u88C5\u7684\u8F6F\u4EF6
    • \u4F7F\u7528 brew install --cask yyy \u53EF\u4EE5\u5B89\u88C5 macOS \u5176\u4ED6\u975E\u5F00\u6E90\u8F6F\u4EF6\u3002

    \u8FD9\u91CC\u662F homebrew \u5E38\u7528\u547D\u4EE4\u7684\u4E00\u4E2A\u6E05\u5355\uFF0C\u53EF\u4F9B\u53C2\u8003\u3002

    \u547D\u4EE4\u63CF\u8FF0
    brew update\u66F4\u65B0 Homebrew
    brew search package\u641C\u7D22\u8F6F\u4EF6\u5305
    brew install package\u5B89\u88C5\u8F6F\u4EF6\u5305
    brew uninstall package\u5378\u8F7D\u8F6F\u4EF6\u5305
    brew upgrade\u5347\u7EA7\u6240\u6709\u8F6F\u4EF6\u5305
    brew upgrade package\u5347\u7EA7\u6307\u5B9A\u8F6F\u4EF6\u5305
    brew list\u5217\u51FA\u5DF2\u5B89\u88C5\u7684\u8F6F\u4EF6\u5305\u5217\u8868
    brew services command package\u7BA1\u7406 brew \u5B89\u88C5\u8F6F\u4EF6\u5305
    brew services list\u5217\u51FA brew \u7BA1\u7406\u8FD0\u884C\u7684\u670D\u52A1
    brew info package\u67E5\u770B\u8F6F\u4EF6\u5305\u4FE1\u606F
    brew deps package\u5217\u51FA\u8F6F\u4EF6\u5305\u7684\u4F9D\u8D56\u5173\u7CFB
    brew help\u67E5\u770B\u5E2E\u52A9
    brew cleanup\u6E05\u9664\u8FC7\u65F6\u8F6F\u4EF6\u5305
    brew link package\u521B\u5EFA\u8F6F\u4EF6\u5305\u7B26\u53F7\u94FE\u63A5
    brew unlink package\u53D6\u6D88\u8F6F\u4EF6\u5305\u7B26\u53F7\u94FE\u63A5
    brew doctor\u68C0\u67E5\u7CFB\u7EDF\u662F\u5426\u5B58\u5728\u95EE\u9898

    \u5B89\u88C5\u5B8C homebrew \u540E\uFF0C\u5EFA\u8BAE\u66FF\u6362homebrew \u7684\u9ED8\u8BA4\u6E90\u4E3A\u4E2D\u79D1\u5927\u7684\uFF0C\u539F\u56E0\u5C31\u4E0D\u7528\u6211\u591A\u8BF4\u4E86\u5427\uFF1F\u66FF\u6362\u65B9\u6CD5\u5982\u4E0B\u6240\u793A\uFF1A

    \u66FF\u6362brew.git:
     cd "$(brew --repo)"
     git remote set-url origin https://mirrors.ustc.edu.cn/brew.git
     
    diff --git a/dist/assets/ConcurrentHashMap.html.127182e6.js b/dist/assets/ConcurrentHashMap.html.77d65cc9.js
    similarity index 99%
    rename from dist/assets/ConcurrentHashMap.html.127182e6.js
    rename to dist/assets/ConcurrentHashMap.html.77d65cc9.js
    index f4231c38..c8e4a70e 100644
    --- a/dist/assets/ConcurrentHashMap.html.127182e6.js
    +++ b/dist/assets/ConcurrentHashMap.html.77d65cc9.js
    @@ -1,4 +1,4 @@
    -import{_ as t}from"./plugin-vue_export-helper.21dcd24c.js";import{r as e,o,c,a as n,b as p,e as l,d as s}from"./app.a0271b9c.js";const i={},u=l(`

    \u5728\u4F7F\u7528HashMap\u65F6\uFF0C\u5728\u591A\u7EBF\u7A0B\u60C5\u51B5\u4E0B\u6269\u5BB9\u4F1A\u51FA\u73B0CPU\u63A5\u8FD1100%\u7684\u60C5\u51B5\uFF0C\u56E0\u4E3Ahashmap\u5E76\u4E0D\u662F\u7EBF\u7A0B\u5B89\u5168\u7684\uFF0C\u901A\u5E38\u6211\u4EEC\u53EF\u4EE5\u4F7F\u7528\u5728java\u4F53\u7CFB\u4E2D\u53E4\u8001\u7684hashtable\u7C7B\uFF0C\u8BE5\u7C7B\u57FA\u672C\u4E0A\u6240\u6709\u7684\u65B9\u6CD5\u90FD\u91C7\u7528synchronized\u8FDB\u884C\u7EBF\u7A0B\u5B89\u5168\u7684\u63A7\u5236\uFF0C\u53EF\u60F3\u800C\u77E5\uFF0C\u5728\u9AD8\u5E76\u53D1\u7684\u60C5\u51B5\u4E0B\uFF0C\u6BCF\u6B21\u53EA\u6709\u4E00\u4E2A\u7EBF\u7A0B\u80FD\u591F\u83B7\u53D6\u5BF9\u8C61\u76D1\u89C6\u5668\u9501\uFF0C\u8FD9\u6837\u7684\u5E76\u53D1\u6027\u80FD\u7684\u786E\u4E0D\u4EE4\u4EBA\u6EE1\u610F\u3002

    \u53E6\u5916\u4E00\u79CD\u65B9\u5F0F\u901A\u8FC7Collections\u7684Map<K,V> synchronizedMap(Map<K,V> m)\u5C06hashmap\u5305\u88C5\u6210\u4E00\u4E2A\u7EBF\u7A0B\u5B89\u5168\u7684map\u3002\u6BD4\u5982SynchronzedMap\u7684put\u65B9\u6CD5\u6E90\u7801\u4E3A\uFF1A

    	public V put(K key, V value) {
    +import{_ as t}from"./plugin-vue_export-helper.21dcd24c.js";import{r as e,o,c,a as n,b as p,e as l,d as s}from"./app.615e41d8.js";const i={},u=l(`

    \u5728\u4F7F\u7528HashMap\u65F6\uFF0C\u5728\u591A\u7EBF\u7A0B\u60C5\u51B5\u4E0B\u6269\u5BB9\u4F1A\u51FA\u73B0CPU\u63A5\u8FD1100%\u7684\u60C5\u51B5\uFF0C\u56E0\u4E3Ahashmap\u5E76\u4E0D\u662F\u7EBF\u7A0B\u5B89\u5168\u7684\uFF0C\u901A\u5E38\u6211\u4EEC\u53EF\u4EE5\u4F7F\u7528\u5728java\u4F53\u7CFB\u4E2D\u53E4\u8001\u7684hashtable\u7C7B\uFF0C\u8BE5\u7C7B\u57FA\u672C\u4E0A\u6240\u6709\u7684\u65B9\u6CD5\u90FD\u91C7\u7528synchronized\u8FDB\u884C\u7EBF\u7A0B\u5B89\u5168\u7684\u63A7\u5236\uFF0C\u53EF\u60F3\u800C\u77E5\uFF0C\u5728\u9AD8\u5E76\u53D1\u7684\u60C5\u51B5\u4E0B\uFF0C\u6BCF\u6B21\u53EA\u6709\u4E00\u4E2A\u7EBF\u7A0B\u80FD\u591F\u83B7\u53D6\u5BF9\u8C61\u76D1\u89C6\u5668\u9501\uFF0C\u8FD9\u6837\u7684\u5E76\u53D1\u6027\u80FD\u7684\u786E\u4E0D\u4EE4\u4EBA\u6EE1\u610F\u3002

    \u53E6\u5916\u4E00\u79CD\u65B9\u5F0F\u901A\u8FC7Collections\u7684Map<K,V> synchronizedMap(Map<K,V> m)\u5C06hashmap\u5305\u88C5\u6210\u4E00\u4E2A\u7EBF\u7A0B\u5B89\u5168\u7684map\u3002\u6BD4\u5982SynchronzedMap\u7684put\u65B9\u6CD5\u6E90\u7801\u4E3A\uFF1A

    	public V put(K key, V value) {
     	    synchronized (mutex) {return m.put(key, value);}
     	}
     

    \u5B9E\u9645\u4E0ASynchronizedMap\u5B9E\u73B0\u4F9D\u7136\u662F\u91C7\u7528synchronized\u72EC\u5360\u5F0F\u9501\u8FDB\u884C\u7EBF\u7A0B\u5B89\u5168\u7684\u5E76\u53D1\u63A7\u5236\u7684\u3002\u540C\u6837\uFF0C\u8FD9\u79CD\u65B9\u6848\u7684\u6027\u80FD\u4E5F\u662F\u4EE4\u4EBA\u4E0D\u592A\u6EE1\u610F\u7684\u3002\u9488\u5BF9\u8FD9\u79CD\u5883\u51B5\uFF0CDoug Lea\u5927\u5E08\u4E0D\u9057\u4F59\u529B\u7684\u4E3A\u6211\u4EEC\u521B\u9020\u4E86\u4E00\u4E9B\u7EBF\u7A0B\u5B89\u5168\u7684\u5E76\u53D1\u5BB9\u5668\uFF0C\u8BA9\u6BCF\u4E00\u4E2Ajava\u5F00\u53D1\u4EBA\u5458\u500D\u611F\u5E78\u798F\u3002\u76F8\u5BF9\u4E8Ehashmap\u6765\u8BF4\uFF0CConcurrentHashMap\u5C31\u662F\u7EBF\u7A0B\u5B89\u5168\u7684map\uFF0C\u5176\u4E2D\u5229\u7528\u4E86\u9501\u5206\u6BB5\u7684\u601D\u60F3\u63D0\u9AD8\u4E86\u5E76\u53D1\u5EA6\u3002

    ConcurrentHashMap\u5728JDK1.6\u7684\u7248\u672C\u7F51\u4E0A\u8D44\u6599\u5F88\u591A\uFF0C\u6709\u5174\u8DA3\u7684\u53EF\u4EE5\u53BB\u770B\u770B\u3002 JDK 1.6\u7248\u672C\u5173\u952E\u8981\u7D20\uFF1A

    1. segment\u7EE7\u627F\u4E86ReentrantLock\u5145\u5F53\u9501\u7684\u89D2\u8272\uFF0C\u4E3A\u6BCF\u4E00\u4E2Asegment\u63D0\u4F9B\u4E86\u7EBF\u7A0B\u5B89\u5168\u7684\u4FDD\u969C\uFF1B
    2. segment\u7EF4\u62A4\u4E86\u54C8\u5E0C\u6563\u5217\u8868\u7684\u82E5\u5E72\u4E2A\u6876\uFF0C\u6BCF\u4E2A\u6876\u7531HashEntry\u6784\u6210\u7684\u94FE\u8868\u3002

    \u800C\u5230\u4E86JDK 1.8\u7684ConcurrentHashMap\u5C31\u6709\u4E86\u5F88\u5927\u7684\u53D8\u5316\uFF0C\u5149\u662F\u4EE3\u7801\u91CF\u5C31\u8DB3\u8DB3\u589E\u52A0\u4E86\u5F88\u591A\u30021.8\u7248\u672C\u820D\u5F03\u4E86segment\uFF0C\u5E76\u4E14\u5927\u91CF\u4F7F\u7528\u4E86synchronized\uFF0C\u4EE5\u53CACAS\u65E0\u9501\u64CD\u4F5C\u4EE5\u4FDD\u8BC1ConcurrentHashMap\u64CD\u4F5C\u7684\u7EBF\u7A0B\u5B89\u5168\u6027\u3002

    \u81F3\u4E8E\u4E3A\u4EC0\u4E48\u4E0D\u7528ReentrantLock\u800C\u662FSynchronzied\u5462\uFF1F\u5B9E\u9645\u4E0A\uFF0Csynchronzied\u505A\u4E86\u5F88\u591A\u7684\u4F18\u5316\uFF0C\u5305\u62EC\u504F\u5411\u9501\uFF0C\u8F7B\u91CF\u7EA7\u9501\uFF0C\u91CD\u91CF\u7EA7\u9501\uFF0C\u53EF\u4EE5\u4F9D\u6B21\u5411\u4E0A\u5347\u7EA7\u9501\u72B6\u6001\uFF0C\u4F46\u4E0D\u80FD\u964D\u7EA7\uFF0C\u56E0\u6B64\uFF0C\u4F7F\u7528synchronized\u76F8\u8F83\u4E8EReentrantLock\u7684\u6027\u80FD\u4F1A\u6301\u5E73\u751A\u81F3\u5728\u67D0\u4E9B\u60C5\u51B5\u66F4\u4F18\uFF0C\u5177\u4F53\u7684\u6027\u80FD\u6D4B\u8BD5\u53EF\u4EE5\u53BB\u7F51\u4E0A\u67E5\u9605\u4E00\u4E9B\u8D44\u6599\u3002\u53E6\u5916\uFF0C\u5E95\u5C42\u6570\u636E\u7ED3\u6784\u6539\u53D8\u4E3A\u91C7\u7528\u6570\u7EC4+\u94FE\u8868+\u7EA2\u9ED1\u6811\u7684\u6570\u636E\u5F62\u5F0F\u3002

    \u5173\u952E\u5C5E\u6027\u53CA\u7C7B

    \u5728\u4E86\u89E3ConcurrentHashMap\u7684\u5177\u4F53\u65B9\u6CD5\u5B9E\u73B0\u524D\uFF0C\u6211\u4EEC\u9700\u8981\u7CFB\u7EDF\u7684\u6765\u770B\u4E00\u4E0B\u51E0\u4E2A\u5173\u952E\u7684\u5730\u65B9\u3002

    ConcurrentHashMap\u7684\u5173\u952E\u5C5E\u6027

    1. tablevolatile Node<K,V>[] table:

    \u88C5\u8F7DNode\u7684\u6570\u7EC4\uFF0C\u4F5C\u4E3AConcurrentHashMap\u7684\u6570\u636E\u5BB9\u5668\uFF0C\u91C7\u7528\u61D2\u52A0\u8F7D\u7684\u65B9\u5F0F\uFF0C\u76F4\u5230\u7B2C\u4E00\u6B21\u63D2\u5165\u6570\u636E\u7684\u65F6\u5019\u624D\u4F1A\u8FDB\u884C\u521D\u59CB\u5316\u64CD\u4F5C\uFF0C\u6570\u7EC4\u7684\u5927\u5C0F\u603B\u662F\u4E3A2\u7684\u5E42\u6B21\u65B9\u3002

    1. nextTablevolatile Node<K,V>[] nextTable;

    \u6269\u5BB9\u65F6\u4F7F\u7528\uFF0C\u5E73\u65F6\u4E3Anull\uFF0C\u53EA\u6709\u5728\u6269\u5BB9\u7684\u65F6\u5019\u624D\u4E3A\u975Enull

    1. sizeCtlvolatile int sizeCtl;

    \u8BE5\u5C5E\u6027\u7528\u6765\u63A7\u5236table\u6570\u7EC4\u7684\u5927\u5C0F\uFF0C\u6839\u636E\u662F\u5426\u521D\u59CB\u5316\u548C\u662F\u5426\u6B63\u5728\u6269\u5BB9\u6709\u51E0\u79CD\u60C5\u51B5\uFF1A

    • \u5F53\u503C\u4E3A\u8D1F\u6570\u65F6\uFF1A \u5982\u679C\u4E3A-1\u8868\u793A\u6B63\u5728\u521D\u59CB\u5316\uFF0C\u5982\u679C\u4E3A-N\u5219\u8868\u793A\u5F53\u524D\u6B63\u6709N-1\u4E2A\u7EBF\u7A0B\u8FDB\u884C\u6269\u5BB9\u64CD\u4F5C\uFF1B
    • \u5F53\u503C\u4E3A\u6B63\u6570\u65F6\uFF1A \u5982\u679C\u5F53\u524D\u6570\u7EC4\u4E3Anull\u7684\u8BDD\u8868\u793Atable\u5728\u521D\u59CB\u5316\u8FC7\u7A0B\u4E2D\uFF0CsizeCtl\u8868\u793A\u4E3A\u9700\u8981\u65B0\u5EFA\u6570\u7EC4\u7684\u957F\u5EA6\uFF1B
    • \u82E5\u5DF2\u7ECF\u521D\u59CB\u5316\u4E86\uFF0C\u8868\u793A\u5F53\u524D\u6570\u636E\u5BB9\u5668\uFF08table\u6570\u7EC4\uFF09\u53EF\u7528\u5BB9\u91CF\u4E5F\u53EF\u4EE5\u7406\u89E3\u6210\u4E34\u754C\u503C\uFF08\u63D2\u5165\u8282\u70B9\u6570\u8D85\u8FC7\u4E86\u8BE5\u4E34\u754C\u503C\u5C31\u9700\u8981\u6269\u5BB9\uFF09\uFF0C\u5177\u4F53\u6307\u4E3A\u6570\u7EC4\u7684\u957F\u5EA6n \u4E58\u4EE5 \u52A0\u8F7D\u56E0\u5B50loadFactor\uFF1B
    • \u5F53\u503C\u4E3A0\u65F6\uFF0C\u5373\u6570\u7EC4\u957F\u5EA6\u4E3A\u9ED8\u8BA4\u521D\u59CB\u503C\u3002
    1. sun.misc.Unsafe U

    \u5728ConcurrentHashMapde\u7684\u5B9E\u73B0\u4E2D\u53EF\u4EE5\u770B\u5230\u5927\u91CF\u7684U.compareAndSwapXXXX\u7684\u65B9\u6CD5\u53BB\u4FEE\u6539ConcurrentHashMap\u7684\u4E00\u4E9B\u5C5E\u6027\u3002

    \u8FD9\u4E9B\u65B9\u6CD5\u5B9E\u9645\u4E0A\u662F\u5229\u7528\u4E86CAS\u7B97\u6CD5\u4FDD\u8BC1\u4E86\u7EBF\u7A0B\u5B89\u5168\u6027\uFF0C\u8FD9\u662F\u4E00\u79CD\u4E50\u89C2\u7B56\u7565\uFF0C\u5047\u8BBE\u6BCF\u4E00\u6B21\u64CD\u4F5C\u90FD\u4E0D\u4F1A\u4EA7\u751F\u51B2\u7A81\uFF0C\u5F53\u4E14\u4EC5\u5F53\u51B2\u7A81\u53D1\u751F\u7684\u65F6\u5019\u518D\u53BB\u5C1D\u8BD5\u3002

    \u800CCAS\u64CD\u4F5C\u4F9D\u8D56\u4E8E\u73B0\u4EE3\u5904\u7406\u5668\u6307\u4EE4\u96C6\uFF0C\u901A\u8FC7\u5E95\u5C42CMPXCHG\u6307\u4EE4\u5B9E\u73B0\u3002CAS(V,O,N)\u6838\u5FC3\u601D\u60F3\u4E3A\uFF1A\u82E5\u5F53\u524D\u53D8\u91CF\u5B9E\u9645\u503CV\u4E0E\u671F\u671B\u7684\u65E7\u503CO\u76F8\u540C\uFF0C\u5219\u8868\u660E\u8BE5\u53D8\u91CF\u6CA1\u88AB\u5176\u4ED6\u7EBF\u7A0B\u8FDB\u884C\u4FEE\u6539\uFF0C\u56E0\u6B64\u53EF\u4EE5\u5B89\u5168\u7684\u5C06\u65B0\u503CN\u8D4B\u503C\u7ED9\u53D8\u91CF\uFF1B\u82E5\u5F53\u524D\u53D8\u91CF\u5B9E\u9645\u503CV\u4E0E\u671F\u671B\u7684\u65E7\u503CO\u4E0D\u76F8\u540C\uFF0C\u5219\u8868\u660E\u8BE5\u53D8\u91CF\u5DF2\u7ECF\u88AB\u5176\u4ED6\u7EBF\u7A0B\u505A\u4E86\u5904\u7406\uFF0C\u6B64\u65F6\u5C06\u65B0\u503CN\u8D4B\u7ED9\u53D8\u91CF\u64CD\u4F5C\u5C31\u662F\u4E0D\u5B89\u5168\u7684\uFF0C\u5728\u8FDB\u884C\u91CD\u8BD5\u3002

    \u800C\u5728\u5927\u91CF\u7684\u540C\u6B65\u7EC4\u4EF6\u548C\u5E76\u53D1\u5BB9\u5668\u7684\u5B9E\u73B0\u4E2D\u4F7F\u7528CAS\u662F\u901A\u8FC7sun.misc.Unsafe\u7C7B\u5B9E\u73B0\u7684\uFF0C\u8BE5\u7C7B\u63D0\u4F9B\u4E86\u4E00\u4E9B\u53EF\u4EE5\u76F4\u63A5\u64CD\u63A7\u5185\u5B58\u548C\u7EBF\u7A0B\u7684\u5E95\u5C42\u64CD\u4F5C\uFF0C\u53EF\u4EE5\u7406\u89E3\u4E3Ajava\u4E2D\u7684\u201C\u6307\u9488\u201D\u3002\u8BE5\u6210\u5458\u53D8\u91CF\u7684\u83B7\u53D6\u662F\u5728\u9759\u6001\u4EE3\u7801\u5757\u4E2D\uFF1A

    static {
    diff --git a/dist/assets/ConcurrentLinkedQueue.html.ad944043.js b/dist/assets/ConcurrentLinkedQueue.html.f8564dd9.js
    similarity index 99%
    rename from dist/assets/ConcurrentLinkedQueue.html.ad944043.js
    rename to dist/assets/ConcurrentLinkedQueue.html.f8564dd9.js
    index 4ee850a0..8bf3412e 100644
    --- a/dist/assets/ConcurrentLinkedQueue.html.ad944043.js
    +++ b/dist/assets/ConcurrentLinkedQueue.html.f8564dd9.js
    @@ -1,4 +1,4 @@
    -import{_ as t}from"./plugin-vue_export-helper.21dcd24c.js";import{r as p,o,c,a as n,b as a,e as l,d as e}from"./app.a0271b9c.js";const u={},i=l(`

    \u961F\u5217\u662F\u6211\u4EEC\u5E38\u7528\u7684\u4E00\u79CD\u6570\u636E\u7ED3\u6784\uFF0C\u4E3A\u4E86\u89E3\u51B3\u7EBF\u7A0B\u5B89\u5168\u7684\u95EE\u9898\uFF0CDoug Lea\u5927\u5E08\u4E3A\u6211\u4EEC\u51C6\u5907\u4E86ConcurrentLinkedQueue\u8FD9\u4E2A\u7EBF\u7A0B\u5B89\u5168\u7684\u961F\u5217\u3002\u4ECE\u7C7B\u540D\u5C31\u53EF\u4EE5\u770B\u7684\u51FA\u6765\u5B9E\u73B0\u961F\u5217\u7684\u6570\u636E\u7ED3\u6784\u662F\u94FE\u5F0F\u3002

    Node

    \u8981\u60F3\u5148\u5B66\u4E60ConcurrentLinkedQueue\u81EA\u7136\u800C\u7136\u5F97\u5148\u4ECE\u5B83\u7684\u8282\u70B9\u7C7B\u770B\u8D77\uFF0C\u660E\u767D\u5B83\u7684\u5E95\u5C42\u6570\u636E\u7ED3\u6784\u3002Node\u7C7B\u7684\u6E90\u7801\u4E3A\uFF1A

    private static class Node<E> {
    +import{_ as t}from"./plugin-vue_export-helper.21dcd24c.js";import{r as p,o,c,a as n,b as a,e as l,d as e}from"./app.615e41d8.js";const u={},i=l(`

    \u961F\u5217\u662F\u6211\u4EEC\u5E38\u7528\u7684\u4E00\u79CD\u6570\u636E\u7ED3\u6784\uFF0C\u4E3A\u4E86\u89E3\u51B3\u7EBF\u7A0B\u5B89\u5168\u7684\u95EE\u9898\uFF0CDoug Lea\u5927\u5E08\u4E3A\u6211\u4EEC\u51C6\u5907\u4E86ConcurrentLinkedQueue\u8FD9\u4E2A\u7EBF\u7A0B\u5B89\u5168\u7684\u961F\u5217\u3002\u4ECE\u7C7B\u540D\u5C31\u53EF\u4EE5\u770B\u7684\u51FA\u6765\u5B9E\u73B0\u961F\u5217\u7684\u6570\u636E\u7ED3\u6784\u662F\u94FE\u5F0F\u3002

    Node

    \u8981\u60F3\u5148\u5B66\u4E60ConcurrentLinkedQueue\u81EA\u7136\u800C\u7136\u5F97\u5148\u4ECE\u5B83\u7684\u8282\u70B9\u7C7B\u770B\u8D77\uFF0C\u660E\u767D\u5B83\u7684\u5E95\u5C42\u6570\u636E\u7ED3\u6784\u3002Node\u7C7B\u7684\u6E90\u7801\u4E3A\uFF1A

    private static class Node<E> {
             volatile E item;
             volatile Node<E> next;
     		.......
    diff --git a/dist/assets/CopyOnWriteArrayList.html.375356c8.js b/dist/assets/CopyOnWriteArrayList.html.2fa1badd.js
    similarity index 99%
    rename from dist/assets/CopyOnWriteArrayList.html.375356c8.js
    rename to dist/assets/CopyOnWriteArrayList.html.2fa1badd.js
    index f77ce901..aa324f64 100644
    --- a/dist/assets/CopyOnWriteArrayList.html.375356c8.js
    +++ b/dist/assets/CopyOnWriteArrayList.html.2fa1badd.js
    @@ -1,4 +1,4 @@
    -import{_ as e}from"./plugin-vue_export-helper.21dcd24c.js";import{r as p,o,c,a as n,b as a,e as i,d as t}from"./app.a0271b9c.js";const l={},r=i(`

    CopyOnWriteArrayList\u7684\u7B80\u4ECB

    java\u5B66\u4E60\u8005\u90FD\u6E05\u695AArrayList\u5E76\u4E0D\u662F\u7EBF\u7A0B\u5B89\u5168\u7684\uFF0C\u5728\u8BFB\u7EBF\u7A0B\u5728\u8BFB\u53D6ArrayList\u7684\u65F6\u5019\u5982\u679C\u6709\u5199\u7EBF\u7A0B\u5728\u5199\u6570\u636E\u7684\u65F6\u5019\uFF0C\u57FA\u4E8Efast-fail\u673A\u5236\uFF0C\u4F1A\u629B\u51FAConcurrentModificationException\u5F02\u5E38\uFF0C\u4E5F\u5C31\u662F\u8BF4ArrayList\u5E76\u4E0D\u662F\u4E00\u4E2A\u7EBF\u7A0B\u5B89\u5168\u7684\u5BB9\u5668\uFF0C\u5F53\u7136\u60A8\u53EF\u4EE5\u7528Vector,\u6216\u8005\u4F7F\u7528Collections\u7684\u9759\u6001\u65B9\u6CD5\u5C06ArrayList\u5305\u88C5\u6210\u4E00\u4E2A\u7EBF\u7A0B\u5B89\u5168\u7684\u7C7B\uFF0C\u4F46\u662F\u8FD9\u4E9B\u65B9\u5F0F\u90FD\u662F\u91C7\u7528java\u5173\u952E\u5B57synchronzied\u5BF9\u65B9\u6CD5\u8FDB\u884C\u4FEE\u9970\uFF0C\u5229\u7528\u72EC\u5360\u5F0F\u9501\u6765\u4FDD\u8BC1\u7EBF\u7A0B\u5B89\u5168\u7684\u3002\u4F46\u662F\uFF0C\u7531\u4E8E\u72EC\u5360\u5F0F\u9501\u5728\u540C\u4E00\u65F6\u523B\u53EA\u6709\u4E00\u4E2A\u7EBF\u7A0B\u80FD\u591F\u83B7\u53D6\u5230\u5BF9\u8C61\u76D1\u89C6\u5668\uFF0C\u5F88\u663E\u7136\u8FD9\u79CD\u65B9\u5F0F\u6548\u7387\u5E76\u4E0D\u662F\u592A\u9AD8\u3002

    \u56DE\u5230\u4E1A\u52A1\u573A\u666F\u4E2D\uFF0C\u6709\u5F88\u591A\u4E1A\u52A1\u5F80\u5F80\u662F\u8BFB\u591A\u5199\u5C11\u7684\uFF0C\u6BD4\u5982\u7CFB\u7EDF\u914D\u7F6E\u7684\u4FE1\u606F\uFF0C\u9664\u4E86\u5728\u521D\u59CB\u8FDB\u884C\u7CFB\u7EDF\u914D\u7F6E\u7684\u65F6\u5019\u9700\u8981\u5199\u5165\u6570\u636E\uFF0C\u5176\u4ED6\u5927\u90E8\u5206\u65F6\u523B\u5176\u4ED6\u6A21\u5757\u4E4B\u540E\u5BF9\u7CFB\u7EDF\u4FE1\u606F\u53EA\u9700\u8981\u8FDB\u884C\u8BFB\u53D6\uFF0C\u53C8\u6BD4\u5982\u767D\u540D\u5355\uFF0C\u9ED1\u540D\u5355\u7B49\u914D\u7F6E\uFF0C\u53EA\u9700\u8981\u8BFB\u53D6\u540D\u5355\u914D\u7F6E\u7136\u540E\u68C0\u6D4B\u5F53\u524D\u7528\u6237\u662F\u5426\u5728\u8BE5\u914D\u7F6E\u8303\u56F4\u4EE5\u5185\u3002

    \u7C7B\u4F3C\u7684\u8FD8\u6709\u5F88\u591A\u4E1A\u52A1\u573A\u666F\uFF0C\u5B83\u4EEC\u90FD\u662F\u5C5E\u4E8E\u8BFB\u591A\u5199\u5C11\u7684\u573A\u666F\u3002\u5982\u679C\u5728\u8FD9\u79CD\u60C5\u51B5\u7528\u5230\u4E0A\u8FF0\u7684\u65B9\u6CD5\uFF0C\u4F7F\u7528Vector,Collections\u8F6C\u6362\u7684\u8FD9\u4E9B\u65B9\u5F0F\u662F\u4E0D\u5408\u7406\u7684\uFF0C\u56E0\u4E3A\u5C3D\u7BA1\u591A\u4E2A\u8BFB\u7EBF\u7A0B\u4ECE\u540C\u4E00\u4E2A\u6570\u636E\u5BB9\u5668\u4E2D\u8BFB\u53D6\u6570\u636E\uFF0C\u4F46\u662F\u8BFB\u7EBF\u7A0B\u5BF9\u6570\u636E\u5BB9\u5668\u7684\u6570\u636E\u5E76\u4E0D\u4F1A\u53D1\u751F\u53D1\u751F\u4FEE\u6539\u3002

    \u5F88\u81EA\u7136\u800C\u7136\u7684\u6211\u4EEC\u4F1A\u8054\u60F3\u5230ReenTrantReadWriteLock\uFF0C\u901A\u8FC7\u8BFB\u5199\u5206\u79BB\u7684\u601D\u60F3\uFF0C\u4F7F\u5F97\u8BFB\u8BFB\u4E4B\u95F4\u4E0D\u4F1A\u963B\u585E\uFF0C\u65E0\u7591\u5982\u679C\u4E00\u4E2Alist\u80FD\u591F\u505A\u5230\u88AB\u591A\u4E2A\u8BFB\u7EBF\u7A0B\u8BFB\u53D6\u7684\u8BDD\uFF0C\u6027\u80FD\u4F1A\u5927\u5927\u63D0\u5347\u4E0D\u5C11\u3002\u4F46\u662F\uFF0C\u5982\u679C\u4EC5\u4EC5\u662F\u5C06list\u901A\u8FC7\u8BFB\u5199\u9501\uFF08ReentrantReadWriteLock\uFF09\u8FDB\u884C\u518D\u4E00\u6B21\u5C01\u88C5\u7684\u8BDD\uFF0C\u7531\u4E8E\u8BFB\u5199\u9501\u7684\u7279\u6027\uFF0C\u5F53\u5199\u9501\u88AB\u5199\u7EBF\u7A0B\u83B7\u53D6\u540E\uFF0C\u8BFB\u5199\u7EBF\u7A0B\u90FD\u4F1A\u88AB\u963B\u585E\u3002\u5982\u679C\u4EC5\u4EC5\u4F7F\u7528\u8BFB\u5199\u9501\u5BF9list\u8FDB\u884C\u5C01\u88C5\u7684\u8BDD\uFF0C\u8FD9\u91CC\u4ECD\u7136\u5B58\u5728\u8BFB\u7EBF\u7A0B\u5728\u8BFB\u6570\u636E\u7684\u65F6\u5019\u88AB\u963B\u585E\u7684\u60C5\u51B5\uFF0C\u5982\u679C\u60F3list\u7684\u8BFB\u6548\u7387\u66F4\u9AD8\u7684\u8BDD\uFF0C\u8FD9\u91CC\u5C31\u662F\u6211\u4EEC\u7684\u7A81\u7834\u53E3\uFF0C\u5982\u679C\u6211\u4EEC\u4FDD\u8BC1\u8BFB\u7EBF\u7A0B\u65E0\u8BBA\u4EC0\u4E48\u65F6\u5019\u90FD\u4E0D\u88AB\u963B\u585E\uFF0C\u6548\u7387\u5C82\u4E0D\u662F\u4F1A\u66F4\u9AD8\uFF1F

    Doug Lea\u5927\u5E08\u5C31\u4E3A\u6211\u4EEC\u63D0\u4F9BCopyOnWriteArrayList\u5BB9\u5668\u53EF\u4EE5\u4FDD\u8BC1\u7EBF\u7A0B\u5B89\u5168\uFF0C\u4FDD\u8BC1\u8BFB\u8BFB\u4E4B\u95F4\u5728\u4EFB\u4F55\u65F6\u5019\u90FD\u4E0D\u4F1A\u88AB\u963B\u585E\uFF0CCopyOnWriteArrayList\u4E5F\u88AB\u5E7F\u6CDB\u5E94\u7528\u4E8E\u5F88\u591A\u4E1A\u52A1\u573A\u666F\u4E4B\u4E2D\uFF0CCopyOnWriteArrayList\u503C\u5F97\u88AB\u6211\u4EEC\u597D\u597D\u8BA4\u8BC6\u4E00\u756A\u3002

    COW\u7684\u8BBE\u8BA1\u601D\u60F3

    \u56DE\u5230\u4E0A\u9762\u6240\u8BF4\u7684\uFF0C\u5982\u679C\u7B80\u5355\u7684\u4F7F\u7528\u8BFB\u5199\u9501\u7684\u8BDD\uFF0C\u5728\u5199\u9501\u88AB\u83B7\u53D6\u4E4B\u540E\uFF0C\u8BFB\u5199\u7EBF\u7A0B\u88AB\u963B\u585E\uFF0C\u53EA\u6709\u5F53\u5199\u9501\u88AB\u91CA\u653E\u540E\u8BFB\u7EBF\u7A0B\u624D\u6709\u673A\u4F1A\u83B7\u53D6\u5230\u9501\u4ECE\u800C\u8BFB\u5230\u6700\u65B0\u7684\u6570\u636E\uFF0C\u7AD9\u5728\u8BFB\u7EBF\u7A0B\u7684\u89D2\u5EA6\u6765\u770B\uFF0C\u5373\u8BFB\u7EBF\u7A0B\u4EFB\u4F55\u65F6\u5019\u90FD\u662F\u83B7\u53D6\u5230\u6700\u65B0\u7684\u6570\u636E\uFF0C\u6EE1\u8DB3\u6570\u636E\u5B9E\u65F6\u6027\u3002

    \u65E2\u7136\u6211\u4EEC\u8BF4\u5230\u8981\u8FDB\u884C\u4F18\u5316\uFF0C\u5FC5\u7136\u6709trade-off,\u6211\u4EEC\u5C31\u53EF\u4EE5\u727A\u7272\u6570\u636E\u5B9E\u65F6\u6027\u6EE1\u8DB3\u6570\u636E\u7684\u6700\u7EC8\u4E00\u81F4\u6027\u5373\u53EF\u3002\u800CCopyOnWriteArrayList\u5C31\u662F\u901A\u8FC7Copy-On-Write(COW)\uFF0C\u5373\u5199\u65F6\u590D\u5236\u7684\u601D\u60F3\u6765\u901A\u8FC7\u5EF6\u65F6\u66F4\u65B0\u7684\u7B56\u7565\u6765\u5B9E\u73B0\u6570\u636E\u7684\u6700\u7EC8\u4E00\u81F4\u6027\uFF0C\u5E76\u4E14\u80FD\u591F\u4FDD\u8BC1\u8BFB\u7EBF\u7A0B\u95F4\u4E0D\u963B\u585E\u3002

    COW\u901A\u4FD7\u7684\u7406\u89E3\u662F\u5F53\u6211\u4EEC\u5F80\u4E00\u4E2A\u5BB9\u5668\u6DFB\u52A0\u5143\u7D20\u7684\u65F6\u5019\uFF0C\u4E0D\u76F4\u63A5\u5F80\u5F53\u524D\u5BB9\u5668\u6DFB\u52A0\uFF0C\u800C\u662F\u5148\u5C06\u5F53\u524D\u5BB9\u5668\u8FDB\u884CCopy\uFF0C\u590D\u5236\u51FA\u4E00\u4E2A\u65B0\u7684\u5BB9\u5668\uFF0C\u7136\u540E\u65B0\u7684\u5BB9\u5668\u91CC\u6DFB\u52A0\u5143\u7D20\uFF0C\u6DFB\u52A0\u5B8C\u5143\u7D20\u4E4B\u540E\uFF0C\u518D\u5C06\u539F\u5BB9\u5668\u7684\u5F15\u7528\u6307\u5411\u65B0\u7684\u5BB9\u5668\u3002

    \u5BF9CopyOnWrite\u5BB9\u5668\u8FDB\u884C\u5E76\u53D1\u7684\u8BFB\u7684\u65F6\u5019\uFF0C\u4E0D\u9700\u8981\u52A0\u9501\uFF0C\u56E0\u4E3A\u5F53\u524D\u5BB9\u5668\u4E0D\u4F1A\u6DFB\u52A0\u4EFB\u4F55\u5143\u7D20\u3002\u6240\u4EE5CopyOnWrite\u5BB9\u5668\u4E5F\u662F\u4E00\u79CD\u8BFB\u5199\u5206\u79BB\u7684\u601D\u60F3\uFF0C\u5EF6\u65F6\u66F4\u65B0\u7684\u7B56\u7565\u662F\u901A\u8FC7\u5728\u5199\u7684\u65F6\u5019\u9488\u5BF9\u7684\u662F\u4E0D\u540C\u7684\u6570\u636E\u5BB9\u5668\u6765\u5B9E\u73B0\u7684\uFF0C\u653E\u5F03\u6570\u636E\u5B9E\u65F6\u6027\u8FBE\u5230\u6570\u636E\u7684\u6700\u7EC8\u4E00\u81F4\u6027\u3002

    CopyOnWriteArrayList\u7684\u5B9E\u73B0\u539F\u7406

    \u73B0\u5728\u6211\u4EEC\u6765\u901A\u8FC7\u770B\u6E90\u7801\u7684\u65B9\u5F0F\u6765\u7406\u89E3CopyOnWriteArrayList\uFF0C\u5B9E\u9645\u4E0ACopyOnWriteArrayList\u5185\u90E8\u7EF4\u62A4\u7684\u5C31\u662F\u4E00\u4E2A\u6570\u7EC4

    /** The array, accessed only via getArray/setArray. */
    +import{_ as e}from"./plugin-vue_export-helper.21dcd24c.js";import{r as p,o,c,a as n,b as a,e as i,d as t}from"./app.615e41d8.js";const l={},r=i(`

    CopyOnWriteArrayList\u7684\u7B80\u4ECB

    java\u5B66\u4E60\u8005\u90FD\u6E05\u695AArrayList\u5E76\u4E0D\u662F\u7EBF\u7A0B\u5B89\u5168\u7684\uFF0C\u5728\u8BFB\u7EBF\u7A0B\u5728\u8BFB\u53D6ArrayList\u7684\u65F6\u5019\u5982\u679C\u6709\u5199\u7EBF\u7A0B\u5728\u5199\u6570\u636E\u7684\u65F6\u5019\uFF0C\u57FA\u4E8Efast-fail\u673A\u5236\uFF0C\u4F1A\u629B\u51FAConcurrentModificationException\u5F02\u5E38\uFF0C\u4E5F\u5C31\u662F\u8BF4ArrayList\u5E76\u4E0D\u662F\u4E00\u4E2A\u7EBF\u7A0B\u5B89\u5168\u7684\u5BB9\u5668\uFF0C\u5F53\u7136\u60A8\u53EF\u4EE5\u7528Vector,\u6216\u8005\u4F7F\u7528Collections\u7684\u9759\u6001\u65B9\u6CD5\u5C06ArrayList\u5305\u88C5\u6210\u4E00\u4E2A\u7EBF\u7A0B\u5B89\u5168\u7684\u7C7B\uFF0C\u4F46\u662F\u8FD9\u4E9B\u65B9\u5F0F\u90FD\u662F\u91C7\u7528java\u5173\u952E\u5B57synchronzied\u5BF9\u65B9\u6CD5\u8FDB\u884C\u4FEE\u9970\uFF0C\u5229\u7528\u72EC\u5360\u5F0F\u9501\u6765\u4FDD\u8BC1\u7EBF\u7A0B\u5B89\u5168\u7684\u3002\u4F46\u662F\uFF0C\u7531\u4E8E\u72EC\u5360\u5F0F\u9501\u5728\u540C\u4E00\u65F6\u523B\u53EA\u6709\u4E00\u4E2A\u7EBF\u7A0B\u80FD\u591F\u83B7\u53D6\u5230\u5BF9\u8C61\u76D1\u89C6\u5668\uFF0C\u5F88\u663E\u7136\u8FD9\u79CD\u65B9\u5F0F\u6548\u7387\u5E76\u4E0D\u662F\u592A\u9AD8\u3002

    \u56DE\u5230\u4E1A\u52A1\u573A\u666F\u4E2D\uFF0C\u6709\u5F88\u591A\u4E1A\u52A1\u5F80\u5F80\u662F\u8BFB\u591A\u5199\u5C11\u7684\uFF0C\u6BD4\u5982\u7CFB\u7EDF\u914D\u7F6E\u7684\u4FE1\u606F\uFF0C\u9664\u4E86\u5728\u521D\u59CB\u8FDB\u884C\u7CFB\u7EDF\u914D\u7F6E\u7684\u65F6\u5019\u9700\u8981\u5199\u5165\u6570\u636E\uFF0C\u5176\u4ED6\u5927\u90E8\u5206\u65F6\u523B\u5176\u4ED6\u6A21\u5757\u4E4B\u540E\u5BF9\u7CFB\u7EDF\u4FE1\u606F\u53EA\u9700\u8981\u8FDB\u884C\u8BFB\u53D6\uFF0C\u53C8\u6BD4\u5982\u767D\u540D\u5355\uFF0C\u9ED1\u540D\u5355\u7B49\u914D\u7F6E\uFF0C\u53EA\u9700\u8981\u8BFB\u53D6\u540D\u5355\u914D\u7F6E\u7136\u540E\u68C0\u6D4B\u5F53\u524D\u7528\u6237\u662F\u5426\u5728\u8BE5\u914D\u7F6E\u8303\u56F4\u4EE5\u5185\u3002

    \u7C7B\u4F3C\u7684\u8FD8\u6709\u5F88\u591A\u4E1A\u52A1\u573A\u666F\uFF0C\u5B83\u4EEC\u90FD\u662F\u5C5E\u4E8E\u8BFB\u591A\u5199\u5C11\u7684\u573A\u666F\u3002\u5982\u679C\u5728\u8FD9\u79CD\u60C5\u51B5\u7528\u5230\u4E0A\u8FF0\u7684\u65B9\u6CD5\uFF0C\u4F7F\u7528Vector,Collections\u8F6C\u6362\u7684\u8FD9\u4E9B\u65B9\u5F0F\u662F\u4E0D\u5408\u7406\u7684\uFF0C\u56E0\u4E3A\u5C3D\u7BA1\u591A\u4E2A\u8BFB\u7EBF\u7A0B\u4ECE\u540C\u4E00\u4E2A\u6570\u636E\u5BB9\u5668\u4E2D\u8BFB\u53D6\u6570\u636E\uFF0C\u4F46\u662F\u8BFB\u7EBF\u7A0B\u5BF9\u6570\u636E\u5BB9\u5668\u7684\u6570\u636E\u5E76\u4E0D\u4F1A\u53D1\u751F\u53D1\u751F\u4FEE\u6539\u3002

    \u5F88\u81EA\u7136\u800C\u7136\u7684\u6211\u4EEC\u4F1A\u8054\u60F3\u5230ReenTrantReadWriteLock\uFF0C\u901A\u8FC7\u8BFB\u5199\u5206\u79BB\u7684\u601D\u60F3\uFF0C\u4F7F\u5F97\u8BFB\u8BFB\u4E4B\u95F4\u4E0D\u4F1A\u963B\u585E\uFF0C\u65E0\u7591\u5982\u679C\u4E00\u4E2Alist\u80FD\u591F\u505A\u5230\u88AB\u591A\u4E2A\u8BFB\u7EBF\u7A0B\u8BFB\u53D6\u7684\u8BDD\uFF0C\u6027\u80FD\u4F1A\u5927\u5927\u63D0\u5347\u4E0D\u5C11\u3002\u4F46\u662F\uFF0C\u5982\u679C\u4EC5\u4EC5\u662F\u5C06list\u901A\u8FC7\u8BFB\u5199\u9501\uFF08ReentrantReadWriteLock\uFF09\u8FDB\u884C\u518D\u4E00\u6B21\u5C01\u88C5\u7684\u8BDD\uFF0C\u7531\u4E8E\u8BFB\u5199\u9501\u7684\u7279\u6027\uFF0C\u5F53\u5199\u9501\u88AB\u5199\u7EBF\u7A0B\u83B7\u53D6\u540E\uFF0C\u8BFB\u5199\u7EBF\u7A0B\u90FD\u4F1A\u88AB\u963B\u585E\u3002\u5982\u679C\u4EC5\u4EC5\u4F7F\u7528\u8BFB\u5199\u9501\u5BF9list\u8FDB\u884C\u5C01\u88C5\u7684\u8BDD\uFF0C\u8FD9\u91CC\u4ECD\u7136\u5B58\u5728\u8BFB\u7EBF\u7A0B\u5728\u8BFB\u6570\u636E\u7684\u65F6\u5019\u88AB\u963B\u585E\u7684\u60C5\u51B5\uFF0C\u5982\u679C\u60F3list\u7684\u8BFB\u6548\u7387\u66F4\u9AD8\u7684\u8BDD\uFF0C\u8FD9\u91CC\u5C31\u662F\u6211\u4EEC\u7684\u7A81\u7834\u53E3\uFF0C\u5982\u679C\u6211\u4EEC\u4FDD\u8BC1\u8BFB\u7EBF\u7A0B\u65E0\u8BBA\u4EC0\u4E48\u65F6\u5019\u90FD\u4E0D\u88AB\u963B\u585E\uFF0C\u6548\u7387\u5C82\u4E0D\u662F\u4F1A\u66F4\u9AD8\uFF1F

    Doug Lea\u5927\u5E08\u5C31\u4E3A\u6211\u4EEC\u63D0\u4F9BCopyOnWriteArrayList\u5BB9\u5668\u53EF\u4EE5\u4FDD\u8BC1\u7EBF\u7A0B\u5B89\u5168\uFF0C\u4FDD\u8BC1\u8BFB\u8BFB\u4E4B\u95F4\u5728\u4EFB\u4F55\u65F6\u5019\u90FD\u4E0D\u4F1A\u88AB\u963B\u585E\uFF0CCopyOnWriteArrayList\u4E5F\u88AB\u5E7F\u6CDB\u5E94\u7528\u4E8E\u5F88\u591A\u4E1A\u52A1\u573A\u666F\u4E4B\u4E2D\uFF0CCopyOnWriteArrayList\u503C\u5F97\u88AB\u6211\u4EEC\u597D\u597D\u8BA4\u8BC6\u4E00\u756A\u3002

    COW\u7684\u8BBE\u8BA1\u601D\u60F3

    \u56DE\u5230\u4E0A\u9762\u6240\u8BF4\u7684\uFF0C\u5982\u679C\u7B80\u5355\u7684\u4F7F\u7528\u8BFB\u5199\u9501\u7684\u8BDD\uFF0C\u5728\u5199\u9501\u88AB\u83B7\u53D6\u4E4B\u540E\uFF0C\u8BFB\u5199\u7EBF\u7A0B\u88AB\u963B\u585E\uFF0C\u53EA\u6709\u5F53\u5199\u9501\u88AB\u91CA\u653E\u540E\u8BFB\u7EBF\u7A0B\u624D\u6709\u673A\u4F1A\u83B7\u53D6\u5230\u9501\u4ECE\u800C\u8BFB\u5230\u6700\u65B0\u7684\u6570\u636E\uFF0C\u7AD9\u5728\u8BFB\u7EBF\u7A0B\u7684\u89D2\u5EA6\u6765\u770B\uFF0C\u5373\u8BFB\u7EBF\u7A0B\u4EFB\u4F55\u65F6\u5019\u90FD\u662F\u83B7\u53D6\u5230\u6700\u65B0\u7684\u6570\u636E\uFF0C\u6EE1\u8DB3\u6570\u636E\u5B9E\u65F6\u6027\u3002

    \u65E2\u7136\u6211\u4EEC\u8BF4\u5230\u8981\u8FDB\u884C\u4F18\u5316\uFF0C\u5FC5\u7136\u6709trade-off,\u6211\u4EEC\u5C31\u53EF\u4EE5\u727A\u7272\u6570\u636E\u5B9E\u65F6\u6027\u6EE1\u8DB3\u6570\u636E\u7684\u6700\u7EC8\u4E00\u81F4\u6027\u5373\u53EF\u3002\u800CCopyOnWriteArrayList\u5C31\u662F\u901A\u8FC7Copy-On-Write(COW)\uFF0C\u5373\u5199\u65F6\u590D\u5236\u7684\u601D\u60F3\u6765\u901A\u8FC7\u5EF6\u65F6\u66F4\u65B0\u7684\u7B56\u7565\u6765\u5B9E\u73B0\u6570\u636E\u7684\u6700\u7EC8\u4E00\u81F4\u6027\uFF0C\u5E76\u4E14\u80FD\u591F\u4FDD\u8BC1\u8BFB\u7EBF\u7A0B\u95F4\u4E0D\u963B\u585E\u3002

    COW\u901A\u4FD7\u7684\u7406\u89E3\u662F\u5F53\u6211\u4EEC\u5F80\u4E00\u4E2A\u5BB9\u5668\u6DFB\u52A0\u5143\u7D20\u7684\u65F6\u5019\uFF0C\u4E0D\u76F4\u63A5\u5F80\u5F53\u524D\u5BB9\u5668\u6DFB\u52A0\uFF0C\u800C\u662F\u5148\u5C06\u5F53\u524D\u5BB9\u5668\u8FDB\u884CCopy\uFF0C\u590D\u5236\u51FA\u4E00\u4E2A\u65B0\u7684\u5BB9\u5668\uFF0C\u7136\u540E\u65B0\u7684\u5BB9\u5668\u91CC\u6DFB\u52A0\u5143\u7D20\uFF0C\u6DFB\u52A0\u5B8C\u5143\u7D20\u4E4B\u540E\uFF0C\u518D\u5C06\u539F\u5BB9\u5668\u7684\u5F15\u7528\u6307\u5411\u65B0\u7684\u5BB9\u5668\u3002

    \u5BF9CopyOnWrite\u5BB9\u5668\u8FDB\u884C\u5E76\u53D1\u7684\u8BFB\u7684\u65F6\u5019\uFF0C\u4E0D\u9700\u8981\u52A0\u9501\uFF0C\u56E0\u4E3A\u5F53\u524D\u5BB9\u5668\u4E0D\u4F1A\u6DFB\u52A0\u4EFB\u4F55\u5143\u7D20\u3002\u6240\u4EE5CopyOnWrite\u5BB9\u5668\u4E5F\u662F\u4E00\u79CD\u8BFB\u5199\u5206\u79BB\u7684\u601D\u60F3\uFF0C\u5EF6\u65F6\u66F4\u65B0\u7684\u7B56\u7565\u662F\u901A\u8FC7\u5728\u5199\u7684\u65F6\u5019\u9488\u5BF9\u7684\u662F\u4E0D\u540C\u7684\u6570\u636E\u5BB9\u5668\u6765\u5B9E\u73B0\u7684\uFF0C\u653E\u5F03\u6570\u636E\u5B9E\u65F6\u6027\u8FBE\u5230\u6570\u636E\u7684\u6700\u7EC8\u4E00\u81F4\u6027\u3002

    CopyOnWriteArrayList\u7684\u5B9E\u73B0\u539F\u7406

    \u73B0\u5728\u6211\u4EEC\u6765\u901A\u8FC7\u770B\u6E90\u7801\u7684\u65B9\u5F0F\u6765\u7406\u89E3CopyOnWriteArrayList\uFF0C\u5B9E\u9645\u4E0ACopyOnWriteArrayList\u5185\u90E8\u7EF4\u62A4\u7684\u5C31\u662F\u4E00\u4E2A\u6570\u7EC4

    /** The array, accessed only via getArray/setArray. */
     private transient volatile Object[] array;
     

    \u5E76\u4E14\u8BE5\u6570\u7EC4\u5F15\u7528\u662F\u88ABvolatile\u4FEE\u9970\uFF0C\u6CE8\u610F\u8FD9\u91CC\u4EC5\u4EC5\u662F\u4FEE\u9970\u7684\u662F\u6570\u7EC4\u5F15\u7528\uFF0C\u5176\u4E2D\u53E6\u6709\u7384\u673A\uFF0C\u7A0D\u540E\u63ED\u6653\u3002\u5173\u4E8Evolatile\u5F88\u91CD\u8981\u7684\u4E00\u6761\u6027\u8D28\u662F\u5B83\u80FD\u591F\u591F\u4FDD\u8BC1\u53EF\u89C1\u6027\u3002\u5BF9list\u6765\u8BF4\uFF0C\u6211\u4EEC\u81EA\u7136\u800C\u7136\u6700\u5173\u5FC3\u7684\u5C31\u662F\u8BFB\u5199\u7684\u65F6\u5019\uFF0C\u5206\u522B\u4E3Aget\u548Cadd\u65B9\u6CD5\u7684\u5B9E\u73B0\u3002

    get\u65B9\u6CD5\u5B9E\u73B0\u539F\u7406

    get\u65B9\u6CD5\u7684\u6E90\u7801\u4E3A\uFF1A

    public E get(int index) {
         return get(getArray(), index);
    diff --git a/dist/assets/CountDownLatch.html.db5e5e87.js b/dist/assets/CountDownLatch.html.79c0b80e.js
    similarity index 99%
    rename from dist/assets/CountDownLatch.html.db5e5e87.js
    rename to dist/assets/CountDownLatch.html.79c0b80e.js
    index f525235d..e7f6827c 100644
    --- a/dist/assets/CountDownLatch.html.db5e5e87.js
    +++ b/dist/assets/CountDownLatch.html.79c0b80e.js
    @@ -1,4 +1,4 @@
    -import{_ as t}from"./plugin-vue_export-helper.21dcd24c.js";import{r as e,o as c,c as o,a as n,b as a,e as l,d as p}from"./app.a0271b9c.js";const i={},u=l(`

    JDK\u4E2D\u63D0\u4F9B\u4E86\u4E00\u4E9B\u5DE5\u5177\u7C7B\u4EE5\u4F9B\u5F00\u53D1\u8005\u4F7F\u7528\u3002\u8FD9\u6837\u7684\u8BDD\u6211\u4EEC\u5728\u9047\u5230\u4E00\u4E9B\u5E38\u89C1\u7684\u5E94\u7528\u573A\u666F\u65F6\u5C31\u53EF\u4EE5\u4F7F\u7528\u8FD9\u4E9B\u5DE5\u5177\u7C7B\uFF0C\u800C\u4E0D\u7528\u81EA\u5DF1\u518D\u91CD\u590D\u9020\u8F6E\u5B50\u4E86\u3002

    \u5B83\u4EEC\u90FD\u5728java.util.concurrent\u5305\u4E0B\u3002\u5148\u603B\u4F53\u6982\u62EC\u4E00\u4E0B\u90FD\u6709\u54EA\u4E9B\u5DE5\u5177\u7C7B\uFF0C\u5B83\u4EEC\u6709\u4EC0\u4E48\u4F5C\u7528\uFF0C\u7136\u540E\u518D\u5206\u522B\u4ECB\u7ECD\u5B83\u4EEC\u7684\u4E3B\u8981\u4F7F\u7528\u65B9\u6CD5\u548C\u539F\u7406\u3002

    \u7C7B\u4F5C\u7528
    Semaphore\u9650\u5236\u7EBF\u7A0B\u7684\u6570\u91CF
    Exchanger\u4E24\u4E2A\u7EBF\u7A0B\u4EA4\u6362\u6570\u636E
    CountDownLatch\u7EBF\u7A0B\u7B49\u5F85\u76F4\u5230\u8BA1\u6570\u5668\u51CF\u4E3A0\u65F6\u5F00\u59CB\u5DE5\u4F5C
    CyclicBarrier\u4F5C\u7528\u8DDFCountDownLatch\u7C7B\u4F3C\uFF0C\u4F46\u662F\u53EF\u4EE5\u91CD\u590D\u4F7F\u7528
    Phaser\u589E\u5F3A\u7684CyclicBarrier

    \u4E0B\u9762\u5206\u522B\u4ECB\u7ECD\u8FD9\u51E0\u4E2A\u7C7B\u3002

    Semaphore

    Semaphore\u4ECB\u7ECD

    Semaphore\u7FFB\u8BD1\u8FC7\u6765\u662F\u4FE1\u53F7\u7684\u610F\u601D\u3002\u987E\u540D\u601D\u4E49\uFF0C\u8FD9\u4E2A\u5DE5\u5177\u7C7B\u63D0\u4F9B\u7684\u529F\u80FD\u5C31\u662F\u591A\u4E2A\u7EBF\u7A0B\u5F7C\u6B64\u201C\u6253\u4FE1\u53F7\u201D\u3002\u800C\u8FD9\u4E2A\u201C\u4FE1\u53F7\u201D\u662F\u4E00\u4E2Aint\u7C7B\u578B\u7684\u6570\u636E\uFF0C\u4E5F\u53EF\u4EE5\u770B\u6210\u662F\u4E00\u79CD\u201C\u8D44\u6E90\u201D\u3002

    \u53EF\u4EE5\u5728\u6784\u9020\u51FD\u6570\u4E2D\u4F20\u5165\u521D\u59CB\u8D44\u6E90\u603B\u6570\uFF0C\u4EE5\u53CA\u662F\u5426\u4F7F\u7528\u201C\u516C\u5E73\u201D\u7684\u540C\u6B65\u5668\u3002\u9ED8\u8BA4\u60C5\u51B5\u4E0B\uFF0C\u662F\u975E\u516C\u5E73\u7684\u3002

    // \u9ED8\u8BA4\u60C5\u51B5\u4E0B\u4F7F\u7528\u975E\u516C\u5E73
    +import{_ as t}from"./plugin-vue_export-helper.21dcd24c.js";import{r as e,o as c,c as o,a as n,b as a,e as l,d as p}from"./app.615e41d8.js";const i={},u=l(`

    JDK\u4E2D\u63D0\u4F9B\u4E86\u4E00\u4E9B\u5DE5\u5177\u7C7B\u4EE5\u4F9B\u5F00\u53D1\u8005\u4F7F\u7528\u3002\u8FD9\u6837\u7684\u8BDD\u6211\u4EEC\u5728\u9047\u5230\u4E00\u4E9B\u5E38\u89C1\u7684\u5E94\u7528\u573A\u666F\u65F6\u5C31\u53EF\u4EE5\u4F7F\u7528\u8FD9\u4E9B\u5DE5\u5177\u7C7B\uFF0C\u800C\u4E0D\u7528\u81EA\u5DF1\u518D\u91CD\u590D\u9020\u8F6E\u5B50\u4E86\u3002

    \u5B83\u4EEC\u90FD\u5728java.util.concurrent\u5305\u4E0B\u3002\u5148\u603B\u4F53\u6982\u62EC\u4E00\u4E0B\u90FD\u6709\u54EA\u4E9B\u5DE5\u5177\u7C7B\uFF0C\u5B83\u4EEC\u6709\u4EC0\u4E48\u4F5C\u7528\uFF0C\u7136\u540E\u518D\u5206\u522B\u4ECB\u7ECD\u5B83\u4EEC\u7684\u4E3B\u8981\u4F7F\u7528\u65B9\u6CD5\u548C\u539F\u7406\u3002

    \u7C7B\u4F5C\u7528
    Semaphore\u9650\u5236\u7EBF\u7A0B\u7684\u6570\u91CF
    Exchanger\u4E24\u4E2A\u7EBF\u7A0B\u4EA4\u6362\u6570\u636E
    CountDownLatch\u7EBF\u7A0B\u7B49\u5F85\u76F4\u5230\u8BA1\u6570\u5668\u51CF\u4E3A0\u65F6\u5F00\u59CB\u5DE5\u4F5C
    CyclicBarrier\u4F5C\u7528\u8DDFCountDownLatch\u7C7B\u4F3C\uFF0C\u4F46\u662F\u53EF\u4EE5\u91CD\u590D\u4F7F\u7528
    Phaser\u589E\u5F3A\u7684CyclicBarrier

    \u4E0B\u9762\u5206\u522B\u4ECB\u7ECD\u8FD9\u51E0\u4E2A\u7C7B\u3002

    Semaphore

    Semaphore\u4ECB\u7ECD

    Semaphore\u7FFB\u8BD1\u8FC7\u6765\u662F\u4FE1\u53F7\u7684\u610F\u601D\u3002\u987E\u540D\u601D\u4E49\uFF0C\u8FD9\u4E2A\u5DE5\u5177\u7C7B\u63D0\u4F9B\u7684\u529F\u80FD\u5C31\u662F\u591A\u4E2A\u7EBF\u7A0B\u5F7C\u6B64\u201C\u6253\u4FE1\u53F7\u201D\u3002\u800C\u8FD9\u4E2A\u201C\u4FE1\u53F7\u201D\u662F\u4E00\u4E2Aint\u7C7B\u578B\u7684\u6570\u636E\uFF0C\u4E5F\u53EF\u4EE5\u770B\u6210\u662F\u4E00\u79CD\u201C\u8D44\u6E90\u201D\u3002

    \u53EF\u4EE5\u5728\u6784\u9020\u51FD\u6570\u4E2D\u4F20\u5165\u521D\u59CB\u8D44\u6E90\u603B\u6570\uFF0C\u4EE5\u53CA\u662F\u5426\u4F7F\u7528\u201C\u516C\u5E73\u201D\u7684\u540C\u6B65\u5668\u3002\u9ED8\u8BA4\u60C5\u51B5\u4E0B\uFF0C\u662F\u975E\u516C\u5E73\u7684\u3002

    // \u9ED8\u8BA4\u60C5\u51B5\u4E0B\u4F7F\u7528\u975E\u516C\u5E73
     public Semaphore(int permits) {
         sync = new NonfairSync(permits);
     }
    diff --git a/dist/assets/DBeaver.html.8a022161.js b/dist/assets/DBeaver.html.16c02541.js
    similarity index 99%
    rename from dist/assets/DBeaver.html.8a022161.js
    rename to dist/assets/DBeaver.html.16c02541.js
    index 50735240..310f493b 100644
    --- a/dist/assets/DBeaver.html.8a022161.js
    +++ b/dist/assets/DBeaver.html.16c02541.js
    @@ -1 +1 @@
    -import{_ as o}from"./plugin-vue_export-helper.21dcd24c.js";import{r as n,o as p,c,a as e,b as r,d as t,e as g}from"./app.a0271b9c.js";const s={},b=e("p",null,"\u4F5C\u4E3A\u4E00\u540D\u5F00\u53D1\u8005\uFF0C\u514D\u4E0D\u4E86\u8981\u548C\u6570\u636E\u5E93\u6253\u4EA4\u9053\uFF0C\u4E8E\u662F\u6211\u4EEC\u5C31\u9700\u8981\u4E00\u6B3E\u987A\u624B\u7684\u6570\u636E\u5E93\u7BA1\u7406\u5DE5\u5177\u3002\u5F88\u957F\u4E00\u6BB5\u65F6\u95F4\u91CC\uFF0CNavicat \u90FD\u662F\u6211\u7684\u9996\u9009\uFF0C\u4F46\u6700\u8FD1\u66F4\u6362\u4E86\u4E00\u53F0\u65B0\u7535\u8111\uFF0C\u4E4B\u524D\u7684\u7EFF\u8272\u5B89\u88C5\u5305\u627E\u4E0D\u5230\u4E86\u3002",-1),i=e("p",null,"\u4E8E\u662F\u5C31\u7422\u78E8\u7740\uFF0C\u627E\u4E00\u6B3E\u514D\u8D39\u7684\uFF0C\u529F\u80FD\u548C Navicat \u6709\u4E00\u62FC\u7684\u6570\u636E\u5E93\u7BA1\u7406\u5DE5\u5177\u6765\u66FF\u4EE3\u3002\u597D\u670B\u53CB macrozheng \u7ED9\u6211\u63A8\u8350\u4E86 DBeaver\uFF0C\u8BD5\u7528\u5B8C\u540E\u4F53\u9A8C\u771F\u5FC3\u4E0D\u9519\uFF0C\u4E8E\u662F\u5C31\u6765\u7ED9\u5927\u5BB6\u5B89\u5229\u4E00\u6CE2\u3002",-1),v=e("h3",{id:"\u4E00\u3001\u5173\u4E8E-dbeaver",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#\u4E00\u3001\u5173\u4E8E-dbeaver","aria-hidden":"true"},"#"),t(" \u4E00\u3001\u5173\u4E8E DBeaver")],-1),d=e("p",null,"DBeaver \u662F\u4E00\u4E2A\u8DE8\u5E73\u53F0\u7684\u6570\u636E\u5E93\u7BA1\u7406\u5DE5\u5177\uFF0C\u652F\u6301 Windows\u3001Linux \u548C macOS\u3002\u5B83\u6709\u4E24\u4E2A\u7248\u672C\uFF0C\u4F01\u4E1A\u7248\u548C\u793E\u533A\u7248\uFF0C\u5BF9\u4E8E\u4E2A\u4EBA\u5F00\u53D1\u8005\u6765\u8BF4\uFF0C\u793E\u533A\u7248\u7684\u529F\u80FD\u5DF2\u7ECF\u8DB3\u591F\u5F3A\u5927\u3002",-1),h=t("DBeaver \u662F\u7531 Java \u7F16\u5199\u7684\uFF0C\u9ED8\u8BA4\u4F7F\u7528 JDK 11 \u8FDB\u884C\u7F16\u8BD1\u3002\u793E\u533A\u7248\u57FA\u4E8E "),m={href:"https://github.com/dbeaver/dbeaver/blob/devel/LICENSE.md",target:"_blank",rel:"noopener noreferrer"},l=t("Apache-2.0 License"),j=t(" \u5728 GitHub \u4E0A\u5F00\u6E90\uFF0C\u76EE\u524D\u5DF2\u83B7\u5F97 24k+ \u7684\u661F\u6807\u3002"),u={href:"https://github.com/dbeaver/dbeaver",target:"_blank",rel:"noopener noreferrer"},_=t("https://github.com/dbeaver/dbeaver"),D=e("p",null,[e("img",{src:"http://cdn.tobebetterjavaer.com/tobebetterjavaer/images/gongju/DBeaver-1.png",alt:""})],-1),B=e("p",null,"DBeaver \u652F\u6301\u51E0\u4E4E\u6240\u6709\u4E3B\u6D41\u7684\u6570\u636E\u5E93\uFF0C\u5305\u62EC\u5173\u7CFB\u578B\u6570\u636E\u5E93\u548C\u975E\u5173\u7CFB\u6570\u636E\u5E93\u3002",-1),f=e("p",null,[e("img",{src:"http://cdn.tobebetterjavaer.com/tobebetterjavaer/images/gongju/DBeaver-2.png",alt:""})],-1),x=e("h3",{id:"\u4E8C\u3001\u5B89\u88C5-dbeaver",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#\u4E8C\u3001\u5B89\u88C5-dbeaver","aria-hidden":"true"},"#"),t(" \u4E8C\u3001\u5B89\u88C5 DBeaver")],-1),k=e("p",null,"\u53EF\u4EE5\u901A\u8FC7 DBeaver \u5B98\u65B9\u4E0B\u8F7D\u5B89\u88C5\u5305\uFF0C\u4E5F\u53EF\u4EE5\u901A\u8FC7 GitHub \u4E0B\u8F7D release \u7248\u672C\u3002",-1),L=t("\u5B98\u65B9\u4E0B\u8F7D\u5730\u5740\uFF1A"),N={href:"https://dbeaver.io/download/",target:"_blank",rel:"noopener noreferrer"},S=t("https://dbeaver.io/download/"),M=e("p",null,[e("img",{src:"http://cdn.tobebetterjavaer.com/tobebetterjavaer/images/gongju/DBeaver-3.png",alt:""})],-1),E=e("p",null,"\u6839\u636E\u81EA\u5DF1\u7535\u8111\u7684\u64CD\u4F5C\u7CFB\u7EDF\u4E0B\u8F7D\u5BF9\u5E94\u7684\u5B89\u88C5\u5305\uFF0C\u5B8C\u6574\u5B89\u88C5\u540E\uFF0C\u7B2C\u4E00\u6B65\u8981\u505A\u7684\u662F\u914D\u7F6E Maven \u955C\u50CF\uFF0C\u5426\u5219\u5728\u540E\u7EED\u4E0B\u8F7D\u6570\u636E\u5E93\u9A71\u52A8\u7684\u65F6\u5019\u4F1A\u975E\u5E38\u7684\u6162\u3002",-1),Q=e("p",null,[e("img",{src:"http://cdn.tobebetterjavaer.com/tobebetterjavaer/images/gongju/DBeaver-4.png",alt:""})],-1),q=t("\u56E0\u4E3A DBeaver \u662F\u57FA\u4E8E "),I={href:"https://github.com/itwanger/toBeBetterJavaer/blob/master/docs/maven/maven.md",target:"_blank",rel:"noopener noreferrer"},w=t("Maven \u6784\u5EFA"),J=t("\u7684\uFF0C\u6570\u636E\u5E93\u9A71\u52A8\u4E5F\u5C31\u662F\u94FE\u63A5\u6570\u636E\u5E93\u7684 JDBC \u9A71\u52A8\u662F\u901A\u8FC7 Maven \u4ED3\u5E93\u4E0B\u8F7D\u7684\u3002\u9009\u62E9\u300C\u9996\u9009\u9879\u300D\u2192\u300CMaven\u300D\uFF0C\u6DFB\u52A0\u963F\u91CC\u4E91\u955C\u50CF\u5730\u5740\uFF1A"),V={href:"http://maven.aliyun.com/nexus/content/groups/public",target:"_blank",rel:"noopener noreferrer"},y=t("http://maven.aliyun.com/nexus/content/groups/public"),C=g('

    \u548C\u914D\u7F6E Maven \u955C\u50CF\u4E00\u6837\uFF0C\u5982\u4E0B\u56FE\u6240\u793A\u3002

    \u914D\u7F6E\u5B8C\u6210\u540E\uFF0C\u8BB0\u5F97\u628A\u963F\u91CC\u4E91\u955C\u50CF\u4ED3\u5E93\u7F6E\u9876\u3002

    \u4E09\u3001\u7BA1\u7406\u6570\u636E\u6E90

    \u50CF\u4F7F\u7528 Navicat \u4E00\u6837\uFF0C\u6211\u4EEC\u9700\u8981\u5148\u5EFA\u7ACB\u8FDE\u63A5\uFF0C\u8FD9\u91CC\u5C31\u4EE5 MySQL \u4E3A\u4F8B\u3002\u70B9\u51FB\u300C\u8FDE\u63A5\u300D\u5C0F\u56FE\u6807\uFF0C\u9009\u62E9\u6570\u636E\u5E93\u3002

    \u70B9\u51FB\u4E0B\u4E00\u6B65\uFF0C\u8FD9\u65F6\u5019\u9700\u8981\u586B\u5199\u6570\u636E\u5E93\u8FDE\u63A5\u4FE1\u606F\u3002

    \u70B9\u51FB\u300C\u6D4B\u8BD5\u94FE\u63A5\u300D\uFF0C\u5982\u679C\u4F7F\u7528\u9ED8\u8BA4\u7684 Maven \u4ED3\u5E93\u65F6\uFF0C\u4E0B\u8F7D\u9A71\u52A8\u4F1A\u975E\u5E38\u6162\uFF0C\u5982\u4E0B\u56FE\u6240\u793A\uFF0C\u8FD8\u5BB9\u6613\u5931\u8D25\u300C\u8E29\u8FC7\u7684\u5751\u5C31\u4E0D\u8981\u518D\u8E29\u4E86\u300D\u3002

    \u5982\u679C\u4F60\u524D\u9762\u6309\u7167\u6211\u8BF4\u7684\u914D\u7F6E\u4E86\u963F\u91CC\u4E91\u7684 Maven \u955C\u50CF\uFF0C\u7A0B\u5E8F\u5C31\u4E0D\u4E00\u6837\u4E86\uFF0C\u70B9\u4E86\u300C\u6D4B\u8BD5\u94FE\u63A5\u300D\uFF0C\u77AC\u95F4\u4F1A\u5F39\u51FA\u300C\u8FDE\u63A5\u5DF2\u6210\u529F\u300D\u7684\u63D0\u793A\u6846\u3002

    \u94FE\u63A5\u6210\u529F\u540E\uFF0C\u5C31\u53EF\u4EE5\u770B\u5230\u6570\u636E\u5E93\u4E2D\u7684\u8868\u554A\u3001\u89C6\u56FE\u554A\u3001\u7D22\u5F15\u554A\u7B49\u7B49\u3002

    \u56DB\u3001\u7BA1\u7406\u8868

    \u6570\u636E\u5E93\u8FDE\u63A5\u6210\u529F\u540E\uFF0C\u6700\u91CD\u8981\u7684\u8FD8\u662F\u64CD\u4F5C\u8868\u3002

    01\u3001\u67E5\u770B\u8868

    \u9009\u62E9\u4E00\u5F20\u8868\uFF0C\u53CC\u51FB\u540E\u5C31\u53EF\u4EE5\u770B\u5230\u8868\u7684\u5C5E\u6027\u4E86\uFF0C\u53EF\u4EE5\u67E5\u770B\u8868\u7684\u5217\u3001\u7EA6\u675F\uFF08\u4E3B\u952E\uFF09\u3001\u5916\u952E\u3001\u7D22\u5F15\u7B49\u7B49\u4FE1\u606F\u3002

    \u70B9\u51FB\u300CDDL\uFF08Data Definition Language\uFF0C\u6570\u636E\u5B9A\u4E49\u8BED\u8A00\uFF09\u300D\u53EF\u4EE5\u770B\u5230\u8BE6\u7EC6\u7684\u5EFA\u8868\u8BED\u53E5\u3002

    \u70B9\u51FB\u300C\u6570\u636E\u300D\u53EF\u4EE5\u67E5\u770B\u8868\u7684\u6570\u636E\uFF0C\u5E95\u90E8\u6709\u300C\u65B0\u589E\u300D\u3001\u300C\u4FEE\u6539\u300D\u3001\u300C\u5220\u9664\u300D\u7B49\u884C\u64CD\u4F5C\u6309\u94AE\u3002

    \u53EF\u4EE5\u5728\u9876\u90E8\u7684\u8FC7\u6EE4\u6846\u4E2D\u586B\u5199\u7B5B\u9009\u6761\u4EF6\uFF0C\u7136\u540E\u76F4\u63A5\u67E5\u8BE2\u7ED3\u679C\u3002

    \u5982\u679C\u4E0D\u60F3\u663E\u793A\u67D0\u4E00\u5217\u7684\u8BDD\uFF0C\u53EF\u4EE5\u76F4\u63A5\u70B9\u51FB\u300C\u81EA\u5B9A\u4E49\u7ED3\u679C\u96C6\u300D\u56FE\u8868\uFF0C\u5C06\u67D0\u4E2A\u5B57\u6BB5\u7684\u72B6\u6001\u8BBE\u7F6E\u4E3A\u4E0D\u53EF\u89C1\u5373\u53EF\u3002

    02\u3001\u65B0\u589E\u8868

    \u5728\u5DE6\u4FA7\u9009\u62E9\u300C\u8868\u300D\uFF0C\u7136\u540E\u53F3\u952E\u9009\u62E9\u300C\u65B0\u5EFA\u8868\u300D\u5373\u53EF\u5EFA\u8868id\u3002

    \u4E4B\u540E\u5728\u53F3\u4FA7\u5217\u7684\u533A\u57DF\u53F3\u952E\uFF0C\u9009\u62E9\u300C\u65B0\u5EFA\u5217\u300D\u5373\u53EF\u6DFB\u52A0\u5B57\u6BB5\u3002

    \u6BD4\u5982\u8BF4\u6211\u4EEC\u65B0\u5EFA\u4E00\u4E2A\u4E3B\u952E ID\uFF0C\u5982\u4E0B\u56FE\u6240\u793A\u3002

    \u5728 DBeaver \u4E2D\uFF0C[v] \u8868\u793A\u771F\uFF0C[] \u8868\u793A\u5426\u3002\u7D27\u63A5\u7740\u5728\u300C\u7EA6\u675F\u300D\u91CC\u9009\u62E9 ID \u5C06\u5176\u8BBE\u7F6E\u4E3A\u4E3B\u952E\u3002

    \u6700\u540E\u70B9\u51FB\u4FDD\u5B58\uFF0C\u4F1A\u5F39\u51FA\u4E00\u4E2A\u5EFA\u8868\u8BED\u53E5\u7684\u9884\u89C8\u6846\uFF0C\u70B9\u51FB\u300C\u6267\u884C\u300D\u5373\u53EF\u5B8C\u6210\u8868\u7684\u521B\u5EFA\u3002

    \u4E94\u3001\u6267\u884C SQL

    \u53F3\u952E\u6570\u636E\u5E93\u8868\uFF0C\u9009\u62E9\u53F3\u952E\u83DC\u5355\u4E2D\u7684\u300CSQL \u7F16\u8F91\u5668\u300D\u53EF\u4EE5\u6253\u5F00 SQL \u7F16\u8F91\u9762\u677F\u3002

    \u7136\u540E\u7F16\u8F91 SQL \u8BED\u53E5\uFF0C\u70B9\u51FB\u8FD0\u884C\u7684\u5C0F\u56FE\u6807\u5C31\u53EF\u4EE5\u67E5\u8BE2\u6570\u636E\u4E86\u3002\u8FD9\u4E2A\u8FC7\u7A0B\u4F1A\u6709\u8BED\u6CD5\u63D0\u793A\uFF0C\u975E\u5E38 nice\u3002

    DBeaver \u6709\u4E00\u4E2A\u5F88\u4EAE\u773C\u7684\u64CD\u4F5C\u5C31\u662F\uFF0C\u53EF\u4EE5\u76F4\u63A5\u9009\u4E2D\u4E00\u6761\u7ED3\u679C\u96C6\uFF0C\u7136\u540E\u53F3\u952E\u751F\u6210 SQL\u3002

    \u6BD4\u5982\u8BF4 insert \u8BED\u53E5\uFF0C\u8FD9\u6837\u518D\u63D2\u5165\u4E00\u6761\u91CD\u590D\u6027\u5185\u5BB9\u7684\u65F6\u5019\u5C31\u975E\u5E38\u65B9\u4FBF\u4E86\u3002

    \u516D\u3001\u5916\u89C2\u914D\u7F6E

    \u53EF\u4EE5\u5728\u9996\u9009\u9879\u91CC\u5BF9\u5916\u89C2\u8FDB\u884C\u8BBE\u7F6E\uFF0C\u6BD4\u5982\u8BF4\u628A\u4E3B\u9898\u4FEE\u6539\u4E3A\u6697\u9ED1\u8272\u3002

    \u7136\u540E\u754C\u9762\u5C31\u53D8\u6210\u4E86\u6697\u9ED1\u7CFB\u3002

    \u8FD8\u53EF\u4EE5\u8BBE\u7F6E\u5B57\u4F53\u5927\u5C0F\u7B49\u3002

    \u4ECE\u6574\u4F53\u7684\u98CE\u683C\u6765\u770B\uFF0CDBeaver \u548C Eclipse \u6709\u4E9B\u7C7B\u4F3C\uFF0C\u4E8B\u5B9E\u4E0A\u4E5F\u7684\u786E\u5982\u6B64\uFF0CDBeaver \u662F\u57FA\u4E8E Eclipse \u5E73\u53F0\u6784\u5EFA\u7684\u3002

    \u4E03\u3001\u603B\u7ED3

    \u603B\u4F53\u6765\u8BF4\uFF0CDBeaver\u662F\u4E00\u6B3E\u975E\u5E38\u4F18\u79C0\u7684\u5F00\u6E90\u6570\u636E\u5E93\u7BA1\u7406\u5DE5\u5177\u4E86\uFF0C\u529F\u80FD\u5F88\u5168\u9762\uFF0C\u65E5\u5E38\u7684\u5F00\u53D1\u57FA\u672C\u4E0A\u662F\u591F\u7528\u4E86\u3002\u5BF9\u6BD4\u6536\u8D39\u7684 Navicat \u548C DataGrip\uFF0C\u53EF\u4EE5\u8BF4\u975E\u5E38\u826F\u5FC3\u4E86\u3002\u5927\u5BB6\u5982\u679C\u9047\u5230\u6536\u8D39\u7248\u4E0D\u80FD\u4F7F\u7528\u7684\u65F6\u5019\uFF0C\u53EF\u4EE5\u6765\u4F53\u9A8C\u4E00\u4E0B\u793E\u533A\u7248 DBeaver\u3002

    ',60);function G(z,H){const a=n("ExternalLinkIcon");return p(),c("div",null,[b,i,v,d,e("p",null,[h,e("a",m,[l,r(a)]),j]),e("blockquote",null,[e("p",null,[e("a",u,[_,r(a)])])]),D,B,f,x,k,e("blockquote",null,[e("p",null,[L,e("a",N,[S,r(a)])])]),M,E,Q,e("p",null,[q,e("a",I,[w,r(a)]),J]),e("blockquote",null,[e("p",null,[e("a",V,[y,r(a)])])]),C])}var O=o(s,[["render",G],["__file","DBeaver.html.vue"]]);export{O as default}; +import{_ as o}from"./plugin-vue_export-helper.21dcd24c.js";import{r as n,o as p,c,a as e,b as r,d as t,e as g}from"./app.615e41d8.js";const s={},b=e("p",null,"\u4F5C\u4E3A\u4E00\u540D\u5F00\u53D1\u8005\uFF0C\u514D\u4E0D\u4E86\u8981\u548C\u6570\u636E\u5E93\u6253\u4EA4\u9053\uFF0C\u4E8E\u662F\u6211\u4EEC\u5C31\u9700\u8981\u4E00\u6B3E\u987A\u624B\u7684\u6570\u636E\u5E93\u7BA1\u7406\u5DE5\u5177\u3002\u5F88\u957F\u4E00\u6BB5\u65F6\u95F4\u91CC\uFF0CNavicat \u90FD\u662F\u6211\u7684\u9996\u9009\uFF0C\u4F46\u6700\u8FD1\u66F4\u6362\u4E86\u4E00\u53F0\u65B0\u7535\u8111\uFF0C\u4E4B\u524D\u7684\u7EFF\u8272\u5B89\u88C5\u5305\u627E\u4E0D\u5230\u4E86\u3002",-1),i=e("p",null,"\u4E8E\u662F\u5C31\u7422\u78E8\u7740\uFF0C\u627E\u4E00\u6B3E\u514D\u8D39\u7684\uFF0C\u529F\u80FD\u548C Navicat \u6709\u4E00\u62FC\u7684\u6570\u636E\u5E93\u7BA1\u7406\u5DE5\u5177\u6765\u66FF\u4EE3\u3002\u597D\u670B\u53CB macrozheng \u7ED9\u6211\u63A8\u8350\u4E86 DBeaver\uFF0C\u8BD5\u7528\u5B8C\u540E\u4F53\u9A8C\u771F\u5FC3\u4E0D\u9519\uFF0C\u4E8E\u662F\u5C31\u6765\u7ED9\u5927\u5BB6\u5B89\u5229\u4E00\u6CE2\u3002",-1),v=e("h3",{id:"\u4E00\u3001\u5173\u4E8E-dbeaver",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#\u4E00\u3001\u5173\u4E8E-dbeaver","aria-hidden":"true"},"#"),t(" \u4E00\u3001\u5173\u4E8E DBeaver")],-1),d=e("p",null,"DBeaver \u662F\u4E00\u4E2A\u8DE8\u5E73\u53F0\u7684\u6570\u636E\u5E93\u7BA1\u7406\u5DE5\u5177\uFF0C\u652F\u6301 Windows\u3001Linux \u548C macOS\u3002\u5B83\u6709\u4E24\u4E2A\u7248\u672C\uFF0C\u4F01\u4E1A\u7248\u548C\u793E\u533A\u7248\uFF0C\u5BF9\u4E8E\u4E2A\u4EBA\u5F00\u53D1\u8005\u6765\u8BF4\uFF0C\u793E\u533A\u7248\u7684\u529F\u80FD\u5DF2\u7ECF\u8DB3\u591F\u5F3A\u5927\u3002",-1),h=t("DBeaver \u662F\u7531 Java \u7F16\u5199\u7684\uFF0C\u9ED8\u8BA4\u4F7F\u7528 JDK 11 \u8FDB\u884C\u7F16\u8BD1\u3002\u793E\u533A\u7248\u57FA\u4E8E "),m={href:"https://github.com/dbeaver/dbeaver/blob/devel/LICENSE.md",target:"_blank",rel:"noopener noreferrer"},l=t("Apache-2.0 License"),j=t(" \u5728 GitHub \u4E0A\u5F00\u6E90\uFF0C\u76EE\u524D\u5DF2\u83B7\u5F97 24k+ \u7684\u661F\u6807\u3002"),u={href:"https://github.com/dbeaver/dbeaver",target:"_blank",rel:"noopener noreferrer"},_=t("https://github.com/dbeaver/dbeaver"),D=e("p",null,[e("img",{src:"http://cdn.tobebetterjavaer.com/tobebetterjavaer/images/gongju/DBeaver-1.png",alt:""})],-1),B=e("p",null,"DBeaver \u652F\u6301\u51E0\u4E4E\u6240\u6709\u4E3B\u6D41\u7684\u6570\u636E\u5E93\uFF0C\u5305\u62EC\u5173\u7CFB\u578B\u6570\u636E\u5E93\u548C\u975E\u5173\u7CFB\u6570\u636E\u5E93\u3002",-1),f=e("p",null,[e("img",{src:"http://cdn.tobebetterjavaer.com/tobebetterjavaer/images/gongju/DBeaver-2.png",alt:""})],-1),x=e("h3",{id:"\u4E8C\u3001\u5B89\u88C5-dbeaver",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#\u4E8C\u3001\u5B89\u88C5-dbeaver","aria-hidden":"true"},"#"),t(" \u4E8C\u3001\u5B89\u88C5 DBeaver")],-1),k=e("p",null,"\u53EF\u4EE5\u901A\u8FC7 DBeaver \u5B98\u65B9\u4E0B\u8F7D\u5B89\u88C5\u5305\uFF0C\u4E5F\u53EF\u4EE5\u901A\u8FC7 GitHub \u4E0B\u8F7D release \u7248\u672C\u3002",-1),L=t("\u5B98\u65B9\u4E0B\u8F7D\u5730\u5740\uFF1A"),N={href:"https://dbeaver.io/download/",target:"_blank",rel:"noopener noreferrer"},S=t("https://dbeaver.io/download/"),M=e("p",null,[e("img",{src:"http://cdn.tobebetterjavaer.com/tobebetterjavaer/images/gongju/DBeaver-3.png",alt:""})],-1),E=e("p",null,"\u6839\u636E\u81EA\u5DF1\u7535\u8111\u7684\u64CD\u4F5C\u7CFB\u7EDF\u4E0B\u8F7D\u5BF9\u5E94\u7684\u5B89\u88C5\u5305\uFF0C\u5B8C\u6574\u5B89\u88C5\u540E\uFF0C\u7B2C\u4E00\u6B65\u8981\u505A\u7684\u662F\u914D\u7F6E Maven \u955C\u50CF\uFF0C\u5426\u5219\u5728\u540E\u7EED\u4E0B\u8F7D\u6570\u636E\u5E93\u9A71\u52A8\u7684\u65F6\u5019\u4F1A\u975E\u5E38\u7684\u6162\u3002",-1),Q=e("p",null,[e("img",{src:"http://cdn.tobebetterjavaer.com/tobebetterjavaer/images/gongju/DBeaver-4.png",alt:""})],-1),q=t("\u56E0\u4E3A DBeaver \u662F\u57FA\u4E8E "),I={href:"https://github.com/itwanger/toBeBetterJavaer/blob/master/docs/maven/maven.md",target:"_blank",rel:"noopener noreferrer"},w=t("Maven \u6784\u5EFA"),J=t("\u7684\uFF0C\u6570\u636E\u5E93\u9A71\u52A8\u4E5F\u5C31\u662F\u94FE\u63A5\u6570\u636E\u5E93\u7684 JDBC \u9A71\u52A8\u662F\u901A\u8FC7 Maven \u4ED3\u5E93\u4E0B\u8F7D\u7684\u3002\u9009\u62E9\u300C\u9996\u9009\u9879\u300D\u2192\u300CMaven\u300D\uFF0C\u6DFB\u52A0\u963F\u91CC\u4E91\u955C\u50CF\u5730\u5740\uFF1A"),V={href:"http://maven.aliyun.com/nexus/content/groups/public",target:"_blank",rel:"noopener noreferrer"},y=t("http://maven.aliyun.com/nexus/content/groups/public"),C=g('

    \u548C\u914D\u7F6E Maven \u955C\u50CF\u4E00\u6837\uFF0C\u5982\u4E0B\u56FE\u6240\u793A\u3002

    \u914D\u7F6E\u5B8C\u6210\u540E\uFF0C\u8BB0\u5F97\u628A\u963F\u91CC\u4E91\u955C\u50CF\u4ED3\u5E93\u7F6E\u9876\u3002

    \u4E09\u3001\u7BA1\u7406\u6570\u636E\u6E90

    \u50CF\u4F7F\u7528 Navicat \u4E00\u6837\uFF0C\u6211\u4EEC\u9700\u8981\u5148\u5EFA\u7ACB\u8FDE\u63A5\uFF0C\u8FD9\u91CC\u5C31\u4EE5 MySQL \u4E3A\u4F8B\u3002\u70B9\u51FB\u300C\u8FDE\u63A5\u300D\u5C0F\u56FE\u6807\uFF0C\u9009\u62E9\u6570\u636E\u5E93\u3002

    \u70B9\u51FB\u4E0B\u4E00\u6B65\uFF0C\u8FD9\u65F6\u5019\u9700\u8981\u586B\u5199\u6570\u636E\u5E93\u8FDE\u63A5\u4FE1\u606F\u3002

    \u70B9\u51FB\u300C\u6D4B\u8BD5\u94FE\u63A5\u300D\uFF0C\u5982\u679C\u4F7F\u7528\u9ED8\u8BA4\u7684 Maven \u4ED3\u5E93\u65F6\uFF0C\u4E0B\u8F7D\u9A71\u52A8\u4F1A\u975E\u5E38\u6162\uFF0C\u5982\u4E0B\u56FE\u6240\u793A\uFF0C\u8FD8\u5BB9\u6613\u5931\u8D25\u300C\u8E29\u8FC7\u7684\u5751\u5C31\u4E0D\u8981\u518D\u8E29\u4E86\u300D\u3002

    \u5982\u679C\u4F60\u524D\u9762\u6309\u7167\u6211\u8BF4\u7684\u914D\u7F6E\u4E86\u963F\u91CC\u4E91\u7684 Maven \u955C\u50CF\uFF0C\u7A0B\u5E8F\u5C31\u4E0D\u4E00\u6837\u4E86\uFF0C\u70B9\u4E86\u300C\u6D4B\u8BD5\u94FE\u63A5\u300D\uFF0C\u77AC\u95F4\u4F1A\u5F39\u51FA\u300C\u8FDE\u63A5\u5DF2\u6210\u529F\u300D\u7684\u63D0\u793A\u6846\u3002

    \u94FE\u63A5\u6210\u529F\u540E\uFF0C\u5C31\u53EF\u4EE5\u770B\u5230\u6570\u636E\u5E93\u4E2D\u7684\u8868\u554A\u3001\u89C6\u56FE\u554A\u3001\u7D22\u5F15\u554A\u7B49\u7B49\u3002

    \u56DB\u3001\u7BA1\u7406\u8868

    \u6570\u636E\u5E93\u8FDE\u63A5\u6210\u529F\u540E\uFF0C\u6700\u91CD\u8981\u7684\u8FD8\u662F\u64CD\u4F5C\u8868\u3002

    01\u3001\u67E5\u770B\u8868

    \u9009\u62E9\u4E00\u5F20\u8868\uFF0C\u53CC\u51FB\u540E\u5C31\u53EF\u4EE5\u770B\u5230\u8868\u7684\u5C5E\u6027\u4E86\uFF0C\u53EF\u4EE5\u67E5\u770B\u8868\u7684\u5217\u3001\u7EA6\u675F\uFF08\u4E3B\u952E\uFF09\u3001\u5916\u952E\u3001\u7D22\u5F15\u7B49\u7B49\u4FE1\u606F\u3002

    \u70B9\u51FB\u300CDDL\uFF08Data Definition Language\uFF0C\u6570\u636E\u5B9A\u4E49\u8BED\u8A00\uFF09\u300D\u53EF\u4EE5\u770B\u5230\u8BE6\u7EC6\u7684\u5EFA\u8868\u8BED\u53E5\u3002

    \u70B9\u51FB\u300C\u6570\u636E\u300D\u53EF\u4EE5\u67E5\u770B\u8868\u7684\u6570\u636E\uFF0C\u5E95\u90E8\u6709\u300C\u65B0\u589E\u300D\u3001\u300C\u4FEE\u6539\u300D\u3001\u300C\u5220\u9664\u300D\u7B49\u884C\u64CD\u4F5C\u6309\u94AE\u3002

    \u53EF\u4EE5\u5728\u9876\u90E8\u7684\u8FC7\u6EE4\u6846\u4E2D\u586B\u5199\u7B5B\u9009\u6761\u4EF6\uFF0C\u7136\u540E\u76F4\u63A5\u67E5\u8BE2\u7ED3\u679C\u3002

    \u5982\u679C\u4E0D\u60F3\u663E\u793A\u67D0\u4E00\u5217\u7684\u8BDD\uFF0C\u53EF\u4EE5\u76F4\u63A5\u70B9\u51FB\u300C\u81EA\u5B9A\u4E49\u7ED3\u679C\u96C6\u300D\u56FE\u8868\uFF0C\u5C06\u67D0\u4E2A\u5B57\u6BB5\u7684\u72B6\u6001\u8BBE\u7F6E\u4E3A\u4E0D\u53EF\u89C1\u5373\u53EF\u3002

    02\u3001\u65B0\u589E\u8868

    \u5728\u5DE6\u4FA7\u9009\u62E9\u300C\u8868\u300D\uFF0C\u7136\u540E\u53F3\u952E\u9009\u62E9\u300C\u65B0\u5EFA\u8868\u300D\u5373\u53EF\u5EFA\u8868id\u3002

    \u4E4B\u540E\u5728\u53F3\u4FA7\u5217\u7684\u533A\u57DF\u53F3\u952E\uFF0C\u9009\u62E9\u300C\u65B0\u5EFA\u5217\u300D\u5373\u53EF\u6DFB\u52A0\u5B57\u6BB5\u3002

    \u6BD4\u5982\u8BF4\u6211\u4EEC\u65B0\u5EFA\u4E00\u4E2A\u4E3B\u952E ID\uFF0C\u5982\u4E0B\u56FE\u6240\u793A\u3002

    \u5728 DBeaver \u4E2D\uFF0C[v] \u8868\u793A\u771F\uFF0C[] \u8868\u793A\u5426\u3002\u7D27\u63A5\u7740\u5728\u300C\u7EA6\u675F\u300D\u91CC\u9009\u62E9 ID \u5C06\u5176\u8BBE\u7F6E\u4E3A\u4E3B\u952E\u3002

    \u6700\u540E\u70B9\u51FB\u4FDD\u5B58\uFF0C\u4F1A\u5F39\u51FA\u4E00\u4E2A\u5EFA\u8868\u8BED\u53E5\u7684\u9884\u89C8\u6846\uFF0C\u70B9\u51FB\u300C\u6267\u884C\u300D\u5373\u53EF\u5B8C\u6210\u8868\u7684\u521B\u5EFA\u3002

    \u4E94\u3001\u6267\u884C SQL

    \u53F3\u952E\u6570\u636E\u5E93\u8868\uFF0C\u9009\u62E9\u53F3\u952E\u83DC\u5355\u4E2D\u7684\u300CSQL \u7F16\u8F91\u5668\u300D\u53EF\u4EE5\u6253\u5F00 SQL \u7F16\u8F91\u9762\u677F\u3002

    \u7136\u540E\u7F16\u8F91 SQL \u8BED\u53E5\uFF0C\u70B9\u51FB\u8FD0\u884C\u7684\u5C0F\u56FE\u6807\u5C31\u53EF\u4EE5\u67E5\u8BE2\u6570\u636E\u4E86\u3002\u8FD9\u4E2A\u8FC7\u7A0B\u4F1A\u6709\u8BED\u6CD5\u63D0\u793A\uFF0C\u975E\u5E38 nice\u3002

    DBeaver \u6709\u4E00\u4E2A\u5F88\u4EAE\u773C\u7684\u64CD\u4F5C\u5C31\u662F\uFF0C\u53EF\u4EE5\u76F4\u63A5\u9009\u4E2D\u4E00\u6761\u7ED3\u679C\u96C6\uFF0C\u7136\u540E\u53F3\u952E\u751F\u6210 SQL\u3002

    \u6BD4\u5982\u8BF4 insert \u8BED\u53E5\uFF0C\u8FD9\u6837\u518D\u63D2\u5165\u4E00\u6761\u91CD\u590D\u6027\u5185\u5BB9\u7684\u65F6\u5019\u5C31\u975E\u5E38\u65B9\u4FBF\u4E86\u3002

    \u516D\u3001\u5916\u89C2\u914D\u7F6E

    \u53EF\u4EE5\u5728\u9996\u9009\u9879\u91CC\u5BF9\u5916\u89C2\u8FDB\u884C\u8BBE\u7F6E\uFF0C\u6BD4\u5982\u8BF4\u628A\u4E3B\u9898\u4FEE\u6539\u4E3A\u6697\u9ED1\u8272\u3002

    \u7136\u540E\u754C\u9762\u5C31\u53D8\u6210\u4E86\u6697\u9ED1\u7CFB\u3002

    \u8FD8\u53EF\u4EE5\u8BBE\u7F6E\u5B57\u4F53\u5927\u5C0F\u7B49\u3002

    \u4ECE\u6574\u4F53\u7684\u98CE\u683C\u6765\u770B\uFF0CDBeaver \u548C Eclipse \u6709\u4E9B\u7C7B\u4F3C\uFF0C\u4E8B\u5B9E\u4E0A\u4E5F\u7684\u786E\u5982\u6B64\uFF0CDBeaver \u662F\u57FA\u4E8E Eclipse \u5E73\u53F0\u6784\u5EFA\u7684\u3002

    \u4E03\u3001\u603B\u7ED3

    \u603B\u4F53\u6765\u8BF4\uFF0CDBeaver\u662F\u4E00\u6B3E\u975E\u5E38\u4F18\u79C0\u7684\u5F00\u6E90\u6570\u636E\u5E93\u7BA1\u7406\u5DE5\u5177\u4E86\uFF0C\u529F\u80FD\u5F88\u5168\u9762\uFF0C\u65E5\u5E38\u7684\u5F00\u53D1\u57FA\u672C\u4E0A\u662F\u591F\u7528\u4E86\u3002\u5BF9\u6BD4\u6536\u8D39\u7684 Navicat \u548C DataGrip\uFF0C\u53EF\u4EE5\u8BF4\u975E\u5E38\u826F\u5FC3\u4E86\u3002\u5927\u5BB6\u5982\u679C\u9047\u5230\u6536\u8D39\u7248\u4E0D\u80FD\u4F7F\u7528\u7684\u65F6\u5019\uFF0C\u53EF\u4EE5\u6765\u4F53\u9A8C\u4E00\u4E0B\u793E\u533A\u7248 DBeaver\u3002

    ',60);function G(z,H){const a=n("ExternalLinkIcon");return p(),c("div",null,[b,i,v,d,e("p",null,[h,e("a",m,[l,r(a)]),j]),e("blockquote",null,[e("p",null,[e("a",u,[_,r(a)])])]),D,B,f,x,k,e("blockquote",null,[e("p",null,[L,e("a",N,[S,r(a)])])]),M,E,Q,e("p",null,[q,e("a",I,[w,r(a)]),J]),e("blockquote",null,[e("p",null,[e("a",V,[y,r(a)])])]),C])}var O=o(s,[["render",G],["__file","DBeaver.html.vue"]]);export{O as default}; diff --git a/dist/assets/Filter-Interceptor-Listener.html.3a5897a3.js b/dist/assets/Filter-Interceptor-Listener.html.3a5897a3.js new file mode 100644 index 00000000..93fa4af0 --- /dev/null +++ b/dist/assets/Filter-Interceptor-Listener.html.3a5897a3.js @@ -0,0 +1 @@ +const e={key:"v-fdb1bc82",path:"/springboot/Filter-Interceptor-Listener.html",title:"\u8FC7\u6EE4\u5668\u3001\u62E6\u622A\u5668\u3001\u76D1\u542C\u5668",lang:"zh-CN",frontmatter:{category:["Java\u4F01\u4E1A\u7EA7\u5F00\u53D1"],tag:["Spring Boot"],title:"\u8FC7\u6EE4\u5668\u3001\u62E6\u622A\u5668\u3001\u76D1\u542C\u5668",summary:"\u524D\u8A00 \u5148\u8BF4\u4F5C\u7528\u3002 \u8FC7\u6EE4\u5668\uFF08Filter\uFF09\uFF1A\u5F53\u6709\u4E00\u5806\u8BF7\u6C42\uFF0C\u53EA\u5E0C\u671B\u7B26\u5408\u9884\u671F\u7684\u8BF7\u6C42\u8FDB\u6765\u3002; \u62E6\u622A\u5668\uFF08Interceptor\uFF09\uFF1A\u60F3\u8981\u5E72\u6D89\u9884\u671F\u7684\u8BF7\u6C42\u3002; \u76D1\u542C\u5668\uFF08Listener\uFF09\uFF1A\u60F3\u8981\u76D1\u542C\u8FD9\u4E9B\u8BF7\u6C42\u5177\u4F53\u505A\u4E86\u4EC0\u4E48\u3002; \u518D\u8BF4\u533A\u522B\u3002 \u8FC7\u6EE4\u5668\u662F\u5728\u8BF7\u6C42\u8FDB\u5165\u5BB9\u5668\u540E\uFF0C\u4F46\u8FD8\u6CA1\u6709\u8FDB\u5165 Servlet \u4E4B\u524D\u8FDB\u884C\u9884\u5904\u7406\u7684\u3002\u5982\u4E0B\u56FE\u6240\u793A\u3002 \u62E6\u622A\u5668\u662F\u5728\u8BF7\u6C42\u8FDB\u5165\u63A7\u5236\u5668\uFF08Controller\uFF09 \u4E4B\u524D",head:[["meta",{property:"og:url",content:"https://tobebetterjavaer.com/springboot/Filter-Interceptor-Listener.html"}],["meta",{property:"og:site_name",content:"Java \u7A0B\u5E8F\u5458\u8FDB\u9636\u4E4B\u8DEF"}],["meta",{property:"og:title",content:"\u8FC7\u6EE4\u5668\u3001\u62E6\u622A\u5668\u3001\u76D1\u542C\u5668"}],["meta",{property:"og:type",content:"article"}],["meta",{property:"og:updated_time",content:"2022-06-10T11:28:25.000Z"}],["meta",{property:"og:locale",content:"zh-CN"}],["meta",{property:"article:tag",content:"Spring Boot"}],["meta",{property:"article:modified_time",content:"2022-06-10T11:28:25.000Z"}]]},excerpt:"",headers:[{level:2,title:"\u524D\u8A00",slug:"\u524D\u8A00",children:[]},{level:2,title:"\u8FC7\u6EE4\u5668",slug:"\u8FC7\u6EE4\u5668",children:[]},{level:2,title:"\u62E6\u622A\u5668",slug:"\u62E6\u622A\u5668",children:[]},{level:2,title:"\u76D1\u542C\u5668",slug:"\u76D1\u542C\u5668",children:[]},{level:2,title:"\u6E90\u7801\u8DEF\u5F84\uFF1A",slug:"\u6E90\u7801\u8DEF\u5F84",children:[]}],git:{createdTime:1653092056e3,updatedTime:1654860505e3,contributors:[{name:"itwanger",email:"www.qing_gee@163.com",commits:3}]},readingTime:{minutes:5.87,words:1761},filePathRelative:"springboot/Filter-Interceptor-Listener.md"};export{e as data}; diff --git a/dist/assets/Filter-Interceptor-Listener.html.61c686d0.js b/dist/assets/Filter-Interceptor-Listener.html.7803e9df.js similarity index 85% rename from dist/assets/Filter-Interceptor-Listener.html.61c686d0.js rename to dist/assets/Filter-Interceptor-Listener.html.7803e9df.js index a2800899..80282596 100644 --- a/dist/assets/Filter-Interceptor-Listener.html.61c686d0.js +++ b/dist/assets/Filter-Interceptor-Listener.html.7803e9df.js @@ -1,4 +1,4 @@ -import{_ as o}from"./plugin-vue_export-helper.21dcd24c.js";import{r as e,o as c,c as l,a as n,b as a,w as i,e as u,d as s}from"./app.a0271b9c.js";const r={},k=u(`

    \u524D\u8A00

    \u5148\u8BF4\u4F5C\u7528\u3002

    • \u8FC7\u6EE4\u5668\uFF08Filter\uFF09\uFF1A\u5F53\u6709\u4E00\u5806\u8BF7\u6C42\uFF0C\u53EA\u5E0C\u671B\u7B26\u5408\u9884\u671F\u7684\u8BF7\u6C42\u8FDB\u6765\u3002
    • \u62E6\u622A\u5668\uFF08Interceptor\uFF09\uFF1A\u60F3\u8981\u5E72\u6D89\u9884\u671F\u7684\u8BF7\u6C42\u3002
    • \u76D1\u542C\u5668\uFF08Listener\uFF09\uFF1A\u60F3\u8981\u76D1\u542C\u8FD9\u4E9B\u8BF7\u6C42\u5177\u4F53\u505A\u4E86\u4EC0\u4E48\u3002

    \u518D\u8BF4\u533A\u522B\u3002

    \u8FC7\u6EE4\u5668\u662F\u5728\u8BF7\u6C42\u8FDB\u5165\u5BB9\u5668\u540E\uFF0C\u4F46\u8FD8\u6CA1\u6709\u8FDB\u5165 Servlet \u4E4B\u524D\u8FDB\u884C\u9884\u5904\u7406\u7684\u3002\u5982\u4E0B\u56FE\u6240\u793A\u3002

    \u62E6\u622A\u5668\u662F\u5728\u8BF7\u6C42\u8FDB\u5165\u63A7\u5236\u5668\uFF08Controller\uFF09 \u4E4B\u524D\u8FDB\u884C\u9884\u5904\u7406\u7684\u3002

    \u865A\u7EBF\u5185\u5C31\u662F\u8FC7\u6EE4\u5668\u548C\u62E6\u622A\u5668\u7684\u4F5C\u7528\u8303\u56F4\uFF1A

    \u8FC7\u6EE4\u5668\u4F9D\u8D56\u4E8E Servlet \u5BB9\u5668\uFF0C\u800C\u62E6\u622A\u5668\u4F9D\u8D56\u4E8E Spring \u7684 IoC \u5BB9\u5668\uFF0C\u56E0\u6B64\u53EF\u4EE5\u901A\u8FC7\u6CE8\u5165\u7684\u65B9\u5F0F\u83B7\u53D6\u5BB9\u5668\u5F53\u4E2D\u7684\u5BF9\u8C61\u3002

    \u76D1\u542C\u5668\u7528\u4E8E\u76D1\u542C Web \u5E94\u7528\u4E2D\u67D0\u4E9B\u5BF9\u8C61\u7684\u521B\u5EFA\u3001\u9500\u6BC1\u3001\u589E\u52A0\u3001\u4FEE\u6539\u3001\u5220\u9664\u7B49\u52A8\u4F5C\uFF0C\u7136\u540E\u505A\u51FA\u76F8\u5E94\u7684\u5904\u7406\u3002

    \u8FC7\u6EE4\u5668

    • \u8FC7\u6EE4\u654F\u611F\u8BCD\u6C47\uFF08\u9632\u6B62sql\u6CE8\u5165\uFF09
    • \u8BBE\u7F6E\u5B57\u7B26\u7F16\u7801
    • URL\u7EA7\u522B\u7684\u6743\u9650\u8BBF\u95EE\u63A7\u5236
    • \u538B\u7F29\u54CD\u5E94\u4FE1\u606F

    \u8FC7\u6EE4\u5668\u7684\u521B\u5EFA\u548C\u9500\u6BC1\u90FD\u7531 Web \u670D\u52A1\u5668\u8D1F\u8D23\uFF0CWeb \u5E94\u7528\u7A0B\u5E8F\u542F\u52A8\u7684\u65F6\u5019\uFF0C\u521B\u5EFA\u8FC7\u6EE4\u5668\u5BF9\u8C61\uFF0C\u4E3A\u540E\u7EED\u7684\u8BF7\u6C42\u8FC7\u6EE4\u505A\u597D\u51C6\u5907\u3002

    \u8FC7\u6EE4\u5668\u53EF\u4EE5\u6709\u5F88\u591A\u4E2A\uFF0C\u4E00\u4E2A\u4E2A\u8FC7\u6EE4\u5668\u7EC4\u5408\u8D77\u6765\u5C31\u6210\u4E86 FilterChain\uFF0C\u4E5F\u5C31\u662F\u8FC7\u6EE4\u5668\u94FE\u3002

    \u5728 Spring \u4E2D\uFF0C\u8FC7\u6EE4\u5668\u90FD\u9ED8\u8BA4\u7EE7\u627F\u4E86 OncePerRequestFilter\uFF0C\u987E\u540D\u601D\u4E49\uFF0COncePerRequestFilter \u7684\u4F5C\u7528\u5C31\u662F\u786E\u4FDD\u4E00\u6B21\u8BF7\u6C42\u53EA\u901A\u8FC7\u4E00\u6B21\u8FC7\u6EE4\u5668\uFF0C\u800C\u4E0D\u91CD\u590D\u6267\u884C\u3002

    \u5728\u7F16\u7A0B\u55B5\u5B9E\u6218\u9879\u76EE\u4E2D\uFF0C\u6211\u4EEC\u5C31\u662F\u901A\u8FC7\u7EE7\u627F OncePerRequestFilter \u6765\u5B9E\u73B0 JWT \u767B\u5F55\u6388\u6743\u8FC7\u6EE4\u7684\u3002

    public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {
    +import{_ as e}from"./plugin-vue_export-helper.21dcd24c.js";import{r as p,o,c,a as n,b as t,e as l,d as s}from"./app.615e41d8.js";const i={},u=l(`

    \u524D\u8A00

    \u5148\u8BF4\u4F5C\u7528\u3002

    • \u8FC7\u6EE4\u5668\uFF08Filter\uFF09\uFF1A\u5F53\u6709\u4E00\u5806\u8BF7\u6C42\uFF0C\u53EA\u5E0C\u671B\u7B26\u5408\u9884\u671F\u7684\u8BF7\u6C42\u8FDB\u6765\u3002
    • \u62E6\u622A\u5668\uFF08Interceptor\uFF09\uFF1A\u60F3\u8981\u5E72\u6D89\u9884\u671F\u7684\u8BF7\u6C42\u3002
    • \u76D1\u542C\u5668\uFF08Listener\uFF09\uFF1A\u60F3\u8981\u76D1\u542C\u8FD9\u4E9B\u8BF7\u6C42\u5177\u4F53\u505A\u4E86\u4EC0\u4E48\u3002

    \u518D\u8BF4\u533A\u522B\u3002

    \u8FC7\u6EE4\u5668\u662F\u5728\u8BF7\u6C42\u8FDB\u5165\u5BB9\u5668\u540E\uFF0C\u4F46\u8FD8\u6CA1\u6709\u8FDB\u5165 Servlet \u4E4B\u524D\u8FDB\u884C\u9884\u5904\u7406\u7684\u3002\u5982\u4E0B\u56FE\u6240\u793A\u3002

    \u62E6\u622A\u5668\u662F\u5728\u8BF7\u6C42\u8FDB\u5165\u63A7\u5236\u5668\uFF08Controller\uFF09 \u4E4B\u524D\u8FDB\u884C\u9884\u5904\u7406\u7684\u3002

    \u865A\u7EBF\u5185\u5C31\u662F\u8FC7\u6EE4\u5668\u548C\u62E6\u622A\u5668\u7684\u4F5C\u7528\u8303\u56F4\uFF1A

    \u8FC7\u6EE4\u5668\u4F9D\u8D56\u4E8E Servlet \u5BB9\u5668\uFF0C\u800C\u62E6\u622A\u5668\u4F9D\u8D56\u4E8E Spring \u7684 IoC \u5BB9\u5668\uFF0C\u56E0\u6B64\u53EF\u4EE5\u901A\u8FC7\u6CE8\u5165\u7684\u65B9\u5F0F\u83B7\u53D6\u5BB9\u5668\u5F53\u4E2D\u7684\u5BF9\u8C61\u3002

    \u76D1\u542C\u5668\u7528\u4E8E\u76D1\u542C Web \u5E94\u7528\u4E2D\u67D0\u4E9B\u5BF9\u8C61\u7684\u521B\u5EFA\u3001\u9500\u6BC1\u3001\u589E\u52A0\u3001\u4FEE\u6539\u3001\u5220\u9664\u7B49\u52A8\u4F5C\uFF0C\u7136\u540E\u505A\u51FA\u76F8\u5E94\u7684\u5904\u7406\u3002

    \u8FC7\u6EE4\u5668

    • \u8FC7\u6EE4\u654F\u611F\u8BCD\u6C47\uFF08\u9632\u6B62sql\u6CE8\u5165\uFF09
    • \u8BBE\u7F6E\u5B57\u7B26\u7F16\u7801
    • URL\u7EA7\u522B\u7684\u6743\u9650\u8BBF\u95EE\u63A7\u5236
    • \u538B\u7F29\u54CD\u5E94\u4FE1\u606F

    \u8FC7\u6EE4\u5668\u7684\u521B\u5EFA\u548C\u9500\u6BC1\u90FD\u7531 Web \u670D\u52A1\u5668\u8D1F\u8D23\uFF0CWeb \u5E94\u7528\u7A0B\u5E8F\u542F\u52A8\u7684\u65F6\u5019\uFF0C\u521B\u5EFA\u8FC7\u6EE4\u5668\u5BF9\u8C61\uFF0C\u4E3A\u540E\u7EED\u7684\u8BF7\u6C42\u8FC7\u6EE4\u505A\u597D\u51C6\u5907\u3002

    \u8FC7\u6EE4\u5668\u53EF\u4EE5\u6709\u5F88\u591A\u4E2A\uFF0C\u4E00\u4E2A\u4E2A\u8FC7\u6EE4\u5668\u7EC4\u5408\u8D77\u6765\u5C31\u6210\u4E86 FilterChain\uFF0C\u4E5F\u5C31\u662F\u8FC7\u6EE4\u5668\u94FE\u3002

    \u5728 Spring \u4E2D\uFF0C\u8FC7\u6EE4\u5668\u90FD\u9ED8\u8BA4\u7EE7\u627F\u4E86 OncePerRequestFilter\uFF0C\u987E\u540D\u601D\u4E49\uFF0COncePerRequestFilter \u7684\u4F5C\u7528\u5C31\u662F\u786E\u4FDD\u4E00\u6B21\u8BF7\u6C42\u53EA\u901A\u8FC7\u4E00\u6B21\u8FC7\u6EE4\u5668\uFF0C\u800C\u4E0D\u91CD\u590D\u6267\u884C\u3002

    \u5728\u7F16\u7A0B\u55B5\u5B9E\u6218\u9879\u76EE\u4E2D\uFF0C\u6211\u4EEC\u5C31\u662F\u901A\u8FC7\u7EE7\u627F OncePerRequestFilter \u6765\u5B9E\u73B0 JWT \u767B\u5F55\u6388\u6743\u8FC7\u6EE4\u7684\u3002

    public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {
     	@Override
         protected void doFilterInternal(HttpServletRequest request,
                                         HttpServletResponse response,
    @@ -51,7 +51,7 @@ import{_ as o}from"./plugin-vue_export-helper.21dcd24c.js";import{r as e,o as c,
             Filter.super.destroy();
         }
     }
    -

    @WebFilter \u6CE8\u89E3\u7528\u4E8E\u5C06\u4E00\u4E2A\u7C7B\u58F0\u660E\u4E3A\u8FC7\u6EE4\u5668\uFF0CurlPatterns \u5C5E\u6027\u7528\u6765\u6307\u5B9A\u8FC7\u6EE4\u5668\u7684 URL \u5339\u914D\u6A21\u5F0F\uFF0CfilterName \u7528\u6765\u5B9A\u4E49\u8FC7\u6EE4\u5668\u7684\u540D\u5B57\u3002

    MyFilter \u8FC7\u6EE4\u5668\u7684\u903B\u8F91\u975E\u5E38\u7B80\u5355\uFF0C\u91CD\u5199\u4E86 Filter \u7684\u4E09\u4E2A\u65B9\u6CD5\uFF0C\u5728 doFilter \u65B9\u6CD5\u4E2D\u52A0\u5165\u4E86\u65F6\u95F4\u6233\u7684\u8BB0\u5F55\u3002

    \u7136\u540E\u6211\u4EEC\u5728\u9879\u76EE\u5165\u53E3\u7C7B\u4E0A\u52A0\u4E0A @ServletComponentScan \u6CE8\u89E3\uFF0C\u8FD9\u6837\u8FC7\u6EE4\u5668\u5C31\u4F1A\u81EA\u52A8\u6CE8\u518C\u3002

    \u542F\u52A8\u670D\u52A1\u5668\uFF0C\u8BBF\u95EE\u4EFB\u610F\u7684 URL\u3002

    \u62E6\u622A\u5668

    • \u767B\u5F55\u9A8C\u8BC1\uFF0C\u5224\u65AD\u7528\u6237\u662F\u5426\u767B\u5F55
    • \u6743\u9650\u9A8C\u8BC1\uFF0C\u5224\u65AD\u7528\u6237\u662F\u5426\u6709\u6743\u9650\u8BBF\u95EE\u8D44\u6E90\uFF0C\u5982\u6821\u9A8Ctoken
    • \u65E5\u5FD7\u8BB0\u5F55\uFF0C\u8BB0\u5F55\u8BF7\u6C42\u64CD\u4F5C\u65E5\u5FD7\uFF08\u7528\u6237ip\uFF0C\u8BBF\u95EE\u65F6\u95F4\u7B49\uFF09\uFF0C\u4EE5\u4FBF\u7EDF\u8BA1\u8BF7\u6C42\u8BBF\u95EE\u91CF
    • \u5904\u7406cookie\u3001\u672C\u5730\u5316\u3001\u56FD\u9645\u5316\u3001\u4E3B\u9898\u7B49
    • \u6027\u80FD\u76D1\u63A7\uFF0C\u76D1\u63A7\u8BF7\u6C42\u5904\u7406\u65F6\u957F\u7B49

    \u6211\u4EEC\u6765\u5199\u4E00\u4E2A\u7B80\u5355\u7684\u62E6\u622A\u5668 LoggerInterceptor\uFF1A

    @Slf4j
    +

    @WebFilter \u6CE8\u89E3\u7528\u4E8E\u5C06\u4E00\u4E2A\u7C7B\u58F0\u660E\u4E3A\u8FC7\u6EE4\u5668\uFF0CurlPatterns \u5C5E\u6027\u7528\u6765\u6307\u5B9A\u8FC7\u6EE4\u5668\u7684 URL \u5339\u914D\u6A21\u5F0F\uFF0CfilterName \u7528\u6765\u5B9A\u4E49\u8FC7\u6EE4\u5668\u7684\u540D\u5B57\u3002

    MyFilter \u8FC7\u6EE4\u5668\u7684\u903B\u8F91\u975E\u5E38\u7B80\u5355\uFF0C\u91CD\u5199\u4E86 Filter \u7684\u4E09\u4E2A\u65B9\u6CD5\uFF0C\u5728 doFilter \u65B9\u6CD5\u4E2D\u52A0\u5165\u4E86\u65F6\u95F4\u6233\u7684\u8BB0\u5F55\u3002

    \u7136\u540E\u6211\u4EEC\u5728\u9879\u76EE\u5165\u53E3\u7C7B\u4E0A\u52A0\u4E0A @ServletComponentScan \u6CE8\u89E3\uFF0C\u8FD9\u6837\u8FC7\u6EE4\u5668\u5C31\u4F1A\u81EA\u52A8\u6CE8\u518C\u3002

    \u542F\u52A8\u670D\u52A1\u5668\uFF0C\u8BBF\u95EE\u4EFB\u610F\u7684 URL\u3002

    \u62E6\u622A\u5668

    • \u767B\u5F55\u9A8C\u8BC1\uFF0C\u5224\u65AD\u7528\u6237\u662F\u5426\u767B\u5F55
    • \u6743\u9650\u9A8C\u8BC1\uFF0C\u5224\u65AD\u7528\u6237\u662F\u5426\u6709\u6743\u9650\u8BBF\u95EE\u8D44\u6E90\uFF0C\u5982\u6821\u9A8Ctoken
    • \u65E5\u5FD7\u8BB0\u5F55\uFF0C\u8BB0\u5F55\u8BF7\u6C42\u64CD\u4F5C\u65E5\u5FD7\uFF08\u7528\u6237ip\uFF0C\u8BBF\u95EE\u65F6\u95F4\u7B49\uFF09\uFF0C\u4EE5\u4FBF\u7EDF\u8BA1\u8BF7\u6C42\u8BBF\u95EE\u91CF
    • \u5904\u7406cookie\u3001\u672C\u5730\u5316\u3001\u56FD\u9645\u5316\u3001\u4E3B\u9898\u7B49
    • \u6027\u80FD\u76D1\u63A7\uFF0C\u76D1\u63A7\u8BF7\u6C42\u5904\u7406\u65F6\u957F\u7B49

    \u6211\u4EEC\u6765\u5199\u4E00\u4E2A\u7B80\u5355\u7684\u62E6\u622A\u5668 LoggerInterceptor\uFF1A

    @Slf4j
     public class LoggerInterceptor implements HandlerInterceptor {
         @Override
         public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
    @@ -122,4 +122,4 @@ import{_ as o}from"./plugin-vue_export-helper.21dcd24c.js";import{r as e,o as c,
         private Object getParameter(Method method, Object[] args) {
         }
     }
    -

    \u901A\u8FC7\u62E6\u622A\u540E\u7684\u8BF7\u6C42\u4FE1\u606F\u5927\u6982\u662F\u8FD9\u6837\u7684\uFF1A

    \u76D1\u542C\u5668

    \u6839\u636E\u76D1\u542C\u5BF9\u8C61\u53EF\u4EE5\u628A\u76D1\u542C\u5668\u5206\u4E3A 3 \u7C7B\uFF1A


    `,53),d=s("\u66F4\u591A\u5185\u5BB9\uFF0C\u53EA\u9488\u5BF9\u300AJava \u7A0B\u5E8F\u5458\u8FDB\u9636\u4E4B\u8DEF\u300B\u661F\u7403\u7528\u6237\u5F00\u653E\uFF0C\u9700\u8981\u7684\u5C0F\u4F19\u4F34\u53EF\u4EE5"),v=s("\u6233\u94FE\u63A5\u{1F517}"),m=s("\u52A0\u5165\u6211\u4EEC\u7684\u661F\u7403\uFF0C\u4E00\u8D77\u5B66\u4E60\uFF0C\u4E00\u8D77\u5377\u3002\u3002"),b=n("strong",null,"\u7F16\u7A0B\u55B5",-1),g=s("\u{1F431}\u662F\u4E00\u4E2A Spring Boot+Vue \u7684\u524D\u540E\u7AEF\u5206\u79BB\u9879\u76EE\uFF0C\u878D\u5408\u4E86\u5E02\u9762\u4E0A\u7EDD\u5927\u591A\u6570\u6D41\u884C\u7684\u6280\u672F\u8981\u70B9\u3002\u901A\u8FC7\u5B66\u4E60\u5B9E\u6218\u9879\u76EE\uFF0C\u4F60\u53EF\u4EE5\u5C06\u6240\u5B66\u7684\u77E5\u8BC6\u901A\u8FC7\u5B9E\u8DF5\u8FDB\u884C\u68C0\u9A8C\u3001\u4F60\u53EF\u4EE5\u62D3\u5BBD\u81EA\u5DF1\u7684\u6280\u672F\u8FB9\u754C\uFF0C\u4F60\u53EF\u4EE5\u638C\u63E1\u4E00\u4E2A\u771F\u6B63\u7684\u5B9E\u6218\u9879\u76EE\u662F\u5982\u4F55\u4ECE 0 \u5230 1 \u7684\u3002"),h=n("hr",null,null,-1),w=n("h3",{id:"\u6E90\u7801\u8DEF\u5F84",tabindex:"-1"},[n("a",{class:"header-anchor",href:"#\u6E90\u7801\u8DEF\u5F84","aria-hidden":"true"},"#"),s(" \u6E90\u7801\u8DEF\u5F84\uFF1A")],-1),f=s("\u7F16\u7A0B\u55B5\uFF1A"),y={href:"https://github.com/itwanger/coding-more",target:"_blank",rel:"noopener noreferrer"},q=s("https://github.com/itwanger/coding-more"),_=s("\u8FC7\u6EE4\u5668\uFF0C\u62E6\u622A\u5668\u3001\u76D1\u542C\u5668\u4E13\u7528\uFF1A"),j={href:"https://github.com/itwanger/codingmore-learning/tree/main/codingmore-filter-interceptor-listener",target:"_blank",rel:"noopener noreferrer"},S=s("https://github.com/itwanger/coding-more"),x=n("p",null,[n("img",{src:"http://cdn.tobebetterjavaer.com/tobebetterjavaer/images/xingbiaogongzhonghao.png",alt:""})],-1);function L(R,C){const p=e("RouterLink"),t=e("ExternalLinkIcon");return c(),l("div",null,[k,n("p",null,[d,a(p,{to:"/springboot/docs/zhishixingqiu/"},{default:i(()=>[v]),_:1}),m,b,g]),h,w,n("blockquote",null,[n("ul",null,[n("li",null,[f,n("a",y,[q,a(t)])]),n("li",null,[_,n("a",j,[S,a(t)])])])]),x])}var I=o(r,[["render",L],["__file","Filter-Interceptor-Listener.html.vue"]]);export{I as default}; +

    \u901A\u8FC7\u62E6\u622A\u540E\u7684\u8BF7\u6C42\u4FE1\u606F\u5927\u6982\u662F\u8FD9\u6837\u7684\uFF1A

    \u76D1\u542C\u5668

    \u6839\u636E\u76D1\u542C\u5BF9\u8C61\u53EF\u4EE5\u628A\u76D1\u542C\u5668\u5206\u4E3A 3 \u7C7B\uFF1A


    `,53),r=s("\u66F4\u591A\u5185\u5BB9\uFF0C\u53EA\u9488\u5BF9\u300AJava \u7A0B\u5E8F\u5458\u8FDB\u9636\u4E4B\u8DEF\u300B\u661F\u7403\u7528\u6237\u5F00\u653E\uFF0C\u9700\u8981\u7684\u5C0F\u4F19\u4F34\u53EF\u4EE5"),k={href:"https://tobebetterjavaer.com/zhishixingqiu/",target:"_blank",rel:"noopener noreferrer"},d=s("\u6233\u94FE\u63A5\u{1F517}"),v=s("\u52A0\u5165\u6211\u4EEC\u7684\u661F\u7403\uFF0C\u4E00\u8D77\u5B66\u4E60\uFF0C\u4E00\u8D77\u5377\u3002\u3002"),m=n("strong",null,"\u7F16\u7A0B\u55B5",-1),b=s("\u{1F431}\u662F\u4E00\u4E2A Spring Boot+Vue \u7684\u524D\u540E\u7AEF\u5206\u79BB\u9879\u76EE\uFF0C\u878D\u5408\u4E86\u5E02\u9762\u4E0A\u7EDD\u5927\u591A\u6570\u6D41\u884C\u7684\u6280\u672F\u8981\u70B9\u3002\u901A\u8FC7\u5B66\u4E60\u5B9E\u6218\u9879\u76EE\uFF0C\u4F60\u53EF\u4EE5\u5C06\u6240\u5B66\u7684\u77E5\u8BC6\u901A\u8FC7\u5B9E\u8DF5\u8FDB\u884C\u68C0\u9A8C\u3001\u4F60\u53EF\u4EE5\u62D3\u5BBD\u81EA\u5DF1\u7684\u6280\u672F\u8FB9\u754C\uFF0C\u4F60\u53EF\u4EE5\u638C\u63E1\u4E00\u4E2A\u771F\u6B63\u7684\u5B9E\u6218\u9879\u76EE\u662F\u5982\u4F55\u4ECE 0 \u5230 1 \u7684\u3002"),g=n("hr",null,null,-1),h=n("h2",{id:"\u6E90\u7801\u8DEF\u5F84",tabindex:"-1"},[n("a",{class:"header-anchor",href:"#\u6E90\u7801\u8DEF\u5F84","aria-hidden":"true"},"#"),s(" \u6E90\u7801\u8DEF\u5F84\uFF1A")],-1),f=s("\u7F16\u7A0B\u55B5\uFF1A"),w={href:"https://github.com/itwanger/coding-more",target:"_blank",rel:"noopener noreferrer"},y=s("https://github.com/itwanger/coding-more"),q=s("\u8FC7\u6EE4\u5668\uFF0C\u62E6\u622A\u5668\u3001\u76D1\u542C\u5668\u4E13\u7528\uFF1A"),j={href:"https://github.com/itwanger/codingmore-learning/tree/main/codingmore-filter-interceptor-listener",target:"_blank",rel:"noopener noreferrer"},_=s("https://github.com/itwanger/coding-more"),S=n("p",null,[n("img",{src:"http://cdn.tobebetterjavaer.com/tobebetterjavaer/images/xingbiaogongzhonghao.png",alt:""})],-1);function x(L,R){const a=p("ExternalLinkIcon");return o(),c("div",null,[u,n("p",null,[r,n("a",k,[d,t(a)]),v,m,b]),g,h,n("blockquote",null,[n("ul",null,[n("li",null,[f,n("a",w,[y,t(a)])]),n("li",null,[q,n("a",j,[_,t(a)])])])]),S])}var H=e(i,[["render",x],["__file","Filter-Interceptor-Listener.html.vue"]]);export{H as default}; diff --git a/dist/assets/Filter-Interceptor-Listener.html.d4211e38.js b/dist/assets/Filter-Interceptor-Listener.html.d4211e38.js deleted file mode 100644 index c117c48d..00000000 --- a/dist/assets/Filter-Interceptor-Listener.html.d4211e38.js +++ /dev/null @@ -1 +0,0 @@ -const e={key:"v-fdb1bc82",path:"/springboot/Filter-Interceptor-Listener.html",title:"Spring Boot \u6574\u5408 Thymeleaf \u6A21\u677F\u5F15\u64CE",lang:"zh-CN",frontmatter:{category:["Java\u4F01\u4E1A\u7EA7\u5F00\u53D1"],tag:["Spring Boot"],title:"Spring Boot \u6574\u5408 Thymeleaf \u6A21\u677F\u5F15\u64CE",summary:"\u524D\u8A00 \u5148\u8BF4\u4F5C\u7528\u3002 \u8FC7\u6EE4\u5668\uFF08Filter\uFF09\uFF1A\u5F53\u6709\u4E00\u5806\u8BF7\u6C42\uFF0C\u53EA\u5E0C\u671B\u7B26\u5408\u9884\u671F\u7684\u8BF7\u6C42\u8FDB\u6765\u3002; \u62E6\u622A\u5668\uFF08Interceptor\uFF09\uFF1A\u60F3\u8981\u5E72\u6D89\u9884\u671F\u7684\u8BF7\u6C42\u3002; \u76D1\u542C\u5668\uFF08Listener\uFF09\uFF1A\u60F3\u8981\u76D1\u542C\u8FD9\u4E9B\u8BF7\u6C42\u5177\u4F53\u505A\u4E86\u4EC0\u4E48\u3002; \u518D\u8BF4\u533A\u522B\u3002 \u8FC7\u6EE4\u5668\u662F\u5728\u8BF7\u6C42\u8FDB\u5165\u5BB9\u5668\u540E\uFF0C\u4F46\u8FD8\u6CA1\u6709\u8FDB\u5165 Servlet \u4E4B\u524D\u8FDB\u884C\u9884\u5904\u7406\u7684\u3002\u5982\u4E0B\u56FE\u6240\u793A\u3002 \u62E6\u622A\u5668\u662F\u5728\u8BF7\u6C42\u8FDB\u5165\u63A7\u5236\u5668\uFF08Controller\uFF09 \u4E4B\u524D",head:[["meta",{property:"og:url",content:"https://tobebetterjavaer.com/springboot/Filter-Interceptor-Listener.html"}],["meta",{property:"og:site_name",content:"Java \u7A0B\u5E8F\u5458\u8FDB\u9636\u4E4B\u8DEF"}],["meta",{property:"og:title",content:"Spring Boot \u6574\u5408 Thymeleaf \u6A21\u677F\u5F15\u64CE"}],["meta",{property:"og:type",content:"article"}],["meta",{property:"og:updated_time",content:"2022-05-21T16:06:08.000Z"}],["meta",{property:"og:locale",content:"zh-CN"}],["meta",{property:"article:tag",content:"Spring Boot"}],["meta",{property:"article:modified_time",content:"2022-05-21T16:06:08.000Z"}]]},excerpt:"",headers:[{level:3,title:"\u524D\u8A00",slug:"\u524D\u8A00",children:[]},{level:3,title:"\u8FC7\u6EE4\u5668",slug:"\u8FC7\u6EE4\u5668",children:[]},{level:3,title:"\u62E6\u622A\u5668",slug:"\u62E6\u622A\u5668",children:[]},{level:3,title:"\u76D1\u542C\u5668",slug:"\u76D1\u542C\u5668",children:[]},{level:3,title:"\u6E90\u7801\u8DEF\u5F84\uFF1A",slug:"\u6E90\u7801\u8DEF\u5F84",children:[]}],git:{createdTime:1653092056e3,updatedTime:1653149168e3,contributors:[{name:"itwanger",email:"www.qing_gee@163.com",commits:2}]},readingTime:{minutes:5.87,words:1760},filePathRelative:"springboot/Filter-Interceptor-Listener.md"};export{e as data}; diff --git a/dist/assets/Lambda.html.16e88b8a.js b/dist/assets/Lambda.html.bd1566d3.js similarity index 99% rename from dist/assets/Lambda.html.16e88b8a.js rename to dist/assets/Lambda.html.bd1566d3.js index 54863db7..4bcd917b 100644 --- a/dist/assets/Lambda.html.16e88b8a.js +++ b/dist/assets/Lambda.html.bd1566d3.js @@ -1,4 +1,4 @@ -import{_ as p}from"./plugin-vue_export-helper.21dcd24c.js";import{r as e,o as c,c as o,a as n,b as i,e as a,d as s}from"./app.a0271b9c.js";const l={},u=a(`

    \u6DF1\u5165\u6D45\u51FA Java 8 Lambda\u8868\u8FBE\u5F0F

    \u4ECA\u5929\u5206\u4EAB\u7684\u4E3B\u9898\u662F\u300ALambda \u8868\u8FBE\u5F0F\u5165\u95E8\u300B\uFF0C\u8FD9\u4E5F\u662F\u4E4B\u524D\u4E00\u4E9B\u8BFB\u8005\u7559\u8A00\u5F3A\u70C8\u8981\u6C42\u6211\u5199\u4E00\u5199\u7684\uFF0C\u4E0D\u597D\u610F\u601D\uFF0C\u8BA9\u4F60\u4EEC\u4E45\u7B49\u4E86\uFF0C\u73B0\u5728\u6765\u6EE1\u8DB3\u4F60\u4EEC\uFF0C\u4E3A\u65F6\u4E0D\u665A\u5427\uFF1F

    01\u3001\u521D\u8BC6 Lambda

    Lambda \u8868\u8FBE\u5F0F\u63CF\u8FF0\u4E86\u4E00\u4E2A\u4EE3\u7801\u5757\uFF08\u6216\u8005\u53EB\u533F\u540D\u65B9\u6CD5\uFF09\uFF0C\u53EF\u4EE5\u5C06\u5176\u4F5C\u4E3A\u53C2\u6570\u4F20\u9012\u7ED9\u6784\u9020\u65B9\u6CD5\u6216\u8005\u666E\u901A\u65B9\u6CD5\u4EE5\u4FBF\u540E\u7EED\u6267\u884C\u3002\u8003\u8651\u4E0B\u9762\u8FD9\u6BB5\u4EE3\u7801\uFF1A

    () -> System.out.println("\u6C89\u9ED8\u738B\u4E8C")
    +import{_ as p}from"./plugin-vue_export-helper.21dcd24c.js";import{r as e,o as c,c as o,a as n,b as i,e as a,d as s}from"./app.615e41d8.js";const l={},u=a(`

    \u6DF1\u5165\u6D45\u51FA Java 8 Lambda\u8868\u8FBE\u5F0F

    \u4ECA\u5929\u5206\u4EAB\u7684\u4E3B\u9898\u662F\u300ALambda \u8868\u8FBE\u5F0F\u5165\u95E8\u300B\uFF0C\u8FD9\u4E5F\u662F\u4E4B\u524D\u4E00\u4E9B\u8BFB\u8005\u7559\u8A00\u5F3A\u70C8\u8981\u6C42\u6211\u5199\u4E00\u5199\u7684\uFF0C\u4E0D\u597D\u610F\u601D\uFF0C\u8BA9\u4F60\u4EEC\u4E45\u7B49\u4E86\uFF0C\u73B0\u5728\u6765\u6EE1\u8DB3\u4F60\u4EEC\uFF0C\u4E3A\u65F6\u4E0D\u665A\u5427\uFF1F

    01\u3001\u521D\u8BC6 Lambda

    Lambda \u8868\u8FBE\u5F0F\u63CF\u8FF0\u4E86\u4E00\u4E2A\u4EE3\u7801\u5757\uFF08\u6216\u8005\u53EB\u533F\u540D\u65B9\u6CD5\uFF09\uFF0C\u53EF\u4EE5\u5C06\u5176\u4F5C\u4E3A\u53C2\u6570\u4F20\u9012\u7ED9\u6784\u9020\u65B9\u6CD5\u6216\u8005\u666E\u901A\u65B9\u6CD5\u4EE5\u4FBF\u540E\u7EED\u6267\u884C\u3002\u8003\u8651\u4E0B\u9762\u8FD9\u6BB5\u4EE3\u7801\uFF1A

    () -> System.out.println("\u6C89\u9ED8\u738B\u4E8C")
     

    \u6765\u4ECE\u5DE6\u5230\u53F3\u89E3\u91CA\u4E00\u4E0B\uFF0C() \u4E3A Lambda \u8868\u8FBE\u5F0F\u7684\u53C2\u6570\u5217\u8868\uFF08\u672C\u4F8B\u4E2D\u6CA1\u6709\u53C2\u6570\uFF09\uFF0C-> \u6807\u8BC6\u8FD9\u4E32\u4EE3\u7801\u4E3A Lambda \u8868\u8FBE\u5F0F\uFF08\u4E5F\u5C31\u662F\u8BF4\uFF0C\u770B\u5230 -> \u5C31\u77E5\u9053\u8FD9\u662F Lambda\uFF09\uFF0CSystem.out.println("\u6C89\u9ED8\u738B\u4E8C") \u4E3A\u8981\u6267\u884C\u7684\u4EE3\u7801\uFF0C\u5373\u5C06\u201C\u6C89\u9ED8\u738B\u4E8C\u201D\u6253\u5370\u5230\u6807\u51C6\u8F93\u51FA\u6D41\u3002

    \u6709\u70B9 Java \u57FA\u7840\u7684\u540C\u5B66\u5E94\u8BE5\u4E0D\u4F1A\u5BF9 Runnable \u63A5\u53E3\u611F\u5230\u964C\u751F\uFF0C\u8FD9\u662F\u591A\u7EBF\u7A0B\u7684\u4E00\u4E2A\u57FA\u7840\u63A5\u53E3\uFF0C\u5B83\u7684\u5B9A\u4E49\u5982\u4E0B\uFF1A

    @FunctionalInterface
     public interface Runnable
     {
    diff --git a/dist/assets/Layout.fbcb8daf.js b/dist/assets/Layout.2f241dd5.js
    similarity index 80%
    rename from dist/assets/Layout.fbcb8daf.js
    rename to dist/assets/Layout.2f241dd5.js
    index 71f29210..4f4617fd 100644
    --- a/dist/assets/Layout.fbcb8daf.js
    +++ b/dist/assets/Layout.2f241dd5.js
    @@ -1 +1 @@
    -import{f as m,h as e,T as i,m as u,g as p,n as d,p as c,q as f,r,s as v,t as g}from"./app.a0271b9c.js";import{S as h}from"./SkipLink.e761490e.js";var b=m({name:"FadeSlideY",setup(s,{slots:a}){const o=u(),t=o.resolve,l=o.pending;return()=>e(i,{name:"fade-slide-y",mode:"out-in",onBeforeEnter:t,onBeforeLeave:l},()=>{var n;return(n=a.default)==null?void 0:n.call(a)})}}),L=m({name:"Layout",setup(){const s=g(),a=p(),o=v(),t=d();return c(),f(()=>a.value.blog.sidebarDisplay||s.value.blog.sidebarDisplay||"mobile"),()=>[e(h),e(r("CommonWrapper"),{},{default:()=>t.value.home?e(r("HomePage")):e(b,()=>e(r("NormalPage"),{key:o.value.path}))})]}});export{L as default};
    +import{f as m,h as e,T as i,m as u,g as p,n as d,p as c,q as f,r,s as v,t as g}from"./app.615e41d8.js";import{S as h}from"./SkipLink.a2c3a90f.js";var b=m({name:"FadeSlideY",setup(s,{slots:a}){const o=u(),t=o.resolve,l=o.pending;return()=>e(i,{name:"fade-slide-y",mode:"out-in",onBeforeEnter:t,onBeforeLeave:l},()=>{var n;return(n=a.default)==null?void 0:n.call(a)})}}),L=m({name:"Layout",setup(){const s=g(),a=p(),o=v(),t=d();return c(),f(()=>a.value.blog.sidebarDisplay||s.value.blog.sidebarDisplay||"mobile"),()=>[e(h),e(r("CommonWrapper"),{},{default:()=>t.value.home?e(r("HomePage")):e(b,()=>e(r("NormalPage"),{key:o.value.path}))})]}});export{L as default};
    diff --git a/dist/assets/LockSupport.html.55f27ea8.js b/dist/assets/LockSupport.html.5ea98b89.js
    similarity index 99%
    rename from dist/assets/LockSupport.html.55f27ea8.js
    rename to dist/assets/LockSupport.html.5ea98b89.js
    index c6e3ae15..dba73c8a 100644
    --- a/dist/assets/LockSupport.html.55f27ea8.js
    +++ b/dist/assets/LockSupport.html.5ea98b89.js
    @@ -1,4 +1,4 @@
    -import{_ as p}from"./plugin-vue_export-helper.21dcd24c.js";import{r as e,o,c,a as n,b as s,e as l,d as t}from"./app.a0271b9c.js";const i={},u=l(`

    \u6DF1\u5165\u7406\u89E3Java\u5E76\u53D1\u7EBF\u7A0B\u963B\u585E\u5524\u9192\u7C7BLockSupport

    LockSupport\u4F4D\u4E8Ejava.util.concurrent.locks\u5305\u4E0B\uFF0C\u6709\u5174\u8DA3\u7684\u53EF\u4EE5\u76F4\u63A5\u53BB\u770B\u6E90\u7801\uFF0C\u8BE5\u7C7B\u7684\u65B9\u6CD5\u5E76\u4E0D\u662F\u5F88\u591A\u3002LockSupprot\u662F\u7EBF\u7A0B\u7684\u963B\u585E\u539F\u8BED\uFF0C\u7528\u6765\u963B\u585E\u7EBF\u7A0B\u548C\u5524\u9192\u7EBF\u7A0B\u3002\u6BCF\u4E2A\u4F7F\u7528LockSupport\u7684\u7EBF\u7A0B\u90FD\u4F1A\u4E0E\u4E00\u4E2A\u8BB8\u53EF\u5173\u8054\uFF0C\u5982\u679C\u8BE5\u8BB8\u53EF\u53EF\u7528\uFF0C\u5E76\u4E14\u53EF\u5728\u7EBF\u7A0B\u4E2D\u4F7F\u7528\uFF0C\u5219\u8C03\u7528park()\u5C06\u4F1A\u7ACB\u5373\u8FD4\u56DE\uFF0C\u5426\u5219\u53EF\u80FD\u963B\u585E\u3002\u5982\u679C\u8BB8\u53EF\u5C1A\u4E0D\u53EF\u7528\uFF0C\u5219\u53EF\u4EE5\u8C03\u7528 unpark \u4F7F\u5176\u53EF\u7528\u3002\u4F46\u662F\u6CE8\u610F\u8BB8\u53EF\u4E0D\u53EF\u91CD\u5165\uFF0C\u4E5F\u5C31\u662F\u8BF4\u53EA\u80FD\u8C03\u7528\u4E00\u6B21park()\u65B9\u6CD5\uFF0C\u5426\u5219\u4F1A\u4E00\u76F4\u963B\u585E\u3002

    LockSupport\u4E2D\u7684\u65B9\u6CD5\u4E0D\u591A\uFF0C\u8FD9\u91CC\u5C06\u8FD9\u4E9B\u65B9\u6CD5\u505A\u4E00\u4E2A\u603B\u7ED3\uFF1A

    \u963B\u585E\u7EBF\u7A0B

    1. void park()\uFF1A\u963B\u585E\u5F53\u524D\u7EBF\u7A0B\uFF0C\u5982\u679C\u8C03\u7528unpark\u65B9\u6CD5\u6216\u8005\u5F53\u524D\u7EBF\u7A0B\u88AB\u4E2D\u65AD\uFF0C\u4ECE\u80FD\u4ECEpark()\u65B9\u6CD5\u4E2D\u8FD4\u56DE
    2. void park(Object blocker)\uFF1A\u529F\u80FD\u540C\u65B9\u6CD51\uFF0C\u5165\u53C2\u589E\u52A0\u4E00\u4E2AObject\u5BF9\u8C61\uFF0C\u7528\u6765\u8BB0\u5F55\u5BFC\u81F4\u7EBF\u7A0B\u963B\u585E\u7684\u963B\u585E\u5BF9\u8C61\uFF0C\u65B9\u4FBF\u8FDB\u884C\u95EE\u9898\u6392\u67E5\uFF1B
    3. void parkNanos(long nanos)\uFF1A\u963B\u585E\u5F53\u524D\u7EBF\u7A0B\uFF0C\u6700\u957F\u4E0D\u8D85\u8FC7nanos\u7EB3\u79D2\uFF0C\u589E\u52A0\u4E86\u8D85\u65F6\u8FD4\u56DE\u7684\u7279\u6027\uFF1B
    4. void parkNanos(Object blocker, long nanos)\uFF1A\u529F\u80FD\u540C\u65B9\u6CD53\uFF0C\u5165\u53C2\u589E\u52A0\u4E00\u4E2AObject\u5BF9\u8C61\uFF0C\u7528\u6765\u8BB0\u5F55\u5BFC\u81F4\u7EBF\u7A0B\u963B\u585E\u7684\u963B\u585E\u5BF9\u8C61\uFF0C\u65B9\u4FBF\u8FDB\u884C\u95EE\u9898\u6392\u67E5\uFF1B
    5. void parkUntil(long deadline)\uFF1A\u963B\u585E\u5F53\u524D\u7EBF\u7A0B\uFF0C\u77E5\u9053deadline\uFF1B
    6. void parkUntil(Object blocker, long deadline)\uFF1A\u529F\u80FD\u540C\u65B9\u6CD55\uFF0C\u5165\u53C2\u589E\u52A0\u4E00\u4E2AObject\u5BF9\u8C61\uFF0C\u7528\u6765\u8BB0\u5F55\u5BFC\u81F4\u7EBF\u7A0B\u963B\u585E\u7684\u963B\u585E\u5BF9\u8C61\uFF0C\u65B9\u4FBF\u8FDB\u884C\u95EE\u9898\u6392\u67E5\uFF1B

    \u5524\u9192\u7EBF\u7A0B

    void unpark(Thread thread):\u5524\u9192\u5904\u4E8E\u963B\u585E\u72B6\u6001\u7684\u6307\u5B9A\u7EBF\u7A0B

    \u5B9E\u9645\u4E0ALockSupport\u963B\u585E\u548C\u5524\u9192\u7EBF\u7A0B\u7684\u529F\u80FD\u662F\u4F9D\u8D56\u4E8Esun.misc.Unsafe\uFF0C\u8FD9\u662F\u4E00\u4E2A\u5F88\u5E95\u5C42\u7684\u7C7B\uFF0C\u6709\u5174\u8DA3\u7684\u53EF\u4EE5\u53BB\u67E5\u9605\u8D44\u6599\uFF0C\u6BD4\u5982park()\u65B9\u6CD5\u7684\u529F\u80FD\u5B9E\u73B0\u5219\u662F\u9760unsafe.park()\u65B9\u6CD5\u3002

    \u53E6\u5916\u5728\u963B\u585E\u7EBF\u7A0B\u8FD9\u4E00\u7CFB\u5217\u65B9\u6CD5\u4E2D\u8FD8\u6709\u4E00\u4E2A\u5F88\u6709\u610F\u601D\u7684\u73B0\u8C61\u5C31\u662F\uFF0C\u6BCF\u4E2A\u65B9\u6CD5\u90FD\u4F1A\u65B0\u589E\u4E00\u4E2A\u5E26\u6709Object\u7684\u963B\u585E\u5BF9\u8C61\u7684\u91CD\u8F7D\u65B9\u6CD5\u3002\u90A3\u4E48\u589E\u52A0\u4E86\u4E00\u4E2AObject\u5BF9\u8C61\u7684\u5165\u53C2\u4F1A\u6709\u4EC0\u4E48\u4E0D\u540C\u7684\u5730\u65B9\u4E86\uFF1F\u793A\u4F8B\u4EE3\u7801\u5F88\u7B80\u5355\u5C31\u4E0D\u8BF4\u4E86\uFF0C\u76F4\u63A5\u770Bdump\u7EBF\u7A0B\u7684\u4FE1\u606F\u3002

    \u8C03\u7528park()\u65B9\u6CD5dump\u7EBF\u7A0B\uFF1A

    "main" #1 prio=5 os_prio=0 tid=0x02cdcc00 nid=0x2b48 waiting on condition [0x00d6f000]
    +import{_ as p}from"./plugin-vue_export-helper.21dcd24c.js";import{r as e,o,c,a as n,b as s,e as l,d as t}from"./app.615e41d8.js";const i={},u=l(`

    \u6DF1\u5165\u7406\u89E3Java\u5E76\u53D1\u7EBF\u7A0B\u963B\u585E\u5524\u9192\u7C7BLockSupport

    LockSupport\u4F4D\u4E8Ejava.util.concurrent.locks\u5305\u4E0B\uFF0C\u6709\u5174\u8DA3\u7684\u53EF\u4EE5\u76F4\u63A5\u53BB\u770B\u6E90\u7801\uFF0C\u8BE5\u7C7B\u7684\u65B9\u6CD5\u5E76\u4E0D\u662F\u5F88\u591A\u3002LockSupprot\u662F\u7EBF\u7A0B\u7684\u963B\u585E\u539F\u8BED\uFF0C\u7528\u6765\u963B\u585E\u7EBF\u7A0B\u548C\u5524\u9192\u7EBF\u7A0B\u3002\u6BCF\u4E2A\u4F7F\u7528LockSupport\u7684\u7EBF\u7A0B\u90FD\u4F1A\u4E0E\u4E00\u4E2A\u8BB8\u53EF\u5173\u8054\uFF0C\u5982\u679C\u8BE5\u8BB8\u53EF\u53EF\u7528\uFF0C\u5E76\u4E14\u53EF\u5728\u7EBF\u7A0B\u4E2D\u4F7F\u7528\uFF0C\u5219\u8C03\u7528park()\u5C06\u4F1A\u7ACB\u5373\u8FD4\u56DE\uFF0C\u5426\u5219\u53EF\u80FD\u963B\u585E\u3002\u5982\u679C\u8BB8\u53EF\u5C1A\u4E0D\u53EF\u7528\uFF0C\u5219\u53EF\u4EE5\u8C03\u7528 unpark \u4F7F\u5176\u53EF\u7528\u3002\u4F46\u662F\u6CE8\u610F\u8BB8\u53EF\u4E0D\u53EF\u91CD\u5165\uFF0C\u4E5F\u5C31\u662F\u8BF4\u53EA\u80FD\u8C03\u7528\u4E00\u6B21park()\u65B9\u6CD5\uFF0C\u5426\u5219\u4F1A\u4E00\u76F4\u963B\u585E\u3002

    LockSupport\u4E2D\u7684\u65B9\u6CD5\u4E0D\u591A\uFF0C\u8FD9\u91CC\u5C06\u8FD9\u4E9B\u65B9\u6CD5\u505A\u4E00\u4E2A\u603B\u7ED3\uFF1A

    \u963B\u585E\u7EBF\u7A0B

    1. void park()\uFF1A\u963B\u585E\u5F53\u524D\u7EBF\u7A0B\uFF0C\u5982\u679C\u8C03\u7528unpark\u65B9\u6CD5\u6216\u8005\u5F53\u524D\u7EBF\u7A0B\u88AB\u4E2D\u65AD\uFF0C\u4ECE\u80FD\u4ECEpark()\u65B9\u6CD5\u4E2D\u8FD4\u56DE
    2. void park(Object blocker)\uFF1A\u529F\u80FD\u540C\u65B9\u6CD51\uFF0C\u5165\u53C2\u589E\u52A0\u4E00\u4E2AObject\u5BF9\u8C61\uFF0C\u7528\u6765\u8BB0\u5F55\u5BFC\u81F4\u7EBF\u7A0B\u963B\u585E\u7684\u963B\u585E\u5BF9\u8C61\uFF0C\u65B9\u4FBF\u8FDB\u884C\u95EE\u9898\u6392\u67E5\uFF1B
    3. void parkNanos(long nanos)\uFF1A\u963B\u585E\u5F53\u524D\u7EBF\u7A0B\uFF0C\u6700\u957F\u4E0D\u8D85\u8FC7nanos\u7EB3\u79D2\uFF0C\u589E\u52A0\u4E86\u8D85\u65F6\u8FD4\u56DE\u7684\u7279\u6027\uFF1B
    4. void parkNanos(Object blocker, long nanos)\uFF1A\u529F\u80FD\u540C\u65B9\u6CD53\uFF0C\u5165\u53C2\u589E\u52A0\u4E00\u4E2AObject\u5BF9\u8C61\uFF0C\u7528\u6765\u8BB0\u5F55\u5BFC\u81F4\u7EBF\u7A0B\u963B\u585E\u7684\u963B\u585E\u5BF9\u8C61\uFF0C\u65B9\u4FBF\u8FDB\u884C\u95EE\u9898\u6392\u67E5\uFF1B
    5. void parkUntil(long deadline)\uFF1A\u963B\u585E\u5F53\u524D\u7EBF\u7A0B\uFF0C\u77E5\u9053deadline\uFF1B
    6. void parkUntil(Object blocker, long deadline)\uFF1A\u529F\u80FD\u540C\u65B9\u6CD55\uFF0C\u5165\u53C2\u589E\u52A0\u4E00\u4E2AObject\u5BF9\u8C61\uFF0C\u7528\u6765\u8BB0\u5F55\u5BFC\u81F4\u7EBF\u7A0B\u963B\u585E\u7684\u963B\u585E\u5BF9\u8C61\uFF0C\u65B9\u4FBF\u8FDB\u884C\u95EE\u9898\u6392\u67E5\uFF1B

    \u5524\u9192\u7EBF\u7A0B

    void unpark(Thread thread):\u5524\u9192\u5904\u4E8E\u963B\u585E\u72B6\u6001\u7684\u6307\u5B9A\u7EBF\u7A0B

    \u5B9E\u9645\u4E0ALockSupport\u963B\u585E\u548C\u5524\u9192\u7EBF\u7A0B\u7684\u529F\u80FD\u662F\u4F9D\u8D56\u4E8Esun.misc.Unsafe\uFF0C\u8FD9\u662F\u4E00\u4E2A\u5F88\u5E95\u5C42\u7684\u7C7B\uFF0C\u6709\u5174\u8DA3\u7684\u53EF\u4EE5\u53BB\u67E5\u9605\u8D44\u6599\uFF0C\u6BD4\u5982park()\u65B9\u6CD5\u7684\u529F\u80FD\u5B9E\u73B0\u5219\u662F\u9760unsafe.park()\u65B9\u6CD5\u3002

    \u53E6\u5916\u5728\u963B\u585E\u7EBF\u7A0B\u8FD9\u4E00\u7CFB\u5217\u65B9\u6CD5\u4E2D\u8FD8\u6709\u4E00\u4E2A\u5F88\u6709\u610F\u601D\u7684\u73B0\u8C61\u5C31\u662F\uFF0C\u6BCF\u4E2A\u65B9\u6CD5\u90FD\u4F1A\u65B0\u589E\u4E00\u4E2A\u5E26\u6709Object\u7684\u963B\u585E\u5BF9\u8C61\u7684\u91CD\u8F7D\u65B9\u6CD5\u3002\u90A3\u4E48\u589E\u52A0\u4E86\u4E00\u4E2AObject\u5BF9\u8C61\u7684\u5165\u53C2\u4F1A\u6709\u4EC0\u4E48\u4E0D\u540C\u7684\u5730\u65B9\u4E86\uFF1F\u793A\u4F8B\u4EE3\u7801\u5F88\u7B80\u5355\u5C31\u4E0D\u8BF4\u4E86\uFF0C\u76F4\u63A5\u770Bdump\u7EBF\u7A0B\u7684\u4FE1\u606F\u3002

    \u8C03\u7528park()\u65B9\u6CD5dump\u7EBF\u7A0B\uFF1A

    "main" #1 prio=5 os_prio=0 tid=0x02cdcc00 nid=0x2b48 waiting on condition [0x00d6f000]
        java.lang.Thread.State: WAITING (parking)
             at sun.misc.Unsafe.park(Native Method)
             at java.util.concurrent.locks.LockSupport.park(LockSupport.java:304)
    diff --git a/dist/assets/Overriding.html.e0ccdfe1.js b/dist/assets/Overriding.html.d8235770.js
    similarity index 99%
    rename from dist/assets/Overriding.html.e0ccdfe1.js
    rename to dist/assets/Overriding.html.d8235770.js
    index fdd8413a..d2cffe6d 100644
    --- a/dist/assets/Overriding.html.e0ccdfe1.js
    +++ b/dist/assets/Overriding.html.d8235770.js
    @@ -1,4 +1,4 @@
    -import{_ as n}from"./plugin-vue_export-helper.21dcd24c.js";import{o as s,c as a,e}from"./app.a0271b9c.js";const p={},t=e(`

    Java\u91CD\u5199\uFF08Overriding\uFF09\u65F6\u5E94\u5F53\u9075\u5B88\u768411\u6761\u89C4\u5219

    \u91CD\u5199\uFF08Overriding\uFF09\u7B97\u662F Java \u4E2D\u4E00\u4E2A\u975E\u5E38\u91CD\u8981\u7684\u6982\u5FF5\uFF0C\u7406\u89E3\u91CD\u5199\u5230\u5E95\u662F\u4EC0\u4E48\u5BF9\u6BCF\u4E2A Java \u7A0B\u5E8F\u5458\u6765\u8BF4\u90FD\u81F3\u5173\u91CD\u8981\uFF0C\u8FD9\u7BC7\u6587\u7AE0\u5C31\u6765\u7ED9\u5927\u5BB6\u8BF4\u8BF4\u91CD\u5199\u8FC7\u7A0B\u4E2D\u5E94\u5F53\u9075\u5B88\u7684 12 \u6761\u89C4\u5219\u3002

    01\u3001\u4EC0\u4E48\u662F\u91CD\u5199\uFF1F

    \u91CD\u5199\u5E26\u6765\u4E86\u4E00\u79CD\u975E\u5E38\u91CD\u8981\u7684\u80FD\u529B\uFF0C\u53EF\u4EE5\u8BA9\u5B50\u7C7B\u91CD\u65B0\u5B9E\u73B0\u4ECE\u8D85\u7C7B\u90A3\u7EE7\u627F\u8FC7\u6765\u7684\u65B9\u6CD5\u3002\u5728\u4E0B\u9762\u8FD9\u5E45\u56FE\u4E2D\uFF0CAnimal \u662F\u7236\u7C7B\uFF0CDog \u662F\u5B50\u7C7B\uFF0CDog \u91CD\u65B0\u5B9E\u73B0\u4E86 move() \u65B9\u6CD5\u7528\u6765\u548C\u7236\u7C7B\u8FDB\u884C\u533A\u5206\uFF0C\u6BD5\u7ADF\u72D7\u72D7\u8DD1\u8D77\u6765\u8FD8\u662F\u6BD4\u8F83\u6709\u7279\u8272\u7684\u3002

    \u91CD\u5199\u7684\u65B9\u6CD5\u548C\u88AB\u91CD\u5199\u7684\u65B9\u6CD5\uFF0C\u4E0D\u4EC5\u65B9\u6CD5\u540D\u76F8\u540C\uFF0C\u53C2\u6570\u4E5F\u76F8\u540C\uFF0C\u53EA\u4E0D\u8FC7\uFF0C\u65B9\u6CD5\u4F53\u6709\u6240\u4E0D\u540C\u3002

    02\u3001\u54EA\u4E9B\u65B9\u6CD5\u53EF\u4EE5\u88AB\u91CD\u5199\uFF1F

    \u89C4\u5219\u4E00\uFF1A\u53EA\u80FD\u91CD\u5199\u7EE7\u627F\u8FC7\u6765\u7684\u65B9\u6CD5\u3002

    \u56E0\u4E3A\u91CD\u5199\u662F\u5728\u5B50\u7C7B\u91CD\u65B0\u5B9E\u73B0\u4ECE\u7236\u7C7B\u7EE7\u627F\u8FC7\u6765\u7684\u65B9\u6CD5\u65F6\u53D1\u751F\u7684\uFF0C\u6240\u4EE5\u53EA\u80FD\u91CD\u5199\u7EE7\u627F\u8FC7\u6765\u7684\u65B9\u6CD5\uFF0C\u8FD9\u5F88\u597D\u7406\u89E3\u3002\u8FD9\u5C31\u610F\u5473\u7740\uFF0C\u53EA\u80FD\u91CD\u5199\u90A3\u4E9B\u88AB public\u3001protected \u6216\u8005 default \u4FEE\u9970\u7684\u65B9\u6CD5\uFF0Cprivate \u4FEE\u9970\u7684\u65B9\u6CD5\u65E0\u6CD5\u88AB\u91CD\u5199\u3002

    Animal \u7C7B\u6709 move()\u3001eat() \u548C sleep() \u4E09\u4E2A\u65B9\u6CD5\uFF1A

    public class Animal {
    +import{_ as n}from"./plugin-vue_export-helper.21dcd24c.js";import{o as s,c as a,e}from"./app.615e41d8.js";const p={},t=e(`

    Java\u91CD\u5199\uFF08Overriding\uFF09\u65F6\u5E94\u5F53\u9075\u5B88\u768411\u6761\u89C4\u5219

    \u91CD\u5199\uFF08Overriding\uFF09\u7B97\u662F Java \u4E2D\u4E00\u4E2A\u975E\u5E38\u91CD\u8981\u7684\u6982\u5FF5\uFF0C\u7406\u89E3\u91CD\u5199\u5230\u5E95\u662F\u4EC0\u4E48\u5BF9\u6BCF\u4E2A Java \u7A0B\u5E8F\u5458\u6765\u8BF4\u90FD\u81F3\u5173\u91CD\u8981\uFF0C\u8FD9\u7BC7\u6587\u7AE0\u5C31\u6765\u7ED9\u5927\u5BB6\u8BF4\u8BF4\u91CD\u5199\u8FC7\u7A0B\u4E2D\u5E94\u5F53\u9075\u5B88\u7684 12 \u6761\u89C4\u5219\u3002

    01\u3001\u4EC0\u4E48\u662F\u91CD\u5199\uFF1F

    \u91CD\u5199\u5E26\u6765\u4E86\u4E00\u79CD\u975E\u5E38\u91CD\u8981\u7684\u80FD\u529B\uFF0C\u53EF\u4EE5\u8BA9\u5B50\u7C7B\u91CD\u65B0\u5B9E\u73B0\u4ECE\u8D85\u7C7B\u90A3\u7EE7\u627F\u8FC7\u6765\u7684\u65B9\u6CD5\u3002\u5728\u4E0B\u9762\u8FD9\u5E45\u56FE\u4E2D\uFF0CAnimal \u662F\u7236\u7C7B\uFF0CDog \u662F\u5B50\u7C7B\uFF0CDog \u91CD\u65B0\u5B9E\u73B0\u4E86 move() \u65B9\u6CD5\u7528\u6765\u548C\u7236\u7C7B\u8FDB\u884C\u533A\u5206\uFF0C\u6BD5\u7ADF\u72D7\u72D7\u8DD1\u8D77\u6765\u8FD8\u662F\u6BD4\u8F83\u6709\u7279\u8272\u7684\u3002

    \u91CD\u5199\u7684\u65B9\u6CD5\u548C\u88AB\u91CD\u5199\u7684\u65B9\u6CD5\uFF0C\u4E0D\u4EC5\u65B9\u6CD5\u540D\u76F8\u540C\uFF0C\u53C2\u6570\u4E5F\u76F8\u540C\uFF0C\u53EA\u4E0D\u8FC7\uFF0C\u65B9\u6CD5\u4F53\u6709\u6240\u4E0D\u540C\u3002

    02\u3001\u54EA\u4E9B\u65B9\u6CD5\u53EF\u4EE5\u88AB\u91CD\u5199\uFF1F

    \u89C4\u5219\u4E00\uFF1A\u53EA\u80FD\u91CD\u5199\u7EE7\u627F\u8FC7\u6765\u7684\u65B9\u6CD5\u3002

    \u56E0\u4E3A\u91CD\u5199\u662F\u5728\u5B50\u7C7B\u91CD\u65B0\u5B9E\u73B0\u4ECE\u7236\u7C7B\u7EE7\u627F\u8FC7\u6765\u7684\u65B9\u6CD5\u65F6\u53D1\u751F\u7684\uFF0C\u6240\u4EE5\u53EA\u80FD\u91CD\u5199\u7EE7\u627F\u8FC7\u6765\u7684\u65B9\u6CD5\uFF0C\u8FD9\u5F88\u597D\u7406\u89E3\u3002\u8FD9\u5C31\u610F\u5473\u7740\uFF0C\u53EA\u80FD\u91CD\u5199\u90A3\u4E9B\u88AB public\u3001protected \u6216\u8005 default \u4FEE\u9970\u7684\u65B9\u6CD5\uFF0Cprivate \u4FEE\u9970\u7684\u65B9\u6CD5\u65E0\u6CD5\u88AB\u91CD\u5199\u3002

    Animal \u7C7B\u6709 move()\u3001eat() \u548C sleep() \u4E09\u4E2A\u65B9\u6CD5\uFF1A

    public class Animal {
         public void move() { }
     
         protected void eat() { }
    diff --git a/dist/assets/ReentrantReadWriteLock.html.b8dcb20a.js b/dist/assets/ReentrantReadWriteLock.html.140f1c3e.js
    similarity index 99%
    rename from dist/assets/ReentrantReadWriteLock.html.b8dcb20a.js
    rename to dist/assets/ReentrantReadWriteLock.html.140f1c3e.js
    index a237aad3..31f93cc0 100644
    --- a/dist/assets/ReentrantReadWriteLock.html.b8dcb20a.js
    +++ b/dist/assets/ReentrantReadWriteLock.html.140f1c3e.js
    @@ -1,4 +1,4 @@
    -import{_ as e}from"./plugin-vue_export-helper.21dcd24c.js";import{r as p,o,c,a as n,b as a,e as l,d as t}from"./app.a0271b9c.js";const i={},u=l(`

    \u6DF1\u5165\u7406\u89E3Java\u5E76\u53D1\u8BFB\u5199\u9501ReentrantReadWriteLock

    \u5728\u5E76\u53D1\u573A\u666F\u4E2D\u7528\u4E8E\u89E3\u51B3\u7EBF\u7A0B\u5B89\u5168\u7684\u95EE\u9898\uFF0C\u6211\u4EEC\u51E0\u4E4E\u4F1A\u9AD8\u9891\u7387\u7684\u4F7F\u7528\u5230\u72EC\u5360\u5F0F\u9501\uFF0C\u901A\u5E38\u4F7F\u7528java\u63D0\u4F9B\u7684\u5173\u952E\u5B57synchronized\u6216\u8005concurrents\u5305\u4E2D\u5B9E\u73B0\u4E86Lock\u63A5\u53E3\u7684ReentrantLock\u3002\u5B83\u4EEC\u90FD\u662F\u72EC\u5360\u5F0F\u83B7\u53D6\u9501\uFF0C\u4E5F\u5C31\u662F\u5728\u540C\u4E00\u65F6\u523B\u53EA\u6709\u4E00\u4E2A\u7EBF\u7A0B\u80FD\u591F\u83B7\u53D6\u9501\u3002

    \u800C\u5728\u4E00\u4E9B\u4E1A\u52A1\u573A\u666F\u4E2D\uFF0C\u5927\u90E8\u5206\u53EA\u662F\u8BFB\u6570\u636E\uFF0C\u5199\u6570\u636E\u5F88\u5C11\uFF0C\u5982\u679C\u4EC5\u4EC5\u662F\u8BFB\u6570\u636E\u7684\u8BDD\u5E76\u4E0D\u4F1A\u5F71\u54CD\u6570\u636E\u6B63\u786E\u6027\uFF08\u51FA\u73B0\u810F\u8BFB\uFF09\uFF0C\u800C\u5982\u679C\u5728\u8FD9\u79CD\u4E1A\u52A1\u573A\u666F\u4E0B\uFF0C\u4F9D\u7136\u4F7F\u7528\u72EC\u5360\u9501\u7684\u8BDD\uFF0C\u5F88\u663E\u7136\u8FD9\u5C06\u662F\u51FA\u73B0\u6027\u80FD\u74F6\u9888\u7684\u5730\u65B9\u3002\u9488\u5BF9\u8FD9\u79CD\u8BFB\u591A\u5199\u5C11\u7684\u60C5\u51B5\uFF0Cjava\u8FD8\u63D0\u4F9B\u4E86\u53E6\u5916\u4E00\u4E2A\u5B9E\u73B0Lock\u63A5\u53E3\u7684ReentrantReadWriteLock(\u8BFB\u5199\u9501)\u3002

    \u8BFB\u5199\u9501\u5141\u8BB8\u540C\u4E00\u65F6\u523B\u88AB\u591A\u4E2A\u8BFB\u7EBF\u7A0B\u8BBF\u95EE\uFF0C\u4F46\u662F\u5728\u5199\u7EBF\u7A0B\u8BBF\u95EE\u65F6\uFF0C\u6240\u6709\u7684\u8BFB\u7EBF\u7A0B\u548C\u5176\u4ED6\u7684\u5199\u7EBF\u7A0B\u90FD\u4F1A\u88AB\u963B\u585E\u3002\u5728\u5206\u6790WirteLock\u548CReadLock\u7684\u4E92\u65A5\u6027\u65F6\u53EF\u4EE5\u6309\u7167WriteLock\u4E0EWriteLock\u4E4B\u95F4\uFF0CWriteLock\u4E0EReadLock\u4E4B\u95F4\u4EE5\u53CAReadLock\u4E0EReadLock\u4E4B\u95F4\u8FDB\u884C\u5206\u6790\u3002

    \u66F4\u591A\u5173\u4E8E\u8BFB\u5199\u9501\u7279\u6027\u4ECB\u7ECD\u5927\u5BB6\u53EF\u4EE5\u770B\u6E90\u7801\u4E0A\u7684\u4ECB\u7ECD\uFF08\u9605\u8BFB\u6E90\u7801\u65F6\u6700\u597D\u7684\u4E00\u79CD\u5B66\u4E60\u65B9\u5F0F\uFF0C\u6211\u4E5F\u6B63\u5728\u5B66\u4E60\u4E2D\uFF0C\u4E0E\u5927\u5BB6\u5171\u52C9\uFF09\uFF0C\u8FD9\u91CC\u505A\u4E00\u4E2A\u5F52\u7EB3\u603B\u7ED3\uFF1A

    1. \u516C\u5E73\u6027\u9009\u62E9\uFF1A\u652F\u6301\u975E\u516C\u5E73\u6027\uFF08\u9ED8\u8BA4\uFF09\u548C\u516C\u5E73\u7684\u9501\u83B7\u53D6\u65B9\u5F0F\uFF0C\u541E\u5410\u91CF\u8FD8\u662F\u975E\u516C\u5E73\u4F18\u4E8E\u516C\u5E73\uFF1B
    2. \u91CD\u5165\u6027\uFF1A\u652F\u6301\u91CD\u5165\uFF0C\u8BFB\u9501\u83B7\u53D6\u540E\u80FD\u518D\u6B21\u83B7\u53D6\uFF0C\u5199\u9501\u83B7\u53D6\u4E4B\u540E\u80FD\u591F\u518D\u6B21\u83B7\u53D6\u5199\u9501\uFF0C\u540C\u65F6\u4E5F\u80FD\u591F\u83B7\u53D6\u8BFB\u9501\uFF1B
    3. \u9501\u964D\u7EA7\uFF1A\u9075\u5FAA\u83B7\u53D6\u5199\u9501\uFF0C\u83B7\u53D6\u8BFB\u9501\u518D\u91CA\u653E\u5199\u9501\u7684\u6B21\u5E8F\uFF0C\u5199\u9501\u80FD\u591F\u964D\u7EA7\u6210\u4E3A\u8BFB\u9501

    \u8981\u60F3\u80FD\u591F\u5F7B\u5E95\u7684\u7406\u89E3\u8BFB\u5199\u9501\u5FC5\u987B\u80FD\u591F\u7406\u89E3\u8FD9\u6837\u51E0\u4E2A\u95EE\u9898\uFF1A

      1. \u8BFB\u5199\u9501\u662F\u600E\u6837\u5B9E\u73B0\u5206\u522B\u8BB0\u5F55\u8BFB\u5199\u72B6\u6001\u7684\uFF1F
      1. \u5199\u9501\u662F\u600E\u6837\u83B7\u53D6\u548C\u91CA\u653E\u7684\uFF1F
    • 3.\u8BFB\u9501\u662F\u600E\u6837\u83B7\u53D6\u548C\u91CA\u653E\u7684\uFF1F

    \u6211\u4EEC\u5E26\u7740\u8FD9\u6837\u7684\u4E09\u4E2A\u95EE\u9898\uFF0C\u518D\u53BB\u4E86\u89E3\u4E0B\u8BFB\u5199\u9501\u3002

    \u5199\u9501\u8BE6\u89E3

    \u5199\u9501\u7684\u83B7\u53D6

    \u540C\u6B65\u7EC4\u4EF6\u7684\u5B9E\u73B0\u805A\u5408\u4E86\u540C\u6B65\u5668\uFF08AQS\uFF09\uFF0C\u5E76\u901A\u8FC7\u91CD\u5199\u91CD\u5199\u540C\u6B65\u5668\uFF08AQS\uFF09\u4E2D\u7684\u65B9\u6CD5\u5B9E\u73B0\u540C\u6B65\u7EC4\u4EF6\u7684\u540C\u6B65\u8BED\u4E49\u3002\u56E0\u6B64\uFF0C\u5199\u9501\u7684\u5B9E\u73B0\u4F9D\u7136\u4E5F\u662F\u91C7\u7528\u8FD9\u79CD\u65B9\u5F0F\u3002\u5728\u540C\u4E00\u65F6\u523B\u5199\u9501\u662F\u4E0D\u80FD\u88AB\u591A\u4E2A\u7EBF\u7A0B\u6240\u83B7\u53D6\uFF0C\u5F88\u663E\u7136\u5199\u9501\u662F\u72EC\u5360\u5F0F\u9501\uFF0C\u800C\u5B9E\u73B0\u5199\u9501\u7684\u540C\u6B65\u8BED\u4E49\u662F\u901A\u8FC7\u91CD\u5199AQS\u4E2D\u7684tryAcquire\u65B9\u6CD5\u5B9E\u73B0\u7684\u3002\u6E90\u7801\u4E3A:

    protected final boolean tryAcquire(int acquires) {
    +import{_ as e}from"./plugin-vue_export-helper.21dcd24c.js";import{r as p,o,c,a as n,b as a,e as l,d as t}from"./app.615e41d8.js";const i={},u=l(`

    \u6DF1\u5165\u7406\u89E3Java\u5E76\u53D1\u8BFB\u5199\u9501ReentrantReadWriteLock

    \u5728\u5E76\u53D1\u573A\u666F\u4E2D\u7528\u4E8E\u89E3\u51B3\u7EBF\u7A0B\u5B89\u5168\u7684\u95EE\u9898\uFF0C\u6211\u4EEC\u51E0\u4E4E\u4F1A\u9AD8\u9891\u7387\u7684\u4F7F\u7528\u5230\u72EC\u5360\u5F0F\u9501\uFF0C\u901A\u5E38\u4F7F\u7528java\u63D0\u4F9B\u7684\u5173\u952E\u5B57synchronized\u6216\u8005concurrents\u5305\u4E2D\u5B9E\u73B0\u4E86Lock\u63A5\u53E3\u7684ReentrantLock\u3002\u5B83\u4EEC\u90FD\u662F\u72EC\u5360\u5F0F\u83B7\u53D6\u9501\uFF0C\u4E5F\u5C31\u662F\u5728\u540C\u4E00\u65F6\u523B\u53EA\u6709\u4E00\u4E2A\u7EBF\u7A0B\u80FD\u591F\u83B7\u53D6\u9501\u3002

    \u800C\u5728\u4E00\u4E9B\u4E1A\u52A1\u573A\u666F\u4E2D\uFF0C\u5927\u90E8\u5206\u53EA\u662F\u8BFB\u6570\u636E\uFF0C\u5199\u6570\u636E\u5F88\u5C11\uFF0C\u5982\u679C\u4EC5\u4EC5\u662F\u8BFB\u6570\u636E\u7684\u8BDD\u5E76\u4E0D\u4F1A\u5F71\u54CD\u6570\u636E\u6B63\u786E\u6027\uFF08\u51FA\u73B0\u810F\u8BFB\uFF09\uFF0C\u800C\u5982\u679C\u5728\u8FD9\u79CD\u4E1A\u52A1\u573A\u666F\u4E0B\uFF0C\u4F9D\u7136\u4F7F\u7528\u72EC\u5360\u9501\u7684\u8BDD\uFF0C\u5F88\u663E\u7136\u8FD9\u5C06\u662F\u51FA\u73B0\u6027\u80FD\u74F6\u9888\u7684\u5730\u65B9\u3002\u9488\u5BF9\u8FD9\u79CD\u8BFB\u591A\u5199\u5C11\u7684\u60C5\u51B5\uFF0Cjava\u8FD8\u63D0\u4F9B\u4E86\u53E6\u5916\u4E00\u4E2A\u5B9E\u73B0Lock\u63A5\u53E3\u7684ReentrantReadWriteLock(\u8BFB\u5199\u9501)\u3002

    \u8BFB\u5199\u9501\u5141\u8BB8\u540C\u4E00\u65F6\u523B\u88AB\u591A\u4E2A\u8BFB\u7EBF\u7A0B\u8BBF\u95EE\uFF0C\u4F46\u662F\u5728\u5199\u7EBF\u7A0B\u8BBF\u95EE\u65F6\uFF0C\u6240\u6709\u7684\u8BFB\u7EBF\u7A0B\u548C\u5176\u4ED6\u7684\u5199\u7EBF\u7A0B\u90FD\u4F1A\u88AB\u963B\u585E\u3002\u5728\u5206\u6790WirteLock\u548CReadLock\u7684\u4E92\u65A5\u6027\u65F6\u53EF\u4EE5\u6309\u7167WriteLock\u4E0EWriteLock\u4E4B\u95F4\uFF0CWriteLock\u4E0EReadLock\u4E4B\u95F4\u4EE5\u53CAReadLock\u4E0EReadLock\u4E4B\u95F4\u8FDB\u884C\u5206\u6790\u3002

    \u66F4\u591A\u5173\u4E8E\u8BFB\u5199\u9501\u7279\u6027\u4ECB\u7ECD\u5927\u5BB6\u53EF\u4EE5\u770B\u6E90\u7801\u4E0A\u7684\u4ECB\u7ECD\uFF08\u9605\u8BFB\u6E90\u7801\u65F6\u6700\u597D\u7684\u4E00\u79CD\u5B66\u4E60\u65B9\u5F0F\uFF0C\u6211\u4E5F\u6B63\u5728\u5B66\u4E60\u4E2D\uFF0C\u4E0E\u5927\u5BB6\u5171\u52C9\uFF09\uFF0C\u8FD9\u91CC\u505A\u4E00\u4E2A\u5F52\u7EB3\u603B\u7ED3\uFF1A

    1. \u516C\u5E73\u6027\u9009\u62E9\uFF1A\u652F\u6301\u975E\u516C\u5E73\u6027\uFF08\u9ED8\u8BA4\uFF09\u548C\u516C\u5E73\u7684\u9501\u83B7\u53D6\u65B9\u5F0F\uFF0C\u541E\u5410\u91CF\u8FD8\u662F\u975E\u516C\u5E73\u4F18\u4E8E\u516C\u5E73\uFF1B
    2. \u91CD\u5165\u6027\uFF1A\u652F\u6301\u91CD\u5165\uFF0C\u8BFB\u9501\u83B7\u53D6\u540E\u80FD\u518D\u6B21\u83B7\u53D6\uFF0C\u5199\u9501\u83B7\u53D6\u4E4B\u540E\u80FD\u591F\u518D\u6B21\u83B7\u53D6\u5199\u9501\uFF0C\u540C\u65F6\u4E5F\u80FD\u591F\u83B7\u53D6\u8BFB\u9501\uFF1B
    3. \u9501\u964D\u7EA7\uFF1A\u9075\u5FAA\u83B7\u53D6\u5199\u9501\uFF0C\u83B7\u53D6\u8BFB\u9501\u518D\u91CA\u653E\u5199\u9501\u7684\u6B21\u5E8F\uFF0C\u5199\u9501\u80FD\u591F\u964D\u7EA7\u6210\u4E3A\u8BFB\u9501

    \u8981\u60F3\u80FD\u591F\u5F7B\u5E95\u7684\u7406\u89E3\u8BFB\u5199\u9501\u5FC5\u987B\u80FD\u591F\u7406\u89E3\u8FD9\u6837\u51E0\u4E2A\u95EE\u9898\uFF1A

      1. \u8BFB\u5199\u9501\u662F\u600E\u6837\u5B9E\u73B0\u5206\u522B\u8BB0\u5F55\u8BFB\u5199\u72B6\u6001\u7684\uFF1F
      1. \u5199\u9501\u662F\u600E\u6837\u83B7\u53D6\u548C\u91CA\u653E\u7684\uFF1F
    • 3.\u8BFB\u9501\u662F\u600E\u6837\u83B7\u53D6\u548C\u91CA\u653E\u7684\uFF1F

    \u6211\u4EEC\u5E26\u7740\u8FD9\u6837\u7684\u4E09\u4E2A\u95EE\u9898\uFF0C\u518D\u53BB\u4E86\u89E3\u4E0B\u8BFB\u5199\u9501\u3002

    \u5199\u9501\u8BE6\u89E3

    \u5199\u9501\u7684\u83B7\u53D6

    \u540C\u6B65\u7EC4\u4EF6\u7684\u5B9E\u73B0\u805A\u5408\u4E86\u540C\u6B65\u5668\uFF08AQS\uFF09\uFF0C\u5E76\u901A\u8FC7\u91CD\u5199\u91CD\u5199\u540C\u6B65\u5668\uFF08AQS\uFF09\u4E2D\u7684\u65B9\u6CD5\u5B9E\u73B0\u540C\u6B65\u7EC4\u4EF6\u7684\u540C\u6B65\u8BED\u4E49\u3002\u56E0\u6B64\uFF0C\u5199\u9501\u7684\u5B9E\u73B0\u4F9D\u7136\u4E5F\u662F\u91C7\u7528\u8FD9\u79CD\u65B9\u5F0F\u3002\u5728\u540C\u4E00\u65F6\u523B\u5199\u9501\u662F\u4E0D\u80FD\u88AB\u591A\u4E2A\u7EBF\u7A0B\u6240\u83B7\u53D6\uFF0C\u5F88\u663E\u7136\u5199\u9501\u662F\u72EC\u5360\u5F0F\u9501\uFF0C\u800C\u5B9E\u73B0\u5199\u9501\u7684\u540C\u6B65\u8BED\u4E49\u662F\u901A\u8FC7\u91CD\u5199AQS\u4E2D\u7684tryAcquire\u65B9\u6CD5\u5B9E\u73B0\u7684\u3002\u6E90\u7801\u4E3A:

    protected final boolean tryAcquire(int acquires) {
         /*
          * Walkthrough:
          * 1. If read count nonzero or write count nonzero
    diff --git a/dist/assets/ScheduledThreadPoolExecutor.html.e216d19d.js b/dist/assets/ScheduledThreadPoolExecutor.html.73744e7a.js
    similarity index 99%
    rename from dist/assets/ScheduledThreadPoolExecutor.html.e216d19d.js
    rename to dist/assets/ScheduledThreadPoolExecutor.html.73744e7a.js
    index 4ecbbb41..6b701181 100644
    --- a/dist/assets/ScheduledThreadPoolExecutor.html.e216d19d.js
    +++ b/dist/assets/ScheduledThreadPoolExecutor.html.73744e7a.js
    @@ -1,4 +1,4 @@
    -import{_ as p}from"./plugin-vue_export-helper.21dcd24c.js";import{r as t,o,c,a as n,b as a,e as l,d as e}from"./app.a0271b9c.js";const u={},i=l(`

    \u81EAJDK 1.5 \u5F00\u59CB\uFF0CJDK\u63D0\u4F9B\u4E86ScheduledThreadPoolExecutor\u7C7B\u7528\u4E8E\u8BA1\u5212\u4EFB\u52A1\uFF08\u53C8\u79F0\u5B9A\u65F6\u4EFB\u52A1\uFF09\uFF0C\u8FD9\u4E2A\u7C7B\u6709\u4E24\u4E2A\u7528\u9014\uFF1A

    • \u5728\u7ED9\u5B9A\u7684\u5EF6\u8FDF\u4E4B\u540E\u8FD0\u884C\u4EFB\u52A1
    • \u5468\u671F\u6027\u91CD\u590D\u6267\u884C\u4EFB\u52A1

    \u5728\u8FD9\u4E4B\u524D\uFF0C\u662F\u4F7F\u7528Timer\u7C7B\u6765\u5B8C\u6210\u5B9A\u65F6\u4EFB\u52A1\u7684\uFF0C\u4F46\u662FTimer\u6709\u7F3A\u9677\uFF1A

    • Timer\u662F\u5355\u7EBF\u7A0B\u6A21\u5F0F\uFF1B
    • \u5982\u679C\u5728\u6267\u884C\u4EFB\u52A1\u671F\u95F4\u67D0\u4E2ATimerTask\u8017\u65F6\u8F83\u4E45\uFF0C\u90A3\u4E48\u5C31\u4F1A\u5F71\u54CD\u5176\u5B83\u4EFB\u52A1\u7684\u8C03\u5EA6\uFF1B
    • Timer\u7684\u4EFB\u52A1\u8C03\u5EA6\u662F\u57FA\u4E8E\u7EDD\u5BF9\u65F6\u95F4\u7684\uFF0C\u5BF9\u7CFB\u7EDF\u65F6\u95F4\u654F\u611F\uFF1B
    • Timer\u4E0D\u4F1A\u6355\u83B7\u6267\u884CTimerTask\u65F6\u6240\u629B\u51FA\u7684\u5F02\u5E38\uFF0C\u7531\u4E8ETimer\u662F\u5355\u7EBF\u7A0B\uFF0C\u6240\u4EE5\u4E00\u65E6\u51FA\u73B0\u5F02\u5E38\uFF0C\u5219\u7EBF\u7A0B\u5C31\u4F1A\u7EC8\u6B62\uFF0C\u5176\u4ED6\u4EFB\u52A1\u4E5F\u5F97\u4E0D\u5230\u6267\u884C\u3002

    \u6240\u4EE5JDK 1.5\u4E4B\u540E\uFF0C\u5927\u5BB6\u5C31\u6452\u5F03Timer,\u4F7F\u7528ScheduledThreadPoolExecutor\u5427\u3002

    \u4F7F\u7528\u6848\u4F8B

    \u5047\u8BBE\u6211\u6709\u4E00\u4E2A\u9700\u6C42\uFF0C\u6307\u5B9A\u65F6\u95F4\u7ED9\u5927\u5BB6\u53D1\u9001\u6D88\u606F\u3002\u90A3\u4E48\u6211\u4EEC\u4F1A\u5C06\u6D88\u606F\uFF08\u5305\u542B\u53D1\u9001\u65F6\u95F4\uFF09\u5B58\u50A8\u5728\u6570\u636E\u5E93\u4E2D\uFF0C\u7136\u540E\u60F3\u7528\u4E00\u4E2A\u5B9A\u65F6\u4EFB\u52A1\uFF0C\u6BCF\u96941\u79D2\u68C0\u67E5\u6570\u636E\u5E93\u5728\u5F53\u524D\u65F6\u95F4\u6709\u6CA1\u6709\u9700\u8981\u53D1\u9001\u7684\u6D88\u606F\uFF0C\u90A3\u8FD9\u4E2A\u8BA1\u5212\u4EFB\u52A1\u600E\u4E48\u5199\uFF1F\u4E0B\u9762\u662F\u4E00\u4E2ADemo:

    public class ThreadPool {
    +import{_ as p}from"./plugin-vue_export-helper.21dcd24c.js";import{r as t,o,c,a as n,b as a,e as l,d as e}from"./app.615e41d8.js";const u={},i=l(`

    \u81EAJDK 1.5 \u5F00\u59CB\uFF0CJDK\u63D0\u4F9B\u4E86ScheduledThreadPoolExecutor\u7C7B\u7528\u4E8E\u8BA1\u5212\u4EFB\u52A1\uFF08\u53C8\u79F0\u5B9A\u65F6\u4EFB\u52A1\uFF09\uFF0C\u8FD9\u4E2A\u7C7B\u6709\u4E24\u4E2A\u7528\u9014\uFF1A

    • \u5728\u7ED9\u5B9A\u7684\u5EF6\u8FDF\u4E4B\u540E\u8FD0\u884C\u4EFB\u52A1
    • \u5468\u671F\u6027\u91CD\u590D\u6267\u884C\u4EFB\u52A1

    \u5728\u8FD9\u4E4B\u524D\uFF0C\u662F\u4F7F\u7528Timer\u7C7B\u6765\u5B8C\u6210\u5B9A\u65F6\u4EFB\u52A1\u7684\uFF0C\u4F46\u662FTimer\u6709\u7F3A\u9677\uFF1A

    • Timer\u662F\u5355\u7EBF\u7A0B\u6A21\u5F0F\uFF1B
    • \u5982\u679C\u5728\u6267\u884C\u4EFB\u52A1\u671F\u95F4\u67D0\u4E2ATimerTask\u8017\u65F6\u8F83\u4E45\uFF0C\u90A3\u4E48\u5C31\u4F1A\u5F71\u54CD\u5176\u5B83\u4EFB\u52A1\u7684\u8C03\u5EA6\uFF1B
    • Timer\u7684\u4EFB\u52A1\u8C03\u5EA6\u662F\u57FA\u4E8E\u7EDD\u5BF9\u65F6\u95F4\u7684\uFF0C\u5BF9\u7CFB\u7EDF\u65F6\u95F4\u654F\u611F\uFF1B
    • Timer\u4E0D\u4F1A\u6355\u83B7\u6267\u884CTimerTask\u65F6\u6240\u629B\u51FA\u7684\u5F02\u5E38\uFF0C\u7531\u4E8ETimer\u662F\u5355\u7EBF\u7A0B\uFF0C\u6240\u4EE5\u4E00\u65E6\u51FA\u73B0\u5F02\u5E38\uFF0C\u5219\u7EBF\u7A0B\u5C31\u4F1A\u7EC8\u6B62\uFF0C\u5176\u4ED6\u4EFB\u52A1\u4E5F\u5F97\u4E0D\u5230\u6267\u884C\u3002

    \u6240\u4EE5JDK 1.5\u4E4B\u540E\uFF0C\u5927\u5BB6\u5C31\u6452\u5F03Timer,\u4F7F\u7528ScheduledThreadPoolExecutor\u5427\u3002

    \u4F7F\u7528\u6848\u4F8B

    \u5047\u8BBE\u6211\u6709\u4E00\u4E2A\u9700\u6C42\uFF0C\u6307\u5B9A\u65F6\u95F4\u7ED9\u5927\u5BB6\u53D1\u9001\u6D88\u606F\u3002\u90A3\u4E48\u6211\u4EEC\u4F1A\u5C06\u6D88\u606F\uFF08\u5305\u542B\u53D1\u9001\u65F6\u95F4\uFF09\u5B58\u50A8\u5728\u6570\u636E\u5E93\u4E2D\uFF0C\u7136\u540E\u60F3\u7528\u4E00\u4E2A\u5B9A\u65F6\u4EFB\u52A1\uFF0C\u6BCF\u96941\u79D2\u68C0\u67E5\u6570\u636E\u5E93\u5728\u5F53\u524D\u65F6\u95F4\u6709\u6CA1\u6709\u9700\u8981\u53D1\u9001\u7684\u6D88\u606F\uFF0C\u90A3\u8FD9\u4E2A\u8BA1\u5212\u4EFB\u52A1\u600E\u4E48\u5199\uFF1F\u4E0B\u9762\u662F\u4E00\u4E2ADemo:

    public class ThreadPool {
         
         private static final ScheduledExecutorService executor = new
             ScheduledThreadPoolExecutor(1, Executors.defaultThreadFactory());
    diff --git a/dist/assets/SkipLink.e761490e.js b/dist/assets/SkipLink.a2c3a90f.js
    similarity index 89%
    rename from dist/assets/SkipLink.e761490e.js
    rename to dist/assets/SkipLink.a2c3a90f.js
    index 001ed7e2..78905bf3 100644
    --- a/dist/assets/SkipLink.e761490e.js
    +++ b/dist/assets/SkipLink.a2c3a90f.js
    @@ -1 +1 @@
    -import{f as c,j as u,k as p,l,h as o}from"./app.a0271b9c.js";var f=c({name:"SkipLink",props:{content:{type:String,default:"main-content"}},setup(s){const r=u(),t=p();l(()=>r.path,()=>t.value.focus());const a=({target:i})=>{const e=document.querySelector(i.hash);if(e){const n=()=>{e.removeAttribute("tabindex"),e.removeEventListener("blur",n)};e.setAttribute("tabindex","-1"),e.addEventListener("blur",n),e.focus(),window.scrollTo(0,0)}};return()=>[o("span",{ref:t,tabindex:"-1"}),o("a",{href:`#${s.content}`,class:"skip-link sr-only",onClick:a},"Skip to content")]}});export{f as S};
    +import{f as c,j as u,k as p,l,h as o}from"./app.615e41d8.js";var f=c({name:"SkipLink",props:{content:{type:String,default:"main-content"}},setup(s){const r=u(),t=p();l(()=>r.path,()=>t.value.focus());const a=({target:i})=>{const e=document.querySelector(i.hash);if(e){const n=()=>{e.removeAttribute("tabindex"),e.removeEventListener("blur",n)};e.setAttribute("tabindex","-1"),e.addEventListener("blur",n),e.focus(),window.scrollTo(0,0)}};return()=>[o("span",{ref:t,tabindex:"-1"}),o("a",{href:`#${s.content}`,class:"skip-link sr-only",onClick:a},"Skip to content")]}});export{f as S};
    diff --git a/dist/assets/Slide.a2a8944b.js b/dist/assets/Slide.39e63deb.js
    similarity index 94%
    rename from dist/assets/Slide.a2a8944b.js
    rename to dist/assets/Slide.39e63deb.js
    index 3652528d..24369cff 100644
    --- a/dist/assets/Slide.a2a8944b.js
    +++ b/dist/assets/Slide.39e63deb.js
    @@ -1 +1 @@
    -import{f as u,v as i,k as o,x as c,h as a,C as v,y as s}from"./app.a0271b9c.js";const r=()=>a(s,{name:"back"},()=>a("path",{d:"M1014.749 449.156v125.688H260.626l345.64 345.64-89.239 89.237L19.307 512l497.72-497.721 89.238 89.238-345.64 345.64h754.124z"})),d=()=>a(s,{name:"home"},()=>a("path",{d:"M780.106 420.978L506.994 147.866 233.882 420.978h.045v455.11H780.06v-455.11h.046zm90.977 90.976V876.09a91.022 91.022 0 01-91.023 91.022H233.927a91.022 91.022 0 01-91.022-91.022V511.954l-67.22 67.175-64.307-64.307 431.309-431.31c35.498-35.498 93.115-35.498 128.614 0l431.309 431.31-64.307 64.307L871.083 512z"}));var h=u({name:"SlidePage",setup(){const l=i(),t=o(!1),e=o(null),n=()=>{t.value=!1};return c(e,n),()=>a("div",{class:"presentation"},[a(v),a("div",{ref:e,class:["menu",{active:t.value}]},[a("button",{class:"menu-button",onClick:()=>{t.value=!t.value}},a("span",{class:"icon"})),a("button",{class:"back-button",onClick:()=>(n(),void window.history.go(-1))},a(r)),a("button",{class:"home-button",onClick:()=>(n(),void l.push("/"))},a(d))])])}});export{h as default};
    +import{f as u,v as i,k as o,x as c,h as a,C as v,y as s}from"./app.615e41d8.js";const r=()=>a(s,{name:"back"},()=>a("path",{d:"M1014.749 449.156v125.688H260.626l345.64 345.64-89.239 89.237L19.307 512l497.72-497.721 89.238 89.238-345.64 345.64h754.124z"})),d=()=>a(s,{name:"home"},()=>a("path",{d:"M780.106 420.978L506.994 147.866 233.882 420.978h.045v455.11H780.06v-455.11h.046zm90.977 90.976V876.09a91.022 91.022 0 01-91.023 91.022H233.927a91.022 91.022 0 01-91.022-91.022V511.954l-67.22 67.175-64.307-64.307 431.309-431.31c35.498-35.498 93.115-35.498 128.614 0l431.309 431.31-64.307 64.307L871.083 512z"}));var h=u({name:"SlidePage",setup(){const l=i(),t=o(!1),e=o(null),n=()=>{t.value=!1};return c(e,n),()=>a("div",{class:"presentation"},[a(v),a("div",{ref:e,class:["menu",{active:t.value}]},[a("button",{class:"menu-button",onClick:()=>{t.value=!t.value}},a("span",{class:"icon"})),a("button",{class:"back-button",onClick:()=>(n(),void window.history.go(-1))},a(r)),a("button",{class:"home-button",onClick:()=>(n(),void l.push("/"))},a(d))])])}});export{h as default};
    diff --git a/dist/assets/ThreadLocal.html.284cf60c.js b/dist/assets/ThreadLocal.html.2993d4fd.js
    similarity index 99%
    rename from dist/assets/ThreadLocal.html.284cf60c.js
    rename to dist/assets/ThreadLocal.html.2993d4fd.js
    index 569015aa..8d66aa63 100644
    --- a/dist/assets/ThreadLocal.html.284cf60c.js
    +++ b/dist/assets/ThreadLocal.html.2993d4fd.js
    @@ -1,4 +1,4 @@
    -import{_ as p}from"./plugin-vue_export-helper.21dcd24c.js";import{r as o,o as c,c as l,a as n,b as e,e as t,d as a}from"./app.a0271b9c.js";const i={},u=t(`

    ThreadLocal\u7684\u7B80\u4ECB

    \u5728\u591A\u7EBF\u7A0B\u7F16\u7A0B\u4E2D\u901A\u5E38\u89E3\u51B3\u7EBF\u7A0B\u5B89\u5168\u7684\u95EE\u9898\u6211\u4EEC\u4F1A\u5229\u7528synchronzed\u6216\u8005lock\u63A7\u5236\u7EBF\u7A0B\u5BF9\u4E34\u754C\u533A\u8D44\u6E90\u7684\u540C\u6B65\u987A\u5E8F\u4ECE\u800C\u89E3\u51B3\u7EBF\u7A0B\u5B89\u5168\u7684\u95EE\u9898\uFF0C\u4F46\u662F\u8FD9\u79CD\u52A0\u9501\u7684\u65B9\u5F0F\u4F1A\u8BA9\u672A\u83B7\u53D6\u5230\u9501\u7684\u7EBF\u7A0B\u8FDB\u884C\u963B\u585E\u7B49\u5F85\uFF0C\u5F88\u663E\u7136\u8FD9\u79CD\u65B9\u5F0F\u7684\u65F6\u95F4\u6548\u7387\u5E76\u4E0D\u662F\u5F88\u597D\u3002

    \u7EBF\u7A0B\u5B89\u5168\u95EE\u9898\u7684\u6838\u5FC3\u5728\u4E8E\u591A\u4E2A\u7EBF\u7A0B\u4F1A\u5BF9\u540C\u4E00\u4E2A\u4E34\u754C\u533A\u5171\u4EAB\u8D44\u6E90\u8FDB\u884C\u64CD\u4F5C\uFF0C\u90A3\u4E48\uFF0C\u5982\u679C\u6BCF\u4E2A\u7EBF\u7A0B\u90FD\u4F7F\u7528\u81EA\u5DF1\u7684\u201C\u5171\u4EAB\u8D44\u6E90\u201D\uFF0C\u5404\u81EA\u4F7F\u7528\u5404\u81EA\u7684\uFF0C\u53C8\u4E92\u76F8\u4E0D\u5F71\u54CD\u5230\u5F7C\u6B64\u5373\u8BA9\u591A\u4E2A\u7EBF\u7A0B\u95F4\u8FBE\u5230\u9694\u79BB\u7684\u72B6\u6001\uFF0C\u8FD9\u6837\u5C31\u4E0D\u4F1A\u51FA\u73B0\u7EBF\u7A0B\u5B89\u5168\u7684\u95EE\u9898\u3002

    \u4E8B\u5B9E\u4E0A\uFF0C\u8FD9\u5C31\u662F\u4E00\u79CD\u201C\u7A7A\u95F4\u6362\u65F6\u95F4\u201D\u7684\u65B9\u6848\uFF0C\u6BCF\u4E2A\u7EBF\u7A0B\u90FD\u4F1A\u90FD\u62E5\u6709\u81EA\u5DF1\u7684\u201C\u5171\u4EAB\u8D44\u6E90\u201D\u65E0\u7591\u5185\u5B58\u4F1A\u5927\u5F88\u591A\uFF0C\u4F46\u662F\u7531\u4E8E\u4E0D\u9700\u8981\u540C\u6B65\u4E5F\u5C31\u51CF\u5C11\u4E86\u7EBF\u7A0B\u53EF\u80FD\u5B58\u5728\u7684\u963B\u585E\u7B49\u5F85\u7684\u60C5\u51B5\u4ECE\u800C\u63D0\u9AD8\u7684\u65F6\u95F4\u6548\u7387\u3002

    \u867D\u7136ThreadLocal\u5E76\u4E0D\u5728java.util.concurrent\u5305\u4E2D\u800C\u5728java.lang\u5305\u4E2D\uFF0C\u4F46\u6211\u66F4\u503E\u5411\u4E8E\u628A\u5B83\u5F53\u4F5C\u662F\u4E00\u79CD\u5E76\u53D1\u5BB9\u5668\uFF08\u867D\u7136\u771F\u6B63\u5B58\u653E\u6570\u636E\u7684\u662FThreadLoclMap\uFF09\u8FDB\u884C\u5F52\u7C7B\u3002

    \u4ECEThreadLocal\u8FD9\u4E2A\u7C7B\u540D\u53EF\u4EE5\u987E\u540D\u601D\u4E49\u7684\u8FDB\u884C\u7406\u89E3\uFF0C\u8868\u793A\u7EBF\u7A0B\u7684\u201C\u672C\u5730\u53D8\u91CF\u201D\uFF0C\u5373\u6BCF\u4E2A\u7EBF\u7A0B\u90FD\u62E5\u6709\u8BE5\u53D8\u91CF\u526F\u672C\uFF0C\u8FBE\u5230\u4EBA\u624B\u4E00\u4EFD\u7684\u6548\u679C\uFF0C\u5404\u7528\u5404\u7684\u8FD9\u6837\u5C31\u53EF\u4EE5\u907F\u514D\u5171\u4EAB\u8D44\u6E90\u7684\u7ADE\u4E89\u3002

    ThreadLocal\u7684\u5B9E\u73B0\u539F\u7406

    \u8981\u60F3\u5B66\u4E60\u5230ThreadLocal\u7684\u5B9E\u73B0\u539F\u7406\uFF0C\u5C31\u5FC5\u987B\u4E86\u89E3\u5B83\u7684\u51E0\u4E2A\u6838\u5FC3\u65B9\u6CD5\uFF0C\u5305\u62EC\u600E\u6837\u5B58\u600E\u6837\u53D6\u7B49\u7B49\uFF0C\u4E0B\u9762\u6211\u4EEC\u4E00\u4E2A\u4E2A\u6765\u770B\u3002

    void set(T value)

    set\u65B9\u6CD5\u8BBE\u7F6E\u5728\u5F53\u524D\u7EBF\u7A0B\u4E2DthreadLocal\u53D8\u91CF\u7684\u503C\uFF0C\u8BE5\u65B9\u6CD5\u7684\u6E90\u7801\u4E3A\uFF1A

    public void set(T value) {
    +import{_ as p}from"./plugin-vue_export-helper.21dcd24c.js";import{r as o,o as c,c as l,a as n,b as e,e as t,d as a}from"./app.615e41d8.js";const i={},u=t(`

    ThreadLocal\u7684\u7B80\u4ECB

    \u5728\u591A\u7EBF\u7A0B\u7F16\u7A0B\u4E2D\u901A\u5E38\u89E3\u51B3\u7EBF\u7A0B\u5B89\u5168\u7684\u95EE\u9898\u6211\u4EEC\u4F1A\u5229\u7528synchronzed\u6216\u8005lock\u63A7\u5236\u7EBF\u7A0B\u5BF9\u4E34\u754C\u533A\u8D44\u6E90\u7684\u540C\u6B65\u987A\u5E8F\u4ECE\u800C\u89E3\u51B3\u7EBF\u7A0B\u5B89\u5168\u7684\u95EE\u9898\uFF0C\u4F46\u662F\u8FD9\u79CD\u52A0\u9501\u7684\u65B9\u5F0F\u4F1A\u8BA9\u672A\u83B7\u53D6\u5230\u9501\u7684\u7EBF\u7A0B\u8FDB\u884C\u963B\u585E\u7B49\u5F85\uFF0C\u5F88\u663E\u7136\u8FD9\u79CD\u65B9\u5F0F\u7684\u65F6\u95F4\u6548\u7387\u5E76\u4E0D\u662F\u5F88\u597D\u3002

    \u7EBF\u7A0B\u5B89\u5168\u95EE\u9898\u7684\u6838\u5FC3\u5728\u4E8E\u591A\u4E2A\u7EBF\u7A0B\u4F1A\u5BF9\u540C\u4E00\u4E2A\u4E34\u754C\u533A\u5171\u4EAB\u8D44\u6E90\u8FDB\u884C\u64CD\u4F5C\uFF0C\u90A3\u4E48\uFF0C\u5982\u679C\u6BCF\u4E2A\u7EBF\u7A0B\u90FD\u4F7F\u7528\u81EA\u5DF1\u7684\u201C\u5171\u4EAB\u8D44\u6E90\u201D\uFF0C\u5404\u81EA\u4F7F\u7528\u5404\u81EA\u7684\uFF0C\u53C8\u4E92\u76F8\u4E0D\u5F71\u54CD\u5230\u5F7C\u6B64\u5373\u8BA9\u591A\u4E2A\u7EBF\u7A0B\u95F4\u8FBE\u5230\u9694\u79BB\u7684\u72B6\u6001\uFF0C\u8FD9\u6837\u5C31\u4E0D\u4F1A\u51FA\u73B0\u7EBF\u7A0B\u5B89\u5168\u7684\u95EE\u9898\u3002

    \u4E8B\u5B9E\u4E0A\uFF0C\u8FD9\u5C31\u662F\u4E00\u79CD\u201C\u7A7A\u95F4\u6362\u65F6\u95F4\u201D\u7684\u65B9\u6848\uFF0C\u6BCF\u4E2A\u7EBF\u7A0B\u90FD\u4F1A\u90FD\u62E5\u6709\u81EA\u5DF1\u7684\u201C\u5171\u4EAB\u8D44\u6E90\u201D\u65E0\u7591\u5185\u5B58\u4F1A\u5927\u5F88\u591A\uFF0C\u4F46\u662F\u7531\u4E8E\u4E0D\u9700\u8981\u540C\u6B65\u4E5F\u5C31\u51CF\u5C11\u4E86\u7EBF\u7A0B\u53EF\u80FD\u5B58\u5728\u7684\u963B\u585E\u7B49\u5F85\u7684\u60C5\u51B5\u4ECE\u800C\u63D0\u9AD8\u7684\u65F6\u95F4\u6548\u7387\u3002

    \u867D\u7136ThreadLocal\u5E76\u4E0D\u5728java.util.concurrent\u5305\u4E2D\u800C\u5728java.lang\u5305\u4E2D\uFF0C\u4F46\u6211\u66F4\u503E\u5411\u4E8E\u628A\u5B83\u5F53\u4F5C\u662F\u4E00\u79CD\u5E76\u53D1\u5BB9\u5668\uFF08\u867D\u7136\u771F\u6B63\u5B58\u653E\u6570\u636E\u7684\u662FThreadLoclMap\uFF09\u8FDB\u884C\u5F52\u7C7B\u3002

    \u4ECEThreadLocal\u8FD9\u4E2A\u7C7B\u540D\u53EF\u4EE5\u987E\u540D\u601D\u4E49\u7684\u8FDB\u884C\u7406\u89E3\uFF0C\u8868\u793A\u7EBF\u7A0B\u7684\u201C\u672C\u5730\u53D8\u91CF\u201D\uFF0C\u5373\u6BCF\u4E2A\u7EBF\u7A0B\u90FD\u62E5\u6709\u8BE5\u53D8\u91CF\u526F\u672C\uFF0C\u8FBE\u5230\u4EBA\u624B\u4E00\u4EFD\u7684\u6548\u679C\uFF0C\u5404\u7528\u5404\u7684\u8FD9\u6837\u5C31\u53EF\u4EE5\u907F\u514D\u5171\u4EAB\u8D44\u6E90\u7684\u7ADE\u4E89\u3002

    ThreadLocal\u7684\u5B9E\u73B0\u539F\u7406

    \u8981\u60F3\u5B66\u4E60\u5230ThreadLocal\u7684\u5B9E\u73B0\u539F\u7406\uFF0C\u5C31\u5FC5\u987B\u4E86\u89E3\u5B83\u7684\u51E0\u4E2A\u6838\u5FC3\u65B9\u6CD5\uFF0C\u5305\u62EC\u600E\u6837\u5B58\u600E\u6837\u53D6\u7B49\u7B49\uFF0C\u4E0B\u9762\u6211\u4EEC\u4E00\u4E2A\u4E2A\u6765\u770B\u3002

    void set(T value)

    set\u65B9\u6CD5\u8BBE\u7F6E\u5728\u5F53\u524D\u7EBF\u7A0B\u4E2DthreadLocal\u53D8\u91CF\u7684\u503C\uFF0C\u8BE5\u65B9\u6CD5\u7684\u6E90\u7801\u4E3A\uFF1A

    public void set(T value) {
     	  //1. \u83B7\u53D6\u5F53\u524D\u7EBF\u7A0B\u5B9E\u4F8B\u5BF9\u8C61
         Thread t = Thread.currentThread();
     
    diff --git a/dist/assets/ZHIHUjavaxuexidaoshemechengduokeyizhaodiyifengongzuo.html.9b7b6461.js b/dist/assets/ZHIHUjavaxuexidaoshemechengduokeyizhaodiyifengongzuo.html.ef1e0c27.js
    similarity index 98%
    rename from dist/assets/ZHIHUjavaxuexidaoshemechengduokeyizhaodiyifengongzuo.html.9b7b6461.js
    rename to dist/assets/ZHIHUjavaxuexidaoshemechengduokeyizhaodiyifengongzuo.html.ef1e0c27.js
    index dc12d35f..6c1eeaf0 100644
    --- a/dist/assets/ZHIHUjavaxuexidaoshemechengduokeyizhaodiyifengongzuo.html.9b7b6461.js
    +++ b/dist/assets/ZHIHUjavaxuexidaoshemechengduokeyizhaodiyifengongzuo.html.ef1e0c27.js
    @@ -1 +1 @@
    -import{_ as r}from"./plugin-vue_export-helper.21dcd24c.js";import{r as n,o as p,c as s,a as e,b as a,e as c,d as t}from"./app.a0271b9c.js";const h={},i=c('

    \u73B0\u5728\u5F88\u665A\u4E86\uFF0C\u4F46\u662F\u770B\u5230\u8FD9\u4E2A\u95EE\u9898\u8FD8\u662F\u6BD4\u8F83\u6709\u611F\u89E6\u7684\u3002\u4E00\u5E74\u524D\uFF0C\u6211\u5927\u4E09\u4E0A\u5B66\u671F\uFF0C\u521B\u4E1A\u5931\u8D25\uFF0C\u60F3\u8F6C\u884C\u505A\u6280\u672F\u3002\u90A3\u65F6\u5019\u6211\u5BF9Java\u521A\u521A\u4E86\u89E3\u8FD9\u51E0\u4E2A\u82F1\u8BED\u5355\u8BCD\u3002 \u81EA\u5DF1\u4E70\u4E86\u672CJava\u4ECE\u5165\u95E8\u5230\u7CBE\u901A\u3002\u4EE5\u4E3A\u53EF\u4EE5\u5F88\u5FEB\u7684\u5B66\u5B8C\uFF0C\u975ECS\u4E13\u4E1A\u3002
    \u73B0\u5728\u6211\u60F3\u8BF4\u6240\u6709\u7CFB\u5217\u7684\u4ECE\u5165\u95E8\u5230\u7CBE\u901A\u90FD\u662F\u5783\u573E\uFF0C\u4E00\u5E74\u591A\u6765\uFF0C\u6211\u6BCF\u5929\u767D\u5929\u770B\u89C6\u9891\uFF0C\u665A\u4E0A\u6572\u4EE3\u7801\u5230\u51CC\u6668\uFF0C\u6211\u662F\u4E00\u4E2A\u5F88\u5014\u7684\u4EBA\uFF0C\u6211\u8BA4\u4E3A\u5929\u4E0B\u6CA1\u6709\u4EFB\u4F55\u4E1C\u897F\u662F\u4EBA\u7C7B\u5B66\u4E0D\u4F1A\u7684\uFF0C\u6240\u4EE5\u6211\u5C31\u4ED8\u51FA\u9AD8\u4E09\u4E00\u6837\u7684\u65F6\u95F4\u53BB\u5B66\u4E60\u3002\u6700\u5F00\u59CB\u5B66\u4E60Java SE\uFF0C\u770B\u7740\u63A7\u5236\u53F0\u6253\u5370\u51FA\u7B2C\u4E00\u884CHello world\u7684\u6B23\u559C\uFF0C\u5230\u540E\u9762\u5B66\u4E60\u6253\u5370\u4E8C\u7EF4\u6570\u7EC4\u7B97\u6CD5\u83F1\u5F62\u7684\u6050\u614C\uFF0C\u518D\u5230\u540E\u9762\u5B66\u4E60Java Swing\u7684\u6709\u8DA3\uFF0C\u518D\u5230\u540E\u9762\u81EA\u5DF1\u5F00\u53D1\u51E0\u6B3E\u5C0F\u6E38\u620F\u3002
    \u8FD9\u5176\u4E2D\u6709\u82E6\u6709\u7D2F\uFF0C\u603B\u4E4B\u5C31\u662F\u5F88\u5B64\u72EC\uFF0C\u6211\u4ECE\u5B66\u6821\u642C\u5230\u4E86\u5916\u9762\u7684\u5C0F\u533A\uFF0C\u6BCF\u5929\u4ECE\u4E8B\u7740\u81EA\u5DF1\u559C\u6B22\u7684\u4E8B\u60C5\uFF0C\u4E00\u76F4\u52302018\u5E741\u67083\u53F7\uFF0C\u6B63\u5F0F\u5165\u804C\u3002\u662F\u4E00\u4E2A\u521D\u521B\u516C\u53F8\u7684\u540E\u7AEF\u4E3B\u8981\u8D1F\u8D23\u4EBA\u3002\u4E00\u5171\u6536\u52304\u4E2Aoffer\u3002\u6295\u4E8610\u591A\u5BB6\u3002

    \u8FD9\u662F\u8FD9\u4E00\u5E74\u6765\u6211\u770B\u7684\u4E00\u4E9B\u4E66\u7C4D\u3002

    \u521A\u5F00\u59CB\u7684\u5B66\u4E60\u5341\u5206\u76F2\u76EE\uFF0C\u4E0D\u77E5\u9053\u5982\u4F55\u53BB\u5B66\u4E60\uFF0C\u770B\u5230\u4E00\u4E2A\u4E1C\u897F\u89C9\u5F97\u6709\u8DA3\u5C31\u53BB\u7814\u7A76\uFF0C\u7ED3\u679C\u6700\u540E\u6CA1\u6709\u7CFB\u7EDF\u6027\u7684\u5B66\u4E60\uFF0C\u8FD8\u6D6A\u8D39\u4E86\u5927\u91CF\u7684\u65F6\u95F4\u3002

    \u73B0\u5728\u6211\u89C9\u5F97\u5982\u679C\u4F60\u8981\u5B66\u4E60Java\u6280\u672F\u53EF\u4EE5\u5148\u81EA\u5B66\u4E00\u6BB5\u65F6\u95F4\uFF0C\u770B\u81EA\u5DF1\u5408\u4E0D\u5408\u9002\uFF0C\u4F46\u662F\u4E00\u5B9A\u8981\u575A\u6301\uFF0C\u56E0\u4E3A\u65E2\u7136\u9009\u62E9\u4E86IT\uFF0C\u5C31\u8981\u517B\u6210\u7EC8\u751F\u5B66\u4E60\u7684\u4E60\u60EF\u3002\u4E0B\u9762\u662F\u6211\u89C9\u5F97\u4F60\u4F5C\u4E3A\u521D\u7EA7Java\u5DE5\u7A0B\u5E08\u5E94\u8BE5\u638C\u63E1\u7684\u6280\u672F\u3002

    1.Java SE\u90E8\u5206 \u521D\u7EA7\u8BED\u6CD5\uFF0C\u9762\u5411\u5BF9\u8C61\uFF0C\u5F02\u5E38\uFF0CIO\u6D41\uFF0C\u591A\u7EBF\u7A0B\uFF0CJava Swing\uFF0CJDBC\uFF0C\u6CDB\u578B\uFF0C\u6CE8\u89E3\uFF0C\u53CD\u5C04\u7B49\u3002

    2.\u6570\u636E\u5E93\u90E8\u5206\uFF0C\u57FA\u7840\u7684sql\u8BED\u53E5\uFF0Csql\u8BED\u53E5\u8C03\u4F18\uFF0C\u7D22\u5F15\uFF0C\u6570\u636E\u5E93\u5F15\u64CE\uFF0C\u5B58\u50A8\u8FC7\u7A0B\uFF0C\u89E6\u53D1\u5668\uFF0C\u4E8B\u52A1\u7B49\u3002

    3. \u524D\u7AEF\u90E8\u5206\uFF0C HTML5 CSS3 JS(\u548CJava\u4E00\u6837\u590D\u6742\uFF0C\u4F1A\u4F7F\u7528\u5C31\u884C)\uFF0C HTML DOM Jquery BootStrap\u7B49\u3002

    4. Java EE\u90E8\u5206\uFF0CTomcat\u548CNginx\u670D\u52A1\u5668\u642D\u5EFA\uFF0C\u914D\u7F6E\u6587\u4EF6\uFF0CServlet\uFF0CJSP\uFF0CFilter\uFF0CListener\uFF0Chttp\u534F\u8BAE\uFF0CMVC\u7B49\u3002

    5. \u6846\u67B6\u90E8\u5206\uFF0C\u6BCF\u4E2A\u6846\u67B6\u90FD\u53EF\u4EE5\u5206\u5F00\u5B66\uFF0C\u5728\u53BB\u5B66\u5982\u4F55\u4F7F\u7528SSM \u6216\u8005SSH\u6846\u67B6\uFF0C\u5982\u4F55\u642D\u5EFA\uFF0C\u5982\u4F55\u6574\u5408\u3002\u5F00\u53D1\u4E2D\u4E3A\u4EC0\u4E48\u4F1A\u7528\u6846\u67B6\uFF0CRest\u662F\u5565\uFF1FSpring\u4E3A\u5565\u7ECF\u4E45\u4E0D\u8870\uFF0C\u5E95\u5C42\u5982\u4F55\u5B9E\u73B0\u7B49\u3002

    6.23\u79CD\u8BBE\u8BA1\u6A21\u5F0F\uFF0C\u638C\u63E1\u5E38\u7528\u7684\uFF0C\u6BD4\u5982\u5355\u4F8B\u6A21\u5F0F\u7684\u591A\u79CD\u5B9E\u73B0\uFF0C\u8D23\u4EFB\u94FE\u6A21\u5F0F\uFF0C\u5DE5\u5382\u6A21\u5F0F\uFF0C\u88C5\u9970\u5668\u6A21\u5F0F\u7B49\uFF0C\u4E86\u89E3\u5E38\u7528\u573A\u666F\u3002

    7. \u57FA\u7840\u7B97\u6CD5\u548C\u6570\u636E\u7ED3\u6784\uFF0C\u516B\u5927\u6392\u5E8F\u7B97\u6CD5\uFF0C\u67E5\u627E\u7B97\u6CD5\u3002(\u9762\u8BD5\u4F1A\u95EE)

    8. (\u4E0D\u505A\u786C\u6027\u8981\u6C42) \u719F\u7EC3\u4F7F\u7528maven\u7B49\u6784\u5EFA\u5DE5\u5177\uFF0Cgit\u7B49\u7248\u672C\u63A7\u5236\u5DE5\u5177\uFF0C\u719F\u6089\u5E38\u7528linux\u547D\u4EE4\uFF0Clog4j\uFF0Cdubug\uFF0Cjunit\u5355\u5143\u6D4B\u8BD5\uFF0C\u65E5\u5FD7\u6253\u5370\u5DE5\u5177\uFF0CRedis\u7B49NoSql\u3002

    9\uFF0C\u4E5F\u662F\u6700\u91CD\u8981\u7684\u4E00\u6761\uFF0C\u5BF9\u5F85Java\u8981\u65F6\u523B\u5145\u6EE1\u6FC0\u60C5\uFF01

    \u592A\u665A\u4E86\uFF0C\u4ECA\u665A\u8BE5\u4F11\u606F\u4E86\uFF0C\u5168\u662F\u624B\u6253\u7684\u3002\u660E\u5929\u5728\u7EE7\u7EED\u7801\u5B57\u5427\u3002\u665A\u5B89\uFF0C\u5E0C\u671B\u5BF9\u4F60\u80FD\u591F\u6709\u6240\u5E2E\u52A9\uFF01


    \u6628\u5929\u665A\u4E0A\u53EB\u8F6E\u5B50\u54E5\u5E2E\u6211\u70B9\u8D5E,\u4E00\u89C9\u9192\u676550\u591A\u4E2A\u8D5E\u4E86\u300220\u591A\u6761\u8BC4\u8BBA\u3002\u770B\u6765\u5927V\u8FD8\u662F\u6709\u7528\u7684\u3002

    \u5176\u5B9E\u8FD9\u4E5F\u662F\u6211\u4E00\u76F4\u60F3\u8BF4\u7684\uFF0C\u5B66\u4E60Java\u4EE5\u6765\u6211\u5C31\u548C\u8F6E\u5B50\u54E5\u4FDD\u6301\u7740\u6C9F\u901A\uFF0C\u5E0C\u671B\u5411\u8F6E\u5B50\u54E5\u591A\u591A\u5B66\u4E60\uFF0C\u73B0\u5728\u4E5F\u7B97\u662F\u670B\u53CB\u4E86\u3002\u5B66\u4E60\u7684\u8FC7\u7A0B\u4E5F\u8BB8\u662F\u75DB\u82E6\u7684\uFF0C\u4F46\u662F\u8FC7\u7A0B\u4E2D\u8BA4\u8BC6\u7684\u670B\u53CB\u4EE5\u53CA\u7ED3\u679C\u90FD\u662F\u4EE4\u4EBA\u5F88\u5F00\u5FC3\u7684\u3002

    \u8BC4\u8BBA\u91CC\u9762\u6709\u8BF4\u63A8\u8350\u4E66\u7C4D\u7684\u3002\u8BF4\u5B9E\u8BDD\uFF0C\u56FD\u5185\u56FD\u5916\u7684\u4E66\u7C4D\u771F\u662F\u4E00\u5927\u5806\u3002\u4F46\u662F\u5F88\u7ECF\u5178\u7684\u4E5F\u5C31\u90A3\u4E48\u4E00\u4E9B\u3002\u5927\u5BB6\u90FD\u77E5\u9053\u3002


    2018\u5E7412\u67081\u65E5\uFF0C\u9996\u5148\u8C22\u8C22\u5927\u5BB6\u7684\u8D5E\u3002\u4E4B\u524D\u81EA\u79F0\u67B6\u6784\u5E08\u6709\u70B9\u513F\u5439\u725B\u5439\u5927\u4E86\u3002\u73B0\u5728\u8DF3\u69FD\u5230\u4E00\u5BB6\u4E2D\u578B\u516C\u53F8\u3002\u53D1\u73B0\u61C2\u5F97\u8D8A\u591A\u8D8A\u89C9\u5F97\u81EA\u5DF1\u65E0\u77E5\u3002\u5728\u6280\u672F\u8FD9\u7247\u6D69\u701A\u7684\u5B87\u5B99\u91CC\u9762\u7FF1\u7FD4\uFF0C\u6709\u5174\u8DA3\u4F1A\u89C9\u5F97\u8FD9\u662F\u4E00\u4EF6\u591A\u591A\u723D\u7684\u4E8B\u60C5\u3002\u5E0C\u671B\u5927\u5BB6\u80FD\u591F\u52AA\u529B\u5B66\u4E60\uFF0C\u7136\u540E\u627E\u5230\u4E00\u4EFD\u81EA\u5DF1\u6EE1\u610F\u7684\u5DE5\u4F5C\u3002\u4F60\u6211\u5171\u52C9


    2022\u5E74\u6211\u53C8\u6765\u66F4\u65B0\u4E86\uFF0C\u73B0\u5728\u5165\u804C\u963F\u91CC\u5DF4\u5DF4\u4E86\u3002\u5E0C\u671B\u5927\u5BB6\u52A0\u6CB9\u3002

    \u8FD9\u91CC\u8BF4\u8BF4\u6211\u5B66\u4E60Java\u7684\u4F7F\u7528\u7684\u51E0\u4E2A\u7F51\u7AD9\u5427:

    ',26),l={href:"https://link.zhihu.com/?target=http%3A//how2j.cn/%3Fp%3D17336",target:"_blank",rel:"noopener noreferrer"},_=t("How2J \u7684 Java\u6559\u7A0B"),d=t(" \uFF08\u6709\u5B8C\u6574\u7684\u6D41\u7A0B\u548C\u7AE0\u8282,\u6700\u4E3B\u8981\u90FD\u662F\u514D\u8D39\u7684\uFF09"),g={href:"https://link.zhihu.com/?target=https%3A//github.com/",target:"_blank",rel:"noopener noreferrer"},u=t("Build software better, together"),f=t("\uFF08\u53EF\u4EE5\u591A\u770B\u770B\u522B\u4EBA\u7684\u6E90\u7801\uFF09"),m={href:"https://link.zhihu.com/?target=https%3A//segmentfault.com/",target:"_blank",rel:"noopener noreferrer"},v=t("SegmentFault"),S=t("\uFF08\u6709\u4EFB\u4F55\u95EE\u9898\u53EF\u4EE5\u53BB\u4E0A\u9762\u63D0\u95EE\uFF09"),k={href:"https://link.zhihu.com/?target=https%3A//stackoverflow.com/",target:"_blank",rel:"noopener noreferrer"},b=t("Stack Overflow - Where Developers Learn, Share, & Build Careers"),J=t("\uFF08\u4F60\u7684\u5F88\u591A\u95EE\u9898\u90FD\u53EF\u4EE5\u5728\u4E0A\u9762\u627E\u5230\u7B54\u6848\uFF09"),w={href:"https://link.zhihu.com/?target=https%3A//www.csdn.net/",target:"_blank",rel:"noopener noreferrer"},z=t("CSDN-\u4E13\u4E1AIT\u6280\u672F\u793E\u533A"),x=t("\uFF08\u6709\u5F88\u591A\u4E66\u7C4D\uFF0C\u8F6F\u4EF6\u8D44\u6E90\uFF09"),H=e("ul",null,[e("li",null,"\u6211\u7684\u4E2A\u4EBA\u535A\u5BA2\u7F51\u7AD9")],-1),j={href:"https://link.zhihu.com/?target=https%3A//www.lanbandeng.com/",target:"_blank",rel:"noopener noreferrer"};function B(C,E){const o=n("ExternalLinkIcon");return p(),s("div",null,[i,e("p",null,[e("a",l,[_,a(o)]),d]),e("p",null,[e("a",g,[u,a(o)]),f]),e("p",null,[e("a",m,[v,a(o)]),S]),e("p",null,[e("a",k,[b,a(o)]),J]),e("p",null,[e("a",w,[z,a(o)]),x]),H,e("p",null,[e("a",j,[a(o)])])])}var A=r(h,[["render",B],["__file","ZHIHUjavaxuexidaoshemechengduokeyizhaodiyifengongzuo.html.vue"]]);export{A as default}; +import{_ as r}from"./plugin-vue_export-helper.21dcd24c.js";import{r as n,o as p,c as s,a as e,b as a,e as c,d as t}from"./app.615e41d8.js";const h={},i=c('

    \u73B0\u5728\u5F88\u665A\u4E86\uFF0C\u4F46\u662F\u770B\u5230\u8FD9\u4E2A\u95EE\u9898\u8FD8\u662F\u6BD4\u8F83\u6709\u611F\u89E6\u7684\u3002\u4E00\u5E74\u524D\uFF0C\u6211\u5927\u4E09\u4E0A\u5B66\u671F\uFF0C\u521B\u4E1A\u5931\u8D25\uFF0C\u60F3\u8F6C\u884C\u505A\u6280\u672F\u3002\u90A3\u65F6\u5019\u6211\u5BF9Java\u521A\u521A\u4E86\u89E3\u8FD9\u51E0\u4E2A\u82F1\u8BED\u5355\u8BCD\u3002 \u81EA\u5DF1\u4E70\u4E86\u672CJava\u4ECE\u5165\u95E8\u5230\u7CBE\u901A\u3002\u4EE5\u4E3A\u53EF\u4EE5\u5F88\u5FEB\u7684\u5B66\u5B8C\uFF0C\u975ECS\u4E13\u4E1A\u3002
    \u73B0\u5728\u6211\u60F3\u8BF4\u6240\u6709\u7CFB\u5217\u7684\u4ECE\u5165\u95E8\u5230\u7CBE\u901A\u90FD\u662F\u5783\u573E\uFF0C\u4E00\u5E74\u591A\u6765\uFF0C\u6211\u6BCF\u5929\u767D\u5929\u770B\u89C6\u9891\uFF0C\u665A\u4E0A\u6572\u4EE3\u7801\u5230\u51CC\u6668\uFF0C\u6211\u662F\u4E00\u4E2A\u5F88\u5014\u7684\u4EBA\uFF0C\u6211\u8BA4\u4E3A\u5929\u4E0B\u6CA1\u6709\u4EFB\u4F55\u4E1C\u897F\u662F\u4EBA\u7C7B\u5B66\u4E0D\u4F1A\u7684\uFF0C\u6240\u4EE5\u6211\u5C31\u4ED8\u51FA\u9AD8\u4E09\u4E00\u6837\u7684\u65F6\u95F4\u53BB\u5B66\u4E60\u3002\u6700\u5F00\u59CB\u5B66\u4E60Java SE\uFF0C\u770B\u7740\u63A7\u5236\u53F0\u6253\u5370\u51FA\u7B2C\u4E00\u884CHello world\u7684\u6B23\u559C\uFF0C\u5230\u540E\u9762\u5B66\u4E60\u6253\u5370\u4E8C\u7EF4\u6570\u7EC4\u7B97\u6CD5\u83F1\u5F62\u7684\u6050\u614C\uFF0C\u518D\u5230\u540E\u9762\u5B66\u4E60Java Swing\u7684\u6709\u8DA3\uFF0C\u518D\u5230\u540E\u9762\u81EA\u5DF1\u5F00\u53D1\u51E0\u6B3E\u5C0F\u6E38\u620F\u3002
    \u8FD9\u5176\u4E2D\u6709\u82E6\u6709\u7D2F\uFF0C\u603B\u4E4B\u5C31\u662F\u5F88\u5B64\u72EC\uFF0C\u6211\u4ECE\u5B66\u6821\u642C\u5230\u4E86\u5916\u9762\u7684\u5C0F\u533A\uFF0C\u6BCF\u5929\u4ECE\u4E8B\u7740\u81EA\u5DF1\u559C\u6B22\u7684\u4E8B\u60C5\uFF0C\u4E00\u76F4\u52302018\u5E741\u67083\u53F7\uFF0C\u6B63\u5F0F\u5165\u804C\u3002\u662F\u4E00\u4E2A\u521D\u521B\u516C\u53F8\u7684\u540E\u7AEF\u4E3B\u8981\u8D1F\u8D23\u4EBA\u3002\u4E00\u5171\u6536\u52304\u4E2Aoffer\u3002\u6295\u4E8610\u591A\u5BB6\u3002

    \u8FD9\u662F\u8FD9\u4E00\u5E74\u6765\u6211\u770B\u7684\u4E00\u4E9B\u4E66\u7C4D\u3002

    \u521A\u5F00\u59CB\u7684\u5B66\u4E60\u5341\u5206\u76F2\u76EE\uFF0C\u4E0D\u77E5\u9053\u5982\u4F55\u53BB\u5B66\u4E60\uFF0C\u770B\u5230\u4E00\u4E2A\u4E1C\u897F\u89C9\u5F97\u6709\u8DA3\u5C31\u53BB\u7814\u7A76\uFF0C\u7ED3\u679C\u6700\u540E\u6CA1\u6709\u7CFB\u7EDF\u6027\u7684\u5B66\u4E60\uFF0C\u8FD8\u6D6A\u8D39\u4E86\u5927\u91CF\u7684\u65F6\u95F4\u3002

    \u73B0\u5728\u6211\u89C9\u5F97\u5982\u679C\u4F60\u8981\u5B66\u4E60Java\u6280\u672F\u53EF\u4EE5\u5148\u81EA\u5B66\u4E00\u6BB5\u65F6\u95F4\uFF0C\u770B\u81EA\u5DF1\u5408\u4E0D\u5408\u9002\uFF0C\u4F46\u662F\u4E00\u5B9A\u8981\u575A\u6301\uFF0C\u56E0\u4E3A\u65E2\u7136\u9009\u62E9\u4E86IT\uFF0C\u5C31\u8981\u517B\u6210\u7EC8\u751F\u5B66\u4E60\u7684\u4E60\u60EF\u3002\u4E0B\u9762\u662F\u6211\u89C9\u5F97\u4F60\u4F5C\u4E3A\u521D\u7EA7Java\u5DE5\u7A0B\u5E08\u5E94\u8BE5\u638C\u63E1\u7684\u6280\u672F\u3002

    1.Java SE\u90E8\u5206 \u521D\u7EA7\u8BED\u6CD5\uFF0C\u9762\u5411\u5BF9\u8C61\uFF0C\u5F02\u5E38\uFF0CIO\u6D41\uFF0C\u591A\u7EBF\u7A0B\uFF0CJava Swing\uFF0CJDBC\uFF0C\u6CDB\u578B\uFF0C\u6CE8\u89E3\uFF0C\u53CD\u5C04\u7B49\u3002

    2.\u6570\u636E\u5E93\u90E8\u5206\uFF0C\u57FA\u7840\u7684sql\u8BED\u53E5\uFF0Csql\u8BED\u53E5\u8C03\u4F18\uFF0C\u7D22\u5F15\uFF0C\u6570\u636E\u5E93\u5F15\u64CE\uFF0C\u5B58\u50A8\u8FC7\u7A0B\uFF0C\u89E6\u53D1\u5668\uFF0C\u4E8B\u52A1\u7B49\u3002

    3. \u524D\u7AEF\u90E8\u5206\uFF0C HTML5 CSS3 JS(\u548CJava\u4E00\u6837\u590D\u6742\uFF0C\u4F1A\u4F7F\u7528\u5C31\u884C)\uFF0C HTML DOM Jquery BootStrap\u7B49\u3002

    4. Java EE\u90E8\u5206\uFF0CTomcat\u548CNginx\u670D\u52A1\u5668\u642D\u5EFA\uFF0C\u914D\u7F6E\u6587\u4EF6\uFF0CServlet\uFF0CJSP\uFF0CFilter\uFF0CListener\uFF0Chttp\u534F\u8BAE\uFF0CMVC\u7B49\u3002

    5. \u6846\u67B6\u90E8\u5206\uFF0C\u6BCF\u4E2A\u6846\u67B6\u90FD\u53EF\u4EE5\u5206\u5F00\u5B66\uFF0C\u5728\u53BB\u5B66\u5982\u4F55\u4F7F\u7528SSM \u6216\u8005SSH\u6846\u67B6\uFF0C\u5982\u4F55\u642D\u5EFA\uFF0C\u5982\u4F55\u6574\u5408\u3002\u5F00\u53D1\u4E2D\u4E3A\u4EC0\u4E48\u4F1A\u7528\u6846\u67B6\uFF0CRest\u662F\u5565\uFF1FSpring\u4E3A\u5565\u7ECF\u4E45\u4E0D\u8870\uFF0C\u5E95\u5C42\u5982\u4F55\u5B9E\u73B0\u7B49\u3002

    6.23\u79CD\u8BBE\u8BA1\u6A21\u5F0F\uFF0C\u638C\u63E1\u5E38\u7528\u7684\uFF0C\u6BD4\u5982\u5355\u4F8B\u6A21\u5F0F\u7684\u591A\u79CD\u5B9E\u73B0\uFF0C\u8D23\u4EFB\u94FE\u6A21\u5F0F\uFF0C\u5DE5\u5382\u6A21\u5F0F\uFF0C\u88C5\u9970\u5668\u6A21\u5F0F\u7B49\uFF0C\u4E86\u89E3\u5E38\u7528\u573A\u666F\u3002

    7. \u57FA\u7840\u7B97\u6CD5\u548C\u6570\u636E\u7ED3\u6784\uFF0C\u516B\u5927\u6392\u5E8F\u7B97\u6CD5\uFF0C\u67E5\u627E\u7B97\u6CD5\u3002(\u9762\u8BD5\u4F1A\u95EE)

    8. (\u4E0D\u505A\u786C\u6027\u8981\u6C42) \u719F\u7EC3\u4F7F\u7528maven\u7B49\u6784\u5EFA\u5DE5\u5177\uFF0Cgit\u7B49\u7248\u672C\u63A7\u5236\u5DE5\u5177\uFF0C\u719F\u6089\u5E38\u7528linux\u547D\u4EE4\uFF0Clog4j\uFF0Cdubug\uFF0Cjunit\u5355\u5143\u6D4B\u8BD5\uFF0C\u65E5\u5FD7\u6253\u5370\u5DE5\u5177\uFF0CRedis\u7B49NoSql\u3002

    9\uFF0C\u4E5F\u662F\u6700\u91CD\u8981\u7684\u4E00\u6761\uFF0C\u5BF9\u5F85Java\u8981\u65F6\u523B\u5145\u6EE1\u6FC0\u60C5\uFF01

    \u592A\u665A\u4E86\uFF0C\u4ECA\u665A\u8BE5\u4F11\u606F\u4E86\uFF0C\u5168\u662F\u624B\u6253\u7684\u3002\u660E\u5929\u5728\u7EE7\u7EED\u7801\u5B57\u5427\u3002\u665A\u5B89\uFF0C\u5E0C\u671B\u5BF9\u4F60\u80FD\u591F\u6709\u6240\u5E2E\u52A9\uFF01


    \u6628\u5929\u665A\u4E0A\u53EB\u8F6E\u5B50\u54E5\u5E2E\u6211\u70B9\u8D5E,\u4E00\u89C9\u9192\u676550\u591A\u4E2A\u8D5E\u4E86\u300220\u591A\u6761\u8BC4\u8BBA\u3002\u770B\u6765\u5927V\u8FD8\u662F\u6709\u7528\u7684\u3002

    \u5176\u5B9E\u8FD9\u4E5F\u662F\u6211\u4E00\u76F4\u60F3\u8BF4\u7684\uFF0C\u5B66\u4E60Java\u4EE5\u6765\u6211\u5C31\u548C\u8F6E\u5B50\u54E5\u4FDD\u6301\u7740\u6C9F\u901A\uFF0C\u5E0C\u671B\u5411\u8F6E\u5B50\u54E5\u591A\u591A\u5B66\u4E60\uFF0C\u73B0\u5728\u4E5F\u7B97\u662F\u670B\u53CB\u4E86\u3002\u5B66\u4E60\u7684\u8FC7\u7A0B\u4E5F\u8BB8\u662F\u75DB\u82E6\u7684\uFF0C\u4F46\u662F\u8FC7\u7A0B\u4E2D\u8BA4\u8BC6\u7684\u670B\u53CB\u4EE5\u53CA\u7ED3\u679C\u90FD\u662F\u4EE4\u4EBA\u5F88\u5F00\u5FC3\u7684\u3002

    \u8BC4\u8BBA\u91CC\u9762\u6709\u8BF4\u63A8\u8350\u4E66\u7C4D\u7684\u3002\u8BF4\u5B9E\u8BDD\uFF0C\u56FD\u5185\u56FD\u5916\u7684\u4E66\u7C4D\u771F\u662F\u4E00\u5927\u5806\u3002\u4F46\u662F\u5F88\u7ECF\u5178\u7684\u4E5F\u5C31\u90A3\u4E48\u4E00\u4E9B\u3002\u5927\u5BB6\u90FD\u77E5\u9053\u3002


    2018\u5E7412\u67081\u65E5\uFF0C\u9996\u5148\u8C22\u8C22\u5927\u5BB6\u7684\u8D5E\u3002\u4E4B\u524D\u81EA\u79F0\u67B6\u6784\u5E08\u6709\u70B9\u513F\u5439\u725B\u5439\u5927\u4E86\u3002\u73B0\u5728\u8DF3\u69FD\u5230\u4E00\u5BB6\u4E2D\u578B\u516C\u53F8\u3002\u53D1\u73B0\u61C2\u5F97\u8D8A\u591A\u8D8A\u89C9\u5F97\u81EA\u5DF1\u65E0\u77E5\u3002\u5728\u6280\u672F\u8FD9\u7247\u6D69\u701A\u7684\u5B87\u5B99\u91CC\u9762\u7FF1\u7FD4\uFF0C\u6709\u5174\u8DA3\u4F1A\u89C9\u5F97\u8FD9\u662F\u4E00\u4EF6\u591A\u591A\u723D\u7684\u4E8B\u60C5\u3002\u5E0C\u671B\u5927\u5BB6\u80FD\u591F\u52AA\u529B\u5B66\u4E60\uFF0C\u7136\u540E\u627E\u5230\u4E00\u4EFD\u81EA\u5DF1\u6EE1\u610F\u7684\u5DE5\u4F5C\u3002\u4F60\u6211\u5171\u52C9


    2022\u5E74\u6211\u53C8\u6765\u66F4\u65B0\u4E86\uFF0C\u73B0\u5728\u5165\u804C\u963F\u91CC\u5DF4\u5DF4\u4E86\u3002\u5E0C\u671B\u5927\u5BB6\u52A0\u6CB9\u3002

    \u8FD9\u91CC\u8BF4\u8BF4\u6211\u5B66\u4E60Java\u7684\u4F7F\u7528\u7684\u51E0\u4E2A\u7F51\u7AD9\u5427:

    ',26),l={href:"https://link.zhihu.com/?target=http%3A//how2j.cn/%3Fp%3D17336",target:"_blank",rel:"noopener noreferrer"},_=t("How2J \u7684 Java\u6559\u7A0B"),d=t(" \uFF08\u6709\u5B8C\u6574\u7684\u6D41\u7A0B\u548C\u7AE0\u8282,\u6700\u4E3B\u8981\u90FD\u662F\u514D\u8D39\u7684\uFF09"),g={href:"https://link.zhihu.com/?target=https%3A//github.com/",target:"_blank",rel:"noopener noreferrer"},u=t("Build software better, together"),f=t("\uFF08\u53EF\u4EE5\u591A\u770B\u770B\u522B\u4EBA\u7684\u6E90\u7801\uFF09"),m={href:"https://link.zhihu.com/?target=https%3A//segmentfault.com/",target:"_blank",rel:"noopener noreferrer"},v=t("SegmentFault"),S=t("\uFF08\u6709\u4EFB\u4F55\u95EE\u9898\u53EF\u4EE5\u53BB\u4E0A\u9762\u63D0\u95EE\uFF09"),k={href:"https://link.zhihu.com/?target=https%3A//stackoverflow.com/",target:"_blank",rel:"noopener noreferrer"},b=t("Stack Overflow - Where Developers Learn, Share, & Build Careers"),J=t("\uFF08\u4F60\u7684\u5F88\u591A\u95EE\u9898\u90FD\u53EF\u4EE5\u5728\u4E0A\u9762\u627E\u5230\u7B54\u6848\uFF09"),w={href:"https://link.zhihu.com/?target=https%3A//www.csdn.net/",target:"_blank",rel:"noopener noreferrer"},z=t("CSDN-\u4E13\u4E1AIT\u6280\u672F\u793E\u533A"),x=t("\uFF08\u6709\u5F88\u591A\u4E66\u7C4D\uFF0C\u8F6F\u4EF6\u8D44\u6E90\uFF09"),H=e("ul",null,[e("li",null,"\u6211\u7684\u4E2A\u4EBA\u535A\u5BA2\u7F51\u7AD9")],-1),j={href:"https://link.zhihu.com/?target=https%3A//www.lanbandeng.com/",target:"_blank",rel:"noopener noreferrer"};function B(C,E){const o=n("ExternalLinkIcon");return p(),s("div",null,[i,e("p",null,[e("a",l,[_,a(o)]),d]),e("p",null,[e("a",g,[u,a(o)]),f]),e("p",null,[e("a",m,[v,a(o)]),S]),e("p",null,[e("a",k,[b,a(o)]),J]),e("p",null,[e("a",w,[z,a(o)]),x]),H,e("p",null,[e("a",j,[a(o)])])])}var A=r(h,[["render",B],["__file","ZHIHUjavaxuexidaoshemechengduokeyizhaodiyifengongzuo.html.vue"]]);export{A as default}; diff --git a/dist/assets/abstract.html.60b3966f.js b/dist/assets/abstract.html.e17df797.js similarity index 99% rename from dist/assets/abstract.html.60b3966f.js rename to dist/assets/abstract.html.e17df797.js index 234cb898..fb21306c 100644 --- a/dist/assets/abstract.html.60b3966f.js +++ b/dist/assets/abstract.html.e17df797.js @@ -1,4 +1,4 @@ -import{_ as n}from"./plugin-vue_export-helper.21dcd24c.js";import{o as s,c as a,e}from"./app.a0271b9c.js";const p={},t=e(`

    Java\u62BD\u8C61\u7C7B

    \u201C\u4E8C\u54E5\uFF0C\u4F60\u8FD9\u660E\u663E\u52A0\u5FEB\u4E86\u66F4\u65B0\u7684\u9891\u7387\u5440\uFF01\u201D\u4E09\u59B9\u5BF9\u4E8E\u6211\u6700\u8FD1\u7684\u809D\u52B2\u7531\u8877\u7684\u4F69\u670D\u4E86\u8D77\u6765\u3002

    \u201C\u54C8\u54C8\uFF0C\u662F\u5440\uFF0C\u8FD9\u6B21\u4E0D\u80FD\u518D\u65AD\u66F4\u4E86\uFF0C\u6211\u8981\u518D\u66F4 175 \u7BC7\uFF0C\u603B\u8BA1 200 \u7BC7\uFF0C\u7ED9\u5E7F\u5927\u7684\u5B66\u5F1F\u5B66\u59B9\u4EEC\u4E00\u4E2A\u5B8C\u6574\u7684 Java \u5B66\u4E60\u4F53\u7CFB\u3002\u201D\u6211\u5BF9\u672A\u6765\u5145\u6EE1\u4E86\u4FE1\u5FC3\u3002

    \u201C\u90A3\u5C31\u5F00\u59CB\u5427\u3002\u201D\u4E09\u59B9\u8BF4\u3002


    \u5B9A\u4E49\u62BD\u8C61\u7C7B\u7684\u65F6\u5019\u9700\u8981\u7528\u5230\u5173\u952E\u5B57 abstract\uFF0C\u653E\u5728 class \u5173\u952E\u5B57\u524D\uFF0C\u5C31\u50CF\u4E0B\u9762\u8FD9\u6837\u3002

    abstract class AbstractPlayer {
    +import{_ as n}from"./plugin-vue_export-helper.21dcd24c.js";import{o as s,c as a,e}from"./app.615e41d8.js";const p={},t=e(`

    Java\u62BD\u8C61\u7C7B

    \u201C\u4E8C\u54E5\uFF0C\u4F60\u8FD9\u660E\u663E\u52A0\u5FEB\u4E86\u66F4\u65B0\u7684\u9891\u7387\u5440\uFF01\u201D\u4E09\u59B9\u5BF9\u4E8E\u6211\u6700\u8FD1\u7684\u809D\u52B2\u7531\u8877\u7684\u4F69\u670D\u4E86\u8D77\u6765\u3002

    \u201C\u54C8\u54C8\uFF0C\u662F\u5440\uFF0C\u8FD9\u6B21\u4E0D\u80FD\u518D\u65AD\u66F4\u4E86\uFF0C\u6211\u8981\u518D\u66F4 175 \u7BC7\uFF0C\u603B\u8BA1 200 \u7BC7\uFF0C\u7ED9\u5E7F\u5927\u7684\u5B66\u5F1F\u5B66\u59B9\u4EEC\u4E00\u4E2A\u5B8C\u6574\u7684 Java \u5B66\u4E60\u4F53\u7CFB\u3002\u201D\u6211\u5BF9\u672A\u6765\u5145\u6EE1\u4E86\u4FE1\u5FC3\u3002

    \u201C\u90A3\u5C31\u5F00\u59CB\u5427\u3002\u201D\u4E09\u59B9\u8BF4\u3002


    \u5B9A\u4E49\u62BD\u8C61\u7C7B\u7684\u65F6\u5019\u9700\u8981\u7528\u5230\u5173\u952E\u5B57 abstract\uFF0C\u653E\u5728 class \u5173\u952E\u5B57\u524D\uFF0C\u5C31\u50CF\u4E0B\u9762\u8FD9\u6837\u3002

    abstract class AbstractPlayer {
     }
     

    \u5173\u4E8E\u62BD\u8C61\u7C7B\u7684\u547D\u540D\uFF0C\u300A\u963F\u91CC\u7684 Java \u5F00\u53D1\u624B\u518C\u300B\u4E0A\u6709\u5F3A\u8C03\uFF0C\u201C\u62BD\u8C61\u7C7B\u547D\u540D\u8981\u4F7F\u7528 Abstract \u6216 Base \u5F00\u5934\u201D\uFF0C\u8FD9\u6761\u89C4\u7EA6\u8FD8\u662F\u503C\u5F97\u9075\u5B88\u7684\u3002

    \u62BD\u8C61\u7C7B\u662F\u4E0D\u80FD\u5B9E\u4F8B\u5316\u7684\uFF0C\u5C1D\u8BD5\u901A\u8FC7 new \u5173\u952E\u5B57\u5B9E\u4F8B\u5316\u7684\u8BDD\uFF0C\u7F16\u8BD1\u5668\u4F1A\u62A5\u9519\uFF0C\u63D0\u793A\u201C\u7C7B\u662F\u62BD\u8C61\u7684\uFF0C\u4E0D\u80FD\u5B9E\u4F8B\u5316\u201D\u3002

    \u867D\u7136\u62BD\u8C61\u7C7B\u4E0D\u80FD\u5B9E\u4F8B\u5316\uFF0C\u4F46\u53EF\u4EE5\u6709\u5B50\u7C7B\u3002\u5B50\u7C7B\u901A\u8FC7 extends \u5173\u952E\u5B57\u6765\u7EE7\u627F\u62BD\u8C61\u7C7B\u3002\u5C31\u50CF\u4E0B\u9762\u8FD9\u6837\u3002

    public class BasketballPlayer extends AbstractPlayer {
     }
    diff --git a/dist/assets/algorithm.html.66d3e273.js b/dist/assets/algorithm.html.8d44122f.js
    similarity index 99%
    rename from dist/assets/algorithm.html.66d3e273.js
    rename to dist/assets/algorithm.html.8d44122f.js
    index 6857a71f..b2dfb570 100644
    --- a/dist/assets/algorithm.html.66d3e273.js
    +++ b/dist/assets/algorithm.html.8d44122f.js
    @@ -1,4 +1,4 @@
    -import{_ as i}from"./plugin-vue_export-helper.21dcd24c.js";import{r,o as s,c as l,a as e,b as o,d as t,e as n}from"./app.a0271b9c.js";const p={},c=e("h1",{id:"\u7B97\u6CD5\u548C\u6570\u636E\u7ED3\u6784\u5B66\u4E60\u8DEF\u7EBF-\u5EFA\u8BAE\u6536\u85CF",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#\u7B97\u6CD5\u548C\u6570\u636E\u7ED3\u6784\u5B66\u4E60\u8DEF\u7EBF-\u5EFA\u8BAE\u6536\u85CF","aria-hidden":"true"},"#"),t(" \u7B97\u6CD5\u548C\u6570\u636E\u7ED3\u6784\u5B66\u4E60\u8DEF\u7EBF\uFF08\u5EFA\u8BAE\u6536\u85CF\u{1F44D}\uFF09")],-1),d=e("p",null,"\u8BF4\u51FA\u6765\u8FD8\u771F\u6709\u70B9\u4E0D\u597D\u610F\u601D\u3002\u4E0A\u5B66\u90A3\u65F6\u5019\u50BB\uFF0C\u4E3A\u4E86\u6821\u62DB\uFF0C\u786C\u7740\u5934\u76AE\u5237\u300A\u7B97\u6CD5\u5BFC\u8BBA\u300B\u3001\u300A\u7F16\u7A0B\u73E0\u7391\u300B\uFF0C\u8FD8\u6709 LeetCode\uFF0C\u5237\u4E86\u5C0F\u4E00\u5E74\u3002",-1),h=e("p",null,"\u5237\u7740\u5FD8\u7740\uFF0C\u5FD8\u7740\u5237\u7740\uFF0C\u4E0D\u5237\u6015\u8003\u5230\uFF0C\u6700\u540E\u5237\u7684\u79C0\u53D1\u90FD\u7A00\u758F\u4E86\u3002",-1),_=t("\u7B49\u627E\u5230\u4E86\u5DE5\u4F5C\u540E\u624D\u604D\u7136\u5927\u609F\uFF0C\u539F\u6765\u5F53\u521D\u6839\u672C\u4E0D\u7528\u90A3\u4E48\u8F9B\u82E6\u3002\u8FD9\u4E0D\uFF0C\u521A\u597D\u6709\u5C0F\u4F19\u4F34\u5728\u300A"),b={href:"https://tobebetterjavaer.com/",target:"_blank",rel:"noopener noreferrer"},u=t("Java \u7A0B\u5E8F\u5458\u8FDB\u9636\u4E4B\u8DEF"),g=t("\u300B\u4E0A\u95EE\u6211\u7B97\u6CD5\u7684\u5B66\u4E60\u8DEF\u7EBF\uFF0C\u6211\u5C31\u6BEB\u4E0D\u4FDD\u7559\u5730\u628A\u6211\u7B97\u6CD5\u65B9\u9762\u7684\u5B66\u4E60\u7ECF\u9A8C\u5206\u4EAB\u51FA\u6765\uFF0C\u5E0C\u671B\u80FD\u7ED9\u5927\u5BB6\u4E00\u70B9\u70B9\u542F\u53D1\u548C\u5E2E\u52A9\u3002"),m=n(`

    \u6211\u753B\u4E86\u4E00\u5F20\u56FE\uFF0C\u91CC\u9762\u51E0\u4E4E\u6DB5\u76D6\u4E86\u6240\u6709\u6570\u636E\u7ED3\u6784\u4E0E\u7B97\u6CD5\u4E66\u7C4D\u4E2D\u90FD\u4F1A\u8BB2\u5230\u7684\u77E5\u8BC6\u70B9\u3002

    \u4F46\u8BB2\u826F\u5FC3\u8BDD\uFF0C\u5BF9\u4E8E\u4E00\u4E2A\u521D\u5B66\u8005\uFF0C\u6216\u8005\u4E0D\u6253\u7B97\u5377\u7B97\u6CD5\u5C97\u7684\u7A0B\u5E8F\u5458\u6765\u8BF4\uFF0C\u5B8C\u5168\u5C31\u6CA1\u5FC5\u8981\u628A\u601D\u7EF4\u5BFC\u56FE\u91CC\u9762\u7684\u6240\u6709\u77E5\u8BC6\u70B9\u90FD\u5B66\u4E86\uFF0C\u90A3\u6837\u5C31\u592A\u4E0D\u9AD8\u6548\u4E86\u3002

    \u6211\u4EEC\u5B66\u4E60\u6570\u636E\u7ED3\u6784\u4E0E\u7B97\u6CD5\uFF0C\u4E5F\u5F97\u8BB2\u7A76\u7B56\u7565\u3002\u6211\u7684\u5EFA\u8BAE\u662F\u8FD9\u6837\u7684\uFF08\u6572\u9ED1\u677F\u3001\u5212\u91CD\u70B9\u4E86\u554A\uFF09\uFF1A

    7 \u4E2A\u6570\u636E\u7ED3\u6784\uFF1A

    • \u6570\u7EC4
    • \u94FE\u8868
    • \u6808
    • \u961F\u5217
    • \u54C8\u5E0C\u8868
    • \u4E8C\u53C9\u6811
    • \u5806

    10 \u4E2A\u7B97\u6CD5\uFF1A

    • \u9012\u5F52
    • \u6392\u5E8F
    • \u4E8C\u5206\u67E5\u627E
    • \u641C\u7D22
    • \u54C8\u5E0C\u7B97\u6CD5
    • \u8D2A\u5FC3\u7B97\u6CD5
    • \u5206\u6CBB\u7B97\u6CD5
    • \u56DE\u6EAF\u7B97\u6CD5
    • \u52A8\u6001\u89C4\u5212
    • \u5B57\u7B26\u4E32\u5339\u914D\u7B97\u6CD5

    \u8FD9\u4E9B\u662F\u5B66\u4E60\u6570\u636E\u7ED3\u6784\u4E0E\u7B97\u6CD5\u65F6\u7684\u91CD\u70B9\u3002\u5F88\u591A\u4EBA\u5728\u7B2C\u4E00\u6B21\u63A5\u89E6\u6570\u636E\u7ED3\u6784\u4E0E\u7B97\u6CD5\u8FD9\u95E8\u8BFE\u65F6\uFF0C\u5F80\u5F80\u4F1A\u89C9\u5F97\u5F88\u62BD\u8C61\uFF0C\u5F88\u96BE\u641E\u61C2\uFF0C\u4EE5\u81F3\u4E8E\u7AD9\u5728\u95E8\u5916\u5F98\u5F8A\u4E0D\u524D\u3002

    \u5176\u5B9E\u771F\u6B63\u7684\u539F\u56E0\u662F\u6CA1\u6709\u627E\u5230\u597D\u7684\u5B66\u4E60\u65B9\u6CD5\uFF0C\u6CA1\u6709\u6293\u4F4F\u5B66\u4E60\u7684\u91CD\u70B9\u3002\u76F8\u4FE1\u4F60\u8BA4\u771F\u770B\u5B8C\u6211\u8FD9\u6761\u5B66\u4E60\u8DEF\u7EBF\u540E\uFF0C\u5B66\u8D77\u6765\u5C31\u4F1A\u6709\u7684\u653E\u77E2\u3001\u4E8B\u534A\u529F\u500D\u4E86\u3002

    \u4E00\u3001\u4EC0\u4E48\u662F\u6570\u636E\u7ED3\u6784

    \u6570\u636E\u7ED3\u6784\u662F\u4E00\u79CD\u5177\u6709\u4E00\u5B9A\u903B\u8F91\u5173\u7CFB\uFF0C\u5728\u8BA1\u7B97\u673A\u4E2D\u5E94\u7528\u67D0\u79CD\u5B58\u50A8\u7ED3\u6784\uFF0C\u5E76\u4E14\u5C01\u88C5\u4E86\u76F8\u5E94\u64CD\u4F5C\u7684\u6570\u636E\u5143\u7D20\u96C6\u5408\u3002\u5B83\u5305\u542B\u4E09\u65B9\u9762\u7684\u5185\u5BB9\uFF0C\u903B\u8F91\u5173\u7CFB\u3001\u5B58\u50A8\u5173\u7CFB\u53CA\u64CD\u4F5C\u3002\u4E0D\u540C\u79CD\u7C7B\u7684\u6570\u636E\u7ED3\u6784\u9002\u5408\u4E8E\u4E0D\u540C\u79CD\u7C7B\u7684\u5E94\u7528\uFF0C\u800C\u90E8\u5206\u751A\u81F3\u4E13\u95E8\u7528\u4E8E\u7279\u5B9A\u7684\u4F5C\u4E1A\u4EFB\u52A1\u3002\u4F8B\u5982\uFF0C\u8BA1\u7B97\u673A\u7F51\u7EDC\u4F9D\u8D56\u4E8E\u8DEF\u7531\u8868\u8FD0\u4F5C\uFF0CB \u6811\u9AD8\u5EA6\u9002\u7528\u4E8E\u6570\u636E\u5E93\u7684\u5C01\u88C5\u3002

    \u7B80\u5355\u70B9\u8BF4\uFF0C\u6570\u636E\u7ED3\u6784\u5C31\u662F\u628A\u4E00\u5806\u6570\u636E\uFF0C\u6309\u7167\u67D0\u79CD\u683C\u5F0F\u63C9\u6210\u4E00\u5768\u3002

    \u5927\u5BB6\u559C\u6B22\u5403\u5BAB\u4FDD\u9E21\u4E01\u5417\uFF1F

    \u53CD\u6B63\u4E8C\u54E5\u633A\u559C\u6B22\u8FD9\u9053\u83DC\u7684\u3002\u6211\u5C31\u4EE5\u5BAB\u4FDD\u9E21\u4E01\u4E3A\u4F8B\uFF0C\u6765\u8BB2\u4E00\u8BB2\u6570\u636E\u7ED3\u6784\u5427\u3002\u7EF4\u57FA\u767E\u79D1\u4E0A\u662F\u8FD9\u6837\u5B9A\u4E49\u7684\u3002

    \u5BAB\u4FDD\u9E21\u4E01\uFF08\u82F1\u8BED\uFF1AKung Pao chicken\u6216Kung-Pao Chicken\uFF09\uFF0C\u53C8\u79F0\u5BAB\u7206\u9E21\u4E01\uFF0C\u5448\u7CCA\u8FA3\u8354\u679D\u5473\uFF0C\u6E90\u4E8E\u9ED4\u83DC\u3001\u6D41\u4F20\u81F3\u9C81\u800C\u540E\u6210\u4E8E\u5DDD\u83DC\u7684\u4E00\u9053\u5DDD\u5473\u540D\u83DC\u3002\u8D35\u5DDE\u3001\u5C71\u4E1C\u548C\u56DB\u5DDD\u4E09\u5730\u5BF9\u8FD9\u9053\u83DC\u7684\u505A\u6CD5\u4E0D\u5B8C\u5168\u4E00\u6837\uFF0C\u79F0\u547C\u4E5F\u6709\u5DEE\u5F02\u3002\u8D35\u5DDE\u79F0\u4E3A\u7CCA\u8FA3\u5B50\u9E21\u4E01\uFF0C\u5C71\u4E1C\u5219\u540D\u4E3A\u9171\u7206\u9E21\u4E01\uFF0C\u800C\u56DB\u5DDD\u662F\u4EE5\u5BAB\u4FDD\u9E21\u4E01\u4E3A\u540D\u7684\u3002

    \u6765\uFF0C\u62BD\u8C61\u4E0B\u5BAB\u4FDD\u9E21\u4E01\u3002

    struct KungPaoChicken {
    +import{_ as i}from"./plugin-vue_export-helper.21dcd24c.js";import{r,o as s,c as l,a as e,b as o,d as t,e as n}from"./app.615e41d8.js";const p={},c=e("h1",{id:"\u7B97\u6CD5\u548C\u6570\u636E\u7ED3\u6784\u5B66\u4E60\u8DEF\u7EBF-\u5EFA\u8BAE\u6536\u85CF",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#\u7B97\u6CD5\u548C\u6570\u636E\u7ED3\u6784\u5B66\u4E60\u8DEF\u7EBF-\u5EFA\u8BAE\u6536\u85CF","aria-hidden":"true"},"#"),t(" \u7B97\u6CD5\u548C\u6570\u636E\u7ED3\u6784\u5B66\u4E60\u8DEF\u7EBF\uFF08\u5EFA\u8BAE\u6536\u85CF\u{1F44D}\uFF09")],-1),d=e("p",null,"\u8BF4\u51FA\u6765\u8FD8\u771F\u6709\u70B9\u4E0D\u597D\u610F\u601D\u3002\u4E0A\u5B66\u90A3\u65F6\u5019\u50BB\uFF0C\u4E3A\u4E86\u6821\u62DB\uFF0C\u786C\u7740\u5934\u76AE\u5237\u300A\u7B97\u6CD5\u5BFC\u8BBA\u300B\u3001\u300A\u7F16\u7A0B\u73E0\u7391\u300B\uFF0C\u8FD8\u6709 LeetCode\uFF0C\u5237\u4E86\u5C0F\u4E00\u5E74\u3002",-1),h=e("p",null,"\u5237\u7740\u5FD8\u7740\uFF0C\u5FD8\u7740\u5237\u7740\uFF0C\u4E0D\u5237\u6015\u8003\u5230\uFF0C\u6700\u540E\u5237\u7684\u79C0\u53D1\u90FD\u7A00\u758F\u4E86\u3002",-1),_=t("\u7B49\u627E\u5230\u4E86\u5DE5\u4F5C\u540E\u624D\u604D\u7136\u5927\u609F\uFF0C\u539F\u6765\u5F53\u521D\u6839\u672C\u4E0D\u7528\u90A3\u4E48\u8F9B\u82E6\u3002\u8FD9\u4E0D\uFF0C\u521A\u597D\u6709\u5C0F\u4F19\u4F34\u5728\u300A"),b={href:"https://tobebetterjavaer.com/",target:"_blank",rel:"noopener noreferrer"},u=t("Java \u7A0B\u5E8F\u5458\u8FDB\u9636\u4E4B\u8DEF"),g=t("\u300B\u4E0A\u95EE\u6211\u7B97\u6CD5\u7684\u5B66\u4E60\u8DEF\u7EBF\uFF0C\u6211\u5C31\u6BEB\u4E0D\u4FDD\u7559\u5730\u628A\u6211\u7B97\u6CD5\u65B9\u9762\u7684\u5B66\u4E60\u7ECF\u9A8C\u5206\u4EAB\u51FA\u6765\uFF0C\u5E0C\u671B\u80FD\u7ED9\u5927\u5BB6\u4E00\u70B9\u70B9\u542F\u53D1\u548C\u5E2E\u52A9\u3002"),m=n(`

    \u6211\u753B\u4E86\u4E00\u5F20\u56FE\uFF0C\u91CC\u9762\u51E0\u4E4E\u6DB5\u76D6\u4E86\u6240\u6709\u6570\u636E\u7ED3\u6784\u4E0E\u7B97\u6CD5\u4E66\u7C4D\u4E2D\u90FD\u4F1A\u8BB2\u5230\u7684\u77E5\u8BC6\u70B9\u3002

    \u4F46\u8BB2\u826F\u5FC3\u8BDD\uFF0C\u5BF9\u4E8E\u4E00\u4E2A\u521D\u5B66\u8005\uFF0C\u6216\u8005\u4E0D\u6253\u7B97\u5377\u7B97\u6CD5\u5C97\u7684\u7A0B\u5E8F\u5458\u6765\u8BF4\uFF0C\u5B8C\u5168\u5C31\u6CA1\u5FC5\u8981\u628A\u601D\u7EF4\u5BFC\u56FE\u91CC\u9762\u7684\u6240\u6709\u77E5\u8BC6\u70B9\u90FD\u5B66\u4E86\uFF0C\u90A3\u6837\u5C31\u592A\u4E0D\u9AD8\u6548\u4E86\u3002

    \u6211\u4EEC\u5B66\u4E60\u6570\u636E\u7ED3\u6784\u4E0E\u7B97\u6CD5\uFF0C\u4E5F\u5F97\u8BB2\u7A76\u7B56\u7565\u3002\u6211\u7684\u5EFA\u8BAE\u662F\u8FD9\u6837\u7684\uFF08\u6572\u9ED1\u677F\u3001\u5212\u91CD\u70B9\u4E86\u554A\uFF09\uFF1A

    7 \u4E2A\u6570\u636E\u7ED3\u6784\uFF1A

    • \u6570\u7EC4
    • \u94FE\u8868
    • \u6808
    • \u961F\u5217
    • \u54C8\u5E0C\u8868
    • \u4E8C\u53C9\u6811
    • \u5806

    10 \u4E2A\u7B97\u6CD5\uFF1A

    • \u9012\u5F52
    • \u6392\u5E8F
    • \u4E8C\u5206\u67E5\u627E
    • \u641C\u7D22
    • \u54C8\u5E0C\u7B97\u6CD5
    • \u8D2A\u5FC3\u7B97\u6CD5
    • \u5206\u6CBB\u7B97\u6CD5
    • \u56DE\u6EAF\u7B97\u6CD5
    • \u52A8\u6001\u89C4\u5212
    • \u5B57\u7B26\u4E32\u5339\u914D\u7B97\u6CD5

    \u8FD9\u4E9B\u662F\u5B66\u4E60\u6570\u636E\u7ED3\u6784\u4E0E\u7B97\u6CD5\u65F6\u7684\u91CD\u70B9\u3002\u5F88\u591A\u4EBA\u5728\u7B2C\u4E00\u6B21\u63A5\u89E6\u6570\u636E\u7ED3\u6784\u4E0E\u7B97\u6CD5\u8FD9\u95E8\u8BFE\u65F6\uFF0C\u5F80\u5F80\u4F1A\u89C9\u5F97\u5F88\u62BD\u8C61\uFF0C\u5F88\u96BE\u641E\u61C2\uFF0C\u4EE5\u81F3\u4E8E\u7AD9\u5728\u95E8\u5916\u5F98\u5F8A\u4E0D\u524D\u3002

    \u5176\u5B9E\u771F\u6B63\u7684\u539F\u56E0\u662F\u6CA1\u6709\u627E\u5230\u597D\u7684\u5B66\u4E60\u65B9\u6CD5\uFF0C\u6CA1\u6709\u6293\u4F4F\u5B66\u4E60\u7684\u91CD\u70B9\u3002\u76F8\u4FE1\u4F60\u8BA4\u771F\u770B\u5B8C\u6211\u8FD9\u6761\u5B66\u4E60\u8DEF\u7EBF\u540E\uFF0C\u5B66\u8D77\u6765\u5C31\u4F1A\u6709\u7684\u653E\u77E2\u3001\u4E8B\u534A\u529F\u500D\u4E86\u3002

    \u4E00\u3001\u4EC0\u4E48\u662F\u6570\u636E\u7ED3\u6784

    \u6570\u636E\u7ED3\u6784\u662F\u4E00\u79CD\u5177\u6709\u4E00\u5B9A\u903B\u8F91\u5173\u7CFB\uFF0C\u5728\u8BA1\u7B97\u673A\u4E2D\u5E94\u7528\u67D0\u79CD\u5B58\u50A8\u7ED3\u6784\uFF0C\u5E76\u4E14\u5C01\u88C5\u4E86\u76F8\u5E94\u64CD\u4F5C\u7684\u6570\u636E\u5143\u7D20\u96C6\u5408\u3002\u5B83\u5305\u542B\u4E09\u65B9\u9762\u7684\u5185\u5BB9\uFF0C\u903B\u8F91\u5173\u7CFB\u3001\u5B58\u50A8\u5173\u7CFB\u53CA\u64CD\u4F5C\u3002\u4E0D\u540C\u79CD\u7C7B\u7684\u6570\u636E\u7ED3\u6784\u9002\u5408\u4E8E\u4E0D\u540C\u79CD\u7C7B\u7684\u5E94\u7528\uFF0C\u800C\u90E8\u5206\u751A\u81F3\u4E13\u95E8\u7528\u4E8E\u7279\u5B9A\u7684\u4F5C\u4E1A\u4EFB\u52A1\u3002\u4F8B\u5982\uFF0C\u8BA1\u7B97\u673A\u7F51\u7EDC\u4F9D\u8D56\u4E8E\u8DEF\u7531\u8868\u8FD0\u4F5C\uFF0CB \u6811\u9AD8\u5EA6\u9002\u7528\u4E8E\u6570\u636E\u5E93\u7684\u5C01\u88C5\u3002

    \u7B80\u5355\u70B9\u8BF4\uFF0C\u6570\u636E\u7ED3\u6784\u5C31\u662F\u628A\u4E00\u5806\u6570\u636E\uFF0C\u6309\u7167\u67D0\u79CD\u683C\u5F0F\u63C9\u6210\u4E00\u5768\u3002

    \u5927\u5BB6\u559C\u6B22\u5403\u5BAB\u4FDD\u9E21\u4E01\u5417\uFF1F

    \u53CD\u6B63\u4E8C\u54E5\u633A\u559C\u6B22\u8FD9\u9053\u83DC\u7684\u3002\u6211\u5C31\u4EE5\u5BAB\u4FDD\u9E21\u4E01\u4E3A\u4F8B\uFF0C\u6765\u8BB2\u4E00\u8BB2\u6570\u636E\u7ED3\u6784\u5427\u3002\u7EF4\u57FA\u767E\u79D1\u4E0A\u662F\u8FD9\u6837\u5B9A\u4E49\u7684\u3002

    \u5BAB\u4FDD\u9E21\u4E01\uFF08\u82F1\u8BED\uFF1AKung Pao chicken\u6216Kung-Pao Chicken\uFF09\uFF0C\u53C8\u79F0\u5BAB\u7206\u9E21\u4E01\uFF0C\u5448\u7CCA\u8FA3\u8354\u679D\u5473\uFF0C\u6E90\u4E8E\u9ED4\u83DC\u3001\u6D41\u4F20\u81F3\u9C81\u800C\u540E\u6210\u4E8E\u5DDD\u83DC\u7684\u4E00\u9053\u5DDD\u5473\u540D\u83DC\u3002\u8D35\u5DDE\u3001\u5C71\u4E1C\u548C\u56DB\u5DDD\u4E09\u5730\u5BF9\u8FD9\u9053\u83DC\u7684\u505A\u6CD5\u4E0D\u5B8C\u5168\u4E00\u6837\uFF0C\u79F0\u547C\u4E5F\u6709\u5DEE\u5F02\u3002\u8D35\u5DDE\u79F0\u4E3A\u7CCA\u8FA3\u5B50\u9E21\u4E01\uFF0C\u5C71\u4E1C\u5219\u540D\u4E3A\u9171\u7206\u9E21\u4E01\uFF0C\u800C\u56DB\u5DDD\u662F\u4EE5\u5BAB\u4FDD\u9E21\u4E01\u4E3A\u540D\u7684\u3002

    \u6765\uFF0C\u62BD\u8C61\u4E0B\u5BAB\u4FDD\u9E21\u4E01\u3002

    struct KungPaoChicken {
       \u9E21\u8089 = []
       \u82B1\u751F = []
       \u8471\u6BB5 = []
    diff --git a/dist/assets/ali-executors.html.e9951d8a.js b/dist/assets/ali-executors.html.3e2ae653.js
    similarity index 99%
    rename from dist/assets/ali-executors.html.e9951d8a.js
    rename to dist/assets/ali-executors.html.3e2ae653.js
    index 8f824969..a482d6d3 100644
    --- a/dist/assets/ali-executors.html.e9951d8a.js
    +++ b/dist/assets/ali-executors.html.3e2ae653.js
    @@ -1,4 +1,4 @@
    -import{_ as n}from"./plugin-vue_export-helper.21dcd24c.js";import{o as a,c as s,e}from"./app.a0271b9c.js";const t={},o=e(`

    \u4E3A\u4EC0\u4E48\u963F\u91CC\u5DF4\u5DF4\u8981\u7981\u7528Executors\u521B\u5EFA\u7EBF\u7A0B\u6C60\uFF1F

    \u770B\u963F\u91CC\u5DF4\u5DF4\u5F00\u53D1\u624B\u518C\u5E76\u53D1\u7F16\u7A0B\u8FD9\u5757\u6709\u4E00\u6761\uFF1A\u7EBF\u7A0B\u6C60\u4E0D\u5141\u8BB8\u4F7F\u7528 Executors \u53BB\u521B\u5EFA\uFF0C\u800C\u662F\u901A\u8FC7 ThreadPoolExecutor \u7684\u65B9\u5F0F\uFF0C\u4ECA\u5929\u6211\u4EEC\u6765\u901A\u8FC7\u6E90\u7801\u5206\u6790\u4E00\u4E0B\u7981\u7528\u7684\u539F\u56E0\u3002

    \u901A\u8FC7\u9605\u8BFB\u672C\u7BC7\u6587\u7AE0\u4F60\u5C06\u4E86\u89E3\u5230\uFF1A

    • \u7EBF\u7A0B\u6C60\u7684\u5B9A\u4E49
    • Executors \u521B\u5EFA\u7EBF\u7A0B\u6C60\u7684\u51E0\u79CD\u65B9\u5F0F
    • ThreadPoolExecutor \u5BF9\u8C61
    • \u7EBF\u7A0B\u6C60\u6267\u884C\u4EFB\u52A1\u903B\u8F91\u548C\u7EBF\u7A0B\u6C60\u53C2\u6570\u7684\u5173\u7CFB
    • Executors \u521B\u5EFA\u8FD4\u56DE ThreadPoolExecutor \u5BF9\u8C61
    • OOM \u5F02\u5E38\u6D4B\u8BD5
    • \u5982\u4F55\u5B9A\u4E49\u7EBF\u7A0B\u6C60\u53C2\u6570

    \u5982\u679C\u53EA\u60F3\u77E5\u9053\u539F\u56E0\u53EF\u4EE5\u76F4\u63A5\u62C9\u5230\u6587\u672B\u603B\u7ED3\u90A3\u3002

    \u4E00\u3001\u7EBF\u7A0B\u6C60\u7684\u5B9A\u4E49

    \u7BA1\u7406\u4E00\u7EC4\u5DE5\u4F5C\u7EBF\u7A0B\u3002\u901A\u8FC7\u7EBF\u7A0B\u6C60\u590D\u7528\u7EBF\u7A0B\u6709\u4EE5\u4E0B\u51E0\u70B9\u4F18\u70B9\uFF1A

    • \u51CF\u5C11\u8D44\u6E90\u521B\u5EFA => \u51CF\u5C11\u5185\u5B58\u5F00\u9500\uFF0C\u521B\u5EFA\u7EBF\u7A0B\u5360\u7528\u5185\u5B58
    • \u964D\u4F4E\u7CFB\u7EDF\u5F00\u9500 => \u521B\u5EFA\u7EBF\u7A0B\u9700\u8981\u65F6\u95F4\uFF0C\u4F1A\u5EF6\u8FDF\u5904\u7406\u7684\u8BF7\u6C42
    • \u63D0\u9AD8\u7A33\u5B9A\u7A33\u5B9A\u6027 => \u907F\u514D\u65E0\u9650\u521B\u5EFA\u7EBF\u7A0B\u5F15\u8D77\u7684 OutOfMemoryError\u3010\u7B80\u79F0 OOM\u3011

    Executors \u521B\u5EFA\u7EBF\u7A0B\u6C60\u7684\u65B9\u5F0F\uFF0C\u6839\u636E\u8FD4\u56DE\u7684\u5BF9\u8C61\u7C7B\u578B\u521B\u5EFA\u7EBF\u7A0B\u6C60\u53EF\u4EE5\u5206\u4E3A\u4E09\u7C7B\uFF1A

    • \u521B\u5EFA\u8FD4\u56DE ThreadPoolExecutor \u5BF9\u8C61
    • \u521B\u5EFA\u8FD4\u56DE ScheduleThreadPoolExecutor \u5BF9\u8C61
    • \u521B\u5EFA\u8FD4\u56DE ForkJoinPool \u5BF9\u8C61

    \u672C\u6587\u53EA\u8BA8\u8BBA\u521B\u5EFA\u8FD4\u56DE ThreadPoolExecutor \u5BF9\u8C61\u3002

    \u4E8C\u3001ThreadPoolExecutor \u5BF9\u8C61

    \u5728\u4ECB\u7ECD Executors \u521B\u5EFA\u7EBF\u7A0B\u6C60\u65B9\u6CD5\u524D\u5148\u4ECB\u7ECD\u4E00\u4E0B ThreadPoolExecutor\uFF0C\u56E0\u4E3A\u8FD9\u4E9B\u521B\u5EFA\u7EBF\u7A0B\u6C60\u7684\u9759\u6001\u65B9\u6CD5\u90FD\u662F\u8FD4\u56DE ThreadPoolExecutor \u5BF9\u8C61\uFF0C\u548C\u6211\u4EEC\u624B\u52A8\u521B\u5EFA ThreadPoolExecutor \u5BF9\u8C61\u7684\u533A\u522B\u5C31\u662F\u6211\u4EEC\u4E0D\u9700\u8981\u81EA\u5DF1\u4F20\u6784\u9020\u65B9\u6CD5\u7684\u53C2\u6570\u3002

    ThreadPoolExecutor \u7684\u6784\u9020\u65B9\u6CD5\u5171\u6709\u56DB\u4E2A\uFF0C\u4F46\u6700\u7EC8\u8C03\u7528\u7684\u90FD\u662F\u540C\u4E00\u4E2A\uFF1A

    public ThreadPoolExecutor(int corePoolSize,
    +import{_ as n}from"./plugin-vue_export-helper.21dcd24c.js";import{o as a,c as s,e}from"./app.615e41d8.js";const t={},o=e(`

    \u4E3A\u4EC0\u4E48\u963F\u91CC\u5DF4\u5DF4\u8981\u7981\u7528Executors\u521B\u5EFA\u7EBF\u7A0B\u6C60\uFF1F

    \u770B\u963F\u91CC\u5DF4\u5DF4\u5F00\u53D1\u624B\u518C\u5E76\u53D1\u7F16\u7A0B\u8FD9\u5757\u6709\u4E00\u6761\uFF1A\u7EBF\u7A0B\u6C60\u4E0D\u5141\u8BB8\u4F7F\u7528 Executors \u53BB\u521B\u5EFA\uFF0C\u800C\u662F\u901A\u8FC7 ThreadPoolExecutor \u7684\u65B9\u5F0F\uFF0C\u4ECA\u5929\u6211\u4EEC\u6765\u901A\u8FC7\u6E90\u7801\u5206\u6790\u4E00\u4E0B\u7981\u7528\u7684\u539F\u56E0\u3002

    \u901A\u8FC7\u9605\u8BFB\u672C\u7BC7\u6587\u7AE0\u4F60\u5C06\u4E86\u89E3\u5230\uFF1A

    • \u7EBF\u7A0B\u6C60\u7684\u5B9A\u4E49
    • Executors \u521B\u5EFA\u7EBF\u7A0B\u6C60\u7684\u51E0\u79CD\u65B9\u5F0F
    • ThreadPoolExecutor \u5BF9\u8C61
    • \u7EBF\u7A0B\u6C60\u6267\u884C\u4EFB\u52A1\u903B\u8F91\u548C\u7EBF\u7A0B\u6C60\u53C2\u6570\u7684\u5173\u7CFB
    • Executors \u521B\u5EFA\u8FD4\u56DE ThreadPoolExecutor \u5BF9\u8C61
    • OOM \u5F02\u5E38\u6D4B\u8BD5
    • \u5982\u4F55\u5B9A\u4E49\u7EBF\u7A0B\u6C60\u53C2\u6570

    \u5982\u679C\u53EA\u60F3\u77E5\u9053\u539F\u56E0\u53EF\u4EE5\u76F4\u63A5\u62C9\u5230\u6587\u672B\u603B\u7ED3\u90A3\u3002

    \u4E00\u3001\u7EBF\u7A0B\u6C60\u7684\u5B9A\u4E49

    \u7BA1\u7406\u4E00\u7EC4\u5DE5\u4F5C\u7EBF\u7A0B\u3002\u901A\u8FC7\u7EBF\u7A0B\u6C60\u590D\u7528\u7EBF\u7A0B\u6709\u4EE5\u4E0B\u51E0\u70B9\u4F18\u70B9\uFF1A

    • \u51CF\u5C11\u8D44\u6E90\u521B\u5EFA => \u51CF\u5C11\u5185\u5B58\u5F00\u9500\uFF0C\u521B\u5EFA\u7EBF\u7A0B\u5360\u7528\u5185\u5B58
    • \u964D\u4F4E\u7CFB\u7EDF\u5F00\u9500 => \u521B\u5EFA\u7EBF\u7A0B\u9700\u8981\u65F6\u95F4\uFF0C\u4F1A\u5EF6\u8FDF\u5904\u7406\u7684\u8BF7\u6C42
    • \u63D0\u9AD8\u7A33\u5B9A\u7A33\u5B9A\u6027 => \u907F\u514D\u65E0\u9650\u521B\u5EFA\u7EBF\u7A0B\u5F15\u8D77\u7684 OutOfMemoryError\u3010\u7B80\u79F0 OOM\u3011

    Executors \u521B\u5EFA\u7EBF\u7A0B\u6C60\u7684\u65B9\u5F0F\uFF0C\u6839\u636E\u8FD4\u56DE\u7684\u5BF9\u8C61\u7C7B\u578B\u521B\u5EFA\u7EBF\u7A0B\u6C60\u53EF\u4EE5\u5206\u4E3A\u4E09\u7C7B\uFF1A

    • \u521B\u5EFA\u8FD4\u56DE ThreadPoolExecutor \u5BF9\u8C61
    • \u521B\u5EFA\u8FD4\u56DE ScheduleThreadPoolExecutor \u5BF9\u8C61
    • \u521B\u5EFA\u8FD4\u56DE ForkJoinPool \u5BF9\u8C61

    \u672C\u6587\u53EA\u8BA8\u8BBA\u521B\u5EFA\u8FD4\u56DE ThreadPoolExecutor \u5BF9\u8C61\u3002

    \u4E8C\u3001ThreadPoolExecutor \u5BF9\u8C61

    \u5728\u4ECB\u7ECD Executors \u521B\u5EFA\u7EBF\u7A0B\u6C60\u65B9\u6CD5\u524D\u5148\u4ECB\u7ECD\u4E00\u4E0B ThreadPoolExecutor\uFF0C\u56E0\u4E3A\u8FD9\u4E9B\u521B\u5EFA\u7EBF\u7A0B\u6C60\u7684\u9759\u6001\u65B9\u6CD5\u90FD\u662F\u8FD4\u56DE ThreadPoolExecutor \u5BF9\u8C61\uFF0C\u548C\u6211\u4EEC\u624B\u52A8\u521B\u5EFA ThreadPoolExecutor \u5BF9\u8C61\u7684\u533A\u522B\u5C31\u662F\u6211\u4EEC\u4E0D\u9700\u8981\u81EA\u5DF1\u4F20\u6784\u9020\u65B9\u6CD5\u7684\u53C2\u6570\u3002

    ThreadPoolExecutor \u7684\u6784\u9020\u65B9\u6CD5\u5171\u6709\u56DB\u4E2A\uFF0C\u4F46\u6700\u7EC8\u8C03\u7528\u7684\u90FD\u662F\u540C\u4E00\u4E2A\uFF1A

    public ThreadPoolExecutor(int corePoolSize,
      int maximumPoolSize,
      long keepAliveTime,
      TimeUnit unit,
    diff --git a/dist/assets/aliyun-shuaiguo-gongchengshi.html.80a83c0a.js b/dist/assets/aliyun-shuaiguo-gongchengshi.html.af9a0166.js
    similarity index 99%
    rename from dist/assets/aliyun-shuaiguo-gongchengshi.html.80a83c0a.js
    rename to dist/assets/aliyun-shuaiguo-gongchengshi.html.af9a0166.js
    index 47814f6e..d3dd6711 100644
    --- a/dist/assets/aliyun-shuaiguo-gongchengshi.html.80a83c0a.js
    +++ b/dist/assets/aliyun-shuaiguo-gongchengshi.html.af9a0166.js
    @@ -1 +1 @@
    -import{_ as e}from"./plugin-vue_export-helper.21dcd24c.js";import{o as a,c as t,e as o}from"./app.a0271b9c.js";const i={},p=o('

    \u771F\u4E0D\u662F\u6211\u6709\u610F\u8981\u9ED1\u8FD9\u4E2A\u963F\u91CC\u4E91\u5DE5\u7A0B\u5E08\uFF0C\u800C\u662F\u4ED6\u51B7\u6F20\u7684\u6001\u5EA6\uFF0C\u8D85\u7EA7\u9AD8\u6C34\u5E73\u7684\u7529\u9505\u80FD\u529B\uFF0C\u5F7B\u5F7B\u5E95\u5E95\u628A\u6211\u7ED9\u6253\u8D25\u4E86\uFF01

    \u7ED9\u5927\u5BB6\u770B\u4E00\u4E0B\u6211\u4EEC\u7684\u7B2C\u4E00\u6CE2\u4EA4\u950B\u3002\u4ECE\u5728\u7EBF\u6C9F\u901A\u8F6C\u5DE5\u5355\u7684\u65F6\u5019\uFF0C\u4E3A\u4E86\u7ED9\u8FD9\u4F4D\u963F\u91CC\u4E91\u7684\u552E\u540E\u5DE5\u7A0B\u5E08\u52A0\u6CB9\u6253\u6C14\uFF0C\u6211\u8FD8\u7279\u610F\u51C6\u5907\u4E86\u4E00\u53E5\u201C\u8F9B\u82E6\u4E86\u201D\uFF0C\u5C31\u5DEE\u8DEA\u4E0B\u4E86\u3002

    \u7ED3\u679C\u7B49\u5230\u7684\u662F\u963F\u91CC\u4E91\u552E\u540E\u5DE5\u7A0B\u5E08\u7684\u4E00\u53E5\uFF1A\u201C\u6211\u6253\u5F00\u770B\u4E86\u4E00\u4E0B\uFF0C\u8FD9\u4E2A\u56FE\u7247\u4E0D\u662F\u60A8\u7ED9\u7684\u8FD9\u4E2A\u8D44\u6E90\u554A\u201D\u3002

    \u6211\u5F53\u65F6\u5FC3\u91CC\u6697\u60F3\uFF0C\u597D\u5BB6\u4F19\uFF0C\u679C\u7136\u7529\u9505\u5C0F\u80FD\u624B\u554A\uFF01

    \u7136\u540E\u6211\u5C31\u8010\u5FC3\u5730\u7ED9\u4ED6\u89E3\u91CA\uFF0CGitHub \u4F1A\u5BF9\u56FE\u7247\u8F6C\u94FE\uFF0C\u53E6\u5916\uFF0C\u7528 HTTP \u7684\u65F6\u5019\u662F\u53EF\u4EE5\u663E\u793A\u7684\uFF0C\u53EA\u6709 CDN \u542F\u7528\u4E86 HTTPS \u624D\u4E0D\u663E\u793A\u3002

    \u7ED3\u679C\u4ED6\u56DE\u4E86\u4E00\u53E5\uFF0C\u201C\u8FD9\u4E2A\u6211\u4EEC\u786E\u8BA4\u4E0D\u4E86\u54C8\uFF0C\u8FD9\u4E2A\u94FE\u63A5\u6CA1\u6709\u8BF7\u6C42 CDN \u57DF\u540D\uFF0C\u4E0D\u663E\u793A\u4E5F\u4E0D\u662F CDN \u8FD4\u56DE\u7684\u201D\u3002

    \u4ECE\u6211\u4EEC\u7684\u7B2C\u4E8C\u6CE2\u4EA4\u950B\u53EF\u4EE5\u770B\u5F97\u51FA\uFF0C\u8FD9\u4F4D\u963F\u91CC\u552E\u540E\u5DE5\u7A0B\u5E08\u7684\u7529\u9505\u5929\u8D4B\u5F00\u59CB\u5D2D\u9732\u5934\u89D2\u4E86\uFF0C\u524D\u540E\u7684\u903B\u8F91\u4E5F\u975E\u5E38\u7F1C\u5BC6\uFF0C\u4E0D\u5BB9\u7F6E\u7591\u3002

    \u63A5\u7740\u6211\u53C8\u7ED9\u4ED6\u89E3\u91CA\uFF0C\u6211\u8BF4\u4F60\u770B\u770B\u8FD9\u4E2A\u56FE\u7247\u6807\u7B7E\u91CC\u8FD8\u6709\u4E00\u4E2A data-canonical-src \u5C5E\u6027\uFF0C\u5B83\u5C31\u6765\u81EA\u4F60\u4EEC\u963F\u91CC\u4E91\u7684 CDN \u554A\uFF0C\u53E6\u5916\uFF0C\u6211\u628A HTTPS \u6539\u6210 HTTP \u5C31\u53EF\u4EE5\u8BBF\u95EE\u4E86\uFF0C\u522B\u7684\u4EC0\u4E48\u90FD\u4E0D\u7528\u52A8\u3002

    \u6211\u4EE5\u4E3A\uFF0C\u8FD9\u4F4D\u963F\u91CC\u552E\u540E\u5DE5\u7A0B\u5E08\u5728\u6536\u5230\u6211\u8FD9\u4E2A\u786E\u51FF\u7684\u8BC1\u636E\u540E\uFF0C\u4F1A\u7A0D\u5FAE\u7814\u7A76\u4E00\u756A\uFF0C\u7ED3\u679C\u6CA1\u60F3\u5230\uFF0C\u4ED6\u9A6C\u4E0A\u5C31\u5F00\u59CB\u6B63\u513F\u516B\u7ECF\u5730\u7529\u9505\u4E86\uFF0C\u201C\u8FD9\u4E2A\u6211\u4EEC\u4E5F\u786E\u8BA4\u4E0D\u4E86\uFF0C\u56E0\u4E3A\u8FD9\u4E2A\u7C7B\u4F3C\u4EE3\u7406\u8BF7\u6C42\u4E86\uFF0C\u62FF\u4E0D\u5230\u5B9E\u9645\u8BF7\u6C42 CDN \u7684\u8FD4\u56DE\u4FE1\u606F\u201D\u3002

    \u597D\u5427\uFF0C\u6211\u88AB\u6253\u8D25\u4E86\uFF0C\u5F7B\u5F7B\u5E95\u5E95\u5730\u8D25\u4E86\uFF0C\u8D25\u7684\u4E00\u584C\u7CCA\u6D82\uFF01

    \u7EC6\u7EC6\u54C1\u4E00\u4E0B\uFF0C\u8FD9\u4F4D\u963F\u91CC\u552E\u540E\u5DE5\u7A0B\u5E08\u7ED9\u51FA\u7684\u7406\u7531\u7EDD\u58C1\u662F\u5929\u8863\u65E0\u7F1D\uFF0C\u6211\u6839\u672C\u5C31\u6CA1\u529E\u6CD5\u53CD\u9A73\uFF01\u8981\u602A\u6211\u53EA\u80FD\u602A\uFF0CGitHub\uFF01

    • \u7B2C\u4E00\uFF0C\u4F60\u4E3A\u4EC0\u4E48\u8981\u8F6C\u94FE\u554A\uFF1F
    • \u7B2C\u4E8C\uFF0C\u4F60\u4E3A\u4EC0\u4E48\u80FD\u8F6C HTTP \u7684 CDN \u94FE\u63A5\uFF0C\u8F6C\u4E0D\u4E86 HTTPS \u7684\u5462\uFF1F
    • \u7B2C\u4E09\uFF0C\u4F60 HTTPS \u4E5F\u4E0D\u662F\u4E0D\u80FD\u8F6C\uFF0C\u76F4\u63A5\u7528 OSS \u7684 HTTPS \u94FE\u63A5\u4F60\u5C31\u80FD\u8F6C\uFF0C\u52A0\u4E86 CDN \u7684\u4F60\u5C31\u4E0D\u884C\uFF1F

    \u4E4B\u524D\u7ED9\u5927\u5BB6\u63D0\u5230\u8FC7\uFF0C\u4E8C\u54E5\u7684\u5C0F\u7834\u7AD9\u300AJava \u7A0B\u5E8F\u5458\u8FDB\u9636\u4E4B\u8DEF\u300B\u7684\u56FE\u5E8A\u662F\u7528 GitHub+jsDelivr \u505A\u7684\uFF0C\u514D\u8D39\u554A\uFF0C\u53EF\u4EE5\u767D\u5AD6\u554A\uFF0C\u6240\u4EE5\u6211\u89C9\u5F97\u7528\u8D77\u6765\u5F88\u723D\uFF01

    \u4F46\u76F4\u5230\u6709\u4E00\u5929\uFF0C\u6709\u4E2A\u5C0F\u4F19\u4F34\u63D0\u4E86\u4E00\u4E2A issue\uFF0C\u8BF4 jsDelivr \u64A4\u51FA\u4E86\u56FD\u5185\u8282\u70B9\uFF0C\u5BFC\u81F4\u90E8\u5206\u56FE\u7247\u4E0D\u663E\u793A\u6216\u8005\u52A0\u8F7D\u7F13\u6162\uFF0C\u6211\u5C31\u5750\u7ACB\u4E0D\u5B89\u3001\u5BDD\u98DF\u96BE\u5B89\u4E86\uFF01

    \u6BD5\u7ADF\u4E8C\u54E5\u53EF\u662F\u4E00\u540D\u8D1F\u8D23\u4EFB\u7684\u597D\u540C\u5FD7\u554A\uFF0C\u5FC5\u987B\u5F97\u89E3\u51B3\u8FD9\u4E2A\u56FE\u5E8A\u7684\u95EE\u9898\u3002\u4E8E\u662F\u6211\u5C31\u6298\u817E\u4E86\u4E24\u5929\u7684 OSS + CDN\uFF0C\u5C0F\u7834\u7AD9\u7684\u56FE\u7247\u662F\u80FD\u6B63\u5E38\u8BBF\u95EE\u4E86\uFF0C\u53EA\u662F\u6CA1\u60F3\u5230\uFF0C\u963F\u91CC\u4E91\u7684\u8FD9\u5957\u56FE\u5E8A\u7EC4\u5408\u5728 GitHub \u4E0A\u8FD9\u4E48\u201C\u4E0D\u9760\u8C31\u201D\u3002

    \u771F\u7684\u662F\u94B1\u82B1\u4E86\uFF0C\u4E8B\u5374\u6CA1\u529E\u597D\u3002\u5BB3\uFF0C\u5148\u6765\u77A7\u77A7\u6211\u81EA\u5DF1\u6478\u7D22\u51FA\u6765\u7684\u6298\u4E2D\u65B9\u6848\u5427\u3002

    1\uFF09HTTPS \u7684 CDN \u94FE\u63A5\u7EDF\u7EDF\u66FF\u6362\u4E3A HTTP \u7684\uFF0C\u81F3\u5C11\u80FD\u663E\u793A\u3002

    2\uFF09\u5982\u679C HTTP \u7684\u4E5F\u663E\u793A\u6709\u95EE\u9898\uFF0C\u6709\u4E9B\u4F1A\u53EA\u663E\u793A\u4E00\u90E8\u5206\uFF08\u83AB\u540D\u5176\u5999\uFF09\uFF0C\u5C31\u6539\u6210 OSS \u7684\u94FE\u63A5\u3002

    \u5148\u628A\u95EE\u9898\u89E3\u51B3\u4E86\u518D\u8BF4\u3002

    \u5C0F\u4F19\u4F34\u4EEC\u6709\u6CA1\u6709\u66F4\u597D\u7684\u7684\u56FE\u5E8A\u89E3\u51B3\u65B9\u6848\u5462\uFF1F\u53EF\u4EE5\u5728\u8BC4\u8BBA\u533A/\u5F39\u5E55\u533A\u7ED9\u51FA\u81EA\u5DF1\u7684\u7B54\u6848\uFF0C\u6551\u6551\u4E8C\u54E5\u8FD9\u4E2A\u5B69\u5B50\u5427\uFF01\uFF01\uFF01\uFF01\uFF01\uFF01

    \u597D\u4E86\uFF0C\u4ECA\u5929\u7684\u5206\u4EAB\u5C31\u5148\u5230\u8FD9\u5427\uFF0C\u5E0C\u671B\u5C0F\u4F19\u4F34\u4EEC\u80FD\u70B9\u70B9\u8D5E\uFF0C\u8F6C\u8F6C\u53D1\uFF0C\u597D\u8BA9\u963F\u91CC\u4E91\u5B98\u65B9\u770B\u5230\u8FD9\u4E2A\u95EE\u9898\uFF0C \u91CD\u89C6\u8FD9\u4E2A\u95EE\u9898\uFF0C\u5E76\u89E3\u51B3\u8FD9\u4E2A\u95EE\u9898\u3002

    ',30),n=[p];function g(r,s){return a(),t("div",null,n)}var h=e(i,[["render",g],["__file","aliyun-shuaiguo-gongchengshi.html.vue"]]);export{h as default}; +import{_ as e}from"./plugin-vue_export-helper.21dcd24c.js";import{o as a,c as t,e as o}from"./app.615e41d8.js";const i={},p=o('

    \u771F\u4E0D\u662F\u6211\u6709\u610F\u8981\u9ED1\u8FD9\u4E2A\u963F\u91CC\u4E91\u5DE5\u7A0B\u5E08\uFF0C\u800C\u662F\u4ED6\u51B7\u6F20\u7684\u6001\u5EA6\uFF0C\u8D85\u7EA7\u9AD8\u6C34\u5E73\u7684\u7529\u9505\u80FD\u529B\uFF0C\u5F7B\u5F7B\u5E95\u5E95\u628A\u6211\u7ED9\u6253\u8D25\u4E86\uFF01

    \u7ED9\u5927\u5BB6\u770B\u4E00\u4E0B\u6211\u4EEC\u7684\u7B2C\u4E00\u6CE2\u4EA4\u950B\u3002\u4ECE\u5728\u7EBF\u6C9F\u901A\u8F6C\u5DE5\u5355\u7684\u65F6\u5019\uFF0C\u4E3A\u4E86\u7ED9\u8FD9\u4F4D\u963F\u91CC\u4E91\u7684\u552E\u540E\u5DE5\u7A0B\u5E08\u52A0\u6CB9\u6253\u6C14\uFF0C\u6211\u8FD8\u7279\u610F\u51C6\u5907\u4E86\u4E00\u53E5\u201C\u8F9B\u82E6\u4E86\u201D\uFF0C\u5C31\u5DEE\u8DEA\u4E0B\u4E86\u3002

    \u7ED3\u679C\u7B49\u5230\u7684\u662F\u963F\u91CC\u4E91\u552E\u540E\u5DE5\u7A0B\u5E08\u7684\u4E00\u53E5\uFF1A\u201C\u6211\u6253\u5F00\u770B\u4E86\u4E00\u4E0B\uFF0C\u8FD9\u4E2A\u56FE\u7247\u4E0D\u662F\u60A8\u7ED9\u7684\u8FD9\u4E2A\u8D44\u6E90\u554A\u201D\u3002

    \u6211\u5F53\u65F6\u5FC3\u91CC\u6697\u60F3\uFF0C\u597D\u5BB6\u4F19\uFF0C\u679C\u7136\u7529\u9505\u5C0F\u80FD\u624B\u554A\uFF01

    \u7136\u540E\u6211\u5C31\u8010\u5FC3\u5730\u7ED9\u4ED6\u89E3\u91CA\uFF0CGitHub \u4F1A\u5BF9\u56FE\u7247\u8F6C\u94FE\uFF0C\u53E6\u5916\uFF0C\u7528 HTTP \u7684\u65F6\u5019\u662F\u53EF\u4EE5\u663E\u793A\u7684\uFF0C\u53EA\u6709 CDN \u542F\u7528\u4E86 HTTPS \u624D\u4E0D\u663E\u793A\u3002

    \u7ED3\u679C\u4ED6\u56DE\u4E86\u4E00\u53E5\uFF0C\u201C\u8FD9\u4E2A\u6211\u4EEC\u786E\u8BA4\u4E0D\u4E86\u54C8\uFF0C\u8FD9\u4E2A\u94FE\u63A5\u6CA1\u6709\u8BF7\u6C42 CDN \u57DF\u540D\uFF0C\u4E0D\u663E\u793A\u4E5F\u4E0D\u662F CDN \u8FD4\u56DE\u7684\u201D\u3002

    \u4ECE\u6211\u4EEC\u7684\u7B2C\u4E8C\u6CE2\u4EA4\u950B\u53EF\u4EE5\u770B\u5F97\u51FA\uFF0C\u8FD9\u4F4D\u963F\u91CC\u552E\u540E\u5DE5\u7A0B\u5E08\u7684\u7529\u9505\u5929\u8D4B\u5F00\u59CB\u5D2D\u9732\u5934\u89D2\u4E86\uFF0C\u524D\u540E\u7684\u903B\u8F91\u4E5F\u975E\u5E38\u7F1C\u5BC6\uFF0C\u4E0D\u5BB9\u7F6E\u7591\u3002

    \u63A5\u7740\u6211\u53C8\u7ED9\u4ED6\u89E3\u91CA\uFF0C\u6211\u8BF4\u4F60\u770B\u770B\u8FD9\u4E2A\u56FE\u7247\u6807\u7B7E\u91CC\u8FD8\u6709\u4E00\u4E2A data-canonical-src \u5C5E\u6027\uFF0C\u5B83\u5C31\u6765\u81EA\u4F60\u4EEC\u963F\u91CC\u4E91\u7684 CDN \u554A\uFF0C\u53E6\u5916\uFF0C\u6211\u628A HTTPS \u6539\u6210 HTTP \u5C31\u53EF\u4EE5\u8BBF\u95EE\u4E86\uFF0C\u522B\u7684\u4EC0\u4E48\u90FD\u4E0D\u7528\u52A8\u3002

    \u6211\u4EE5\u4E3A\uFF0C\u8FD9\u4F4D\u963F\u91CC\u552E\u540E\u5DE5\u7A0B\u5E08\u5728\u6536\u5230\u6211\u8FD9\u4E2A\u786E\u51FF\u7684\u8BC1\u636E\u540E\uFF0C\u4F1A\u7A0D\u5FAE\u7814\u7A76\u4E00\u756A\uFF0C\u7ED3\u679C\u6CA1\u60F3\u5230\uFF0C\u4ED6\u9A6C\u4E0A\u5C31\u5F00\u59CB\u6B63\u513F\u516B\u7ECF\u5730\u7529\u9505\u4E86\uFF0C\u201C\u8FD9\u4E2A\u6211\u4EEC\u4E5F\u786E\u8BA4\u4E0D\u4E86\uFF0C\u56E0\u4E3A\u8FD9\u4E2A\u7C7B\u4F3C\u4EE3\u7406\u8BF7\u6C42\u4E86\uFF0C\u62FF\u4E0D\u5230\u5B9E\u9645\u8BF7\u6C42 CDN \u7684\u8FD4\u56DE\u4FE1\u606F\u201D\u3002

    \u597D\u5427\uFF0C\u6211\u88AB\u6253\u8D25\u4E86\uFF0C\u5F7B\u5F7B\u5E95\u5E95\u5730\u8D25\u4E86\uFF0C\u8D25\u7684\u4E00\u584C\u7CCA\u6D82\uFF01

    \u7EC6\u7EC6\u54C1\u4E00\u4E0B\uFF0C\u8FD9\u4F4D\u963F\u91CC\u552E\u540E\u5DE5\u7A0B\u5E08\u7ED9\u51FA\u7684\u7406\u7531\u7EDD\u58C1\u662F\u5929\u8863\u65E0\u7F1D\uFF0C\u6211\u6839\u672C\u5C31\u6CA1\u529E\u6CD5\u53CD\u9A73\uFF01\u8981\u602A\u6211\u53EA\u80FD\u602A\uFF0CGitHub\uFF01

    • \u7B2C\u4E00\uFF0C\u4F60\u4E3A\u4EC0\u4E48\u8981\u8F6C\u94FE\u554A\uFF1F
    • \u7B2C\u4E8C\uFF0C\u4F60\u4E3A\u4EC0\u4E48\u80FD\u8F6C HTTP \u7684 CDN \u94FE\u63A5\uFF0C\u8F6C\u4E0D\u4E86 HTTPS \u7684\u5462\uFF1F
    • \u7B2C\u4E09\uFF0C\u4F60 HTTPS \u4E5F\u4E0D\u662F\u4E0D\u80FD\u8F6C\uFF0C\u76F4\u63A5\u7528 OSS \u7684 HTTPS \u94FE\u63A5\u4F60\u5C31\u80FD\u8F6C\uFF0C\u52A0\u4E86 CDN \u7684\u4F60\u5C31\u4E0D\u884C\uFF1F

    \u4E4B\u524D\u7ED9\u5927\u5BB6\u63D0\u5230\u8FC7\uFF0C\u4E8C\u54E5\u7684\u5C0F\u7834\u7AD9\u300AJava \u7A0B\u5E8F\u5458\u8FDB\u9636\u4E4B\u8DEF\u300B\u7684\u56FE\u5E8A\u662F\u7528 GitHub+jsDelivr \u505A\u7684\uFF0C\u514D\u8D39\u554A\uFF0C\u53EF\u4EE5\u767D\u5AD6\u554A\uFF0C\u6240\u4EE5\u6211\u89C9\u5F97\u7528\u8D77\u6765\u5F88\u723D\uFF01

    \u4F46\u76F4\u5230\u6709\u4E00\u5929\uFF0C\u6709\u4E2A\u5C0F\u4F19\u4F34\u63D0\u4E86\u4E00\u4E2A issue\uFF0C\u8BF4 jsDelivr \u64A4\u51FA\u4E86\u56FD\u5185\u8282\u70B9\uFF0C\u5BFC\u81F4\u90E8\u5206\u56FE\u7247\u4E0D\u663E\u793A\u6216\u8005\u52A0\u8F7D\u7F13\u6162\uFF0C\u6211\u5C31\u5750\u7ACB\u4E0D\u5B89\u3001\u5BDD\u98DF\u96BE\u5B89\u4E86\uFF01

    \u6BD5\u7ADF\u4E8C\u54E5\u53EF\u662F\u4E00\u540D\u8D1F\u8D23\u4EFB\u7684\u597D\u540C\u5FD7\u554A\uFF0C\u5FC5\u987B\u5F97\u89E3\u51B3\u8FD9\u4E2A\u56FE\u5E8A\u7684\u95EE\u9898\u3002\u4E8E\u662F\u6211\u5C31\u6298\u817E\u4E86\u4E24\u5929\u7684 OSS + CDN\uFF0C\u5C0F\u7834\u7AD9\u7684\u56FE\u7247\u662F\u80FD\u6B63\u5E38\u8BBF\u95EE\u4E86\uFF0C\u53EA\u662F\u6CA1\u60F3\u5230\uFF0C\u963F\u91CC\u4E91\u7684\u8FD9\u5957\u56FE\u5E8A\u7EC4\u5408\u5728 GitHub \u4E0A\u8FD9\u4E48\u201C\u4E0D\u9760\u8C31\u201D\u3002

    \u771F\u7684\u662F\u94B1\u82B1\u4E86\uFF0C\u4E8B\u5374\u6CA1\u529E\u597D\u3002\u5BB3\uFF0C\u5148\u6765\u77A7\u77A7\u6211\u81EA\u5DF1\u6478\u7D22\u51FA\u6765\u7684\u6298\u4E2D\u65B9\u6848\u5427\u3002

    1\uFF09HTTPS \u7684 CDN \u94FE\u63A5\u7EDF\u7EDF\u66FF\u6362\u4E3A HTTP \u7684\uFF0C\u81F3\u5C11\u80FD\u663E\u793A\u3002

    2\uFF09\u5982\u679C HTTP \u7684\u4E5F\u663E\u793A\u6709\u95EE\u9898\uFF0C\u6709\u4E9B\u4F1A\u53EA\u663E\u793A\u4E00\u90E8\u5206\uFF08\u83AB\u540D\u5176\u5999\uFF09\uFF0C\u5C31\u6539\u6210 OSS \u7684\u94FE\u63A5\u3002

    \u5148\u628A\u95EE\u9898\u89E3\u51B3\u4E86\u518D\u8BF4\u3002

    \u5C0F\u4F19\u4F34\u4EEC\u6709\u6CA1\u6709\u66F4\u597D\u7684\u7684\u56FE\u5E8A\u89E3\u51B3\u65B9\u6848\u5462\uFF1F\u53EF\u4EE5\u5728\u8BC4\u8BBA\u533A/\u5F39\u5E55\u533A\u7ED9\u51FA\u81EA\u5DF1\u7684\u7B54\u6848\uFF0C\u6551\u6551\u4E8C\u54E5\u8FD9\u4E2A\u5B69\u5B50\u5427\uFF01\uFF01\uFF01\uFF01\uFF01\uFF01

    \u597D\u4E86\uFF0C\u4ECA\u5929\u7684\u5206\u4EAB\u5C31\u5148\u5230\u8FD9\u5427\uFF0C\u5E0C\u671B\u5C0F\u4F19\u4F34\u4EEC\u80FD\u70B9\u70B9\u8D5E\uFF0C\u8F6C\u8F6C\u53D1\uFF0C\u597D\u8BA9\u963F\u91CC\u4E91\u5B98\u65B9\u770B\u5230\u8FD9\u4E2A\u95EE\u9898\uFF0C \u91CD\u89C6\u8FD9\u4E2A\u95EE\u9898\uFF0C\u5E76\u89E3\u51B3\u8FD9\u4E2A\u95EE\u9898\u3002

    ',30),n=[p];function g(r,s){return a(),t("div",null,n)}var h=e(i,[["render",g],["__file","aliyun-shuaiguo-gongchengshi.html.vue"]]);export{h as default}; diff --git a/dist/assets/annotation.html.b0fc1ba0.js b/dist/assets/annotation.html.3a9fcfe1.js similarity index 99% rename from dist/assets/annotation.html.b0fc1ba0.js rename to dist/assets/annotation.html.3a9fcfe1.js index 85f15550..faa0c25f 100644 --- a/dist/assets/annotation.html.b0fc1ba0.js +++ b/dist/assets/annotation.html.3a9fcfe1.js @@ -1,4 +1,4 @@ -import{_ as n}from"./plugin-vue_export-helper.21dcd24c.js";import{o as s,c as a,e as p}from"./app.a0271b9c.js";const t={},e=p(`

    \u6DF1\u5165\u7406\u89E3Java\u6CE8\u89E3

    \u201C\u4E8C\u54E5\uFF0C\u8FD9\u8282\u8BB2\u6CE8\u89E3\u5417\uFF1F\u201D\u4E09\u59B9\u95EE\u3002

    \u201C\u662F\u7684\u3002\u201D\u6211\u8BF4\uFF0C\u201C\u6CE8\u89E3\u662F Java \u4E2D\u975E\u5E38\u91CD\u8981\u7684\u4E00\u90E8\u5206\uFF0C\u4F46\u7ECF\u5E38\u88AB\u5FFD\u89C6\u4E5F\u662F\u771F\u7684\u3002\u4E4B\u6240\u4EE5\u8FD9\u4E48\u8BF4\u662F\u56E0\u4E3A\u6211\u4EEC\u66F4\u503E\u5411\u6210\u4E3A\u4E00\u540D\u6CE8\u89E3\u7684\u4F7F\u7528\u8005\u800C\u4E0D\u662F\u521B\u5EFA\u8005\u3002@Override \u6CE8\u89E3\u7528\u8FC7\u5427\uFF1F\u4F46\u4F60\u77E5\u9053\u600E\u4E48\u81EA\u5B9A\u4E49\u4E00\u4E2A\u6CE8\u89E3\u5417\uFF1F\u201D

    \u4E09\u59B9\u6BEB\u4E0D\u72B9\u8C6B\u5730\u6447\u6447\u5934\uFF0C\u6446\u6446\u624B\uFF0C\u4E0D\u597D\u610F\u601D\u5730\u627F\u8BA4\u81EA\u5DF1\u7684\u786E\u6CA1\u6709\u81EA\u5B9A\u4E49\u8FC7\u3002

    \u201C\u597D\u5427\uFF0C\u54E5\u6765\u544A\u8BC9\u4F60\u5427\u3002\u201D

    \u6CE8\u89E3\uFF08Annotation\uFF09\u662F\u5728 Java 1.5 \u65F6\u5F15\u5165\u7684\u6982\u5FF5\uFF0C\u540C class \u548C interface \u4E00\u6837\uFF0C\u4E5F\u5C5E\u4E8E\u4E00\u79CD\u7C7B\u578B\u3002\u6CE8\u89E3\u63D0\u4F9B\u4E86\u4E00\u7CFB\u5217\u6570\u636E\u7528\u6765\u88C5\u9970\u7A0B\u5E8F\u4EE3\u7801\uFF08\u7C7B\u3001\u65B9\u6CD5\u3001\u5B57\u6BB5\u7B49\uFF09\uFF0C\u4F46\u662F\u6CE8\u89E3\u5E76\u4E0D\u662F\u6240\u88C5\u9970\u4EE3\u7801\u7684\u4E00\u90E8\u5206\uFF0C\u5B83\u5BF9\u4EE3\u7801\u7684\u8FD0\u884C\u6548\u679C\u6CA1\u6709\u76F4\u63A5\u5F71\u54CD\uFF0C\u7531\u7F16\u8BD1\u5668\u51B3\u5B9A\u8BE5\u6267\u884C\u54EA\u4E9B\u64CD\u4F5C\u3002

    \u6765\u770B\u4E00\u6BB5\u4EE3\u7801\u3002

    public class AutowiredTest {
    +import{_ as n}from"./plugin-vue_export-helper.21dcd24c.js";import{o as s,c as a,e as p}from"./app.615e41d8.js";const t={},e=p(`

    \u6DF1\u5165\u7406\u89E3Java\u6CE8\u89E3

    \u201C\u4E8C\u54E5\uFF0C\u8FD9\u8282\u8BB2\u6CE8\u89E3\u5417\uFF1F\u201D\u4E09\u59B9\u95EE\u3002

    \u201C\u662F\u7684\u3002\u201D\u6211\u8BF4\uFF0C\u201C\u6CE8\u89E3\u662F Java \u4E2D\u975E\u5E38\u91CD\u8981\u7684\u4E00\u90E8\u5206\uFF0C\u4F46\u7ECF\u5E38\u88AB\u5FFD\u89C6\u4E5F\u662F\u771F\u7684\u3002\u4E4B\u6240\u4EE5\u8FD9\u4E48\u8BF4\u662F\u56E0\u4E3A\u6211\u4EEC\u66F4\u503E\u5411\u6210\u4E3A\u4E00\u540D\u6CE8\u89E3\u7684\u4F7F\u7528\u8005\u800C\u4E0D\u662F\u521B\u5EFA\u8005\u3002@Override \u6CE8\u89E3\u7528\u8FC7\u5427\uFF1F\u4F46\u4F60\u77E5\u9053\u600E\u4E48\u81EA\u5B9A\u4E49\u4E00\u4E2A\u6CE8\u89E3\u5417\uFF1F\u201D

    \u4E09\u59B9\u6BEB\u4E0D\u72B9\u8C6B\u5730\u6447\u6447\u5934\uFF0C\u6446\u6446\u624B\uFF0C\u4E0D\u597D\u610F\u601D\u5730\u627F\u8BA4\u81EA\u5DF1\u7684\u786E\u6CA1\u6709\u81EA\u5B9A\u4E49\u8FC7\u3002

    \u201C\u597D\u5427\uFF0C\u54E5\u6765\u544A\u8BC9\u4F60\u5427\u3002\u201D

    \u6CE8\u89E3\uFF08Annotation\uFF09\u662F\u5728 Java 1.5 \u65F6\u5F15\u5165\u7684\u6982\u5FF5\uFF0C\u540C class \u548C interface \u4E00\u6837\uFF0C\u4E5F\u5C5E\u4E8E\u4E00\u79CD\u7C7B\u578B\u3002\u6CE8\u89E3\u63D0\u4F9B\u4E86\u4E00\u7CFB\u5217\u6570\u636E\u7528\u6765\u88C5\u9970\u7A0B\u5E8F\u4EE3\u7801\uFF08\u7C7B\u3001\u65B9\u6CD5\u3001\u5B57\u6BB5\u7B49\uFF09\uFF0C\u4F46\u662F\u6CE8\u89E3\u5E76\u4E0D\u662F\u6240\u88C5\u9970\u4EE3\u7801\u7684\u4E00\u90E8\u5206\uFF0C\u5B83\u5BF9\u4EE3\u7801\u7684\u8FD0\u884C\u6548\u679C\u6CA1\u6709\u76F4\u63A5\u5F71\u54CD\uFF0C\u7531\u7F16\u8BD1\u5668\u51B3\u5B9A\u8BE5\u6267\u884C\u54EA\u4E9B\u64CD\u4F5C\u3002

    \u6765\u770B\u4E00\u6BB5\u4EE3\u7801\u3002

    public class AutowiredTest {
         @Autowired
         private String name;
     
    diff --git a/dist/assets/aop-log.html.f3df7d62.js b/dist/assets/aop-log.html.ec10c829.js
    similarity index 99%
    rename from dist/assets/aop-log.html.f3df7d62.js
    rename to dist/assets/aop-log.html.ec10c829.js
    index d3e001ae..0c3aba40 100644
    --- a/dist/assets/aop-log.html.f3df7d62.js
    +++ b/dist/assets/aop-log.html.ec10c829.js
    @@ -1,4 +1,4 @@
    -import{_ as t}from"./plugin-vue_export-helper.21dcd24c.js";import{r as e,o as p,c as o,a as n,b as c,e as i,d as s}from"./app.a0271b9c.js";const l={},u=i(`

    Spring AOP \u626B\u76F2

    AOP \u662F Spring \u4F53\u7CFB\u4E2D\u975E\u5E38\u91CD\u8981\u7684\u4E24\u4E2A\u6982\u5FF5\u4E4B\u4E00\uFF08\u53E6\u5916\u4E00\u4E2A\u662F IoC\uFF09\uFF0C\u4ECA\u5929\u8FD9\u7BC7\u6587\u7AE0\u5C31\u6765\u5E26\u5927\u5BB6\u901A\u8FC7\u5B9E\u6218\u7684\u65B9\u5F0F\uFF0C\u5728\u7F16\u7A0B\u732B SpringBoot \u9879\u76EE\u4E2D\u4F7F\u7528 AOP \u6280\u672F\u4E3A controller \u5C42\u6DFB\u52A0\u4E00\u4E2A\u5207\u9762\u6765\u5B9E\u73B0\u63A5\u53E3\u8BBF\u95EE\u7684\u7EDF\u4E00\u65E5\u5FD7\u8BB0\u5F55\u3002

    \u4E00\u3001\u5173\u4E8E AOP

    AOP\uFF0C\u4E5F\u5C31\u662F Aspect-oriented Programming\uFF0C\u8BD1\u4E3A\u9762\u5411\u5207\u9762\u7F16\u7A0B\uFF0C\u662F\u8BA1\u7B97\u673A\u79D1\u5B66\u4E2D\u7684\u4E00\u4E2A\u8BBE\u8BA1\u601D\u60F3\uFF0C\u65E8\u5728\u901A\u8FC7\u5207\u9762\u6280\u672F\u4E3A\u4E1A\u52A1\u4E3B\u4F53\u589E\u52A0\u989D\u5916\u7684\u901A\u77E5\uFF08Advice\uFF09\uFF0C\u4ECE\u800C\u5BF9\u58F0\u660E\u4E3A\u201C\u5207\u70B9\u201D\uFF08Pointcut\uFF09\u7684\u4EE3\u7801\u5757\u8FDB\u884C\u7EDF\u4E00\u7BA1\u7406\u548C\u88C5\u9970\u3002

    \u8FD9\u79CD\u601D\u60F3\u975E\u5E38\u9002\u7528\u4E8E\uFF0C\u5C06\u90A3\u4E9B\u4E0E\u6838\u5FC3\u4E1A\u52A1\u4E0D\u90A3\u4E48\u5BC6\u5207\u5173\u8054\u7684\u529F\u80FD\u6DFB\u52A0\u5230\u7A0B\u5E8F\u4E2D\uFF0C\u5C31\u597D\u6BD4\u6211\u4EEC\u4ECA\u5929\u7684\u4E3B\u9898\u2014\u2014\u65E5\u5FD7\u529F\u80FD\uFF0C\u5C31\u662F\u4E00\u4E2A\u5178\u578B\u7684\u6848\u4F8B\u3002

    AOP \u662F\u5BF9\u9762\u5411\u5BF9\u8C61\u7F16\u7A0B\uFF08Object-oriented Programming\uFF0C\u4FD7\u79F0 OOP\uFF09\u7684\u4E00\u79CD\u8865\u5145\uFF0COOP \u7684\u6838\u5FC3\u5355\u5143\u662F\u7C7B\uFF08class\uFF09\uFF0C\u800C AOP \u7684\u6838\u5FC3\u5355\u5143\u662F\u5207\u9762\uFF08Aspect\uFF09\u3002\u5229\u7528 AOP \u53EF\u4EE5\u5BF9\u4E1A\u52A1\u903B\u8F91\u7684\u5404\u4E2A\u90E8\u5206\u8FDB\u884C\u9694\u79BB\uFF0C\u4ECE\u800C\u964D\u4F4E\u8026\u5408\u5EA6\uFF0C\u63D0\u9AD8\u7A0B\u5E8F\u7684\u53EF\u91CD\u7528\u6027\uFF0C\u540C\u65F6\u4E5F\u63D0\u9AD8\u4E86\u5F00\u53D1\u6548\u7387\u3002

    \u6211\u4EEC\u53EF\u4EE5\u7B80\u5355\u7684\u628A AOP \u7406\u89E3\u4E3A\u8D2F\u7A7F\u4E8E\u65B9\u6CD5\u4E4B\u4E2D\uFF0C\u5728\u65B9\u6CD5\u6267\u884C\u524D\u3001\u6267\u884C\u65F6\u3001\u6267\u884C\u540E\u3001\u8FD4\u56DE\u503C\u540E\u3001\u5F02\u5E38\u540E\u8981\u6267\u884C\u7684\u64CD\u4F5C\u3002

    \u4E8C\u3001AOP \u7684\u76F8\u5173\u672F\u8BED

    \u6765\u770B\u4E0B\u9762\u8FD9\u5E45\u56FE\uFF0C\u8FD9\u662F\u4E00\u4E2A AOP \u7684\u6A21\u578B\u56FE\uFF0C\u5C31\u662F\u5728\u67D0\u4E9B\u65B9\u6CD5\u6267\u884C\u524D\u540E\u6267\u884C\u4E00\u4E9B\u901A\u7528\u7684\u64CD\u4F5C\uFF0C\u5E76\u4E14\u8FD9\u4E9B\u64CD\u4F5C\u4E0D\u4F1A\u5F71\u54CD\u7A0B\u5E8F\u672C\u8EAB\u7684\u8FD0\u884C\u3002

    \u6211\u4EEC\u4E86\u89E3\u4E0B AOP \u6D89\u53CA\u5230\u7684 5 \u4E2A\u5173\u952E\u672F\u8BED\uFF1A

    1\uFF09\u6A2A\u5207\u5173\u6CE8\u70B9\uFF0C\u4ECE\u6BCF\u4E2A\u65B9\u6CD5\u4E2D\u62BD\u53D6\u51FA\u6765\u7684\u540C\u4E00\u7C7B\u975E\u6838\u5FC3\u4E1A\u52A1

    2\uFF09\u5207\u9762\uFF08Aspect\uFF09\uFF0C\u5BF9\u6A2A\u5207\u5173\u6CE8\u70B9\u8FDB\u884C\u5C01\u88C5\u7684\u7C7B\uFF0C\u6BCF\u4E2A\u5173\u6CE8\u70B9\u4F53\u73B0\u4E3A\u4E00\u4E2A\u901A\u77E5\u65B9\u6CD5\uFF1B\u901A\u5E38\u4F7F\u7528 @Aspect \u6CE8\u89E3\u6765\u5B9A\u4E49\u5207\u9762\u3002

    3\uFF09\u901A\u77E5\uFF08Advice\uFF09\uFF0C\u5207\u9762\u5FC5\u987B\u8981\u5B8C\u6210\u7684\u5404\u4E2A\u5177\u4F53\u5DE5\u4F5C\uFF0C\u6BD4\u5982\u6211\u4EEC\u7684\u65E5\u5FD7\u5207\u9762\u9700\u8981\u8BB0\u5F55\u63A5\u53E3\u8C03\u7528\u524D\u540E\u7684\u65F6\u957F\uFF0C\u5C31\u9700\u8981\u5728\u8C03\u7528\u63A5\u53E3\u524D\u540E\u8BB0\u5F55\u65F6\u95F4\uFF0C\u518D\u53D6\u5DEE\u503C\u3002\u901A\u77E5\u7684\u65B9\u5F0F\u6709\u4E94\u79CD\uFF1A

    • @Before\uFF1A\u901A\u77E5\u65B9\u6CD5\u4F1A\u5728\u76EE\u6807\u65B9\u6CD5\u8C03\u7528\u4E4B\u524D\u6267\u884C
    • @After\uFF1A\u901A\u77E5\u65B9\u6CD5\u4F1A\u5728\u76EE\u6807\u65B9\u6CD5\u8C03\u7528\u540E\u6267\u884C
    • @AfterReturning\uFF1A\u901A\u77E5\u65B9\u6CD5\u4F1A\u5728\u76EE\u6807\u65B9\u6CD5\u8FD4\u56DE\u540E\u6267\u884C
    • @AfterThrowing\uFF1A\u901A\u77E5\u65B9\u6CD5\u4F1A\u5728\u76EE\u6807\u65B9\u6CD5\u629B\u51FA\u5F02\u5E38\u540E\u6267\u884C
    • @Around\uFF1A\u628A\u6574\u4E2A\u76EE\u6807\u65B9\u6CD5\u5305\u88F9\u8D77\u6765\uFF0C\u5728\u88AB\u8C03\u7528\u524D\u548C\u8C03\u7528\u4E4B\u540E\u5206\u522B\u6267\u884C\u901A\u77E5\u65B9\u6CD5

    4\uFF09\u8FDE\u63A5\u70B9\uFF08JoinPoint\uFF09\uFF0C\u901A\u77E5\u5E94\u7528\u7684\u65F6\u673A\uFF0C\u6BD4\u5982\u63A5\u53E3\u65B9\u6CD5\u88AB\u8C03\u7528\u65F6\u5C31\u662F\u65E5\u5FD7\u5207\u9762\u7684\u8FDE\u63A5\u70B9\u3002

    5\uFF09\u5207\u70B9\uFF08Pointcut\uFF09\uFF0C\u901A\u77E5\u529F\u80FD\u88AB\u5E94\u7528\u7684\u8303\u56F4\uFF0C\u6BD4\u5982\u672C\u7BC7\u65E5\u5FD7\u5207\u9762\u7684\u5E94\u7528\u8303\u56F4\u662F\u6240\u6709 controller \u7684\u63A5\u53E3\u3002\u901A\u5E38\u4F7F\u7528 @Pointcut \u6CE8\u89E3\u6765\u5B9A\u4E49\u5207\u70B9\u8868\u8FBE\u5F0F\u3002

    \u5207\u5165\u70B9\u8868\u8FBE\u5F0F\u7684\u8BED\u6CD5\u683C\u5F0F\u89C4\u8303\u5982\u4E0B\u6240\u793A\uFF1A

    execution(modifiers-pattern? ret-type-pattern declaring-type-pattern?
    +import{_ as t}from"./plugin-vue_export-helper.21dcd24c.js";import{r as e,o as p,c as o,a as n,b as c,e as i,d as s}from"./app.615e41d8.js";const l={},u=i(`

    Spring AOP \u626B\u76F2

    AOP \u662F Spring \u4F53\u7CFB\u4E2D\u975E\u5E38\u91CD\u8981\u7684\u4E24\u4E2A\u6982\u5FF5\u4E4B\u4E00\uFF08\u53E6\u5916\u4E00\u4E2A\u662F IoC\uFF09\uFF0C\u4ECA\u5929\u8FD9\u7BC7\u6587\u7AE0\u5C31\u6765\u5E26\u5927\u5BB6\u901A\u8FC7\u5B9E\u6218\u7684\u65B9\u5F0F\uFF0C\u5728\u7F16\u7A0B\u732B SpringBoot \u9879\u76EE\u4E2D\u4F7F\u7528 AOP \u6280\u672F\u4E3A controller \u5C42\u6DFB\u52A0\u4E00\u4E2A\u5207\u9762\u6765\u5B9E\u73B0\u63A5\u53E3\u8BBF\u95EE\u7684\u7EDF\u4E00\u65E5\u5FD7\u8BB0\u5F55\u3002

    \u4E00\u3001\u5173\u4E8E AOP

    AOP\uFF0C\u4E5F\u5C31\u662F Aspect-oriented Programming\uFF0C\u8BD1\u4E3A\u9762\u5411\u5207\u9762\u7F16\u7A0B\uFF0C\u662F\u8BA1\u7B97\u673A\u79D1\u5B66\u4E2D\u7684\u4E00\u4E2A\u8BBE\u8BA1\u601D\u60F3\uFF0C\u65E8\u5728\u901A\u8FC7\u5207\u9762\u6280\u672F\u4E3A\u4E1A\u52A1\u4E3B\u4F53\u589E\u52A0\u989D\u5916\u7684\u901A\u77E5\uFF08Advice\uFF09\uFF0C\u4ECE\u800C\u5BF9\u58F0\u660E\u4E3A\u201C\u5207\u70B9\u201D\uFF08Pointcut\uFF09\u7684\u4EE3\u7801\u5757\u8FDB\u884C\u7EDF\u4E00\u7BA1\u7406\u548C\u88C5\u9970\u3002

    \u8FD9\u79CD\u601D\u60F3\u975E\u5E38\u9002\u7528\u4E8E\uFF0C\u5C06\u90A3\u4E9B\u4E0E\u6838\u5FC3\u4E1A\u52A1\u4E0D\u90A3\u4E48\u5BC6\u5207\u5173\u8054\u7684\u529F\u80FD\u6DFB\u52A0\u5230\u7A0B\u5E8F\u4E2D\uFF0C\u5C31\u597D\u6BD4\u6211\u4EEC\u4ECA\u5929\u7684\u4E3B\u9898\u2014\u2014\u65E5\u5FD7\u529F\u80FD\uFF0C\u5C31\u662F\u4E00\u4E2A\u5178\u578B\u7684\u6848\u4F8B\u3002

    AOP \u662F\u5BF9\u9762\u5411\u5BF9\u8C61\u7F16\u7A0B\uFF08Object-oriented Programming\uFF0C\u4FD7\u79F0 OOP\uFF09\u7684\u4E00\u79CD\u8865\u5145\uFF0COOP \u7684\u6838\u5FC3\u5355\u5143\u662F\u7C7B\uFF08class\uFF09\uFF0C\u800C AOP \u7684\u6838\u5FC3\u5355\u5143\u662F\u5207\u9762\uFF08Aspect\uFF09\u3002\u5229\u7528 AOP \u53EF\u4EE5\u5BF9\u4E1A\u52A1\u903B\u8F91\u7684\u5404\u4E2A\u90E8\u5206\u8FDB\u884C\u9694\u79BB\uFF0C\u4ECE\u800C\u964D\u4F4E\u8026\u5408\u5EA6\uFF0C\u63D0\u9AD8\u7A0B\u5E8F\u7684\u53EF\u91CD\u7528\u6027\uFF0C\u540C\u65F6\u4E5F\u63D0\u9AD8\u4E86\u5F00\u53D1\u6548\u7387\u3002

    \u6211\u4EEC\u53EF\u4EE5\u7B80\u5355\u7684\u628A AOP \u7406\u89E3\u4E3A\u8D2F\u7A7F\u4E8E\u65B9\u6CD5\u4E4B\u4E2D\uFF0C\u5728\u65B9\u6CD5\u6267\u884C\u524D\u3001\u6267\u884C\u65F6\u3001\u6267\u884C\u540E\u3001\u8FD4\u56DE\u503C\u540E\u3001\u5F02\u5E38\u540E\u8981\u6267\u884C\u7684\u64CD\u4F5C\u3002

    \u4E8C\u3001AOP \u7684\u76F8\u5173\u672F\u8BED

    \u6765\u770B\u4E0B\u9762\u8FD9\u5E45\u56FE\uFF0C\u8FD9\u662F\u4E00\u4E2A AOP \u7684\u6A21\u578B\u56FE\uFF0C\u5C31\u662F\u5728\u67D0\u4E9B\u65B9\u6CD5\u6267\u884C\u524D\u540E\u6267\u884C\u4E00\u4E9B\u901A\u7528\u7684\u64CD\u4F5C\uFF0C\u5E76\u4E14\u8FD9\u4E9B\u64CD\u4F5C\u4E0D\u4F1A\u5F71\u54CD\u7A0B\u5E8F\u672C\u8EAB\u7684\u8FD0\u884C\u3002

    \u6211\u4EEC\u4E86\u89E3\u4E0B AOP \u6D89\u53CA\u5230\u7684 5 \u4E2A\u5173\u952E\u672F\u8BED\uFF1A

    1\uFF09\u6A2A\u5207\u5173\u6CE8\u70B9\uFF0C\u4ECE\u6BCF\u4E2A\u65B9\u6CD5\u4E2D\u62BD\u53D6\u51FA\u6765\u7684\u540C\u4E00\u7C7B\u975E\u6838\u5FC3\u4E1A\u52A1

    2\uFF09\u5207\u9762\uFF08Aspect\uFF09\uFF0C\u5BF9\u6A2A\u5207\u5173\u6CE8\u70B9\u8FDB\u884C\u5C01\u88C5\u7684\u7C7B\uFF0C\u6BCF\u4E2A\u5173\u6CE8\u70B9\u4F53\u73B0\u4E3A\u4E00\u4E2A\u901A\u77E5\u65B9\u6CD5\uFF1B\u901A\u5E38\u4F7F\u7528 @Aspect \u6CE8\u89E3\u6765\u5B9A\u4E49\u5207\u9762\u3002

    3\uFF09\u901A\u77E5\uFF08Advice\uFF09\uFF0C\u5207\u9762\u5FC5\u987B\u8981\u5B8C\u6210\u7684\u5404\u4E2A\u5177\u4F53\u5DE5\u4F5C\uFF0C\u6BD4\u5982\u6211\u4EEC\u7684\u65E5\u5FD7\u5207\u9762\u9700\u8981\u8BB0\u5F55\u63A5\u53E3\u8C03\u7528\u524D\u540E\u7684\u65F6\u957F\uFF0C\u5C31\u9700\u8981\u5728\u8C03\u7528\u63A5\u53E3\u524D\u540E\u8BB0\u5F55\u65F6\u95F4\uFF0C\u518D\u53D6\u5DEE\u503C\u3002\u901A\u77E5\u7684\u65B9\u5F0F\u6709\u4E94\u79CD\uFF1A

    • @Before\uFF1A\u901A\u77E5\u65B9\u6CD5\u4F1A\u5728\u76EE\u6807\u65B9\u6CD5\u8C03\u7528\u4E4B\u524D\u6267\u884C
    • @After\uFF1A\u901A\u77E5\u65B9\u6CD5\u4F1A\u5728\u76EE\u6807\u65B9\u6CD5\u8C03\u7528\u540E\u6267\u884C
    • @AfterReturning\uFF1A\u901A\u77E5\u65B9\u6CD5\u4F1A\u5728\u76EE\u6807\u65B9\u6CD5\u8FD4\u56DE\u540E\u6267\u884C
    • @AfterThrowing\uFF1A\u901A\u77E5\u65B9\u6CD5\u4F1A\u5728\u76EE\u6807\u65B9\u6CD5\u629B\u51FA\u5F02\u5E38\u540E\u6267\u884C
    • @Around\uFF1A\u628A\u6574\u4E2A\u76EE\u6807\u65B9\u6CD5\u5305\u88F9\u8D77\u6765\uFF0C\u5728\u88AB\u8C03\u7528\u524D\u548C\u8C03\u7528\u4E4B\u540E\u5206\u522B\u6267\u884C\u901A\u77E5\u65B9\u6CD5

    4\uFF09\u8FDE\u63A5\u70B9\uFF08JoinPoint\uFF09\uFF0C\u901A\u77E5\u5E94\u7528\u7684\u65F6\u673A\uFF0C\u6BD4\u5982\u63A5\u53E3\u65B9\u6CD5\u88AB\u8C03\u7528\u65F6\u5C31\u662F\u65E5\u5FD7\u5207\u9762\u7684\u8FDE\u63A5\u70B9\u3002

    5\uFF09\u5207\u70B9\uFF08Pointcut\uFF09\uFF0C\u901A\u77E5\u529F\u80FD\u88AB\u5E94\u7528\u7684\u8303\u56F4\uFF0C\u6BD4\u5982\u672C\u7BC7\u65E5\u5FD7\u5207\u9762\u7684\u5E94\u7528\u8303\u56F4\u662F\u6240\u6709 controller \u7684\u63A5\u53E3\u3002\u901A\u5E38\u4F7F\u7528 @Pointcut \u6CE8\u89E3\u6765\u5B9A\u4E49\u5207\u70B9\u8868\u8FBE\u5F0F\u3002

    \u5207\u5165\u70B9\u8868\u8FBE\u5F0F\u7684\u8BED\u6CD5\u683C\u5F0F\u89C4\u8303\u5982\u4E0B\u6240\u793A\uFF1A

    execution(modifiers-pattern? ret-type-pattern declaring-type-pattern?
     				name-pattern(param-pattern)
                     throws-pattern?)
     
    • modifiers-pattern? \u4E3A\u8BBF\u95EE\u6743\u9650\u4FEE\u9970\u7B26
    • ret-type-pattern \u4E3A\u8FD4\u56DE\u7C7B\u578B\uFF0C\u901A\u5E38\u7528 * \u6765\u8868\u793A\u4EFB\u610F\u8FD4\u56DE\u7C7B\u578B
    • declaring-type-pattern? \u4E3A\u5305\u540D
    • name-pattern \u4E3A\u65B9\u6CD5\u540D\uFF0C\u53EF\u4EE5\u4F7F\u7528 * \u6765\u8868\u793A\u6240\u6709\uFF0C\u6216\u8005 set* \u6765\u8868\u793A\u6240\u6709\u4EE5 set \u5F00\u5934\u7684\u7C7B\u540D
    • param-pattern) \u4E3A\u53C2\u6570\u7C7B\u578B\uFF0C\u591A\u4E2A\u53C2\u6570\u53EF\u4EE5\u7528 , \u9694\u5F00\uFF0C\u5404\u4E2A\u53C2\u4E0E\u4E5F\u53EF\u4EE5\u4F7F\u7528 * \u6765\u8868\u793A\u6240\u6709\u7C7B\u578B\u7684\u53C2\u6570\uFF0C\u8FD8\u53EF\u4EE5\u4F7F\u7528 (..) \u8868\u793A\u96F6\u4E2A\u6216\u8005\u4EFB\u610F\u53C2\u6570
    • throws-pattern? \u4E3A\u5F02\u5E38\u7C7B\u578B
    • ? \u8868\u793A\u524D\u9762\u7684\u4E3A\u53EF\u9009\u9879

    \u4E3E\u4E2A\u4F8B\u5B50\uFF1A

    @Pointcut("execution(public * com.codingmore.controller.*.*(..))")
    diff --git a/dist/assets/api-wangguan.html.9f0edd64.js b/dist/assets/api-wangguan.html.ec8dd3f1.js
    similarity index 99%
    rename from dist/assets/api-wangguan.html.9f0edd64.js
    rename to dist/assets/api-wangguan.html.ec8dd3f1.js
    index 66126cee..4c8ff436 100644
    --- a/dist/assets/api-wangguan.html.9f0edd64.js
    +++ b/dist/assets/api-wangguan.html.ec8dd3f1.js
    @@ -1 +1 @@
    -import{_ as i}from"./plugin-vue_export-helper.21dcd24c.js";import{r as n,o,c as s,a as e,b as t,d as a,e as l}from"./app.a0271b9c.js";const g={},c=a("\u6574\u7406\uFF1A\u6C89\u9ED8\u738B\u4E8C\uFF0C\u6233"),p={href:"https://mp.weixin.qq.com/s/b2xf4GiJksBQqjHVpsh49Q",target:"_blank",rel:"noopener noreferrer"},d=a("\u8F6C\u8F7D\u94FE\u63A5"),h=a("\uFF0C\u4F5C\u8005\uFF1A\u697C\u4ED4\uFF0C\u6233"),b={href:"https://mp.weixin.qq.com/s/0Qupyl5eCyQGFEAIY6GxoQ",target:"_blank",rel:"noopener noreferrer"},u=a("\u539F\u6587\u94FE\u63A5"),f=a("\u3002"),m=l('

    \u5FAE\u670D\u52A1\u8FD1\u51E0\u5E74\u975E\u5E38\u706B\uFF0C\u56F4\u7ED5\u5FAE\u670D\u52A1\u7684\u6280\u672F\u751F\u6001\u4E5F\u6BD4\u8F83\u591A\uFF0C\u6BD4\u5982\u5FAE\u670D\u52A1\u7F51\u5173\u3001Docker\u3001Kubernetes\u7B49\u3002

    \u6211\u662F\u4E8E2019\u5E74\u5F00\u59CB\u63A5\u89E6\u5FAE\u670D\u52A1\u7F51\u5173\uFF0C\u5F53\u65F6\u548C\u516C\u53F8\u7684\u4E00\u4F4D\u540C\u4E8B\u4E00\u8D77\u5F00\u53D1\uFF0C\u7531\u4E8E\u6280\u672F\u80FD\u529B\u6709\u9650\uFF0C\u6211\u53EA\u8D1F\u8D23\u7F51\u5173\u540E\u53F0\uFF0C\u540E\u7EED\u5FAE\u670D\u52A1\u7F51\u5173\u7684\u8FED\u4EE3\uFF0C\u6211\u5176\u5B9E\u6CA1\u6709\u53C2\u4E0E\uFF0C\u4E0D\u8FC7\u540E\u6765\u62BD\u7A7A\u770B\u4E86\u5FAE\u670D\u52A1\u7F51\u5173\u524D\u53F0\u7684\u4EE3\u7801\uFF0C\u6240\u4EE5\u5BF9\u8FD9\u5957\u5FAE\u670D\u52A1\u7F51\u5173\u7684\u5B9E\u73B0\u539F\u7406\u7B97\u662F\u57FA\u672C\u638C\u63E1\u3002

    \u6700\u8FD1\u5728\u5199\u6280\u672F\u6808\u76F8\u5173\u7684\u6587\u7AE0\uFF0C\u521A\u597D\u5199\u5230\u5FAE\u670D\u52A1\u7F51\u5173\uFF0C\u5C31\u628A\u4E4B\u524D\u5B66\u4E60\u7684\u77E5\u8BC6\u8FDB\u884C\u7B80\u5355\u603B\u7ED3\uFF0C\u540C\u65F6\u4E5F\u628A\u5E02\u9762\u4E0A\u5E38\u7528\u7684\u5FAE\u670D\u52A1\u7F51\u5173\u8FDB\u884C\u68B3\u7406\uFF0C\u4E00\u65B9\u9762\u4FBF\u4E8E\u540E\u7EED\u6280\u672F\u9009\u578B\uFF0C\u53E6\u4E00\u65B9\u9762\u4E5F\u7B97\u662F\u7ED9\u81EA\u5DF1\u4E00\u4E2A\u4EA4\u4EE3\u3002\u4E0B\u9762\u662F\u6587\u7AE0\u76EE\u5F55\uFF1A

    API\u7F51\u5173\u57FA\u7840

    \u4EC0\u4E48\u662FAPI\u7F51\u5173

    API\u7F51\u5173\u662F\u4E00\u4E2A\u670D\u52A1\u5668\uFF0C\u662F\u7CFB\u7EDF\u7684\u552F\u4E00\u5165\u53E3\u3002 \u4ECE\u9762\u5411\u5BF9\u8C61\u8BBE\u8BA1\u7684\u89D2\u5EA6\u770B\uFF0C\u5B83\u4E0E\u5916\u89C2\u6A21\u5F0F\u7C7B\u4F3C\u3002

    API\u7F51\u5173\u5C01\u88C5\u4E86\u7CFB\u7EDF\u5185\u90E8\u67B6\u6784\uFF0C\u4E3A\u6BCF\u4E2A\u5BA2\u6237\u7AEF\u63D0\u4F9B\u4E00\u4E2A\u5B9A\u5236\u7684API\u3002\u5B83\u53EF\u80FD\u8FD8\u5177\u6709\u5176\u5B83\u804C\u8D23\uFF0C\u5982\u8EAB\u4EFD\u9A8C\u8BC1\u3001\u76D1\u63A7\u3001\u8D1F\u8F7D\u5747\u8861\u3001\u7F13\u5B58\u3001\u534F\u8BAE\u8F6C\u6362\u3001\u9650\u6D41\u7194\u65AD\u3001\u9759\u6001\u54CD\u5E94\u5904\u7406\u3002

    API\u7F51\u5173\u65B9\u5F0F\u7684\u6838\u5FC3\u8981\u70B9\u662F\uFF0C\u6240\u6709\u7684\u5BA2\u6237\u7AEF\u548C\u6D88\u8D39\u7AEF\u90FD\u901A\u8FC7\u7EDF\u4E00\u7684\u7F51\u5173\u63A5\u5165\u5FAE\u670D\u52A1\uFF0C\u5728\u7F51\u5173\u5C42\u5904\u7406\u6240\u6709\u7684\u975E\u4E1A\u52A1\u529F\u80FD\u3002\u901A\u5E38\uFF0C\u7F51\u5173\u4E5F\u662F\u63D0\u4F9BREST/HTTP\u7684\u8BBF\u95EEAPI\u3002

    \u7F51\u5173\u7684\u4E3B\u8981\u529F\u80FD

    \u5FAE\u670D\u52A1\u7F51\u5173\u4F5C\u4E3A\u5FAE\u670D\u52A1\u540E\u7AEF\u670D\u52A1\u7684\u7EDF\u4E00\u5165\u53E3\uFF0C\u5B83\u53EF\u4EE5\u7EDF\u7B79\u7BA1\u7406\u540E\u7AEF\u670D\u52A1\uFF0C\u4E3B\u8981\u5206\u4E3A\u6570\u636E\u5E73\u9762\u548C\u63A7\u5236\u5E73\u9762\uFF1A

    • \u6570\u636E\u5E73\u9762\u4E3B\u8981\u529F\u80FD\u662F\u63A5\u5165\u7528\u6237\u7684HTTP\u8BF7\u6C42\u548C\u5FAE\u670D\u52A1\u88AB\u62C6\u5206\u540E\u7684\u805A\u5408\u3002\u4F7F\u7528\u5FAE\u670D\u52A1\u7F51\u5173\u7EDF\u4E00\u5BF9\u5916\u66B4\u9732\u540E\u7AEF\u670D\u52A1\u7684API\u548C\u5951\u7EA6\uFF0C\u8DEF\u7531\u548C\u8FC7\u6EE4\u529F\u80FD\u6B63\u662F\u7F51\u5173\u7684\u6838\u5FC3\u80FD\u529B\u6A21\u5757\u3002\u53E6\u5916\uFF0C\u5FAE\u670D\u52A1\u7F51\u5173\u53EF\u4EE5\u5B9E\u73B0\u62E6\u622A\u673A\u5236\u548C\u4E13\u6CE8\u8DE8\u6A2A\u5207\u9762\u7684\u529F\u80FD\uFF0C\u5305\u62EC\u534F\u8BAE\u8F6C\u6362\u3001\u5B89\u5168\u8BA4\u8BC1\u3001\u7194\u65AD\u9650\u6D41\u3001\u7070\u5EA6\u53D1\u5E03\u3001\u65E5\u5FD7\u7BA1\u7406\u3001\u6D41\u91CF\u76D1\u63A7\u7B49\u3002
    • \u63A7\u5236\u5E73\u9762\u4E3B\u8981\u529F\u80FD\u662F\u5BF9\u540E\u7AEF\u670D\u52A1\u505A\u7EDF\u4E00\u7684\u7BA1\u63A7\u548C\u914D\u7F6E\u7BA1\u7406\u3002\u4F8B\u5982\uFF0C\u53EF\u4EE5\u63A7\u5236\u7F51\u5173\u7684\u5F39\u6027\u4F38\u7F29\uFF1B\u53EF\u4EE5\u7EDF\u4E00\u4E0B\u53D1\u914D\u7F6E\uFF1B\u53EF\u4EE5\u5BF9\u7F51\u5173\u670D\u52A1\u6DFB\u52A0\u6807\u7B7E\uFF1B\u53EF\u4EE5\u5728\u5FAE\u670D\u52A1\u7F51\u5173\u4E0A\u901A\u8FC7\u914D\u7F6ESwagger\u529F\u80FD\u7EDF\u4E00\u5C06\u540E\u7AEF\u670D\u52A1\u7684API\u5951\u7EA6\u66B4\u9732\u7ED9\u4F7F\u7528\u65B9\uFF0C\u5B8C\u6210\u6587\u6863\u670D\u52A1\uFF0C\u63D0\u9AD8\u5DE5\u4F5C\u6548\u7387\u548C\u964D\u4F4E\u6C9F\u901A\u6210\u672C\u3002

    • \u8DEF\u7531\u529F\u80FD\uFF1A\u8DEF\u7531\u662F\u5FAE\u670D\u52A1\u7F51\u5173\u7684\u6838\u5FC3\u80FD\u529B\u3002\u901A\u8FC7\u8DEF\u7531\u529F\u80FD\u5FAE\u670D\u52A1\u7F51\u5173\u53EF\u4EE5\u5C06\u8BF7\u6C42\u8F6C\u53D1\u5230\u76EE\u6807\u5FAE\u670D\u52A1\u3002\u5728\u5FAE\u670D\u52A1\u67B6\u6784\u4E2D\uFF0C\u7F51\u5173\u53EF\u4EE5\u7ED3\u5408\u6CE8\u518C\u4E2D\u5FC3\u7684\u52A8\u6001\u670D\u52A1\u53D1\u73B0\uFF0C\u5B9E\u73B0\u5BF9\u540E\u7AEF\u670D\u52A1\u7684\u53D1\u73B0\uFF0C\u8C03\u7528\u65B9\u53EA\u9700\u8981\u77E5\u9053\u7F51\u5173\u5BF9\u5916\u66B4\u9732\u7684\u670D\u52A1API\u5C31\u53EF\u4EE5\u900F\u660E\u5730\u8BBF\u95EE\u540E\u7AEF\u5FAE\u670D\u52A1\u3002
    • \u8D1F\u8F7D\u5747\u8861\uFF1AAPI\u7F51\u5173\u7ED3\u5408\u8D1F\u8F7D\u5747\u8861\u6280\u672F\uFF0C\u5229\u7528Eureka\u6216\u8005Consul\u7B49\u670D\u52A1\u53D1\u73B0\u5DE5\u5177\uFF0C\u901A\u8FC7\u8F6E\u8BE2\u3001\u6307\u5B9A\u6743\u91CD\u3001IP\u5730\u5740\u54C8\u5E0C\u7B49\u673A\u5236\u5B9E\u73B0\u4E0B\u6E38\u670D\u52A1\u7684\u8D1F\u8F7D\u5747\u8861\u3002
    • \u7EDF\u4E00\u9274\u6743\uFF1A\u4E00\u822C\u800C\u8A00\uFF0C\u65E0\u8BBA\u5BF9\u5185\u7F51\u8FD8\u662F\u5916\u7F51\u7684\u63A5\u53E3\u90FD\u9700\u8981\u505A\u7528\u6237\u8EAB\u4EFD\u8BA4\u8BC1\uFF0C\u800C\u7528\u6237\u8BA4\u8BC1\u5728\u4E00\u4E9B\u89C4\u6A21\u8F83\u5927\u7684\u7CFB\u7EDF\u4E2D\u90FD\u4F1A\u91C7\u7528\u7EDF\u4E00\u7684\u5355\u70B9\u767B\u5F55\uFF08Single Sign On\uFF09\u7CFB\u7EDF\uFF0C\u5982\u679C\u6BCF\u4E2A\u5FAE\u670D\u52A1\u90FD\u8981\u5BF9\u63A5\u5355\u70B9\u767B\u5F55\u7CFB\u7EDF\uFF0C\u90A3\u4E48\u663E\u7136\u6BD4\u8F83\u6D6A\u8D39\u8D44\u6E90\u4E14\u5F00\u53D1\u6548\u7387\u4F4E\u3002API\u7F51\u5173\u662F\u7EDF\u4E00\u7BA1\u7406\u5B89\u5168\u6027\u7684\u7EDD\u4F73\u573A\u6240\uFF0C\u53EF\u4EE5\u5C06\u8BA4\u8BC1\u7684\u90E8\u5206\u62BD\u53D6\u5230\u7F51\u5173\u5C42\uFF0C\u5FAE\u670D\u52A1\u7CFB\u7EDF\u65E0\u987B\u5173\u6CE8\u8BA4\u8BC1\u7684\u903B\u8F91\uFF0C\u53EA\u5173\u6CE8\u81EA\u8EAB\u4E1A\u52A1\u5373\u53EF\u3002
    • \u534F\u8BAE\u8F6C\u6362\uFF1AAPI\u7F51\u5173\u7684\u4E00\u5927\u4F5C\u7528\u5728\u4E8E\u6784\u5EFA\u5F02\u6784\u7CFB\u7EDF\uFF0CAPI\u7F51\u5173\u4F5C\u4E3A\u5355\u4E00\u5165\u53E3\uFF0C\u901A\u8FC7\u534F\u8BAE\u8F6C\u6362\u6574\u5408\u540E\u53F0\u57FA\u4E8EREST\u3001AMQP\u3001Dubbo\u7B49\u4E0D\u540C\u98CE\u683C\u548C\u5B9E\u73B0\u6280\u672F\u7684\u5FAE\u670D\u52A1\uFF0C\u9762\u5411Web Mobile\u3001\u5F00\u653E\u5E73\u53F0\u7B49\u7279\u5B9A\u5BA2\u6237\u7AEF\u63D0\u4F9B\u7EDF\u4E00\u670D\u52A1\u3002
    • \u6307\u6807\u76D1\u63A7\uFF1A\u7F51\u5173\u53EF\u4EE5\u7EDF\u8BA1\u540E\u7AEF\u670D\u52A1\u7684\u8BF7\u6C42\u6B21\u6570\uFF0C\u5E76\u4E14\u53EF\u4EE5\u5B9E\u65F6\u5730\u66F4\u65B0\u5F53\u524D\u7684\u6D41\u91CF\u5065\u5EB7\u72B6\u6001\uFF0C\u53EF\u4EE5\u5BF9URL\u7C92\u5EA6\u7684\u670D\u52A1\u8FDB\u884C\u5EF6\u8FDF\u7EDF\u8BA1\uFF0C\u4E5F\u53EF\u4EE5\u4F7F\u7528Hystrix Dashboard\u67E5\u770B\u540E\u7AEF\u670D\u52A1\u7684\u6D41\u91CF\u72B6\u6001\u53CA\u662F\u5426\u6709\u7194\u65AD\u53D1\u751F\u3002
    • \u9650\u6D41\u7194\u65AD\uFF1A\u5728\u67D0\u4E9B\u573A\u666F\u4E0B\u9700\u8981\u63A7\u5236\u5BA2\u6237\u7AEF\u7684\u8BBF\u95EE\u6B21\u6570\u548C\u8BBF\u95EE\u9891\u7387\uFF0C\u4E00\u4E9B\u9AD8\u5E76\u53D1\u7CFB\u7EDF\u6709\u65F6\u8FD8\u4F1A\u6709\u9650\u6D41\u7684\u9700\u6C42\u3002\u5728\u7F51\u5173\u4E0A\u53EF\u4EE5\u914D\u7F6E\u4E00\u4E2A\u9608\u503C\uFF0C\u5F53\u8BF7\u6C42\u6570\u8D85\u8FC7\u9608\u503C\u65F6\u5C31\u76F4\u63A5\u8FD4\u56DE\u9519\u8BEF\u800C\u4E0D\u7EE7\u7EED\u8BBF\u95EE\u540E\u53F0\u670D\u52A1\u3002\u5F53\u51FA\u73B0\u6D41\u91CF\u6D2A\u5CF0\u6216\u8005\u540E\u7AEF\u670D\u52A1\u51FA\u73B0\u5EF6\u8FDF\u6216\u6545\u969C\u65F6\uFF0C\u7F51\u5173\u80FD\u591F\u4E3B\u52A8\u8FDB\u884C\u7194\u65AD\uFF0C\u4FDD\u62A4\u540E\u7AEF\u670D\u52A1\uFF0C\u5E76\u4FDD\u6301\u524D\u7AEF\u7528\u6237\u4F53\u9A8C\u826F\u597D\u3002
    • \u9ED1\u767D\u540D\u5355\uFF1A\u5FAE\u670D\u52A1\u7F51\u5173\u53EF\u4EE5\u4F7F\u7528\u7CFB\u7EDF\u9ED1\u540D\u5355\uFF0C\u8FC7\u6EE4HTTP\u8BF7\u6C42\u7279\u5F81\uFF0C\u62E6\u622A\u5F02\u5E38\u5BA2\u6237\u7AEF\u7684\u8BF7\u6C42\uFF0C\u4F8B\u5982DDoS\u653B\u51FB\u7B49\u4FB5\u8680\u5E26\u5BBD\u6216\u8D44\u6E90\u8FEB\u4F7F\u670D\u52A1\u4E2D\u65AD\u7B49\u884C\u4E3A\uFF0C\u53EF\u4EE5\u5728\u7F51\u5173\u5C42\u9762\u8FDB\u884C\u62E6\u622A\u8FC7\u6EE4\u3002\u6BD4\u8F83\u5E38\u89C1\u7684\u62E6\u622A\u7B56\u7565\u662F\u6839\u636EIP\u5730\u5740\u589E\u52A0\u9ED1\u540D\u5355\u3002\u5728\u5B58\u5728\u9274\u6743\u7BA1\u7406\u7684\u8DEF\u7531\u670D\u52A1\u4E2D\u53EF\u4EE5\u901A\u8FC7\u8BBE\u7F6E\u767D\u540D\u5355\u8DF3\u8FC7\u9274\u6743\u7BA1\u7406\u800C\u76F4\u63A5\u8BBF\u95EE\u540E\u7AEF\u670D\u52A1\u8D44\u6E90\u3002
    • \u7070\u5EA6\u53D1\u5E03\uFF1A\u5FAE\u670D\u52A1\u7F51\u5173\u53EF\u4EE5\u6839\u636EHTTP\u8BF7\u6C42\u4E2D\u7684\u7279\u6B8A\u6807\u8BB0\u548C\u540E\u7AEF\u670D\u52A1\u5217\u8868\u5143\u6570\u636E\u6807\u8BC6\u8FDB\u884C\u6D41\u91CF\u63A7\u5236\uFF0C\u5B9E\u73B0\u5728\u7528\u6237\u65E0\u611F\u77E5\u7684\u60C5\u51B5\u4E0B\u5B8C\u6210\u7070\u5EA6\u53D1\u5E03\u3002
    • \u6D41\u91CF\u67D3\u8272\uFF1A\u548C\u7070\u5EA6\u53D1\u5E03\u7684\u539F\u7406\u76F8\u4F3C\uFF0C\u7F51\u5173\u53EF\u4EE5\u6839\u636EHTTP\u8BF7\u6C42\u7684Host\u3001Head\u3001Agent\u7B49\u6807\u8BC6\u5BF9\u8BF7\u6C42\u8FDB\u884C\u67D3\u8272\uFF0C\u6709\u4E86\u7F51\u5173\u7684\u6D41\u91CF\u67D3\u8272\u529F\u80FD\uFF0C\u6211\u4EEC\u53EF\u4EE5\u5BF9\u670D\u52A1\u540E\u7EED\u7684\u8C03\u7528\u94FE\u8DEF\u8FDB\u884C\u8DDF\u8E2A\uFF0C\u5BF9\u670D\u52A1\u5EF6\u8FDF\u53CA\u670D\u52A1\u8FD0\u884C\u72B6\u51B5\u8FDB\u884C\u8FDB\u4E00\u6B65\u7684\u94FE\u8DEF\u5206\u6790\u3002
    • \u6587\u6863\u4E2D\u5FC3\uFF1A\u7F51\u5173\u7ED3\u5408Swagger\uFF0C\u53EF\u4EE5\u5C06\u540E\u7AEF\u7684\u5FAE\u670D\u52A1\u66B4\u9732\u7ED9\u7F51\u5173\uFF0C\u7F51\u5173\u4F5C\u4E3A\u7EDF\u4E00\u7684\u5165\u53E3\u7ED9\u63A5\u53E3\u7684\u4F7F\u7528\u65B9\u63D0\u4F9B\u67E5\u770B\u540E\u7AEF\u670D\u52A1\u7684API\u89C4\u8303\uFF0C\u4E0D\u9700\u8981\u77E5\u9053\u6BCF\u4E00\u4E2A\u540E\u7AEF\u5FAE\u670D\u52A1\u7684Swagger\u5730\u5740\uFF0C\u8FD9\u6837\u7F51\u5173\u8D77\u5230\u4E86\u5BF9\u540E\u7AEFAPI\u805A\u5408\u7684\u6548\u679C\u3002
    • \u65E5\u5FD7\u5BA1\u8BA1\uFF1A\u5FAE\u670D\u52A1\u7F51\u5173\u53EF\u4EE5\u4F5C\u4E3A\u7EDF\u4E00\u7684\u65E5\u5FD7\u8BB0\u5F55\u548C\u6536\u96C6\u5668\uFF0C\u5BF9\u670D\u52A1URL\u7C92\u5EA6\u7684\u65E5\u5FD7\u8BF7\u6C42\u4FE1\u606F\u548C\u54CD\u5E94\u4FE1\u606F\u8FDB\u884C\u62E6\u622A\u3002

    API\u7F51\u5173\u9009\u578B

    \u5E38\u7528API\u7F51\u5173

    \u5148\u7B80\u5355\u770B\u4E00\u4E0B\u5E02\u9762\u4E0A\u5E38\u7528\u7684API\u7F51\u5173\uFF1A

    Nginx

    Nginx\u662F\u4E00\u4E2A\u9AD8\u6027\u80FD\u7684HTTP\u548C\u53CD\u5411\u4EE3\u7406\u670D\u52A1\u5668\u3002Nginx\u4E00\u65B9\u9762\u53EF\u4EE5\u505A\u53CD\u5411\u4EE3\u7406\uFF0C\u53E6\u5916\u4E00\u65B9\u9762\u53EF\u4EE5\u505A\u9759\u6001\u8D44\u6E90\u670D\u52A1\u5668\uFF0C\u63A5\u53E3\u4F7F\u7528Lua\u52A8\u6001\u8BED\u8A00\u53EF\u4EE5\u5B8C\u6210\u7075\u6D3B\u7684\u5B9A\u5236\u529F\u80FD\u3002

    Nginx \u5728\u542F\u52A8\u540E\uFF0C\u4F1A\u6709\u4E00\u4E2A Master \u8FDB\u7A0B\u548C\u591A\u4E2A Worker \u8FDB\u7A0B\uFF0CMaster \u8FDB\u7A0B\u548C Worker \u8FDB\u7A0B\u4E4B\u95F4\u662F\u901A\u8FC7\u8FDB\u7A0B\u95F4\u901A\u4FE1\u8FDB\u884C\u4EA4\u4E92\u7684\uFF0C\u5982\u56FE\u6240\u793A\u3002Worker \u5DE5\u4F5C\u8FDB\u7A0B\u7684\u963B\u585E\u70B9\u662F\u5728\u50CF select()\u3001epoll_wait() \u7B49\u8FD9\u6837\u7684 I/O \u591A\u8DEF\u590D\u7528\u51FD\u6570\u8C03\u7528\u5904\uFF0C\u4EE5\u7B49\u5F85\u53D1\u751F\u6570\u636E\u53EF\u8BFB / \u5199\u4E8B\u4EF6\u3002Nginx \u91C7\u7528\u4E86\u5F02\u6B65\u975E\u963B\u585E\u7684\u65B9\u5F0F\u6765\u5904\u7406\u8BF7\u6C42\uFF0C\u4E5F\u5C31\u662F\u8BF4\uFF0CNginx \u662F\u53EF\u4EE5\u540C\u65F6\u5904\u7406\u6210\u5343\u4E0A\u4E07\u4E2A\u8BF7\u6C42\u7684\u3002

    Zuul

    Zuul \u662F Netflix \u5F00\u6E90\u7684\u4E00\u4E2AAPI\u7F51\u5173\u7EC4\u4EF6\uFF0C\u5B83\u53EF\u4EE5\u548C Eureka\u3001Ribbon\u3001Hystrix \u7B49\u7EC4\u4EF6\u914D\u5408\u4F7F\u7528\u3002\u793E\u533A\u6D3B\u8DC3\uFF0C\u878D\u5408\u4E8E SpringCloud \u5B8C\u6574\u751F\u6001\uFF0C\u662F\u6784\u5EFA\u5FAE\u670D\u52A1\u4F53\u7CFB\u524D\u7F6E\u7F51\u5173\u670D\u52A1\u7684\u6700\u4F73\u9009\u578B\u4E4B\u4E00\u3002

    Zuul \u7684\u6838\u5FC3\u662F\u4E00\u7CFB\u5217\u7684\u8FC7\u6EE4\u5668\uFF0C\u8FD9\u4E9B\u8FC7\u6EE4\u5668\u53EF\u4EE5\u5B8C\u6210\u4EE5\u4E0B\u529F\u80FD\uFF1A

    • \u7EDF\u4E00\u9274\u6743 + \u52A8\u6001\u8DEF\u7531 + \u8D1F\u8F7D\u5747\u8861 + \u538B\u529B\u6D4B\u8BD5
    • \u5BA1\u67E5\u4E0E\u76D1\u63A7\uFF1A\u4E0E\u8FB9\u7F18\u4F4D\u7F6E\u8FFD\u8E2A\u6709\u610F\u4E49\u7684\u6570\u636E\u548C\u7EDF\u8BA1\u7ED3\u679C\uFF0C\u4ECE\u800C\u5E26\u6765\u7CBE\u786E\u7684\u751F\u4EA7\u89C6\u56FE\u3002
    • \u591A\u533A\u57DF\u5F39\u6027\uFF1A\u8DE8\u8D8A AWS Region \u8FDB\u884C\u8BF7\u6C42\u8DEF\u7531\uFF0C\u65E8\u5728\u5B9E\u73B0 ELB\uFF08Elastic Load Balancing\uFF0C\u5F39\u6027\u8D1F\u8F7D\u5747\u8861\uFF09\u4F7F\u7528\u7684\u591A\u6837\u5316\uFF0C\u4EE5\u53CA\u8BA9\u7CFB\u7EDF\u7684\u8FB9\u7F18\u66F4\u8D34\u8FD1\u7CFB\u7EDF\u7684\u4F7F\u7528\u8005\u3002

    Zuul \u76EE\u524D\u6709\u4E24\u4E2A\u5927\u7684\u7248\u672C\uFF1AZuul1 \u548C Zuul2

    Zuul1 \u662F\u57FA\u4E8E Servlet \u6846\u67B6\u6784\u5EFA\uFF0C\u5982\u56FE\u6240\u793A\uFF0C\u91C7\u7528\u7684\u662F\u963B\u585E\u548C\u591A\u7EBF\u7A0B\u65B9\u5F0F\uFF0C\u5373\u4E00\u4E2A\u7EBF\u7A0B\u5904\u7406\u4E00\u6B21\u8FDE\u63A5\u8BF7\u6C42\uFF0C\u8FD9\u79CD\u65B9\u5F0F\u5728\u5185\u90E8\u5EF6\u8FDF\u4E25\u91CD\u3001\u8BBE\u5907\u6545\u969C\u8F83\u591A\u60C5\u51B5\u4E0B\u4F1A\u5F15\u8D77\u5B58\u6D3B\u7684\u8FDE\u63A5\u589E\u591A\u548C\u7EBF\u7A0B\u589E\u52A0\u7684\u60C5\u51B5\u53D1\u751F\u3002

    Netflix \u53D1\u5E03\u7684 Zuul2 \u6709\u91CD\u5927\u7684\u66F4\u65B0\uFF0C\u5B83\u8FD0\u884C\u5728\u5F02\u6B65\u548C\u65E0\u963B\u585E\u6846\u67B6\u4E0A\uFF0C\u6BCF\u4E2A CPU \u6838\u4E00\u4E2A\u7EBF\u7A0B\uFF0C\u5904\u7406\u6240\u6709\u7684\u8BF7\u6C42\u548C\u54CD\u5E94\uFF0C\u8BF7\u6C42\u548C\u54CD\u5E94\u7684\u751F\u547D\u5468\u671F\u662F\u901A\u8FC7\u4E8B\u4EF6\u548C\u56DE\u8C03\u6765\u5904\u7406\u7684\uFF0C\u8FD9\u79CD\u65B9\u5F0F\u51CF\u5C11\u4E86\u7EBF\u7A0B\u6570\u91CF\uFF0C\u56E0\u6B64\u5F00\u9500\u8F83\u5C0F\u3002

    Spring Cloud GetWay

    Spring Cloud Gateway \u662FSpring Cloud\u7684\u4E00\u4E2A\u5168\u65B0\u7684API\u7F51\u5173\u9879\u76EE\uFF0C\u76EE\u7684\u662F\u4E3A\u4E86\u66FF\u6362\u6389Zuul1\uFF0C\u5B83\u57FA\u4E8ESpring5.0 + SpringBoot2.0 + WebFlux\uFF08\u57FA\u4E8E\u2FBC\u6027\u80FD\u7684Reactor\u6A21\u5F0F\u54CD\u5E94\u5F0F\u901A\u4FE1\u6846\u67B6Netty\uFF0C\u5F02\u6B65\u2FAE\u963B\u585E\u6A21\u578B\uFF09\u7B49\u6280\u672F\u5F00\u53D1\uFF0C\u6027\u80FD\u2FBC\u4E8EZuul\uFF0C\u5B98\u2F45\u6D4B\u8BD5\uFF0CSpring Cloud GateWay\u662FZuul\u76841.6\u500D\uFF0C\u65E8\u5728\u4E3A\u5FAE\u670D\u52A1\u67B6\u6784\u63D0\u4F9B\u2F00\u79CD\u7B80\u5355\u6709\u6548\u7684\u7EDF\u2F00\u7684API\u8DEF\u7531\u7BA1\u7406\u2F45\u5F0F\u3002

    Spring Cloud Gateway\u53EF\u4EE5\u4E0ESpring Cloud Discovery Client\uFF08\u5982Eureka\uFF09\u3001Ribbon\u3001Hystrix\u7B49\u7EC4\u4EF6\u914D\u5408\u4F7F\u7528\uFF0C\u5B9E\u73B0\u8DEF\u7531\u8F6C\u53D1\u3001\u8D1F\u8F7D\u5747\u8861\u3001\u7194\u65AD\u3001\u9274\u6743\u3001\u8DEF\u5F84\u91CD\u5199\u3001\u2F47\u5FD7\u76D1\u63A7\u7B49\uFF0C\u5E76\u4E14Gateway\u8FD8\u5185\u7F6E\u4E86\u9650\u6D41\u8FC7\u6EE4\u5668\uFF0C\u5B9E\u73B0\u4E86\u9650\u6D41\u7684\u529F\u80FD\u3002

    Kong

    Kong\u662F\u4E00\u6B3E\u57FA\u4E8EOpenResty\uFF08Nginx + Lua\u6A21\u5757\uFF09\u7F16\u5199\u7684\u9AD8\u53EF\u7528\u3001\u6613\u6269\u5C55\u7684\uFF0C\u7531Mashape\u516C\u53F8\u5F00\u6E90\u7684API Gateway\u9879\u76EE\u3002Kong\u662F\u57FA\u4E8ENGINX\u548CApache Cassandra\u6216PostgreSQL\u6784\u5EFA\u7684\uFF0C\u80FD\u63D0\u4F9B\u6613\u4E8E\u4F7F\u7528\u7684RESTful API\u6765\u64CD\u4F5C\u548C\u914D\u7F6EAPI\u7BA1\u7406\u7CFB\u7EDF\uFF0C\u6240\u4EE5\u5B83\u53EF\u4EE5\u6C34\u5E73\u6269\u5C55\u591A\u4E2AKong\u670D\u52A1\u5668\uFF0C\u901A\u8FC7\u524D\u7F6E\u7684\u8D1F\u8F7D\u5747\u8861\u914D\u7F6E\u628A\u8BF7\u6C42\u5747\u5300\u5730\u5206\u53D1\u5230\u5404\u4E2AServer\uFF0C\u6765\u5E94\u5BF9\u5927\u6279\u91CF\u7684\u7F51\u7EDC\u8BF7\u6C42\u3002

    Kong\u4E3B\u8981\u6709\u4E09\u4E2A\u7EC4\u4EF6\uFF1A

    • Kong Server \uFF1A\u57FA\u4E8ENginx\u7684\u670D\u52A1\u5668\uFF0C\u7528\u6765\u63A5\u6536API\u8BF7\u6C42\u3002
    • Apache Cassandra/PostgreSQL \uFF1A\u7528\u6765\u5B58\u50A8\u64CD\u4F5C\u6570\u636E\u3002
    • Kong dashboard\uFF1A\u5B98\u65B9\u63A8\u8350UI\u7BA1\u7406\u5DE5\u5177\uFF0C\u4E5F\u53EF\u4EE5\u4F7F\u7528 restfull \u65B9\u5F0F\u7BA1\u7406admin api\u3002

    Kong\u91C7\u7528\u63D2\u4EF6\u673A\u5236\u8FDB\u884C\u529F\u80FD\u5B9A\u5236\uFF0C\u63D2\u4EF6\u96C6\uFF08\u53EF\u4EE5\u662F0\u6216N\u4E2A\uFF09\u5728API\u8BF7\u6C42\u54CD\u5E94\u5FAA\u73AF\u7684\u751F\u547D\u5468\u671F\u4E2D\u88AB\u6267\u884C\u3002\u63D2\u4EF6\u4F7F\u7528Lua\u7F16\u5199\uFF0C\u76EE\u524D\u5DF2\u6709\u51E0\u4E2A\u57FA\u7840\u529F\u80FD\uFF1AHTTP\u57FA\u672C\u8BA4\u8BC1\u3001\u5BC6\u94A5\u8BA4\u8BC1\u3001CORS\uFF08Cross-Origin Resource Sharing\uFF0C\u8DE8\u57DF\u8D44\u6E90\u5171\u4EAB\uFF09\u3001TCP\u3001UDP\u3001\u6587\u4EF6\u65E5\u5FD7\u3001API\u8BF7\u6C42\u9650\u6D41\u3001\u8BF7\u6C42\u8F6C\u53D1\u4EE5\u53CANginx\u76D1\u63A7\u3002

    Kong\u7F51\u5173\u5177\u6709\u4EE5\u4E0B\u7684\u7279\u6027\uFF1A

    • \u53EF\u6269\u5C55\u6027: \u901A\u8FC7\u7B80\u5355\u5730\u6DFB\u52A0\u66F4\u591A\u7684\u670D\u52A1\u5668\uFF0C\u53EF\u4EE5\u8F7B\u677E\u5730\u8FDB\u884C\u6A2A\u5411\u6269\u5C55\uFF0C\u8FD9\u610F\u5473\u7740\u60A8\u7684\u5E73\u53F0\u53EF\u4EE5\u5728\u4E00\u4E2A\u8F83\u4F4E\u8D1F\u8F7D\u7684\u60C5\u51B5\u4E0B\u5904\u7406\u4EFB\u4F55\u8BF7\u6C42\uFF1B
    • \u6A21\u5757\u5316: \u53EF\u4EE5\u901A\u8FC7\u6DFB\u52A0\u65B0\u7684\u63D2\u4EF6\u8FDB\u884C\u6269\u5C55\uFF0C\u8FD9\u4E9B\u63D2\u4EF6\u53EF\u4EE5\u901A\u8FC7RESTful Admin API\u8F7B\u677E\u914D\u7F6E\uFF1B
    • \u5728\u4EFB\u4F55\u57FA\u7840\u67B6\u6784\u4E0A\u8FD0\u884C: Kong\u7F51\u5173\u53EF\u4EE5\u5728\u4EFB\u4F55\u5730\u65B9\u90FD\u80FD\u8FD0\u884C\u3002\u60A8\u53EF\u4EE5\u5728\u4E91\u6216\u5185\u90E8\u7F51\u7EDC\u73AF\u5883\u4E2D\u90E8\u7F72Kong\uFF0C\u5305\u62EC\u5355\u4E2A\u6216\u591A\u4E2A\u6570\u636E\u4E2D\u5FC3\u8BBE\u7F6E\uFF0C\u4EE5\u53CApublic\uFF0Cprivate \u6216invite-only APIs\u3002

    Traefik

    Tr\xE6f\u026Ak \u662F\u4E00\u4E2A\u4E3A\u4E86\u8BA9\u90E8\u7F72\u5FAE\u670D\u52A1\u66F4\u52A0\u4FBF\u6377\u800C\u8BDE\u751F\u7684\u73B0\u4EE3HTTP\u53CD\u5411\u4EE3\u7406\u3001\u8D1F\u8F7D\u5747\u8861\u5DE5\u5177\u3002 \u5B83\u652F\u6301\u591A\u79CD\u540E\u53F0 (Docker, Swarm, Kubernetes, Marathon, Mesos, Consul, Etcd, Zookeeper, BoltDB, Rest API, file\u2026) \u6765\u81EA\u52A8\u5316\u3001\u52A8\u6001\u7684\u5E94\u7528\u5B83\u7684\u914D\u7F6E\u6587\u4EF6\u8BBE\u7F6E\u3002

    \u91CD\u8981\u7279\u6027\uFF1A

    • \u5B83\u975E\u5E38\u5FEB\uFF0C\u65E0\u9700\u5B89\u88C5\u5176\u4ED6\u4F9D\u8D56\uFF0C\u901A\u8FC7Go\u8BED\u8A00\u7F16\u5199\u7684\u5355\u4E00\u53EF\u6267\u884C\u6587\u4EF6\uFF1B
    • \u591A\u79CD\u540E\u53F0\u652F\u6301\uFF1ADocker, Swarm, Kubernetes, Marathon, Mesos, Consul, Etcd\uFF1B
    • \u652F\u6301\u652F\u6301Rest API\u3001Websocket\u3001HTTP/2\u3001Docker\u955C\u50CF\uFF1B
    • \u76D1\u542C\u540E\u53F0\u53D8\u5316\u8FDB\u800C\u81EA\u52A8\u5316\u5E94\u7528\u65B0\u7684\u914D\u7F6E\u6587\u4EF6\u8BBE\u7F6E\uFF1B
    • \u914D\u7F6E\u6587\u4EF6\u70ED\u66F4\u65B0\uFF0C\u65E0\u9700\u91CD\u542F\u8FDB\u7A0B\uFF1B
    • \u540E\u7AEF\u65AD\u8DEF\u5668\u3001\u8D1F\u8F7D\u5747\u8861\u3001\u5BB9\u9519\u673A\u5236\uFF1B
    • \u6E05\u723D\u7684\u524D\u7AEF\u9875\u9762\uFF0C\u53EF\u76D1\u63A7\u670D\u52A1\u6307\u6807\u3002

    \u5173\u4E8ETraefik\u7684\u66F4\u591A\u5185\u5BB9\uFF0C\u53EF\u4EE5\u67E5\u770B\u5B98\u7F51\uFF1Ahttps://traefik.cn/

    API\u7F51\u5173\u5BF9\u6BD4

    \u4E0A\u9762\u662F\u7F51\u5173\u5BF9\u6BD4\u622A\u56FE\uFF0C\u5077\u4E2A\u61D2\uFF0C\u5927\u5BB6\u4E3B\u8981\u5173\u6CE8Kong\u3001Traefik\u548CZuul\u5373\u53EF\uFF1A

    • \u4ECE\u5F00\u6E90\u793E\u533A\u6D3B\u8DC3\u5EA6\u6765\u770B\uFF0C\u65E0\u7591\u662FKong\u548CTraefik\u8F83\u597D\uFF1B
    • \u4ECE\u6210\u719F\u5EA6\u6765\u770B\uFF0C\u8F83\u597D\u7684\u662FKong\u3001Tyk\u3001Traefik\uFF1B
    • \u4ECE\u6027\u80FD\u6765\u770B\uFF0CKong\u8981\u6BD4\u5176\u4ED6\u51E0\u4E2A\u9886\u5148\u4E00\u4E9B\uFF1B
    • \u4ECE\u67B6\u6784\u4F18\u52BF\u7684\u6269\u5C55\u6027\u6765\u770B\uFF0CKong\u3001Tyk\u6709\u4E30\u5BCC\u7684\u63D2\u4EF6\uFF0CAmbassador\u4E5F\u6709\u63D2\u4EF6\u4F46\u4E0D\u591A\uFF0C\u800CZuul\u662F\u5B8C\u5168\u9700\u8981\u81EA\u7814\uFF0C\u4F46Zuul\u7531\u4E8E\u4E0ESpring Cloud\u6DF1\u5EA6\u96C6\u6210\uFF0C\u4F7F\u7528\u5EA6\u4E5F\u5F88\u9AD8\uFF0C\u8FD1\u5E74\u6765Istio\u670D\u52A1\u7F51\u683C\u7684\u6D41\u884C\uFF0CAmbassador\u56E0\u4E3A\u80FD\u591F\u548CIstio\u65E0\u7F1D\u96C6\u6210\u4E5F\u662F\u76F8\u5F53\u5927\u7684\u4F18\u52BF\u3002

    \u4E0B\u9762\u662F\u5176\u5B83\u7F51\u53CB\u7684\u601D\u8003\u7ED3\u8BBA\uFF0C\u53EF\u4F9B\u53C2\u8003\uFF1A

    • \u6027\u80FD\uFF1ANginx+Lua\u5F62\u5F0F\u5FC5\u7136\u662F\u9AD8\u4E8EJava\u8BED\u8A00\u5B9E\u73B0\u7684\u7F51\u5173\u7684\uFF0CJava\u6280\u672F\u6808\u91CC\u9762Zuul1.0\u662F\u57FA\u4E8EServlet\u5B9E\u73B0\u7684\uFF0C\u5269\u4E0B\u90FD\u662F\u57FA\u4E8Ewebflux\u5B9E\u73B0\uFF0C\u6027\u80FD\u662F\u9AD8\u4E8E\u57FA\u4E8EServlet\u5B9E\u73B0\u7684\u3002\u5728\u6027\u80FD\u65B9\u9762\u6211\u89C9\u5F97\u9009\u62E9\u7F51\u5173\u53EF\u80FD\u4E0D\u7B97\u90A3\u4E48\u91CD\u8981\uFF0C\u591A\u52A0\u51E0\u53F0\u673A\u5668\u5C31\u53EF\u4EE5\u641E\u5B9A\u3002
    • \u53EF\u7EF4\u62A4\u6027\u548C\u6269\u5C55\u6027\uFF1ANginx+Lua\u8FD9\u4E2A\u7EC4\u5408\u638C\u63E1\u7684\u4EBA\u4E0D\u7B97\u591A\uFF0C\u5982\u679C\u56E2\u961F\u6709\u5927\u795E\uFF0C\u5927\u4F6C\u4EEC\u5C31\u968F\u610F\u4E86\uFF0C\u5F53\u6CA1\u770B\u5230\u8FD9\u6BB5\u8BDD\uFF0C\u5BF9\u4E8E\u4E00\u822C\u56E2\u961F\u6765\u8BF4\u7684\u8BDD\uFF0C\u9009\u62E9\u81EA\u5DF1\u56E2\u961F\u64C5\u957F\u7684\u8BED\u8A00\u66F4\u91CD\u8981\u3002Java\u6280\u672F\u6808\u4E0B\u76843\u79CD\u7F51\u5173\uFF0C\u5BF9\u4E8EZuul\u548CSpring Cloud Getway\u9700\u8981\u6216\u591A\u6216\u5C11\u8981\u641E\u4E00\u4E9B\u96C6\u6210\u548C\u914D\u7F6E\u9875\u9762\u6765\u7EF4\u62A4\uFF0C\u4F46\u662F\u5BF9\u4E8ESoul\u6211\u5C31\u65E0\u8111\u770B\u770B\u6587\u7AE0\uFF0C\u9700\u8981\u54EA\u4E2A\u642C\u54EA\u4E2A\u597D\u4E86\uFF0C\u5C24\u5176\u662F\u53EF\u4EE5\u65E0\u8111\u5BF9\u63A5Dubbo\u7F8E\u6ECB\u6ECB\uFF0C\u6B64\u5916Soul2.0\u4EE5\u540E\u7248\u672C\u53EF\u4EE5\u6446\u8131ZK\uFF0C\u5728\u6211\u5FC3\u91CC\u518D\u65E0\u8BDF\u75C5\uFF0C\u6211\u5C31\u559C\u6B22\u65E0\u8111\u64CD\u4F5C\u3002
    • \u9AD8\u53EF\u7528\uFF1A\u5BF9\u4E8E\u7F51\u5173\u9AD8\u53EF\u7528\u57FA\u672C\u90FD\u662F\u7EDF\u4E00\u7684\u7B56\u7565\u90FD\u662F\u91C7\u7528\u591A\u673A\u5668\u90E8\u7F72\u7684\u65B9\u5F0F\uFF0C\u524D\u9762\u6302\u4E00\u4E2A\u8D1F\u8F7D\uFF0C\u5BF9\u4E8E\u800C\u5916\u9700\u8981\u7528\u7684\u4E00\u4E9B\u7EC4\u4EF6\u5927\u5BB6\u6CE8\u610F\u4E00\u4E0B\u3002

    \u57FA\u4E8ETraefik\u81EA\u7814\u7684\u5FAE\u670D\u52A1\u7F51\u5173

    \u8FD9\u4E2A\u662F\u6211\u53F8\u81EA\u7814\u7684\u5FAE\u670D\u52A1\u7F51\u5173\uFF0C\u57FA\u4E8ETraefik\u8FDB\u884C\u5F00\u53D1\uFF0C\u4E0B\u9762\u4ECE\u6280\u672F\u9009\u578B\u3001\u7F51\u5173\u6846\u67B6\u3001\u7F51\u5173\u540E\u53F0\u3001\u534F\u8BAE\u8F6C\u6362\u8FDB\u884C\u8BB2\u89E3\uFF0C\u7EDD\u5BF9\u5E72\u8D27\uFF01

    \u6280\u672F\u6808\u9009\u578B

    • Traefik\uFF1A\u4E00\u6B3E\u5F00\u6E90\u7684\u53CD\u5411\u4EE3\u7406\u4E0E\u8D1F\u8F7D\u5747\u8861\u5DE5\u5177\uFF0C\u5B83\u6700\u5927\u7684\u4F18\u70B9\u662F\u80FD\u591F\u4E0E\u5E38\u89C1\u7684\u5FAE\u670D\u52A1\u7CFB\u7EDF\u76F4\u63A5\u6574\u5408\uFF0C\u53EF\u4EE5\u5B9E\u73B0\u81EA\u52A8\u5316\u52A8\u6001\u914D\u7F6E\u3002traefik\u8F83\u4E3A\u8F7B\u91CF\uFF0C\u975E\u5E38\u6613\u4E8E\u4F7F\u7528\u548C\u8BBE\u7F6E\uFF0C\u6027\u80FD\u6BD4\u8F83\u597D\uFF0C\u5DF2\u5728\u5168\u7403\u8303\u56F4\u5185\u7528\u4E8E\u751F\u4EA7\u73AF\u5883\u3002
    • Etcd\uFF1A\u4E00\u4E2AGo\u8A00\u7F16\u5199\u7684\u5206\u5E03\u5F0F\u3001\u9AD8\u53EF\u7528\u7684\u4E00\u81F4\u6027\u952E\u503C\u5B58\u50A8\u7CFB\u7EDF\uFF0C\u7528\u4E8E\u63D0\u4F9B\u53EF\u9760\u7684\u5206\u5E03\u5F0F\u952E\u503C\u5B58\u50A8\u3001\u914D\u7F6E\u5171\u4EAB\u548C\u670D\u52A1\u53D1\u73B0\u7B49\u529F\u80FD\u3002
    • Go\uFF1A\u5E76\u53D1\u80FD\u529B\u5F3A\uFF0C\u6027\u80FD\u5AB2\u7F8EC\uFF0C\u5904\u7406\u80FD\u529B\u662FPHP\u76844\u500D\uFF0C\u6548\u7387\u9AD8\uFF0C\u8BED\u6CD5\u7B80\u5355\uFF0C\u6613\u4E0A\u624B\uFF0C\u5F00\u53D1\u6548\u7387\u63A5\u8FD1PHP\u3002

    \u7F51\u5173\u6846\u67B6

    \u6574\u4E2A\u7F51\u5173\u6846\u67B6\u5206\u4E3A3\u5757\uFF1A

    • \u7F51\u5173\u540E\u53F0\uFF08hal-fe\u548Chal-admin\uFF09\uFF1A\u7528\u4E8E\u5E94\u7528\u3001\u670D\u52A1\u548C\u63D2\u4EF6\u7684\u914D\u7F6E\uFF0C\u7136\u540E\u5C06\u914D\u7F6E\u4FE1\u606F\u53D1\u5E03\u5230ETCD\uFF1B
    • Traefik\uFF1A\u8BFB\u53D6ETCD\u914D\u7F6E\uFF0C\u6839\u636E\u914D\u7F6E\u4FE1\u606F\u5BF9\u8BF7\u6C42\u8FDB\u884C\u8DEF\u7531\u5206\u53D1\uFF0C\u5982\u679C\u9700\u8981\u9274\u6743\uFF0C\u4F1A\u76F4\u63A5\u901A\u8FC7hal-agent\u6A21\u5757\u8FDB\u884C\u7EDF\u4E00\u9274\u6743\u3002\u9274\u6743\u5B8C\u6BD5\u540E\uFF0C\u5982\u679C\u662FHttp\u8BF7\u6C42\uFF0C\u76F4\u63A5\u6253\u5230\u4E0B\u6E38\u670D\u52A1\uFF0C\u5982\u679C\u662FGrpc\u548CThrift\u534F\u8BAE\uFF0C\u4F1A\u901A\u8FC7hal-proxy\u6A21\u5757\u8FDB\u884C\u534F\u8BAE\u8F6C\u6362\u3002
    • \u534F\u8BAE\u8F6C\u6362\u6A21\u5757\uFF1A\u8BFB\u53D6ETCD\u914D\u7F6E\uFF0C\u5BF9Traefik\u5206\u53D1\u8FC7\u6765\u7684\u8BF7\u6C42\uFF0C\u8FDB\u884CGrpc\u548CThrift\u534F\u8BAE\u8F6C\u6362\uFF0C\u5E76\u901A\u8FC7\u670D\u52A1\u53D1\u73B0\u673A\u5236\uFF0C\u83B7\u53D6\u670D\u52A1\u4E0B\u6E38\u673A\u5668\uFF0C\u5E76\u901A\u8FC7\u8D1F\u8F7D\u5747\u8861\uFF0C\u5C06\u8F6C\u6362\u540E\u7684\u6570\u636E\u6253\u5230\u4E0B\u6E38\u670D\u52A1\u673A\u5668\u3002

    \u7F51\u5173\u540E\u53F0

    \u4E3B\u8981\u75313\u5927\u6A21\u5757\u7EC4\u6210\uFF1A

    • \u5E94\u7528\uFF1A\u4E3B\u8981\u5305\u62EC\u5E94\u7528\u540D\u3001\u57DF\u540D\u3001\u8DEF\u5F84\u524D\u7F00\u3001\u6240\u5C5E\u7EC4\u3001\u72B6\u6001\u7B49\uFF0C\u6BD4\u5982\u5370\u5EA6\u6D77\u5916\u5546\u57CE\u3001\u5370\u5EA6\u793E\u533A\uFF1B
    • \u670D\u52A1\uFF1A\u4E3B\u8981\u5305\u62EC\u670D\u52A1\u540D\u3001\u6CE8\u518C\u65B9\u5F0F\u3001\u534F\u8BAE\u7C7B\u578B\u3001\u6240\u5C5E\u7EC4\u3001\u72B6\u6001\u7B49\uFF0C\u6BD4\u5982\u8BC4\u8BBA\u670D\u52A1\u3001\u5730\u5740\u670D\u52A1\u3001\u641C\u7D22\u670D\u52A1\u3002
    • \u63D2\u4EF6\uFF1A\u4E3B\u8981\u5305\u62EC\u63D2\u4EF6\u540D\u79F0\u3001\u63D2\u4EF6\u7C7B\u578B\u3001\u63D2\u4EF6\u5C5E\u6027\u914D\u7F6E\u7B49\uFF0C\u6BD4\u5982\u8DEF\u5F84\u524D\u7F00\u66FF\u6362\u63D2\u4EF6\u3001\u9274\u6743\u63D2\u4EF6\u3002

    \u4E00\u4E2A\u5E94\u7528\u53EA\u80FD\u7ED1\u5B9A\u4E00\u4E2A\u670D\u52A1\uFF0C\u4F46\u662F\u53EF\u4EE5\u7ED1\u5B9A\u591A\u4E2A\u63D2\u4EF6\u3002 \u901A\u8FC7\u540E\u53F0\u5B8C\u6210\u7F51\u5173\u914D\u7F6E\u540E\uFF0C\u5C06\u8FD9\u4E9B\u914D\u7F6E\u4FE1\u606F\u751F\u6210Config\u6587\u4EF6\uFF0C\u53D1\u5E03\u5230ETCD\u4E2D\uFF0CConfig\u6587\u4EF6\u9700\u8981\u9075\u5FAA\u4E25\u683C\u7684\u6570\u636E\u683C\u5F0F\uFF0C\u6BD4\u5982Traefix\u914D\u7F6E\u9700\u8981\u9075\u5FAA\u5B98\u65B9\u7684\u6587\u4EF6\u914D\u7F6E\u683C\u5F0F\uFF0C\u624D\u80FD\u88ABTraefik\u8BC6\u522B\u3002

    \u534F\u8BAE\u8F6C\u6362\u6A21\u5757

    hal-proxy\u6A21\u5757\u662F\u6574\u4E2A\u5FAE\u670D\u52A1\u7F51\u5173\u6700\u590D\u6742\uFF0C\u4E5F\u662F\u6280\u672F\u542B\u91CF\u6700\u9AD8\u7684\u6A21\u5757\uFF0C\u6240\u4EE5\u7ED9\u5927\u5BB6\u8BE6\u7EC6\u8BB2\u89E3\u4E00\u4E0B\u3002

    \u95EE\u9898\u5F15\u5165

    \u5728\u8BB2\u8FD9\u4E2A\u6A21\u5757\u524D\uFF0C\u6211\u4EEC\u5148\u770B\u4E0B\u9762\u51E0\u4E2A\u95EE\u9898\uFF1A

    • \u5F53\u8BF7\u6C42\u4ECE\u4E0A\u6E38\u7684trafik\u8FC7\u6765\u65F6\uFF0C\u9700\u8981\u77E5\u9053\u8BBF\u95EE\u4E0B\u6E38\u7684\u673A\u5668IP\u548C\u7AEF\u53E3\uFF0C\u624D\u80FD\u5C06\u8BF7\u6C42\u53D1\u9001\u7ED9\u4E0B\u6E38\uFF0C\u8FD9\u4E9B\u673A\u5668\u5982\u4F55\u83B7\u53D6\u5462\uFF1F
    • \u6709\u4E86\u673A\u5668\u540E\uFF0C\u6211\u4EEC\u9700\u8981\u548C\u4E0B\u6E38\u673A\u5668\u5EFA\u7ACB\u8FDE\u63A5\uFF0C\u5982\u679C\u8FDE\u63A5\u7528\u4E00\u6B21\u5C31\u76F4\u63A5\u91CA\u653E\uFF0C\u80AF\u5B9A\u5BF9\u670D\u52A1\u4F1A\u9020\u6210\u5F88\u5927\u7684\u538B\u529B\uFF0C\u8FD9\u5C31\u9700\u8981\u5F15\u5165Client\u7F13\u5B58\u6C60\uFF0C\u90A3\u8FD9\u4E2AClient\u7F13\u5B58\u6C60\u6211\u4EEC\u53C8\u8BE5\u5982\u4F55\u5B9E\u73B0\u5462\uFF1F
    • \u6700\u540E\u5C31\u662F\u9700\u8981\u5BF9\u534F\u8BAE\u8FDB\u884C\u8F6C\u6362\uFF0C\u56E0\u4E3A\u4E0D\u540C\u7684\u4E0B\u6E38\u670D\u52A1\uFF0C\u652F\u6301\u7684\u534F\u8BAE\u7C7B\u578B\u662F\u4E0D\u4E00\u6837\u7684\uFF0C\u8FD9\u4E2A\u7F51\u5173\u53C8\u662F\u5982\u4F55\u52A8\u6001\u652F\u6301\u7684\u5462\uFF1F

    \u5B9E\u73B0\u539F\u7406

    \u6211\u4EEC\u8FD8\u662F\u5148\u770B\u4E00\u4E0Bhal-proxy\u5185\u90E8\u6709\u54EA\u4E9B\u6A21\u5757\uFF0C\u9996\u5148\u662FResolver\u6A21\u5757\uFF0C\u8FD9\u4E2A\u6A21\u5757\u7684\u662F\u4EC0\u4E48\u4F5C\u7528\u5462\uFF1F\u8FD9\u91CC\u6211\u7B80\u5355\u4ECB\u7ECD\u4E00\u4E0B\uFF0C\u76EE\u524D\u516C\u53F8\u5185\u90E8\u901A\u8FC7\u670D\u52A1\u83B7\u53D6\u5230\u673A\u5668\u5217\u8868\u7684\u65B9\u5F0F\u6709\u591A\u79CD\uFF0C\u6BD4\u5982MIS\u5E73\u53F0\u3001\u670D\u52A1\u6811\u7B49\uFF0C\u4E5F\u5C31\u662F\u6709\u7684\u662F\u901A\u8FC7\u5E73\u53F0\u914D\u7F6E\u7684\uFF0C\u6709\u7684\u662F\u76F4\u63A5\u6302\u5728\u670D\u52A1\u6811\u4E0B\uFF0C\u65E0\u8BBA\u54EA\u79CD\u65B9\u5F0F\uFF0C\u6211\u4EEC\u90FD\u901A\u8FC7\u670D\u52A1\u540D\uFF0C\u901A\u8FC7\u4E00\u5B9A\u7684\u65B9\u5F0F\uFF0C\u627E\u5230\u8BE5\u670D\u52A1\u4E0B\u9762\u6240\u6709\u7684\u4E3B\u673A\u3002

    \u6240\u4EE5Resolver\u6A21\u5757\u7684\u4F5C\u7528\uFF0C\u5176\u5B9E\u5C31\u662F\u901A\u8FC7\u670D\u52A1\u540D\uFF0C\u627E\u5230\u8BE5\u670D\u52A1\u4E0B\u7684\u6240\u6709\u673A\u5668\u7684IP\u548C\u670D\u52A1\u7AEF\u53E3\uFF0C\u7136\u540E\u6301\u4E45\u5316\u5230\u5185\u5B58\u4E2D\uFF0C\u5E76\u5B9A\u65F6\u66F4\u65B0\u3002

    \u534F\u8BAE\u6A21\u5757\u5C31\u662F\u652F\u6301\u4E0D\u540C\u7684\u534F\u8BAE\u8F6C\u6362\uFF0C\u6BCF\u4E2A\u534F\u8BAE\u7C7B\u578B\u7684\u8F6C\u6362\uFF0C\u90FD\u9700\u8981\u5355\u72EC\u5B9E\u73B0\uFF0C\u8FD9\u4E9B\u534F\u8BAE\u8F6C\u6362\uFF0C\u65E0\u975E\u5C31\u662F\u5148\u901A\u8FC7\u673A\u5668IP\u548C\u7AEF\u53E3\u521D\u59CB\u5316Client\uFF0C\u7136\u540E\u518D\u5C06\u6570\u636E\u8FDB\u884C\u8F6C\u6362\u540E\uFF0C\u76F4\u63A5\u53D1\u9001\u5230\u4E0B\u6E38\u7684\u673A\u5668\u3002

    \u6700\u540E\u5C31\u662F\u8FDE\u63A5\u6C60\uFF0C\u4E4B\u524D\u6211\u4EEC\u5176\u5B9E\u4E5F\u7528\u5230go\u81EA\u5E26\u7684pool\u6765\u505A\uFF0C\u4F46\u662F\u5F53\u5BF9pool\u6570\u636E\u8FDB\u884C\u66F4\u65B0\u65F6\uFF0C\u9700\u8981\u52A0\u9501\uFF0C\u6240\u4EE5\u6027\u80FD\u4E00\u76F4\u8D77\u4E0D\u6765\uFF0C\u540E\u6765\u6539\u6210\u4E86\u73AF\u5F62\u961F\u5217\uFF0C\u7136\u540E\u5BF9\u6570\u636E\u7684\u64CD\u4F5C\u5168\u90E8\u901A\u8FC7\u539F\u5B50\u64CD\u4F5C\u65B9\u5F0F\uFF0C\u5C31\u5B9E\u73B0\u4E86\u65E0\u9501\u64CD\u4F5C\uFF0C\u5927\u5927\u63D0\u9AD8\u7684\u5E76\u53D1\u6027\u80FD\u3002

    \u5B9E\u73B0\u903B\u8F91

    \u8FD9\u4E2A\u662Fhal-proxy\u7684\u903B\u8F91\u5B9E\u73B0\u56FE\uFF0C\u753B\u4E862\u5929\uFF0C\u5305\u542B\u6240\u6709\u6838\u5FC3\u5BF9\u8C61\u7684\u4EA4\u4E92\u65B9\u5F0F\uFF0C\u8FD9\u91CC\u5C31\u4E0D\u53BB\u7EC6\u8BB2\uFF0C\u80FD\u638C\u63E1\u591A\u5C11\uFF0C\u9760\u5927\u5BB6\u81EA\u5DF1\u9886\u609F\uFF0C\u5982\u679C\u6709\u4EFB\u4F55\u7591\u95EE(\u6216\u8005\u770B\u4E0D\u6E05\u56FE\u7247)\uFF0C\u53EF\u4EE5\u5173\u6CE8\u6211\u516C\u4F17\u53F7\uFF0C\u52A0\u6211\u5FAE\u4FE1\u6C9F\u901A\u3002


    ',85),v=a("\u6574\u7406\uFF1A\u6C89\u9ED8\u738B\u4E8C\uFF0C\u6233"),x={href:"https://mp.weixin.qq.com/s/b2xf4GiJksBQqjHVpsh49Q",target:"_blank",rel:"noopener noreferrer"},P=a("\u8F6C\u8F7D\u94FE\u63A5"),_=a("\uFF0C\u4F5C\u8005\uFF1A\u697C\u4ED4\uFF0C\u6233"),k={href:"https://mp.weixin.qq.com/s/0Qupyl5eCyQGFEAIY6GxoQ",target:"_blank",rel:"noopener noreferrer"},I=a("\u539F\u6587\u94FE\u63A5"),T=a("\u3002"),A=e("p",null,[e("img",{src:"http://cdn.tobebetterjavaer.com/tobebetterjavaer/images/xingbiaogongzhonghao.png",alt:""})],-1);function j(w,S){const r=n("ExternalLinkIcon");return o(),s("div",null,[e("blockquote",null,[e("p",null,[c,e("a",p,[d,t(r)]),h,e("a",b,[u,t(r)]),f])]),m,e("blockquote",null,[e("p",null,[v,e("a",x,[P,t(r)]),_,e("a",k,[I,t(r)]),T])]),A])}var E=i(g,[["render",j],["__file","api-wangguan.html.vue"]]);export{E as default}; +import{_ as i}from"./plugin-vue_export-helper.21dcd24c.js";import{r as n,o,c as s,a as e,b as t,d as a,e as l}from"./app.615e41d8.js";const g={},c=a("\u6574\u7406\uFF1A\u6C89\u9ED8\u738B\u4E8C\uFF0C\u6233"),p={href:"https://mp.weixin.qq.com/s/b2xf4GiJksBQqjHVpsh49Q",target:"_blank",rel:"noopener noreferrer"},d=a("\u8F6C\u8F7D\u94FE\u63A5"),h=a("\uFF0C\u4F5C\u8005\uFF1A\u697C\u4ED4\uFF0C\u6233"),b={href:"https://mp.weixin.qq.com/s/0Qupyl5eCyQGFEAIY6GxoQ",target:"_blank",rel:"noopener noreferrer"},u=a("\u539F\u6587\u94FE\u63A5"),f=a("\u3002"),m=l('

    \u5FAE\u670D\u52A1\u8FD1\u51E0\u5E74\u975E\u5E38\u706B\uFF0C\u56F4\u7ED5\u5FAE\u670D\u52A1\u7684\u6280\u672F\u751F\u6001\u4E5F\u6BD4\u8F83\u591A\uFF0C\u6BD4\u5982\u5FAE\u670D\u52A1\u7F51\u5173\u3001Docker\u3001Kubernetes\u7B49\u3002

    \u6211\u662F\u4E8E2019\u5E74\u5F00\u59CB\u63A5\u89E6\u5FAE\u670D\u52A1\u7F51\u5173\uFF0C\u5F53\u65F6\u548C\u516C\u53F8\u7684\u4E00\u4F4D\u540C\u4E8B\u4E00\u8D77\u5F00\u53D1\uFF0C\u7531\u4E8E\u6280\u672F\u80FD\u529B\u6709\u9650\uFF0C\u6211\u53EA\u8D1F\u8D23\u7F51\u5173\u540E\u53F0\uFF0C\u540E\u7EED\u5FAE\u670D\u52A1\u7F51\u5173\u7684\u8FED\u4EE3\uFF0C\u6211\u5176\u5B9E\u6CA1\u6709\u53C2\u4E0E\uFF0C\u4E0D\u8FC7\u540E\u6765\u62BD\u7A7A\u770B\u4E86\u5FAE\u670D\u52A1\u7F51\u5173\u524D\u53F0\u7684\u4EE3\u7801\uFF0C\u6240\u4EE5\u5BF9\u8FD9\u5957\u5FAE\u670D\u52A1\u7F51\u5173\u7684\u5B9E\u73B0\u539F\u7406\u7B97\u662F\u57FA\u672C\u638C\u63E1\u3002

    \u6700\u8FD1\u5728\u5199\u6280\u672F\u6808\u76F8\u5173\u7684\u6587\u7AE0\uFF0C\u521A\u597D\u5199\u5230\u5FAE\u670D\u52A1\u7F51\u5173\uFF0C\u5C31\u628A\u4E4B\u524D\u5B66\u4E60\u7684\u77E5\u8BC6\u8FDB\u884C\u7B80\u5355\u603B\u7ED3\uFF0C\u540C\u65F6\u4E5F\u628A\u5E02\u9762\u4E0A\u5E38\u7528\u7684\u5FAE\u670D\u52A1\u7F51\u5173\u8FDB\u884C\u68B3\u7406\uFF0C\u4E00\u65B9\u9762\u4FBF\u4E8E\u540E\u7EED\u6280\u672F\u9009\u578B\uFF0C\u53E6\u4E00\u65B9\u9762\u4E5F\u7B97\u662F\u7ED9\u81EA\u5DF1\u4E00\u4E2A\u4EA4\u4EE3\u3002\u4E0B\u9762\u662F\u6587\u7AE0\u76EE\u5F55\uFF1A

    API\u7F51\u5173\u57FA\u7840

    \u4EC0\u4E48\u662FAPI\u7F51\u5173

    API\u7F51\u5173\u662F\u4E00\u4E2A\u670D\u52A1\u5668\uFF0C\u662F\u7CFB\u7EDF\u7684\u552F\u4E00\u5165\u53E3\u3002 \u4ECE\u9762\u5411\u5BF9\u8C61\u8BBE\u8BA1\u7684\u89D2\u5EA6\u770B\uFF0C\u5B83\u4E0E\u5916\u89C2\u6A21\u5F0F\u7C7B\u4F3C\u3002

    API\u7F51\u5173\u5C01\u88C5\u4E86\u7CFB\u7EDF\u5185\u90E8\u67B6\u6784\uFF0C\u4E3A\u6BCF\u4E2A\u5BA2\u6237\u7AEF\u63D0\u4F9B\u4E00\u4E2A\u5B9A\u5236\u7684API\u3002\u5B83\u53EF\u80FD\u8FD8\u5177\u6709\u5176\u5B83\u804C\u8D23\uFF0C\u5982\u8EAB\u4EFD\u9A8C\u8BC1\u3001\u76D1\u63A7\u3001\u8D1F\u8F7D\u5747\u8861\u3001\u7F13\u5B58\u3001\u534F\u8BAE\u8F6C\u6362\u3001\u9650\u6D41\u7194\u65AD\u3001\u9759\u6001\u54CD\u5E94\u5904\u7406\u3002

    API\u7F51\u5173\u65B9\u5F0F\u7684\u6838\u5FC3\u8981\u70B9\u662F\uFF0C\u6240\u6709\u7684\u5BA2\u6237\u7AEF\u548C\u6D88\u8D39\u7AEF\u90FD\u901A\u8FC7\u7EDF\u4E00\u7684\u7F51\u5173\u63A5\u5165\u5FAE\u670D\u52A1\uFF0C\u5728\u7F51\u5173\u5C42\u5904\u7406\u6240\u6709\u7684\u975E\u4E1A\u52A1\u529F\u80FD\u3002\u901A\u5E38\uFF0C\u7F51\u5173\u4E5F\u662F\u63D0\u4F9BREST/HTTP\u7684\u8BBF\u95EEAPI\u3002

    \u7F51\u5173\u7684\u4E3B\u8981\u529F\u80FD

    \u5FAE\u670D\u52A1\u7F51\u5173\u4F5C\u4E3A\u5FAE\u670D\u52A1\u540E\u7AEF\u670D\u52A1\u7684\u7EDF\u4E00\u5165\u53E3\uFF0C\u5B83\u53EF\u4EE5\u7EDF\u7B79\u7BA1\u7406\u540E\u7AEF\u670D\u52A1\uFF0C\u4E3B\u8981\u5206\u4E3A\u6570\u636E\u5E73\u9762\u548C\u63A7\u5236\u5E73\u9762\uFF1A

    • \u6570\u636E\u5E73\u9762\u4E3B\u8981\u529F\u80FD\u662F\u63A5\u5165\u7528\u6237\u7684HTTP\u8BF7\u6C42\u548C\u5FAE\u670D\u52A1\u88AB\u62C6\u5206\u540E\u7684\u805A\u5408\u3002\u4F7F\u7528\u5FAE\u670D\u52A1\u7F51\u5173\u7EDF\u4E00\u5BF9\u5916\u66B4\u9732\u540E\u7AEF\u670D\u52A1\u7684API\u548C\u5951\u7EA6\uFF0C\u8DEF\u7531\u548C\u8FC7\u6EE4\u529F\u80FD\u6B63\u662F\u7F51\u5173\u7684\u6838\u5FC3\u80FD\u529B\u6A21\u5757\u3002\u53E6\u5916\uFF0C\u5FAE\u670D\u52A1\u7F51\u5173\u53EF\u4EE5\u5B9E\u73B0\u62E6\u622A\u673A\u5236\u548C\u4E13\u6CE8\u8DE8\u6A2A\u5207\u9762\u7684\u529F\u80FD\uFF0C\u5305\u62EC\u534F\u8BAE\u8F6C\u6362\u3001\u5B89\u5168\u8BA4\u8BC1\u3001\u7194\u65AD\u9650\u6D41\u3001\u7070\u5EA6\u53D1\u5E03\u3001\u65E5\u5FD7\u7BA1\u7406\u3001\u6D41\u91CF\u76D1\u63A7\u7B49\u3002
    • \u63A7\u5236\u5E73\u9762\u4E3B\u8981\u529F\u80FD\u662F\u5BF9\u540E\u7AEF\u670D\u52A1\u505A\u7EDF\u4E00\u7684\u7BA1\u63A7\u548C\u914D\u7F6E\u7BA1\u7406\u3002\u4F8B\u5982\uFF0C\u53EF\u4EE5\u63A7\u5236\u7F51\u5173\u7684\u5F39\u6027\u4F38\u7F29\uFF1B\u53EF\u4EE5\u7EDF\u4E00\u4E0B\u53D1\u914D\u7F6E\uFF1B\u53EF\u4EE5\u5BF9\u7F51\u5173\u670D\u52A1\u6DFB\u52A0\u6807\u7B7E\uFF1B\u53EF\u4EE5\u5728\u5FAE\u670D\u52A1\u7F51\u5173\u4E0A\u901A\u8FC7\u914D\u7F6ESwagger\u529F\u80FD\u7EDF\u4E00\u5C06\u540E\u7AEF\u670D\u52A1\u7684API\u5951\u7EA6\u66B4\u9732\u7ED9\u4F7F\u7528\u65B9\uFF0C\u5B8C\u6210\u6587\u6863\u670D\u52A1\uFF0C\u63D0\u9AD8\u5DE5\u4F5C\u6548\u7387\u548C\u964D\u4F4E\u6C9F\u901A\u6210\u672C\u3002

    • \u8DEF\u7531\u529F\u80FD\uFF1A\u8DEF\u7531\u662F\u5FAE\u670D\u52A1\u7F51\u5173\u7684\u6838\u5FC3\u80FD\u529B\u3002\u901A\u8FC7\u8DEF\u7531\u529F\u80FD\u5FAE\u670D\u52A1\u7F51\u5173\u53EF\u4EE5\u5C06\u8BF7\u6C42\u8F6C\u53D1\u5230\u76EE\u6807\u5FAE\u670D\u52A1\u3002\u5728\u5FAE\u670D\u52A1\u67B6\u6784\u4E2D\uFF0C\u7F51\u5173\u53EF\u4EE5\u7ED3\u5408\u6CE8\u518C\u4E2D\u5FC3\u7684\u52A8\u6001\u670D\u52A1\u53D1\u73B0\uFF0C\u5B9E\u73B0\u5BF9\u540E\u7AEF\u670D\u52A1\u7684\u53D1\u73B0\uFF0C\u8C03\u7528\u65B9\u53EA\u9700\u8981\u77E5\u9053\u7F51\u5173\u5BF9\u5916\u66B4\u9732\u7684\u670D\u52A1API\u5C31\u53EF\u4EE5\u900F\u660E\u5730\u8BBF\u95EE\u540E\u7AEF\u5FAE\u670D\u52A1\u3002
    • \u8D1F\u8F7D\u5747\u8861\uFF1AAPI\u7F51\u5173\u7ED3\u5408\u8D1F\u8F7D\u5747\u8861\u6280\u672F\uFF0C\u5229\u7528Eureka\u6216\u8005Consul\u7B49\u670D\u52A1\u53D1\u73B0\u5DE5\u5177\uFF0C\u901A\u8FC7\u8F6E\u8BE2\u3001\u6307\u5B9A\u6743\u91CD\u3001IP\u5730\u5740\u54C8\u5E0C\u7B49\u673A\u5236\u5B9E\u73B0\u4E0B\u6E38\u670D\u52A1\u7684\u8D1F\u8F7D\u5747\u8861\u3002
    • \u7EDF\u4E00\u9274\u6743\uFF1A\u4E00\u822C\u800C\u8A00\uFF0C\u65E0\u8BBA\u5BF9\u5185\u7F51\u8FD8\u662F\u5916\u7F51\u7684\u63A5\u53E3\u90FD\u9700\u8981\u505A\u7528\u6237\u8EAB\u4EFD\u8BA4\u8BC1\uFF0C\u800C\u7528\u6237\u8BA4\u8BC1\u5728\u4E00\u4E9B\u89C4\u6A21\u8F83\u5927\u7684\u7CFB\u7EDF\u4E2D\u90FD\u4F1A\u91C7\u7528\u7EDF\u4E00\u7684\u5355\u70B9\u767B\u5F55\uFF08Single Sign On\uFF09\u7CFB\u7EDF\uFF0C\u5982\u679C\u6BCF\u4E2A\u5FAE\u670D\u52A1\u90FD\u8981\u5BF9\u63A5\u5355\u70B9\u767B\u5F55\u7CFB\u7EDF\uFF0C\u90A3\u4E48\u663E\u7136\u6BD4\u8F83\u6D6A\u8D39\u8D44\u6E90\u4E14\u5F00\u53D1\u6548\u7387\u4F4E\u3002API\u7F51\u5173\u662F\u7EDF\u4E00\u7BA1\u7406\u5B89\u5168\u6027\u7684\u7EDD\u4F73\u573A\u6240\uFF0C\u53EF\u4EE5\u5C06\u8BA4\u8BC1\u7684\u90E8\u5206\u62BD\u53D6\u5230\u7F51\u5173\u5C42\uFF0C\u5FAE\u670D\u52A1\u7CFB\u7EDF\u65E0\u987B\u5173\u6CE8\u8BA4\u8BC1\u7684\u903B\u8F91\uFF0C\u53EA\u5173\u6CE8\u81EA\u8EAB\u4E1A\u52A1\u5373\u53EF\u3002
    • \u534F\u8BAE\u8F6C\u6362\uFF1AAPI\u7F51\u5173\u7684\u4E00\u5927\u4F5C\u7528\u5728\u4E8E\u6784\u5EFA\u5F02\u6784\u7CFB\u7EDF\uFF0CAPI\u7F51\u5173\u4F5C\u4E3A\u5355\u4E00\u5165\u53E3\uFF0C\u901A\u8FC7\u534F\u8BAE\u8F6C\u6362\u6574\u5408\u540E\u53F0\u57FA\u4E8EREST\u3001AMQP\u3001Dubbo\u7B49\u4E0D\u540C\u98CE\u683C\u548C\u5B9E\u73B0\u6280\u672F\u7684\u5FAE\u670D\u52A1\uFF0C\u9762\u5411Web Mobile\u3001\u5F00\u653E\u5E73\u53F0\u7B49\u7279\u5B9A\u5BA2\u6237\u7AEF\u63D0\u4F9B\u7EDF\u4E00\u670D\u52A1\u3002
    • \u6307\u6807\u76D1\u63A7\uFF1A\u7F51\u5173\u53EF\u4EE5\u7EDF\u8BA1\u540E\u7AEF\u670D\u52A1\u7684\u8BF7\u6C42\u6B21\u6570\uFF0C\u5E76\u4E14\u53EF\u4EE5\u5B9E\u65F6\u5730\u66F4\u65B0\u5F53\u524D\u7684\u6D41\u91CF\u5065\u5EB7\u72B6\u6001\uFF0C\u53EF\u4EE5\u5BF9URL\u7C92\u5EA6\u7684\u670D\u52A1\u8FDB\u884C\u5EF6\u8FDF\u7EDF\u8BA1\uFF0C\u4E5F\u53EF\u4EE5\u4F7F\u7528Hystrix Dashboard\u67E5\u770B\u540E\u7AEF\u670D\u52A1\u7684\u6D41\u91CF\u72B6\u6001\u53CA\u662F\u5426\u6709\u7194\u65AD\u53D1\u751F\u3002
    • \u9650\u6D41\u7194\u65AD\uFF1A\u5728\u67D0\u4E9B\u573A\u666F\u4E0B\u9700\u8981\u63A7\u5236\u5BA2\u6237\u7AEF\u7684\u8BBF\u95EE\u6B21\u6570\u548C\u8BBF\u95EE\u9891\u7387\uFF0C\u4E00\u4E9B\u9AD8\u5E76\u53D1\u7CFB\u7EDF\u6709\u65F6\u8FD8\u4F1A\u6709\u9650\u6D41\u7684\u9700\u6C42\u3002\u5728\u7F51\u5173\u4E0A\u53EF\u4EE5\u914D\u7F6E\u4E00\u4E2A\u9608\u503C\uFF0C\u5F53\u8BF7\u6C42\u6570\u8D85\u8FC7\u9608\u503C\u65F6\u5C31\u76F4\u63A5\u8FD4\u56DE\u9519\u8BEF\u800C\u4E0D\u7EE7\u7EED\u8BBF\u95EE\u540E\u53F0\u670D\u52A1\u3002\u5F53\u51FA\u73B0\u6D41\u91CF\u6D2A\u5CF0\u6216\u8005\u540E\u7AEF\u670D\u52A1\u51FA\u73B0\u5EF6\u8FDF\u6216\u6545\u969C\u65F6\uFF0C\u7F51\u5173\u80FD\u591F\u4E3B\u52A8\u8FDB\u884C\u7194\u65AD\uFF0C\u4FDD\u62A4\u540E\u7AEF\u670D\u52A1\uFF0C\u5E76\u4FDD\u6301\u524D\u7AEF\u7528\u6237\u4F53\u9A8C\u826F\u597D\u3002
    • \u9ED1\u767D\u540D\u5355\uFF1A\u5FAE\u670D\u52A1\u7F51\u5173\u53EF\u4EE5\u4F7F\u7528\u7CFB\u7EDF\u9ED1\u540D\u5355\uFF0C\u8FC7\u6EE4HTTP\u8BF7\u6C42\u7279\u5F81\uFF0C\u62E6\u622A\u5F02\u5E38\u5BA2\u6237\u7AEF\u7684\u8BF7\u6C42\uFF0C\u4F8B\u5982DDoS\u653B\u51FB\u7B49\u4FB5\u8680\u5E26\u5BBD\u6216\u8D44\u6E90\u8FEB\u4F7F\u670D\u52A1\u4E2D\u65AD\u7B49\u884C\u4E3A\uFF0C\u53EF\u4EE5\u5728\u7F51\u5173\u5C42\u9762\u8FDB\u884C\u62E6\u622A\u8FC7\u6EE4\u3002\u6BD4\u8F83\u5E38\u89C1\u7684\u62E6\u622A\u7B56\u7565\u662F\u6839\u636EIP\u5730\u5740\u589E\u52A0\u9ED1\u540D\u5355\u3002\u5728\u5B58\u5728\u9274\u6743\u7BA1\u7406\u7684\u8DEF\u7531\u670D\u52A1\u4E2D\u53EF\u4EE5\u901A\u8FC7\u8BBE\u7F6E\u767D\u540D\u5355\u8DF3\u8FC7\u9274\u6743\u7BA1\u7406\u800C\u76F4\u63A5\u8BBF\u95EE\u540E\u7AEF\u670D\u52A1\u8D44\u6E90\u3002
    • \u7070\u5EA6\u53D1\u5E03\uFF1A\u5FAE\u670D\u52A1\u7F51\u5173\u53EF\u4EE5\u6839\u636EHTTP\u8BF7\u6C42\u4E2D\u7684\u7279\u6B8A\u6807\u8BB0\u548C\u540E\u7AEF\u670D\u52A1\u5217\u8868\u5143\u6570\u636E\u6807\u8BC6\u8FDB\u884C\u6D41\u91CF\u63A7\u5236\uFF0C\u5B9E\u73B0\u5728\u7528\u6237\u65E0\u611F\u77E5\u7684\u60C5\u51B5\u4E0B\u5B8C\u6210\u7070\u5EA6\u53D1\u5E03\u3002
    • \u6D41\u91CF\u67D3\u8272\uFF1A\u548C\u7070\u5EA6\u53D1\u5E03\u7684\u539F\u7406\u76F8\u4F3C\uFF0C\u7F51\u5173\u53EF\u4EE5\u6839\u636EHTTP\u8BF7\u6C42\u7684Host\u3001Head\u3001Agent\u7B49\u6807\u8BC6\u5BF9\u8BF7\u6C42\u8FDB\u884C\u67D3\u8272\uFF0C\u6709\u4E86\u7F51\u5173\u7684\u6D41\u91CF\u67D3\u8272\u529F\u80FD\uFF0C\u6211\u4EEC\u53EF\u4EE5\u5BF9\u670D\u52A1\u540E\u7EED\u7684\u8C03\u7528\u94FE\u8DEF\u8FDB\u884C\u8DDF\u8E2A\uFF0C\u5BF9\u670D\u52A1\u5EF6\u8FDF\u53CA\u670D\u52A1\u8FD0\u884C\u72B6\u51B5\u8FDB\u884C\u8FDB\u4E00\u6B65\u7684\u94FE\u8DEF\u5206\u6790\u3002
    • \u6587\u6863\u4E2D\u5FC3\uFF1A\u7F51\u5173\u7ED3\u5408Swagger\uFF0C\u53EF\u4EE5\u5C06\u540E\u7AEF\u7684\u5FAE\u670D\u52A1\u66B4\u9732\u7ED9\u7F51\u5173\uFF0C\u7F51\u5173\u4F5C\u4E3A\u7EDF\u4E00\u7684\u5165\u53E3\u7ED9\u63A5\u53E3\u7684\u4F7F\u7528\u65B9\u63D0\u4F9B\u67E5\u770B\u540E\u7AEF\u670D\u52A1\u7684API\u89C4\u8303\uFF0C\u4E0D\u9700\u8981\u77E5\u9053\u6BCF\u4E00\u4E2A\u540E\u7AEF\u5FAE\u670D\u52A1\u7684Swagger\u5730\u5740\uFF0C\u8FD9\u6837\u7F51\u5173\u8D77\u5230\u4E86\u5BF9\u540E\u7AEFAPI\u805A\u5408\u7684\u6548\u679C\u3002
    • \u65E5\u5FD7\u5BA1\u8BA1\uFF1A\u5FAE\u670D\u52A1\u7F51\u5173\u53EF\u4EE5\u4F5C\u4E3A\u7EDF\u4E00\u7684\u65E5\u5FD7\u8BB0\u5F55\u548C\u6536\u96C6\u5668\uFF0C\u5BF9\u670D\u52A1URL\u7C92\u5EA6\u7684\u65E5\u5FD7\u8BF7\u6C42\u4FE1\u606F\u548C\u54CD\u5E94\u4FE1\u606F\u8FDB\u884C\u62E6\u622A\u3002

    API\u7F51\u5173\u9009\u578B

    \u5E38\u7528API\u7F51\u5173

    \u5148\u7B80\u5355\u770B\u4E00\u4E0B\u5E02\u9762\u4E0A\u5E38\u7528\u7684API\u7F51\u5173\uFF1A

    Nginx

    Nginx\u662F\u4E00\u4E2A\u9AD8\u6027\u80FD\u7684HTTP\u548C\u53CD\u5411\u4EE3\u7406\u670D\u52A1\u5668\u3002Nginx\u4E00\u65B9\u9762\u53EF\u4EE5\u505A\u53CD\u5411\u4EE3\u7406\uFF0C\u53E6\u5916\u4E00\u65B9\u9762\u53EF\u4EE5\u505A\u9759\u6001\u8D44\u6E90\u670D\u52A1\u5668\uFF0C\u63A5\u53E3\u4F7F\u7528Lua\u52A8\u6001\u8BED\u8A00\u53EF\u4EE5\u5B8C\u6210\u7075\u6D3B\u7684\u5B9A\u5236\u529F\u80FD\u3002

    Nginx \u5728\u542F\u52A8\u540E\uFF0C\u4F1A\u6709\u4E00\u4E2A Master \u8FDB\u7A0B\u548C\u591A\u4E2A Worker \u8FDB\u7A0B\uFF0CMaster \u8FDB\u7A0B\u548C Worker \u8FDB\u7A0B\u4E4B\u95F4\u662F\u901A\u8FC7\u8FDB\u7A0B\u95F4\u901A\u4FE1\u8FDB\u884C\u4EA4\u4E92\u7684\uFF0C\u5982\u56FE\u6240\u793A\u3002Worker \u5DE5\u4F5C\u8FDB\u7A0B\u7684\u963B\u585E\u70B9\u662F\u5728\u50CF select()\u3001epoll_wait() \u7B49\u8FD9\u6837\u7684 I/O \u591A\u8DEF\u590D\u7528\u51FD\u6570\u8C03\u7528\u5904\uFF0C\u4EE5\u7B49\u5F85\u53D1\u751F\u6570\u636E\u53EF\u8BFB / \u5199\u4E8B\u4EF6\u3002Nginx \u91C7\u7528\u4E86\u5F02\u6B65\u975E\u963B\u585E\u7684\u65B9\u5F0F\u6765\u5904\u7406\u8BF7\u6C42\uFF0C\u4E5F\u5C31\u662F\u8BF4\uFF0CNginx \u662F\u53EF\u4EE5\u540C\u65F6\u5904\u7406\u6210\u5343\u4E0A\u4E07\u4E2A\u8BF7\u6C42\u7684\u3002

    Zuul

    Zuul \u662F Netflix \u5F00\u6E90\u7684\u4E00\u4E2AAPI\u7F51\u5173\u7EC4\u4EF6\uFF0C\u5B83\u53EF\u4EE5\u548C Eureka\u3001Ribbon\u3001Hystrix \u7B49\u7EC4\u4EF6\u914D\u5408\u4F7F\u7528\u3002\u793E\u533A\u6D3B\u8DC3\uFF0C\u878D\u5408\u4E8E SpringCloud \u5B8C\u6574\u751F\u6001\uFF0C\u662F\u6784\u5EFA\u5FAE\u670D\u52A1\u4F53\u7CFB\u524D\u7F6E\u7F51\u5173\u670D\u52A1\u7684\u6700\u4F73\u9009\u578B\u4E4B\u4E00\u3002

    Zuul \u7684\u6838\u5FC3\u662F\u4E00\u7CFB\u5217\u7684\u8FC7\u6EE4\u5668\uFF0C\u8FD9\u4E9B\u8FC7\u6EE4\u5668\u53EF\u4EE5\u5B8C\u6210\u4EE5\u4E0B\u529F\u80FD\uFF1A

    • \u7EDF\u4E00\u9274\u6743 + \u52A8\u6001\u8DEF\u7531 + \u8D1F\u8F7D\u5747\u8861 + \u538B\u529B\u6D4B\u8BD5
    • \u5BA1\u67E5\u4E0E\u76D1\u63A7\uFF1A\u4E0E\u8FB9\u7F18\u4F4D\u7F6E\u8FFD\u8E2A\u6709\u610F\u4E49\u7684\u6570\u636E\u548C\u7EDF\u8BA1\u7ED3\u679C\uFF0C\u4ECE\u800C\u5E26\u6765\u7CBE\u786E\u7684\u751F\u4EA7\u89C6\u56FE\u3002
    • \u591A\u533A\u57DF\u5F39\u6027\uFF1A\u8DE8\u8D8A AWS Region \u8FDB\u884C\u8BF7\u6C42\u8DEF\u7531\uFF0C\u65E8\u5728\u5B9E\u73B0 ELB\uFF08Elastic Load Balancing\uFF0C\u5F39\u6027\u8D1F\u8F7D\u5747\u8861\uFF09\u4F7F\u7528\u7684\u591A\u6837\u5316\uFF0C\u4EE5\u53CA\u8BA9\u7CFB\u7EDF\u7684\u8FB9\u7F18\u66F4\u8D34\u8FD1\u7CFB\u7EDF\u7684\u4F7F\u7528\u8005\u3002

    Zuul \u76EE\u524D\u6709\u4E24\u4E2A\u5927\u7684\u7248\u672C\uFF1AZuul1 \u548C Zuul2

    Zuul1 \u662F\u57FA\u4E8E Servlet \u6846\u67B6\u6784\u5EFA\uFF0C\u5982\u56FE\u6240\u793A\uFF0C\u91C7\u7528\u7684\u662F\u963B\u585E\u548C\u591A\u7EBF\u7A0B\u65B9\u5F0F\uFF0C\u5373\u4E00\u4E2A\u7EBF\u7A0B\u5904\u7406\u4E00\u6B21\u8FDE\u63A5\u8BF7\u6C42\uFF0C\u8FD9\u79CD\u65B9\u5F0F\u5728\u5185\u90E8\u5EF6\u8FDF\u4E25\u91CD\u3001\u8BBE\u5907\u6545\u969C\u8F83\u591A\u60C5\u51B5\u4E0B\u4F1A\u5F15\u8D77\u5B58\u6D3B\u7684\u8FDE\u63A5\u589E\u591A\u548C\u7EBF\u7A0B\u589E\u52A0\u7684\u60C5\u51B5\u53D1\u751F\u3002

    Netflix \u53D1\u5E03\u7684 Zuul2 \u6709\u91CD\u5927\u7684\u66F4\u65B0\uFF0C\u5B83\u8FD0\u884C\u5728\u5F02\u6B65\u548C\u65E0\u963B\u585E\u6846\u67B6\u4E0A\uFF0C\u6BCF\u4E2A CPU \u6838\u4E00\u4E2A\u7EBF\u7A0B\uFF0C\u5904\u7406\u6240\u6709\u7684\u8BF7\u6C42\u548C\u54CD\u5E94\uFF0C\u8BF7\u6C42\u548C\u54CD\u5E94\u7684\u751F\u547D\u5468\u671F\u662F\u901A\u8FC7\u4E8B\u4EF6\u548C\u56DE\u8C03\u6765\u5904\u7406\u7684\uFF0C\u8FD9\u79CD\u65B9\u5F0F\u51CF\u5C11\u4E86\u7EBF\u7A0B\u6570\u91CF\uFF0C\u56E0\u6B64\u5F00\u9500\u8F83\u5C0F\u3002

    Spring Cloud GetWay

    Spring Cloud Gateway \u662FSpring Cloud\u7684\u4E00\u4E2A\u5168\u65B0\u7684API\u7F51\u5173\u9879\u76EE\uFF0C\u76EE\u7684\u662F\u4E3A\u4E86\u66FF\u6362\u6389Zuul1\uFF0C\u5B83\u57FA\u4E8ESpring5.0 + SpringBoot2.0 + WebFlux\uFF08\u57FA\u4E8E\u2FBC\u6027\u80FD\u7684Reactor\u6A21\u5F0F\u54CD\u5E94\u5F0F\u901A\u4FE1\u6846\u67B6Netty\uFF0C\u5F02\u6B65\u2FAE\u963B\u585E\u6A21\u578B\uFF09\u7B49\u6280\u672F\u5F00\u53D1\uFF0C\u6027\u80FD\u2FBC\u4E8EZuul\uFF0C\u5B98\u2F45\u6D4B\u8BD5\uFF0CSpring Cloud GateWay\u662FZuul\u76841.6\u500D\uFF0C\u65E8\u5728\u4E3A\u5FAE\u670D\u52A1\u67B6\u6784\u63D0\u4F9B\u2F00\u79CD\u7B80\u5355\u6709\u6548\u7684\u7EDF\u2F00\u7684API\u8DEF\u7531\u7BA1\u7406\u2F45\u5F0F\u3002

    Spring Cloud Gateway\u53EF\u4EE5\u4E0ESpring Cloud Discovery Client\uFF08\u5982Eureka\uFF09\u3001Ribbon\u3001Hystrix\u7B49\u7EC4\u4EF6\u914D\u5408\u4F7F\u7528\uFF0C\u5B9E\u73B0\u8DEF\u7531\u8F6C\u53D1\u3001\u8D1F\u8F7D\u5747\u8861\u3001\u7194\u65AD\u3001\u9274\u6743\u3001\u8DEF\u5F84\u91CD\u5199\u3001\u2F47\u5FD7\u76D1\u63A7\u7B49\uFF0C\u5E76\u4E14Gateway\u8FD8\u5185\u7F6E\u4E86\u9650\u6D41\u8FC7\u6EE4\u5668\uFF0C\u5B9E\u73B0\u4E86\u9650\u6D41\u7684\u529F\u80FD\u3002

    Kong

    Kong\u662F\u4E00\u6B3E\u57FA\u4E8EOpenResty\uFF08Nginx + Lua\u6A21\u5757\uFF09\u7F16\u5199\u7684\u9AD8\u53EF\u7528\u3001\u6613\u6269\u5C55\u7684\uFF0C\u7531Mashape\u516C\u53F8\u5F00\u6E90\u7684API Gateway\u9879\u76EE\u3002Kong\u662F\u57FA\u4E8ENGINX\u548CApache Cassandra\u6216PostgreSQL\u6784\u5EFA\u7684\uFF0C\u80FD\u63D0\u4F9B\u6613\u4E8E\u4F7F\u7528\u7684RESTful API\u6765\u64CD\u4F5C\u548C\u914D\u7F6EAPI\u7BA1\u7406\u7CFB\u7EDF\uFF0C\u6240\u4EE5\u5B83\u53EF\u4EE5\u6C34\u5E73\u6269\u5C55\u591A\u4E2AKong\u670D\u52A1\u5668\uFF0C\u901A\u8FC7\u524D\u7F6E\u7684\u8D1F\u8F7D\u5747\u8861\u914D\u7F6E\u628A\u8BF7\u6C42\u5747\u5300\u5730\u5206\u53D1\u5230\u5404\u4E2AServer\uFF0C\u6765\u5E94\u5BF9\u5927\u6279\u91CF\u7684\u7F51\u7EDC\u8BF7\u6C42\u3002

    Kong\u4E3B\u8981\u6709\u4E09\u4E2A\u7EC4\u4EF6\uFF1A

    • Kong Server \uFF1A\u57FA\u4E8ENginx\u7684\u670D\u52A1\u5668\uFF0C\u7528\u6765\u63A5\u6536API\u8BF7\u6C42\u3002
    • Apache Cassandra/PostgreSQL \uFF1A\u7528\u6765\u5B58\u50A8\u64CD\u4F5C\u6570\u636E\u3002
    • Kong dashboard\uFF1A\u5B98\u65B9\u63A8\u8350UI\u7BA1\u7406\u5DE5\u5177\uFF0C\u4E5F\u53EF\u4EE5\u4F7F\u7528 restfull \u65B9\u5F0F\u7BA1\u7406admin api\u3002

    Kong\u91C7\u7528\u63D2\u4EF6\u673A\u5236\u8FDB\u884C\u529F\u80FD\u5B9A\u5236\uFF0C\u63D2\u4EF6\u96C6\uFF08\u53EF\u4EE5\u662F0\u6216N\u4E2A\uFF09\u5728API\u8BF7\u6C42\u54CD\u5E94\u5FAA\u73AF\u7684\u751F\u547D\u5468\u671F\u4E2D\u88AB\u6267\u884C\u3002\u63D2\u4EF6\u4F7F\u7528Lua\u7F16\u5199\uFF0C\u76EE\u524D\u5DF2\u6709\u51E0\u4E2A\u57FA\u7840\u529F\u80FD\uFF1AHTTP\u57FA\u672C\u8BA4\u8BC1\u3001\u5BC6\u94A5\u8BA4\u8BC1\u3001CORS\uFF08Cross-Origin Resource Sharing\uFF0C\u8DE8\u57DF\u8D44\u6E90\u5171\u4EAB\uFF09\u3001TCP\u3001UDP\u3001\u6587\u4EF6\u65E5\u5FD7\u3001API\u8BF7\u6C42\u9650\u6D41\u3001\u8BF7\u6C42\u8F6C\u53D1\u4EE5\u53CANginx\u76D1\u63A7\u3002

    Kong\u7F51\u5173\u5177\u6709\u4EE5\u4E0B\u7684\u7279\u6027\uFF1A

    • \u53EF\u6269\u5C55\u6027: \u901A\u8FC7\u7B80\u5355\u5730\u6DFB\u52A0\u66F4\u591A\u7684\u670D\u52A1\u5668\uFF0C\u53EF\u4EE5\u8F7B\u677E\u5730\u8FDB\u884C\u6A2A\u5411\u6269\u5C55\uFF0C\u8FD9\u610F\u5473\u7740\u60A8\u7684\u5E73\u53F0\u53EF\u4EE5\u5728\u4E00\u4E2A\u8F83\u4F4E\u8D1F\u8F7D\u7684\u60C5\u51B5\u4E0B\u5904\u7406\u4EFB\u4F55\u8BF7\u6C42\uFF1B
    • \u6A21\u5757\u5316: \u53EF\u4EE5\u901A\u8FC7\u6DFB\u52A0\u65B0\u7684\u63D2\u4EF6\u8FDB\u884C\u6269\u5C55\uFF0C\u8FD9\u4E9B\u63D2\u4EF6\u53EF\u4EE5\u901A\u8FC7RESTful Admin API\u8F7B\u677E\u914D\u7F6E\uFF1B
    • \u5728\u4EFB\u4F55\u57FA\u7840\u67B6\u6784\u4E0A\u8FD0\u884C: Kong\u7F51\u5173\u53EF\u4EE5\u5728\u4EFB\u4F55\u5730\u65B9\u90FD\u80FD\u8FD0\u884C\u3002\u60A8\u53EF\u4EE5\u5728\u4E91\u6216\u5185\u90E8\u7F51\u7EDC\u73AF\u5883\u4E2D\u90E8\u7F72Kong\uFF0C\u5305\u62EC\u5355\u4E2A\u6216\u591A\u4E2A\u6570\u636E\u4E2D\u5FC3\u8BBE\u7F6E\uFF0C\u4EE5\u53CApublic\uFF0Cprivate \u6216invite-only APIs\u3002

    Traefik

    Tr\xE6f\u026Ak \u662F\u4E00\u4E2A\u4E3A\u4E86\u8BA9\u90E8\u7F72\u5FAE\u670D\u52A1\u66F4\u52A0\u4FBF\u6377\u800C\u8BDE\u751F\u7684\u73B0\u4EE3HTTP\u53CD\u5411\u4EE3\u7406\u3001\u8D1F\u8F7D\u5747\u8861\u5DE5\u5177\u3002 \u5B83\u652F\u6301\u591A\u79CD\u540E\u53F0 (Docker, Swarm, Kubernetes, Marathon, Mesos, Consul, Etcd, Zookeeper, BoltDB, Rest API, file\u2026) \u6765\u81EA\u52A8\u5316\u3001\u52A8\u6001\u7684\u5E94\u7528\u5B83\u7684\u914D\u7F6E\u6587\u4EF6\u8BBE\u7F6E\u3002

    \u91CD\u8981\u7279\u6027\uFF1A

    • \u5B83\u975E\u5E38\u5FEB\uFF0C\u65E0\u9700\u5B89\u88C5\u5176\u4ED6\u4F9D\u8D56\uFF0C\u901A\u8FC7Go\u8BED\u8A00\u7F16\u5199\u7684\u5355\u4E00\u53EF\u6267\u884C\u6587\u4EF6\uFF1B
    • \u591A\u79CD\u540E\u53F0\u652F\u6301\uFF1ADocker, Swarm, Kubernetes, Marathon, Mesos, Consul, Etcd\uFF1B
    • \u652F\u6301\u652F\u6301Rest API\u3001Websocket\u3001HTTP/2\u3001Docker\u955C\u50CF\uFF1B
    • \u76D1\u542C\u540E\u53F0\u53D8\u5316\u8FDB\u800C\u81EA\u52A8\u5316\u5E94\u7528\u65B0\u7684\u914D\u7F6E\u6587\u4EF6\u8BBE\u7F6E\uFF1B
    • \u914D\u7F6E\u6587\u4EF6\u70ED\u66F4\u65B0\uFF0C\u65E0\u9700\u91CD\u542F\u8FDB\u7A0B\uFF1B
    • \u540E\u7AEF\u65AD\u8DEF\u5668\u3001\u8D1F\u8F7D\u5747\u8861\u3001\u5BB9\u9519\u673A\u5236\uFF1B
    • \u6E05\u723D\u7684\u524D\u7AEF\u9875\u9762\uFF0C\u53EF\u76D1\u63A7\u670D\u52A1\u6307\u6807\u3002

    \u5173\u4E8ETraefik\u7684\u66F4\u591A\u5185\u5BB9\uFF0C\u53EF\u4EE5\u67E5\u770B\u5B98\u7F51\uFF1Ahttps://traefik.cn/

    API\u7F51\u5173\u5BF9\u6BD4

    \u4E0A\u9762\u662F\u7F51\u5173\u5BF9\u6BD4\u622A\u56FE\uFF0C\u5077\u4E2A\u61D2\uFF0C\u5927\u5BB6\u4E3B\u8981\u5173\u6CE8Kong\u3001Traefik\u548CZuul\u5373\u53EF\uFF1A

    • \u4ECE\u5F00\u6E90\u793E\u533A\u6D3B\u8DC3\u5EA6\u6765\u770B\uFF0C\u65E0\u7591\u662FKong\u548CTraefik\u8F83\u597D\uFF1B
    • \u4ECE\u6210\u719F\u5EA6\u6765\u770B\uFF0C\u8F83\u597D\u7684\u662FKong\u3001Tyk\u3001Traefik\uFF1B
    • \u4ECE\u6027\u80FD\u6765\u770B\uFF0CKong\u8981\u6BD4\u5176\u4ED6\u51E0\u4E2A\u9886\u5148\u4E00\u4E9B\uFF1B
    • \u4ECE\u67B6\u6784\u4F18\u52BF\u7684\u6269\u5C55\u6027\u6765\u770B\uFF0CKong\u3001Tyk\u6709\u4E30\u5BCC\u7684\u63D2\u4EF6\uFF0CAmbassador\u4E5F\u6709\u63D2\u4EF6\u4F46\u4E0D\u591A\uFF0C\u800CZuul\u662F\u5B8C\u5168\u9700\u8981\u81EA\u7814\uFF0C\u4F46Zuul\u7531\u4E8E\u4E0ESpring Cloud\u6DF1\u5EA6\u96C6\u6210\uFF0C\u4F7F\u7528\u5EA6\u4E5F\u5F88\u9AD8\uFF0C\u8FD1\u5E74\u6765Istio\u670D\u52A1\u7F51\u683C\u7684\u6D41\u884C\uFF0CAmbassador\u56E0\u4E3A\u80FD\u591F\u548CIstio\u65E0\u7F1D\u96C6\u6210\u4E5F\u662F\u76F8\u5F53\u5927\u7684\u4F18\u52BF\u3002

    \u4E0B\u9762\u662F\u5176\u5B83\u7F51\u53CB\u7684\u601D\u8003\u7ED3\u8BBA\uFF0C\u53EF\u4F9B\u53C2\u8003\uFF1A

    • \u6027\u80FD\uFF1ANginx+Lua\u5F62\u5F0F\u5FC5\u7136\u662F\u9AD8\u4E8EJava\u8BED\u8A00\u5B9E\u73B0\u7684\u7F51\u5173\u7684\uFF0CJava\u6280\u672F\u6808\u91CC\u9762Zuul1.0\u662F\u57FA\u4E8EServlet\u5B9E\u73B0\u7684\uFF0C\u5269\u4E0B\u90FD\u662F\u57FA\u4E8Ewebflux\u5B9E\u73B0\uFF0C\u6027\u80FD\u662F\u9AD8\u4E8E\u57FA\u4E8EServlet\u5B9E\u73B0\u7684\u3002\u5728\u6027\u80FD\u65B9\u9762\u6211\u89C9\u5F97\u9009\u62E9\u7F51\u5173\u53EF\u80FD\u4E0D\u7B97\u90A3\u4E48\u91CD\u8981\uFF0C\u591A\u52A0\u51E0\u53F0\u673A\u5668\u5C31\u53EF\u4EE5\u641E\u5B9A\u3002
    • \u53EF\u7EF4\u62A4\u6027\u548C\u6269\u5C55\u6027\uFF1ANginx+Lua\u8FD9\u4E2A\u7EC4\u5408\u638C\u63E1\u7684\u4EBA\u4E0D\u7B97\u591A\uFF0C\u5982\u679C\u56E2\u961F\u6709\u5927\u795E\uFF0C\u5927\u4F6C\u4EEC\u5C31\u968F\u610F\u4E86\uFF0C\u5F53\u6CA1\u770B\u5230\u8FD9\u6BB5\u8BDD\uFF0C\u5BF9\u4E8E\u4E00\u822C\u56E2\u961F\u6765\u8BF4\u7684\u8BDD\uFF0C\u9009\u62E9\u81EA\u5DF1\u56E2\u961F\u64C5\u957F\u7684\u8BED\u8A00\u66F4\u91CD\u8981\u3002Java\u6280\u672F\u6808\u4E0B\u76843\u79CD\u7F51\u5173\uFF0C\u5BF9\u4E8EZuul\u548CSpring Cloud Getway\u9700\u8981\u6216\u591A\u6216\u5C11\u8981\u641E\u4E00\u4E9B\u96C6\u6210\u548C\u914D\u7F6E\u9875\u9762\u6765\u7EF4\u62A4\uFF0C\u4F46\u662F\u5BF9\u4E8ESoul\u6211\u5C31\u65E0\u8111\u770B\u770B\u6587\u7AE0\uFF0C\u9700\u8981\u54EA\u4E2A\u642C\u54EA\u4E2A\u597D\u4E86\uFF0C\u5C24\u5176\u662F\u53EF\u4EE5\u65E0\u8111\u5BF9\u63A5Dubbo\u7F8E\u6ECB\u6ECB\uFF0C\u6B64\u5916Soul2.0\u4EE5\u540E\u7248\u672C\u53EF\u4EE5\u6446\u8131ZK\uFF0C\u5728\u6211\u5FC3\u91CC\u518D\u65E0\u8BDF\u75C5\uFF0C\u6211\u5C31\u559C\u6B22\u65E0\u8111\u64CD\u4F5C\u3002
    • \u9AD8\u53EF\u7528\uFF1A\u5BF9\u4E8E\u7F51\u5173\u9AD8\u53EF\u7528\u57FA\u672C\u90FD\u662F\u7EDF\u4E00\u7684\u7B56\u7565\u90FD\u662F\u91C7\u7528\u591A\u673A\u5668\u90E8\u7F72\u7684\u65B9\u5F0F\uFF0C\u524D\u9762\u6302\u4E00\u4E2A\u8D1F\u8F7D\uFF0C\u5BF9\u4E8E\u800C\u5916\u9700\u8981\u7528\u7684\u4E00\u4E9B\u7EC4\u4EF6\u5927\u5BB6\u6CE8\u610F\u4E00\u4E0B\u3002

    \u57FA\u4E8ETraefik\u81EA\u7814\u7684\u5FAE\u670D\u52A1\u7F51\u5173

    \u8FD9\u4E2A\u662F\u6211\u53F8\u81EA\u7814\u7684\u5FAE\u670D\u52A1\u7F51\u5173\uFF0C\u57FA\u4E8ETraefik\u8FDB\u884C\u5F00\u53D1\uFF0C\u4E0B\u9762\u4ECE\u6280\u672F\u9009\u578B\u3001\u7F51\u5173\u6846\u67B6\u3001\u7F51\u5173\u540E\u53F0\u3001\u534F\u8BAE\u8F6C\u6362\u8FDB\u884C\u8BB2\u89E3\uFF0C\u7EDD\u5BF9\u5E72\u8D27\uFF01

    \u6280\u672F\u6808\u9009\u578B

    • Traefik\uFF1A\u4E00\u6B3E\u5F00\u6E90\u7684\u53CD\u5411\u4EE3\u7406\u4E0E\u8D1F\u8F7D\u5747\u8861\u5DE5\u5177\uFF0C\u5B83\u6700\u5927\u7684\u4F18\u70B9\u662F\u80FD\u591F\u4E0E\u5E38\u89C1\u7684\u5FAE\u670D\u52A1\u7CFB\u7EDF\u76F4\u63A5\u6574\u5408\uFF0C\u53EF\u4EE5\u5B9E\u73B0\u81EA\u52A8\u5316\u52A8\u6001\u914D\u7F6E\u3002traefik\u8F83\u4E3A\u8F7B\u91CF\uFF0C\u975E\u5E38\u6613\u4E8E\u4F7F\u7528\u548C\u8BBE\u7F6E\uFF0C\u6027\u80FD\u6BD4\u8F83\u597D\uFF0C\u5DF2\u5728\u5168\u7403\u8303\u56F4\u5185\u7528\u4E8E\u751F\u4EA7\u73AF\u5883\u3002
    • Etcd\uFF1A\u4E00\u4E2AGo\u8A00\u7F16\u5199\u7684\u5206\u5E03\u5F0F\u3001\u9AD8\u53EF\u7528\u7684\u4E00\u81F4\u6027\u952E\u503C\u5B58\u50A8\u7CFB\u7EDF\uFF0C\u7528\u4E8E\u63D0\u4F9B\u53EF\u9760\u7684\u5206\u5E03\u5F0F\u952E\u503C\u5B58\u50A8\u3001\u914D\u7F6E\u5171\u4EAB\u548C\u670D\u52A1\u53D1\u73B0\u7B49\u529F\u80FD\u3002
    • Go\uFF1A\u5E76\u53D1\u80FD\u529B\u5F3A\uFF0C\u6027\u80FD\u5AB2\u7F8EC\uFF0C\u5904\u7406\u80FD\u529B\u662FPHP\u76844\u500D\uFF0C\u6548\u7387\u9AD8\uFF0C\u8BED\u6CD5\u7B80\u5355\uFF0C\u6613\u4E0A\u624B\uFF0C\u5F00\u53D1\u6548\u7387\u63A5\u8FD1PHP\u3002

    \u7F51\u5173\u6846\u67B6

    \u6574\u4E2A\u7F51\u5173\u6846\u67B6\u5206\u4E3A3\u5757\uFF1A

    • \u7F51\u5173\u540E\u53F0\uFF08hal-fe\u548Chal-admin\uFF09\uFF1A\u7528\u4E8E\u5E94\u7528\u3001\u670D\u52A1\u548C\u63D2\u4EF6\u7684\u914D\u7F6E\uFF0C\u7136\u540E\u5C06\u914D\u7F6E\u4FE1\u606F\u53D1\u5E03\u5230ETCD\uFF1B
    • Traefik\uFF1A\u8BFB\u53D6ETCD\u914D\u7F6E\uFF0C\u6839\u636E\u914D\u7F6E\u4FE1\u606F\u5BF9\u8BF7\u6C42\u8FDB\u884C\u8DEF\u7531\u5206\u53D1\uFF0C\u5982\u679C\u9700\u8981\u9274\u6743\uFF0C\u4F1A\u76F4\u63A5\u901A\u8FC7hal-agent\u6A21\u5757\u8FDB\u884C\u7EDF\u4E00\u9274\u6743\u3002\u9274\u6743\u5B8C\u6BD5\u540E\uFF0C\u5982\u679C\u662FHttp\u8BF7\u6C42\uFF0C\u76F4\u63A5\u6253\u5230\u4E0B\u6E38\u670D\u52A1\uFF0C\u5982\u679C\u662FGrpc\u548CThrift\u534F\u8BAE\uFF0C\u4F1A\u901A\u8FC7hal-proxy\u6A21\u5757\u8FDB\u884C\u534F\u8BAE\u8F6C\u6362\u3002
    • \u534F\u8BAE\u8F6C\u6362\u6A21\u5757\uFF1A\u8BFB\u53D6ETCD\u914D\u7F6E\uFF0C\u5BF9Traefik\u5206\u53D1\u8FC7\u6765\u7684\u8BF7\u6C42\uFF0C\u8FDB\u884CGrpc\u548CThrift\u534F\u8BAE\u8F6C\u6362\uFF0C\u5E76\u901A\u8FC7\u670D\u52A1\u53D1\u73B0\u673A\u5236\uFF0C\u83B7\u53D6\u670D\u52A1\u4E0B\u6E38\u673A\u5668\uFF0C\u5E76\u901A\u8FC7\u8D1F\u8F7D\u5747\u8861\uFF0C\u5C06\u8F6C\u6362\u540E\u7684\u6570\u636E\u6253\u5230\u4E0B\u6E38\u670D\u52A1\u673A\u5668\u3002

    \u7F51\u5173\u540E\u53F0

    \u4E3B\u8981\u75313\u5927\u6A21\u5757\u7EC4\u6210\uFF1A

    • \u5E94\u7528\uFF1A\u4E3B\u8981\u5305\u62EC\u5E94\u7528\u540D\u3001\u57DF\u540D\u3001\u8DEF\u5F84\u524D\u7F00\u3001\u6240\u5C5E\u7EC4\u3001\u72B6\u6001\u7B49\uFF0C\u6BD4\u5982\u5370\u5EA6\u6D77\u5916\u5546\u57CE\u3001\u5370\u5EA6\u793E\u533A\uFF1B
    • \u670D\u52A1\uFF1A\u4E3B\u8981\u5305\u62EC\u670D\u52A1\u540D\u3001\u6CE8\u518C\u65B9\u5F0F\u3001\u534F\u8BAE\u7C7B\u578B\u3001\u6240\u5C5E\u7EC4\u3001\u72B6\u6001\u7B49\uFF0C\u6BD4\u5982\u8BC4\u8BBA\u670D\u52A1\u3001\u5730\u5740\u670D\u52A1\u3001\u641C\u7D22\u670D\u52A1\u3002
    • \u63D2\u4EF6\uFF1A\u4E3B\u8981\u5305\u62EC\u63D2\u4EF6\u540D\u79F0\u3001\u63D2\u4EF6\u7C7B\u578B\u3001\u63D2\u4EF6\u5C5E\u6027\u914D\u7F6E\u7B49\uFF0C\u6BD4\u5982\u8DEF\u5F84\u524D\u7F00\u66FF\u6362\u63D2\u4EF6\u3001\u9274\u6743\u63D2\u4EF6\u3002

    \u4E00\u4E2A\u5E94\u7528\u53EA\u80FD\u7ED1\u5B9A\u4E00\u4E2A\u670D\u52A1\uFF0C\u4F46\u662F\u53EF\u4EE5\u7ED1\u5B9A\u591A\u4E2A\u63D2\u4EF6\u3002 \u901A\u8FC7\u540E\u53F0\u5B8C\u6210\u7F51\u5173\u914D\u7F6E\u540E\uFF0C\u5C06\u8FD9\u4E9B\u914D\u7F6E\u4FE1\u606F\u751F\u6210Config\u6587\u4EF6\uFF0C\u53D1\u5E03\u5230ETCD\u4E2D\uFF0CConfig\u6587\u4EF6\u9700\u8981\u9075\u5FAA\u4E25\u683C\u7684\u6570\u636E\u683C\u5F0F\uFF0C\u6BD4\u5982Traefix\u914D\u7F6E\u9700\u8981\u9075\u5FAA\u5B98\u65B9\u7684\u6587\u4EF6\u914D\u7F6E\u683C\u5F0F\uFF0C\u624D\u80FD\u88ABTraefik\u8BC6\u522B\u3002

    \u534F\u8BAE\u8F6C\u6362\u6A21\u5757

    hal-proxy\u6A21\u5757\u662F\u6574\u4E2A\u5FAE\u670D\u52A1\u7F51\u5173\u6700\u590D\u6742\uFF0C\u4E5F\u662F\u6280\u672F\u542B\u91CF\u6700\u9AD8\u7684\u6A21\u5757\uFF0C\u6240\u4EE5\u7ED9\u5927\u5BB6\u8BE6\u7EC6\u8BB2\u89E3\u4E00\u4E0B\u3002

    \u95EE\u9898\u5F15\u5165

    \u5728\u8BB2\u8FD9\u4E2A\u6A21\u5757\u524D\uFF0C\u6211\u4EEC\u5148\u770B\u4E0B\u9762\u51E0\u4E2A\u95EE\u9898\uFF1A

    • \u5F53\u8BF7\u6C42\u4ECE\u4E0A\u6E38\u7684trafik\u8FC7\u6765\u65F6\uFF0C\u9700\u8981\u77E5\u9053\u8BBF\u95EE\u4E0B\u6E38\u7684\u673A\u5668IP\u548C\u7AEF\u53E3\uFF0C\u624D\u80FD\u5C06\u8BF7\u6C42\u53D1\u9001\u7ED9\u4E0B\u6E38\uFF0C\u8FD9\u4E9B\u673A\u5668\u5982\u4F55\u83B7\u53D6\u5462\uFF1F
    • \u6709\u4E86\u673A\u5668\u540E\uFF0C\u6211\u4EEC\u9700\u8981\u548C\u4E0B\u6E38\u673A\u5668\u5EFA\u7ACB\u8FDE\u63A5\uFF0C\u5982\u679C\u8FDE\u63A5\u7528\u4E00\u6B21\u5C31\u76F4\u63A5\u91CA\u653E\uFF0C\u80AF\u5B9A\u5BF9\u670D\u52A1\u4F1A\u9020\u6210\u5F88\u5927\u7684\u538B\u529B\uFF0C\u8FD9\u5C31\u9700\u8981\u5F15\u5165Client\u7F13\u5B58\u6C60\uFF0C\u90A3\u8FD9\u4E2AClient\u7F13\u5B58\u6C60\u6211\u4EEC\u53C8\u8BE5\u5982\u4F55\u5B9E\u73B0\u5462\uFF1F
    • \u6700\u540E\u5C31\u662F\u9700\u8981\u5BF9\u534F\u8BAE\u8FDB\u884C\u8F6C\u6362\uFF0C\u56E0\u4E3A\u4E0D\u540C\u7684\u4E0B\u6E38\u670D\u52A1\uFF0C\u652F\u6301\u7684\u534F\u8BAE\u7C7B\u578B\u662F\u4E0D\u4E00\u6837\u7684\uFF0C\u8FD9\u4E2A\u7F51\u5173\u53C8\u662F\u5982\u4F55\u52A8\u6001\u652F\u6301\u7684\u5462\uFF1F

    \u5B9E\u73B0\u539F\u7406

    \u6211\u4EEC\u8FD8\u662F\u5148\u770B\u4E00\u4E0Bhal-proxy\u5185\u90E8\u6709\u54EA\u4E9B\u6A21\u5757\uFF0C\u9996\u5148\u662FResolver\u6A21\u5757\uFF0C\u8FD9\u4E2A\u6A21\u5757\u7684\u662F\u4EC0\u4E48\u4F5C\u7528\u5462\uFF1F\u8FD9\u91CC\u6211\u7B80\u5355\u4ECB\u7ECD\u4E00\u4E0B\uFF0C\u76EE\u524D\u516C\u53F8\u5185\u90E8\u901A\u8FC7\u670D\u52A1\u83B7\u53D6\u5230\u673A\u5668\u5217\u8868\u7684\u65B9\u5F0F\u6709\u591A\u79CD\uFF0C\u6BD4\u5982MIS\u5E73\u53F0\u3001\u670D\u52A1\u6811\u7B49\uFF0C\u4E5F\u5C31\u662F\u6709\u7684\u662F\u901A\u8FC7\u5E73\u53F0\u914D\u7F6E\u7684\uFF0C\u6709\u7684\u662F\u76F4\u63A5\u6302\u5728\u670D\u52A1\u6811\u4E0B\uFF0C\u65E0\u8BBA\u54EA\u79CD\u65B9\u5F0F\uFF0C\u6211\u4EEC\u90FD\u901A\u8FC7\u670D\u52A1\u540D\uFF0C\u901A\u8FC7\u4E00\u5B9A\u7684\u65B9\u5F0F\uFF0C\u627E\u5230\u8BE5\u670D\u52A1\u4E0B\u9762\u6240\u6709\u7684\u4E3B\u673A\u3002

    \u6240\u4EE5Resolver\u6A21\u5757\u7684\u4F5C\u7528\uFF0C\u5176\u5B9E\u5C31\u662F\u901A\u8FC7\u670D\u52A1\u540D\uFF0C\u627E\u5230\u8BE5\u670D\u52A1\u4E0B\u7684\u6240\u6709\u673A\u5668\u7684IP\u548C\u670D\u52A1\u7AEF\u53E3\uFF0C\u7136\u540E\u6301\u4E45\u5316\u5230\u5185\u5B58\u4E2D\uFF0C\u5E76\u5B9A\u65F6\u66F4\u65B0\u3002

    \u534F\u8BAE\u6A21\u5757\u5C31\u662F\u652F\u6301\u4E0D\u540C\u7684\u534F\u8BAE\u8F6C\u6362\uFF0C\u6BCF\u4E2A\u534F\u8BAE\u7C7B\u578B\u7684\u8F6C\u6362\uFF0C\u90FD\u9700\u8981\u5355\u72EC\u5B9E\u73B0\uFF0C\u8FD9\u4E9B\u534F\u8BAE\u8F6C\u6362\uFF0C\u65E0\u975E\u5C31\u662F\u5148\u901A\u8FC7\u673A\u5668IP\u548C\u7AEF\u53E3\u521D\u59CB\u5316Client\uFF0C\u7136\u540E\u518D\u5C06\u6570\u636E\u8FDB\u884C\u8F6C\u6362\u540E\uFF0C\u76F4\u63A5\u53D1\u9001\u5230\u4E0B\u6E38\u7684\u673A\u5668\u3002

    \u6700\u540E\u5C31\u662F\u8FDE\u63A5\u6C60\uFF0C\u4E4B\u524D\u6211\u4EEC\u5176\u5B9E\u4E5F\u7528\u5230go\u81EA\u5E26\u7684pool\u6765\u505A\uFF0C\u4F46\u662F\u5F53\u5BF9pool\u6570\u636E\u8FDB\u884C\u66F4\u65B0\u65F6\uFF0C\u9700\u8981\u52A0\u9501\uFF0C\u6240\u4EE5\u6027\u80FD\u4E00\u76F4\u8D77\u4E0D\u6765\uFF0C\u540E\u6765\u6539\u6210\u4E86\u73AF\u5F62\u961F\u5217\uFF0C\u7136\u540E\u5BF9\u6570\u636E\u7684\u64CD\u4F5C\u5168\u90E8\u901A\u8FC7\u539F\u5B50\u64CD\u4F5C\u65B9\u5F0F\uFF0C\u5C31\u5B9E\u73B0\u4E86\u65E0\u9501\u64CD\u4F5C\uFF0C\u5927\u5927\u63D0\u9AD8\u7684\u5E76\u53D1\u6027\u80FD\u3002

    \u5B9E\u73B0\u903B\u8F91

    \u8FD9\u4E2A\u662Fhal-proxy\u7684\u903B\u8F91\u5B9E\u73B0\u56FE\uFF0C\u753B\u4E862\u5929\uFF0C\u5305\u542B\u6240\u6709\u6838\u5FC3\u5BF9\u8C61\u7684\u4EA4\u4E92\u65B9\u5F0F\uFF0C\u8FD9\u91CC\u5C31\u4E0D\u53BB\u7EC6\u8BB2\uFF0C\u80FD\u638C\u63E1\u591A\u5C11\uFF0C\u9760\u5927\u5BB6\u81EA\u5DF1\u9886\u609F\uFF0C\u5982\u679C\u6709\u4EFB\u4F55\u7591\u95EE(\u6216\u8005\u770B\u4E0D\u6E05\u56FE\u7247)\uFF0C\u53EF\u4EE5\u5173\u6CE8\u6211\u516C\u4F17\u53F7\uFF0C\u52A0\u6211\u5FAE\u4FE1\u6C9F\u901A\u3002


    ',85),v=a("\u6574\u7406\uFF1A\u6C89\u9ED8\u738B\u4E8C\uFF0C\u6233"),x={href:"https://mp.weixin.qq.com/s/b2xf4GiJksBQqjHVpsh49Q",target:"_blank",rel:"noopener noreferrer"},P=a("\u8F6C\u8F7D\u94FE\u63A5"),_=a("\uFF0C\u4F5C\u8005\uFF1A\u697C\u4ED4\uFF0C\u6233"),k={href:"https://mp.weixin.qq.com/s/0Qupyl5eCyQGFEAIY6GxoQ",target:"_blank",rel:"noopener noreferrer"},I=a("\u539F\u6587\u94FE\u63A5"),T=a("\u3002"),A=e("p",null,[e("img",{src:"http://cdn.tobebetterjavaer.com/tobebetterjavaer/images/xingbiaogongzhonghao.png",alt:""})],-1);function j(w,S){const r=n("ExternalLinkIcon");return o(),s("div",null,[e("blockquote",null,[e("p",null,[c,e("a",p,[d,t(r)]),h,e("a",b,[u,t(r)]),f])]),m,e("blockquote",null,[e("p",null,[v,e("a",x,[P,t(r)]),_,e("a",k,[I,t(r)]),T])]),A])}var E=i(g,[["render",j],["__file","api-wangguan.html.vue"]]);export{E as default}; diff --git a/dist/assets/app.615e41d8.js b/dist/assets/app.615e41d8.js new file mode 100644 index 00000000..028f43d3 --- /dev/null +++ b/dist/assets/app.615e41d8.js @@ -0,0 +1,25 @@ +var sf=Object.defineProperty,uf=Object.defineProperties;var df=Object.getOwnPropertyDescriptors;var Va=Object.getOwnPropertySymbols;var ff=Object.prototype.hasOwnProperty,mf=Object.prototype.propertyIsEnumerable;var Ma=(e,t,n)=>t in e?sf(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n,le=(e,t)=>{for(var n in t||(t={}))ff.call(t,n)&&Ma(e,n,t[n]);if(Va)for(var n of Va(t))mf.call(t,n)&&Ma(e,n,t[n]);return e},Fe=(e,t)=>uf(e,df(t));const ka={},hf="modulepreload",za={},vf="/",d=function(t,n){return!n||n.length===0?t():Promise.all(n.map(r=>{if(r=`${vf}${r}`,r in za)return;za[r]=!0;const o=r.endsWith(".css"),i=o?'[rel="stylesheet"]':"";if(document.querySelector(`link[href="${r}"]${i}`))return;const a=document.createElement("link");if(a.rel=o?"stylesheet":hf,o||(a.as="script",a.crossOrigin=""),a.href=r,document.head.appendChild(a),o)return new Promise((l,c)=>{a.addEventListener("load",l),a.addEventListener("error",()=>c(new Error(`Unable to preload CSS for ${r}`)))})})).then(()=>t())},pf={"v-8daa1a0e":()=>d(()=>import("./index.html.b90a750c.js"),[]).then(({data:e})=>e),"v-79fdd481":()=>d(()=>import("./home.html.1fffdb8f.js"),[]).then(({data:e})=>e),"v-5eb6769a":()=>d(()=>import("./bzhan-10wan.html.98f8ba37.js"),[]).then(({data:e})=>e),"v-047e0dd0":()=>d(()=>import("./csdn-1000wan.html.438218cb.js"),[]).then(({data:e})=>e),"v-728c3a8f":()=>d(()=>import("./index.html.a4bb5c6e.js"),[]).then(({data:e})=>e),"v-d4d4d9f0":()=>d(()=>import("./zhihu-1000wan.html.4bf2b6f4.js"),[]).then(({data:e})=>e),"v-4c9adc8f":()=>d(()=>import("./array.html.77525f56.js"),[]).then(({data:e})=>e),"v-c5b29e8a":()=>d(()=>import("./print.html.6fe8360d.js"),[]).then(({data:e})=>e),"v-5bc8e34a":()=>d(()=>import("./basic-data-type.html.6be3e7e2.js"),[]).then(({data:e})=>e),"v-2e99fc7b":()=>d(()=>import("./flow-control.html.f6c60ead.js"),[]).then(({data:e})=>e),"v-2ed31bba":()=>d(()=>import("./javadoc.html.b34e8efb.js"),[]).then(({data:e})=>e),"v-5bd30156":()=>d(()=>import("./operator.html.9431d9fc.js"),[]).then(({data:e})=>e),"v-116742fa":()=>d(()=>import("./java-basic-34.html.70be78f8.js"),[]).then(({data:e})=>e),"v-41eeffa1":()=>d(()=>import("./java-basic.html.52bd7f06.js"),[]).then(({data:e})=>e),"v-453decce":()=>d(()=>import("./java-thread.html.4a99fb0e.js"),[]).then(({data:e})=>e),"v-1a5aed8d":()=>d(()=>import("./jvm.html.1b4e3107.js"),[]).then(({data:e})=>e),"v-68d21dbd":()=>d(()=>import("./48-keywords.html.e76832ee.js"),[]).then(({data:e})=>e),"v-079af819":()=>d(()=>import("./Overriding.html.14f830f8.js"),[]).then(({data:e})=>e),"v-bb853b5a":()=>d(()=>import("./annotation.html.14064668.js"),[]).then(({data:e})=>e),"v-4b1bf2c5":()=>d(()=>import("./box.html.54cc70a2.js"),[]).then(({data:e})=>e),"v-40e5cd2e":()=>d(()=>import("./class-object.html.c43412d3.js"),[]).then(({data:e})=>e),"v-788ca7fc":()=>d(()=>import("./comparable-omparator.html.397dc2ff.js"),[]).then(({data:e})=>e),"v-3684a67a":()=>d(()=>import("./deep-copy.html.b367f078.js"),[]).then(({data:e})=>e),"v-36e67681":()=>d(()=>import("./enum.html.21e74b14.js"),[]).then(({data:e})=>e),"v-9048faf2":()=>d(()=>import("./equals-hashcode.html.cd3210fa.js"),[]).then(({data:e})=>e),"v-ce39a3f6":()=>d(()=>import("./fanshe.html.13ada7e7.js"),[]).then(({data:e})=>e),"v-06b06a8e":()=>d(()=>import("./generic.html.7ec41e80.js"),[]).then(({data:e})=>e),"v-7c307347":()=>d(()=>import("./hashcode.html.24290486.js"),[]).then(({data:e})=>e),"v-d4ba57a4":()=>d(()=>import("./immutable.html.fdd47709.js"),[]).then(({data:e})=>e),"v-35db81bc":()=>d(()=>import("./instanceof-jvm.html.845ed78f.js"),[]).then(({data:e})=>e),"v-3516d6cc":()=>d(()=>import("./int-cache.html.0d30900e.js"),[]).then(({data:e})=>e),"v-da276006":()=>d(()=>import("./java-naming.html.de2604a0.js"),[]).then(({data:e})=>e),"v-692842f0":()=>d(()=>import("./java-unicode.html.9e4e93b1.js"),[]).then(({data:e})=>e),"v-e7ec28a8":()=>d(()=>import("./jdk-while-for-wuxian-xunhuan.html.e352d875.js"),[]).then(({data:e})=>e),"v-8d888ea8":()=>d(()=>import("./jdk9-char-byte-string.html.e81be44e.js"),[]).then(({data:e})=>e),"v-7b47ec96":()=>d(()=>import("./override-overload.html.f7d74176.js"),[]).then(({data:e})=>e),"v-a5cf66ce":()=>d(()=>import("./pass-by-value.html.e26c3cdc.js"),[]).then(({data:e})=>e),"v-3b06244a":()=>d(()=>import("./true-generic.html.ce09d792.js"),[]).then(({data:e})=>e),"v-7553bbe0":()=>d(()=>import("./varables.html.6a80fc0e.js"),[]).then(({data:e})=>e),"v-662a92aa":()=>d(()=>import("./beijing.html.78adaacf.js"),[]).then(({data:e})=>e),"v-38cd1384":()=>d(()=>import("./chengdu.html.c9264a1d.js"),[]).then(({data:e})=>e),"v-3eb2e9b0":()=>d(()=>import("./guangzhou.html.58700f92.js"),[]).then(({data:e})=>e),"v-697611a4":()=>d(()=>import("./hangzhou.html.52f2ce43.js"),[]).then(({data:e})=>e),"v-743d326c":()=>d(()=>import("./jinan.html.d4c22f59.js"),[]).then(({data:e})=>e),"v-345abdb5":()=>d(()=>import("./nanjing.html.44d630fa.js"),[]).then(({data:e})=>e),"v-e7504db2":()=>d(()=>import("./qingdao.html.826f4cb2.js"),[]).then(({data:e})=>e),"v-33fa70f5":()=>d(()=>import("./shenzhen.html.98e7f6e9.js"),[]).then(({data:e})=>e),"v-3819c1f4":()=>d(()=>import("./suzhou.html.428c3730.js"),[]).then(({data:e})=>e),"v-55b57168":()=>d(()=>import("./xian.html.badb133a.js"),[]).then(({data:e})=>e),"v-b3887a38":()=>d(()=>import("./zhengzhou.html.c309c263.js"),[]).then(({data:e})=>e),"v-48818f7a":()=>d(()=>import("./arraylist.html.0dcdca73.js"),[]).then(({data:e})=>e),"v-85734e74":()=>d(()=>import("./fail-fast.html.4b8a884f.js"),[]).then(({data:e})=>e),"v-a612d212":()=>d(()=>import("./gailan.html.87d77185.js"),[]).then(({data:e})=>e),"v-69fbae62":()=>d(()=>import("./hashmap-interview.html.307a5634.js"),[]).then(({data:e})=>e),"v-60be3e7a":()=>d(()=>import("./hashmap.html.f8e12ca4.js"),[]).then(({data:e})=>e),"v-754b8740":()=>d(()=>import("./iterator-iterable.html.967b5cf7.js"),[]).then(({data:e})=>e),"v-2136d56c":()=>d(()=>import("./linkedlist.html.8ede144e.js"),[]).then(({data:e})=>e),"v-65f6d97a":()=>d(()=>import("./list-war-2.html.b8fa44fb.js"),[]).then(({data:e})=>e),"v-f7fcdb1e":()=>d(()=>import("./arrays.html.7944f961.js"),[]).then(({data:e})=>e),"v-17562512":()=>d(()=>import("./collections.html.2e6479a3.js"),[]).then(({data:e})=>e),"v-7d0053a9":()=>d(()=>import("./guava.html.e73aaedd.js"),[]).then(({data:e})=>e),"v-2d07de66":()=>d(()=>import("./hutool.html.06e72427.js"),[]).then(({data:e})=>e),"v-a7472ae2":()=>d(()=>import("./os.html.5e6a959a.js"),[]).then(({data:e})=>e),"v-366b86bc":()=>d(()=>import("./wangluo.html.b41cb57f.js"),[]).then(({data:e})=>e),"v-6ef55906":()=>d(()=>import("./bat-shuati.html.01dded07.js"),[]).then(({data:e})=>e),"v-bb191cda":()=>d(()=>import("./history.html.6df608e4.js"),[]).then(({data:e})=>e),"v-440da5e9":()=>d(()=>import("./java.html.8cfce3ac.js"),[]).then(({data:e})=>e),"v-03f42fc2":()=>d(()=>import("./jianli.html.28361c8b.js"),[]).then(({data:e})=>e),"v-1f0822f4":()=>d(()=>import("./learn-jianyi.html.1b72d4e2.js"),[]).then(({data:e})=>e),"v-43185964":()=>d(()=>import("./nicearticle.html.b56e678a.js"),[]).then(({data:e})=>e),"v-e1dd7216":()=>d(()=>import("./pdf.html.a28195f1.js"),[]).then(({data:e})=>e),"v-5ee46134":()=>d(()=>import("./progit.html.df477a55.js"),[]).then(({data:e})=>e),"v-ed798b2e":()=>d(()=>import("./yuanyifeng-c-language.html.dbcc3d40.js"),[]).then(({data:e})=>e),"v-39324891":()=>d(()=>import("./rumen.html.9cc17590.js"),[]).then(({data:e})=>e),"v-7f4a0796":()=>d(()=>import("./gailan.html.fee068f9.js"),[]).then(({data:e})=>e),"v-27e42762":()=>d(()=>import("./npe.html.a94a2b73.js"),[]).then(({data:e})=>e),"v-ad4adf1c":()=>d(()=>import("./shijian.html.0924a1ec.js"),[]).then(({data:e})=>e),"v-053b70f2":()=>d(()=>import("./try-with-resouces.html.8dcef913.js"),[]).then(({data:e})=>e),"v-24bf8472":()=>d(()=>import("./git-qiyuan.html.054515ab.js"),[]).then(({data:e})=>e),"v-c4de51c4":()=>d(()=>import("./progit.html.a119468c.js"),[]).then(({data:e})=>e),"v-7b2a5ff2":()=>d(()=>import("./Chocolatey-Homebrew.html.ad256880.js"),[]).then(({data:e})=>e),"v-3d562a9a":()=>d(()=>import("./DBeaver.html.75fbe8f6.js"),[]).then(({data:e})=>e),"v-c6c0b0d0":()=>d(()=>import("./chiner.html.13c55607.js"),[]).then(({data:e})=>e),"v-2d6ff326":()=>d(()=>import("./choco.html.f8923e81.js"),[]).then(({data:e})=>e),"v-54937d2a":()=>d(()=>import("./fastjson.html.f97ae6fd.js"),[]).then(({data:e})=>e),"v-fe63cc9c":()=>d(()=>import("./forest.html.79a7cfed.js"),[]).then(({data:e})=>e),"v-00cd7f78":()=>d(()=>import("./gson.html.e79a454d.js"),[]).then(({data:e})=>e),"v-1e073750":()=>d(()=>import("./jackson.html.ded110ad.js"),[]).then(({data:e})=>e),"v-065f99d6":()=>d(()=>import("./junit.html.2436284c.js"),[]).then(({data:e})=>e),"v-b8f624f0":()=>d(()=>import("./knife4j.html.a18b3a85.js"),[]).then(({data:e})=>e),"v-e034f2ee":()=>d(()=>import("./log4j.html.14af993a.js"),[]).then(({data:e})=>e),"v-70680037":()=>d(()=>import("./log4j2.html.9b5a6f13.js"),[]).then(({data:e})=>e),"v-1eebad78":()=>d(()=>import("./logback.html.a9628274.js"),[]).then(({data:e})=>e),"v-fdffa3a8":()=>d(()=>import("./others.html.ed8fcf05.js"),[]).then(({data:e})=>e),"v-19392480":()=>d(()=>import("./slf4j.html.2fd3dca6.js"),[]).then(({data:e})=>e),"v-abf717d2":()=>d(()=>import("./tabby.html.8b43d084.js"),[]).then(({data:e})=>e),"v-cfb128b2":()=>d(()=>import("./warp.html.4380b228.js"),[]).then(({data:e})=>e),"v-2f1b6319":()=>d(()=>import("./4-debug-skill.html.9bd076fc.js"),[]).then(({data:e})=>e),"v-62663e4e":()=>d(()=>import("./BIONIOAIO.html.ea89d11f.js"),[]).then(({data:e})=>e),"v-3bf159f4":()=>d(()=>import("./shangtou.html.dd79a90f.js"),[]).then(({data:e})=>e),"v-0a083d40":()=>d(()=>import("./Lambda.html.997b367a.js"),[]).then(({data:e})=>e),"v-aa8f9c32":()=>d(()=>import("./optional.html.23c0a140.js"),[]).then(({data:e})=>e),"v-6d140547":()=>d(()=>import("./stream.html.214aab27.js"),[]).then(({data:e})=>e),"v-0d07ca65":()=>d(()=>import("./asm.html.0e0abd8b.js"),[]).then(({data:e})=>e),"v-3748383d":()=>d(()=>import("./bytecode.html.ba8f00b6.js"),[]).then(({data:e})=>e),"v-efd40586":()=>d(()=>import("./class-file-jiegou.html.3dff0326.js"),[]).then(({data:e})=>e),"v-b9ac0ed2":()=>d(()=>import("./class-load.html.6a788fca.js"),[]).then(({data:e})=>e),"v-16000f89":()=>d(()=>import("./compile-jdk.html.531caac0.js"),[]).then(({data:e})=>e),"v-2781e43c":()=>d(()=>import("./cpu-percent-100.html.f6bd745b.js"),[]).then(({data:e})=>e),"v-c9f5a514":()=>d(()=>import("./gc.html.cec6db87.js"),[]).then(({data:e})=>e),"v-e8fbf108":()=>d(()=>import("./how-jvm-run-zijiema-zhiling.html.400c699c.js"),[]).then(({data:e})=>e),"v-63d827b2":()=>d(()=>import("./how-run-java-code.html.1867de4d.js"),[]).then(({data:e})=>e),"v-1b3dc969":()=>d(()=>import("./hsdb.html.e06d55d6.js"),[]).then(({data:e})=>e),"v-a2340bea":()=>d(()=>import("./jit.html.a14bdfce.js"),[]).then(({data:e})=>e),"v-07af3814":()=>d(()=>import("./meituan-9-gc.html.f5a5b89a.js"),[]).then(({data:e})=>e),"v-e8878c14":()=>d(()=>import("./neicun-jiegou.html.f0fca3bb.js"),[]).then(({data:e})=>e),"v-30815cda":()=>d(()=>import("./oom.html.23228526.js"),[]).then(({data:e})=>e),"v-2254b233":()=>d(()=>import("./problem-tools.html.fab08888.js"),[]).then(({data:e})=>e),"v-4c99a464":()=>d(()=>import("./tujie-gc.html.ca2dffab.js"),[]).then(({data:e})=>e),"v-57bf2d3c":()=>d(()=>import("./what-happen-when-javac.html.ab4282c1.js"),[]).then(({data:e})=>e),"v-214d568e":()=>d(()=>import("./what-is-jvm.html.5131a239.js"),[]).then(({data:e})=>e),"v-5adc261b":()=>d(()=>import("./whereis-the-object.html.c695df3e.js"),[]).then(({data:e})=>e),"v-b827481e":()=>d(()=>import("./zijiema-zhiling.html.34c655bc.js"),[]).then(({data:e})=>e),"v-32ecf2e8":()=>d(()=>import("./zongjie.html.c9e5e3c3.js"),[]).then(({data:e})=>e),"v-2ead7d38":()=>d(()=>import("./auto-generator.html.7efe2473.js"),[]).then(({data:e})=>e),"v-070fbd0c":()=>d(()=>import("./index.html.fd879420.js"),[]).then(({data:e})=>e),"v-97a45628":()=>d(()=>import("./yuneban-wangyiyunyinyue.html.275a589e.js"),[]).then(({data:e})=>e),"v-000948f2":()=>d(()=>import("./waibao-1geyue.html.fbddc89c.js"),[]).then(({data:e})=>e),"v-66366bd2":()=>d(()=>import("./yanjiusuo-20wan.html.76b660c5.js"),[]).then(({data:e})=>e),"v-6002cbaa":()=>d(()=>import("./maven.html.abe414c5.js"),[]).then(({data:e})=>e),"v-6ec52668":()=>d(()=>import("./redis12question.html.58f0e7e0.js"),[]).then(({data:e})=>e),"v-fdcf9bf0":()=>d(()=>import("./shanganaliyun.html.04eee07a.js"),[]).then(({data:e})=>e),"v-fcf91dba":()=>d(()=>import("./api-wangguan.html.c2b18262.js"),[]).then(({data:e})=>e),"v-23fb287c":()=>d(()=>import("./rumen.html.28382740.js"),[]).then(({data:e})=>e),"v-20db0618":()=>d(()=>import("./100-budiushi.html.c3040dbf.js"),[]).then(({data:e})=>e),"v-ea0a417a":()=>d(()=>import("./rabbitmq-rumen.html.1f0066c6.js"),[]).then(({data:e})=>e),"v-43bd2008":()=>d(()=>import("./deletedb-binlog-weiguanjishu.html.605b28a5.js"),[]).then(({data:e})=>e),"v-1f354ebe":()=>d(()=>import("./redis-shuju-yizhixing.html.0d2d7824.js"),[]).then(({data:e})=>e),"v-c64f1dca":()=>d(()=>import("./40-interview.html.2cb0fe6c.js"),[]).then(({data:e})=>e),"v-189ab80d":()=>d(()=>import("./nginx.html.baa53af7.js"),[]).then(({data:e})=>e),"v-8be2b210":()=>d(()=>import("./BOKEYUANruhegaoxiaodixuexijishu.html.54dd2a4d.js"),[]).then(({data:e})=>e),"v-b5321080":()=>d(()=>import("./ZHIHUjavaxuexidaoshemechengduokeyizhaodiyifengongzuo.html.e4fead09.js"),[]).then(({data:e})=>e),"v-7625a17a":()=>d(()=>import("./bokeyuan-jianxijavazhongdifangwenquanxiankongzhi.html.bc8753e4.js"),[]).then(({data:e})=>e),"v-b39bf9b6":()=>d(()=>import("./bokeyuan-ruhegaoxiaodixuexijishu.html.e9d4ca36.js"),[]).then(({data:e})=>e),"v-bb8a78fa":()=>d(()=>import("./haibukuaiyongmybatisplusshoubashoujiaoni.html.4769ffdb.js"),[]).then(({data:e})=>e),"v-3404ee90":()=>d(()=>import("./javaxuexidaoshemechengduokeyizhaodiyifengongzuo.html.3289a228.js"),[]).then(({data:e})=>e),"v-42ab3f07":()=>d(()=>import("./jiagoushizenyanghuizhijitongjiagoulantu.html.980a677a.js"),[]).then(({data:e})=>e),"v-ba14f030":()=>d(()=>import("./jielehenduosihuodiganchu.html.0ffa8f43.js"),[]).then(({data:e})=>e),"v-8ef10754":()=>d(()=>import("./jishuzongjianbeikaichuliao.html.1b7e52c1.js"),[]).then(({data:e})=>e),"v-b04aa828":()=>d(()=>import("./nginx-setting.html.68b3250b.js"),[]).then(({data:e})=>e),"v-5ff455de":()=>d(()=>import("./weixin-bagwpdf.html.a32b4b3a.js"),[]).then(({data:e})=>e),"v-dfeef5c6":()=>d(()=>import("./weixin-chengxwjdwzhqcgxm.html.18dc866d.js"),[]).then(({data:e})=>e),"v-1a392032":()=>d(()=>import("./weixin-githubxbkdjavajccjyh.html.be4183ae.js"),[]).then(({data:e})=>e),"v-d0172620":()=>d(()=>import("./weixin-liaoliaoxianliu.html.624e17ae.js"),[]).then(({data:e})=>e),"v-39c49d7e":()=>d(()=>import("./weixin-likbj.html.4138e613.js"),[]).then(({data:e})=>e),"v-0397d0de":()=>d(()=>import("./weixin-mozdsdzfjavableetcodetxxk.html.10059c85.js"),[]).then(({data:e})=>e),"v-692b01ca":()=>d(()=>import("./weixin-piaolwzjztqdtskwlzfpdf.html.ef3235a6.js"),[]).then(({data:e})=>e),"v-16ac8eee":()=>d(()=>import("./weixin-quoppomspwml.html.27944449.js"),[]).then(({data:e})=>e),"v-01db1eaa":()=>d(()=>import("./weixin-shejmsnb.html.5a6a099f.js"),[]).then(({data:e})=>e),"v-16f50d13":()=>d(()=>import("./weixin-shenrjcjavabfbchwjdhl.html.ca182283.js"),[]).then(({data:e})=>e),"v-51ad9d8d":()=>d(()=>import("./weixin-xinllgjszjszzpojozsyjbsjlxyhjfyll.html.8f640dc9.js"),[]).then(({data:e})=>e),"v-84fc24ae":()=>d(()=>import("./weixin-zaixsfdnavicatzkkydsjkglgjjmgxk.html.ad8c7107.js"),[]).then(({data:e})=>e),"v-273df44a":()=>d(()=>import("./weixin-zhongxcwbztashjjavahdmj.html.844aa3a1.js"),[]).then(({data:e})=>e),"v-0bc0f1a3":()=>d(()=>import("./weixin-zuixinbujiabandigongsimingdan.html.bf87a7d5.js"),[]).then(({data:e})=>e),"v-9570d5e4":()=>d(()=>import("./zhihu-jisjkyynxzdtjdyj.html.8094217b.js"),[]).then(({data:e})=>e),"v-8e1aac5c":()=>d(()=>import("./zhihu-weismyrsyxkjgscxyzhdjyxz.html.98987909.js"),[]).then(({data:e})=>e),"v-59da4d60":()=>d(()=>import("./zhihu-younxzdjsjzyxsjrdgq.html.e644f706.js"),[]).then(({data:e})=>e),"v-1ef77dfe":()=>d(()=>import("./abstract.html.3094fdb5.js"),[]).then(({data:e})=>e),"v-42f4881f":()=>d(()=>import("./code-init.html.70ef628a.js"),[]).then(({data:e})=>e),"v-44efe198":()=>d(()=>import("./construct.html.5ae3e6eb.js"),[]).then(({data:e})=>e),"v-0cdc8b4e":()=>d(()=>import("./final.html.c83d9074.js"),[]).then(({data:e})=>e),"v-205a2eee":()=>d(()=>import("./inner-class.html.f2dd62ed.js"),[]).then(({data:e})=>e),"v-1b40dbb7":()=>d(()=>import("./instanceof.html.d3be3510.js"),[]).then(({data:e})=>e),"v-cf613514":()=>d(()=>import("./interface.html.7833e904.js"),[]).then(({data:e})=>e),"v-7bb58bbc":()=>d(()=>import("./method.html.4d951864.js"),[]).then(({data:e})=>e),"v-fbea188e":()=>d(()=>import("./object-class.html.85420110.js"),[]).then(({data:e})=>e),"v-2e2eacb5":()=>d(()=>import("./static.html.1a009c06.js"),[]).then(({data:e})=>e),"v-7cc17552":()=>d(()=>import("./this-super.html.65fa5da3.js"),[]).then(({data:e})=>e),"v-cee31e70":()=>d(()=>import("./var.html.7a0cfd0f.js"),[]).then(({data:e})=>e),"v-a931ed42":()=>d(()=>import("./hello-world.html.d0d5adf0.js"),[]).then(({data:e})=>e),"v-472dda20":()=>d(()=>import("./what-is-java.html.b724e432.js"),[]).then(({data:e})=>e),"v-264d9d3b":()=>d(()=>import("./redis-springboot.html.44044d02.js"),[]).then(({data:e})=>e),"v-520f0e13":()=>d(()=>import("./rumen.html.e13dbda5.js"),[]).then(({data:e})=>e),"v-f63181d6":()=>d(()=>import("./xuebeng-chuantou-jichuan.html.26ef04a3.js"),[]).then(({data:e})=>e),"v-3b896528":()=>d(()=>import("./image-yasuo.html.8853b749.js"),[]).then(({data:e})=>e),"v-5d00799b":()=>d(()=>import("./log4j2.html.b3fd06a7.js"),[]).then(({data:e})=>e),"v-0a391fc2":()=>d(()=>import("./computer-base.html.f469b424.js"),[]).then(({data:e})=>e),"v-fdb1bc82":()=>d(()=>import("./Filter-Interceptor-Listener.html.3a5897a3.js"),[]).then(({data:e})=>e),"v-174081f7":()=>d(()=>import("./aop-log.html.390b071a.js"),[]).then(({data:e})=>e),"v-534b7235":()=>d(()=>import("./cors.html.b8f51585.js"),[]).then(({data:e})=>e),"v-5b4d8cf6":()=>d(()=>import("./initializr.html.47ddf572.js"),[]).then(({data:e})=>e),"v-7ff17e1a":()=>d(()=>import("./ioc.html.1c4cca00.js"),[]).then(({data:e})=>e),"v-5964f7d5":()=>d(()=>import("./jpa.html.cb4e1f80.js"),[]).then(({data:e})=>e),"v-27c6ab2e":()=>d(()=>import("./jwt.html.b4f208bb.js"),[]).then(({data:e})=>e),"v-72c3c3e8":()=>d(()=>import("./linux-codingmore-run.html.6ac5d933.js"),[]).then(({data:e})=>e),"v-c65767f6":()=>d(()=>import("./logback.html.28ab1df5.js"),[]).then(({data:e})=>e),"v-56fd99ea":()=>d(()=>import("./macos-codingmore-run.html.f9eb5e90.js"),[]).then(({data:e})=>e),"v-765c4bce":()=>d(()=>import("./mysql-druid.html.1c47eb57.js"),[]).then(({data:e})=>e),"v-1e34c521":()=>d(()=>import("./oss.html.8b1ce1ec.js"),[]).then(({data:e})=>e),"v-a4a685a0":()=>d(()=>import("./springtask.html.04deb6a0.js"),[]).then(({data:e})=>e),"v-eb0f47f4":()=>d(()=>import("./swagger.html.1142f08f.js"),[]).then(({data:e})=>e),"v-4d7a00b5":()=>d(()=>import("./thymeleaf.html.b2ef505e.js"),[]).then(({data:e})=>e),"v-6f0be684":()=>d(()=>import("./tomcat.html.73ec3645.js"),[]).then(({data:e})=>e),"v-33b6789c":()=>d(()=>import("./transaction.html.1d6a1548.js"),[]).then(({data:e})=>e),"v-5ca9fbdb":()=>d(()=>import("./windows-codingmore-run.html.6d49b8aa.js"),[]).then(({data:e})=>e),"v-8d804d8e":()=>d(()=>import("./constant-pool.html.c79f5c21.js"),[]).then(({data:e})=>e),"v-03911b96":()=>d(()=>import("./equals.html.2fb94b25.js"),[]).then(({data:e})=>e),"v-a45f0e08":()=>d(()=>import("./immutable.html.36fadfba.js"),[]).then(({data:e})=>e),"v-95e9527c":()=>d(()=>import("./intern.html.3d87fa6f.js"),[]).then(({data:e})=>e),"v-db441b2c":()=>d(()=>import("./join.html.bb336f49.js"),[]).then(({data:e})=>e),"v-f0ca9e38":()=>d(()=>import("./split.html.0ff2ce60.js"),[]).then(({data:e})=>e),"v-42ee1292":()=>d(()=>import("./buy-cloud-server.html.595deaa6.js"),[]).then(({data:e})=>e),"v-1267a82e":()=>d(()=>import("./buy-domain.html.1227af51.js"),[]).then(({data:e})=>e),"v-5590a9da":()=>d(()=>import("./https-domain.html.847eb117.js"),[]).then(({data:e})=>e),"v-6d7e6055":()=>d(()=>import("./install-baota-mianban.html.822010d2.js"),[]).then(({data:e})=>e),"v-830a668e":()=>d(()=>import("./record-domain.html.667d7982.js"),[]).then(({data:e})=>e),"v-5c219956":()=>d(()=>import("./tobebetterjavaer-wangzhan-shangxian.html.a80895d2.js"),[]).then(({data:e})=>e),"v-611e28c1":()=>d(()=>import("./tupian-zhuanlian.html.7ab13c07.js"),[]).then(({data:e})=>e),"v-49acdbe9":()=>d(()=>import("./BlockingQueue.html.9ccd9ba0.js"),[]).then(({data:e})=>e),"v-03b9fcee":()=>d(()=>import("./ConcurrentHashMap.html.e7f83c81.js"),[]).then(({data:e})=>e),"v-109bb8a4":()=>d(()=>import("./ConcurrentLinkedQueue.html.da4bfec1.js"),[]).then(({data:e})=>e),"v-396740a1":()=>d(()=>import("./CopyOnWriteArrayList.html.b8e564c2.js"),[]).then(({data:e})=>e),"v-f606f74c":()=>d(()=>import("./CountDownLatch.html.f036fab2.js"),[]).then(({data:e})=>e),"v-ccb364be":()=>d(()=>import("./LockSupport.html.c7d00cfa.js"),[]).then(({data:e})=>e),"v-4c7ec7a6":()=>d(()=>import("./ReentrantReadWriteLock.html.d1bd972f.js"),[]).then(({data:e})=>e),"v-17464182":()=>d(()=>import("./ScheduledThreadPoolExecutor.html.8d668046.js"),[]).then(({data:e})=>e),"v-00920464":()=>d(()=>import("./ThreadLocal.html.f9a6fed8.js"),[]).then(({data:e})=>e),"v-3d590e34":()=>d(()=>import("./ali-executors.html.988adc8e.js"),[]).then(({data:e})=>e),"v-1df9d2c2":()=>d(()=>import("./aqs.html.d6a8f5b4.js"),[]).then(({data:e})=>e),"v-f854807c":()=>d(()=>import("./atomic.html.93391f09.js"),[]).then(({data:e})=>e),"v-c14f0f20":()=>d(()=>import("./cas.html.4534d702.js"),[]).then(({data:e})=>e),"v-66a4042c":()=>d(()=>import("./condition.html.a41bdc76.js"),[]).then(({data:e})=>e),"v-6d64b820":()=>d(()=>import("./fork-join.html.f967d485.js"),[]).then(({data:e})=>e),"v-31e3344a":()=>d(()=>import("./jmm.html.7be72db5.js"),[]).then(({data:e})=>e),"v-46ec2dc2":()=>d(()=>import("./lock.html.5385ecc8.js"),[]).then(({data:e})=>e),"v-adf4a16e":()=>d(()=>import("./map.html.ae80f8e6.js"),[]).then(({data:e})=>e),"v-147d8971":()=>d(()=>import("./pool.html.1918e02b.js"),[]).then(({data:e})=>e),"v-06ad3e4d":()=>d(()=>import("./reentrantLock.html.002f84e4.js"),[]).then(({data:e})=>e),"v-80e01c30":()=>d(()=>import("./shengchanzhe-xiaofeizhe.html.0915b865.js"),[]).then(({data:e})=>e),"v-f96cf90e":()=>d(()=>import("./synchronized.html.6094d556.js"),[]).then(({data:e})=>e),"v-1e8914e1":()=>d(()=>import("./thread-bring-some-problem.html.c8ae3e7a.js"),[]).then(({data:e})=>e),"v-f8642b66":()=>d(()=>import("./thread-group-and-thread-priority.html.873709ce.js"),[]).then(({data:e})=>e),"v-9fc9a5a2":()=>d(()=>import("./thread-state-and-method.html.70b8e2e8.js"),[]).then(({data:e})=>e),"v-9ae84c1e":()=>d(()=>import("./volatile.html.26279f7f.js"),[]).then(({data:e})=>e),"v-06f71d0a":()=>d(()=>import("./wangzhe-thread.html.dda72253.js"),[]).then(({data:e})=>e),"v-6feb1e09":()=>d(()=>import("./why-need-thread.html.507a940d.js"),[]).then(({data:e})=>e),"v-6476d1b6":()=>d(()=>import("./aliyun-shuaiguo-gongchengshi.html.e4346151.js"),[]).then(({data:e})=>e),"v-da1bbc34":()=>d(()=>import("./chadiansanhuo.html.e9cc0b99.js"),[]).then(({data:e})=>e),"v-78df38f4":()=>d(()=>import("./chengxuyuannv-chonghui-java.html.b9de6702.js"),[]).then(({data:e})=>e),"v-1749ea82":()=>d(()=>import("./daxue-nuli-jisuanji.html.2b1074e1.js"),[]).then(({data:e})=>e),"v-eb9ba2e8":()=>d(()=>import("./fumutuanju.html.577491d1.js"),[]).then(({data:e})=>e),"v-4d6508bf":()=>d(()=>import("./electron-information-engineering.html.16bd5754.js"),[]).then(({data:e})=>e),"v-ea4c66a8":()=>d(()=>import("./read-csapp.html.768012b7.js"),[]).then(({data:e})=>e),"v-358ab252":()=>d(()=>import("./algorithm.html.14390f00.js"),[]).then(({data:e})=>e),"v-96d47244":()=>d(()=>import("./c.html.5983fe89.js"),[]).then(({data:e})=>e),"v-64f5ed84":()=>d(()=>import("./ccc.html.51a24970.js"),[]).then(({data:e})=>e),"v-1d705569":()=>d(()=>import("./go.html.528d4a75.js"),[]).then(({data:e})=>e),"v-80075a2c":()=>d(()=>import("./lanqiaobei.html.17699093.js"),[]).then(({data:e})=>e),"v-6914dc26":()=>d(()=>import("./os.html.34768944.js"),[]).then(({data:e})=>e),"v-3ebce416":()=>d(()=>import("./python.html.a467fb74.js"),[]).then(({data:e})=>e),"v-6713c6ee":()=>d(()=>import("./qianduan.html.61a4f111.js"),[]).then(({data:e})=>e),"v-6789c688":()=>d(()=>import("./index.html.698aa818.js"),[]).then(({data:e})=>e),"v-459170da":()=>d(()=>import("./java-mianshi-zhinan.html.f1a349c4.js"),[]).then(({data:e})=>e),"v-00f81024":()=>d(()=>import("./index.html.9ee0e417.js"),[]).then(({data:e})=>e),"v-f6116100":()=>d(()=>import("./jibenjieshao.html.b8a08842.js"),[]).then(({data:e})=>e),"v-089862ea":()=>d(()=>import("./mysql.html.99fca397.js"),[]).then(({data:e})=>e),"v-617d67b6":()=>d(()=>import("./collection.html.42c40509.js"),[]).then(({data:e})=>e),"v-e5434cc0":()=>d(()=>import("./javase.html.811355dc.js"),[]).then(({data:e})=>e),"v-39f8d868":()=>d(()=>import("./javathread.html.1bcda474.js"),[]).then(({data:e})=>e),"v-35406b06":()=>d(()=>import("./jvm.html.dd68f45e.js"),[]).then(({data:e})=>e),"v-7990f3ea":()=>d(()=>import("./mybatis.html.7c33d756.js"),[]).then(({data:e})=>e),"v-7897c568":()=>d(()=>import("./nixi.html.c022f9fe.js"),[]).then(({data:e})=>e),"v-6f6524a3":()=>d(()=>import("./redis.html.b039ba47.js"),[]).then(({data:e})=>e),"v-02987727":()=>d(()=>import("./spring.html.75b19ea2.js"),[]).then(({data:e})=>e),"v-c16116c6":()=>d(()=>import("./jvm.html.49208e4a.js"),[]).then(({data:e})=>e),"v-39e4032a":()=>d(()=>import("./thread.html.34ab4613.js"),[]).then(({data:e})=>e),"v-6775b565":()=>d(()=>import("./yitiaolong.html.0ffd862a.js"),[]).then(({data:e})=>e),"v-3706649a":()=>d(()=>import("./404.html.e75684b7.js"),[]).then(({data:e})=>e)};function Ni(e,t){const n=Object.create(null),r=e.split(",");for(let o=0;o!!n[o.toLowerCase()]:o=>!!n[o]}const _f="itemscope,allowfullscreen,formnovalidate,ismap,nomodule,novalidate,readonly",gf=Ni(_f);function rs(e){return!!e||e===""}function Hi(e){if(ae(e)){const t={};for(let n=0;n{if(n){const r=n.split(yf);r.length>1&&(t[r[0].trim()]=r[1].trim())}}),t}function Bi(e){let t="";if(De(e))t=e;else if(ae(e))for(let n=0;n{},Of=()=>!1,wf=/^on[^a-z]/,Lr=e=>wf.test(e),Fi=e=>e.startsWith("onUpdate:"),He=Object.assign,qi=(e,t)=>{const n=e.indexOf(t);n>-1&&e.splice(n,1)},Tf=Object.prototype.hasOwnProperty,_e=(e,t)=>Tf.call(e,t),ae=Array.isArray,Zn=e=>yo(e)==="[object Map]",xf=e=>yo(e)==="[object Set]",de=e=>typeof e=="function",De=e=>typeof e=="string",Ji=e=>typeof e=="symbol",Je=e=>e!==null&&typeof e=="object",os=e=>Je(e)&&de(e.then)&&de(e.catch),Pf=Object.prototype.toString,yo=e=>Pf.call(e),If=e=>yo(e).slice(8,-1),Lf=e=>yo(e)==="[object Object]",Ui=e=>De(e)&&e!=="NaN"&&e[0]!=="-"&&""+parseInt(e,10)===e,Xn=Ni(",key,ref,ref_for,ref_key,onVnodeBeforeMount,onVnodeMounted,onVnodeBeforeUpdate,onVnodeUpdated,onVnodeBeforeUnmount,onVnodeUnmounted"),Eo=e=>{const t=Object.create(null);return n=>t[n]||(t[n]=e(n))},Af=/-(\w)/g,lt=Eo(e=>e.replace(Af,(t,n)=>n?n.toUpperCase():"")),Df=/\B([A-Z])/g,Sn=Eo(e=>e.replace(Df,"-$1").toLowerCase()),Ar=Eo(e=>e.charAt(0).toUpperCase()+e.slice(1)),Co=Eo(e=>e?`on${Ar(e)}`:""),fr=(e,t)=>!Object.is(e,t),Vo=(e,t)=>{for(let n=0;n{Object.defineProperty(e,t,{configurable:!0,enumerable:!1,value:n})},is=e=>{const t=parseFloat(e);return isNaN(t)?e:t};let $a;const jf=()=>$a||($a=typeof globalThis!="undefined"?globalThis:typeof self!="undefined"?self:typeof window!="undefined"?window:typeof global!="undefined"?global:{});let Xe;class kf{constructor(t=!1){this.active=!0,this.effects=[],this.cleanups=[],!t&&Xe&&(this.parent=Xe,this.index=(Xe.scopes||(Xe.scopes=[])).push(this)-1)}run(t){if(this.active){const n=Xe;try{return Xe=this,t()}finally{Xe=n}}}on(){Xe=this}off(){Xe=this.parent}stop(t){if(this.active){let n,r;for(n=0,r=this.effects.length;n{const t=new Set(e);return t.w=0,t.n=0,t},as=e=>(e.w&Jt)>0,ls=e=>(e.n&Jt)>0,Vf=({deps:e})=>{if(e.length)for(let t=0;t{const{deps:t}=e;if(t.length){let n=0;for(let r=0;r{(u==="length"||u>=r)&&l.push(c)});else switch(n!==void 0&&l.push(a.get(n)),t){case"add":ae(e)?Ui(n)&&l.push(a.get("length")):(l.push(a.get(an)),Zn(e)&&l.push(a.get(li)));break;case"delete":ae(e)||(l.push(a.get(an)),Zn(e)&&l.push(a.get(li)));break;case"set":Zn(e)&&l.push(a.get(an));break}if(l.length===1)l[0]&&ci(l[0]);else{const c=[];for(const u of l)u&&c.push(...u);ci(Wi(c))}}function ci(e,t){const n=ae(e)?e:[...e];for(const r of n)r.computed&&Ha(r);for(const r of n)r.computed||Ha(r)}function Ha(e,t){(e!==ut||e.allowRecurse)&&(e.scheduler?e.scheduler():e.run())}const zf=Ni("__proto__,__v_isRef,__isVue"),us=new Set(Object.getOwnPropertyNames(Symbol).filter(e=>e!=="arguments"&&e!=="caller").map(e=>Symbol[e]).filter(Ji)),$f=Yi(),Nf=Yi(!1,!0),Hf=Yi(!0),Ba=Bf();function Bf(){const e={};return["includes","indexOf","lastIndexOf"].forEach(t=>{e[t]=function(...n){const r=Ee(this);for(let i=0,a=this.length;i{e[t]=function(...n){Cn();const r=Ee(this)[t].apply(this,n);return Vn(),r}}),e}function Yi(e=!1,t=!1){return function(r,o,i){if(o==="__v_isReactive")return!e;if(o==="__v_isReadonly")return e;if(o==="__v_isShallow")return t;if(o==="__v_raw"&&i===(e?t?om:vs:t?hs:ms).get(r))return r;const a=ae(r);if(!e&&a&&_e(Ba,o))return Reflect.get(Ba,o,i);const l=Reflect.get(r,o,i);return(Ji(o)?us.has(o):zf(o))||(e||rt(r,"get",o),t)?l:qe(l)?a&&Ui(o)?l:l.value:Je(l)?e?Zi(l):sn(l):l}}const Ff=ds(),qf=ds(!0);function ds(e=!1){return function(n,r,o,i){let a=n[r];if(mr(a)&&qe(a)&&!qe(o))return!1;if(!e&&!mr(o)&&(si(o)||(o=Ee(o),a=Ee(a)),!ae(n)&&qe(a)&&!qe(o)))return a.value=o,!0;const l=ae(n)&&Ui(r)?Number(r)e,Oo=e=>Reflect.getPrototypeOf(e);function Rr(e,t,n=!1,r=!1){e=e.__v_raw;const o=Ee(e),i=Ee(t);n||(t!==i&&rt(o,"get",t),rt(o,"get",i));const{has:a}=Oo(o),l=r?Gi:n?ea:hr;if(a.call(o,t))return l(e.get(t));if(a.call(o,i))return l(e.get(i));e!==o&&e.get(t)}function Sr(e,t=!1){const n=this.__v_raw,r=Ee(n),o=Ee(e);return t||(e!==o&&rt(r,"has",e),rt(r,"has",o)),e===o?n.has(e):n.has(e)||n.has(o)}function Cr(e,t=!1){return e=e.__v_raw,!t&&rt(Ee(e),"iterate",an),Reflect.get(e,"size",e)}function Fa(e){e=Ee(e);const t=Ee(this);return Oo(t).has.call(t,e)||(t.add(e),At(t,"add",e,e)),this}function qa(e,t){t=Ee(t);const n=Ee(this),{has:r,get:o}=Oo(n);let i=r.call(n,e);i||(e=Ee(e),i=r.call(n,e));const a=o.call(n,e);return n.set(e,t),i?fr(t,a)&&At(n,"set",e,t):At(n,"add",e,t),this}function Ja(e){const t=Ee(this),{has:n,get:r}=Oo(t);let o=n.call(t,e);o||(e=Ee(e),o=n.call(t,e)),r&&r.call(t,e);const i=t.delete(e);return o&&At(t,"delete",e,void 0),i}function Ua(){const e=Ee(this),t=e.size!==0,n=e.clear();return t&&At(e,"clear",void 0,void 0),n}function Vr(e,t){return function(r,o){const i=this,a=i.__v_raw,l=Ee(a),c=t?Gi:e?ea:hr;return!e&&rt(l,"iterate",an),a.forEach((u,s)=>r.call(o,c(u),c(s),i))}}function Mr(e,t,n){return function(...r){const o=this.__v_raw,i=Ee(o),a=Zn(i),l=e==="entries"||e===Symbol.iterator&&a,c=e==="keys"&&a,u=o[e](...r),s=n?Gi:t?ea:hr;return!t&&rt(i,"iterate",c?li:an),{next(){const{value:f,done:m}=u.next();return m?{value:f,done:m}:{value:l?[s(f[0]),s(f[1])]:s(f),done:m}},[Symbol.iterator](){return this}}}}function St(e){return function(...t){return e==="delete"?!1:this}}function Gf(){const e={get(i){return Rr(this,i)},get size(){return Cr(this)},has:Sr,add:Fa,set:qa,delete:Ja,clear:Ua,forEach:Vr(!1,!1)},t={get(i){return Rr(this,i,!1,!0)},get size(){return Cr(this)},has:Sr,add:Fa,set:qa,delete:Ja,clear:Ua,forEach:Vr(!1,!0)},n={get(i){return Rr(this,i,!0)},get size(){return Cr(this,!0)},has(i){return Sr.call(this,i,!0)},add:St("add"),set:St("set"),delete:St("delete"),clear:St("clear"),forEach:Vr(!0,!1)},r={get(i){return Rr(this,i,!0,!0)},get size(){return Cr(this,!0)},has(i){return Sr.call(this,i,!0)},add:St("add"),set:St("set"),delete:St("delete"),clear:St("clear"),forEach:Vr(!0,!0)};return["keys","values","entries",Symbol.iterator].forEach(i=>{e[i]=Mr(i,!1,!1),n[i]=Mr(i,!0,!1),t[i]=Mr(i,!1,!0),r[i]=Mr(i,!0,!0)}),[e,n,t,r]}const[Qf,Zf,Xf,em]=Gf();function Qi(e,t){const n=t?e?em:Xf:e?Zf:Qf;return(r,o,i)=>o==="__v_isReactive"?!e:o==="__v_isReadonly"?e:o==="__v_raw"?r:Reflect.get(_e(n,o)&&o in r?n:r,o,i)}const tm={get:Qi(!1,!1)},nm={get:Qi(!1,!0)},rm={get:Qi(!0,!1)},ms=new WeakMap,hs=new WeakMap,vs=new WeakMap,om=new WeakMap;function im(e){switch(e){case"Object":case"Array":return 1;case"Map":case"Set":case"WeakMap":case"WeakSet":return 2;default:return 0}}function am(e){return e.__v_skip||!Object.isExtensible(e)?0:im(If(e))}function sn(e){return mr(e)?e:Xi(e,!1,fs,tm,ms)}function lm(e){return Xi(e,!1,Yf,nm,hs)}function Zi(e){return Xi(e,!0,Kf,rm,vs)}function Xi(e,t,n,r,o){if(!Je(e)||e.__v_raw&&!(t&&e.__v_isReactive))return e;const i=o.get(e);if(i)return i;const a=am(e);if(a===0)return e;const l=new Proxy(e,a===2?r:n);return o.set(e,l),l}function Pn(e){return mr(e)?Pn(e.__v_raw):!!(e&&e.__v_isReactive)}function mr(e){return!!(e&&e.__v_isReadonly)}function si(e){return!!(e&&e.__v_isShallow)}function ps(e){return Pn(e)||mr(e)}function Ee(e){const t=e&&e.__v_raw;return t?Ee(t):e}function _s(e){return to(e,"__v_skip",!0),e}const hr=e=>Je(e)?sn(e):e,ea=e=>Je(e)?Zi(e):e;function gs(e){Ft&&ut&&(e=Ee(e),ss(e.dep||(e.dep=Wi())))}function bs(e,t){e=Ee(e),e.dep&&ci(e.dep)}function qe(e){return!!(e&&e.__v_isRef===!0)}function ve(e){return Es(e,!1)}function ys(e){return Es(e,!0)}function Es(e,t){return qe(e)?e:new cm(e,t)}class cm{constructor(t,n){this.__v_isShallow=n,this.dep=void 0,this.__v_isRef=!0,this._rawValue=n?t:Ee(t),this._value=n?t:hr(t)}get value(){return gs(this),this._value}set value(t){t=this.__v_isShallow?t:Ee(t),fr(t,this._rawValue)&&(this._rawValue=t,this._value=this.__v_isShallow?t:hr(t),bs(this))}}function Ge(e){return qe(e)?e.value:e}const sm={get:(e,t,n)=>Ge(Reflect.get(e,t,n)),set:(e,t,n,r)=>{const o=e[t];return qe(o)&&!qe(n)?(o.value=n,!0):Reflect.set(e,t,n,r)}};function Os(e){return Pn(e)?e:new Proxy(e,sm)}class um{constructor(t,n,r){this._object=t,this._key=n,this._defaultValue=r,this.__v_isRef=!0}get value(){const t=this._object[this._key];return t===void 0?this._defaultValue:t}set value(t){this._object[this._key]=t}}function ta(e,t,n){const r=e[t];return qe(r)?r:new um(e,t,n)}class dm{constructor(t,n,r,o){this._setter=n,this.dep=void 0,this.__v_isRef=!0,this._dirty=!0,this.effect=new Ki(t,()=>{this._dirty||(this._dirty=!0,bs(this))}),this.effect.computed=this,this.effect.active=this._cacheable=!o,this.__v_isReadonly=r}get value(){const t=Ee(this);return gs(t),(t._dirty||!t._cacheable)&&(t._dirty=!1,t._value=t.effect.run()),t._value}set value(t){this._setter(t)}}function fm(e,t,n=!1){let r,o;const i=de(e);return i?(r=e,o=mt):(r=e.get,o=e.set),new dm(r,o,i||!o,n)}function qt(e,t,n,r){let o;try{o=r?e(...r):e()}catch(i){Dr(i,t,n)}return o}function at(e,t,n,r){if(de(e)){const i=qt(e,t,n,r);return i&&os(i)&&i.catch(a=>{Dr(a,t,n)}),i}const o=[];for(let i=0;i>>1;vr(tt[r])Tt&&tt.splice(t,1)}function xs(e,t,n,r){ae(e)?n.push(...e):(!t||!t.includes(e,e.allowRecurse?r+1:r))&&n.push(e),Ts()}function pm(e){xs(e,Yn,er,_n)}function _m(e){xs(e,zt,tr,gn)}function wo(e,t=null){if(er.length){for(di=t,Yn=[...new Set(er)],er.length=0,_n=0;_nvr(n)-vr(r)),gn=0;gne.id==null?1/0:e.id;function Ps(e){ui=!1,no=!0,wo(e),tt.sort((n,r)=>vr(n)-vr(r));const t=mt;try{for(Tt=0;Tth.trim())),f&&(o=n.map(is))}let l,c=r[l=Co(t)]||r[l=Co(lt(t))];!c&&i&&(c=r[l=Co(Sn(t))]),c&&at(c,e,6,o);const u=r[l+"Once"];if(u){if(!e.emitted)e.emitted={};else if(e.emitted[l])return;e.emitted[l]=!0,at(u,e,6,o)}}function Is(e,t,n=!1){const r=t.emitsCache,o=r.get(e);if(o!==void 0)return o;const i=e.emits;let a={},l=!1;if(!de(e)){const c=u=>{const s=Is(u,t,!0);s&&(l=!0,He(a,s))};!n&&t.mixins.length&&t.mixins.forEach(c),e.extends&&c(e.extends),e.mixins&&e.mixins.forEach(c)}return!i&&!l?(r.set(e,null),null):(ae(i)?i.forEach(c=>a[c]=null):He(a,i),r.set(e,a),a)}function To(e,t){return!e||!Lr(t)?!1:(t=t.slice(2).replace(/Once$/,""),_e(e,t[0].toLowerCase()+t.slice(1))||_e(e,Sn(t))||_e(e,t))}let dt=null,Ls=null;function oo(e){const t=dt;return dt=e,Ls=e&&e.type.__scopeId||null,t}function bm(e,t=dt,n){if(!t||e._n)return e;const r=(...o)=>{r._d&&rl(-1);const i=oo(t),a=e(...o);return oo(i),r._d&&rl(1),a};return r._n=!0,r._c=!0,r._d=!0,r}function Mo(e){const{type:t,vnode:n,proxy:r,withProxy:o,props:i,propsOptions:[a],slots:l,attrs:c,emit:u,render:s,renderCache:f,data:m,setupState:h,ctx:b,inheritAttrs:y}=e;let w,g;const E=oo(e);try{if(n.shapeFlag&4){const P=o||r;w=st(s.call(P,P,f,i,h,m,b)),g=c}else{const P=t;w=st(P.length>1?P(i,{attrs:c,slots:l,emit:u}):P(i,null)),g=t.props?c:ym(c)}}catch(P){or.length=0,Dr(P,e,1),w=$e(bt)}let x=w;if(g&&y!==!1){const P=Object.keys(g),{shapeFlag:I}=x;P.length&&I&7&&(a&&P.some(Fi)&&(g=Em(g,a)),x=Ut(x,g))}return n.dirs&&(x=Ut(x),x.dirs=x.dirs?x.dirs.concat(n.dirs):n.dirs),n.transition&&(x.transition=n.transition),w=x,oo(E),w}const ym=e=>{let t;for(const n in e)(n==="class"||n==="style"||Lr(n))&&((t||(t={}))[n]=e[n]);return t},Em=(e,t)=>{const n={};for(const r in e)(!Fi(r)||!(r.slice(9)in t))&&(n[r]=e[r]);return n};function Om(e,t,n){const{props:r,children:o,component:i}=e,{props:a,children:l,patchFlag:c}=t,u=i.emitsOptions;if(t.dirs||t.transition)return!0;if(n&&c>=0){if(c&1024)return!0;if(c&16)return r?Wa(r,a,u):!!a;if(c&8){const s=t.dynamicProps;for(let f=0;fe.__isSuspense;function As(e,t){t&&t.pendingBranch?ae(e)?t.effects.push(...e):t.effects.push(e):_m(e)}function ln(e,t){if(ze){let n=ze.provides;const r=ze.parent&&ze.parent.provides;r===n&&(n=ze.provides=Object.create(r)),n[e]=t}}function Ne(e,t,n=!1){const r=ze||dt;if(r){const o=r.parent==null?r.vnode.appContext&&r.vnode.appContext.provides:r.parent.provides;if(o&&e in o)return o[e];if(arguments.length>1)return n&&de(t)?t.call(r.proxy):t}}const Ka={};function je(e,t,n){return Ds(e,t,n)}function Ds(e,t,{immediate:n,deep:r,flush:o,onTrack:i,onTrigger:a}=Ie){const l=ze;let c,u=!1,s=!1;if(qe(e)?(c=()=>e.value,u=si(e)):Pn(e)?(c=()=>e,r=!0):ae(e)?(s=!0,u=e.some(g=>Pn(g)||si(g)),c=()=>e.map(g=>{if(qe(g))return g.value;if(Pn(g))return En(g);if(de(g))return qt(g,l,2)})):de(e)?t?c=()=>qt(e,l,2):c=()=>{if(!(l&&l.isUnmounted))return f&&f(),at(e,l,3,[m])}:c=mt,t&&r){const g=c;c=()=>En(g())}let f,m=g=>{f=w.onStop=()=>{qt(g,l,4)}};if(An)return m=mt,t?n&&at(t,l,3,[c(),s?[]:void 0,m]):c(),mt;let h=s?[]:Ka;const b=()=>{if(!!w.active)if(t){const g=w.run();(r||u||(s?g.some((E,x)=>fr(E,h[x])):fr(g,h)))&&(f&&f(),at(t,l,3,[g,h===Ka?void 0:h,m]),h=g)}else w.run()};b.allowRecurse=!!t;let y;o==="sync"?y=b:o==="post"?y=()=>Ye(b,l&&l.suspense):y=()=>pm(b);const w=new Ki(c,y);return t?n?b():h=w.run():o==="post"?Ye(w.run.bind(w),l&&l.suspense):w.run(),()=>{w.stop(),l&&l.scope&&qi(l.scope.effects,w)}}function xm(e,t,n){const r=this.proxy,o=De(e)?e.includes(".")?js(r,e):()=>r[e]:e.bind(r,r);let i;de(t)?i=t:(i=t.handler,n=t);const a=ze;Ln(this);const l=Ds(o,i.bind(r),n);return a?Ln(a):cn(),l}function js(e,t){const n=t.split(".");return()=>{let r=e;for(let o=0;o{En(n,t)});else if(Lf(e))for(const n in e)En(e[n],t);return e}function ks(){const e={isMounted:!1,isLeaving:!1,isUnmounting:!1,leavingVNodes:new Map};return Ce(()=>{e.isMounted=!0}),Mn(()=>{e.isUnmounting=!0}),e}const ot=[Function,Array],Pm={name:"BaseTransition",props:{mode:String,appear:Boolean,persisted:Boolean,onBeforeEnter:ot,onEnter:ot,onAfterEnter:ot,onEnterCancelled:ot,onBeforeLeave:ot,onLeave:ot,onAfterLeave:ot,onLeaveCancelled:ot,onBeforeAppear:ot,onAppear:ot,onAfterAppear:ot,onAppearCancelled:ot},setup(e,{slots:t}){const n=Io(),r=ks();let o;return()=>{const i=t.default&&ia(t.default(),!0);if(!i||!i.length)return;let a=i[0];if(i.length>1){for(const y of i)if(y.type!==bt){a=y;break}}const l=Ee(e),{mode:c}=l;if(r.isLeaving)return zo(a);const u=Ya(a);if(!u)return zo(a);const s=pr(u,l,r,n);_r(u,s);const f=n.subTree,m=f&&Ya(f);let h=!1;const{getTransitionKey:b}=u.type;if(b){const y=b();o===void 0?o=y:y!==o&&(o=y,h=!0)}if(m&&m.type!==bt&&(!tn(u,m)||h)){const y=pr(m,l,r,n);if(_r(m,y),c==="out-in")return r.isLeaving=!0,y.afterLeave=()=>{r.isLeaving=!1,n.update()},zo(a);c==="in-out"&&u.type!==bt&&(y.delayLeave=(w,g,E)=>{const x=Ss(r,m);x[String(m.key)]=m,w._leaveCb=()=>{g(),w._leaveCb=void 0,delete s.delayedLeave},s.delayedLeave=E})}return a}}},Rs=Pm;function Ss(e,t){const{leavingVNodes:n}=e;let r=n.get(t.type);return r||(r=Object.create(null),n.set(t.type,r)),r}function pr(e,t,n,r){const{appear:o,mode:i,persisted:a=!1,onBeforeEnter:l,onEnter:c,onAfterEnter:u,onEnterCancelled:s,onBeforeLeave:f,onLeave:m,onAfterLeave:h,onLeaveCancelled:b,onBeforeAppear:y,onAppear:w,onAfterAppear:g,onAppearCancelled:E}=t,x=String(e.key),P=Ss(n,e),I=(k,W)=>{k&&at(k,r,9,W)},j=(k,W)=>{const Z=W[1];I(k,W),ae(k)?k.every(q=>q.length<=1)&&Z():k.length<=1&&Z()},D={mode:i,persisted:a,beforeEnter(k){let W=l;if(!n.isMounted)if(o)W=y||l;else return;k._leaveCb&&k._leaveCb(!0);const Z=P[x];Z&&tn(e,Z)&&Z.el._leaveCb&&Z.el._leaveCb(),I(W,[k])},enter(k){let W=c,Z=u,q=s;if(!n.isMounted)if(o)W=w||c,Z=g||u,q=E||s;else return;let A=!1;const R=k._enterCb=S=>{A||(A=!0,S?I(q,[k]):I(Z,[k]),D.delayedLeave&&D.delayedLeave(),k._enterCb=void 0)};W?j(W,[k,R]):R()},leave(k,W){const Z=String(e.key);if(k._enterCb&&k._enterCb(!0),n.isUnmounting)return W();I(f,[k]);let q=!1;const A=k._leaveCb=R=>{q||(q=!0,W(),R?I(b,[k]):I(h,[k]),k._leaveCb=void 0,P[Z]===e&&delete P[Z])};P[Z]=e,m?j(m,[k,A]):A()},clone(k){return pr(k,t,n,r)}};return D}function zo(e){if(jr(e))return e=Ut(e),e.children=null,e}function Ya(e){return jr(e)?e.children?e.children[0]:void 0:e}function _r(e,t){e.shapeFlag&6&&e.component?_r(e.component.subTree,t):e.shapeFlag&128?(e.ssContent.transition=t.clone(e.ssContent),e.ssFallback.transition=t.clone(e.ssFallback)):e.transition=t}function ia(e,t=!1,n){let r=[],o=0;for(let i=0;i1)for(let i=0;i!!e.type.__asyncLoader;function p(e){de(e)&&(e={loader:e});const{loader:t,loadingComponent:n,errorComponent:r,delay:o=200,timeout:i,suspensible:a=!0,onError:l}=e;let c=null,u,s=0;const f=()=>(s++,c=null,m()),m=()=>{let h;return c||(h=c=t().catch(b=>{if(b=b instanceof Error?b:new Error(String(b)),l)return new Promise((y,w)=>{l(b,()=>y(f()),()=>w(b),s+1)});throw b}).then(b=>h!==c&&c?c:(b&&(b.__esModule||b[Symbol.toStringTag]==="Module")&&(b=b.default),u=b,b)))};return oe({name:"AsyncComponentWrapper",__asyncLoader:m,get __asyncResolved(){return u},setup(){const h=ze;if(u)return()=>$o(u,h);const b=E=>{c=null,Dr(E,h,13,!r)};if(a&&h.suspense||An)return m().then(E=>()=>$o(E,h)).catch(E=>(b(E),()=>r?$e(r,{error:E}):null));const y=ve(!1),w=ve(),g=ve(!!o);return o&&setTimeout(()=>{g.value=!1},o),i!=null&&setTimeout(()=>{if(!y.value&&!w.value){const E=new Error(`Async component timed out after ${i}ms.`);b(E),w.value=E}},i),m().then(()=>{y.value=!0,h.parent&&jr(h.parent.vnode)&&oa(h.parent.update)}).catch(E=>{b(E),w.value=E}),()=>{if(y.value&&u)return $o(u,h);if(w.value&&r)return $e(r,{error:w.value});if(n&&!g.value)return $e(n)}}})}function $o(e,{vnode:{ref:t,props:n,children:r,shapeFlag:o},parent:i}){const a=$e(e,n,r);return a.ref=t,a}const jr=e=>e.type.__isKeepAlive;function Im(e,t){Cs(e,"a",t)}function Lm(e,t){Cs(e,"da",t)}function Cs(e,t,n=ze){const r=e.__wdc||(e.__wdc=()=>{let o=n;for(;o;){if(o.isDeactivated)return;o=o.parent}return e()});if(xo(t,r,n),n){let o=n.parent;for(;o&&o.parent;)jr(o.parent.vnode)&&Am(r,t,n,o),o=o.parent}}function Am(e,t,n,r){const o=xo(t,e,r,!0);zs(()=>{qi(r[t],o)},n)}function xo(e,t,n=ze,r=!1){if(n){const o=n[e]||(n[e]=[]),i=t.__weh||(t.__weh=(...a)=>{if(n.isUnmounted)return;Cn(),Ln(n);const l=at(t,n,e,a);return cn(),Vn(),l});return r?o.unshift(i):o.push(i),i}}const jt=e=>(t,n=ze)=>(!An||e==="sp")&&xo(e,t,n),Vs=jt("bm"),Ce=jt("m"),Dm=jt("bu"),Ms=jt("u"),Mn=jt("bum"),zs=jt("um"),jm=jt("sp"),km=jt("rtg"),Rm=jt("rtc");function Sm(e,t=ze){xo("ec",e,t)}function _t(e,t,n,r){const o=e.dirs,i=t&&t.dirs;for(let a=0;ae?Zs(e)?ca(e)||e.proxy:fi(e.parent):null,io=He(Object.create(null),{$:e=>e,$el:e=>e.vnode.el,$data:e=>e.data,$props:e=>e.props,$attrs:e=>e.attrs,$slots:e=>e.slots,$refs:e=>e.refs,$parent:e=>fi(e.parent),$root:e=>fi(e.root),$emit:e=>e.emit,$options:e=>Hs(e),$forceUpdate:e=>e.f||(e.f=()=>oa(e.update)),$nextTick:e=>e.n||(e.n=ra.bind(e.proxy)),$watch:e=>xm.bind(e)}),Mm={get({_:e},t){const{ctx:n,setupState:r,data:o,props:i,accessCache:a,type:l,appContext:c}=e;let u;if(t[0]!=="$"){const h=a[t];if(h!==void 0)switch(h){case 1:return r[t];case 2:return o[t];case 4:return n[t];case 3:return i[t]}else{if(r!==Ie&&_e(r,t))return a[t]=1,r[t];if(o!==Ie&&_e(o,t))return a[t]=2,o[t];if((u=e.propsOptions[0])&&_e(u,t))return a[t]=3,i[t];if(n!==Ie&&_e(n,t))return a[t]=4,n[t];mi&&(a[t]=0)}}const s=io[t];let f,m;if(s)return t==="$attrs"&&rt(e,"get",t),s(e);if((f=l.__cssModules)&&(f=f[t]))return f;if(n!==Ie&&_e(n,t))return a[t]=4,n[t];if(m=c.config.globalProperties,_e(m,t))return m[t]},set({_:e},t,n){const{data:r,setupState:o,ctx:i}=e;return o!==Ie&&_e(o,t)?(o[t]=n,!0):r!==Ie&&_e(r,t)?(r[t]=n,!0):_e(e.props,t)||t[0]==="$"&&t.slice(1)in e?!1:(i[t]=n,!0)},has({_:{data:e,setupState:t,accessCache:n,ctx:r,appContext:o,propsOptions:i}},a){let l;return!!n[a]||e!==Ie&&_e(e,a)||t!==Ie&&_e(t,a)||(l=i[0])&&_e(l,a)||_e(r,a)||_e(io,a)||_e(o.config.globalProperties,a)},defineProperty(e,t,n){return n.get!=null?e._.accessCache[t]=0:_e(n,"value")&&this.set(e,t,n.value,null),Reflect.defineProperty(e,t,n)}};let mi=!0;function zm(e){const t=Hs(e),n=e.proxy,r=e.ctx;mi=!1,t.beforeCreate&&Qa(t.beforeCreate,e,"bc");const{data:o,computed:i,methods:a,watch:l,provide:c,inject:u,created:s,beforeMount:f,mounted:m,beforeUpdate:h,updated:b,activated:y,deactivated:w,beforeDestroy:g,beforeUnmount:E,destroyed:x,unmounted:P,render:I,renderTracked:j,renderTriggered:D,errorCaptured:k,serverPrefetch:W,expose:Z,inheritAttrs:q,components:A,directives:R,filters:S}=t;if(u&&$m(u,r,null,e.appContext.config.unwrapInjectedRef),a)for(const Y in a){const X=a[Y];de(X)&&(r[Y]=X.bind(n))}if(o){const Y=o.call(n,n);Je(Y)&&(e.data=sn(Y))}if(mi=!0,i)for(const Y in i){const X=i[Y],fe=de(X)?X.bind(n,n):de(X.get)?X.get.bind(n,n):mt,pe=!de(X)&&de(X.set)?X.set.bind(n):mt,ye=H({get:fe,set:pe});Object.defineProperty(r,Y,{enumerable:!0,configurable:!0,get:()=>ye.value,set:we=>ye.value=we})}if(l)for(const Y in l)Ns(l[Y],r,n,Y);if(c){const Y=de(c)?c.call(n):c;Reflect.ownKeys(Y).forEach(X=>{ln(X,Y[X])})}s&&Qa(s,e,"c");function K(Y,X){ae(X)?X.forEach(fe=>Y(fe.bind(n))):X&&Y(X.bind(n))}if(K(Vs,f),K(Ce,m),K(Dm,h),K(Ms,b),K(Im,y),K(Lm,w),K(Sm,k),K(Rm,j),K(km,D),K(Mn,E),K(zs,P),K(jm,W),ae(Z))if(Z.length){const Y=e.exposed||(e.exposed={});Z.forEach(X=>{Object.defineProperty(Y,X,{get:()=>n[X],set:fe=>n[X]=fe})})}else e.exposed||(e.exposed={});I&&e.render===mt&&(e.render=I),q!=null&&(e.inheritAttrs=q),A&&(e.components=A),R&&(e.directives=R)}function $m(e,t,n=mt,r=!1){ae(e)&&(e=hi(e));for(const o in e){const i=e[o];let a;Je(i)?"default"in i?a=Ne(i.from||o,i.default,!0):a=Ne(i.from||o):a=Ne(i),qe(a)&&r?Object.defineProperty(t,o,{enumerable:!0,configurable:!0,get:()=>a.value,set:l=>a.value=l}):t[o]=a}}function Qa(e,t,n){at(ae(e)?e.map(r=>r.bind(t.proxy)):e.bind(t.proxy),t,n)}function Ns(e,t,n,r){const o=r.includes(".")?js(n,r):()=>n[r];if(De(e)){const i=t[e];de(i)&&je(o,i)}else if(de(e))je(o,e.bind(n));else if(Je(e))if(ae(e))e.forEach(i=>Ns(i,t,n,r));else{const i=de(e.handler)?e.handler.bind(n):t[e.handler];de(i)&&je(o,i,e)}}function Hs(e){const t=e.type,{mixins:n,extends:r}=t,{mixins:o,optionsCache:i,config:{optionMergeStrategies:a}}=e.appContext,l=i.get(t);let c;return l?c=l:!o.length&&!n&&!r?c=t:(c={},o.length&&o.forEach(u=>ao(c,u,a,!0)),ao(c,t,a)),i.set(t,c),c}function ao(e,t,n,r=!1){const{mixins:o,extends:i}=t;i&&ao(e,i,n,!0),o&&o.forEach(a=>ao(e,a,n,!0));for(const a in t)if(!(r&&a==="expose")){const l=Nm[a]||n&&n[a];e[a]=l?l(e[a],t[a]):t[a]}return e}const Nm={data:Za,props:Xt,emits:Xt,methods:Xt,computed:Xt,beforeCreate:We,created:We,beforeMount:We,mounted:We,beforeUpdate:We,updated:We,beforeDestroy:We,beforeUnmount:We,destroyed:We,unmounted:We,activated:We,deactivated:We,errorCaptured:We,serverPrefetch:We,components:Xt,directives:Xt,watch:Bm,provide:Za,inject:Hm};function Za(e,t){return t?e?function(){return He(de(e)?e.call(this,this):e,de(t)?t.call(this,this):t)}:t:e}function Hm(e,t){return Xt(hi(e),hi(t))}function hi(e){if(ae(e)){const t={};for(let n=0;n0)&&!(a&16)){if(a&8){const s=e.vnode.dynamicProps;for(let f=0;f{c=!0;const[m,h]=Fs(f,t,!0);He(a,m),h&&l.push(...h)};!n&&t.mixins.length&&t.mixins.forEach(s),e.extends&&s(e.extends),e.mixins&&e.mixins.forEach(s)}if(!i&&!c)return r.set(e,xn),xn;if(ae(i))for(let s=0;s-1,h[1]=y<0||b-1||_e(h,"default"))&&l.push(f)}}}const u=[a,l];return r.set(e,u),u}function Xa(e){return e[0]!=="$"}function el(e){const t=e&&e.toString().match(/^\s*function (\w+)/);return t?t[1]:e===null?"null":""}function tl(e,t){return el(e)===el(t)}function nl(e,t){return ae(t)?t.findIndex(n=>tl(n,e)):de(t)&&tl(t,e)?0:-1}const qs=e=>e[0]==="_"||e==="$stable",aa=e=>ae(e)?e.map(st):[st(e)],Jm=(e,t,n)=>{if(t._n)return t;const r=bm((...o)=>aa(t(...o)),n);return r._c=!1,r},Js=(e,t,n)=>{const r=e._ctx;for(const o in e){if(qs(o))continue;const i=e[o];if(de(i))t[o]=Jm(o,i,r);else if(i!=null){const a=aa(i);t[o]=()=>a}}},Us=(e,t)=>{const n=aa(t);e.slots.default=()=>n},Um=(e,t)=>{if(e.vnode.shapeFlag&32){const n=t._;n?(e.slots=Ee(t),to(t,"_",n)):Js(t,e.slots={})}else e.slots={},t&&Us(e,t);to(e.slots,Po,1)},Wm=(e,t,n)=>{const{vnode:r,slots:o}=e;let i=!0,a=Ie;if(r.shapeFlag&32){const l=t._;l?n&&l===1?i=!1:(He(o,t),!n&&l===1&&delete o._):(i=!t.$stable,Js(t,o)),a=t}else t&&(Us(e,t),a={default:1});if(i)for(const l in o)!qs(l)&&!(l in a)&&delete o[l]};function Ws(){return{app:null,config:{isNativeTag:Of,performance:!1,globalProperties:{},optionMergeStrategies:{},errorHandler:void 0,warnHandler:void 0,compilerOptions:{}},mixins:[],components:{},directives:{},provides:Object.create(null),optionsCache:new WeakMap,propsCache:new WeakMap,emitsCache:new WeakMap}}let Km=0;function Ym(e,t){return function(r,o=null){de(r)||(r=Object.assign({},r)),o!=null&&!Je(o)&&(o=null);const i=Ws(),a=new Set;let l=!1;const c=i.app={_uid:Km++,_component:r,_props:o,_container:null,_context:i,_instance:null,version:vh,get config(){return i.config},set config(u){},use(u,...s){return a.has(u)||(u&&de(u.install)?(a.add(u),u.install(c,...s)):de(u)&&(a.add(u),u(c,...s))),c},mixin(u){return i.mixins.includes(u)||i.mixins.push(u),c},component(u,s){return s?(i.components[u]=s,c):i.components[u]},directive(u,s){return s?(i.directives[u]=s,c):i.directives[u]},mount(u,s,f){if(!l){const m=$e(r,o);return m.appContext=i,s&&t?t(m,u):e(m,u,f),l=!0,c._container=u,u.__vue_app__=c,ca(m.component)||m.component.proxy}},unmount(){l&&(e(null,c._container),delete c._container.__vue_app__)},provide(u,s){return i.provides[u]=s,c}};return c}}function lo(e,t,n,r,o=!1){if(ae(e)){e.forEach((m,h)=>lo(m,t&&(ae(t)?t[h]:t),n,r,o));return}if(nr(r)&&!o)return;const i=r.shapeFlag&4?ca(r.component)||r.component.proxy:r.el,a=o?null:i,{i:l,r:c}=e,u=t&&t.r,s=l.refs===Ie?l.refs={}:l.refs,f=l.setupState;if(u!=null&&u!==c&&(De(u)?(s[u]=null,_e(f,u)&&(f[u]=null)):qe(u)&&(u.value=null)),de(c))qt(c,l,12,[a,s]);else{const m=De(c),h=qe(c);if(m||h){const b=()=>{if(e.f){const y=m?s[c]:c.value;o?ae(y)&&qi(y,i):ae(y)?y.includes(i)||y.push(i):m?(s[c]=[i],_e(f,c)&&(f[c]=s[c])):(c.value=[i],e.k&&(s[e.k]=c.value))}else m?(s[c]=a,_e(f,c)&&(f[c]=a)):h&&(c.value=a,e.k&&(s[e.k]=a))};a?(b.id=-1,Ye(b,n)):b()}}}let Ct=!1;const zr=e=>/svg/.test(e.namespaceURI)&&e.tagName!=="foreignObject",$r=e=>e.nodeType===8;function Gm(e){const{mt:t,p:n,o:{patchProp:r,createText:o,nextSibling:i,parentNode:a,remove:l,insert:c,createComment:u}}=e,s=(g,E)=>{if(!E.hasChildNodes()){n(null,g,E),ro(),E._vnode=g;return}Ct=!1,f(E.firstChild,g,null,null,null),ro(),E._vnode=g,Ct&&console.error("Hydration completed but contains mismatches.")},f=(g,E,x,P,I,j=!1)=>{const D=$r(g)&&g.data==="[",k=()=>y(g,E,x,P,I,D),{type:W,ref:Z,shapeFlag:q,patchFlag:A}=E,R=g.nodeType;E.el=g,A===-2&&(j=!1,E.dynamicChildren=null);let S=null;switch(W){case gr:R!==3?E.children===""?(c(E.el=o(""),a(g),g),S=g):S=k():(g.data!==E.children&&(Ct=!0,g.data=E.children),S=i(g));break;case bt:R!==8||D?S=k():S=i(g);break;case rr:if(R!==1&&R!==3)S=k();else{S=g;const F=!E.children.length;for(let K=0;K{j=j||!!E.dynamicChildren;const{type:D,props:k,patchFlag:W,shapeFlag:Z,dirs:q}=E,A=D==="input"&&q||D==="option";if(A||W!==-1){if(q&&_t(E,null,x,"created"),k)if(A||!j||W&48)for(const S in k)(A&&S.endsWith("value")||Lr(S)&&!Xn(S))&&r(g,S,null,k[S],!1,void 0,x);else k.onClick&&r(g,"onClick",null,k.onClick,!1,void 0,x);let R;if((R=k&&k.onVnodeBeforeMount)&&it(R,x,E),q&&_t(E,null,x,"beforeMount"),((R=k&&k.onVnodeMounted)||q)&&As(()=>{R&&it(R,x,E),q&&_t(E,null,x,"mounted")},P),Z&16&&!(k&&(k.innerHTML||k.textContent))){let S=h(g.firstChild,E,g,x,P,I,j);for(;S;){Ct=!0;const F=S;S=S.nextSibling,l(F)}}else Z&8&&g.textContent!==E.children&&(Ct=!0,g.textContent=E.children)}return g.nextSibling},h=(g,E,x,P,I,j,D)=>{D=D||!!E.dynamicChildren;const k=E.children,W=k.length;for(let Z=0;Z{const{slotScopeIds:D}=E;D&&(I=I?I.concat(D):D);const k=a(g),W=h(i(g),E,k,x,P,I,j);return W&&$r(W)&&W.data==="]"?i(E.anchor=W):(Ct=!0,c(E.anchor=u("]"),k,W),W)},y=(g,E,x,P,I,j)=>{if(Ct=!0,E.el=null,j){const W=w(g);for(;;){const Z=i(g);if(Z&&Z!==W)l(Z);else break}}const D=i(g),k=a(g);return l(g),n(null,E,k,D,x,P,zr(k),I),D},w=g=>{let E=0;for(;g;)if(g=i(g),g&&$r(g)&&(g.data==="["&&E++,g.data==="]")){if(E===0)return i(g);E--}return g};return[s,f]}const Ye=As;function Qm(e){return Zm(e,Gm)}function Zm(e,t){const n=jf();n.__VUE__=!0;const{insert:r,remove:o,patchProp:i,createElement:a,createText:l,createComment:c,setText:u,setElementText:s,parentNode:f,nextSibling:m,setScopeId:h=mt,cloneNode:b,insertStaticContent:y}=e,w=(_,O,L,C=null,M=null,z=null,J=!1,B=null,U=!!O.dynamicChildren)=>{if(_===O)return;_&&!tn(_,O)&&(C=Q(_),Le(_,M,z,!0),_=null),O.patchFlag===-2&&(U=!1,O.dynamicChildren=null);const{type:N,ref:ne,shapeFlag:te}=O;switch(N){case gr:g(_,O,L,C);break;case bt:E(_,O,L,C);break;case rr:_==null&&x(O,L,C,J);break;case et:R(_,O,L,C,M,z,J,B,U);break;default:te&1?j(_,O,L,C,M,z,J,B,U):te&6?S(_,O,L,C,M,z,J,B,U):(te&64||te&128)&&N.process(_,O,L,C,M,z,J,B,U,ge)}ne!=null&&M&&lo(ne,_&&_.ref,z,O||_,!O)},g=(_,O,L,C)=>{if(_==null)r(O.el=l(O.children),L,C);else{const M=O.el=_.el;O.children!==_.children&&u(M,O.children)}},E=(_,O,L,C)=>{_==null?r(O.el=c(O.children||""),L,C):O.el=_.el},x=(_,O,L,C)=>{[_.el,_.anchor]=y(_.children,O,L,C,_.el,_.anchor)},P=({el:_,anchor:O},L,C)=>{let M;for(;_&&_!==O;)M=m(_),r(_,L,C),_=M;r(O,L,C)},I=({el:_,anchor:O})=>{let L;for(;_&&_!==O;)L=m(_),o(_),_=L;o(O)},j=(_,O,L,C,M,z,J,B,U)=>{J=J||O.type==="svg",_==null?D(O,L,C,M,z,J,B,U):Z(_,O,M,z,J,B,U)},D=(_,O,L,C,M,z,J,B)=>{let U,N;const{type:ne,props:te,shapeFlag:ee,transition:ie,patchFlag:se,dirs:Te}=_;if(_.el&&b!==void 0&&se===-1)U=_.el=b(_.el);else{if(U=_.el=a(_.type,z,te&&te.is,te),ee&8?s(U,_.children):ee&16&&W(_.children,U,null,C,M,z&&ne!=="foreignObject",J,B),Te&&_t(_,null,C,"created"),te){for(const Ae in te)Ae!=="value"&&!Xn(Ae)&&i(U,Ae,null,te[Ae],z,_.children,C,M,$);"value"in te&&i(U,"value",null,te.value),(N=te.onVnodeBeforeMount)&&it(N,C,_)}k(U,_,_.scopeId,J,C)}Te&&_t(_,null,C,"beforeMount");const xe=(!M||M&&!M.pendingBranch)&&ie&&!ie.persisted;xe&&ie.beforeEnter(U),r(U,O,L),((N=te&&te.onVnodeMounted)||xe||Te)&&Ye(()=>{N&&it(N,C,_),xe&&ie.enter(U),Te&&_t(_,null,C,"mounted")},M)},k=(_,O,L,C,M)=>{if(L&&h(_,L),C)for(let z=0;z{for(let N=U;N<_.length;N++){const ne=_[N]=B?Nt(_[N]):st(_[N]);w(null,ne,O,L,C,M,z,J,B)}},Z=(_,O,L,C,M,z,J)=>{const B=O.el=_.el;let{patchFlag:U,dynamicChildren:N,dirs:ne}=O;U|=_.patchFlag&16;const te=_.props||Ie,ee=O.props||Ie;let ie;L&&Yt(L,!1),(ie=ee.onVnodeBeforeUpdate)&&it(ie,L,O,_),ne&&_t(O,_,L,"beforeUpdate"),L&&Yt(L,!0);const se=M&&O.type!=="foreignObject";if(N?q(_.dynamicChildren,N,B,L,C,se,z):J||fe(_,O,B,null,L,C,se,z,!1),U>0){if(U&16)A(B,O,te,ee,L,C,M);else if(U&2&&te.class!==ee.class&&i(B,"class",null,ee.class,M),U&4&&i(B,"style",te.style,ee.style,M),U&8){const Te=O.dynamicProps;for(let xe=0;xe{ie&&it(ie,L,O,_),ne&&_t(O,_,L,"updated")},C)},q=(_,O,L,C,M,z,J)=>{for(let B=0;B{if(L!==C){for(const B in C){if(Xn(B))continue;const U=C[B],N=L[B];U!==N&&B!=="value"&&i(_,B,N,U,J,O.children,M,z,$)}if(L!==Ie)for(const B in L)!Xn(B)&&!(B in C)&&i(_,B,L[B],null,J,O.children,M,z,$);"value"in C&&i(_,"value",L.value,C.value)}},R=(_,O,L,C,M,z,J,B,U)=>{const N=O.el=_?_.el:l(""),ne=O.anchor=_?_.anchor:l("");let{patchFlag:te,dynamicChildren:ee,slotScopeIds:ie}=O;ie&&(B=B?B.concat(ie):ie),_==null?(r(N,L,C),r(ne,L,C),W(O.children,L,ne,M,z,J,B,U)):te>0&&te&64&&ee&&_.dynamicChildren?(q(_.dynamicChildren,ee,L,M,z,J,B),(O.key!=null||M&&O===M.subTree)&&Ks(_,O,!0)):fe(_,O,L,ne,M,z,J,B,U)},S=(_,O,L,C,M,z,J,B,U)=>{O.slotScopeIds=B,_==null?O.shapeFlag&512?M.ctx.activate(O,L,C,J,U):F(O,L,C,M,z,J,U):K(_,O,U)},F=(_,O,L,C,M,z,J)=>{const B=_.component=ch(_,C,M);if(jr(_)&&(B.ctx.renderer=ge),sh(B),B.asyncDep){if(M&&M.registerDep(B,Y),!_.el){const U=B.subTree=$e(bt);E(null,U,O,L)}return}Y(B,_,O,L,M,z,J)},K=(_,O,L)=>{const C=O.component=_.component;if(Om(_,O,L))if(C.asyncDep&&!C.asyncResolved){X(C,O,L);return}else C.next=O,vm(C.update),C.update();else O.el=_.el,C.vnode=O},Y=(_,O,L,C,M,z,J)=>{const B=()=>{if(_.isMounted){let{next:ne,bu:te,u:ee,parent:ie,vnode:se}=_,Te=ne,xe;Yt(_,!1),ne?(ne.el=se.el,X(_,ne,J)):ne=se,te&&Vo(te),(xe=ne.props&&ne.props.onVnodeBeforeUpdate)&&it(xe,ie,ne,se),Yt(_,!0);const Ae=Mo(_),ct=_.subTree;_.subTree=Ae,w(ct,Ae,f(ct.el),Q(ct),_,M,z),ne.el=Ae.el,Te===null&&wm(_,Ae.el),ee&&Ye(ee,M),(xe=ne.props&&ne.props.onVnodeUpdated)&&Ye(()=>it(xe,ie,ne,se),M)}else{let ne;const{el:te,props:ee}=O,{bm:ie,m:se,parent:Te}=_,xe=nr(O);if(Yt(_,!1),ie&&Vo(ie),!xe&&(ne=ee&&ee.onVnodeBeforeMount)&&it(ne,Te,O),Yt(_,!0),te&&ce){const Ae=()=>{_.subTree=Mo(_),ce(te,_.subTree,_,M,null)};xe?O.type.__asyncLoader().then(()=>!_.isUnmounted&&Ae()):Ae()}else{const Ae=_.subTree=Mo(_);w(null,Ae,L,C,_,M,z),O.el=Ae.el}if(se&&Ye(se,M),!xe&&(ne=ee&&ee.onVnodeMounted)){const Ae=O;Ye(()=>it(ne,Te,Ae),M)}(O.shapeFlag&256||Te&&nr(Te.vnode)&&Te.vnode.shapeFlag&256)&&_.a&&Ye(_.a,M),_.isMounted=!0,O=L=C=null}},U=_.effect=new Ki(B,()=>oa(N),_.scope),N=_.update=()=>U.run();N.id=_.uid,Yt(_,!0),N()},X=(_,O,L)=>{O.component=_;const C=_.vnode.props;_.vnode=O,_.next=null,qm(_,O.props,C,L),Wm(_,O.children,L),Cn(),wo(void 0,_.update),Vn()},fe=(_,O,L,C,M,z,J,B,U=!1)=>{const N=_&&_.children,ne=_?_.shapeFlag:0,te=O.children,{patchFlag:ee,shapeFlag:ie}=O;if(ee>0){if(ee&128){ye(N,te,L,C,M,z,J,B,U);return}else if(ee&256){pe(N,te,L,C,M,z,J,B,U);return}}ie&8?(ne&16&&$(N,M,z),te!==N&&s(L,te)):ne&16?ie&16?ye(N,te,L,C,M,z,J,B,U):$(N,M,z,!0):(ne&8&&s(L,""),ie&16&&W(te,L,C,M,z,J,B,U))},pe=(_,O,L,C,M,z,J,B,U)=>{_=_||xn,O=O||xn;const N=_.length,ne=O.length,te=Math.min(N,ne);let ee;for(ee=0;eene?$(_,M,z,!0,!1,te):W(O,L,C,M,z,J,B,U,te)},ye=(_,O,L,C,M,z,J,B,U)=>{let N=0;const ne=O.length;let te=_.length-1,ee=ne-1;for(;N<=te&&N<=ee;){const ie=_[N],se=O[N]=U?Nt(O[N]):st(O[N]);if(tn(ie,se))w(ie,se,L,null,M,z,J,B,U);else break;N++}for(;N<=te&&N<=ee;){const ie=_[te],se=O[ee]=U?Nt(O[ee]):st(O[ee]);if(tn(ie,se))w(ie,se,L,null,M,z,J,B,U);else break;te--,ee--}if(N>te){if(N<=ee){const ie=ee+1,se=ieee)for(;N<=te;)Le(_[N],M,z,!0),N++;else{const ie=N,se=N,Te=new Map;for(N=se;N<=ee;N++){const Ze=O[N]=U?Nt(O[N]):st(O[N]);Ze.key!=null&&Te.set(Ze.key,N)}let xe,Ae=0;const ct=ee-se+1;let mn=!1,Ra=0;const Nn=new Array(ct);for(N=0;N=ct){Le(Ze,M,z,!0);continue}let pt;if(Ze.key!=null)pt=Te.get(Ze.key);else for(xe=se;xe<=ee;xe++)if(Nn[xe-se]===0&&tn(Ze,O[xe])){pt=xe;break}pt===void 0?Le(Ze,M,z,!0):(Nn[pt-se]=N+1,pt>=Ra?Ra=pt:mn=!0,w(Ze,O[pt],L,null,M,z,J,B,U),Ae++)}const Sa=mn?Xm(Nn):xn;for(xe=Sa.length-1,N=ct-1;N>=0;N--){const Ze=se+N,pt=O[Ze],Ca=Ze+1{const{el:z,type:J,transition:B,children:U,shapeFlag:N}=_;if(N&6){we(_.component.subTree,O,L,C);return}if(N&128){_.suspense.move(O,L,C);return}if(N&64){J.move(_,O,L,ge);return}if(J===et){r(z,O,L);for(let te=0;teB.enter(z),M);else{const{leave:te,delayLeave:ee,afterLeave:ie}=B,se=()=>r(z,O,L),Te=()=>{te(z,()=>{se(),ie&&ie()})};ee?ee(z,se,Te):Te()}else r(z,O,L)},Le=(_,O,L,C=!1,M=!1)=>{const{type:z,props:J,ref:B,children:U,dynamicChildren:N,shapeFlag:ne,patchFlag:te,dirs:ee}=_;if(B!=null&&lo(B,null,L,_,!0),ne&256){O.ctx.deactivate(_);return}const ie=ne&1&&ee,se=!nr(_);let Te;if(se&&(Te=J&&J.onVnodeBeforeUnmount)&&it(Te,O,_),ne&6)G(_.component,L,C);else{if(ne&128){_.suspense.unmount(L,C);return}ie&&_t(_,null,O,"beforeUnmount"),ne&64?_.type.remove(_,O,L,M,ge,C):N&&(z!==et||te>0&&te&64)?$(N,O,L,!1,!0):(z===et&&te&384||!M&&ne&16)&&$(U,O,L),C&&Be(_)}(se&&(Te=J&&J.onVnodeUnmounted)||ie)&&Ye(()=>{Te&&it(Te,O,_),ie&&_t(_,null,O,"unmounted")},L)},Be=_=>{const{type:O,el:L,anchor:C,transition:M}=_;if(O===et){V(L,C);return}if(O===rr){I(_);return}const z=()=>{o(L),M&&!M.persisted&&M.afterLeave&&M.afterLeave()};if(_.shapeFlag&1&&M&&!M.persisted){const{leave:J,delayLeave:B}=M,U=()=>J(L,z);B?B(_.el,z,U):U()}else z()},V=(_,O)=>{let L;for(;_!==O;)L=m(_),o(_),_=L;o(O)},G=(_,O,L)=>{const{bum:C,scope:M,update:z,subTree:J,um:B}=_;C&&Vo(C),M.stop(),z&&(z.active=!1,Le(J,_,O,L)),B&&Ye(B,O),Ye(()=>{_.isUnmounted=!0},O),O&&O.pendingBranch&&!O.isUnmounted&&_.asyncDep&&!_.asyncResolved&&_.suspenseId===O.pendingId&&(O.deps--,O.deps===0&&O.resolve())},$=(_,O,L,C=!1,M=!1,z=0)=>{for(let J=z;J<_.length;J++)Le(_[J],O,L,C,M)},Q=_=>_.shapeFlag&6?Q(_.component.subTree):_.shapeFlag&128?_.suspense.next():m(_.anchor||_.el),me=(_,O,L)=>{_==null?O._vnode&&Le(O._vnode,null,null,!0):w(O._vnode||null,_,O,null,null,null,L),ro(),O._vnode=_},ge={p:w,um:Le,m:we,r:Be,mt:F,mc:W,pc:fe,pbc:q,n:Q,o:e};let ue,ce;return t&&([ue,ce]=t(ge)),{render:me,hydrate:ue,createApp:Ym(me,ue)}}function Yt({effect:e,update:t},n){e.allowRecurse=t.allowRecurse=n}function Ks(e,t,n=!1){const r=e.children,o=t.children;if(ae(r)&&ae(o))for(let i=0;i>1,e[n[l]]0&&(t[r]=n[i-1]),n[i]=r)}}for(i=n.length,a=n[i-1];i-- >0;)n[i]=a,a=t[a];return n}const eh=e=>e.__isTeleport,et=Symbol(void 0),gr=Symbol(void 0),bt=Symbol(void 0),rr=Symbol(void 0),or=[];let ft=null;function h2(e=!1){or.push(ft=e?null:[])}function th(){or.pop(),ft=or[or.length-1]||null}let br=1;function rl(e){br+=e}function nh(e){return e.dynamicChildren=br>0?ft||xn:null,th(),br>0&&ft&&ft.push(e),e}function v2(e,t,n,r,o,i){return nh(Gs(e,t,n,r,o,i,!0))}function pi(e){return e?e.__v_isVNode===!0:!1}function tn(e,t){return e.type===t.type&&e.key===t.key}const Po="__vInternal",Ys=({key:e})=>e!=null?e:null,Yr=({ref:e,ref_key:t,ref_for:n})=>e!=null?De(e)||qe(e)||de(e)?{i:dt,r:e,k:t,f:!!n}:e:null;function Gs(e,t=null,n=null,r=0,o=null,i=e===et?0:1,a=!1,l=!1){const c={__v_isVNode:!0,__v_skip:!0,type:e,props:t,key:t&&Ys(t),ref:t&&Yr(t),scopeId:Ls,slotScopeIds:null,children:n,component:null,suspense:null,ssContent:null,ssFallback:null,dirs:null,transition:null,el:null,anchor:null,target:null,targetAnchor:null,staticCount:0,shapeFlag:i,patchFlag:r,dynamicProps:o,dynamicChildren:null,appContext:null};return l?(la(c,n),i&128&&e.normalize(c)):n&&(c.shapeFlag|=De(n)?8:16),br>0&&!a&&ft&&(c.patchFlag>0||i&6)&&c.patchFlag!==32&&ft.push(c),c}const $e=rh;function rh(e,t=null,n=null,r=0,o=null,i=!1){if((!e||e===Cm)&&(e=bt),pi(e)){const l=Ut(e,t,!0);return n&&la(l,n),br>0&&!i&&ft&&(l.shapeFlag&6?ft[ft.indexOf(e)]=l:ft.push(l)),l.patchFlag|=-2,l}if(hh(e)&&(e=e.__vccOpts),t){t=oh(t);let{class:l,style:c}=t;l&&!De(l)&&(t.class=Bi(l)),Je(c)&&(ps(c)&&!ae(c)&&(c=He({},c)),t.style=Hi(c))}const a=De(e)?1:Tm(e)?128:eh(e)?64:Je(e)?4:de(e)?2:0;return Gs(e,t,n,r,o,a,i,!0)}function oh(e){return e?ps(e)||Po in e?He({},e):e:null}function Ut(e,t,n=!1){const{props:r,ref:o,patchFlag:i,children:a}=e,l=t?ih(r||{},t):r;return{__v_isVNode:!0,__v_skip:!0,type:e.type,props:l,key:l&&Ys(l),ref:t&&t.ref?n&&o?ae(o)?o.concat(Yr(t)):[o,Yr(t)]:Yr(t):o,scopeId:e.scopeId,slotScopeIds:e.slotScopeIds,children:a,target:e.target,targetAnchor:e.targetAnchor,staticCount:e.staticCount,shapeFlag:e.shapeFlag,patchFlag:t&&e.type!==et?i===-1?16:i|16:i,dynamicProps:e.dynamicProps,dynamicChildren:e.dynamicChildren,appContext:e.appContext,dirs:e.dirs,transition:e.transition,component:e.component,suspense:e.suspense,ssContent:e.ssContent&&Ut(e.ssContent),ssFallback:e.ssFallback&&Ut(e.ssFallback),el:e.el,anchor:e.anchor}}function Qs(e=" ",t=0){return $e(gr,null,e,t)}function p2(e,t){const n=$e(rr,null,e);return n.staticCount=t,n}function st(e){return e==null||typeof e=="boolean"?$e(bt):ae(e)?$e(et,null,e.slice()):typeof e=="object"?Nt(e):$e(gr,null,String(e))}function Nt(e){return e.el===null||e.memo?e:Ut(e)}function la(e,t){let n=0;const{shapeFlag:r}=e;if(t==null)t=null;else if(ae(t))n=16;else if(typeof t=="object")if(r&65){const o=t.default;o&&(o._c&&(o._d=!1),la(e,o()),o._c&&(o._d=!0));return}else{n=32;const o=t._;!o&&!(Po in t)?t._ctx=dt:o===3&&dt&&(dt.slots._===1?t._=1:(t._=2,e.patchFlag|=1024))}else de(t)?(t={default:t,_ctx:dt},n=32):(t=String(t),r&64?(n=16,t=[Qs(t)]):n=8);e.children=t,e.shapeFlag|=n}function ih(...e){const t={};for(let n=0;nze||dt,Ln=e=>{ze=e,e.scope.on()},cn=()=>{ze&&ze.scope.off(),ze=null};function Zs(e){return e.vnode.shapeFlag&4}let An=!1;function sh(e,t=!1){An=t;const{props:n,children:r}=e.vnode,o=Zs(e);Fm(e,n,o,t),Um(e,r);const i=o?uh(e,t):void 0;return An=!1,i}function uh(e,t){const n=e.type;e.accessCache=Object.create(null),e.proxy=_s(new Proxy(e.ctx,Mm));const{setup:r}=n;if(r){const o=e.setupContext=r.length>1?fh(e):null;Ln(e),Cn();const i=qt(r,e,0,[e.props,o]);if(Vn(),cn(),os(i)){if(i.then(cn,cn),t)return i.then(a=>{ol(e,a,t)}).catch(a=>{Dr(a,e,0)});e.asyncDep=i}else ol(e,i,t)}else Xs(e,t)}function ol(e,t,n){de(t)?e.type.__ssrInlineRender?e.ssrRender=t:e.render=t:Je(t)&&(e.setupState=Os(t)),Xs(e,n)}let il;function Xs(e,t,n){const r=e.type;if(!e.render){if(!t&&il&&!r.render){const o=r.template;if(o){const{isCustomElement:i,compilerOptions:a}=e.appContext.config,{delimiters:l,compilerOptions:c}=r,u=He(He({isCustomElement:i,delimiters:l},a),c);r.render=il(o,u)}}e.render=r.render||mt}Ln(e),Cn(),zm(e),Vn(),cn()}function dh(e){return new Proxy(e.attrs,{get(t,n){return rt(e,"get","$attrs"),t[n]}})}function fh(e){const t=r=>{e.exposed=r||{}};let n;return{get attrs(){return n||(n=dh(e))},slots:e.slots,emit:e.emit,expose:t}}function ca(e){if(e.exposed)return e.exposeProxy||(e.exposeProxy=new Proxy(Os(_s(e.exposed)),{get(t,n){if(n in t)return t[n];if(n in io)return io[n](e)}}))}function mh(e,t=!0){return de(e)?e.displayName||e.name:e.name||t&&e.__name}function hh(e){return de(e)&&"__vccOpts"in e}const H=(e,t)=>fm(e,t,An);function v(e,t,n){const r=arguments.length;return r===2?Je(t)&&!ae(t)?pi(t)?$e(e,null,[t]):$e(e,t):$e(e,null,t):(r>3?n=Array.prototype.slice.call(arguments,2):r===3&&pi(n)&&(n=[n]),$e(e,t,n))}const vh="3.2.37",ph="http://www.w3.org/2000/svg",nn=typeof document!="undefined"?document:null,al=nn&&nn.createElement("template"),_h={insert:(e,t,n)=>{t.insertBefore(e,n||null)},remove:e=>{const t=e.parentNode;t&&t.removeChild(e)},createElement:(e,t,n,r)=>{const o=t?nn.createElementNS(ph,e):nn.createElement(e,n?{is:n}:void 0);return e==="select"&&r&&r.multiple!=null&&o.setAttribute("multiple",r.multiple),o},createText:e=>nn.createTextNode(e),createComment:e=>nn.createComment(e),setText:(e,t)=>{e.nodeValue=t},setElementText:(e,t)=>{e.textContent=t},parentNode:e=>e.parentNode,nextSibling:e=>e.nextSibling,querySelector:e=>nn.querySelector(e),setScopeId(e,t){e.setAttribute(t,"")},cloneNode(e){const t=e.cloneNode(!0);return"_value"in e&&(t._value=e._value),t},insertStaticContent(e,t,n,r,o,i){const a=n?n.previousSibling:t.lastChild;if(o&&(o===i||o.nextSibling))for(;t.insertBefore(o.cloneNode(!0),n),!(o===i||!(o=o.nextSibling)););else{al.innerHTML=r?`${e}`:e;const l=al.content;if(r){const c=l.firstChild;for(;c.firstChild;)l.appendChild(c.firstChild);l.removeChild(c)}t.insertBefore(l,n)}return[a?a.nextSibling:t.firstChild,n?n.previousSibling:t.lastChild]}};function gh(e,t,n){const r=e._vtc;r&&(t=(t?[t,...r]:[...r]).join(" ")),t==null?e.removeAttribute("class"):n?e.setAttribute("class",t):e.className=t}function bh(e,t,n){const r=e.style,o=De(n);if(n&&!o){for(const i in n)_i(r,i,n[i]);if(t&&!De(t))for(const i in t)n[i]==null&&_i(r,i,"")}else{const i=r.display;o?t!==n&&(r.cssText=n):t&&e.removeAttribute("style"),"_vod"in e&&(r.display=i)}}const ll=/\s*!important$/;function _i(e,t,n){if(ae(n))n.forEach(r=>_i(e,t,r));else if(n==null&&(n=""),t.startsWith("--"))e.setProperty(t,n);else{const r=yh(e,t);ll.test(n)?e.setProperty(Sn(r),n.replace(ll,""),"important"):e[r]=n}}const cl=["Webkit","Moz","ms"],No={};function yh(e,t){const n=No[t];if(n)return n;let r=lt(t);if(r!=="filter"&&r in e)return No[t]=r;r=Ar(r);for(let o=0;o{let e=Date.now,t=!1;if(typeof window!="undefined"){Date.now()>document.createEvent("Event").timeStamp&&(e=performance.now.bind(performance));const n=navigator.userAgent.match(/firefox\/(\d+)/i);t=!!(n&&Number(n[1])<=53)}return[e,t]})();let gi=0;const Th=Promise.resolve(),xh=()=>{gi=0},Ph=()=>gi||(Th.then(xh),gi=eu());function Ih(e,t,n,r){e.addEventListener(t,n,r)}function Lh(e,t,n,r){e.removeEventListener(t,n,r)}function Ah(e,t,n,r,o=null){const i=e._vei||(e._vei={}),a=i[t];if(r&&a)a.value=r;else{const[l,c]=Dh(t);if(r){const u=i[t]=jh(r,o);Ih(e,l,u,c)}else a&&(Lh(e,l,a,c),i[t]=void 0)}}const ul=/(?:Once|Passive|Capture)$/;function Dh(e){let t;if(ul.test(e)){t={};let n;for(;n=e.match(ul);)e=e.slice(0,e.length-n[0].length),t[n[0].toLowerCase()]=!0}return[Sn(e.slice(2)),t]}function jh(e,t){const n=r=>{const o=r.timeStamp||eu();(wh||o>=n.attached-1)&&at(kh(r,n.value),t,5,[r])};return n.value=e,n.attached=Ph(),n}function kh(e,t){if(ae(t)){const n=e.stopImmediatePropagation;return e.stopImmediatePropagation=()=>{n.call(e),e._stopped=!0},t.map(r=>o=>!o._stopped&&r&&r(o))}else return t}const dl=/^on[a-z]/,Rh=(e,t,n,r,o=!1,i,a,l,c)=>{t==="class"?gh(e,r,o):t==="style"?bh(e,n,r):Lr(t)?Fi(t)||Ah(e,t,n,r,a):(t[0]==="."?(t=t.slice(1),!0):t[0]==="^"?(t=t.slice(1),!1):Sh(e,t,r,o))?Oh(e,t,r,i,a,l,c):(t==="true-value"?e._trueValue=r:t==="false-value"&&(e._falseValue=r),Eh(e,t,r,o))};function Sh(e,t,n,r){return r?!!(t==="innerHTML"||t==="textContent"||t in e&&dl.test(t)&&de(n)):t==="spellcheck"||t==="draggable"||t==="translate"||t==="form"||t==="list"&&e.tagName==="INPUT"||t==="type"&&e.tagName==="TEXTAREA"||dl.test(t)&&De(n)?!1:t in e}const Vt="transition",Hn="animation",Dt=(e,{slots:t})=>v(Rs,nu(e),t);Dt.displayName="Transition";const tu={name:String,type:String,css:{type:Boolean,default:!0},duration:[String,Number,Object],enterFromClass:String,enterActiveClass:String,enterToClass:String,appearFromClass:String,appearActiveClass:String,appearToClass:String,leaveFromClass:String,leaveActiveClass:String,leaveToClass:String},Ch=Dt.props=He({},Rs.props,tu),Gt=(e,t=[])=>{ae(e)?e.forEach(n=>n(...t)):e&&e(...t)},fl=e=>e?ae(e)?e.some(t=>t.length>1):e.length>1:!1;function nu(e){const t={};for(const A in e)A in tu||(t[A]=e[A]);if(e.css===!1)return t;const{name:n="v",type:r,duration:o,enterFromClass:i=`${n}-enter-from`,enterActiveClass:a=`${n}-enter-active`,enterToClass:l=`${n}-enter-to`,appearFromClass:c=i,appearActiveClass:u=a,appearToClass:s=l,leaveFromClass:f=`${n}-leave-from`,leaveActiveClass:m=`${n}-leave-active`,leaveToClass:h=`${n}-leave-to`}=e,b=Vh(o),y=b&&b[0],w=b&&b[1],{onBeforeEnter:g,onEnter:E,onEnterCancelled:x,onLeave:P,onLeaveCancelled:I,onBeforeAppear:j=g,onAppear:D=E,onAppearCancelled:k=x}=t,W=(A,R,S)=>{$t(A,R?s:l),$t(A,R?u:a),S&&S()},Z=(A,R)=>{A._isLeaving=!1,$t(A,f),$t(A,h),$t(A,m),R&&R()},q=A=>(R,S)=>{const F=A?D:E,K=()=>W(R,A,S);Gt(F,[R,K]),ml(()=>{$t(R,A?c:i),Ot(R,A?s:l),fl(F)||hl(R,r,y,K)})};return He(t,{onBeforeEnter(A){Gt(g,[A]),Ot(A,i),Ot(A,a)},onBeforeAppear(A){Gt(j,[A]),Ot(A,c),Ot(A,u)},onEnter:q(!1),onAppear:q(!0),onLeave(A,R){A._isLeaving=!0;const S=()=>Z(A,R);Ot(A,f),ou(),Ot(A,m),ml(()=>{!A._isLeaving||($t(A,f),Ot(A,h),fl(P)||hl(A,r,w,S))}),Gt(P,[A,S])},onEnterCancelled(A){W(A,!1),Gt(x,[A])},onAppearCancelled(A){W(A,!0),Gt(k,[A])},onLeaveCancelled(A){Z(A),Gt(I,[A])}})}function Vh(e){if(e==null)return null;if(Je(e))return[Ho(e.enter),Ho(e.leave)];{const t=Ho(e);return[t,t]}}function Ho(e){return is(e)}function Ot(e,t){t.split(/\s+/).forEach(n=>n&&e.classList.add(n)),(e._vtc||(e._vtc=new Set)).add(t)}function $t(e,t){t.split(/\s+/).forEach(r=>r&&e.classList.remove(r));const{_vtc:n}=e;n&&(n.delete(t),n.size||(e._vtc=void 0))}function ml(e){requestAnimationFrame(()=>{requestAnimationFrame(e)})}let Mh=0;function hl(e,t,n,r){const o=e._endId=++Mh,i=()=>{o===e._endId&&r()};if(n)return setTimeout(i,n);const{type:a,timeout:l,propCount:c}=ru(e,t);if(!a)return r();const u=a+"end";let s=0;const f=()=>{e.removeEventListener(u,m),i()},m=h=>{h.target===e&&++s>=c&&f()};setTimeout(()=>{s(n[b]||"").split(", "),o=r(Vt+"Delay"),i=r(Vt+"Duration"),a=vl(o,i),l=r(Hn+"Delay"),c=r(Hn+"Duration"),u=vl(l,c);let s=null,f=0,m=0;t===Vt?a>0&&(s=Vt,f=a,m=i.length):t===Hn?u>0&&(s=Hn,f=u,m=c.length):(f=Math.max(a,u),s=f>0?a>u?Vt:Hn:null,m=s?s===Vt?i.length:c.length:0);const h=s===Vt&&/\b(transform|all)(,|$)/.test(n[Vt+"Property"]);return{type:s,timeout:f,propCount:m,hasTransform:h}}function vl(e,t){for(;e.lengthpl(n)+pl(e[r])))}function pl(e){return Number(e.slice(0,-1).replace(",","."))*1e3}function ou(){return document.body.offsetHeight}const iu=new WeakMap,au=new WeakMap,zh={name:"TransitionGroup",props:He({},Ch,{tag:String,moveClass:String}),setup(e,{slots:t}){const n=Io(),r=ks();let o,i;return Ms(()=>{if(!o.length)return;const a=e.moveClass||`${e.name||"v"}-move`;if(!Bh(o[0].el,n.vnode.el,a))return;o.forEach($h),o.forEach(Nh);const l=o.filter(Hh);ou(),l.forEach(c=>{const u=c.el,s=u.style;Ot(u,a),s.transform=s.webkitTransform=s.transitionDuration="";const f=u._moveCb=m=>{m&&m.target!==u||(!m||/transform$/.test(m.propertyName))&&(u.removeEventListener("transitionend",f),u._moveCb=null,$t(u,a))};u.addEventListener("transitionend",f)})}),()=>{const a=Ee(e),l=nu(a);let c=a.tag||et;o=i,i=t.default?ia(t.default()):[];for(let u=0;u{a.split(/\s+/).forEach(l=>l&&r.classList.remove(l))}),n.split(/\s+/).forEach(a=>a&&r.classList.add(a)),r.style.display="none";const o=t.nodeType===1?t:t.parentNode;o.appendChild(r);const{hasTransform:i}=ru(r);return o.removeChild(r),i}const Fh=He({patchProp:Rh},_h);let Bo,gl=!1;function qh(){return Bo=gl?Bo:Qm(Fh),gl=!0,Bo}const Jh=(...e)=>{const t=qh().createApp(...e),{mount:n}=t;return t.mount=r=>{const o=Uh(r);if(o)return n(o,!0,o instanceof SVGElement)},t};function Uh(e){return De(e)?document.querySelector(e):e}const Wh={base:"/",lang:"en-US",title:"",description:"",head:[["script",{},` + var _hmt = _hmt || []; + (function() { + var hm = document.createElement("script"); + hm.src = "https://hm.baidu.com/hm.js?5230ac143650bf5eb3c14f3fb9b1d3ec"; + var s = document.getElementsByTagName("script")[0]; + s.parentNode.insertBefore(hm, s); + })(); + `],["link",{rel:"stylesheet",href:"//at.alicdn.com/t/font_3180624_7cy10l7jqqh.css"}],["link",{rel:"icon",href:"/favicon.ico"}],["link",{rel:"icon",href:"/assets/icon/chrome-mask-512.png",type:"image/png",sizes:"512x512"}],["link",{rel:"icon",href:"/assets/icon/chrome-mask-192.png",type:"image/png",sizes:"192x192"}],["link",{rel:"icon",href:"/assets/icon/chrome-512.png",type:"image/png",sizes:"512x512"}],["link",{rel:"icon",href:"/assets/icon/chrome-192.png",type:"image/png",sizes:"192x192"}],["link",{rel:"manifest",href:"/manifest.webmanifest",crossorigin:"use-credentials"}],["meta",{name:"theme-color",content:"#46bd87"}],["link",{rel:"apple-touch-icon",href:"/assets/icon/apple-icon-152.png"}],["meta",{name:"apple-mobile-web-app-capable",content:"yes"}],["meta",{name:"apple-mobile-web-app-status-bar-style",content:"black"}],["meta",{name:"msapplication-TileImage",content:"/assets/icon/ms-icon-144.png"}],["meta",{name:"msapplication-TileColor",content:"#ffffff"}],["meta",{name:"viewport",content:"width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover"}]],locales:{"/":{lang:"zh-CN",title:"Java \u7A0B\u5E8F\u5458\u8FDB\u9636\u4E4B\u8DEF",description:"\u4E00\u4EFD\u901A\u4FD7\u6613\u61C2\u3001\u98CE\u8DA3\u5E7D\u9ED8\u7684Java\u5B66\u4E60\u6307\u5357\uFF0C\u5185\u5BB9\u6DB5\u76D6Java\u57FA\u7840\u3001Java\u5E76\u53D1\u7F16\u7A0B\u3001Java\u865A\u62DF\u673A\u3001Java\u4F01\u4E1A\u7EA7\u5F00\u53D1\u3001Java\u9762\u8BD5\u7B49\u6838\u5FC3\u77E5\u8BC6\u70B9\u3002\u5B66Java\uFF0C\u5C31\u8BA4\u51C6Java\u7A0B\u5E8F\u5458\u8FDB\u9636\u4E4B\u8DEF"}}};var Kh=([e,t,n])=>e==="meta"&&t.name?`${e}.${t.name}`:["title","base"].includes(e)?e:e==="template"&&t.id?`${e}.${t.id}`:JSON.stringify([e,t,n]),Yh=e=>{const t=new Set,n=[];return e.forEach(r=>{const o=Kh(r);t.has(o)||(t.add(o),n.push(r))}),n},Gh=e=>/(\.html|\/)$/.test(e)?e:e+"/",Qh=e=>e.startsWith("ftp://"),un=e=>/^(https?:)?\/\//.test(e),co=(e,t="/")=>!!(un(e)||Qh(e)||e.startsWith("/")&&!e.startsWith(t)&&!e.endsWith(".md")),Zh=e=>/^mailto:/.test(e),Xh=e=>/^tel:/.test(e),sa=e=>Object.prototype.toString.call(e)==="[object Object]",ua=e=>e.replace(/\/$/,""),lu=e=>e.replace(/^\//,""),ev=(e,t)=>{const n=Object.keys(e).sort((r,o)=>{const i=o.split("/").length-r.split("/").length;return i!==0?i:o.length-r.length});for(const r of n)if(t.startsWith(r))return r;return"/"},tv=(e,t="/")=>e.replace(/^(https?:)?\/\/[^/]*/,"").replace(new RegExp(`^${t}`),"/");const cu={"v-8daa1a0e":p(()=>d(()=>import("./index.html.9c1a7487.js"),["assets/index.html.9c1a7487.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-79fdd481":p(()=>d(()=>import("./home.html.25268b5b.js"),["assets/home.html.25268b5b.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-5eb6769a":p(()=>d(()=>import("./bzhan-10wan.html.e0ad4af0.js"),["assets/bzhan-10wan.html.e0ad4af0.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-047e0dd0":p(()=>d(()=>import("./csdn-1000wan.html.22ddf17a.js"),["assets/csdn-1000wan.html.22ddf17a.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-728c3a8f":p(()=>d(()=>import("./index.html.efbaa943.js"),["assets/index.html.efbaa943.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-d4d4d9f0":p(()=>d(()=>import("./zhihu-1000wan.html.51362a9b.js"),["assets/zhihu-1000wan.html.51362a9b.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-4c9adc8f":p(()=>d(()=>import("./array.html.19972859.js"),["assets/array.html.19972859.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-c5b29e8a":p(()=>d(()=>import("./print.html.4135561a.js"),["assets/print.html.4135561a.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-5bc8e34a":p(()=>d(()=>import("./basic-data-type.html.20d3399e.js"),["assets/basic-data-type.html.20d3399e.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-2e99fc7b":p(()=>d(()=>import("./flow-control.html.5046ff0c.js"),["assets/flow-control.html.5046ff0c.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-2ed31bba":p(()=>d(()=>import("./javadoc.html.435ee8ec.js"),["assets/javadoc.html.435ee8ec.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-5bd30156":p(()=>d(()=>import("./operator.html.152cf4bc.js"),["assets/operator.html.152cf4bc.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-116742fa":p(()=>d(()=>import("./java-basic-34.html.c0108ee7.js"),["assets/java-basic-34.html.c0108ee7.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-41eeffa1":p(()=>d(()=>import("./java-basic.html.34b72317.js"),["assets/java-basic.html.34b72317.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-453decce":p(()=>d(()=>import("./java-thread.html.87abce4b.js"),["assets/java-thread.html.87abce4b.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-1a5aed8d":p(()=>d(()=>import("./jvm.html.cb0eace1.js"),["assets/jvm.html.cb0eace1.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-68d21dbd":p(()=>d(()=>import("./48-keywords.html.c30c9b30.js"),["assets/48-keywords.html.c30c9b30.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-079af819":p(()=>d(()=>import("./Overriding.html.d8235770.js"),["assets/Overriding.html.d8235770.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-bb853b5a":p(()=>d(()=>import("./annotation.html.3a9fcfe1.js"),["assets/annotation.html.3a9fcfe1.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-4b1bf2c5":p(()=>d(()=>import("./box.html.03f96a13.js"),["assets/box.html.03f96a13.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-40e5cd2e":p(()=>d(()=>import("./class-object.html.a22a09d8.js"),["assets/class-object.html.a22a09d8.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-788ca7fc":p(()=>d(()=>import("./comparable-omparator.html.1a3bff07.js"),["assets/comparable-omparator.html.1a3bff07.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-3684a67a":p(()=>d(()=>import("./deep-copy.html.1b203746.js"),["assets/deep-copy.html.1b203746.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-36e67681":p(()=>d(()=>import("./enum.html.637c7ac9.js"),["assets/enum.html.637c7ac9.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-9048faf2":p(()=>d(()=>import("./equals-hashcode.html.033e729f.js"),["assets/equals-hashcode.html.033e729f.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-ce39a3f6":p(()=>d(()=>import("./fanshe.html.e42ba18d.js"),["assets/fanshe.html.e42ba18d.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-06b06a8e":p(()=>d(()=>import("./generic.html.df9c6eb8.js"),["assets/generic.html.df9c6eb8.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-7c307347":p(()=>d(()=>import("./hashcode.html.6a0e81d9.js"),["assets/hashcode.html.6a0e81d9.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-d4ba57a4":p(()=>d(()=>import("./immutable.html.aab5b4ed.js"),["assets/immutable.html.aab5b4ed.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-35db81bc":p(()=>d(()=>import("./instanceof-jvm.html.84099ac1.js"),["assets/instanceof-jvm.html.84099ac1.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-3516d6cc":p(()=>d(()=>import("./int-cache.html.bb142a51.js"),["assets/int-cache.html.bb142a51.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-da276006":p(()=>d(()=>import("./java-naming.html.1100d2ca.js"),["assets/java-naming.html.1100d2ca.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-692842f0":p(()=>d(()=>import("./java-unicode.html.c63853a0.js"),["assets/java-unicode.html.c63853a0.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-e7ec28a8":p(()=>d(()=>import("./jdk-while-for-wuxian-xunhuan.html.a5707bd9.js"),["assets/jdk-while-for-wuxian-xunhuan.html.a5707bd9.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-8d888ea8":p(()=>d(()=>import("./jdk9-char-byte-string.html.884765a3.js"),["assets/jdk9-char-byte-string.html.884765a3.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-7b47ec96":p(()=>d(()=>import("./override-overload.html.1c9aaf26.js"),["assets/override-overload.html.1c9aaf26.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-a5cf66ce":p(()=>d(()=>import("./pass-by-value.html.cf8023d5.js"),["assets/pass-by-value.html.cf8023d5.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-3b06244a":p(()=>d(()=>import("./true-generic.html.a683e7b2.js"),["assets/true-generic.html.a683e7b2.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-7553bbe0":p(()=>d(()=>import("./varables.html.3f84ac76.js"),["assets/varables.html.3f84ac76.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-662a92aa":p(()=>d(()=>import("./beijing.html.a011f671.js"),["assets/beijing.html.a011f671.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-38cd1384":p(()=>d(()=>import("./chengdu.html.7221dfab.js"),["assets/chengdu.html.7221dfab.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-3eb2e9b0":p(()=>d(()=>import("./guangzhou.html.c44755f8.js"),["assets/guangzhou.html.c44755f8.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-697611a4":p(()=>d(()=>import("./hangzhou.html.a9b39480.js"),["assets/hangzhou.html.a9b39480.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-743d326c":p(()=>d(()=>import("./jinan.html.95982728.js"),["assets/jinan.html.95982728.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-345abdb5":p(()=>d(()=>import("./nanjing.html.099e9844.js"),["assets/nanjing.html.099e9844.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-e7504db2":p(()=>d(()=>import("./qingdao.html.c4a4c2c4.js"),["assets/qingdao.html.c4a4c2c4.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-33fa70f5":p(()=>d(()=>import("./shenzhen.html.61178979.js"),["assets/shenzhen.html.61178979.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-3819c1f4":p(()=>d(()=>import("./suzhou.html.b2ed5bbc.js"),["assets/suzhou.html.b2ed5bbc.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-55b57168":p(()=>d(()=>import("./xian.html.b0d9fb64.js"),["assets/xian.html.b0d9fb64.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-b3887a38":p(()=>d(()=>import("./zhengzhou.html.bee29209.js"),["assets/zhengzhou.html.bee29209.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-48818f7a":p(()=>d(()=>import("./arraylist.html.f57cbfa7.js"),["assets/arraylist.html.f57cbfa7.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-85734e74":p(()=>d(()=>import("./fail-fast.html.dca676b6.js"),["assets/fail-fast.html.dca676b6.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-a612d212":p(()=>d(()=>import("./gailan.html.50f82bf5.js"),["assets/gailan.html.50f82bf5.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-69fbae62":p(()=>d(()=>import("./hashmap-interview.html.36f118fd.js"),["assets/hashmap-interview.html.36f118fd.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-60be3e7a":p(()=>d(()=>import("./hashmap.html.e3590cbb.js"),["assets/hashmap.html.e3590cbb.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-754b8740":p(()=>d(()=>import("./iterator-iterable.html.7a5374e3.js"),["assets/iterator-iterable.html.7a5374e3.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-2136d56c":p(()=>d(()=>import("./linkedlist.html.e021186b.js"),["assets/linkedlist.html.e021186b.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-65f6d97a":p(()=>d(()=>import("./list-war-2.html.4306ceaf.js"),["assets/list-war-2.html.4306ceaf.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-f7fcdb1e":p(()=>d(()=>import("./arrays.html.ea4b1150.js"),["assets/arrays.html.ea4b1150.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-17562512":p(()=>d(()=>import("./collections.html.37777ec8.js"),["assets/collections.html.37777ec8.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-7d0053a9":p(()=>d(()=>import("./guava.html.bbc48258.js"),["assets/guava.html.bbc48258.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-2d07de66":p(()=>d(()=>import("./hutool.html.5bf70ca7.js"),["assets/hutool.html.5bf70ca7.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-a7472ae2":p(()=>d(()=>import("./os.html.1d208877.js"),["assets/os.html.1d208877.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-366b86bc":p(()=>d(()=>import("./wangluo.html.bf2e0885.js"),["assets/wangluo.html.bf2e0885.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-6ef55906":p(()=>d(()=>import("./bat-shuati.html.214e49f5.js"),["assets/bat-shuati.html.214e49f5.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-bb191cda":p(()=>d(()=>import("./history.html.57bb6aeb.js"),["assets/history.html.57bb6aeb.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-440da5e9":p(()=>d(()=>import("./java.html.9104a10d.js"),["assets/java.html.9104a10d.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-03f42fc2":p(()=>d(()=>import("./jianli.html.2cde4ea0.js"),["assets/jianli.html.2cde4ea0.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-1f0822f4":p(()=>d(()=>import("./learn-jianyi.html.2486d715.js"),["assets/learn-jianyi.html.2486d715.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-43185964":p(()=>d(()=>import("./nicearticle.html.4730077f.js"),["assets/nicearticle.html.4730077f.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-e1dd7216":p(()=>d(()=>import("./pdf.html.79c228f5.js"),["assets/pdf.html.79c228f5.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-5ee46134":p(()=>d(()=>import("./progit.html.95158ac7.js"),["assets/progit.html.95158ac7.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-ed798b2e":p(()=>d(()=>import("./yuanyifeng-c-language.html.90250cb3.js"),["assets/yuanyifeng-c-language.html.90250cb3.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-39324891":p(()=>d(()=>import("./rumen.html.ee21a790.js"),["assets/rumen.html.ee21a790.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-7f4a0796":p(()=>d(()=>import("./gailan.html.0ea3f7da.js"),["assets/gailan.html.0ea3f7da.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-27e42762":p(()=>d(()=>import("./npe.html.297684ef.js"),["assets/npe.html.297684ef.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-ad4adf1c":p(()=>d(()=>import("./shijian.html.d1dfaaba.js"),["assets/shijian.html.d1dfaaba.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-053b70f2":p(()=>d(()=>import("./try-with-resouces.html.52a831d4.js"),["assets/try-with-resouces.html.52a831d4.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-24bf8472":p(()=>d(()=>import("./git-qiyuan.html.085fb4bc.js"),["assets/git-qiyuan.html.085fb4bc.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-c4de51c4":p(()=>d(()=>import("./progit.html.284a6498.js"),["assets/progit.html.284a6498.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-7b2a5ff2":p(()=>d(()=>import("./Chocolatey-Homebrew.html.5637171d.js"),["assets/Chocolatey-Homebrew.html.5637171d.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-3d562a9a":p(()=>d(()=>import("./DBeaver.html.16c02541.js"),["assets/DBeaver.html.16c02541.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-c6c0b0d0":p(()=>d(()=>import("./chiner.html.daf0adff.js"),["assets/chiner.html.daf0adff.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-2d6ff326":p(()=>d(()=>import("./choco.html.2c7d8900.js"),["assets/choco.html.2c7d8900.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-54937d2a":p(()=>d(()=>import("./fastjson.html.bf5a0ad8.js"),["assets/fastjson.html.bf5a0ad8.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-fe63cc9c":p(()=>d(()=>import("./forest.html.3141000b.js"),["assets/forest.html.3141000b.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-00cd7f78":p(()=>d(()=>import("./gson.html.a359eddd.js"),["assets/gson.html.a359eddd.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-1e073750":p(()=>d(()=>import("./jackson.html.f4471baf.js"),["assets/jackson.html.f4471baf.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-065f99d6":p(()=>d(()=>import("./junit.html.9c832cdc.js"),["assets/junit.html.9c832cdc.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-b8f624f0":p(()=>d(()=>import("./knife4j.html.4fbb94b8.js"),["assets/knife4j.html.4fbb94b8.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-e034f2ee":p(()=>d(()=>import("./log4j.html.0b4fd542.js"),["assets/log4j.html.0b4fd542.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-70680037":p(()=>d(()=>import("./log4j2.html.d1682823.js"),["assets/log4j2.html.d1682823.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-1eebad78":p(()=>d(()=>import("./logback.html.806b8b11.js"),["assets/logback.html.806b8b11.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-fdffa3a8":p(()=>d(()=>import("./others.html.63b5af1f.js"),["assets/others.html.63b5af1f.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-19392480":p(()=>d(()=>import("./slf4j.html.f772534d.js"),["assets/slf4j.html.f772534d.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-abf717d2":p(()=>d(()=>import("./tabby.html.c3b44c08.js"),["assets/tabby.html.c3b44c08.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-cfb128b2":p(()=>d(()=>import("./warp.html.8ae8cc83.js"),["assets/warp.html.8ae8cc83.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-2f1b6319":p(()=>d(()=>import("./4-debug-skill.html.0c72ed75.js"),["assets/4-debug-skill.html.0c72ed75.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-62663e4e":p(()=>d(()=>import("./BIONIOAIO.html.4c184e72.js"),["assets/BIONIOAIO.html.4c184e72.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-3bf159f4":p(()=>d(()=>import("./shangtou.html.d25e4bab.js"),["assets/shangtou.html.d25e4bab.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-0a083d40":p(()=>d(()=>import("./Lambda.html.bd1566d3.js"),["assets/Lambda.html.bd1566d3.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-aa8f9c32":p(()=>d(()=>import("./optional.html.775157f3.js"),["assets/optional.html.775157f3.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-6d140547":p(()=>d(()=>import("./stream.html.02d08777.js"),["assets/stream.html.02d08777.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-0d07ca65":p(()=>d(()=>import("./asm.html.43e7fd57.js"),["assets/asm.html.43e7fd57.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-3748383d":p(()=>d(()=>import("./bytecode.html.568c5a04.js"),["assets/bytecode.html.568c5a04.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-efd40586":p(()=>d(()=>import("./class-file-jiegou.html.3aa9524b.js"),["assets/class-file-jiegou.html.3aa9524b.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-b9ac0ed2":p(()=>d(()=>import("./class-load.html.07c5abca.js"),["assets/class-load.html.07c5abca.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-16000f89":p(()=>d(()=>import("./compile-jdk.html.fddb4940.js"),["assets/compile-jdk.html.fddb4940.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-2781e43c":p(()=>d(()=>import("./cpu-percent-100.html.30d9234e.js"),["assets/cpu-percent-100.html.30d9234e.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-c9f5a514":p(()=>d(()=>import("./gc.html.714d0f7b.js"),["assets/gc.html.714d0f7b.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-e8fbf108":p(()=>d(()=>import("./how-jvm-run-zijiema-zhiling.html.f5dbcd2c.js"),["assets/how-jvm-run-zijiema-zhiling.html.f5dbcd2c.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-63d827b2":p(()=>d(()=>import("./how-run-java-code.html.5154cace.js"),["assets/how-run-java-code.html.5154cace.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-1b3dc969":p(()=>d(()=>import("./hsdb.html.4b8d1063.js"),["assets/hsdb.html.4b8d1063.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-a2340bea":p(()=>d(()=>import("./jit.html.cd04156f.js"),["assets/jit.html.cd04156f.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-07af3814":p(()=>d(()=>import("./meituan-9-gc.html.7173ffd4.js"),["assets/meituan-9-gc.html.7173ffd4.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-e8878c14":p(()=>d(()=>import("./neicun-jiegou.html.fee2587a.js"),["assets/neicun-jiegou.html.fee2587a.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-30815cda":p(()=>d(()=>import("./oom.html.cbfa1fb6.js"),["assets/oom.html.cbfa1fb6.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-2254b233":p(()=>d(()=>import("./problem-tools.html.c0e0819e.js"),["assets/problem-tools.html.c0e0819e.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-4c99a464":p(()=>d(()=>import("./tujie-gc.html.3ec6a37b.js"),["assets/tujie-gc.html.3ec6a37b.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-57bf2d3c":p(()=>d(()=>import("./what-happen-when-javac.html.a24cf79e.js"),["assets/what-happen-when-javac.html.a24cf79e.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-214d568e":p(()=>d(()=>import("./what-is-jvm.html.3177cd0e.js"),["assets/what-is-jvm.html.3177cd0e.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-5adc261b":p(()=>d(()=>import("./whereis-the-object.html.5fa8d65e.js"),["assets/whereis-the-object.html.5fa8d65e.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-b827481e":p(()=>d(()=>import("./zijiema-zhiling.html.60db7eb3.js"),["assets/zijiema-zhiling.html.60db7eb3.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-32ecf2e8":p(()=>d(()=>import("./zongjie.html.1ee2edb6.js"),["assets/zongjie.html.1ee2edb6.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-2ead7d38":p(()=>d(()=>import("./auto-generator.html.341a868e.js"),["assets/auto-generator.html.341a868e.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-070fbd0c":p(()=>d(()=>import("./index.html.c95125a9.js"),["assets/index.html.c95125a9.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-97a45628":p(()=>d(()=>import("./yuneban-wangyiyunyinyue.html.83ef1711.js"),["assets/yuneban-wangyiyunyinyue.html.83ef1711.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-000948f2":p(()=>d(()=>import("./waibao-1geyue.html.31a36346.js"),["assets/waibao-1geyue.html.31a36346.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-66366bd2":p(()=>d(()=>import("./yanjiusuo-20wan.html.4b71b495.js"),["assets/yanjiusuo-20wan.html.4b71b495.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-6002cbaa":p(()=>d(()=>import("./maven.html.d13a0dbf.js"),["assets/maven.html.d13a0dbf.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-6ec52668":p(()=>d(()=>import("./redis12question.html.f0270e84.js"),["assets/redis12question.html.f0270e84.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-fdcf9bf0":p(()=>d(()=>import("./shanganaliyun.html.802605a1.js"),["assets/shanganaliyun.html.802605a1.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-fcf91dba":p(()=>d(()=>import("./api-wangguan.html.ec8dd3f1.js"),["assets/api-wangguan.html.ec8dd3f1.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-23fb287c":p(()=>d(()=>import("./rumen.html.3f2b5ec9.js"),["assets/rumen.html.3f2b5ec9.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-20db0618":p(()=>d(()=>import("./100-budiushi.html.281fc989.js"),["assets/100-budiushi.html.281fc989.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-ea0a417a":p(()=>d(()=>import("./rabbitmq-rumen.html.5bf7bc58.js"),["assets/rabbitmq-rumen.html.5bf7bc58.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-43bd2008":p(()=>d(()=>import("./deletedb-binlog-weiguanjishu.html.0dd5fe85.js"),["assets/deletedb-binlog-weiguanjishu.html.0dd5fe85.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-1f354ebe":p(()=>d(()=>import("./redis-shuju-yizhixing.html.480d5fea.js"),["assets/redis-shuju-yizhixing.html.480d5fea.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-c64f1dca":p(()=>d(()=>import("./40-interview.html.e460eeeb.js"),["assets/40-interview.html.e460eeeb.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-189ab80d":p(()=>d(()=>import("./nginx.html.25ed8525.js"),["assets/nginx.html.25ed8525.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-8be2b210":p(()=>d(()=>import("./BOKEYUANruhegaoxiaodixuexijishu.html.665a0cbe.js"),["assets/BOKEYUANruhegaoxiaodixuexijishu.html.665a0cbe.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-b5321080":p(()=>d(()=>import("./ZHIHUjavaxuexidaoshemechengduokeyizhaodiyifengongzuo.html.ef1e0c27.js"),["assets/ZHIHUjavaxuexidaoshemechengduokeyizhaodiyifengongzuo.html.ef1e0c27.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-7625a17a":p(()=>d(()=>import("./bokeyuan-jianxijavazhongdifangwenquanxiankongzhi.html.5212785d.js"),["assets/bokeyuan-jianxijavazhongdifangwenquanxiankongzhi.html.5212785d.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-b39bf9b6":p(()=>d(()=>import("./bokeyuan-ruhegaoxiaodixuexijishu.html.e50696a0.js"),["assets/bokeyuan-ruhegaoxiaodixuexijishu.html.e50696a0.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-bb8a78fa":p(()=>d(()=>import("./haibukuaiyongmybatisplusshoubashoujiaoni.html.6feacfb3.js"),["assets/haibukuaiyongmybatisplusshoubashoujiaoni.html.6feacfb3.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-3404ee90":p(()=>d(()=>import("./javaxuexidaoshemechengduokeyizhaodiyifengongzuo.html.6e4f2abd.js"),["assets/javaxuexidaoshemechengduokeyizhaodiyifengongzuo.html.6e4f2abd.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-42ab3f07":p(()=>d(()=>import("./jiagoushizenyanghuizhijitongjiagoulantu.html.aafe265c.js"),["assets/jiagoushizenyanghuizhijitongjiagoulantu.html.aafe265c.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-ba14f030":p(()=>d(()=>import("./jielehenduosihuodiganchu.html.576b64a2.js"),["assets/jielehenduosihuodiganchu.html.576b64a2.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-8ef10754":p(()=>d(()=>import("./jishuzongjianbeikaichuliao.html.6397e62a.js"),["assets/jishuzongjianbeikaichuliao.html.6397e62a.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-b04aa828":p(()=>d(()=>import("./nginx-setting.html.3934a533.js"),["assets/nginx-setting.html.3934a533.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-5ff455de":p(()=>d(()=>import("./weixin-bagwpdf.html.e485fe14.js"),["assets/weixin-bagwpdf.html.e485fe14.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-dfeef5c6":p(()=>d(()=>import("./weixin-chengxwjdwzhqcgxm.html.5c788b1b.js"),["assets/weixin-chengxwjdwzhqcgxm.html.5c788b1b.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-1a392032":p(()=>d(()=>import("./weixin-githubxbkdjavajccjyh.html.11c03a69.js"),["assets/weixin-githubxbkdjavajccjyh.html.11c03a69.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-d0172620":p(()=>d(()=>import("./weixin-liaoliaoxianliu.html.fa1a5a6a.js"),["assets/weixin-liaoliaoxianliu.html.fa1a5a6a.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-39c49d7e":p(()=>d(()=>import("./weixin-likbj.html.a9767504.js"),["assets/weixin-likbj.html.a9767504.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-0397d0de":p(()=>d(()=>import("./weixin-mozdsdzfjavableetcodetxxk.html.62ab0a25.js"),["assets/weixin-mozdsdzfjavableetcodetxxk.html.62ab0a25.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-692b01ca":p(()=>d(()=>import("./weixin-piaolwzjztqdtskwlzfpdf.html.0792de0c.js"),["assets/weixin-piaolwzjztqdtskwlzfpdf.html.0792de0c.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-16ac8eee":p(()=>d(()=>import("./weixin-quoppomspwml.html.03c9aa24.js"),["assets/weixin-quoppomspwml.html.03c9aa24.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-01db1eaa":p(()=>d(()=>import("./weixin-shejmsnb.html.1f9c172b.js"),["assets/weixin-shejmsnb.html.1f9c172b.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-16f50d13":p(()=>d(()=>import("./weixin-shenrjcjavabfbchwjdhl.html.8fda2ac2.js"),["assets/weixin-shenrjcjavabfbchwjdhl.html.8fda2ac2.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-51ad9d8d":p(()=>d(()=>import("./weixin-xinllgjszjszzpojozsyjbsjlxyhjfyll.html.b7b8ec57.js"),["assets/weixin-xinllgjszjszzpojozsyjbsjlxyhjfyll.html.b7b8ec57.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-84fc24ae":p(()=>d(()=>import("./weixin-zaixsfdnavicatzkkydsjkglgjjmgxk.html.bcbd11eb.js"),["assets/weixin-zaixsfdnavicatzkkydsjkglgjjmgxk.html.bcbd11eb.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-273df44a":p(()=>d(()=>import("./weixin-zhongxcwbztashjjavahdmj.html.2296ba72.js"),["assets/weixin-zhongxcwbztashjjavahdmj.html.2296ba72.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-0bc0f1a3":p(()=>d(()=>import("./weixin-zuixinbujiabandigongsimingdan.html.d0426aa9.js"),["assets/weixin-zuixinbujiabandigongsimingdan.html.d0426aa9.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-9570d5e4":p(()=>d(()=>import("./zhihu-jisjkyynxzdtjdyj.html.468f166c.js"),["assets/zhihu-jisjkyynxzdtjdyj.html.468f166c.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-8e1aac5c":p(()=>d(()=>import("./zhihu-weismyrsyxkjgscxyzhdjyxz.html.ec5fcad9.js"),["assets/zhihu-weismyrsyxkjgscxyzhdjyxz.html.ec5fcad9.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-59da4d60":p(()=>d(()=>import("./zhihu-younxzdjsjzyxsjrdgq.html.c66976c6.js"),["assets/zhihu-younxzdjsjzyxsjrdgq.html.c66976c6.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-1ef77dfe":p(()=>d(()=>import("./abstract.html.e17df797.js"),["assets/abstract.html.e17df797.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-42f4881f":p(()=>d(()=>import("./code-init.html.58676afd.js"),["assets/code-init.html.58676afd.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-44efe198":p(()=>d(()=>import("./construct.html.0a38a577.js"),["assets/construct.html.0a38a577.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-0cdc8b4e":p(()=>d(()=>import("./final.html.e625665e.js"),["assets/final.html.e625665e.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-205a2eee":p(()=>d(()=>import("./inner-class.html.858a9fd0.js"),["assets/inner-class.html.858a9fd0.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-1b40dbb7":p(()=>d(()=>import("./instanceof.html.edc709c7.js"),["assets/instanceof.html.edc709c7.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-cf613514":p(()=>d(()=>import("./interface.html.de30e51e.js"),["assets/interface.html.de30e51e.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-7bb58bbc":p(()=>d(()=>import("./method.html.1f147cbd.js"),["assets/method.html.1f147cbd.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-fbea188e":p(()=>d(()=>import("./object-class.html.698d849f.js"),["assets/object-class.html.698d849f.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-2e2eacb5":p(()=>d(()=>import("./static.html.c9732093.js"),["assets/static.html.c9732093.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-7cc17552":p(()=>d(()=>import("./this-super.html.ff84e809.js"),["assets/this-super.html.ff84e809.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-cee31e70":p(()=>d(()=>import("./var.html.6e7f16a9.js"),["assets/var.html.6e7f16a9.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-a931ed42":p(()=>d(()=>import("./hello-world.html.26946542.js"),["assets/hello-world.html.26946542.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-472dda20":p(()=>d(()=>import("./what-is-java.html.efbb701f.js"),["assets/what-is-java.html.efbb701f.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-264d9d3b":p(()=>d(()=>import("./redis-springboot.html.3faa6adc.js"),["assets/redis-springboot.html.3faa6adc.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-520f0e13":p(()=>d(()=>import("./rumen.html.27e01d35.js"),["assets/rumen.html.27e01d35.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-f63181d6":p(()=>d(()=>import("./xuebeng-chuantou-jichuan.html.ffa86b85.js"),["assets/xuebeng-chuantou-jichuan.html.ffa86b85.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-3b896528":p(()=>d(()=>import("./image-yasuo.html.0e3ff54c.js"),["assets/image-yasuo.html.0e3ff54c.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-5d00799b":p(()=>d(()=>import("./log4j2.html.066d10f7.js"),["assets/log4j2.html.066d10f7.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-0a391fc2":p(()=>d(()=>import("./computer-base.html.ca77cdaf.js"),["assets/computer-base.html.ca77cdaf.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-fdb1bc82":p(()=>d(()=>import("./Filter-Interceptor-Listener.html.7803e9df.js"),["assets/Filter-Interceptor-Listener.html.7803e9df.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-174081f7":p(()=>d(()=>import("./aop-log.html.ec10c829.js"),["assets/aop-log.html.ec10c829.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-534b7235":p(()=>d(()=>import("./cors.html.b1e575b3.js"),["assets/cors.html.b1e575b3.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-5b4d8cf6":p(()=>d(()=>import("./initializr.html.8afcbffb.js"),["assets/initializr.html.8afcbffb.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-7ff17e1a":p(()=>d(()=>import("./ioc.html.a79e951b.js"),["assets/ioc.html.a79e951b.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-5964f7d5":p(()=>d(()=>import("./jpa.html.c491ef74.js"),["assets/jpa.html.c491ef74.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-27c6ab2e":p(()=>d(()=>import("./jwt.html.2aed3523.js"),["assets/jwt.html.2aed3523.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-72c3c3e8":p(()=>d(()=>import("./linux-codingmore-run.html.d96d85b1.js"),["assets/linux-codingmore-run.html.d96d85b1.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-c65767f6":p(()=>d(()=>import("./logback.html.ce19f5e4.js"),["assets/logback.html.ce19f5e4.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-56fd99ea":p(()=>d(()=>import("./macos-codingmore-run.html.100361aa.js"),["assets/macos-codingmore-run.html.100361aa.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-765c4bce":p(()=>d(()=>import("./mysql-druid.html.9707dc06.js"),["assets/mysql-druid.html.9707dc06.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-1e34c521":p(()=>d(()=>import("./oss.html.e3216442.js"),["assets/oss.html.e3216442.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-a4a685a0":p(()=>d(()=>import("./springtask.html.6f8efcf6.js"),["assets/springtask.html.6f8efcf6.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-eb0f47f4":p(()=>d(()=>import("./swagger.html.e13d1880.js"),["assets/swagger.html.e13d1880.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-4d7a00b5":p(()=>d(()=>import("./thymeleaf.html.943910b5.js"),["assets/thymeleaf.html.943910b5.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-6f0be684":p(()=>d(()=>import("./tomcat.html.af3e6ee8.js"),["assets/tomcat.html.af3e6ee8.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-33b6789c":p(()=>d(()=>import("./transaction.html.9982a65f.js"),["assets/transaction.html.9982a65f.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-5ca9fbdb":p(()=>d(()=>import("./windows-codingmore-run.html.225f6c56.js"),["assets/windows-codingmore-run.html.225f6c56.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-8d804d8e":p(()=>d(()=>import("./constant-pool.html.81e697ea.js"),["assets/constant-pool.html.81e697ea.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-03911b96":p(()=>d(()=>import("./equals.html.f7e52978.js"),["assets/equals.html.f7e52978.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-a45f0e08":p(()=>d(()=>import("./immutable.html.acff64d4.js"),["assets/immutable.html.acff64d4.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-95e9527c":p(()=>d(()=>import("./intern.html.cb5b47c3.js"),["assets/intern.html.cb5b47c3.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-db441b2c":p(()=>d(()=>import("./join.html.50d59b6e.js"),["assets/join.html.50d59b6e.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-f0ca9e38":p(()=>d(()=>import("./split.html.b69d2cd1.js"),["assets/split.html.b69d2cd1.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-42ee1292":p(()=>d(()=>import("./buy-cloud-server.html.5057ae50.js"),["assets/buy-cloud-server.html.5057ae50.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-1267a82e":p(()=>d(()=>import("./buy-domain.html.e087e5aa.js"),["assets/buy-domain.html.e087e5aa.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-5590a9da":p(()=>d(()=>import("./https-domain.html.81185a29.js"),["assets/https-domain.html.81185a29.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-6d7e6055":p(()=>d(()=>import("./install-baota-mianban.html.fc940506.js"),["assets/install-baota-mianban.html.fc940506.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-830a668e":p(()=>d(()=>import("./record-domain.html.3a82f73e.js"),["assets/record-domain.html.3a82f73e.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-5c219956":p(()=>d(()=>import("./tobebetterjavaer-wangzhan-shangxian.html.eb4a3068.js"),["assets/tobebetterjavaer-wangzhan-shangxian.html.eb4a3068.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-611e28c1":p(()=>d(()=>import("./tupian-zhuanlian.html.cc248511.js"),["assets/tupian-zhuanlian.html.cc248511.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-49acdbe9":p(()=>d(()=>import("./BlockingQueue.html.76b31f3c.js"),["assets/BlockingQueue.html.76b31f3c.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-03b9fcee":p(()=>d(()=>import("./ConcurrentHashMap.html.77d65cc9.js"),["assets/ConcurrentHashMap.html.77d65cc9.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-109bb8a4":p(()=>d(()=>import("./ConcurrentLinkedQueue.html.f8564dd9.js"),["assets/ConcurrentLinkedQueue.html.f8564dd9.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-396740a1":p(()=>d(()=>import("./CopyOnWriteArrayList.html.2fa1badd.js"),["assets/CopyOnWriteArrayList.html.2fa1badd.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-f606f74c":p(()=>d(()=>import("./CountDownLatch.html.79c0b80e.js"),["assets/CountDownLatch.html.79c0b80e.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-ccb364be":p(()=>d(()=>import("./LockSupport.html.5ea98b89.js"),["assets/LockSupport.html.5ea98b89.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-4c7ec7a6":p(()=>d(()=>import("./ReentrantReadWriteLock.html.140f1c3e.js"),["assets/ReentrantReadWriteLock.html.140f1c3e.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-17464182":p(()=>d(()=>import("./ScheduledThreadPoolExecutor.html.73744e7a.js"),["assets/ScheduledThreadPoolExecutor.html.73744e7a.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-00920464":p(()=>d(()=>import("./ThreadLocal.html.2993d4fd.js"),["assets/ThreadLocal.html.2993d4fd.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-3d590e34":p(()=>d(()=>import("./ali-executors.html.3e2ae653.js"),["assets/ali-executors.html.3e2ae653.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-1df9d2c2":p(()=>d(()=>import("./aqs.html.58976faa.js"),["assets/aqs.html.58976faa.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-f854807c":p(()=>d(()=>import("./atomic.html.08ec5c1f.js"),["assets/atomic.html.08ec5c1f.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-c14f0f20":p(()=>d(()=>import("./cas.html.68e07dc8.js"),["assets/cas.html.68e07dc8.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-66a4042c":p(()=>d(()=>import("./condition.html.4a44859a.js"),["assets/condition.html.4a44859a.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-6d64b820":p(()=>d(()=>import("./fork-join.html.e8674cdb.js"),["assets/fork-join.html.e8674cdb.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-31e3344a":p(()=>d(()=>import("./jmm.html.2560457a.js"),["assets/jmm.html.2560457a.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-46ec2dc2":p(()=>d(()=>import("./lock.html.707d5244.js"),["assets/lock.html.707d5244.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-adf4a16e":p(()=>d(()=>import("./map.html.6ee85b94.js"),["assets/map.html.6ee85b94.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-147d8971":p(()=>d(()=>import("./pool.html.7274870a.js"),["assets/pool.html.7274870a.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-06ad3e4d":p(()=>d(()=>import("./reentrantLock.html.8b519bdc.js"),["assets/reentrantLock.html.8b519bdc.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-80e01c30":p(()=>d(()=>import("./shengchanzhe-xiaofeizhe.html.b76e11fd.js"),["assets/shengchanzhe-xiaofeizhe.html.b76e11fd.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-f96cf90e":p(()=>d(()=>import("./synchronized.html.0249091e.js"),["assets/synchronized.html.0249091e.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-1e8914e1":p(()=>d(()=>import("./thread-bring-some-problem.html.891141f3.js"),["assets/thread-bring-some-problem.html.891141f3.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-f8642b66":p(()=>d(()=>import("./thread-group-and-thread-priority.html.777c962b.js"),["assets/thread-group-and-thread-priority.html.777c962b.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-9fc9a5a2":p(()=>d(()=>import("./thread-state-and-method.html.a816be26.js"),["assets/thread-state-and-method.html.a816be26.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-9ae84c1e":p(()=>d(()=>import("./volatile.html.4f34c8de.js"),["assets/volatile.html.4f34c8de.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-06f71d0a":p(()=>d(()=>import("./wangzhe-thread.html.752a4836.js"),["assets/wangzhe-thread.html.752a4836.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-6feb1e09":p(()=>d(()=>import("./why-need-thread.html.8e1db849.js"),["assets/why-need-thread.html.8e1db849.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-6476d1b6":p(()=>d(()=>import("./aliyun-shuaiguo-gongchengshi.html.af9a0166.js"),["assets/aliyun-shuaiguo-gongchengshi.html.af9a0166.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-da1bbc34":p(()=>d(()=>import("./chadiansanhuo.html.fc173db8.js"),["assets/chadiansanhuo.html.fc173db8.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-78df38f4":p(()=>d(()=>import("./chengxuyuannv-chonghui-java.html.01f1b5cf.js"),["assets/chengxuyuannv-chonghui-java.html.01f1b5cf.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-1749ea82":p(()=>d(()=>import("./daxue-nuli-jisuanji.html.ad13ab16.js"),["assets/daxue-nuli-jisuanji.html.ad13ab16.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-eb9ba2e8":p(()=>d(()=>import("./fumutuanju.html.ca0f5d88.js"),["assets/fumutuanju.html.ca0f5d88.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-4d6508bf":p(()=>d(()=>import("./electron-information-engineering.html.6411b062.js"),["assets/electron-information-engineering.html.6411b062.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-ea4c66a8":p(()=>d(()=>import("./read-csapp.html.c0e758ea.js"),["assets/read-csapp.html.c0e758ea.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-358ab252":p(()=>d(()=>import("./algorithm.html.8d44122f.js"),["assets/algorithm.html.8d44122f.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-96d47244":p(()=>d(()=>import("./c.html.6387955f.js"),["assets/c.html.6387955f.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-64f5ed84":p(()=>d(()=>import("./ccc.html.bf391d30.js"),["assets/ccc.html.bf391d30.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-1d705569":p(()=>d(()=>import("./go.html.dbab658a.js"),["assets/go.html.dbab658a.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-80075a2c":p(()=>d(()=>import("./lanqiaobei.html.e24944e8.js"),["assets/lanqiaobei.html.e24944e8.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-6914dc26":p(()=>d(()=>import("./os.html.781c26b2.js"),["assets/os.html.781c26b2.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-3ebce416":p(()=>d(()=>import("./python.html.6ba47e37.js"),["assets/python.html.6ba47e37.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-6713c6ee":p(()=>d(()=>import("./qianduan.html.ef57d5d5.js"),["assets/qianduan.html.ef57d5d5.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-6789c688":p(()=>d(()=>import("./index.html.96eac070.js"),["assets/index.html.96eac070.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-459170da":p(()=>d(()=>import("./java-mianshi-zhinan.html.9c0ece4d.js"),["assets/java-mianshi-zhinan.html.9c0ece4d.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-00f81024":p(()=>d(()=>import("./index.html.bc31ce34.js"),["assets/index.html.bc31ce34.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-f6116100":p(()=>d(()=>import("./jibenjieshao.html.6a5f31db.js"),["assets/jibenjieshao.html.6a5f31db.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-089862ea":p(()=>d(()=>import("./mysql.html.1afcd596.js"),["assets/mysql.html.1afcd596.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-617d67b6":p(()=>d(()=>import("./collection.html.e1c47b4b.js"),["assets/collection.html.e1c47b4b.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-e5434cc0":p(()=>d(()=>import("./javase.html.4c6f74ba.js"),["assets/javase.html.4c6f74ba.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-39f8d868":p(()=>d(()=>import("./javathread.html.9fc70ce0.js"),["assets/javathread.html.9fc70ce0.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-35406b06":p(()=>d(()=>import("./jvm.html.c049e00d.js"),["assets/jvm.html.c049e00d.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-7990f3ea":p(()=>d(()=>import("./mybatis.html.41ff93f4.js"),["assets/mybatis.html.41ff93f4.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-7897c568":p(()=>d(()=>import("./nixi.html.de6f9361.js"),["assets/nixi.html.de6f9361.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-6f6524a3":p(()=>d(()=>import("./redis.html.bcbe4235.js"),["assets/redis.html.bcbe4235.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-02987727":p(()=>d(()=>import("./spring.html.40b7b2ff.js"),["assets/spring.html.40b7b2ff.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-c16116c6":p(()=>d(()=>import("./jvm.html.375475cb.js"),["assets/jvm.html.375475cb.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-39e4032a":p(()=>d(()=>import("./thread.html.4fcef02c.js"),["assets/thread.html.4fcef02c.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-6775b565":p(()=>d(()=>import("./yitiaolong.html.277dddb2.js"),["assets/yitiaolong.html.277dddb2.js","assets/plugin-vue_export-helper.21dcd24c.js"])),"v-3706649a":p(()=>d(()=>import("./404.html.6cb935de.js"),["assets/404.html.6cb935de.js","assets/plugin-vue_export-helper.21dcd24c.js"]))},nv={"404":p(()=>d(()=>import("./404.c61acaed.js"),["assets/404.c61acaed.js","assets/SkipLink.a2c3a90f.js"])),Layout:p(()=>d(()=>import("./Layout.2f241dd5.js"),["assets/Layout.2f241dd5.js","assets/SkipLink.a2c3a90f.js"])),Slide:p(()=>d(()=>import("./Slide.39e63deb.js"),[]))};var su=ve(pf),uu=Zi({key:"",path:"",title:"",lang:"",frontmatter:{},excerpt:"",headers:[]}),xt=ve(uu),Qe=()=>xt;ka.webpackHot&&(__VUE_HMR_RUNTIME__.updatePageData=e=>{su.value[e.key]=()=>Promise.resolve(e),e.key===xt.value.key&&(xt.value=e)});var du=Symbol(""),Me=()=>{const e=Ne(du);if(!e)throw new Error("usePageFrontmatter() is called without provider.");return e},fu=Symbol(""),rv=()=>{const e=Ne(fu);if(!e)throw new Error("usePageHead() is called without provider.");return e},ov=Symbol(""),mu=Symbol(""),da=()=>{const e=Ne(mu);if(!e)throw new Error("usePageLang() is called without provider.");return e},fa=Symbol(""),dn=()=>{const e=Ne(fa);if(!e)throw new Error("useRouteLocale() is called without provider.");return e},Bt=ve(Wh),ma=()=>Bt;ka.webpackHot&&(__VUE_HMR_RUNTIME__.updateSiteData=e=>{Bt.value=e});var hu=Symbol(""),Lo=()=>{const e=Ne(hu);if(!e)throw new Error("useSiteLocaleData() is called without provider.");return e},iv=Symbol(""),en=sn({resolvePageData:async e=>{const t=su.value[e],n=await(t==null?void 0:t());return n!=null?n:uu},resolvePageFrontmatter:e=>e.frontmatter,resolvePageHead:(e,t,n)=>{const r=De(t.description)?t.description:n.description,o=[...ae(t.head)?t.head:[],...n.head,["title",{},e],["meta",{name:"description",content:r}]];return Yh(o)},resolvePageHeadTitle:(e,t)=>`${e.title?`${e.title} | `:""}${t.title}`,resolvePageLang:e=>e.lang||"en",resolveRouteLocale:(e,t)=>ev(e,t),resolveSiteLocaleData:(e,t)=>le(le({},e),e.locales[t])}),vu=oe({name:"ClientOnly",setup(e,t){const n=ve(!1);return Ce(()=>{n.value=!0}),()=>{var r,o;return n.value?(o=(r=t.slots).default)==null?void 0:o.call(r):null}}}),pu=oe({name:"Content",props:{pageKey:{type:String,required:!1,default:""}},setup(e){const t=Qe(),n=H(()=>cu[e.pageKey||t.value.key]);return()=>n.value?v(n.value):v("div","404 Not Found")}}),bl=oe({name:"Vuepress",setup(){const e=Qe(),t=H(()=>{let n;if(e.value.path){const r=e.value.frontmatter.layout;De(r)?n=r:n="Layout"}else n="404";return nv[n]||Ve(n,!1)});return()=>v(t.value)}}),Wt=e=>un(e)?e:`${ma().value.base}${lu(e)}`;var av={},vt=e=>e;const _u=({type:e="info",text:t="",vertical:n="top",color:r},{slots:o})=>{var i;return v("span",{class:["badge",e,{diy:r}],style:le({verticalAlign:n},r?{backgroundColor:r}:{})},t||((i=o.default)==null?void 0:i.call(o)))};_u.displayName="Badge";const gu=({icon:e="",color:t,size:n})=>e?v("span",{class:["icon",`iconfont icon-${e}`],style:le(le({},t?{color:t}:{}),n?{"font-size":`${n}px`}:{})}):null;gu.displayName="FontIcon";function Ao(e){return Sf()?(Cf(e),!0):!1}var yl;const kr=typeof window!="undefined",lv=e=>typeof e=="string",Fo=()=>{},El=kr&&((yl=window==null?void 0:window.navigator)==null?void 0:yl.userAgent)&&/iP(ad|hone|od)/.test(window.navigator.userAgent);function ha(e,t){function n(...r){e(()=>t.apply(this,r),{fn:t,thisArg:this,args:r})}return n}const bu=e=>e();function cv(e,t={}){let n,r;return i=>{const a=Ge(e),l=Ge(t.maxWait);if(n&&clearTimeout(n),a<=0||l!==void 0&&l<=0)return r&&(clearTimeout(r),r=null),i();l&&!r&&(r=setTimeout(()=>{n&&clearTimeout(n),r=null,i()},l)),n=setTimeout(()=>{r&&clearTimeout(r),r=null,i()},a)}}function sv(e,t=!0,n=!0){let r=0,o,i=!0;const a=()=>{o&&(clearTimeout(o),o=void 0)};return c=>{const u=Ge(e),s=Date.now()-r;if(a(),u<=0)return r=Date.now(),c();s>u&&(n||!i)?(r=Date.now(),c()):t&&(o=setTimeout(()=>{r=Date.now(),i=!0,a(),c()},u)),!n&&!o&&(o=setTimeout(()=>i=!0,u)),i=!1}}function uv(e=bu){const t=ve(!0);function n(){t.value=!1}function r(){t.value=!0}return{isActive:t,pause:n,resume:r,eventFilter:(...i)=>{t.value&&e(...i)}}}function dv(e,t=200,n={}){return ha(cv(t,n),e)}function fv(e,t=200,n=!0,r=!0){return ha(sv(t,n,r),e)}function mv(e,t=!0){Io()?Vs(e):t?e():ra(e)}var Ol=Object.getOwnPropertySymbols,hv=Object.prototype.hasOwnProperty,vv=Object.prototype.propertyIsEnumerable,pv=(e,t)=>{var n={};for(var r in e)hv.call(e,r)&&t.indexOf(r)<0&&(n[r]=e[r]);if(e!=null&&Ol)for(var r of Ol(e))t.indexOf(r)<0&&vv.call(e,r)&&(n[r]=e[r]);return n};function _v(e,t,n={}){const r=n,{eventFilter:o=bu}=r,i=pv(r,["eventFilter"]);return je(e,ha(o,t),i)}var gv=Object.defineProperty,bv=Object.defineProperties,yv=Object.getOwnPropertyDescriptors,so=Object.getOwnPropertySymbols,yu=Object.prototype.hasOwnProperty,Eu=Object.prototype.propertyIsEnumerable,wl=(e,t,n)=>t in e?gv(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n,Ev=(e,t)=>{for(var n in t||(t={}))yu.call(t,n)&&wl(e,n,t[n]);if(so)for(var n of so(t))Eu.call(t,n)&&wl(e,n,t[n]);return e},Ov=(e,t)=>bv(e,yv(t)),wv=(e,t)=>{var n={};for(var r in e)yu.call(e,r)&&t.indexOf(r)<0&&(n[r]=e[r]);if(e!=null&&so)for(var r of so(e))t.indexOf(r)<0&&Eu.call(e,r)&&(n[r]=e[r]);return n};function Tv(e,t,n={}){const r=n,{eventFilter:o}=r,i=wv(r,["eventFilter"]),{eventFilter:a,pause:l,resume:c,isActive:u}=uv(o);return{stop:_v(e,t,Ov(Ev({},i),{eventFilter:a})),pause:l,resume:c,isActive:u}}function ir(e){var t;const n=Ge(e);return(t=n==null?void 0:n.$el)!=null?t:n}const yr=kr?window:void 0,xv=kr?window.document:void 0;kr&&window.navigator;kr&&window.location;function ht(...e){let t,n,r,o;if(lv(e[0])?([n,r,o]=e,t=yr):[t,n,r,o]=e,!t)return Fo;let i=Fo;const a=je(()=>ir(t),c=>{i(),c&&(c.addEventListener(n,r,o),i=()=>{c.removeEventListener(n,r,o),i=Fo})},{immediate:!0,flush:"post"}),l=()=>{a(),i()};return Ao(l),l}function _2(e,t,n={}){const{window:r=yr,ignore:o,capture:i=!0}=n;if(!r)return;const a=ve(!0);let l;const c=f=>{r.clearTimeout(l);const m=ir(e),h=f.composedPath();!m||m===f.target||h.includes(m)||!a.value||o&&o.length>0&&o.some(b=>{const y=ir(b);return y&&(f.target===y||h.includes(y))})||t(f)},u=[ht(r,"click",c,{passive:!0,capture:i}),ht(r,"pointerdown",f=>{const m=ir(e);a.value=!!m&&!f.composedPath().includes(m)},{passive:!0}),ht(r,"pointerup",f=>{l=r.setTimeout(()=>c(f),50)},{passive:!0})];return()=>u.forEach(f=>f())}function Pv(e,t={}){const{window:n=yr}=t,r=Boolean(n&&"matchMedia"in n);let o;const i=ve(!1),a=()=>{!r||(o||(o=n.matchMedia(e)),i.value=o.matches)};return mv(()=>{a(),o&&("addEventListener"in o?o.addEventListener("change",a):o.addListener(a),Ao(()=>{"removeEventListener"in o?o.removeEventListener("change",a):o.removeListener(a)}))}),i}const bi=typeof globalThis!="undefined"?globalThis:typeof window!="undefined"?window:typeof global!="undefined"?global:typeof self!="undefined"?self:{},yi="__vueuse_ssr_handlers__";bi[yi]=bi[yi]||{};const Iv=bi[yi];function Lv(e,t){return Iv[e]||t}function Av(e){return e==null?"any":e instanceof Set?"set":e instanceof Map?"map":e instanceof Date?"date":typeof e=="boolean"?"boolean":typeof e=="string"?"string":typeof e=="object"||Array.isArray(e)?"object":Number.isNaN(e)?"any":"number"}const Dv={boolean:{read:e=>e==="true",write:e=>String(e)},object:{read:e=>JSON.parse(e),write:e=>JSON.stringify(e)},number:{read:e=>Number.parseFloat(e),write:e=>String(e)},any:{read:e=>e,write:e=>String(e)},string:{read:e=>e,write:e=>String(e)},map:{read:e=>new Map(JSON.parse(e)),write:e=>JSON.stringify(Array.from(e.entries()))},set:{read:e=>new Set(JSON.parse(e)),write:e=>JSON.stringify(Array.from(e))},date:{read:e=>new Date(e),write:e=>e.toISOString()}};function jv(e,t,n,r={}){var o;const{flush:i="pre",deep:a=!0,listenToStorageChanges:l=!0,writeDefaults:c=!0,shallow:u,window:s=yr,eventFilter:f,onError:m=j=>{console.error(j)}}=r,h=(u?ys:ve)(t);if(!n)try{n=Lv("getDefaultStorage",()=>{var j;return(j=yr)==null?void 0:j.localStorage})()}catch(j){m(j)}if(!n)return h;const b=Ge(t),y=Av(b),w=(o=r.serializer)!=null?o:Dv[y],{pause:g,resume:E}=Tv(h,()=>x(h.value),{flush:i,deep:a,eventFilter:f});return s&&l&&ht(s,"storage",I),I(),h;function x(j){try{j==null?n.removeItem(e):n.setItem(e,w.write(j))}catch(D){m(D)}}function P(j){if(!(j&&j.key!==e)){g();try{const D=j?j.newValue:n.getItem(e);return D==null?(c&&b!==null&&n.setItem(e,w.write(b)),b):typeof D!="string"?D:w.read(D)}catch(D){m(D)}finally{E()}}}function I(j){j&&j.key!==e||(h.value=P(j))}}function kv(e){return Pv("(prefers-color-scheme: dark)",e)}const Tl=[["requestFullscreen","exitFullscreen","fullscreenElement","fullscreenEnabled","fullscreenchange","fullscreenerror"],["webkitRequestFullscreen","webkitExitFullscreen","webkitFullscreenElement","webkitFullscreenEnabled","webkitfullscreenchange","webkitfullscreenerror"],["webkitRequestFullScreen","webkitCancelFullScreen","webkitCurrentFullScreenElement","webkitCancelFullScreen","webkitfullscreenchange","webkitfullscreenerror"],["mozRequestFullScreen","mozCancelFullScreen","mozFullScreenElement","mozFullScreenEnabled","mozfullscreenchange","mozfullscreenerror"],["msRequestFullscreen","msExitFullscreen","msFullscreenElement","msFullscreenEnabled","MSFullscreenChange","MSFullscreenError"]];function va(e,t={}){const{document:n=xv,autoExit:r=!1}=t,o=e||(n==null?void 0:n.querySelector("html")),i=ve(!1);let a=!1,l=Tl[0];if(!n)a=!1;else for(const y of Tl)if(y[1]in n){l=y,a=!0;break}const[c,u,s,,f]=l;async function m(){!a||(n!=null&&n[s]&&await n[u](),i.value=!1)}async function h(){if(!a)return;await m();const y=ir(o);y&&(await y[c](),i.value=!0)}async function b(){i.value?await m():await h()}return n&&ht(n,f,()=>{i.value=!!(n!=null&&n[s])},!1),r&&Ao(m),{isSupported:a,isFullscreen:i,enter:h,exit:m,toggle:b}}var xl;(function(e){e.UP="UP",e.RIGHT="RIGHT",e.DOWN="DOWN",e.LEFT="LEFT",e.NONE="NONE"})(xl||(xl={}));function Rv(e){const t=e||window.event;return t.touches.length>1?!0:(t.preventDefault&&t.preventDefault(),!1)}function Sv(e,t=!1){const n=ve(t);let r=null,o;je(()=>Ge(e),l=>{if(l){const c=l;o=c.style.overflow,n.value&&(c.style.overflow="hidden")}},{immediate:!0});const i=()=>{const l=Ge(e);!l||n.value||(El&&(r=ht(l,"touchmove",Rv,{passive:!1})),l.style.overflow="hidden",n.value=!0)},a=()=>{const l=Ge(e);!l||!n.value||(El&&(r==null||r()),l.style.overflow=o,n.value=!1)};return Ao(a),H({get(){return n.value},set(l){l?i():a()}})}const Cv={blog:{intro:"/about-the-author/",sidebarDisplay:"mobile",avatar:"/assets/icon/itwanger-282.png",description:"\u6CA1\u6709\u4EC0\u4E48\u4F7F\u6211\u505C\u7559\u2014\u2014\u9664\u4E86\u76EE\u7684\uFF0C\u7EB5\u7136\u5CB8\u65C1\u6709\u73AB\u7470\u3001\u6709\u7EFF\u836B\u3001\u6709\u5B81\u9759\u7684\u6E2F\u6E7E\uFF0C\u6211\u662F\u4E0D\u7CFB\u4E4B\u821F\u3002",medias:{Zhihu:"https://www.zhihu.com/people/cmower",Github:"https://github.com/itwanger",Gitee:"https://gitee.com/itwanger"}},encrypt:{},pure:!1,darkmode:"switch",themeColor:!1,fullscreen:!1,locales:{"/":{lang:"zh-CN",navbarLocales:{langName:"\u7B80\u4F53\u4E2D\u6587",selectLangText:"\u9009\u62E9\u8BED\u8A00",selectLangAriaLabel:"\u9009\u62E9\u8BED\u8A00"},metaLocales:{author:"\u4F5C\u8005",date:"\u5199\u4F5C\u65E5\u671F",origin:"\u539F\u521B",views:"\u8BBF\u95EE\u91CF",category:"\u5206\u7C7B",tag:"\u6807\u7B7E",readingTime:"\u9605\u8BFB\u65F6\u95F4",words:"\u5B57\u6570",toc:"\u6B64\u9875\u5185\u5BB9",prev:"\u4E0A\u4E00\u9875",next:"\u4E0B\u4E00\u9875",lastUpdated:"\u4E0A\u6B21\u7F16\u8F91\u4E8E",contributors:"\u8D21\u732E\u8005",editLink:"\u7F16\u8F91\u6B64\u9875"},outlookLocales:{themeColor:"\u4E3B\u9898\u8272",darkmode:"\u5916\u89C2",fullscreen:"\u5168\u5C4F"},encryptLocales:{title:"\u6587\u7AE0\u5DF2\u52A0\u5BC6",placeholder:"\u8F93\u5165\u5BC6\u7801",remember:"\u8BB0\u4F4F\u5BC6\u7801",errorHint:"\u8BF7\u8F93\u5165\u6B63\u786E\u7684\u5BC6\u7801"},routeLocales:{"404msg":["\u8FD9\u91CC\u4EC0\u4E48\u4E5F\u6CA1\u6709","\u6211\u4EEC\u662F\u600E\u4E48\u6765\u5230\u8FD9\u513F\u7684\uFF1F","\u8FD9 \u662F \u56DB \u96F6 \u56DB !","\u770B\u8D77\u6765\u4F60\u8BBF\u95EE\u4E86\u4E00\u4E2A\u5931\u6548\u7684\u94FE\u63A5"],back:"\u8FD4\u56DE\u4E0A\u4E00\u9875",home:"\u5E26\u6211\u56DE\u5BB6",openInNewWindow:"Open in new window"},blog:{},repoDisplay:!0,navbarIcon:!0,navbarAutoHide:"mobile",hideSiteNameonMobile:!0,sidebar:{"/zhishixingqiu/":["java-mianshi-zhinan","readme.md"],"/download/":["java","pdf","learn-jianyi","nicearticle","history"],"/xuexiluxian/":[{text:"Java\u5B66\u4E60\u8DEF\u7EBF",prefix:"java/",collapsable:!0,children:["yitiaolong","thread","jvm"]},"c.md","ccc.md","python","go","os","qianduan","lanqiaobei","algorithm"],"/sidebar/sanfene/":[{text:"Java \u57FA\u7840",link:"javase.md"},{text:"Java \u96C6\u5408\u6846\u67B6",link:"collection.md"},{text:"Java \u5E76\u53D1\u7F16\u7A0B",link:"javathread.md"},{text:"Java \u865A\u62DF\u673A",link:"jvm.md"},{text:"Spring",link:"spring.md"},{text:"Redis",link:"redis.md"},"mybatis.md"],"/":[{text:"\u4E00\u3001\u524D\u8A00",link:"home.md"},{text:"\u4E8C\u3001Java\u6838\u5FC3",collapsable:!0,children:[{prefix:"overview/",text:"2.1 Java\u6982\u8FF0",collapsable:!0,children:["what-is-java",{text:"\u7F16\u5199\u7B2C\u4E00\u4E2A Java \u7A0B\u5E8F",link:"hello-world"}]},{text:"2.2 Java\u57FA\u7840\u8BED\u6CD5",collapsable:!0,children:[{text:"\u57FA\u672C\u6570\u636E\u7C7B\u578B",link:"basic-grammar/basic-data-type"},{text:"\u6D41\u7A0B\u63A7\u5236\u8BED\u53E5",link:"basic-grammar/flow-control"},{text:"\u8FD0\u7B97\u7B26",link:"basic-grammar/operator"},{text:"\u6CE8\u91CA",link:"basic-grammar/javadoc"},{text:"\u5173\u952E\u5B57",link:"basic-extra-meal/48-keywords"},{text:"\u547D\u540D\u89C4\u8303",link:"basic-extra-meal/java-naming"}]},{text:"2.3 \u9762\u5411\u5BF9\u8C61\u7F16\u7A0B",collapsable:!0,children:[{text:"\u5BF9\u8C61\u548C\u7C7B",link:"oo/object-class"},{text:"\u53D8\u91CF",link:"oo/var"},{text:"\u65B9\u6CD5",link:"oo/method"},{text:"\u6784\u9020\u65B9\u6CD5",link:"oo/construct"},"nice-article/bokeyuan-jianxijavazhongdifangwenquanxiankongzhi",{text:"\u4EE3\u7801\u521D\u59CB\u5316\u5757",link:"oo/code-init"},{text:"\u62BD\u8C61\u7C7B",link:"oo/abstract"},{text:"\u63A5\u53E3",link:"oo/interface"},{text:"\u5185\u90E8\u7C7B",link:"oo/inner-class"},{text:"static",link:"oo/static"},{text:"this \u548C super",link:"oo/this-super"},{text:"final",link:"oo/final"},{text:"instanceof",link:"oo/instanceof"},{text:"\u4E0D\u53EF\u53D8\u5BF9\u8C61",link:"basic-extra-meal/immutable"},{text:"\u53EF\u53D8\u53C2\u6570",link:"basic-extra-meal/varables"},{text:"\u6CDB\u578B",link:"basic-extra-meal/generic"},{text:"\u6CE8\u89E3",link:"basic-extra-meal/annotation"},{text:"\u679A\u4E3E",link:"basic-extra-meal/enum"},{text:"\u53CD\u5C04",link:"basic-extra-meal/fanshe"}]},{text:"2.4 \u5B57\u7B26\u4E32&\u6570\u7EC4",collapsable:!0,children:[{text:"\u5B57\u7B26\u4E32\u4E3A\u4EC0\u4E48\u662F\u4E0D\u53EF\u53D8\u7684",link:"string/immutable"},{text:"\u5B57\u7B26\u4E32\u5E38\u91CF\u6C60",link:"string/constant-pool"},{text:" String#intern",link:"string/intern"},{text:"\u5B57\u7B26\u4E32\u6BD4\u8F83",link:"string/equals"},{text:"\u5B57\u7B26\u4E32\u62FC\u63A5",link:"string/join"},{text:"\u5B57\u7B26\u4E32\u5206\u5272",link:"string/split"},{text:"\u6570\u7EC4",link:"array/array"},{text:"\u6253\u5370\u6570\u7EC4",link:"array/print"}]},{text:"2.5 \u96C6\u5408\u6846\u67B6\uFF08\u5BB9\u5668\uFF09",collapsable:!0,children:[{text:"\u6982\u8FF0",link:"collection/gailan"},{text:"ArrayList",link:"collection/arraylist"},{text:"LinkedList",link:"collection/linkedlist"},{text:"ArrayList\u548CLinkedList\u7684\u533A\u522B",link:"collection/list-war-2"},{text:"Iterator\u548CIterable",link:"collection/iterator-iterable"},{text:"fail-fast",link:"collection/fail-fast"},{text:"HashMap",link:"collection/hashmap"}]},{text:"2.6 IO",collapsable:!0,prefix:"io/",children:[{text:"\u6982\u89C8",link:"shangtou"},{text:"BIO\u3001NIO\u548CAIO",link:"BIONIOAIO"}]},{text:"2.7 \u5F02\u5E38\u5904\u7406",collapsable:!0,prefix:"exception/",children:[{text:"\u6982\u89C8",link:"gailan"},{text:"try-with-resouces",link:"try-with-resouces"},{text:"\u6700\u4F73\u5B9E\u8DF5",link:"shijian"},{text:"NullPointerException",link:"npe"}]},{text:"2.8 \u5E38\u7528\u5DE5\u5177\u7C7B",collapsable:!0,prefix:"common-tool/",children:[{text:"Arrays",link:"arrays"},{text:"Collections",link:"collections"},{text:"Hutool",link:"hutool"},{text:"Guava",link:"guava"}]},{text:"2.9 Java\u65B0\u7279\u6027",prefix:"java8/",collapsable:!0,children:[{text:"Stream",link:"stream"},{text:"Optional",link:"optional"},{text:"Lambda",link:"Lambda"}]},{text:"2.10 Java\u91CD\u8981\u77E5\u8BC6\u70B9",prefix:"basic-extra-meal/",collapsable:!0,children:[{text:"Unicode\u548CUTF-8\u7F16\u7801",link:"java-unicode"},{text:"new Integer\u548CInteger.valueOf\u533A\u522B",link:"int-cache"},{text:"\u62C6\u7BB1\u548C\u88C5\u7BB1",link:"box"},{text:"\u6D45\u62F7\u8D1D\u4E0E\u6DF1\u62F7\u8D1D",link:"deep-copy"},{text:"\u6DF1\u5165\u7406\u89E3Java\u4E2D\u7684hashCode\u65B9\u6CD5",link:"hashcode"},{text:"\u91CD\u5199equals\u65F6\u4E3A\u4EC0\u4E48\u8981\u91CD\u5199hashCode",link:"equals-hashcode"},{text:"\u91CD\u5199\u548C\u91CD\u8F7D\u7684\u533A\u522B",link:"override-overload"},{text:"\u91CD\u5199\u65F6\u5E94\u5F53\u9075\u5B88\u768411\u6761\u89C4\u5219",link:"Overriding"},{text:"Java\u5230\u5E95\u662F\u503C\u4F20\u9012\u8FD8\u662F\u5F15\u7528\u4F20\u9012",link:"pass-by-value"},{text:"Java\u4E3A\u4EC0\u4E48\u4E0D\u80FD\u5B9E\u73B0\u771F\u6B63\u7684\u6CDB\u578B",link:"true-generic"},{text:"Comparable\u548CComparator\u7684\u533A\u522B",link:"comparable-omparator"},{text:"JDK9\u4E2DString\u4E3A\u4EC0\u4E48\u7531char[]\u6539\u6210byte[]",link:"jdk9-char-byte-string"},{text:"JDK\u6E90\u7801\u65E0\u9650\u5FAA\u73AF\u7528for(;;)\u8FD8\u662Fwhile(true)",link:"jdk-while-for-wuxian-xunhuan"},{text:"\u5148\u6709Class\u8FD8\u662F\u5148\u6709Object",link:"class-object"},{text:"instanceof\u5173\u952E\u5B57\u662F\u5982\u4F55\u5B9E\u73B0\u7684",link:"instanceof-jvm"}]},{text:"2.11 \u5E76\u53D1\u7F16\u7A0B",collapsable:!0,prefix:"thread/",children:[{text:"\u521B\u5EFAJava\u7EBF\u7A0B\u76843\u79CD\u65B9\u5F0F",link:"wangzhe-thread"},{text:"\u7EBF\u7A0B\u76846\u79CD\u72B6\u6001\u53CA\u5207\u6362",link:"thread-state-and-method"},{text:"\u7EBF\u7A0B\u7EC4\u548C\u7EBF\u7A0B\u4F18\u5148\u7EA7",link:"thread-group-and-thread-priority"},{text:"\u8FDB\u7A0B\u4E0E\u7EBF\u7A0B\u7684\u533A\u522B",link:"why-need-thread"},{text:"\u5E76\u53D1\u7F16\u7A0B\u5E26\u6765\u4E86\u54EA\u4E9B\u95EE\u9898",link:"thread-bring-some-problem"},{text:"Java\u5185\u5B58\u6A21\u578B",link:"jmm"},{text:"volatile",link:"volatile"},{text:"synchronized",link:"synchronized"},{text:"CAS\u7684\u539F\u7406",link:"cas"},{text:"AQS\u8BE6\u89E3",link:"aqs"},{text:"\u9501",link:"lock"},{text:"\u91CD\u5165\u9501ReentrantLock",link:"reentrantLock"},{text:"\u8BFB\u5199\u9501ReentrantReadWriteLock",link:"ReentrantReadWriteLock"},{text:"\u7EBF\u7A0B\u534F\u4F5C\u7C7BCondition",link:"condition"},{text:"\u7EBF\u7A0B\u963B\u585E\u5524\u9192\u7C7BLockSupport",link:"LockSupport"},{text:"\u5E76\u53D1\u96C6\u5408\u5BB9\u5668",link:"map"},{text:"ConcurrentHashMap",link:"ConcurrentHashMap"},{text:"ConcurrentLinkedQueue",link:"ConcurrentLinkedQueue"},{text:"CopyOnWriteArrayList",link:"CopyOnWriteArrayList"},{text:"ThreadLocal",link:"ThreadLocal"},{text:"BlockingQueue",link:"BlockingQueue"},{text:"\u7EBF\u7A0B\u6C60",link:"pool"},{text:"\u8BA1\u5212\u4EFB\u52A1",link:"ScheduledThreadPoolExecutor"},{text:"\u539F\u5B50\u64CD\u4F5C\u7C7B",link:"atomic"},{text:"\u901A\u4FE1\u5DE5\u5177\u7C7BCountDownLatch",link:"CountDownLatch"},{text:"Fork/Join\u6846\u67B6",link:"fork-join"},{text:"\u751F\u4EA7\u8005-\u6D88\u8D39\u8005\u6A21\u5F0F",link:"shengchanzhe-xiaofeizhe"}]},{text:"2.12 JVM",prefix:"jvm/",collapsable:!0,children:[{text:"JVM\u5230\u5E95\u662F\u4EC0\u4E48\uFF1F",link:"what-is-jvm"},{text:"JVM\u5230\u5E95\u662F\u5982\u4F55\u8FD0\u884CJava\u4EE3\u7801\u7684",link:"how-run-java-code"},{text:"\u7C7B\u52A0\u8F7D\u673A\u5236",link:"class-load"},{text:"\u8BE6\u89E3Java\u7684\u7C7B\u6587\u4EF6\u7ED3\u6784",link:"class-file-jiegou"},{text:"\u4ECEjavap\u7684\u89D2\u5EA6\u8F7B\u677E\u770B\u61C2\u5B57\u8282\u7801",link:"bytecode"},{text:"\u5B57\u8282\u7801\u6307\u4EE4\u8BE6\u89E3",link:"zijiema-zhiling"},{text:"\u865A\u62DF\u673A\u662F\u5982\u4F55\u6267\u884C\u5B57\u8282\u7801\u6307\u4EE4\u7684",link:"how-jvm-run-zijiema-zhiling"},{text:"HSDB\uFF08Hotspot Debugger\uFF09",link:"hsdb"},{text:"\u53F2\u4E0A\u6700\u901A\u4FD7\u6613\u61C2\u7684ASM\u6559\u7A0B",link:"asm"},{text:"\u81EA\u5DF1\u7F16\u8BD1JDK",link:"compile-jdk"},{text:"\u6DF1\u5165\u7406\u89E3JVM\u7684\u5185\u5B58\u7ED3\u6784",link:"neicun-jiegou"},{text:"Java \u521B\u5EFA\u7684\u5BF9\u8C61\u5230\u5E95\u653E\u5728\u54EA",link:"whereis-the-object"},{text:"\u4ECE\u5934\u5230\u5C3E\u8BF4\u4E00\u6B21Java\u5783\u573E\u56DE\u6536",link:"gc"},{text:"\u56FE\u89E3Java\u7684\u5783\u573E\u56DE\u6536\u673A\u5236",link:"tujie-gc"},{text:"Java\u95EE\u9898\u8BCA\u65AD\u548C\u6392\u67E5\u5DE5\u5177",link:"problem-tools"},{text:"JIT\u539F\u7406\u89E3\u6790\u53CA\u5B9E\u8DF5",link:"jit"},{text:"\u5185\u5B58\u6EA2\u51FA\u6392\u67E5\u4F18\u5316\u5B9E\u6218",link:"oom"},{text:"CPU 100% \u6392\u67E5\u4F18\u5316\u5B9E\u8DF5",link:"cpu-percent-100"},{text:"JVM \u6838\u5FC3\u77E5\u8BC6\u70B9\u603B\u7ED3",link:"zongjie"}]}]},{text:"\u4E09\u3001Java\u4F01\u4E1A\u7EA7\u5F00\u53D1",collapsable:!0,children:[{text:"3.1 \u5F00\u53D1\u5DE5\u5177",collapsable:!0,children:["maven/maven.md","git/git-qiyuan.md","nginx/nginx.md"]},{text:"3.2 IDE/\u7F16\u8F91\u5668",collapsable:!0,children:["ide/4-debug-skill.md"]},{text:"3.3 Spring",collapsable:!0,children:[{text:"Spring AOP\u626B\u76F2",link:"springboot/aop-log"},{text:"Spring IoC\u626B\u76F2",link:"springboot/ioc"}]},{text:"3.4 SpringBoot",collapsable:!0,children:[{text:"\u642D\u5EFA\u7B2C\u4E00\u4E2ASpring Boot\u9879\u76EE",link:"springboot/initializr"},{text:"\u6574\u5408MySQL\u548CDruid",link:"springboot/mysql-druid"},{text:"\u6574\u5408JPA",link:"springboot/jpa"},{text:"\u6574\u5408Thymeleaf",link:"springboot/thymeleaf"},{text:"\u5F00\u542F\u4E8B\u52A1\u652F\u6301",link:"springboot/transaction"},{text:"\u8FC7\u6EE4\u5668\u3001\u62E6\u622A\u5668\u3001\u76D1\u542C\u5668",link:"springboot/Filter-Interceptor-Listener"},{text:"\u6574\u5408Redis\u5B9E\u73B0\u7F13\u5B58",link:"redis/redis-springboot"},{text:"\u6574\u5408Logback",link:"springboot/logback"},{text:"\u6574\u5408Swagger-UI",link:"springboot/swagger"},{text:"\u6574\u5408Knife4j",link:"gongju/knife4j"},{text:"\u6574\u5408SpringTask",link:"springboot/springtask"},{text:"\u6574\u5408MyBatis-Plus AutoGenerator",link:"kaiyuan/auto-generator"},"springboot/macos-codingmore-run","springboot/windows-codingmore-run"]},{text:"3.5 \u8F85\u52A9\u5DE5\u5177",collapsable:!0,children:[{text:"\u9AD8\u903C\u683C\u7EC8\u7AEF\u5DE5\u5177Tabby",link:"gongju/tabby"},{text:"21\u4E16\u7EAA\u4EBA\u7528\u7684\u7EC8\u7AEF\u5DE5\u5177Warp",link:"gongju/warp"},{text:"Win\u547D\u4EE4\u884C\u8F6F\u4EF6\u7BA1\u7406\u5668Chocolatey",link:"gongju/choco"},{text:"\u6570\u636E\u5E93\u8BBE\u8BA1\u795E\u5668chiner",link:"gongju/chiner"},{text:"\u6570\u636E\u5E93\u64CD\u4F5C\u5DE5\u5177DBeaver",link:"gongju/DBeaver"},"gongju/baota-mianban.md"]},{text:"3.6 \u5F00\u6E90\u8F6E\u5B50",collapsable:!0,children:[{text:"HTTP\u8C03\u7528\u6846\u67B6Forest",link:"gongju/forest"},{text:"\u5355\u5143\u6D4B\u8BD5Junit",link:"gongju/junit"},{text:"\u963F\u91CC\u5F00\u6E90\u7684fastjson",link:"gongju/fastjson"},{text:"\u8C37\u6B4C\u5F00\u6E90\u7684Gson",link:"gongju/gson"},{text:"SpringBoot\u5185\u7F6E\u7684Jackson",link:"gongju/jackson"},{text:"\u65E5\u5FD7\u6846\u67B6\u7684\u9F3B\u7956Log4j",link:"gongju/log4j"},{text:"\u9AD8\u6027\u80FD\u65E5\u5FD7\u6846\u67B6Log4j2",link:"gongju/log4j2"},{text:"Spring Boot\u5185\u7F6E\u7684Logback",link:"gongju/logback"},{text:"\u65E5\u5FD7\u95E8\u9762SLF4J",link:"gongju/slf4j"}]},{text:"3.7 \u5206\u5E03\u5F0F",collapsable:!0,children:[{text:"Elasticsearch\u5165\u95E8",link:"elasticsearch/rumen"},{text:"\u804A\u804AZooKeeper",link:"zookeeper/jibenjieshao"},{text:"\u804A\u804A\u5FAE\u670D\u52A1\u7F51\u5173",link:"microservice/api-wangguan"}]},{text:"3.8 \u6D88\u606F\u961F\u5217",collapsable:!0,children:[{text:"RabbitMQ\u5165\u95E8",link:"mq/rabbitmq-rumen"},{text:"\u5982\u4F55\u4FDD\u969C\u6D88\u606F\u4E0D\u4E22\u5931",link:"mq/100-budiushi"}]}]},{text:"\u56DB\u3001\u6570\u636E\u5E93",collapsable:!0,children:[{text:"MySQL",collapsable:!0,children:[{text:"MySQL\u548CRedis\u6570\u636E\u4E00\u81F4\u6027",link:"mysql/redis-shuju-yizhixing"}]},{text:"Redis",collapsable:!0,children:[{text:"Redis\u5165\u95E8",link:"redis/rumen"},{text:"\u7F13\u5B58\u96EA\u5D29\u3001\u7A7F\u900F\u3001\u51FB\u7A7F",link:"redis/xuebeng-chuantou-jichuan"}]},{text:"MongoDB",collapsable:!0,children:["mongodb/rumen"]}]},{text:"\u4E94\u3001\u8BA1\u7B97\u673A\u57FA\u7840",collapsable:!0,prefix:"cs/",children:[{text:"\u8BA1\u7B97\u673A\u64CD\u4F5C\u7CFB\u7EDF",link:"os"},{text:"\u8BA1\u7B97\u673A\u7F51\u7EDC",link:"wangluo"}]},{text:"\u516D\u3001\u6C42\u804C\u9762\u8BD5",collapsable:!0,children:[{text:"\u9762\u8BD5\u9898\u96C6\u5408",collapsable:!0,children:["baguwen/java-basic-34","collection/hashmap-interview","mianjing/redis12question","nginx/40-interview"]},{text:"\u80CC\u8BF5\u7248\u516B\u80A1\u6587",collapsable:!0,children:["baguwen/java-basic","baguwen/java-thread","baguwen/jvm","sidebar/herongwei/mysql"]},{text:"\u57CE\u5E02\u9009\u62E9",prefix:"cityselect/",collapsable:!0,children:["beijing","chengdu","guangzhou","hangzhou","nanjing","qingdao","shenzhen","suzhou","xian","zhengzhou","jinan"]}]},{text:"\u4E03\u3001\u5B66\u4E60\u8D44\u6E90",collapsable:!0,children:[{text:"PDF\u4E0B\u8F7D",collapsable:!0,children:[{icon:"xiazai",link:"download/java.md"},{icon:"xiazai",link:"nice-article/weixin-bagwpdf.md"},{icon:"xiazai",link:"nice-article/weixin-shenrjcjavabfbchwjdhl.md"},{icon:"xiazai",link:"nice-article/weixin-githubxbkdjavajccjyh.md"},{icon:"xiazai",link:"nice-article/weixin-shejmsnb.md"},{icon:"xiazai",link:"nice-article/weixin-mozdsdzfjavableetcodetxxk.md"},{icon:"xiazai",link:"download/yuanyifeng-c-language.md"},{icon:"xiazai",link:"download/bat-shuati.md"},{icon:"xiazai",link:"download/weixin-piaolwzjztqdtskwlzfpdf.md"},{icon:"xiazai",link:"download/progit.md"},{icon:"xiazai",link:"download/jianli.md"}]},{text:"\u5B66\u4E60\u5EFA\u8BAE",collapsable:!0,prefix:"xuexijianyi/",children:["read-csapp","electron-information-engineering"]}]},{text:"\u516B\u3001\u77E5\u8BC6\u5E93\u642D\u5EFA",collapsable:!0,prefix:"szjy/",children:["buy-cloud-server","install-baota-mianban","buy-domain","record-domain","https-domain"]},{text:"\u4E5D\u3001\u8054\u7CFB\u4F5C\u8005",collapsable:!0,children:[{text:"\u5FC3\u8DEF\u5386\u7A0B",prefix:"about-the-author/",collapsable:!0,children:["bzhan-10wan","zhihu-1000wan","csdn-1000wan","readme.md"]}]}]},sidebarIcon:!0,headerDepth:2,author:{name:"\u6C89\u9ED8\u738B\u4E8C",url:"https://tobebetterjavaer.com"},logo:"http://cdn.tobebetterjavaer.com/tobebetterjavaer/images/logo-02.png",repo:"https://github.com/itwanger/toBeBetterJavaer",docsDir:"docs",docsBranch:"master",navbar:[{text:"\u8FDB\u9636\u4E4B\u8DEF",icon:"lujing",link:"/home.md"},{text:"\u661F\u7403\u4E13\u680F",icon:"Artboard",link:"/zhishixingqiu/java-mianshi-zhinan.md"},{text:"\u5B66\u4E60\u8DEF\u7EBF",icon:"luxian",link:"/xuexiluxian/"},{text:"B\u7AD9\u89C6\u9891",icon:"bzhan",link:"https://space.bilibili.com/513340480"},{text:"\u73CD\u85CF\u8D44\u6E90",icon:"youzhi",children:[{text:"Java\u7535\u5B50\u4E66\u4E0B\u8F7D",icon:"java",link:"/download/java.md"},{text:"\u9762\u6E23\u9006\u88AD",icon:"zhunbei",link:"/sidebar/sanfene/nixi.md"},{text:"\u4F18\u8D28\u6587\u7AE0",icon:"youzhi",link:"/download/nicearticle.md"},{text:"\u7F51\u7EDC\u65E5\u5FD7",icon:"rizhi",link:"/download/history.md"},{text:"\u56DE\u5230\u8FC7\u53BB",icon:"fanhuijiuban",link:"https://docsify.tobebetterjavaer.com/"}]}],footer:'\u8C6BICP\u59072021038026\u53F7-1\u8C6B\u516C\u7F51\u5B89\u5907 41030502000411\u53F7',displayFooter:!0,pageInfo:["Author","Original","Date","Category","Tag","ReadingTime"]}}},Ou=ve(Cv),pa=()=>Ou;ka.webpackHot&&(__VUE_HMR_RUNTIME__.updateThemeData=e=>{Ou.value=e});const wu=Symbol(""),Vv=()=>{const e=Ne(wu);if(!e)throw new Error("useThemeLocaleData() is called without provider.");return e},Mv=(e,t)=>{var n;return le(le({},e),(n=e.locales)==null?void 0:n[t])};const ke=({name:e="",color:t="currentColor"},{slots:n})=>{var r;return v("svg",{xmlns:"http://www.w3.org/2000/svg",class:["icon",`${e}-icon`],viewBox:"0 0 1024 1024",fill:t,"aria-label":`${e} icon`},(r=n.default)==null?void 0:r.call(n))};ke.displayName="IconBase";const Tu=(e,{slots:t})=>{var n;return((n=t.default)==null?void 0:n.call(t))||null},Er=e=>{const t=Io();return typeof(t==null?void 0:t.appContext.components)=="object"&&(e in t.appContext.components||lt(e)in t.appContext.components||Ar(lt(e))in t.appContext.components)},zn=e=>{const t=dn();return H(()=>e[t.value])},xu=(e,t)=>{let n=1;for(let r=0;r>6;return n+=n<<3,n^=n>>11,n%t},Pu=/#.*$/u,zv=e=>{const t=Pu.exec(e);return t?t[0]:""},Pl=e=>decodeURI(e).replace(Pu,"").replace(/(index)?\.(md|html)$/,""),_a=(e,t)=>{if(t===void 0)return!1;const n=Pl(e.path),r=Pl(t),o=zv(t);return o?o===e.hash&&(!r||n===r):n===r};class $v{constructor(){const t="message-container",n=document.getElementById(t);n?this.containerElement=n:(this.containerElement=document.createElement("div"),this.containerElement.id=t,document.body.appendChild(this.containerElement))}pop(t,n=2e3){const r=document.createElement("div");r.className="message move-in",r.innerHTML=t,this.containerElement.appendChild(r),n>0&&setTimeout(()=>{this.close(r)},n)}close(t){t.className=t.className.replace("move-in",""),t.className+="move-out",t.addEventListener("animationend",()=>{t.remove()})}}const ga=(e,...t)=>{const n=e.resolve(...t),r=n.matched[n.matched.length-1];if(!(r!=null&&r.redirect))return n;const{redirect:o}=r,i=typeof o=="function"?o(n):o,a=(l=>typeof l=="string")(i)?{path:i}:i;return ga(e,le({hash:n.hash,query:n.query,params:n.params},a))};var qo,rn=function(){var e=1e3,t=6e4,n=36e5,r="millisecond",o="second",i="minute",a="hour",l="day",c="week",u="month",s="quarter",f="year",m="date",h="Invalid Date",b=/^(\d{4})[-/]?(\d{1,2})?[-/]?(\d{0,2})[Tt\s]*(\d{1,2})?:?(\d{1,2})?:?(\d{1,2})?[.:]?(\d+)?$/,y=/\[([^\]]+)]|Y{1,4}|M{1,4}|D{1,2}|d{1,4}|H{1,2}|h{1,2}|a|A|m{1,2}|s{1,2}|Z{1,2}|SSS/g,w={name:"en",weekdays:"Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),months:"January_February_March_April_May_June_July_August_September_October_November_December".split("_")},g=function(q,A,R){var S=String(q);return!S||S.length>=A?q:""+Array(A+1-S.length).join(R)+q},E={s:g,z:function(q){var A=-q.utcOffset(),R=Math.abs(A),S=Math.floor(R/60),F=R%60;return(A<=0?"+":"-")+g(S,2,"0")+":"+g(F,2,"0")},m:function q(A,R){if(A.date()1)return q(Y[0])}else{var X=A.name;P[X]=A,F=X}return!S&&F&&(x=F),F||!S&&x},D=function(q,A){if(I(q))return q.clone();var R=typeof A=="object"?A:{};return R.date=q,R.args=arguments,new W(R)},k=E;k.l=j,k.i=I,k.w=function(q,A){return D(q,{locale:A.$L,utc:A.$u,x:A.$x,$offset:A.$offset})};var W=function(){function q(R){this.$L=j(R.locale,null,!0),this.parse(R)}var A=q.prototype;return A.parse=function(R){this.$d=function(S){var F=S.date,K=S.utc;if(F===null)return new Date(NaN);if(k.u(F))return new Date;if(F instanceof Date)return new Date(F);if(typeof F=="string"&&!/Z$/i.test(F)){var Y=F.match(b);if(Y){var X=Y[2]-1||0,fe=(Y[7]||"0").substring(0,3);return K?new Date(Date.UTC(Y[1],X,Y[3]||1,Y[4]||0,Y[5]||0,Y[6]||0,fe)):new Date(Y[1],X,Y[3]||1,Y[4]||0,Y[5]||0,Y[6]||0,fe)}}return new Date(F)}(R),this.$x=R.x||{},this.init()},A.init=function(){var R=this.$d;this.$y=R.getFullYear(),this.$M=R.getMonth(),this.$D=R.getDate(),this.$W=R.getDay(),this.$H=R.getHours(),this.$m=R.getMinutes(),this.$s=R.getSeconds(),this.$ms=R.getMilliseconds()},A.$utils=function(){return k},A.isValid=function(){return this.$d.toString()!==h},A.isSame=function(R,S){var F=D(R);return this.startOf(S)<=F&&F<=this.endOf(S)},A.isAfter=function(R,S){return D(R)=0?1:b.date()),w=h.year||b.year(),g=h.month>=0?h.month:h.year||h.day?0:b.month(),E=h.hour||0,x=h.minute||0,P=h.second||0,I=h.millisecond||0;return m?new Date(Date.UTC(w,g,y,E,x,P,I)):new Date(w,g,y,E,x,P,I)}return f},i=r.parse;r.parse=function(u){u.date=o.bind(this)(u),i.bind(this)(u)};var a=r.set,l=r.add,c=function(u,s,f,m){if(m===void 0&&(m=1),s instanceof Object){var h=Object.keys(s),b=this;return h.forEach(function(y){b=u.bind(b)(s[y]*m,y)}),b}return u.bind(this)(s*m,f)};r.set=function(u,s){return s=s===void 0?u:s,c.bind(this)(function(f,m){return a.bind(this)(m,f)},s,u)},r.add=function(u,s){return c.bind(this)(l,u,s)},r.subtract=function(u,s){return c.bind(this)(l,u,s,-1)}},Bv=function(){var e={year:0,month:1,day:2,hour:3,minute:4,second:5},t={};return function(n,r,o){var i,a=function(s,f,m){m===void 0&&(m={});var h=new Date(s),b=function(y,w){w===void 0&&(w={});var g=w.timeZoneName||"short",E=y+"|"+g,x=t[E];return x||(x=new Intl.DateTimeFormat("en-US",{hour12:!1,timeZone:y,year:"numeric",month:"2-digit",day:"2-digit",hour:"2-digit",minute:"2-digit",second:"2-digit",timeZoneName:g}),t[E]=x),x}(f,m);return b.formatToParts(h)},l=function(s,f){for(var m=a(s,f),h=[],b=0;b=0&&(h[E]=parseInt(g,10))}var x=h[3],P=x===24?0:x,I=h[0]+"-"+h[1]+"-"+h[2]+" "+P+":"+h[4]+":"+h[5]+":000",j=+s;return(o.utc(I).valueOf()-(j-=j%1e3))/6e4},c=r.prototype;c.tz=function(s,f){s===void 0&&(s=i);var m=this.utcOffset(),h=this.toDate(),b=h.toLocaleString("en-US",{timeZone:s}),y=Math.round((h-new Date(b))/1e3/60),w=o(b).$set("millisecond",this.$ms).utcOffset(15*-Math.round(h.getTimezoneOffset()/15)-y,!0);if(f){var g=w.utcOffset();w=w.add(m-g,"minute")}return w.$x.$timezone=s,w},c.offsetName=function(s){var f=this.$x.$timezone||o.tz.guess(),m=a(this.valueOf(),f,{timeZoneName:s}).find(function(h){return h.type.toLowerCase()==="timezonename"});return m&&m.value};var u=c.startOf;c.startOf=function(s,f){if(!this.$x||!this.$x.$timezone)return u.call(this,s,f);var m=o(this.format("YYYY-MM-DD HH:mm:ss:SSS"));return u.call(m,s,f).tz(this.$x.$timezone,!0)},o.tz=function(s,f,m){var h=m&&f,b=m||f||i,y=l(+o(),b);if(typeof s!="string")return o(s).tz(b);var w=function(P,I,j){var D=P-60*I*1e3,k=l(D,j);if(I===k)return[D,I];var W=l(D-=60*(k-I)*1e3,j);return k===W?[D,k]:[P-60*Math.min(k,W)*1e3,Math.max(k,W)]}(o.utc(s,h).valueOf(),y,b),g=w[0],E=w[1],x=o(g).utcOffset(E);return x.$x.$timezone=b,x},o.tz.guess=function(){return Intl.DateTimeFormat().resolvedOptions().timeZone},o.tz.setDefault=function(s){i=s}}}(),Fv=function(){var e="minute",t=/[+-]\d\d(?::?\d\d)?/g,n=/([+-]|\d\d)/g;return function(r,o,i){var a=o.prototype;i.utc=function(h){return new o({date:h,utc:!0,args:arguments})},a.utc=function(h){var b=i(this.toDate(),{locale:this.$L,utc:!0});return h?b.add(this.utcOffset(),e):b},a.local=function(){return i(this.toDate(),{locale:this.$L,utc:!1})};var l=a.parse;a.parse=function(h){h.utc&&(this.$u=!0),this.$utils().u(h.$offset)||(this.$offset=h.$offset),l.call(this,h)};var c=a.init;a.init=function(){if(this.$u){var h=this.$d;this.$y=h.getUTCFullYear(),this.$M=h.getUTCMonth(),this.$D=h.getUTCDate(),this.$W=h.getUTCDay(),this.$H=h.getUTCHours(),this.$m=h.getUTCMinutes(),this.$s=h.getUTCSeconds(),this.$ms=h.getUTCMilliseconds()}else c.call(this)};var u=a.utcOffset;a.utcOffset=function(h,b){var y=this.$utils().u;if(y(h))return this.$u?0:y(this.$offset)?u.call(this):this.$offset;if(typeof h=="string"&&(h=function(x){x===void 0&&(x="");var P=x.match(t);if(!P)return null;var I=(""+P[0]).match(n)||["-",0,0],j=I[0],D=60*+I[1]+ +I[2];return D===0?0:j==="+"?D:-D}(h),h===null))return this;var w=Math.abs(h)<=16?60*h:h,g=this;if(b)return g.$offset=w,g.$u=h===0,g;if(h!==0){var E=this.$u?this.toDate().getTimezoneOffset():-1*this.utcOffset();(g=this.local().add(w+E,e)).$offset=w,g.$x.$localOffset=E}else g=this.utc();return g};var s=a.format;a.format=function(h){var b=h||(this.$u?"YYYY-MM-DDTHH:mm:ss[Z]":"");return s.call(this,b)},a.valueOf=function(){var h=this.$utils().u(this.$offset)?0:this.$offset+(this.$x.$localOffset||this.$d.getTimezoneOffset());return this.$d.valueOf()-6e4*h},a.isUTC=function(){return!!this.$u},a.toISOString=function(){return this.toDate().toISOString()},a.toString=function(){return this.toDate().toUTCString()};var f=a.toDate;a.toDate=function(h){return h==="s"&&this.$offset?i(this.format("YYYY-MM-DD HH:mm:ss:SSS")).toDate():f.call(this)};var m=a.diff;a.diff=function(h,b,y){if(h&&this.$u===h.$u)return m.call(this,h,b,y);var w=this.local(),g=i(h).local();return m.call(w,g,b,y)}}}();rn.extend(Nv),rn.extend(Hv),rn.extend(Fv),rn.extend(Bv);const qv={name:"zh-cn",weekdays:"\u661F\u671F\u65E5_\u661F\u671F\u4E00_\u661F\u671F\u4E8C_\u661F\u671F\u4E09_\u661F\u671F\u56DB_\u661F\u671F\u4E94_\u661F\u671F\u516D".split("_"),weekdaysShort:"\u5468\u65E5_\u5468\u4E00_\u5468\u4E8C_\u5468\u4E09_\u5468\u56DB_\u5468\u4E94_\u5468\u516D".split("_"),weekdaysMin:"\u65E5_\u4E00_\u4E8C_\u4E09_\u56DB_\u4E94_\u516D".split("_"),months:"\u4E00\u6708_\u4E8C\u6708_\u4E09\u6708_\u56DB\u6708_\u4E94\u6708_\u516D\u6708_\u4E03\u6708_\u516B\u6708_\u4E5D\u6708_\u5341\u6708_\u5341\u4E00\u6708_\u5341\u4E8C\u6708".split("_"),monthsShort:"1\u6708_2\u6708_3\u6708_4\u6708_5\u6708_6\u6708_7\u6708_8\u6708_9\u6708_10\u6708_11\u6708_12\u6708".split("_"),ordinal:(e,t)=>t==="W"?`${e}\u5468`:`${e}\u65E5`,weekStart:1,yearStart:4,formats:{LT:"HH:mm",LTS:"HH:mm:ss",L:"YYYY/MM/DD",LL:"YYYY\u5E74M\u6708D\u65E5",LLL:"YYYY\u5E74M\u6708D\u65E5Ah\u70B9mm\u5206",LLLL:"YYYY\u5E74M\u6708D\u65E5ddddAh\u70B9mm\u5206",l:"YYYY/M/D",ll:"YYYY\u5E74M\u6708D\u65E5",lll:"YYYY\u5E74M\u6708D\u65E5 HH:mm",llll:"YYYY\u5E74M\u6708D\u65E5dddd HH:mm"},relativeTime:{future:"%s\u5185",past:"%s\u524D",s:"\u51E0\u79D2",m:"1 \u5206\u949F",mm:"%d \u5206\u949F",h:"1 \u5C0F\u65F6",hh:"%d \u5C0F\u65F6",d:"1 \u5929",dd:"%d \u5929",M:"1 \u4E2A\u6708",MM:"%d \u4E2A\u6708",y:"1 \u5E74",yy:"%d \u5E74"},meridiem:(e,t)=>{const n=100*e+t;return n<600?"\u51CC\u6668":n<900?"\u65E9\u4E0A":n<1100?"\u4E0A\u5348":n<1300?"\u4E2D\u5348":n<1800?"\u4E0B\u5348":"\u665A\u4E0A"}},Jv={name:"en",weekdays:"Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),months:"January_February_March_April_May_June_July_August_September_October_November_December".split("_")};rn.locale("zh",qv),rn.locale("en",Jv);const Pt=rn,Il=(e,t={})=>{const{lang:n,timezone:r,type:o}=t;Pt.locale(((l="en")=>{const c=l.toLowerCase();return c==="zh"||c==="zh-cn"?"zh":(c==="en-us"||c==="en-uk"||c==="en"||console.warn(`${l} locale missing in config`),"en")})(n));const i=r?Pt(e).tz(r).format("LL"):Pt(e).format("LL"),a=r?Pt(e).tz(r).format("HH:mm"):Pt(e).format("HH:mm");return o==="date"?i:o==="time"?a:`${i} ${a}`},Ll=(e,t={})=>{const{timezone:n}=t;if(e){if(Pt(e instanceof Date?e:e.trim()).isValid()){const o=n?Pt(e).tz(n):Pt(e),i=o.year(),a=o.month()+1,l=o.date(),c=o.hour(),u=o.minute(),s=o.second(),f=o.millisecond(),m=c===0&&u===0&&s===0&&f===0,h=o.toDate();return{display:Il(h,le({type:m?"date":"full"},t)),value:h,detail:le({year:i,month:a,day:l},m?{}:{hour:c,minute:u,second:s})}}const r=/(?:(\d{2,4})[/-](\d{1,2})[/-](\d{1,2}))?\s*(?:(\d{1,2}):(\d{1,2})(?::(\d{1,2}))?)?/u.exec(e.trim());if(r){const[,o,i,a,l,c,u]=r,s=w=>w===void 0?void 0:Number(w),f=w=>l&&c&&!u?0:w,m={year:(w=>w&&w<100?w+2e3:w)(s(o)),month:s(i),day:s(a),hour:s(l),minute:s(c),second:f(s(u))},h=o===void 0&&i===void 0&&a===void 0,b=l===void 0&&c===void 0&&u===void 0,y=Pt(Fe(le({},m),{month:m.month-1})).toDate();return{display:Il(y,le({type:b?"date":h?"time":"full"},t)),value:h?void 0:y,detail:b?{year:m.year,month:m.month,day:m.day}:h?{hour:m.hour,minute:m.minute,second:m.second}:m}}}return null},Al=(e,t=!1)=>e?Array.isArray(e)?e.map(n=>typeof n=="string"?{name:n}:n):typeof e=="string"?[{name:e}]:typeof e=="object"&&e.name?[e]:(console.error(`Expect 'author' to be \`AuthorInfo[] | AuthorInfo | string[] | string ${t?"":"| false"} | undefined\`, but got`,e),[]):[],Uv=e=>{if(e){if(Array.isArray(e))return e;if(typeof e=="string")return[e];console.error("Expect 'category' to be `string[] | string | undefined`, but got",e)}return[]},Wv=e=>{if(e){if(Array.isArray(e))return e;if(typeof e=="string")return[e];console.error("Expect 'tag' to be `string[] | string | undefined`, but got",e)}return[]};const Iu=()=>v(ke,{name:"back-to-top"},()=>[v("path",{d:"M512 843.2c-36.2 0-66.4-13.6-85.8-21.8-10.8-4.6-22.6 3.6-21.8 15.2l7 102c.4 6.2 7.6 9.4 12.6 5.6l29-22c3.6-2.8 9-1.8 11.4 2l41 64.2c3 4.8 10.2 4.8 13.2 0l41-64.2c2.4-3.8 7.8-4.8 11.4-2l29 22c5 3.8 12.2.6 12.6-5.6l7-102c.8-11.6-11-20-21.8-15.2-19.6 8.2-49.6 21.8-85.8 21.8z"}),v("path",{d:"m795.4 586.2-96-98.2C699.4 172 513 32 513 32S324.8 172 324.8 488l-96 98.2c-3.6 3.6-5.2 9-4.4 14.2L261.2 824c1.8 11.4 14.2 17 23.6 10.8L419 744s41.4 40 94.2 40c52.8 0 92.2-40 92.2-40l134.2 90.8c9.2 6.2 21.6.6 23.6-10.8l37-223.8c.4-5.2-1.2-10.4-4.8-14zM513 384c-34 0-61.4-28.6-61.4-64s27.6-64 61.4-64c34 0 61.4 28.6 61.4 64S547 384 513 384z"})]);Iu.displayName="BacktoTopIcon";var Kv=oe({name:"BackToTop",props:{threshold:{type:Number,default:300}},setup(e){const t=Me(),n=pa(),r=zn({"/":{backToTop:"\u8FD4\u56DE\u9876\u90E8"}}),o=ve(0),i=H(()=>{const{backToTop:c}=n.value;return typeof c=="number"?c:e.threshold}),a=H(()=>{const c=n.value.backToTop!==!1,u=t.value.backToTop;return(u||c&&u!==!1)&&o.value>i.value}),l=()=>window.pageYOffset||document.documentElement.scrollTop||document.body.scrollTop||0;return Ce(()=>{o.value=l()}),ht("scroll",dv(()=>{o.value=l()},100)),()=>v(Dt,{name:"fade"},()=>a.value?v("button",{class:"back-to-top","aria-label":r.value.backToTop,"data-balloon-pos":"left",onClick:()=>{window.scrollTo({top:0,behavior:"smooth"}),o.value=0}},v(Iu)):null)}}),Yv=vt({enhance:({app:e})=>{e.component("Badge",_u),e.component("FontIcon",gu)},setup:()=>{},rootComponents:[Kv]});function Lu(e,t,n){var r,o,i;t===void 0&&(t=50),n===void 0&&(n={});var a=(r=n.isImmediate)!=null&&r,l=(o=n.callback)!=null&&o,c=n.maxWait,u=Date.now(),s=[];function f(){if(c!==void 0){var h=Date.now()-u;if(h+t>=c)return c-h}return t}var m=function(){var h=[].slice.call(arguments),b=this;return new Promise(function(y,w){var g=a&&i===void 0;if(i!==void 0&&clearTimeout(i),i=setTimeout(function(){if(i=void 0,u=Date.now(),!a){var x=e.apply(b,h);l&&l(x),s.forEach(function(P){return(0,P.resolve)(x)}),s=[]}},f()),g){var E=e.apply(b,h);return l&&l(E),y(E)}s.push({resolve:y,reject:w})})};return m.cancel=function(h){i!==void 0&&clearTimeout(i),s.forEach(function(b){return(0,b.reject)(h)}),s=[]},m}/*! + * vue-router v4.0.15 + * (c) 2022 Eduardo San Martin Morote + * @license MIT + */const Au=typeof Symbol=="function"&&typeof Symbol.toStringTag=="symbol",$n=e=>Au?Symbol(e):"_vr_"+e,Gv=$n("rvlm"),Dl=$n("rvd"),Do=$n("r"),ba=$n("rl"),Ei=$n("rvl"),bn=typeof window!="undefined";function Qv(e){return e.__esModule||Au&&e[Symbol.toStringTag]==="Module"}const Pe=Object.assign;function Jo(e,t){const n={};for(const r in t){const o=t[r];n[r]=Array.isArray(o)?o.map(e):e(o)}return n}const ar=()=>{},Zv=/\/$/,Xv=e=>e.replace(Zv,"");function Uo(e,t,n="/"){let r,o={},i="",a="";const l=t.indexOf("?"),c=t.indexOf("#",l>-1?l:0);return l>-1&&(r=t.slice(0,l),i=t.slice(l+1,c>-1?c:t.length),o=e(i)),c>-1&&(r=r||t.slice(0,c),a=t.slice(c,t.length)),r=rp(r!=null?r:t,n),{fullPath:r+(i&&"?")+i+a,path:r,query:o,hash:a}}function ep(e,t){const n=t.query?e(t.query):"";return t.path+(n&&"?")+n+(t.hash||"")}function jl(e,t){return!t||!e.toLowerCase().startsWith(t.toLowerCase())?e:e.slice(t.length)||"/"}function tp(e,t,n){const r=t.matched.length-1,o=n.matched.length-1;return r>-1&&r===o&&Dn(t.matched[r],n.matched[o])&&Du(t.params,n.params)&&e(t.query)===e(n.query)&&t.hash===n.hash}function Dn(e,t){return(e.aliasOf||e)===(t.aliasOf||t)}function Du(e,t){if(Object.keys(e).length!==Object.keys(t).length)return!1;for(const n in e)if(!np(e[n],t[n]))return!1;return!0}function np(e,t){return Array.isArray(e)?kl(e,t):Array.isArray(t)?kl(t,e):e===t}function kl(e,t){return Array.isArray(t)?e.length===t.length&&e.every((n,r)=>n===t[r]):e.length===1&&e[0]===t}function rp(e,t){if(e.startsWith("/"))return e;if(!e)return t;const n=t.split("/"),r=e.split("/");let o=n.length-1,i,a;for(i=0;i({left:window.pageXOffset,top:window.pageYOffset});function cp(e){let t;if("el"in e){const n=e.el,r=typeof n=="string"&&n.startsWith("#"),o=typeof n=="string"?r?document.getElementById(n.slice(1)):document.querySelector(n):n;if(!o)return;t=lp(o,e)}else t=e;"scrollBehavior"in document.documentElement.style?window.scrollTo(t):window.scrollTo(t.left!=null?t.left:window.pageXOffset,t.top!=null?t.top:window.pageYOffset)}function Rl(e,t){return(history.state?history.state.position-t:-1)+e}const Oi=new Map;function sp(e,t){Oi.set(e,t)}function up(e){const t=Oi.get(e);return Oi.delete(e),t}let dp=()=>location.protocol+"//"+location.host;function ju(e,t){const{pathname:n,search:r,hash:o}=t,i=e.indexOf("#");if(i>-1){let l=o.includes(e.slice(i))?e.slice(i).length:1,c=o.slice(l);return c[0]!=="/"&&(c="/"+c),jl(c,"")}return jl(n,e)+r+o}function fp(e,t,n,r){let o=[],i=[],a=null;const l=({state:m})=>{const h=ju(e,location),b=n.value,y=t.value;let w=0;if(m){if(n.value=h,t.value=m,a&&a===b){a=null;return}w=y?m.position-y.position:0}else r(h);o.forEach(g=>{g(n.value,b,{delta:w,type:Or.pop,direction:w?w>0?lr.forward:lr.back:lr.unknown})})};function c(){a=n.value}function u(m){o.push(m);const h=()=>{const b=o.indexOf(m);b>-1&&o.splice(b,1)};return i.push(h),h}function s(){const{history:m}=window;!m.state||m.replaceState(Pe({},m.state,{scroll:jo()}),"")}function f(){for(const m of i)m();i=[],window.removeEventListener("popstate",l),window.removeEventListener("beforeunload",s)}return window.addEventListener("popstate",l),window.addEventListener("beforeunload",s),{pauseListeners:c,listen:u,destroy:f}}function Sl(e,t,n,r=!1,o=!1){return{back:e,current:t,forward:n,replaced:r,position:window.history.length,scroll:o?jo():null}}function mp(e){const{history:t,location:n}=window,r={value:ju(e,n)},o={value:t.state};o.value||i(r.value,{back:null,current:r.value,forward:null,position:t.length-1,replaced:!0,scroll:null},!0);function i(c,u,s){const f=e.indexOf("#"),m=f>-1?(n.host&&document.querySelector("base")?e:e.slice(f))+c:dp()+e+c;try{t[s?"replaceState":"pushState"](u,"",m),o.value=u}catch(h){console.error(h),n[s?"replace":"assign"](m)}}function a(c,u){const s=Pe({},t.state,Sl(o.value.back,c,o.value.forward,!0),u,{position:o.value.position});i(c,s,!0),r.value=c}function l(c,u){const s=Pe({},o.value,t.state,{forward:c,scroll:jo()});i(s.current,s,!0);const f=Pe({},Sl(r.value,c,null),{position:s.position+1},u);i(c,f,!1),r.value=c}return{location:r,state:o,push:l,replace:a}}function hp(e){e=op(e);const t=mp(e),n=fp(e,t.state,t.location,t.replace);function r(i,a=!0){a||n.pauseListeners(),history.go(i)}const o=Pe({location:"",base:e,go:r,createHref:ap.bind(null,e)},t,n);return Object.defineProperty(o,"location",{enumerable:!0,get:()=>t.location.value}),Object.defineProperty(o,"state",{enumerable:!0,get:()=>t.state.value}),o}function vp(e){return typeof e=="string"||e&&typeof e=="object"}function ku(e){return typeof e=="string"||typeof e=="symbol"}const wt={path:"/",name:void 0,params:{},query:{},hash:"",fullPath:"/",matched:[],meta:{},redirectedFrom:void 0},Ru=$n("nf");var Cl;(function(e){e[e.aborted=4]="aborted",e[e.cancelled=8]="cancelled",e[e.duplicated=16]="duplicated"})(Cl||(Cl={}));function jn(e,t){return Pe(new Error,{type:e,[Ru]:!0},t)}function Mt(e,t){return e instanceof Error&&Ru in e&&(t==null||!!(e.type&t))}const Vl="[^/]+?",pp={sensitive:!1,strict:!1,start:!0,end:!0},_p=/[.+*?^${}()[\]/\\]/g;function gp(e,t){const n=Pe({},pp,t),r=[];let o=n.start?"^":"";const i=[];for(const u of e){const s=u.length?[]:[90];n.strict&&!u.length&&(o+="/");for(let f=0;f1&&(s.endsWith("/")?s=s.slice(0,-1):f=!0);else throw new Error(`Missing required param "${b}"`);s+=E}}return s}return{re:a,score:r,keys:i,parse:l,stringify:c}}function bp(e,t){let n=0;for(;nt.length?t.length===1&&t[0]===40+40?1:-1:0}function yp(e,t){let n=0;const r=e.score,o=t.score;for(;n1&&(c==="*"||c==="+")&&t(`A repeatable param (${u}) must be alone in its segment. eg: '/:ids+.`),i.push({type:1,value:u,regexp:s,repeatable:c==="*"||c==="+",optional:c==="*"||c==="?"})):t("Invalid state to consume buffer"),u="")}function m(){u+=c}for(;l{a(E)}:ar}function a(s){if(ku(s)){const f=r.get(s);f&&(r.delete(s),n.splice(n.indexOf(f),1),f.children.forEach(a),f.alias.forEach(a))}else{const f=n.indexOf(s);f>-1&&(n.splice(f,1),s.record.name&&r.delete(s.record.name),s.children.forEach(a),s.alias.forEach(a))}}function l(){return n}function c(s){let f=0;for(;f=0&&(s.record.path!==n[f].record.path||!Su(s,n[f]));)f++;n.splice(f,0,s),s.record.name&&!Ml(s)&&r.set(s.record.name,s)}function u(s,f){let m,h={},b,y;if("name"in s&&s.name){if(m=r.get(s.name),!m)throw jn(1,{location:s});y=m.record.name,h=Pe(Pp(f.params,m.keys.filter(E=>!E.optional).map(E=>E.name)),s.params),b=m.stringify(h)}else if("path"in s)b=s.path,m=n.find(E=>E.re.test(b)),m&&(h=m.parse(b),y=m.record.name);else{if(m=f.name?r.get(f.name):n.find(E=>E.re.test(f.path)),!m)throw jn(1,{location:s,currentLocation:f});y=m.record.name,h=Pe({},f.params,s.params),b=m.stringify(h)}const w=[];let g=m;for(;g;)w.unshift(g.record),g=g.parent;return{name:y,path:b,params:h,matched:w,meta:Ap(w)}}return e.forEach(s=>i(s)),{addRoute:i,resolve:u,removeRoute:a,getRoutes:l,getRecordMatcher:o}}function Pp(e,t){const n={};for(const r of t)r in e&&(n[r]=e[r]);return n}function Ip(e){return{path:e.path,redirect:e.redirect,name:e.name,meta:e.meta||{},aliasOf:void 0,beforeEnter:e.beforeEnter,props:Lp(e),children:e.children||[],instances:{},leaveGuards:new Set,updateGuards:new Set,enterCallbacks:{},components:"components"in e?e.components||{}:{default:e.component}}}function Lp(e){const t={},n=e.props||!1;if("component"in e)t.default=n;else for(const r in e.components)t[r]=typeof n=="boolean"?n:n[r];return t}function Ml(e){for(;e;){if(e.record.aliasOf)return!0;e=e.parent}return!1}function Ap(e){return e.reduce((t,n)=>Pe(t,n.meta),{})}function zl(e,t){const n={};for(const r in e)n[r]=r in t?t[r]:e[r];return n}function Su(e,t){return t.children.some(n=>n===e||Su(e,n))}const Cu=/#/g,Dp=/&/g,jp=/\//g,kp=/=/g,Rp=/\?/g,Vu=/\+/g,Sp=/%5B/g,Cp=/%5D/g,Mu=/%5E/g,Vp=/%60/g,zu=/%7B/g,Mp=/%7C/g,$u=/%7D/g,zp=/%20/g;function ya(e){return encodeURI(""+e).replace(Mp,"|").replace(Sp,"[").replace(Cp,"]")}function $p(e){return ya(e).replace(zu,"{").replace($u,"}").replace(Mu,"^")}function wi(e){return ya(e).replace(Vu,"%2B").replace(zp,"+").replace(Cu,"%23").replace(Dp,"%26").replace(Vp,"`").replace(zu,"{").replace($u,"}").replace(Mu,"^")}function Np(e){return wi(e).replace(kp,"%3D")}function Hp(e){return ya(e).replace(Cu,"%23").replace(Rp,"%3F")}function Bp(e){return e==null?"":Hp(e).replace(jp,"%2F")}function uo(e){try{return decodeURIComponent(""+e)}catch{}return""+e}function Fp(e){const t={};if(e===""||e==="?")return t;const r=(e[0]==="?"?e.slice(1):e).split("&");for(let o=0;oi&&wi(i)):[r&&wi(r)]).forEach(i=>{i!==void 0&&(t+=(t.length?"&":"")+n,i!=null&&(t+="="+i))})}return t}function qp(e){const t={};for(const n in e){const r=e[n];r!==void 0&&(t[n]=Array.isArray(r)?r.map(o=>o==null?null:""+o):r==null?r:""+r)}return t}function Bn(){let e=[];function t(r){return e.push(r),()=>{const o=e.indexOf(r);o>-1&&e.splice(o,1)}}function n(){e=[]}return{add:t,list:()=>e,reset:n}}function Ht(e,t,n,r,o){const i=r&&(r.enterCallbacks[o]=r.enterCallbacks[o]||[]);return()=>new Promise((a,l)=>{const c=f=>{f===!1?l(jn(4,{from:n,to:t})):f instanceof Error?l(f):vp(f)?l(jn(2,{from:t,to:f})):(i&&r.enterCallbacks[o]===i&&typeof f=="function"&&i.push(f),a())},u=e.call(r&&r.instances[o],t,n,c);let s=Promise.resolve(u);e.length<3&&(s=s.then(c)),s.catch(f=>l(f))})}function Wo(e,t,n,r){const o=[];for(const i of e)for(const a in i.components){let l=i.components[a];if(!(t!=="beforeRouteEnter"&&!i.instances[a]))if(Jp(l)){const u=(l.__vccOpts||l)[t];u&&o.push(Ht(u,n,r,i,a))}else{let c=l();o.push(()=>c.then(u=>{if(!u)return Promise.reject(new Error(`Couldn't resolve component "${a}" at "${i.path}"`));const s=Qv(u)?u.default:u;i.components[a]=s;const m=(s.__vccOpts||s)[t];return m&&Ht(m,n,r,i,a)()}))}}return o}function Jp(e){return typeof e=="object"||"displayName"in e||"props"in e||"__vccOpts"in e}function Nl(e){const t=Ne(Do),n=Ne(ba),r=H(()=>t.resolve(Ge(e.to))),o=H(()=>{const{matched:c}=r.value,{length:u}=c,s=c[u-1],f=n.matched;if(!s||!f.length)return-1;const m=f.findIndex(Dn.bind(null,s));if(m>-1)return m;const h=Hl(c[u-2]);return u>1&&Hl(s)===h&&f[f.length-1].path!==h?f.findIndex(Dn.bind(null,c[u-2])):m}),i=H(()=>o.value>-1&&Kp(n.params,r.value.params)),a=H(()=>o.value>-1&&o.value===n.matched.length-1&&Du(n.params,r.value.params));function l(c={}){return Wp(c)?t[Ge(e.replace)?"replace":"push"](Ge(e.to)).catch(ar):Promise.resolve()}return{route:r,href:H(()=>r.value.href),isActive:i,isExactActive:a,navigate:l}}const Up=oe({name:"RouterLink",props:{to:{type:[String,Object],required:!0},replace:Boolean,activeClass:String,exactActiveClass:String,custom:Boolean,ariaCurrentValue:{type:String,default:"page"}},useLink:Nl,setup(e,{slots:t}){const n=sn(Nl(e)),{options:r}=Ne(Do),o=H(()=>({[Bl(e.activeClass,r.linkActiveClass,"router-link-active")]:n.isActive,[Bl(e.exactActiveClass,r.linkExactActiveClass,"router-link-exact-active")]:n.isExactActive}));return()=>{const i=t.default&&t.default(n);return e.custom?i:v("a",{"aria-current":n.isExactActive?e.ariaCurrentValue:null,href:n.href,onClick:n.navigate,class:o.value},i)}}}),fn=Up;function Wp(e){if(!(e.metaKey||e.altKey||e.ctrlKey||e.shiftKey)&&!e.defaultPrevented&&!(e.button!==void 0&&e.button!==0)){if(e.currentTarget&&e.currentTarget.getAttribute){const t=e.currentTarget.getAttribute("target");if(/\b_blank\b/i.test(t))return}return e.preventDefault&&e.preventDefault(),!0}}function Kp(e,t){for(const n in t){const r=t[n],o=e[n];if(typeof r=="string"){if(r!==o)return!1}else if(!Array.isArray(o)||o.length!==r.length||r.some((i,a)=>i!==o[a]))return!1}return!0}function Hl(e){return e?e.aliasOf?e.aliasOf.path:e.path:""}const Bl=(e,t,n)=>e!=null?e:t!=null?t:n,Yp=oe({name:"RouterView",inheritAttrs:!1,props:{name:{type:String,default:"default"},route:Object},compatConfig:{MODE:3},setup(e,{attrs:t,slots:n}){const r=Ne(Ei),o=H(()=>e.route||r.value),i=Ne(Dl,0),a=H(()=>o.value.matched[i]);ln(Dl,i+1),ln(Gv,a),ln(Ei,o);const l=ve();return je(()=>[l.value,a.value,e.name],([c,u,s],[f,m,h])=>{u&&(u.instances[s]=c,m&&m!==u&&c&&c===f&&(u.leaveGuards.size||(u.leaveGuards=m.leaveGuards),u.updateGuards.size||(u.updateGuards=m.updateGuards))),c&&u&&(!m||!Dn(u,m)||!f)&&(u.enterCallbacks[s]||[]).forEach(b=>b(c))},{flush:"post"}),()=>{const c=o.value,u=a.value,s=u&&u.components[e.name],f=e.name;if(!s)return Fl(n.default,{Component:s,route:c});const m=u.props[e.name],h=m?m===!0?c.params:typeof m=="function"?m(c):m:null,y=v(s,Pe({},h,t,{onVnodeUnmounted:w=>{w.component.isUnmounted&&(u.instances[f]=null)},ref:l}));return Fl(n.default,{Component:y,route:c})||y}}});function Fl(e,t){if(!e)return null;const n=e(t);return n.length===1?n[0]:n}const Nu=Yp;function Gp(e){const t=xp(e.routes,e),n=e.parseQuery||Fp,r=e.stringifyQuery||$l,o=e.history,i=Bn(),a=Bn(),l=Bn(),c=ys(wt);let u=wt;bn&&e.scrollBehavior&&"scrollRestoration"in history&&(history.scrollRestoration="manual");const s=Jo.bind(null,V=>""+V),f=Jo.bind(null,Bp),m=Jo.bind(null,uo);function h(V,G){let $,Q;return ku(V)?($=t.getRecordMatcher(V),Q=G):Q=V,t.addRoute(Q,$)}function b(V){const G=t.getRecordMatcher(V);G&&t.removeRoute(G)}function y(){return t.getRoutes().map(V=>V.record)}function w(V){return!!t.getRecordMatcher(V)}function g(V,G){if(G=Pe({},G||c.value),typeof V=="string"){const ce=Uo(n,V,G.path),_=t.resolve({path:ce.path},G),O=o.createHref(ce.fullPath);return Pe(ce,_,{params:m(_.params),hash:uo(ce.hash),redirectedFrom:void 0,href:O})}let $;if("path"in V)$=Pe({},V,{path:Uo(n,V.path,G.path).path});else{const ce=Pe({},V.params);for(const _ in ce)ce[_]==null&&delete ce[_];$=Pe({},V,{params:f(V.params)}),G.params=f(G.params)}const Q=t.resolve($,G),me=V.hash||"";Q.params=s(m(Q.params));const ge=ep(r,Pe({},V,{hash:$p(me),path:Q.path})),ue=o.createHref(ge);return Pe({fullPath:ge,hash:me,query:r===$l?qp(V.query):V.query||{}},Q,{redirectedFrom:void 0,href:ue})}function E(V){return typeof V=="string"?Uo(n,V,c.value.path):Pe({},V)}function x(V,G){if(u!==V)return jn(8,{from:G,to:V})}function P(V){return D(V)}function I(V){return P(Pe(E(V),{replace:!0}))}function j(V){const G=V.matched[V.matched.length-1];if(G&&G.redirect){const{redirect:$}=G;let Q=typeof $=="function"?$(V):$;return typeof Q=="string"&&(Q=Q.includes("?")||Q.includes("#")?Q=E(Q):{path:Q},Q.params={}),Pe({query:V.query,hash:V.hash,params:V.params},Q)}}function D(V,G){const $=u=g(V),Q=c.value,me=V.state,ge=V.force,ue=V.replace===!0,ce=j($);if(ce)return D(Pe(E(ce),{state:me,force:ge,replace:ue}),G||$);const _=$;_.redirectedFrom=G;let O;return!ge&&tp(r,Q,$)&&(O=jn(16,{to:_,from:Q}),pe(Q,Q,!0,!1)),(O?Promise.resolve(O):W(_,Q)).catch(L=>Mt(L)?Mt(L,2)?L:fe(L):Y(L,_,Q)).then(L=>{if(L){if(Mt(L,2))return D(Pe(E(L.to),{state:me,force:ge,replace:ue}),G||_)}else L=q(_,Q,!0,ue,me);return Z(_,Q,L),L})}function k(V,G){const $=x(V,G);return $?Promise.reject($):Promise.resolve()}function W(V,G){let $;const[Q,me,ge]=Qp(V,G);$=Wo(Q.reverse(),"beforeRouteLeave",V,G);for(const ce of Q)ce.leaveGuards.forEach(_=>{$.push(Ht(_,V,G))});const ue=k.bind(null,V,G);return $.push(ue),hn($).then(()=>{$=[];for(const ce of i.list())$.push(Ht(ce,V,G));return $.push(ue),hn($)}).then(()=>{$=Wo(me,"beforeRouteUpdate",V,G);for(const ce of me)ce.updateGuards.forEach(_=>{$.push(Ht(_,V,G))});return $.push(ue),hn($)}).then(()=>{$=[];for(const ce of V.matched)if(ce.beforeEnter&&!G.matched.includes(ce))if(Array.isArray(ce.beforeEnter))for(const _ of ce.beforeEnter)$.push(Ht(_,V,G));else $.push(Ht(ce.beforeEnter,V,G));return $.push(ue),hn($)}).then(()=>(V.matched.forEach(ce=>ce.enterCallbacks={}),$=Wo(ge,"beforeRouteEnter",V,G),$.push(ue),hn($))).then(()=>{$=[];for(const ce of a.list())$.push(Ht(ce,V,G));return $.push(ue),hn($)}).catch(ce=>Mt(ce,8)?ce:Promise.reject(ce))}function Z(V,G,$){for(const Q of l.list())Q(V,G,$)}function q(V,G,$,Q,me){const ge=x(V,G);if(ge)return ge;const ue=G===wt,ce=bn?history.state:{};$&&(Q||ue?o.replace(V.fullPath,Pe({scroll:ue&&ce&&ce.scroll},me)):o.push(V.fullPath,me)),c.value=V,pe(V,G,$,ue),fe()}let A;function R(){A||(A=o.listen((V,G,$)=>{const Q=g(V),me=j(Q);if(me){D(Pe(me,{replace:!0}),Q).catch(ar);return}u=Q;const ge=c.value;bn&&sp(Rl(ge.fullPath,$.delta),jo()),W(Q,ge).catch(ue=>Mt(ue,12)?ue:Mt(ue,2)?(D(ue.to,Q).then(ce=>{Mt(ce,20)&&!$.delta&&$.type===Or.pop&&o.go(-1,!1)}).catch(ar),Promise.reject()):($.delta&&o.go(-$.delta,!1),Y(ue,Q,ge))).then(ue=>{ue=ue||q(Q,ge,!1),ue&&($.delta?o.go(-$.delta,!1):$.type===Or.pop&&Mt(ue,20)&&o.go(-1,!1)),Z(Q,ge,ue)}).catch(ar)}))}let S=Bn(),F=Bn(),K;function Y(V,G,$){fe(V);const Q=F.list();return Q.length?Q.forEach(me=>me(V,G,$)):console.error(V),Promise.reject(V)}function X(){return K&&c.value!==wt?Promise.resolve():new Promise((V,G)=>{S.add([V,G])})}function fe(V){return K||(K=!V,R(),S.list().forEach(([G,$])=>V?$(V):G()),S.reset()),V}function pe(V,G,$,Q){const{scrollBehavior:me}=e;if(!bn||!me)return Promise.resolve();const ge=!$&&up(Rl(V.fullPath,0))||(Q||!$)&&history.state&&history.state.scroll||null;return ra().then(()=>me(V,G,ge)).then(ue=>ue&&cp(ue)).catch(ue=>Y(ue,V,G))}const ye=V=>o.go(V);let we;const Le=new Set;return{currentRoute:c,addRoute:h,removeRoute:b,hasRoute:w,getRoutes:y,resolve:g,options:e,push:P,replace:I,go:ye,back:()=>ye(-1),forward:()=>ye(1),beforeEach:i.add,beforeResolve:a.add,afterEach:l.add,onError:F.add,isReady:X,install(V){const G=this;V.component("RouterLink",fn),V.component("RouterView",Nu),V.config.globalProperties.$router=G,Object.defineProperty(V.config.globalProperties,"$route",{enumerable:!0,get:()=>Ge(c)}),bn&&!we&&c.value===wt&&(we=!0,P(o.location).catch(me=>{}));const $={};for(const me in wt)$[me]=H(()=>c.value[me]);V.provide(Do,G),V.provide(ba,sn($)),V.provide(Ei,c);const Q=V.unmount;Le.add(V),V.unmount=function(){Le.delete(V),Le.size<1&&(u=wt,A&&A(),A=null,c.value=wt,we=!1,K=!1),Q()}}}}function hn(e){return e.reduce((t,n)=>t.then(()=>n()),Promise.resolve())}function Qp(e,t){const n=[],r=[],o=[],i=Math.max(t.matched.length,e.matched.length);for(let a=0;aDn(u,l))?r.push(l):n.push(l));const c=e.matched[a];c&&(t.matched.find(u=>Dn(u,c))||o.push(c))}return[n,r,o]}function Et(){return Ne(Do)}function Re(){return Ne(ba)}const Zp=({headerLinkSelector:e,headerAnchorSelector:t,delay:n,offset:r=5})=>{const o=Et(),i=Qe(),l=Lu(()=>{var y,w,g,E;const c=Array.from(document.querySelectorAll(e)),s=Array.from(document.querySelectorAll(t)).filter(x=>c.some(P=>P.hash===x.hash)),f=Math.max(window.pageYOffset,document.documentElement.scrollTop,document.body.scrollTop),m=window.innerHeight+f,h=Math.max(document.documentElement.scrollHeight,document.body.scrollHeight),b=Math.abs(h-m)=((w=(y=P.parentElement)==null?void 0:y.offsetTop)!=null?w:0)-r,D=!I||f<((E=(g=I.parentElement)==null?void 0:g.offsetTop)!=null?E:0)-r;if(!(j&&D))continue;const W=decodeURIComponent(o.currentRoute.value.hash),Z=decodeURIComponent(P.hash);if(W===Z)return;if(b){for(let q=x+1;q{l(),window.addEventListener("scroll",l)}),Mn(()=>{window.removeEventListener("scroll",l)}),je(()=>i.value.path,l)},Xp=async(e,...t)=>{const{scrollBehavior:n}=e.options;e.options.scrollBehavior=void 0,await e.replace(...t).finally(()=>e.options.scrollBehavior=n)},e_=".sidebar-link, .toc-link",t_=".header-anchor",n_=200,r_=5;var o_=vt({setup(){Zp({headerLinkSelector:e_,headerAnchorSelector:t_,delay:n_,offset:r_})}});const i_=v("svg",{class:"external-link-icon",xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",focusable:"false",x:"0px",y:"0px",viewBox:"0 0 100 100",width:"15",height:"15"},[v("path",{fill:"currentColor",d:"M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"}),v("polygon",{fill:"currentColor",points:"45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"})]),Hu=oe({name:"ExternalLinkIcon",props:{locales:{type:Object,required:!1,default:()=>({})}},setup(e){const t=dn(),n=H(()=>{var r;return(r=e.locales[t.value])!=null?r:{openInNewWindow:"open in new window"}});return()=>v("span",[i_,v("span",{class:"external-link-icon-sr-only"},n.value.openInNewWindow)])}}),a_={};var l_=vt({enhance({app:e}){e.component("ExternalLinkIcon",v(Hu,{locales:a_}))}});const be={settings:{minimum:.08,easing:"ease",speed:200,trickle:!0,trickleRate:.02,trickleSpeed:800,barSelector:'[role="bar"]',parent:"body",template:'
    '},status:null,set:e=>{const t=be.isStarted();e=Ko(e,be.settings.minimum,1),be.status=e===1?null:e;const n=be.render(!t),r=n.querySelector(be.settings.barSelector),o=be.settings.speed,i=be.settings.easing;return n.offsetWidth,c_(a=>{Nr(r,{transform:"translate3d("+ql(e)+"%,0,0)",transition:"all "+o+"ms "+i}),e===1?(Nr(n,{transition:"none",opacity:"1"}),n.offsetWidth,setTimeout(function(){Nr(n,{transition:"all "+o+"ms linear",opacity:"0"}),setTimeout(function(){be.remove(),a()},o)},o)):setTimeout(()=>a(),o)}),be},isStarted:()=>typeof be.status=="number",start:()=>{be.status||be.set(0);const e=()=>{setTimeout(()=>{!be.status||(be.trickle(),e())},be.settings.trickleSpeed)};return be.settings.trickle&&e(),be},done:e=>!e&&!be.status?be:be.inc(.3+.5*Math.random()).set(1),inc:e=>{let t=be.status;return t?(typeof e!="number"&&(e=(1-t)*Ko(Math.random()*t,.1,.95)),t=Ko(t+e,0,.994),be.set(t)):be.start()},trickle:()=>be.inc(Math.random()*be.settings.trickleRate),render:e=>{if(be.isRendered())return document.getElementById("nprogress");Jl(document.documentElement,"nprogress-busy");const t=document.createElement("div");t.id="nprogress",t.innerHTML=be.settings.template;const n=t.querySelector(be.settings.barSelector),r=e?"-100":ql(be.status||0),o=document.querySelector(be.settings.parent);return Nr(n,{transition:"all 0 linear",transform:"translate3d("+r+"%,0,0)"}),o!==document.body&&Jl(o,"nprogress-custom-parent"),o==null||o.appendChild(t),t},remove:()=>{Ul(document.documentElement,"nprogress-busy"),Ul(document.querySelector(be.settings.parent),"nprogress-custom-parent");const e=document.getElementById("nprogress");e&&s_(e)},isRendered:()=>!!document.getElementById("nprogress")},Ko=(e,t,n)=>en?n:e,ql=e=>(-1+e)*100,c_=function(){const e=[];function t(){const n=e.shift();n&&n(t)}return function(n){e.push(n),e.length===1&&t()}}(),Nr=function(){const e=["Webkit","O","Moz","ms"],t={};function n(a){return a.replace(/^-ms-/,"ms-").replace(/-([\da-z])/gi,function(l,c){return c.toUpperCase()})}function r(a){const l=document.body.style;if(a in l)return a;let c=e.length;const u=a.charAt(0).toUpperCase()+a.slice(1);let s;for(;c--;)if(s=e[c]+u,s in l)return s;return a}function o(a){return a=n(a),t[a]||(t[a]=r(a))}function i(a,l,c){l=o(l),a.style[l]=c}return function(a,l){for(const c in l){const u=l[c];u!==void 0&&Object.prototype.hasOwnProperty.call(l,c)&&i(a,c,u)}}}(),Bu=(e,t)=>(typeof e=="string"?e:Ea(e)).indexOf(" "+t+" ")>=0,Jl=(e,t)=>{const n=Ea(e),r=n+t;Bu(n,t)||(e.className=r.substring(1))},Ul=(e,t)=>{const n=Ea(e);if(!Bu(e,t))return;const r=n.replace(" "+t+" "," ");e.className=r.substring(1,r.length-1)},Ea=e=>(" "+(e.className||"")+" ").replace(/\s+/gi," "),s_=e=>{e&&e.parentNode&&e.parentNode.removeChild(e)};const u_=()=>{Ce(()=>{const e=Et(),t=new Set;t.add(e.currentRoute.value.path),e.beforeEach(n=>{t.has(n.path)||be.start()}),e.afterEach(n=>{t.add(n.path),be.done()})})};var d_=vt({setup(){u_()}}),f_=vt({enhance({app:e}){const t=pa(),n=e._context.provides[fa],r=H(()=>Mv(t.value,n.value));e.provide(wu,r),Object.defineProperties(e.config.globalProperties,{$theme:{get(){return t.value}},$themeLocale:{get(){return r.value}}})}});const Fn={selector:'.theme-hope-content div[class*="language-"] pre',pure:!1},Wl=()=>!!navigator&&/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/iu.test(navigator.userAgent),m_=()=>{const e=Re(),t=zn({"/":{copy:"\u590D\u5236\u6210\u529F",hint:"\u590D\u5236\u4EE3\u7801"}});let n;const r=i=>{if(!i.hasAttribute("copy-code-registerd")){const a=document.createElement("button");a.className="copy-code-button",a.innerHTML='',a.addEventListener("click",()=>{(l=>{const c=document.getSelection(),u=!!(c&&c.rangeCount>0)&&c.getRangeAt(0),s=document.createElement("textarea");s.value=l,s.setAttribute("readonly",""),s.style.position="absolute",s.style.top="-9999px",document.body.appendChild(s),s.select(),document.execCommand("copy"),n.pop(`${t.value.copy} \u{1F389}`,Fn.duration),document.body.removeChild(s),u&&c&&(c.removeAllRanges(),c.addRange(u))})(i.innerText)}),a.setAttribute("aria-label",t.value.hint),a.setAttribute("data-balloon-pos","left"),i.parentElement&&i.parentElement.insertBefore(a,i),i.setAttribute("copy-code-registerd","")}},o=()=>{const i=Fn.selector;setTimeout(()=>{document.querySelectorAll(i).forEach(r)},Fn.delay||500)};Ce(()=>{n=new $v,Wl()&&!Fn.showInMobile||o()}),je(()=>e.path,()=>{Wl()&&!Fn.showInMobile||o()})};var h_=vt({setup:()=>{m_()}});const v_=()=>d(()=>import("./highlight.esm.d982e650.js"),[]),p_=()=>d(()=>import("./markdown.esm.832a189d.js"),[]),__=()=>d(()=>import("./math.esm.a3f84b6f.js"),[]),g_=()=>d(()=>import("./notes.esm.3c361cb7.js"),[]),b_=()=>d(()=>import("./reveal.esm.b96f05d8.js"),[]),y_=()=>d(()=>import("./search.esm.80da4a02.js"),[]),E_=()=>d(()=>import("./zoom.esm.8514a202.js"),[]),O_=()=>[b_(),p_(),v_(),__(),y_(),g_(),E_()];const w_=()=>v(ke,{name:"loading"},()=>["0s","-0.333s","-0.667s"].map(e=>v("circle",{cx:50,cy:50,r:0,fill:"none",stroke:"currentColor",strokeWidth:"2"},[v("animate",{attributeName:"r",repeatCount:"indefinite",dur:"1s",values:"0;40",keyTimes:"0;1",keySplines:"0 0.2 0.8 1",calcMode:"spline",begin:e}),v("animate",{attributeName:"opacity",repeatCount:"indefinite",dur:"1s",values:"1;0",keyTimes:"0;1",keySplines:"0.2 0 0.8 1",calcMode:"spline",begin:e})])));var T_=oe({name:"Presentation",props:{id:{type:String,required:!0},theme:{type:String,default:"auto"}},setup(e){const t=Me(),n=ve(""),r=ve(!1),o=ve(),i=ve();let a;return Ce(()=>{var l;if(i.value){n.value=decodeURIComponent(((l=o.value)==null?void 0:l.dataset.code)||""),i.value.setAttribute("id",e.id),i.value.setAttribute("data-theme",e.theme);const c=[new Promise(u=>setTimeout(u,500)),...O_()];Promise.all(c).then(([,u,...s])=>{a=new u.default(i.value,{plugins:s.map(f=>f.default)}),a.initialize(Fe(le({backgroundTransition:"slide",hash:t.value.layout==="Slide",mouseWheel:t.value.layout==="Slide",transition:"slide",slideNumber:!0},t.value.reveal||{}),{embedded:t.value.layout!=="Slide"})).then(()=>{r.value=!1,a.configure({backgroundTransition:"slide"})})})}}),Mn(()=>{a==null||a.destroy()}),()=>v("div",{ref:o,class:{"md-enhance-presentation":!0,loading:r.value}},[r.value?v(w_):null,v("div",{ref:i,class:["reveal","reveal-viewport"]},v("div",{class:"slides",style:{display:r.value?"none":"block"},innerHTML:`
    - + -

    Java:34道精选高频面试题必看👍

    沉默王二2021年12月16日
    • 求职面试
    • 面试题集合
    大约 21 分钟

    Java:34道精选高频面试题必看👍

    1.介绍一下 java 吧

    java 是一门开源的跨平台的面向对象的计算机语言.

    跨平台是因为 java 的 class 文件是运行在虚拟机上的,其实跨平台的,而虚拟机是不同平台有不同版本,所以说 java 是跨平台的.

    面向对象有几个特点:

    • 1.封装
      • 两层含义:一层含义是把对象的属性和行为看成一个密不可分的整体,将这两者'封装'在一个不可分割的独立单元(即对象)中
      • 另一层含义指'信息隐藏,把不需要让外界知道的信息隐藏起来,有些对象的属性及行为允许外界用户知道或使用,但不允许更改,而另一些属性或行为,则不允许外界知晓,或只允许使用对象的功能,而尽可能隐藏对象的功能实现细节

    优点:

    1.良好的封装能够减少耦合,符合程序设计追求'高内聚,低耦合'。
    2.类内部的结构可以自由修改
    3.可以对成员变量进行更精确的控制
    4.隐藏信息实现细节。

    • 2.继承
      • 继承就是子类继承父类的特征和行为,使得子类对象(实例)具有父类的实例域和方法,或子类从父类继承方法,使得子类具有父类相同的行为。

    优点:

    1.提高类代码的复用性
    2.提高了代码的维护性

    • 3.多态
      • 多态是同一个行为具有多个不同表现形式或形态的能力。Java语言中含有方法重载与对象多态两种形式的多态:
        • 1.方法重载:在一个类中,允许多个方法使用同一个名字,但方法的参数不同,完成的功能也不同。
        • 2.对象多态:子类对象可以与父类对象进行转换,而且根据其使用的子类不同完成的功能也不同(重写父类的方法)。

    优点

    1. 消除类型之间的耦合关系
    2. 可替换性
    3. 可扩充性
    4. 接口性
    5. 灵活性
    6. 简化性

    2.java 有哪些数据类型?

    java 主要有两种数据类型

    • 1.基本数据类型
      • 基本数据有八个,
        • byte,short,int,long属于数值型中的整数型
        • float,double属于数值型中的浮点型
        • char属于字符型
        • boolean属于布尔型
    • 2.引用数据类型
      • 引用数据类型有三个,分别是类,接口和数组

    3.接口和抽象类有什么区别?

    • 1.接口是抽象类的变体,接口中所有的方法都是抽象的。而抽象类是声明方法的存在而不去实现它的类。
    • 2.接口可以多继承,抽象类不行。
    • 3.接口定义方法,不能实现,默认是 public abstract,而抽象类可以实现部分方法。
    • 4.接口中基本数据类型为 public static final 并且需要给出初始值,而抽类象不是的。

    4.重载和重写什么区别?

    重写:

    • 1.参数列表必须完全与被重写的方法相同,否则不能称其为重写而是重载.
    • 2.返回的类型必须一直与被重写的方法的返回类型相同,否则不能称其为重写而是重载。
    • 3.访问修饰符的限制一定要大于被重写方法的访问修饰符
    • 4.重写方法一定不能抛出新的检查异常或者比被重写方法申明更加宽泛的检查型异常

    重载:

    • 1.必须具有不同的参数列表
    • 2.可以有不同的返回类型,只要参数列表不同就可以了;
    • 3.可以有不同的访问修饰符
    • 4.可以抛出不同的异常

    5.常见的异常有哪些?

    • NullPointerException 空指针异常
    • ArrayIndexOutOfBoundsException 索引越界异常
    • InputFormatException 输入类型不匹配
    • SQLException SQL异常
    • IllegalArgumentException 非法参数
    • NumberFormatException 类型转换异常 等等....

    6.异常要怎么解决?

    Java标准库内建了一些通用的异常,这些类以Throwable为顶层父类。

    Throwable又派生出Error类和Exception类

    错误:Error类以及他的子类的实例,代表了JVM本身的错误。错误不能被程序员通过代码处理,Error很少出现。因此,程序员应该关注Exception为父类的分支下的各种异常类。

    异常:Exception以及他的子类,代表程序运行时发送的各种不期望发生的事件。可以被Java异常处理机制使用,是异常处理的核心。

    处理方法:

    • 1.try()catch(){}
    try{
    +    

    Java:34道精选高频面试题必看👍

    沉默王二2021年12月16日
    • 求职面试
    • 面试题集合
    大约 21 分钟

    Java:34道精选高频面试题必看👍

    1.介绍一下 java 吧

    java 是一门开源的跨平台的面向对象的计算机语言.

    跨平台是因为 java 的 class 文件是运行在虚拟机上的,其实跨平台的,而虚拟机是不同平台有不同版本,所以说 java 是跨平台的.

    面向对象有几个特点:

    • 1.封装
      • 两层含义:一层含义是把对象的属性和行为看成一个密不可分的整体,将这两者'封装'在一个不可分割的独立单元(即对象)中
      • 另一层含义指'信息隐藏,把不需要让外界知道的信息隐藏起来,有些对象的属性及行为允许外界用户知道或使用,但不允许更改,而另一些属性或行为,则不允许外界知晓,或只允许使用对象的功能,而尽可能隐藏对象的功能实现细节

    优点:

    1.良好的封装能够减少耦合,符合程序设计追求'高内聚,低耦合'。
    2.类内部的结构可以自由修改
    3.可以对成员变量进行更精确的控制
    4.隐藏信息实现细节。

    • 2.继承
      • 继承就是子类继承父类的特征和行为,使得子类对象(实例)具有父类的实例域和方法,或子类从父类继承方法,使得子类具有父类相同的行为。

    优点:

    1.提高类代码的复用性
    2.提高了代码的维护性

    • 3.多态
      • 多态是同一个行为具有多个不同表现形式或形态的能力。Java语言中含有方法重载与对象多态两种形式的多态:
        • 1.方法重载:在一个类中,允许多个方法使用同一个名字,但方法的参数不同,完成的功能也不同。
        • 2.对象多态:子类对象可以与父类对象进行转换,而且根据其使用的子类不同完成的功能也不同(重写父类的方法)。

    优点

    1. 消除类型之间的耦合关系
    2. 可替换性
    3. 可扩充性
    4. 接口性
    5. 灵活性
    6. 简化性

    2.java 有哪些数据类型?

    java 主要有两种数据类型

    • 1.基本数据类型
      • 基本数据有八个,
        • byte,short,int,long属于数值型中的整数型
        • float,double属于数值型中的浮点型
        • char属于字符型
        • boolean属于布尔型
    • 2.引用数据类型
      • 引用数据类型有三个,分别是类,接口和数组

    3.接口和抽象类有什么区别?

    • 1.接口是抽象类的变体,接口中所有的方法都是抽象的。而抽象类是声明方法的存在而不去实现它的类。
    • 2.接口可以多继承,抽象类不行。
    • 3.接口定义方法,不能实现,默认是 public abstract,而抽象类可以实现部分方法。
    • 4.接口中基本数据类型为 public static final 并且需要给出初始值,而抽类象不是的。

    4.重载和重写什么区别?

    重写:

    • 1.参数列表必须完全与被重写的方法相同,否则不能称其为重写而是重载.
    • 2.返回的类型必须一直与被重写的方法的返回类型相同,否则不能称其为重写而是重载。
    • 3.访问修饰符的限制一定要大于被重写方法的访问修饰符
    • 4.重写方法一定不能抛出新的检查异常或者比被重写方法申明更加宽泛的检查型异常

    重载:

    • 1.必须具有不同的参数列表
    • 2.可以有不同的返回类型,只要参数列表不同就可以了;
    • 3.可以有不同的访问修饰符
    • 4.可以抛出不同的异常

    5.常见的异常有哪些?

    • NullPointerException 空指针异常
    • ArrayIndexOutOfBoundsException 索引越界异常
    • InputFormatException 输入类型不匹配
    • SQLException SQL异常
    • IllegalArgumentException 非法参数
    • NumberFormatException 类型转换异常 等等....

    6.异常要怎么解决?

    Java标准库内建了一些通用的异常,这些类以Throwable为顶层父类。

    Throwable又派生出Error类和Exception类

    错误:Error类以及他的子类的实例,代表了JVM本身的错误。错误不能被程序员通过代码处理,Error很少出现。因此,程序员应该关注Exception为父类的分支下的各种异常类。

    异常:Exception以及他的子类,代表程序运行时发送的各种不期望发生的事件。可以被Java异常处理机制使用,是异常处理的核心。

    处理方法:

    • 1.try()catch(){}
    try{
     // 程序代码
     }catch(ExceptionName e1){
     //Catch 块
    @@ -141,6 +141,6 @@ try {
     

    28.线程池有哪些参数?

    • 1.corePoolSize核心线程数,线程池中始终存活的线程数。

    • 2.maximumPoolSize: 最大线程数,线程池中允许的最大线程数。

    • 3.keepAliveTime: 存活时间,线程没有任务执行时最多保持多久时间会终止。

    • 4.unit: 单位,参数keepAliveTime的时间单位,7种可选。

    • 5.workQueue: 一个阻塞队列,用来存储等待执行的任务,均为线程安全,7种可选。

    • 6.threadFactory: 线程工厂,主要用来创建线程,默及正常优先级、非守护线程。

    • 7.handler拒绝策略,拒绝处理任务时的策略,4种可选,默认为AbortPolicy。

    29.线程池的执行流程?

    • 判断线程池中的线程数是否大于设置的核心线程数
      • 如果小于,就创建一个核心线程来执行任务
      • 如果大于,就会判断缓冲队列是否满了
        • 如果没有满,则放入队列,等待线程空闲时执行任务
        • 如果队列已经满了,则判断是否达到了线程池设置的最大线程数
          • 如果没有达到,就创建新线程来执行任务
          • 如果已经达到了最大线程数,则执行指定的拒绝策略

    30.线程池的拒绝策略有哪些?

    • AbortPolicy:直接丢弃任务,抛出异常,这是默认策略
    • CallerRunsPolicy:只用调用者所在的线程来处理任务
    • DiscardOldestPolicy:丢弃等待队列中最旧的任务,并执行当前任务
    • DiscardPolicy:直接丢弃任务,也不抛出异常

    31.介绍一下四种引用类型?

    • 强引用 StrongReference
    Object obj = new Object(); 
     //只要obj还指向Object对象,Object对象就不会被回收
     

    垃圾回收器不会回收被引用的对象,哪怕内存不足时,JVM 也会直接抛出 OutOfMemoryError,除非赋值为 null。

    • 软引用 SoftReference

    软引用是用来描述一些非必需但仍有用的对象。在内存足够的时候,软引用对象不会被回收,只有在内存不足时,系统则会回收软引用对象,如果回收了软引用对象之后仍然没有足够的内存,才会抛出内存溢出异常。

    • 弱引用 WeakReference

    弱引用的引用强度比软引用要更弱一些,无论内存是否足够,只要 JVM 开始进行垃圾回收,那些被弱引用关联的对象都会被回收。

    • 虚引用 PhantomReference

    虚引用是最弱的一种引用关系,如果一个对象仅持有虚引用,那么它就和没有任何引用一样,它随时可能会被回收,在 JDK1.2 之后,用 PhantomReference 类来表示,通过查看这个类的源码,发现它只有一个构造函数和一个 get() 方法,而且它的 get() 方法仅仅是返回一个null,也就是说将永远无法通过虚引用来获取对象,虚引用必须要和 ReferenceQueue 引用队列一起使用,NIO 的堆外内存就是靠其管理。

    32.深拷贝、浅拷贝是什么?

    • 浅拷贝并不是真的拷贝,只是复制指向某个对象的指针,而不复制对象本身,新旧对象还是共享同一块内存。
    • 深拷贝会另外创造一个一模一样的对象,新对象跟原对象不共享内存,修改新对象不会改到原对象。

    33.聊聊 ThreadLocal 吧

    • ThreadLocal其实就是线程本地变量,他会在每个线程都创建一个副本,那么在线程之间访问内部副本变量就行了,做到了线程之间互相隔离。
    • ThreadLocal 有一个静态内部类 ThreadLocalMap,ThreadLocalMap 又包含了一个 Entry 数组,Entry 本身是一个弱引用,他的 key 是指向 ThreadLocal 的弱引用,弱引用的目的是为了防止内存泄露,如果是强引用那么除非线程结束,否则无法终止,可能会有内存泄漏的风险。
    • 但是这样还是会存在内存泄露的问题,假如 key 和 ThreadLocal 对象被回收之后,entry 中就存在 key 为 null ,但是 value 有值的 entry 对象,但是永远没办法被访问到,同样除非线程结束运行。解决方法就是调用 remove 方法删除 entry 对象

    34.一个对象的内存布局是怎么样的?

    • 1.对象头: 对象头又分为 MarkWordClass Pointer 两部分。
      • MarkWord:包含一系列的标记位,比如轻量级锁的标记位,偏向锁标记位,gc记录信息等等。
      • ClassPointer:用来指向对象对应的 Class 对象(其对应的元数据对象)的内存地址。在 32 位系统占 4 字节,在 64 位系统中占 8 字节。
    • 2.Length:只在数组对象中存在,用来记录数组的长度,占用 4 字节
    • 3.Instance data: 对象实际数据,对象实际数据包括了对象的所有成员变量,其大小由各个成员变量的大小决定。(这里不包括静态成员变量,因为其是在方法区维护的)
    • 4.Padding:Java 对象占用空间是 8 字节对齐的,即所有 Java 对象占用 bytes 数必须是 8 的倍数,是因为当我们从磁盘中取一个数据时,不会说我想取一个字节就是一个字节,都是按照一块儿一块儿来取的,这一块大小是 8 个字节,所以为了完整,padding 的作用就是补充字节,保证对象是 8 字节的整数倍

    作者:moon聊技术,转载链接:https://mp.weixin.qq.com/s/aTWtqPyMQ-6P_c8iuMVrkgopen in new window

    - + diff --git a/dist/baguwen/java-basic.html b/dist/baguwen/java-basic.html index f582ff50..a1e3299d 100644 --- a/dist/baguwen/java-basic.html +++ b/dist/baguwen/java-basic.html @@ -39,10 +39,10 @@ } - + -

    Java 基础八股文(背诵版)必看👍

    沉默王二2021年12月3日
    • 求职面试
    • 背诵版八股文
    大约 20 分钟

    Java 基础八股文(背诵版)必看👍

    Java 语言具有哪些特点?

    • Java 为纯面向对象的语言。它能够直接反应现实生活中的对象。
    • 具有平台无关性。Java 利用 Java 虚拟机运行字节码,无论是在 Windows、Linux 还是 MacOS 等其它平台对 Java 程序进行编译,编译后的程序可在其它平台运行。
    • Java 为解释型语言,编译器把 Java 代码编译成平台无关的中间代码,然后在 JVM 上解释运行,具有很好的可移植性。
    • Java 提供了很多内置类库。如对多线程支持,对网络通信支持,最重要的一点是提供了垃圾回收器。
    • Java 具有较好的安全性和健壮性。Java 提供了异常处理和垃圾回收机制,去除了 C++中难以理解的指针特性。

    JDK 与 JRE 有什么区别?

    • JDK:Java 开发工具包(Java Development Kit),提供了 Java 的开发环境和运行环境。
    • JRE:Java 运行环境(Java Runtime Environment),提供了 Java 运行所需的环境。
    • JDK 包含了 JRE。如果只运行 Java 程序,安装 JRE 即可。要编写 Java 程序需安装 JDK.

    简述 Java 基本数据类型

    • byte: 占用 1 个字节,取值范围-128 ~ 127
    • short: 占用 2 个字节,取值范围-2^15^ ~ 2^15^-1
    • int:占用 4 个字节,取值范围-2^31^ ~ 2^31^-1
    • long:占用 8 个字节
    • float:占用 4 个字节
    • double:占用 8 个字节
    • char: 占用 2 个字节
    • boolean:占用大小根据实现虚拟机不同有所差异

    简述自动装箱拆箱

    对于 Java 基本数据类型,均对应一个包装类。

    装箱就是自动将基本数据类型转换为包装器类型,如 int->Integer

    拆箱就是自动将包装器类型转换为基本数据类型,如 Integer->int

    简述 Java 访问修饰符

    • default: 默认访问修饰符,在同一包内可见
    • private: 在同一类内可见,不能修饰类
    • protected : 对同一包内的类和所有子类可见,不能修饰类
    • public: 对所有类可见

    构造方法、成员变量初始化以及静态成员变量三者的初始化顺序?

    先后顺序:静态成员变量、成员变量、构造方法。

    详细的先后顺序:父类静态变量、父类静态代码块、子类静态变量、子类静态代码块、父类非静态变量、父类非静态代码块、父类构造函数、子类非静态变量、子类非静态代码块、子类构造函数。

    Java 代码块执行顺序

    • 父类静态代码块(只执行一次)
    • 子类静态代码块(只执行一次)
    • 父类构造代码块
    • 父类构造函数
    • 子类构造代码块
    • 子类构造函数
    • 普通代码块

    面向对象的三大特性?

    继承:对象的一个新类可以从现有的类中派生,派生类可以从它的基类那继承方法和实例变量,且派生类可以修改或新增新的方法使之更适合特殊的需求。

    封装:将客观事物抽象成类,每个类可以把自身数据和方法只让可信的类或对象操作,对不可信的进行信息隐藏。

    多态:允许不同类的对象对同一消息作出响应。不同对象调用相同方法即使参数也相同,最终表现行为是不一样的。

    为什么 Java 语言不支持多重继承?

    为了程序的结构能够更加清晰从而便于维护。假设 Java 语言支持多重继承,类 C 继承自类 A 和类 B,如果类 A 和 B 都有自定义的成员方法 f(),那么当代码中调用类 C 的 f() 会产生二义性。

    Java 语言通过实现多个接口间接支持多重继承,接口由于只包含方法定义,不能有方法的实现,类 C 继承接口 A 与接口 B 时即使它们都有方法f(),也不能直接调用方法,需实现具体的f()方法才能调用,不会产生二义性。

    多重继承会使类型转换、构造方法的调用顺序变得复杂,会影响到性能。

    简述 Java 的多态

    Java 多态可以分为编译时多态和运行时多态。

    编译时多态主要指方法的重载,即通过参数列表的不同来区分不同的方法。

    运行时多态主要指继承父类和实现接口时,可使用父类引用指向子类对象。

    运行时多态的实现:主要依靠方法表,方法表中最先存放的是 Object 类的方法,接下来是该类的父类的方法,最后是该类本身的方法。如果子类改写了父类的方法,那么子类和父类的那些同名方法共享一个方法表项,都被认作是父类的方法。因此可以实现运行时多态。

    Java 提供的多态机制?

    Java 提供了两种用于多态的机制,分别是重载与覆盖。

    重载:重载是指同一个类中有多个同名的方法,但这些方法有不同的参数,在编译期间就可以确定调用哪个方法。

    覆盖:覆盖是指派生类重写基类的方法,使用基类指向其子类的实例对象,或接口的引用变量指向其实现类的实例对象,在程序调用的运行期根据引用变量所指的具体实例对象调用正在运行的那个对象的方法,即需要到运行期才能确定调用哪个方法。

    重载与覆盖的区别?

    • 覆盖是父类与子类之间的关系,是垂直关系;重载是同一类中方法之间的关系,是水平关系。
    • 覆盖只能由一个方法或一对方法产生关系;重载是多个方法之间的关系。
    • 覆盖要求参数列表相同;重载要求参数列表不同。
    • 覆盖中,调用方法体是根据对象的类型来决定的,而重载是根据调用时实参表与形参表来对应选择方法体。
    • 重载方法可以改变返回值的类型,覆盖方法不能改变返回值的类型。

    接口和抽象类的相同点和不同点?

    相同点:

    • 都不能被实例化。
    • 接口的实现类或抽象类的子类需实现接口或抽象类中相应的方法才能被实例化。

    不同点:

    • 接口只能有方法定义,不能有方法的实现,而抽象类可以有方法的定义与实现。

    • 实现接口的关键字为 implements,继承抽象类的关键字为 extends。一个类可以实现多个接口,只能继承一个抽象类。

    • 当子类和父类之间存在逻辑上的层次结构,推荐使用抽象类,有利于功能的累积。当功能不需要,希望支持差别较大的两个或更多对象间的特定交互行为,推荐使用接口。使用接口能降低软件系统的耦合度,便于日后维护或添加删除方法。

    简述抽象类与接口的区别

    抽象类:体现的是 is-a 的关系,如对于 man is a person,就可以将 person 定义为抽象类。

    接口:体现的是 can 的关系。是作为模板实现的。如设置接口 fly,plane 类和 bird 类均可实现该接口。

    一个类只能继承一个抽象类,但可以实现多个接口。

    简述内部类及其作用

    • 成员内部类:作为成员对象的内部类。可以访问 private 及以上外部类的属性和方法。外部类想要访问内部类属性或方法时,必须要创建一个内部类对象,然后通过该对象访问内部类的属性或方法。外部类也可访问 private 修饰的内部类属性。
    • 局部内部类:存在于方法中的内部类。访问权限类似局部变量,只能访问外部类的 final 变量。
    • 匿名内部类:只能使用一次,没有类名,只能访问外部类的 final 变量。
    • 静态内部类:类似类的静态成员变量。

    Java 语言中关键字 static 的作用是什么?

    static 的主要作用有两个:

    • 为某种特定数据类型或对象分配与创建对象个数无关的单一的存储空间。
    • 使得某个方法或属性与类而不是对象关联在一起,即在不创建对象的情况下可通过类直接调用方法或使用类的属性。

    具体而言 static 又可分为 4 种使用方式:

    • 修饰成员变量。用 static 关键字修饰的静态变量在内存中只有一个副本。只要静态变量所在的类被加载,这个静态变量就会被分配空间,可以使用“类.静态变量”和“对象.静态变量”的方法使用。
    • 修饰成员方法。static 修饰的方法无需创建对象就可以被调用。static 方法中不能使用 this 和 super 关键字,不能调用非 static 方法,只能访问所属类的静态成员变量和静态成员方法。
    • 修饰代码块。JVM 在加载类的时候会执行 static 代码块。static 代码块常用于初始化静态变量。static 代码块只会被执行一次。
    • 修饰内部类。static 内部类可以不依赖外部类实例对象而被实例化。静态内部类不能与外部类有相同的名字,不能访问普通成员变量,只能访问外部类中的静态成员和静态成员方法。

    为什么要把 String 设计为不可变?

    • 节省空间:字符串常量存储在 JVM 的字符串池中可以被用户共享。
    • 提高效率:String 可以被不同线程共享,是线程安全的。在涉及多线程操作中不需要同步操作。
    • 安全:String 常被用于用户名、密码、文件名等使用,由于其不可变,可避免黑客行为对其恶意修改。

    简述 String/StringBuffer 与 StringBuilder

    String 类采用利用 final 修饰的字符数组进行字符串保存,因此不可变。如果对 String 类型对象修改,需要新建对象,将老字符和新增加的字符一并存进去。

    StringBuilder,采用无 final 修饰的字符数组进行保存,因此可变。但线程不安全。

    StringBuffer,采用无 final 修饰的字符数组进行保存,可理解为实现线程安全的 StringBuilder。

    判等运算符==与 equals 的区别?

    == 比较的是引用,equals 比较的是内容。

    如果变量是基础数据类型,== 用于比较其对应值是否相等。如果变量指向的是对象,== 用于比较两个对象是否指向同一块存储空间。

    equals 是 Object 类提供的方法之一,每个 Java 类都继承自 Object 类,所以每个对象都具有 equals 这个方法。Object 类中定义的 equals 方法内部是直接调用 == 比较对象的。但通过覆盖的方法可以让它不是比较引用而是比较数据内容。

    简述 Object 类常用方法

    • hashCode:通过对象计算出的散列码。用于 map 型或 equals 方法。需要保证同一个对象多次调用该方法,总返回相同的整型值。
    • equals:判断两个对象是否一致。需保证 equals 方法相同对应的对象 hashCode 也相同。
    • toString: 用字符串表示该对象
    • clone:深拷贝一个对象

    Java 中一维数组和二维数组的声明方式?

    一维数组的声明方式:

    type arrayName[]
    +    

    Java 基础八股文(背诵版)必看👍

    沉默王二2021年12月3日
    • 求职面试
    • 背诵版八股文
    大约 20 分钟

    Java 基础八股文(背诵版)必看👍

    Java 语言具有哪些特点?

    • Java 为纯面向对象的语言。它能够直接反应现实生活中的对象。
    • 具有平台无关性。Java 利用 Java 虚拟机运行字节码,无论是在 Windows、Linux 还是 MacOS 等其它平台对 Java 程序进行编译,编译后的程序可在其它平台运行。
    • Java 为解释型语言,编译器把 Java 代码编译成平台无关的中间代码,然后在 JVM 上解释运行,具有很好的可移植性。
    • Java 提供了很多内置类库。如对多线程支持,对网络通信支持,最重要的一点是提供了垃圾回收器。
    • Java 具有较好的安全性和健壮性。Java 提供了异常处理和垃圾回收机制,去除了 C++中难以理解的指针特性。

    JDK 与 JRE 有什么区别?

    • JDK:Java 开发工具包(Java Development Kit),提供了 Java 的开发环境和运行环境。
    • JRE:Java 运行环境(Java Runtime Environment),提供了 Java 运行所需的环境。
    • JDK 包含了 JRE。如果只运行 Java 程序,安装 JRE 即可。要编写 Java 程序需安装 JDK.

    简述 Java 基本数据类型

    • byte: 占用 1 个字节,取值范围-128 ~ 127
    • short: 占用 2 个字节,取值范围-2^15^ ~ 2^15^-1
    • int:占用 4 个字节,取值范围-2^31^ ~ 2^31^-1
    • long:占用 8 个字节
    • float:占用 4 个字节
    • double:占用 8 个字节
    • char: 占用 2 个字节
    • boolean:占用大小根据实现虚拟机不同有所差异

    简述自动装箱拆箱

    对于 Java 基本数据类型,均对应一个包装类。

    装箱就是自动将基本数据类型转换为包装器类型,如 int->Integer

    拆箱就是自动将包装器类型转换为基本数据类型,如 Integer->int

    简述 Java 访问修饰符

    • default: 默认访问修饰符,在同一包内可见
    • private: 在同一类内可见,不能修饰类
    • protected : 对同一包内的类和所有子类可见,不能修饰类
    • public: 对所有类可见

    构造方法、成员变量初始化以及静态成员变量三者的初始化顺序?

    先后顺序:静态成员变量、成员变量、构造方法。

    详细的先后顺序:父类静态变量、父类静态代码块、子类静态变量、子类静态代码块、父类非静态变量、父类非静态代码块、父类构造函数、子类非静态变量、子类非静态代码块、子类构造函数。

    Java 代码块执行顺序

    • 父类静态代码块(只执行一次)
    • 子类静态代码块(只执行一次)
    • 父类构造代码块
    • 父类构造函数
    • 子类构造代码块
    • 子类构造函数
    • 普通代码块

    面向对象的三大特性?

    继承:对象的一个新类可以从现有的类中派生,派生类可以从它的基类那继承方法和实例变量,且派生类可以修改或新增新的方法使之更适合特殊的需求。

    封装:将客观事物抽象成类,每个类可以把自身数据和方法只让可信的类或对象操作,对不可信的进行信息隐藏。

    多态:允许不同类的对象对同一消息作出响应。不同对象调用相同方法即使参数也相同,最终表现行为是不一样的。

    为什么 Java 语言不支持多重继承?

    为了程序的结构能够更加清晰从而便于维护。假设 Java 语言支持多重继承,类 C 继承自类 A 和类 B,如果类 A 和 B 都有自定义的成员方法 f(),那么当代码中调用类 C 的 f() 会产生二义性。

    Java 语言通过实现多个接口间接支持多重继承,接口由于只包含方法定义,不能有方法的实现,类 C 继承接口 A 与接口 B 时即使它们都有方法f(),也不能直接调用方法,需实现具体的f()方法才能调用,不会产生二义性。

    多重继承会使类型转换、构造方法的调用顺序变得复杂,会影响到性能。

    简述 Java 的多态

    Java 多态可以分为编译时多态和运行时多态。

    编译时多态主要指方法的重载,即通过参数列表的不同来区分不同的方法。

    运行时多态主要指继承父类和实现接口时,可使用父类引用指向子类对象。

    运行时多态的实现:主要依靠方法表,方法表中最先存放的是 Object 类的方法,接下来是该类的父类的方法,最后是该类本身的方法。如果子类改写了父类的方法,那么子类和父类的那些同名方法共享一个方法表项,都被认作是父类的方法。因此可以实现运行时多态。

    Java 提供的多态机制?

    Java 提供了两种用于多态的机制,分别是重载与覆盖。

    重载:重载是指同一个类中有多个同名的方法,但这些方法有不同的参数,在编译期间就可以确定调用哪个方法。

    覆盖:覆盖是指派生类重写基类的方法,使用基类指向其子类的实例对象,或接口的引用变量指向其实现类的实例对象,在程序调用的运行期根据引用变量所指的具体实例对象调用正在运行的那个对象的方法,即需要到运行期才能确定调用哪个方法。

    重载与覆盖的区别?

    • 覆盖是父类与子类之间的关系,是垂直关系;重载是同一类中方法之间的关系,是水平关系。
    • 覆盖只能由一个方法或一对方法产生关系;重载是多个方法之间的关系。
    • 覆盖要求参数列表相同;重载要求参数列表不同。
    • 覆盖中,调用方法体是根据对象的类型来决定的,而重载是根据调用时实参表与形参表来对应选择方法体。
    • 重载方法可以改变返回值的类型,覆盖方法不能改变返回值的类型。

    接口和抽象类的相同点和不同点?

    相同点:

    • 都不能被实例化。
    • 接口的实现类或抽象类的子类需实现接口或抽象类中相应的方法才能被实例化。

    不同点:

    • 接口只能有方法定义,不能有方法的实现,而抽象类可以有方法的定义与实现。

    • 实现接口的关键字为 implements,继承抽象类的关键字为 extends。一个类可以实现多个接口,只能继承一个抽象类。

    • 当子类和父类之间存在逻辑上的层次结构,推荐使用抽象类,有利于功能的累积。当功能不需要,希望支持差别较大的两个或更多对象间的特定交互行为,推荐使用接口。使用接口能降低软件系统的耦合度,便于日后维护或添加删除方法。

    简述抽象类与接口的区别

    抽象类:体现的是 is-a 的关系,如对于 man is a person,就可以将 person 定义为抽象类。

    接口:体现的是 can 的关系。是作为模板实现的。如设置接口 fly,plane 类和 bird 类均可实现该接口。

    一个类只能继承一个抽象类,但可以实现多个接口。

    简述内部类及其作用

    • 成员内部类:作为成员对象的内部类。可以访问 private 及以上外部类的属性和方法。外部类想要访问内部类属性或方法时,必须要创建一个内部类对象,然后通过该对象访问内部类的属性或方法。外部类也可访问 private 修饰的内部类属性。
    • 局部内部类:存在于方法中的内部类。访问权限类似局部变量,只能访问外部类的 final 变量。
    • 匿名内部类:只能使用一次,没有类名,只能访问外部类的 final 变量。
    • 静态内部类:类似类的静态成员变量。

    Java 语言中关键字 static 的作用是什么?

    static 的主要作用有两个:

    • 为某种特定数据类型或对象分配与创建对象个数无关的单一的存储空间。
    • 使得某个方法或属性与类而不是对象关联在一起,即在不创建对象的情况下可通过类直接调用方法或使用类的属性。

    具体而言 static 又可分为 4 种使用方式:

    • 修饰成员变量。用 static 关键字修饰的静态变量在内存中只有一个副本。只要静态变量所在的类被加载,这个静态变量就会被分配空间,可以使用“类.静态变量”和“对象.静态变量”的方法使用。
    • 修饰成员方法。static 修饰的方法无需创建对象就可以被调用。static 方法中不能使用 this 和 super 关键字,不能调用非 static 方法,只能访问所属类的静态成员变量和静态成员方法。
    • 修饰代码块。JVM 在加载类的时候会执行 static 代码块。static 代码块常用于初始化静态变量。static 代码块只会被执行一次。
    • 修饰内部类。static 内部类可以不依赖外部类实例对象而被实例化。静态内部类不能与外部类有相同的名字,不能访问普通成员变量,只能访问外部类中的静态成员和静态成员方法。

    为什么要把 String 设计为不可变?

    • 节省空间:字符串常量存储在 JVM 的字符串池中可以被用户共享。
    • 提高效率:String 可以被不同线程共享,是线程安全的。在涉及多线程操作中不需要同步操作。
    • 安全:String 常被用于用户名、密码、文件名等使用,由于其不可变,可避免黑客行为对其恶意修改。

    简述 String/StringBuffer 与 StringBuilder

    String 类采用利用 final 修饰的字符数组进行字符串保存,因此不可变。如果对 String 类型对象修改,需要新建对象,将老字符和新增加的字符一并存进去。

    StringBuilder,采用无 final 修饰的字符数组进行保存,因此可变。但线程不安全。

    StringBuffer,采用无 final 修饰的字符数组进行保存,可理解为实现线程安全的 StringBuilder。

    判等运算符==与 equals 的区别?

    == 比较的是引用,equals 比较的是内容。

    如果变量是基础数据类型,== 用于比较其对应值是否相等。如果变量指向的是对象,== 用于比较两个对象是否指向同一块存储空间。

    equals 是 Object 类提供的方法之一,每个 Java 类都继承自 Object 类,所以每个对象都具有 equals 这个方法。Object 类中定义的 equals 方法内部是直接调用 == 比较对象的。但通过覆盖的方法可以让它不是比较引用而是比较数据内容。

    简述 Object 类常用方法

    • hashCode:通过对象计算出的散列码。用于 map 型或 equals 方法。需要保证同一个对象多次调用该方法,总返回相同的整型值。
    • equals:判断两个对象是否一致。需保证 equals 方法相同对应的对象 hashCode 也相同。
    • toString: 用字符串表示该对象
    • clone:深拷贝一个对象

    Java 中一维数组和二维数组的声明方式?

    一维数组的声明方式:

    type arrayName[]
     type[] arrayName
     

    二维数组的声明方式:

    type arrayName[][]
     type[][] arrayName
    @@ -51,6 +51,6 @@ type[].getClass()
     类名.class
     

    Java 反射机制是什么?

    Java 反射机制是指在程序的运行过程中可以构造任意一个类的对象、获取任意一个类的成员变量和成员方法、获取任意一个对象所属的类信息、调用任意一个对象的属性和方法。反射机制使得 Java 具有动态获取程序信息和动态调用对象方法的能力。可以通过以下类调用反射 API。

    • Class 类:可获得类属性方法
    • Field 类:获得类的成员变量
    • Method 类:获取类的方法信息
    • Construct 类:获取类的构造方法等信息

    序列化是什么?

    序列化是一种将对象转换成字节序列的过程,用于解决在对对象流进行读写操作时所引发的问题。序列化可以将对象的状态写在流里进行网络传输,或者保存到文件、数据库等系统里,并在需要的时候把该流读取出来重新构造成一个相同的对象。

    简述 Java 序列化与反序列化的实现

    序列化:将 java 对象转化为字节序列,由此可以通过网络对象进行传输。

    反序列化:将字节序列转化为 java 对象。

    具体实现:实现 Serializable 接口,或实现 Externalizable 接口中的 writeExternal()与 readExternal()方法。

    简述 Java 的 List

    List 是一个有序队列,在 Java 中有两种实现方式:

    ArrayList 使用数组实现,是容量可变的非线程安全列表,随机访问快,集合扩容时会创建更大的数组,把原有数组复制到新数组。

    LinkedList 本质是双向链表,与 ArrayList 相比插入和删除速度更快,但随机访问元素很慢。

    Java 中线程安全的基本数据结构有哪些

    • HashTable: 哈希表的线程安全版,效率低
    • ConcurrentHashMap:哈希表的线程安全版,效率高,用于替代 HashTable
    • Vector:线程安全版 Arraylist
    • Stack:线程安全版栈
    • BlockingQueue 及其子类:线程安全版队列

    简述 Java 的 Set

    Set 即集合,该数据结构不允许元素重复且无序。Java 对 Set 有三种实现方式:

    HashSet 通过 HashMap 实现,HashMap 的 Key 即 HashSet 存储的元素,Value 系统自定义一个名为 PRESENT 的 Object 类型常量。判断元素是否相同时,先比较 hashCode,相同后再利用 equals 比较,查询 O(1)

    LinkedHashSet 继承自 HashSet,通过 LinkedHashMap 实现,使用双向链表维护元素插入顺序。

    TreeSet 通过 TreeMap 实现的,底层数据结构是红黑树,添加元素到集合时按照比较规则将其插入合适的位置,保证插入后的集合仍然有序。查询 O(logn)

    简述 Java 的 HashMap

    JDK8 之前底层实现是数组 + 链表,JDK8 改为数组 + 链表/红黑树。主要成员变量包括存储数据的 table 数组、元素数量 size、加载因子 loadFactor。HashMap 中数据以键值对的形式存在,键对应的 hash 值用来计算数组下标,如果两个元素 key 的 hash 值一样,就会发生哈希冲突,被放到同一个链表上。

    table 数组记录 HashMap 的数据,每个下标对应一条链表,所有哈希冲突的数据都会被存放到同一条链表,Node/Entry 节点包含四个成员变量:key、value、next 指针和 hash 值。在 JDK8 后链表超过 8 会转化为红黑树。

    若当前数据/总数据容量>负载因子,Hashmap 将执行扩容操作。默认初始化容量为 16,扩容容量必须是 2 的幂次方、最大容量为 1<< 30 、默认加载因子为 0.75。

    为何 HashMap 线程不安全

    在 JDK1.7 中,HashMap 采用头插法插入元素,因此并发情况下会导致环形链表,产生死循环。

    虽然 JDK1.8 采用了尾插法解决了这个问题,但是并发下的 put 操作也会使前一个 key 被后一个 key 覆盖。

    由于 HashMap 有扩容机制存在,也存在 A 线程进行扩容后,B 线程执行 get 方法出现失误的情况。

    简述 Java 的 TreeMap

    TreeMap 是底层利用红黑树实现的 Map 结构,底层实现是一棵平衡的排序二叉树,由于红黑树的插入、删除、遍历时间复杂度都为 O(logN),所以性能上低于哈希表。但是哈希表无法提供键值对的有序输出,红黑树可以按照键的值的大小有序输出。

    ArrayList、Vector 和 LinkedList 有什么共同点与区别?

    • ArrayList、Vector 和 LinkedList 都是可伸缩的数组,即可以动态改变长度的数组。
    • ArrayList 和 Vector 都是基于存储元素的 Object[] array 来实现的,它们会在内存中开辟一块连续的空间来存储,支持下标、索引访问。但在涉及插入元素时可能需要移动容器中的元素,插入效率较低。当存储元素超过容器的初始化容量大小,ArrayList 与 Vector 均会进行扩容。
    • Vector 是线程安全的,其大部分方法是直接或间接同步的。ArrayList 不是线程安全的,其方法不具有同步性质。LinkedList 也不是线程安全的。
    • LinkedList 采用双向列表实现,对数据索引需要从头开始遍历,因此随机访问效率较低,但在插入元素的时候不需要对数据进行移动,插入效率较高。

    HashMap 和 Hashtable 有什么区别?

    • HashMap 是 Hashtable 的轻量级实现,HashMap 允许 key 和 value 为 null,但最多允许一条记录的 key 为 null.而 HashTable 不允许。
    • HashTable 中的方法是线程安全的,而 HashMap 不是。在多线程访问 HashMap 需要提供额外的同步机制。
    • Hashtable 使用 Enumeration 进行遍历,HashMap 使用 Iterator 进行遍历。

    如何决定使用 HashMap 还是 TreeMap?

    如果对 Map 进行插入、删除或定位一个元素的操作更频繁,HashMap 是更好的选择。如果需要对 key 集合进行有序的遍历,TreeMap 是更好的选择。

    HashSet 中,equals 与 hashCode 之间的关系?

    equals 和 hashCode 这两个方法都是从 object 类中继承过来的,equals 主要用于判断对象的内存地址引用是否是同一个地址;hashCode 根据定义的哈希规则将对象的内存地址转换为一个哈希码。HashSet 中存储的元素是不能重复的,主要通过 hashCode 与 equals 两个方法来判断存储的对象是否相同:

    • 如果两个对象的 hashCode 值不同,说明两个对象不相同。
    • 如果两个对象的 hashCode 值相同,接着会调用对象的 equals 方法,如果 equlas 方法的返回结果为 true,那么说明两个对象相同,否则不相同。

    fail-fast 和 fail-safe 迭代器的区别是什么?

    • fail-fast 直接在容器上进行,在遍历过程中,一旦发现容器中的数据被修改,就会立刻抛出 ConcurrentModificationException 异常从而导致遍历失败。常见的使用 fail-fast 方式的容器有 HashMap 和 ArrayList 等。
    • fail-safe 这种遍历基于容器的一个克隆。因此对容器中的内容修改不影响遍历。常见的使用 fail-safe 方式遍历的容器有 ConcurrentHashMap 和 CopyOnWriteArrayList。

    Collection 和 Collections 有什么区别?

    • Collection 是一个集合接口,它提供了对集合对象进行基本操作的通用接口方法,所有集合都是它的子类,比如 List、Set 等。
    • Collections 是一个包装类,包含了很多静态方法、不能被实例化,而是作为工具类使用,比如提供的排序方法:Collections.sort(list);提供的反转方法:Collections.reverse(list)。

    投稿作者:后端技术小牛说 转载链接:https://mp.weixin.qq.com/s/PmeH38qWVxyIhBpsAsjG7wopen in new window

    - + diff --git a/dist/baguwen/java-thread.html b/dist/baguwen/java-thread.html index ef6bf628..f5f8623a 100644 --- a/dist/baguwen/java-thread.html +++ b/dist/baguwen/java-thread.html @@ -39,10 +39,10 @@ } - + -

    Java 并发编程八股文(背诵版)必看👍

    沉默王二2021年12月3日
    • 求职面试
    • 背诵版八股文
    大约 19 分钟

    Java 并发编程八股文(背诵版)必看👍

    简述Java内存模型(JMM)

    Java内存模型定义了程序中各种变量的访问规则:

    • 所有变量都存储在主存,每个线程都有自己的工作内存。
    • 工作内存中保存了被该线程使用的变量的主存副本,线程对变量的所有操作都必须在工作空间进行,不能直接读写主内存数据。
    • 操作完成后,线程的工作内存通过缓存一致性协议将操作完的数据刷回主存。

    简述as-if-serial

    编译器会对原始的程序进行指令重排序和优化。但不管怎么重排序,其结果都必须和用户原始程序输出的预定结果保持一致。

    简述happens-before八大规则

    • 程序次序规则:一个线程内,按照代码顺序,书写在前面的操作先行发生于书写在后面的操作;
    • 锁定规则:一个unLock操作先行发生于后面对同一个锁的lock操作;
    • volatile变量规则:对一个变量的写操作先行发生于后面对这个变量的读操作;
    • 传递规则:如果操作A先行发生于操作B,而操作B又先行发生于操作C,则可以得出操作A先行发生于操作C;
    • 线程启动规则:Thread对象的start()方法先行发生于此线程的每个一个动作;
    • 线程中断规则:对线程interrupt()方法的调用先行发生于被中断线程的代码检测到中断事件的发生;
    • 线程终结规则:线程中所有的操作都先行发生于线程的终止检测,我们可以通过Thread.join()方法结束、Thread.isAlive()的返回值手段检测到线程已经终止执行;
    • 对象终结规则:一个对象的初始化完成先行发生于他的finalize()方法的开始;

    as-if-serial 和 happens-before 的区别

    as-if-serial 保证单线程程序的执行结果不变,happens-before 保证正确同步的多线程程序的执行结果不变。

    简述原子性操作

    一个操作或者多个操作,要么全部执行并且执行的过程不会被任何因素打断,要么就都不执行,这就是原子性操作。

    简述线程的可见性

    可见性指当一个线程修改了共享变量时,其他线程能够立即得知修改。volatile、synchronized、final 关键字都能保证可见性。

    简述有序性

    虽然多线程存在并发和指令优化等操作,但在本线程内观察该线程的所有执行操作是有序的。

    简述Java中volatile关键字作用

    • 保证变量对所有线程的可见性。当一个线程修改了变量值,新值对于其他线程来说是立即可以得知的。
    • 禁止指令重排。使用 volatile 变量进行写操作,编译器在生成字节码时,会在指令序列中插入内存屏障来禁止特定类型的处理器进行重排序。

    Java线程的实现方式

    • 实现Runnable接口
    • 继承Thread类
    • 实现Callable接口

    简述Java线程的状态

    线程状态有 NEW、RUNNABLE、BLOCK、WAITING、TIMED_WAITING、THERMINATED

    • NEW:新建状态,线程被创建且未启动,此时还未调用 start 方法。
    • RUNNABLE:运行状态。表示线程正在JVM中执行,但是这个执行,不一定真的在跑,也可能在排队等CPU。
    • BLOCKED:阻塞状态。线程等待获取锁,锁还没获得。
    • WAITING:等待状态。线程内run方法执行完Object.wait()/Thread.join()进入该状态。
    • TIMED_WAITING:限期等待。在一定时间之后跳出状态。调用Thread.sleep(long) Object.wait(long) Thread.join(long)进入状态。其中这些参数代表等待的时间。
    • TERMINATED:结束状态。线程调用完run方法进入该状态。

    简述线程通信的方式

    • volatile 关键词修饰变量,保证所有线程对变量访问的可见性。
    • synchronized关键词。确保多个线程在同一时刻只能有一个处于方法或同步块中。
    • wait/notify方法
    • IO通信

    简述线程池

    没有线程池的情况下,多次创建,销毁线程开销比较大。如果在开辟的线程执行完当前任务后复用已创建的线程,可以降低开销、控制最大并发数。

    线程池创建线程时,会将线程封装成工作线程 Worker,Worker 在执行完任务后还会循环获取工作队列中的任务来执行。

    将任务派发给线程池时,会出现以下几种情况

    • 核心线程池未满,创建一个新的线程执行任务。
    • 如果核心线程池已满,工作队列未满,将线程存储在工作队列。
    • 如果工作队列已满,线程数小于最大线程数就创建一个新线程处理任务。
    • 如果超过大小线程数,按照拒绝策略来处理任务。

    线程池参数:

    • corePoolSize:常驻核心线程数。超过该值后如果线程空闲会被销毁。
    • maximumPoolSize:线程池能够容纳同时执行的线程最大数。
    • keepAliveTime:线程空闲时间,线程空闲时间达到该值后会被销毁,直到只剩下 corePoolSize 个线程为止,避免浪费内存资源。
    • workQueue:工作队列。
    • threadFactory:线程工厂,用来生产一组相同任务的线程。
    • handler:拒绝策略。

    拒绝策略有以下几种:

    • AbortPolicy:丢弃任务并抛出异常
    • CallerRunsPolicy:重新尝试提交该任务
    • DiscardOldestPolicy 抛弃队列里等待最久的任务并把当前任务加入队列
    • DiscardPolicy 表示直接抛弃当前任务但不抛出异常。

    简述Executor框架

    Executor框架目的是将任务提交和任务如何运行分离开来的机制。用户不再需要从代码层考虑设计任务的提交运行,只需要调用Executor框架实现类的Execute方法就可以提交任务。

    简述Executor的继承关系

    • Executor:一个接口,其定义了一个接收Runnable对象的方法executor,该方法接收一个Runable实例执行这个任务。
    • ExecutorService:Executor的子类接口,其定义了一个接收Callable对象的方法,返回 Future 对象,同时提供execute方法。
    • ScheduledExecutorService:ExecutorService的子类接口,支持定期执行任务。
    • AbstractExecutorService:抽象类,提供 ExecutorService 执行方法的默认实现。
    • Executors:实现ExecutorService接口的静态工厂类,提供了一系列工厂方法用于创建线程池。
    • ThreadPoolExecutor:继承AbstractExecutorService,用于创建线程池。
    • ForkJoinPool: 继承AbstractExecutorService,Fork 将大任务分叉为多个小任务,然后让小任务执行,Join 是获得小任务的结果,类似于map reduce。
    • ThreadPoolExecutor:继承ThreadPoolExecutor,实现ScheduledExecutorService,用于创建带定时任务的线程池。

    简述线程池的状态

    • Running:能接受新提交的任务,也可以处理阻塞队列的任务。
    • Shutdown:不再接受新提交的任务,但可以处理存量任务,线程池处于running时调用shutdown方法,会进入该状态。
    • Stop:不接受新任务,不处理存量任务,调用shutdownnow进入该状态。
    • Tidying:所有任务已经终止了,worker_count(有效线程数)为0。
    • Terminated:线程池彻底终止。在tidying模式下调用terminated方法会进入该状态。

    简述线程池类型

    • newCachedThreadPool 可缓存线程池,可设置最小线程数和最大线程数,线程空闲1分钟后自动销毁。
    • newFixedThreadPool 指定工作线程数量线程池。
    • newSingleThreadExecutor 单线程Executor。
    • newScheduleThreadPool 支持定时任务的指定工作线程数量线程池。
    • newSingleThreadScheduledExecutor 支持定时任务的单线程Executor。

    简述阻塞队列

    阻塞队列是生产者消费者的实现具体组件之一。当阻塞队列为空时,从队列中获取元素的操作将会被阻塞,当阻塞队列满了,往队列添加元素的操作将会被阻塞。具体实现有:

    • ArrayBlockingQueue:底层是由数组组成的有界阻塞队列。
    • LinkedBlockingQueue:底层是由链表组成的有界阻塞队列。
    • PriorityBlockingQueue:阻塞优先队列。
    • DelayQueue:创建元素时可以指定多久才能从队列中获取当前元素
    • SynchronousQueue:不存储元素的阻塞队列,每一个存储必须等待一个取出操作
    • LinkedTransferQueue:与LinkedBlockingQueue相比多一个transfer方法,即如果当前有消费者正等待接收元素,可以把生产者传入的元素立刻传输给消费者。
    • LinkedBlockingDeque:双向阻塞队列。

    谈一谈ThreadLocal

    ThreadLocal 是线程共享变量。ThreadLoacl 有一个静态内部类 ThreadLocalMap,其 Key 是 ThreadLocal 对象,值是 Entry 对象,ThreadLocalMap是每个线程私有的。

    • set 给ThreadLocalMap设置值。
    • get 获取ThreadLocalMap。
    • remove 删除ThreadLocalMap类型的对象。

    存在的问题:对于线程池,由于线程池会重用 Thread 对象,因此与 Thread 绑定的 ThreadLocal 也会被重用,造成一系列问题。

    比如说内存泄漏。由于 ThreadLocal 是弱引用,但 Entry 的 value 是强引用,因此当 ThreadLocal 被垃圾回收后,value 依旧不会被释放,产生内存泄漏。

    聊聊你对Java并发包下unsafe类的理解

    对于 Java 语言,没有直接的指针组件,一般也不能使用偏移量对某块内存进行操作。这些操作相对来讲是安全(safe)的。

    Java 有个类叫 Unsafe 类,这个类使 Java 拥有了像 C 语言的指针一样操作内存空间的能力,同时也带来了指针的问题。这个类可以说是 Java 并发开发的基础。

    Java中的乐观锁与CAS算法

    乐观锁认为数据发送时发生并发冲突的概率不大,所以读操作前不上锁。

    到了写操作时才会进行判断,数据在此期间是否被其他线程修改。如果发生修改,那就返回写入失败;如果没有被修改,那就执行修改操作,返回修改成功。

    乐观锁一般都采用 Compare And Swap(CAS)算法进行实现。顾名思义,该算法涉及到了两个操作,比较(Compare)和交换(Swap)。

    CAS 算法的思路如下:

    • 该算法认为不同线程对变量的操作时产生竞争的情况比较少。
    • 该算法的核心是对当前读取变量值 E 和内存中的变量旧值 V 进行比较。
    • 如果相等,就代表其他线程没有对该变量进行修改,就将变量值更新为新值 N。
    • 如果不等,就认为在读取值 E 到比较阶段,有其他线程对变量进行过修改,不进行任何操作。

    ABA问题及解决方法简述

    CAS 算法是基于值来做比较的,如果当前有两个线程,一个线程将变量值从 A 改为 B ,再由 B 改回为 A ,当前线程开始执行 CAS 算法时,就很容易认为值没有变化,误认为读取数据到执行 CAS 算法的期间,没有线程修改过数据。

    juc 包提供了一个 AtomicStampedReference,即在原始的版本下加入版本号戳,解决 ABA 问题。

    简述常见的Atomic类

    在很多时候,我们需要的仅仅是一个简单的、高效的、线程安全的++或者--方案,使用synchronized关键字和lock固然可以实现,但代价比较大,此时用原子类更加方便。基本数据类型的原子类有:

    • AtomicInteger 原子更新整型
    • AtomicLong 原子更新长整型
    • AtomicBoolean 原子更新布尔类型

    Atomic数组类型有:

    • AtomicIntegerArray 原子更新整型数组里的元素
    • AtomicLongArray 原子更新长整型数组里的元素
    • AtomicReferenceArray 原子更新引用类型数组里的元素。

    Atomic引用类型有:

    • AtomicReference 原子更新引用类型
    • AtomicMarkableReference 原子更新带有标记位的引用类型,可以绑定一个 boolean 标记
    • AtomicStampedReference 原子更新带有版本号的引用类型

    FieldUpdater类型:

    • AtomicIntegerFieldUpdater 原子更新整型字段的更新器
    • AtomicLongFieldUpdater 原子更新长整型字段的更新器
    • AtomicReferenceFieldUpdater 原子更新引用类型字段的更新器

    简述Atomic类基本实现原理

    以AtomicIntger 为例。

    方法getAndIncrement,以原子方式将当前的值加1,具体实现为:

    • 在 for 死循环中取得 AtomicInteger 里存储的数值
    • 对 AtomicInteger 当前的值加 1
    • 调用 compareAndSet 方法进行原子更新
    • 先检查当前数值是否等于 expect
    • 如果等于则说明当前值没有被其他线程修改,则将值更新为 next,
    • 如果不是会更新失败返回 false,程序会进入 for 循环重新进行 compareAndSet 操作。

    简述CountDownLatch

    CountDownLatch这个类使一个线程等待其他线程各自执行完毕后再执行。是通过一个计数器来实现的,计数器的初始值是线程的数量。每当一个线程执行完毕后,调用countDown方法,计数器的值就减1,当计数器的值为0时,表示所有线程都执行完毕,然后在等待的线程就可以恢复工作了。只能一次性使用,不能reset。

    简述CyclicBarrier

    CyclicBarrier 主要功能和CountDownLatch类似,也是通过一个计数器,使一个线程等待其他线程各自执行完毕后再执行。但是其可以重复使用(reset)。

    简述Semaphore

    Semaphore即信号量。Semaphore 的构造方法参数接收一个 int 值,设置一个计数器,表示可用的许可数量即最大并发数。使用 acquire 方法获得一个许可证,计数器减一,使用 release 方法归还许可,计数器加一。如果此时计数器值为0,线程进入休眠。

    简述Exchanger

    Exchanger类可用于两个线程之间交换信息。可简单地将Exchanger对象理解为一个包含两个格子的容器,通过exchanger方法可以向两个格子中填充信息。线程通过exchange 方法交换数据,第一个线程执行 exchange 方法后会阻塞等待第二个线程执行该方法。当两个线程都到达同步点时这两个线程就可以交换数据当两个格子中的均被填充时,该对象会自动将两个格子的信息交换,然后返回给线程,从而实现两个线程的信息交换。

    简述ConcurrentHashMap

    JDK7采用锁分段技术。首先将数据分成 Segment 数据段,然后给每一个数据段配一把锁,当一个线程占用锁访问其中一个段的数据时,其他段的数据也能被其他线程访问。

    get 除读到空值不需要加锁。该方法先经过一次再散列,再用这个散列值通过散列运算定位到 Segment,最后通过散列算法定位到元素。put 须加锁,首先定位到 Segment,然后进行插入操作,第一步判断是否需要对 Segment 里的 HashEntry 数组进行扩容,第二步定位添加元素的位置,然后将其放入数组。

    JDK8的改进

    • 取消分段锁机制,采用CAS算法进行值的设置,如果CAS失败再使用 synchronized 加锁添加元素
    • 引入红黑树结构,当某个槽内的元素个数超过8且 Node数组 容量大于 64 时,链表转为红黑树。
    • 使用了更加优化的方式统计集合内的元素数量。

    synchronized底层实现原理

    Java 对象底层都会关联一个 monitor,使用 synchronized 时 JVM 会根据使用环境找到对象的 monitor,根据 monitor 的状态进行加解锁的判断。如果成功加锁就成为该 monitor 的唯一持有者,monitor 在被释放前不能再被其他线程获取。

    synchronized在JVM编译后会产生monitorenter 和 monitorexit 这两个字节码指令,获取和释放 monitor。这两个字节码指令都需要一个引用类型的参数指明要锁定和解锁的对象,对于同步普通方法,锁是当前实例对象;对于静态同步方法,锁是当前类的 Class 对象;对于同步方法块,锁是 synchronized 括号里的对象。

    执行 monitorenter 指令时,首先尝试获取对象锁。如果这个对象没有被锁定,或当前线程已经持有锁,就把锁的计数器加 1,执行 monitorexit 指令时会将锁计数器减 1。一旦计数器为 0 锁随即就被释放。

    synchronized关键词使用方法

    • 直接修饰某个实例方法
    • 直接修饰某个静态方法
    • 修饰代码块

    简述Java偏向锁

    JDK 1.6 中提出了偏向锁的概念。该锁提出的原因是,开发者发现多数情况下锁并不存在竞争,一把锁往往是由同一个线程获得的。偏向锁并不会主动释放,这样每次偏向锁进入的时候都会判断该资源是否是偏向自己的,如果是偏向自己的则不需要进行额外的操作,直接可以进入同步操作。

    其申请流程为:

    • 首先需要判断对象的 Mark Word 是否属于偏向模式,如果不属于,那就进入轻量级锁判断逻辑。否则继续下一步判断;
    • 判断目前请求锁的线程 ID 是否和偏向锁本身记录的线程 ID 一致。如果一致,继续下一步的判断,如果不一致,跳转到步骤4;
    • 判断是否需要重偏向。如果不用的话,直接获得偏向锁;
    • 利用 CAS 算法将对象的 Mark Word 进行更改,使线程 ID 部分换成本线程 ID。如果更换成功,则重偏向完成,获得偏向锁。如果失败,则说明有多线程竞争,升级为轻量级锁。

    简述轻量级锁

    轻量级锁是为了在没有竞争的前提下减少重量级锁出现并导致的性能消耗。

    其申请流程为:

    • 如果同步对象没有被锁定,虚拟机将在当前线程的栈帧中建立一个锁记录空间,存储锁对象目前 Mark Word 的拷贝。
    • 虚拟机使用 CAS 尝试把对象的 Mark Word 更新为指向锁记录的指针
    • 如果更新成功即代表该线程拥有了锁,锁标志位将转变为 00,表示处于轻量级锁定状态。
    • 如果更新失败就意味着至少存在一条线程与当前线程竞争。虚拟机检查对象的 Mark Word 是否指向当前线程的栈帧
    • 如果指向当前线程的栈帧,说明当前线程已经拥有了锁,直接进入同步块继续执行
    • 如果不是则说明锁对象已经被其他线程抢占。
    • 如果出现两条以上线程争用同一个锁,轻量级锁就不再有效,将膨胀为重量级锁,锁标志状态变为 10,此时Mark Word 存储的就是指向重量级锁的指针,后面等待锁的线程也必须阻塞。

    简述锁优化策略

    即自适应自旋、锁消除、锁粗化、锁升级等策略偏。

    简述Java的自旋锁

    线程获取锁失败后,可以采用这样的策略,可以不放弃 CPU ,不停的重试内重试,这种操作也称为自旋锁。

    简述自适应自旋锁

    自适应自旋锁自旋次数不再人为设定,通常由前一次在同一个锁上的自旋时间及锁的拥有者的状态决定。

    简述锁粗化

    锁粗化的思想就是扩大加锁范围,避免反复的加锁和解锁。

    简述锁消除

    锁消除是一种更为彻底的优化,在编译时,Java编译器对运行上下文进行扫描,去除不可能存在共享资源竞争的锁。

    简述Lock与ReentrantLock

    Lock接口是 Java并发包的顶层接口。

    可重入锁 ReentrantLock 是 Lock 最常见的实现,与 synchronized 一样可重入。ReentrantLock 在默认情况下是非公平的,可以通过构造方法指定公平锁。一旦使用了公平锁,性能会下降。

    简述AQS

    AQS(AbstractQuenedSynchronizer)抽象的队列式同步器。AQS是将每一条请求共享资源的线程封装成一个锁队列的一个结点(Node),来实现锁的分配。AQS是用来构建锁或其他同步组件的基础框架,它使用一个 volatile int state 变量作为共享资源,如果线程获取资源失败,则进入同步队列等待;如果获取成功就执行临界区代码,释放资源时会通知同步队列中的等待线程。

    子类通过继承同步器并实现它的抽象方法getState、setState 和 compareAndSetState对同步状态进行更改。

    AQS获取独占锁/释放独占锁原理:

    获取:(acquire)

    • 调用 tryAcquire 方法安全地获取线程同步状态,获取失败的线程会被构造同步节点并通过 addWaiter 方法加入到同步队列的尾部,在队列中自旋。
    • 调用 acquireQueued 方法使得该节点以死循环的方式获取同步状态,如果获取不到则阻塞。

    释放:(release)

    • 调用 tryRelease 方法释放同步状态
    • 调用 unparkSuccessor 方法唤醒头节点的后继节点,使后继节点重新尝试获取同步状态。

    AQS获取共享锁/释放共享锁原理

    获取锁(acquireShared)

    • 调用 tryAcquireShared 方法尝试获取同步状态,返回值不小于 0 表示能获取同步状态。
    • 释放(releaseShared),并唤醒后续处于等待状态的节点。

    投稿作者:后端技术小牛说 转载链接:https://mp.weixin.qq.com/s/PmeH38qWVxyIhBpsAsjG7wopen in new window

    - +

    Java 并发编程八股文(背诵版)必看👍

    沉默王二2021年12月3日
    • 求职面试
    • 背诵版八股文
    大约 19 分钟

    Java 并发编程八股文(背诵版)必看👍

    简述Java内存模型(JMM)

    Java内存模型定义了程序中各种变量的访问规则:

    • 所有变量都存储在主存,每个线程都有自己的工作内存。
    • 工作内存中保存了被该线程使用的变量的主存副本,线程对变量的所有操作都必须在工作空间进行,不能直接读写主内存数据。
    • 操作完成后,线程的工作内存通过缓存一致性协议将操作完的数据刷回主存。

    简述as-if-serial

    编译器会对原始的程序进行指令重排序和优化。但不管怎么重排序,其结果都必须和用户原始程序输出的预定结果保持一致。

    简述happens-before八大规则

    • 程序次序规则:一个线程内,按照代码顺序,书写在前面的操作先行发生于书写在后面的操作;
    • 锁定规则:一个unLock操作先行发生于后面对同一个锁的lock操作;
    • volatile变量规则:对一个变量的写操作先行发生于后面对这个变量的读操作;
    • 传递规则:如果操作A先行发生于操作B,而操作B又先行发生于操作C,则可以得出操作A先行发生于操作C;
    • 线程启动规则:Thread对象的start()方法先行发生于此线程的每个一个动作;
    • 线程中断规则:对线程interrupt()方法的调用先行发生于被中断线程的代码检测到中断事件的发生;
    • 线程终结规则:线程中所有的操作都先行发生于线程的终止检测,我们可以通过Thread.join()方法结束、Thread.isAlive()的返回值手段检测到线程已经终止执行;
    • 对象终结规则:一个对象的初始化完成先行发生于他的finalize()方法的开始;

    as-if-serial 和 happens-before 的区别

    as-if-serial 保证单线程程序的执行结果不变,happens-before 保证正确同步的多线程程序的执行结果不变。

    简述原子性操作

    一个操作或者多个操作,要么全部执行并且执行的过程不会被任何因素打断,要么就都不执行,这就是原子性操作。

    简述线程的可见性

    可见性指当一个线程修改了共享变量时,其他线程能够立即得知修改。volatile、synchronized、final 关键字都能保证可见性。

    简述有序性

    虽然多线程存在并发和指令优化等操作,但在本线程内观察该线程的所有执行操作是有序的。

    简述Java中volatile关键字作用

    • 保证变量对所有线程的可见性。当一个线程修改了变量值,新值对于其他线程来说是立即可以得知的。
    • 禁止指令重排。使用 volatile 变量进行写操作,编译器在生成字节码时,会在指令序列中插入内存屏障来禁止特定类型的处理器进行重排序。

    Java线程的实现方式

    • 实现Runnable接口
    • 继承Thread类
    • 实现Callable接口

    简述Java线程的状态

    线程状态有 NEW、RUNNABLE、BLOCK、WAITING、TIMED_WAITING、THERMINATED

    • NEW:新建状态,线程被创建且未启动,此时还未调用 start 方法。
    • RUNNABLE:运行状态。表示线程正在JVM中执行,但是这个执行,不一定真的在跑,也可能在排队等CPU。
    • BLOCKED:阻塞状态。线程等待获取锁,锁还没获得。
    • WAITING:等待状态。线程内run方法执行完Object.wait()/Thread.join()进入该状态。
    • TIMED_WAITING:限期等待。在一定时间之后跳出状态。调用Thread.sleep(long) Object.wait(long) Thread.join(long)进入状态。其中这些参数代表等待的时间。
    • TERMINATED:结束状态。线程调用完run方法进入该状态。

    简述线程通信的方式

    • volatile 关键词修饰变量,保证所有线程对变量访问的可见性。
    • synchronized关键词。确保多个线程在同一时刻只能有一个处于方法或同步块中。
    • wait/notify方法
    • IO通信

    简述线程池

    没有线程池的情况下,多次创建,销毁线程开销比较大。如果在开辟的线程执行完当前任务后复用已创建的线程,可以降低开销、控制最大并发数。

    线程池创建线程时,会将线程封装成工作线程 Worker,Worker 在执行完任务后还会循环获取工作队列中的任务来执行。

    将任务派发给线程池时,会出现以下几种情况

    • 核心线程池未满,创建一个新的线程执行任务。
    • 如果核心线程池已满,工作队列未满,将线程存储在工作队列。
    • 如果工作队列已满,线程数小于最大线程数就创建一个新线程处理任务。
    • 如果超过大小线程数,按照拒绝策略来处理任务。

    线程池参数:

    • corePoolSize:常驻核心线程数。超过该值后如果线程空闲会被销毁。
    • maximumPoolSize:线程池能够容纳同时执行的线程最大数。
    • keepAliveTime:线程空闲时间,线程空闲时间达到该值后会被销毁,直到只剩下 corePoolSize 个线程为止,避免浪费内存资源。
    • workQueue:工作队列。
    • threadFactory:线程工厂,用来生产一组相同任务的线程。
    • handler:拒绝策略。

    拒绝策略有以下几种:

    • AbortPolicy:丢弃任务并抛出异常
    • CallerRunsPolicy:重新尝试提交该任务
    • DiscardOldestPolicy 抛弃队列里等待最久的任务并把当前任务加入队列
    • DiscardPolicy 表示直接抛弃当前任务但不抛出异常。

    简述Executor框架

    Executor框架目的是将任务提交和任务如何运行分离开来的机制。用户不再需要从代码层考虑设计任务的提交运行,只需要调用Executor框架实现类的Execute方法就可以提交任务。

    简述Executor的继承关系

    • Executor:一个接口,其定义了一个接收Runnable对象的方法executor,该方法接收一个Runable实例执行这个任务。
    • ExecutorService:Executor的子类接口,其定义了一个接收Callable对象的方法,返回 Future 对象,同时提供execute方法。
    • ScheduledExecutorService:ExecutorService的子类接口,支持定期执行任务。
    • AbstractExecutorService:抽象类,提供 ExecutorService 执行方法的默认实现。
    • Executors:实现ExecutorService接口的静态工厂类,提供了一系列工厂方法用于创建线程池。
    • ThreadPoolExecutor:继承AbstractExecutorService,用于创建线程池。
    • ForkJoinPool: 继承AbstractExecutorService,Fork 将大任务分叉为多个小任务,然后让小任务执行,Join 是获得小任务的结果,类似于map reduce。
    • ThreadPoolExecutor:继承ThreadPoolExecutor,实现ScheduledExecutorService,用于创建带定时任务的线程池。

    简述线程池的状态

    • Running:能接受新提交的任务,也可以处理阻塞队列的任务。
    • Shutdown:不再接受新提交的任务,但可以处理存量任务,线程池处于running时调用shutdown方法,会进入该状态。
    • Stop:不接受新任务,不处理存量任务,调用shutdownnow进入该状态。
    • Tidying:所有任务已经终止了,worker_count(有效线程数)为0。
    • Terminated:线程池彻底终止。在tidying模式下调用terminated方法会进入该状态。

    简述线程池类型

    • newCachedThreadPool 可缓存线程池,可设置最小线程数和最大线程数,线程空闲1分钟后自动销毁。
    • newFixedThreadPool 指定工作线程数量线程池。
    • newSingleThreadExecutor 单线程Executor。
    • newScheduleThreadPool 支持定时任务的指定工作线程数量线程池。
    • newSingleThreadScheduledExecutor 支持定时任务的单线程Executor。

    简述阻塞队列

    阻塞队列是生产者消费者的实现具体组件之一。当阻塞队列为空时,从队列中获取元素的操作将会被阻塞,当阻塞队列满了,往队列添加元素的操作将会被阻塞。具体实现有:

    • ArrayBlockingQueue:底层是由数组组成的有界阻塞队列。
    • LinkedBlockingQueue:底层是由链表组成的有界阻塞队列。
    • PriorityBlockingQueue:阻塞优先队列。
    • DelayQueue:创建元素时可以指定多久才能从队列中获取当前元素
    • SynchronousQueue:不存储元素的阻塞队列,每一个存储必须等待一个取出操作
    • LinkedTransferQueue:与LinkedBlockingQueue相比多一个transfer方法,即如果当前有消费者正等待接收元素,可以把生产者传入的元素立刻传输给消费者。
    • LinkedBlockingDeque:双向阻塞队列。

    谈一谈ThreadLocal

    ThreadLocal 是线程共享变量。ThreadLoacl 有一个静态内部类 ThreadLocalMap,其 Key 是 ThreadLocal 对象,值是 Entry 对象,ThreadLocalMap是每个线程私有的。

    • set 给ThreadLocalMap设置值。
    • get 获取ThreadLocalMap。
    • remove 删除ThreadLocalMap类型的对象。

    存在的问题:对于线程池,由于线程池会重用 Thread 对象,因此与 Thread 绑定的 ThreadLocal 也会被重用,造成一系列问题。

    比如说内存泄漏。由于 ThreadLocal 是弱引用,但 Entry 的 value 是强引用,因此当 ThreadLocal 被垃圾回收后,value 依旧不会被释放,产生内存泄漏。

    聊聊你对Java并发包下unsafe类的理解

    对于 Java 语言,没有直接的指针组件,一般也不能使用偏移量对某块内存进行操作。这些操作相对来讲是安全(safe)的。

    Java 有个类叫 Unsafe 类,这个类使 Java 拥有了像 C 语言的指针一样操作内存空间的能力,同时也带来了指针的问题。这个类可以说是 Java 并发开发的基础。

    Java中的乐观锁与CAS算法

    乐观锁认为数据发送时发生并发冲突的概率不大,所以读操作前不上锁。

    到了写操作时才会进行判断,数据在此期间是否被其他线程修改。如果发生修改,那就返回写入失败;如果没有被修改,那就执行修改操作,返回修改成功。

    乐观锁一般都采用 Compare And Swap(CAS)算法进行实现。顾名思义,该算法涉及到了两个操作,比较(Compare)和交换(Swap)。

    CAS 算法的思路如下:

    • 该算法认为不同线程对变量的操作时产生竞争的情况比较少。
    • 该算法的核心是对当前读取变量值 E 和内存中的变量旧值 V 进行比较。
    • 如果相等,就代表其他线程没有对该变量进行修改,就将变量值更新为新值 N。
    • 如果不等,就认为在读取值 E 到比较阶段,有其他线程对变量进行过修改,不进行任何操作。

    ABA问题及解决方法简述

    CAS 算法是基于值来做比较的,如果当前有两个线程,一个线程将变量值从 A 改为 B ,再由 B 改回为 A ,当前线程开始执行 CAS 算法时,就很容易认为值没有变化,误认为读取数据到执行 CAS 算法的期间,没有线程修改过数据。

    juc 包提供了一个 AtomicStampedReference,即在原始的版本下加入版本号戳,解决 ABA 问题。

    简述常见的Atomic类

    在很多时候,我们需要的仅仅是一个简单的、高效的、线程安全的++或者--方案,使用synchronized关键字和lock固然可以实现,但代价比较大,此时用原子类更加方便。基本数据类型的原子类有:

    • AtomicInteger 原子更新整型
    • AtomicLong 原子更新长整型
    • AtomicBoolean 原子更新布尔类型

    Atomic数组类型有:

    • AtomicIntegerArray 原子更新整型数组里的元素
    • AtomicLongArray 原子更新长整型数组里的元素
    • AtomicReferenceArray 原子更新引用类型数组里的元素。

    Atomic引用类型有:

    • AtomicReference 原子更新引用类型
    • AtomicMarkableReference 原子更新带有标记位的引用类型,可以绑定一个 boolean 标记
    • AtomicStampedReference 原子更新带有版本号的引用类型

    FieldUpdater类型:

    • AtomicIntegerFieldUpdater 原子更新整型字段的更新器
    • AtomicLongFieldUpdater 原子更新长整型字段的更新器
    • AtomicReferenceFieldUpdater 原子更新引用类型字段的更新器

    简述Atomic类基本实现原理

    以AtomicIntger 为例。

    方法getAndIncrement,以原子方式将当前的值加1,具体实现为:

    • 在 for 死循环中取得 AtomicInteger 里存储的数值
    • 对 AtomicInteger 当前的值加 1
    • 调用 compareAndSet 方法进行原子更新
    • 先检查当前数值是否等于 expect
    • 如果等于则说明当前值没有被其他线程修改,则将值更新为 next,
    • 如果不是会更新失败返回 false,程序会进入 for 循环重新进行 compareAndSet 操作。

    简述CountDownLatch

    CountDownLatch这个类使一个线程等待其他线程各自执行完毕后再执行。是通过一个计数器来实现的,计数器的初始值是线程的数量。每当一个线程执行完毕后,调用countDown方法,计数器的值就减1,当计数器的值为0时,表示所有线程都执行完毕,然后在等待的线程就可以恢复工作了。只能一次性使用,不能reset。

    简述CyclicBarrier

    CyclicBarrier 主要功能和CountDownLatch类似,也是通过一个计数器,使一个线程等待其他线程各自执行完毕后再执行。但是其可以重复使用(reset)。

    简述Semaphore

    Semaphore即信号量。Semaphore 的构造方法参数接收一个 int 值,设置一个计数器,表示可用的许可数量即最大并发数。使用 acquire 方法获得一个许可证,计数器减一,使用 release 方法归还许可,计数器加一。如果此时计数器值为0,线程进入休眠。

    简述Exchanger

    Exchanger类可用于两个线程之间交换信息。可简单地将Exchanger对象理解为一个包含两个格子的容器,通过exchanger方法可以向两个格子中填充信息。线程通过exchange 方法交换数据,第一个线程执行 exchange 方法后会阻塞等待第二个线程执行该方法。当两个线程都到达同步点时这两个线程就可以交换数据当两个格子中的均被填充时,该对象会自动将两个格子的信息交换,然后返回给线程,从而实现两个线程的信息交换。

    简述ConcurrentHashMap

    JDK7采用锁分段技术。首先将数据分成 Segment 数据段,然后给每一个数据段配一把锁,当一个线程占用锁访问其中一个段的数据时,其他段的数据也能被其他线程访问。

    get 除读到空值不需要加锁。该方法先经过一次再散列,再用这个散列值通过散列运算定位到 Segment,最后通过散列算法定位到元素。put 须加锁,首先定位到 Segment,然后进行插入操作,第一步判断是否需要对 Segment 里的 HashEntry 数组进行扩容,第二步定位添加元素的位置,然后将其放入数组。

    JDK8的改进

    • 取消分段锁机制,采用CAS算法进行值的设置,如果CAS失败再使用 synchronized 加锁添加元素
    • 引入红黑树结构,当某个槽内的元素个数超过8且 Node数组 容量大于 64 时,链表转为红黑树。
    • 使用了更加优化的方式统计集合内的元素数量。

    synchronized底层实现原理

    Java 对象底层都会关联一个 monitor,使用 synchronized 时 JVM 会根据使用环境找到对象的 monitor,根据 monitor 的状态进行加解锁的判断。如果成功加锁就成为该 monitor 的唯一持有者,monitor 在被释放前不能再被其他线程获取。

    synchronized在JVM编译后会产生monitorenter 和 monitorexit 这两个字节码指令,获取和释放 monitor。这两个字节码指令都需要一个引用类型的参数指明要锁定和解锁的对象,对于同步普通方法,锁是当前实例对象;对于静态同步方法,锁是当前类的 Class 对象;对于同步方法块,锁是 synchronized 括号里的对象。

    执行 monitorenter 指令时,首先尝试获取对象锁。如果这个对象没有被锁定,或当前线程已经持有锁,就把锁的计数器加 1,执行 monitorexit 指令时会将锁计数器减 1。一旦计数器为 0 锁随即就被释放。

    synchronized关键词使用方法

    • 直接修饰某个实例方法
    • 直接修饰某个静态方法
    • 修饰代码块

    简述Java偏向锁

    JDK 1.6 中提出了偏向锁的概念。该锁提出的原因是,开发者发现多数情况下锁并不存在竞争,一把锁往往是由同一个线程获得的。偏向锁并不会主动释放,这样每次偏向锁进入的时候都会判断该资源是否是偏向自己的,如果是偏向自己的则不需要进行额外的操作,直接可以进入同步操作。

    其申请流程为:

    • 首先需要判断对象的 Mark Word 是否属于偏向模式,如果不属于,那就进入轻量级锁判断逻辑。否则继续下一步判断;
    • 判断目前请求锁的线程 ID 是否和偏向锁本身记录的线程 ID 一致。如果一致,继续下一步的判断,如果不一致,跳转到步骤4;
    • 判断是否需要重偏向。如果不用的话,直接获得偏向锁;
    • 利用 CAS 算法将对象的 Mark Word 进行更改,使线程 ID 部分换成本线程 ID。如果更换成功,则重偏向完成,获得偏向锁。如果失败,则说明有多线程竞争,升级为轻量级锁。

    简述轻量级锁

    轻量级锁是为了在没有竞争的前提下减少重量级锁出现并导致的性能消耗。

    其申请流程为:

    • 如果同步对象没有被锁定,虚拟机将在当前线程的栈帧中建立一个锁记录空间,存储锁对象目前 Mark Word 的拷贝。
    • 虚拟机使用 CAS 尝试把对象的 Mark Word 更新为指向锁记录的指针
    • 如果更新成功即代表该线程拥有了锁,锁标志位将转变为 00,表示处于轻量级锁定状态。
    • 如果更新失败就意味着至少存在一条线程与当前线程竞争。虚拟机检查对象的 Mark Word 是否指向当前线程的栈帧
    • 如果指向当前线程的栈帧,说明当前线程已经拥有了锁,直接进入同步块继续执行
    • 如果不是则说明锁对象已经被其他线程抢占。
    • 如果出现两条以上线程争用同一个锁,轻量级锁就不再有效,将膨胀为重量级锁,锁标志状态变为 10,此时Mark Word 存储的就是指向重量级锁的指针,后面等待锁的线程也必须阻塞。

    简述锁优化策略

    即自适应自旋、锁消除、锁粗化、锁升级等策略偏。

    简述Java的自旋锁

    线程获取锁失败后,可以采用这样的策略,可以不放弃 CPU ,不停的重试内重试,这种操作也称为自旋锁。

    简述自适应自旋锁

    自适应自旋锁自旋次数不再人为设定,通常由前一次在同一个锁上的自旋时间及锁的拥有者的状态决定。

    简述锁粗化

    锁粗化的思想就是扩大加锁范围,避免反复的加锁和解锁。

    简述锁消除

    锁消除是一种更为彻底的优化,在编译时,Java编译器对运行上下文进行扫描,去除不可能存在共享资源竞争的锁。

    简述Lock与ReentrantLock

    Lock接口是 Java并发包的顶层接口。

    可重入锁 ReentrantLock 是 Lock 最常见的实现,与 synchronized 一样可重入。ReentrantLock 在默认情况下是非公平的,可以通过构造方法指定公平锁。一旦使用了公平锁,性能会下降。

    简述AQS

    AQS(AbstractQuenedSynchronizer)抽象的队列式同步器。AQS是将每一条请求共享资源的线程封装成一个锁队列的一个结点(Node),来实现锁的分配。AQS是用来构建锁或其他同步组件的基础框架,它使用一个 volatile int state 变量作为共享资源,如果线程获取资源失败,则进入同步队列等待;如果获取成功就执行临界区代码,释放资源时会通知同步队列中的等待线程。

    子类通过继承同步器并实现它的抽象方法getState、setState 和 compareAndSetState对同步状态进行更改。

    AQS获取独占锁/释放独占锁原理:

    获取:(acquire)

    • 调用 tryAcquire 方法安全地获取线程同步状态,获取失败的线程会被构造同步节点并通过 addWaiter 方法加入到同步队列的尾部,在队列中自旋。
    • 调用 acquireQueued 方法使得该节点以死循环的方式获取同步状态,如果获取不到则阻塞。

    释放:(release)

    • 调用 tryRelease 方法释放同步状态
    • 调用 unparkSuccessor 方法唤醒头节点的后继节点,使后继节点重新尝试获取同步状态。

    AQS获取共享锁/释放共享锁原理

    获取锁(acquireShared)

    • 调用 tryAcquireShared 方法尝试获取同步状态,返回值不小于 0 表示能获取同步状态。
    • 释放(releaseShared),并唤醒后续处于等待状态的节点。

    投稿作者:后端技术小牛说 转载链接:https://mp.weixin.qq.com/s/PmeH38qWVxyIhBpsAsjG7wopen in new window

    + diff --git a/dist/baguwen/jvm.html b/dist/baguwen/jvm.html index b891d633..e6e23460 100644 --- a/dist/baguwen/jvm.html +++ b/dist/baguwen/jvm.html @@ -39,10 +39,10 @@ } - + -

    Java 虚拟机八股文(背诵版)必看👍

    沉默王二2021年12月3日
    • 求职面试
    • 背诵版八股文
    大约 12 分钟

    Java 虚拟机八股文(背诵版)必看👍

    简述JVM内存模型

    线程私有的运行时数据区: 程序计数器、Java 虚拟机栈、本地方法栈。

    线程共享的运行时数据区:Java 堆、方法区。

    简述程序计数器

    程序计数器表示当前线程所执行的字节码的行号指示器。

    程序计数器不会产生StackOverflowError和OutOfMemoryError。

    简述虚拟机栈

    Java 虚拟机栈用来描述 Java 方法执行的内存模型。线程创建时就会分配一个栈空间,线程结束后栈空间被回收。

    栈中元素用于支持虚拟机进行方法调用,每个方法在执行时都会创建一个栈帧存储方法的局部变量表、操作栈、动态链接和返回地址等信息。

    虚拟机栈会产生两类异常:

    • StackOverflowError:线程请求的栈深度大于虚拟机允许的深度抛出。
    • OutOfMemoryError:如果 JVM 栈容量可以动态扩展,虚拟机栈占用内存超出抛出。

    简述本地方法栈

    本地方法栈与虚拟机栈作用相似,不同的是虚拟机栈为虚拟机执行 Java 方法服务,本地方法栈为本地方法服务。可以将虚拟机栈看作普通的java函数对应的内存模型,本地方法栈看作由native关键词修饰的函数对应的内存模型。

    本地方法栈会产生两类异常:

    • StackOverflowError:线程请求的栈深度大于虚拟机允许的深度抛出。
    • OutOfMemoryError:如果 JVM 栈容量可以动态扩展,虚拟机栈占用内存超出抛出。

    简述JVM中的堆

    堆主要作用是存放对象实例,Java 里几乎所有对象实例都在堆上分配内存,堆也是内存管理中最大的一块。Java的垃圾回收主要就是针对堆这一区域进行。 可通过 -Xms 和 -Xmx 设置堆的最小和最大容量。

    堆会抛出 OutOfMemoryError异常。

    简述方法区

    方法区用于存储被虚拟机加载的类信息、常量、静态变量等数据。

    JDK6之前使用永久代实现方法区,容易内存溢出。JDK7 把放在永久代的字符串常量池、静态变量等移出,JDK8 中抛弃永久代,改用在本地内存中实现的元空间来实现方法区,把 JDK 7 中永久代内容移到元空间。

    方法区会抛出 OutOfMemoryError异常。

    简述运行时常量池

    运行时常量池存放常量池表,用于存放编译器生成的各种字面量与符号引用。一般除了保存 Class 文件中描述的符号引用外,还会把符号引用翻译的直接引用也存储在运行时常量池。除此之外,也会存放字符串基本类型。

    JDK8之前,放在方法区,大小受限于方法区。JDK8将运行时常量池存放堆中。

    简述直接内存

    直接内存也称为堆外内存,就是把内存对象分配在JVM堆外的内存区域。这部分内存不是虚拟机管理,而是由操作系统来管理。 Java通过DriectByteBuffer对其进行操作,避免了在 Java 堆和 Native堆来回复制数据。

    简述Java创建对象的过程

    • 检查该指令的参数能否在常量池中定位到一个类的符号引用,并检查引用代表的类是否已被加载、解析和初始化,如果没有就先执行类加载。
    • 通过检查通过后虚拟机将为新生对象分配内存。
    • 完成内存分配后虚拟机将成员变量设为零值
    • 设置对象头,包括哈希码、GC 信息、锁信息、对象所属类的类元信息等。
    • 执行 init 方法,初始化成员变量,执行实例化代码块,调用类的构造方法,并把堆内对象的首地址赋值给引用变量。

    简述JVM给对象分配内存的策略

    • 指针碰撞:这种方式在内存中放一个指针作为分界指示器将使用过的内存放在一边,空闲的放在另一边,通过指针挪动完成分配。
    • 空闲列表:对于 Java 堆内存不规整的情况,虚拟机必须维护一个列表记录哪些内存可用,在分配时从列表中找到一块足够大的空间划分给对象并更新列表记录。

    Java对象内存分配是如何保证线程安全的

    第一种方法,采用CAS机制,配合失败重试的方式保证更新操作的原子性。该方式效率低。

    第二种方法,每个线程在Java堆中预先分配一小块内存,然后再给对象分配内存的时候,直接在自己这块"私有"内存中分配。一般采用这种策略。

    简述对象的内存布局

    对象在堆内存的存储布局可分为对象头、实例数据和对齐填充。

    1)对象头主要包含两部分数据: MarkWord、类型指针。

    MarkWord 用于存储哈希码(HashCode)、GC分代年龄、锁状态标志位、线程持有的锁、偏向线程ID等信息。

    类型指针即对象指向他的类元数据指针,如果对象是一个 Java 数组,会有一块用于记录数组长度的数据。

    2)实例数据存储代码中所定义的各种类型的字段信息。

    3)对齐填充起占位作用。HotSpot 虚拟机要求对象的起始地址必须是8的整数倍,因此需要对齐填充。

    如何判断对象是否是垃圾

    1)引用计数法:

    设置引用计数器,对象被引用计数器加 1,引用失效时计数器减 1,如果计数器为 0 则被标记为垃圾。会存在对象间循环引用的问题,一般不使用这种方法。

    2)可达性分析:

    通过 GC Roots 的根对象作为起始节点,从这些节点开始,根据引用关系向下搜索,如果某个对象没有被搜到,则会被标记为垃圾。可作为 GC Roots 的对象包括虚拟机栈和本地方法栈中引用的对象、类静态属性引用的对象、常量引用的对象。

    简述java的引用类型

    • 强引用: 被强引用关联的对象不会被回收。一般采用 new 方法创建强引用。
    • 软引用:被软引用关联的对象只有在内存不够的情况下才会被回收。一般采用 SoftReference 类来创建软引用。
    • 弱引用:垃圾收集器碰到即回收,也就是说它只能存活到下一次垃圾回收发生之前。一般采用 WeakReference 类来创建弱引用。
    • 虚引用: 无法通过该引用获取对象。唯一目的就是为了能在对象被回收时收到一个系统通知。虚引用必须与引用队列联合使用。

    简述标记清除算法、标记整理算法和标记复制算法

    • 标记清除算法:先标记需清除的对象,之后统一回收。这种方法效率不高,会产生大量不连续的碎片。
    • 标记整理算法:先标记存活对象,然后让所有存活对象向一端移动,之后清理端边界以外的内存
    • 标记复制算法:将可用内存按容量划分为大小相等的两块,每次只使用其中一块。当使用的这块空间用完了,就将存活对象复制到另一块,再把已使用过的内存空间一次清理掉。

    简述分代收集算法

    根据对象存活周期将内存划分为几块,不同块采用适当的收集算法。

    一般将堆分为新生代和老年代,对这两块采用不同的算法。

    新生代使用:标记复制算法

    老年代使用:标记清除或者标记整理算法

    简述Serial垃圾收集器

    Serial垃圾收集器是单线程串行收集器。垃圾回收的时候,必须暂停其他所有线程。新生代使用标记复制算法,老年代使用标记整理算法。简单高效。

    简述ParNew垃圾收集器

    ParNew垃圾收集器可以看作Serial垃圾收集器的多线程版本,新生代使用标记复制算法,老年代使用标记整理算法。

    简述Parallel Scavenge垃圾收集器

    注重吞吐量,即 CPU运行代码时间/CPU耗时总时间(CPU运行代码时间+ 垃圾回收时间)。新生代使用标记复制算法,老年代使用标记整理算法。

    简述CMS垃圾收集器

    CMS垃圾收集器注重最短时间停顿。CMS垃圾收集器为最早提出的并发收集器,垃圾收集线程与用户线程同时工作。采用标记清除算法。该收集器分为初始标记、并发标记、并发预清理、并发清除、并发重置这么几个步骤。

    • 初始标记:暂停其他线程(stop the world),标记与GC roots直接关联的对象。
    • 并发标记:可达性分析过程(程序不会停顿)。
    • 并发预清理:查找执行并发标记阶段从年轻代晋升到老年代的对象,重新标记,暂停虚拟机(stop the world)扫描CMS堆中剩余对象。
    • 并发清除:清理垃圾对象,(程序不会停顿)。
    • 并发重置,重置CMS收集器的数据结构。

    简述G1垃圾收集器

    和Serial、Parallel Scavenge、CMS不同,G1垃圾收集器把堆划分成多个大小相等的独立区域(Region),新生代和老年代不再物理隔离。通过引入 Region 的概念,从而将原来的一整块内存空间划分成多个的小空间,使得每个小空间可以单独进行垃圾回收。

    • 初始标记:标记与GC roots直接关联的对象。
    • 并发标记:可达性分析。
    • 最终标记:对并发标记过程中,用户线程修改的对象再次标记一下。
    • 筛选回收:对各个Region的回收价值和成本进行排序,然后根据用户所期望的GC停顿时间制定回收计划并回收。

    简述Minor GC

    Minor GC指发生在新生代的垃圾收集,因为 Java 对象大多存活时间短,所以 Minor GC 非常频繁,一般回收速度也比较快。

    简述Full GC

    Full GC 是清理整个堆空间—包括年轻代和永久代。调用System.gc(),老年代空间不足,空间分配担保失败,永生代空间不足会产生full gc。

    常见内存分配策略

    大多数情况下对象在新生代 Eden 区分配,当 Eden 没有足够空间时将发起一次 Minor GC。

    大对象需要大量连续内存空间,直接进入老年代区分配。

    如果经历过第一次 Minor GC 仍然存活且能被 Survivor 容纳,该对象就会被移动到 Survivor 中并将年龄设置为 1,并且每熬过一次 Minor GC 年龄就加 1 ,当增加到一定程度(默认15)就会被晋升到老年代。

    如果在 Survivor 中相同年龄所有对象大小的总和大于 Survivor 的一半,年龄不小于该年龄的对象就可以直接进入老年代。

    MinorGC 前,虚拟机必须检查老年代最大可用连续空间是否大于新生代对象总空间,如果满足则说明这次 Minor GC 确定安全。如果不,JVM会查看HandlePromotionFailure 参数是否允许担保失败,如果允许会继续检查老年代最大可用连续空间是否大于历次晋升老年代对象的平均大小,如果满足将Minor GC,否则改成一次 FullGC。

    简述JVM类加载过程

    1)加载:

    • 通过全类名获取类的二进制字节流。
    • 将类的静态存储结构转化为方法区的运行时数据结构。
    • 在内存中生成类的Class对象,作为方法区数据的入口。

    2)验证:对文件格式,元数据,字节码,符号引用等验证正确性。

    3)准备:在方法区内为类变量分配内存并设置为0值。

    4)解析:将符号引用转化为直接引用。

    5)初始化:执行类构造器clinit方法,真正初始化。

    简述JVM中的类加载器

    • BootstrapClassLoader启动类加载器:加载/lib下的jar包和类。 由C++编写。
    • ExtensionClassLoader扩展类加载器: /lib/ext目录下的jar包和类。由Java编写。
    • AppClassLoader应用类加载器,加载当前classPath下的jar包和类。由Java编写。

    简述双亲委派机制

    一个类加载器收到类加载请求之后,首先判断当前类是否被加载过。已经被加载的类会直接返回,如果没有被加载,首先将类加载请求转发给父类加载器,一直转发到启动类加载器,只有当父类加载器无法完成时才尝试自己加载。

    加载类顺序:BootstrapClassLoader->ExtensionClassLoader->AppClassLoader->CustomClassLoader 检查类是否加载顺序: CustomClassLoader->AppClassLoader->ExtensionClassLoader->BootstrapClassLoader

    双亲委派机制的优点

    • 避免类的重复加载。相同的类被不同的类加载器加载会产生不同的类,双亲委派保证了Java程序的稳定运行。
    • 保证核心API不被修改。
    • 如何破坏双亲委派机制
    • 重载loadClass()方法,即自定义类加载器。

    如何构建自定义类加载器

    新建自定义类继承自java.lang.ClassLoader,重写findClass、loadClass、defineClass方法

    JVM常见调优参数

    • -Xms 初始堆大小
    • -Xmx 最大堆大小
    • -XX:NewSize 年轻代大小
    • -XX:MaxNewSize 年轻代最大值
    • -XX:PermSize 永生代初始值
    • -XX:MaxPermSize 永生代最大值
    • -XX:NewRatio 新生代与老年代的比例

    投稿作者:后端技术小牛说 转载链接:https://mp.weixin.qq.com/s/PmeH38qWVxyIhBpsAsjG7wopen in new window

    - +

    Java 虚拟机八股文(背诵版)必看👍

    沉默王二2021年12月3日
    • 求职面试
    • 背诵版八股文
    大约 12 分钟

    Java 虚拟机八股文(背诵版)必看👍

    简述JVM内存模型

    线程私有的运行时数据区: 程序计数器、Java 虚拟机栈、本地方法栈。

    线程共享的运行时数据区:Java 堆、方法区。

    简述程序计数器

    程序计数器表示当前线程所执行的字节码的行号指示器。

    程序计数器不会产生StackOverflowError和OutOfMemoryError。

    简述虚拟机栈

    Java 虚拟机栈用来描述 Java 方法执行的内存模型。线程创建时就会分配一个栈空间,线程结束后栈空间被回收。

    栈中元素用于支持虚拟机进行方法调用,每个方法在执行时都会创建一个栈帧存储方法的局部变量表、操作栈、动态链接和返回地址等信息。

    虚拟机栈会产生两类异常:

    • StackOverflowError:线程请求的栈深度大于虚拟机允许的深度抛出。
    • OutOfMemoryError:如果 JVM 栈容量可以动态扩展,虚拟机栈占用内存超出抛出。

    简述本地方法栈

    本地方法栈与虚拟机栈作用相似,不同的是虚拟机栈为虚拟机执行 Java 方法服务,本地方法栈为本地方法服务。可以将虚拟机栈看作普通的java函数对应的内存模型,本地方法栈看作由native关键词修饰的函数对应的内存模型。

    本地方法栈会产生两类异常:

    • StackOverflowError:线程请求的栈深度大于虚拟机允许的深度抛出。
    • OutOfMemoryError:如果 JVM 栈容量可以动态扩展,虚拟机栈占用内存超出抛出。

    简述JVM中的堆

    堆主要作用是存放对象实例,Java 里几乎所有对象实例都在堆上分配内存,堆也是内存管理中最大的一块。Java的垃圾回收主要就是针对堆这一区域进行。 可通过 -Xms 和 -Xmx 设置堆的最小和最大容量。

    堆会抛出 OutOfMemoryError异常。

    简述方法区

    方法区用于存储被虚拟机加载的类信息、常量、静态变量等数据。

    JDK6之前使用永久代实现方法区,容易内存溢出。JDK7 把放在永久代的字符串常量池、静态变量等移出,JDK8 中抛弃永久代,改用在本地内存中实现的元空间来实现方法区,把 JDK 7 中永久代内容移到元空间。

    方法区会抛出 OutOfMemoryError异常。

    简述运行时常量池

    运行时常量池存放常量池表,用于存放编译器生成的各种字面量与符号引用。一般除了保存 Class 文件中描述的符号引用外,还会把符号引用翻译的直接引用也存储在运行时常量池。除此之外,也会存放字符串基本类型。

    JDK8之前,放在方法区,大小受限于方法区。JDK8将运行时常量池存放堆中。

    简述直接内存

    直接内存也称为堆外内存,就是把内存对象分配在JVM堆外的内存区域。这部分内存不是虚拟机管理,而是由操作系统来管理。 Java通过DriectByteBuffer对其进行操作,避免了在 Java 堆和 Native堆来回复制数据。

    简述Java创建对象的过程

    • 检查该指令的参数能否在常量池中定位到一个类的符号引用,并检查引用代表的类是否已被加载、解析和初始化,如果没有就先执行类加载。
    • 通过检查通过后虚拟机将为新生对象分配内存。
    • 完成内存分配后虚拟机将成员变量设为零值
    • 设置对象头,包括哈希码、GC 信息、锁信息、对象所属类的类元信息等。
    • 执行 init 方法,初始化成员变量,执行实例化代码块,调用类的构造方法,并把堆内对象的首地址赋值给引用变量。

    简述JVM给对象分配内存的策略

    • 指针碰撞:这种方式在内存中放一个指针作为分界指示器将使用过的内存放在一边,空闲的放在另一边,通过指针挪动完成分配。
    • 空闲列表:对于 Java 堆内存不规整的情况,虚拟机必须维护一个列表记录哪些内存可用,在分配时从列表中找到一块足够大的空间划分给对象并更新列表记录。

    Java对象内存分配是如何保证线程安全的

    第一种方法,采用CAS机制,配合失败重试的方式保证更新操作的原子性。该方式效率低。

    第二种方法,每个线程在Java堆中预先分配一小块内存,然后再给对象分配内存的时候,直接在自己这块"私有"内存中分配。一般采用这种策略。

    简述对象的内存布局

    对象在堆内存的存储布局可分为对象头、实例数据和对齐填充。

    1)对象头主要包含两部分数据: MarkWord、类型指针。

    MarkWord 用于存储哈希码(HashCode)、GC分代年龄、锁状态标志位、线程持有的锁、偏向线程ID等信息。

    类型指针即对象指向他的类元数据指针,如果对象是一个 Java 数组,会有一块用于记录数组长度的数据。

    2)实例数据存储代码中所定义的各种类型的字段信息。

    3)对齐填充起占位作用。HotSpot 虚拟机要求对象的起始地址必须是8的整数倍,因此需要对齐填充。

    如何判断对象是否是垃圾

    1)引用计数法:

    设置引用计数器,对象被引用计数器加 1,引用失效时计数器减 1,如果计数器为 0 则被标记为垃圾。会存在对象间循环引用的问题,一般不使用这种方法。

    2)可达性分析:

    通过 GC Roots 的根对象作为起始节点,从这些节点开始,根据引用关系向下搜索,如果某个对象没有被搜到,则会被标记为垃圾。可作为 GC Roots 的对象包括虚拟机栈和本地方法栈中引用的对象、类静态属性引用的对象、常量引用的对象。

    简述java的引用类型

    • 强引用: 被强引用关联的对象不会被回收。一般采用 new 方法创建强引用。
    • 软引用:被软引用关联的对象只有在内存不够的情况下才会被回收。一般采用 SoftReference 类来创建软引用。
    • 弱引用:垃圾收集器碰到即回收,也就是说它只能存活到下一次垃圾回收发生之前。一般采用 WeakReference 类来创建弱引用。
    • 虚引用: 无法通过该引用获取对象。唯一目的就是为了能在对象被回收时收到一个系统通知。虚引用必须与引用队列联合使用。

    简述标记清除算法、标记整理算法和标记复制算法

    • 标记清除算法:先标记需清除的对象,之后统一回收。这种方法效率不高,会产生大量不连续的碎片。
    • 标记整理算法:先标记存活对象,然后让所有存活对象向一端移动,之后清理端边界以外的内存
    • 标记复制算法:将可用内存按容量划分为大小相等的两块,每次只使用其中一块。当使用的这块空间用完了,就将存活对象复制到另一块,再把已使用过的内存空间一次清理掉。

    简述分代收集算法

    根据对象存活周期将内存划分为几块,不同块采用适当的收集算法。

    一般将堆分为新生代和老年代,对这两块采用不同的算法。

    新生代使用:标记复制算法

    老年代使用:标记清除或者标记整理算法

    简述Serial垃圾收集器

    Serial垃圾收集器是单线程串行收集器。垃圾回收的时候,必须暂停其他所有线程。新生代使用标记复制算法,老年代使用标记整理算法。简单高效。

    简述ParNew垃圾收集器

    ParNew垃圾收集器可以看作Serial垃圾收集器的多线程版本,新生代使用标记复制算法,老年代使用标记整理算法。

    简述Parallel Scavenge垃圾收集器

    注重吞吐量,即 CPU运行代码时间/CPU耗时总时间(CPU运行代码时间+ 垃圾回收时间)。新生代使用标记复制算法,老年代使用标记整理算法。

    简述CMS垃圾收集器

    CMS垃圾收集器注重最短时间停顿。CMS垃圾收集器为最早提出的并发收集器,垃圾收集线程与用户线程同时工作。采用标记清除算法。该收集器分为初始标记、并发标记、并发预清理、并发清除、并发重置这么几个步骤。

    • 初始标记:暂停其他线程(stop the world),标记与GC roots直接关联的对象。
    • 并发标记:可达性分析过程(程序不会停顿)。
    • 并发预清理:查找执行并发标记阶段从年轻代晋升到老年代的对象,重新标记,暂停虚拟机(stop the world)扫描CMS堆中剩余对象。
    • 并发清除:清理垃圾对象,(程序不会停顿)。
    • 并发重置,重置CMS收集器的数据结构。

    简述G1垃圾收集器

    和Serial、Parallel Scavenge、CMS不同,G1垃圾收集器把堆划分成多个大小相等的独立区域(Region),新生代和老年代不再物理隔离。通过引入 Region 的概念,从而将原来的一整块内存空间划分成多个的小空间,使得每个小空间可以单独进行垃圾回收。

    • 初始标记:标记与GC roots直接关联的对象。
    • 并发标记:可达性分析。
    • 最终标记:对并发标记过程中,用户线程修改的对象再次标记一下。
    • 筛选回收:对各个Region的回收价值和成本进行排序,然后根据用户所期望的GC停顿时间制定回收计划并回收。

    简述Minor GC

    Minor GC指发生在新生代的垃圾收集,因为 Java 对象大多存活时间短,所以 Minor GC 非常频繁,一般回收速度也比较快。

    简述Full GC

    Full GC 是清理整个堆空间—包括年轻代和永久代。调用System.gc(),老年代空间不足,空间分配担保失败,永生代空间不足会产生full gc。

    常见内存分配策略

    大多数情况下对象在新生代 Eden 区分配,当 Eden 没有足够空间时将发起一次 Minor GC。

    大对象需要大量连续内存空间,直接进入老年代区分配。

    如果经历过第一次 Minor GC 仍然存活且能被 Survivor 容纳,该对象就会被移动到 Survivor 中并将年龄设置为 1,并且每熬过一次 Minor GC 年龄就加 1 ,当增加到一定程度(默认15)就会被晋升到老年代。

    如果在 Survivor 中相同年龄所有对象大小的总和大于 Survivor 的一半,年龄不小于该年龄的对象就可以直接进入老年代。

    MinorGC 前,虚拟机必须检查老年代最大可用连续空间是否大于新生代对象总空间,如果满足则说明这次 Minor GC 确定安全。如果不,JVM会查看HandlePromotionFailure 参数是否允许担保失败,如果允许会继续检查老年代最大可用连续空间是否大于历次晋升老年代对象的平均大小,如果满足将Minor GC,否则改成一次 FullGC。

    简述JVM类加载过程

    1)加载:

    • 通过全类名获取类的二进制字节流。
    • 将类的静态存储结构转化为方法区的运行时数据结构。
    • 在内存中生成类的Class对象,作为方法区数据的入口。

    2)验证:对文件格式,元数据,字节码,符号引用等验证正确性。

    3)准备:在方法区内为类变量分配内存并设置为0值。

    4)解析:将符号引用转化为直接引用。

    5)初始化:执行类构造器clinit方法,真正初始化。

    简述JVM中的类加载器

    • BootstrapClassLoader启动类加载器:加载/lib下的jar包和类。 由C++编写。
    • ExtensionClassLoader扩展类加载器: /lib/ext目录下的jar包和类。由Java编写。
    • AppClassLoader应用类加载器,加载当前classPath下的jar包和类。由Java编写。

    简述双亲委派机制

    一个类加载器收到类加载请求之后,首先判断当前类是否被加载过。已经被加载的类会直接返回,如果没有被加载,首先将类加载请求转发给父类加载器,一直转发到启动类加载器,只有当父类加载器无法完成时才尝试自己加载。

    加载类顺序:BootstrapClassLoader->ExtensionClassLoader->AppClassLoader->CustomClassLoader 检查类是否加载顺序: CustomClassLoader->AppClassLoader->ExtensionClassLoader->BootstrapClassLoader

    双亲委派机制的优点

    • 避免类的重复加载。相同的类被不同的类加载器加载会产生不同的类,双亲委派保证了Java程序的稳定运行。
    • 保证核心API不被修改。
    • 如何破坏双亲委派机制
    • 重载loadClass()方法,即自定义类加载器。

    如何构建自定义类加载器

    新建自定义类继承自java.lang.ClassLoader,重写findClass、loadClass、defineClass方法

    JVM常见调优参数

    • -Xms 初始堆大小
    • -Xmx 最大堆大小
    • -XX:NewSize 年轻代大小
    • -XX:MaxNewSize 年轻代最大值
    • -XX:PermSize 永生代初始值
    • -XX:MaxPermSize 永生代最大值
    • -XX:NewRatio 新生代与老年代的比例

    投稿作者:后端技术小牛说 转载链接:https://mp.weixin.qq.com/s/PmeH38qWVxyIhBpsAsjG7wopen in new window

    + diff --git a/dist/basic-extra-meal/48-keywords.html b/dist/basic-extra-meal/48-keywords.html index 2c32ff30..a1b17bb6 100644 --- a/dist/basic-extra-meal/48-keywords.html +++ b/dist/basic-extra-meal/48-keywords.html @@ -39,10 +39,10 @@ } - + -

    Java中常用的48个关键字

    沉默王二2021年10月22日
    • Java核心
    • Java
    大约 4 分钟

    Java中常用的48个关键字

    “二哥,就我之前学过的这些 Java 代码中,有 public、static、void、main 等等,它们应该都是关键字吧?”三妹的脸上泛着甜甜的笑容,我想她在学习 Java 方面已经变得越来越自信了。

    “是的,三妹。Java 中的关键字可不少呢!你一下子可能记不了那么多,不过,先保留个印象吧,对以后的学习会很有帮助。”

    PS:按照首字母的自然顺序排列。

    1. abstract: 用于声明抽象类,以及抽象方法。

    2. boolean: 用于将变量声明为布尔值类型,只有 true 和 false 两个值。

    3. break: 用于中断循环或 switch 语句。

    4. byte: 用于声明一个可以容纳 8 个比特的变量。

    5. case: 用于在 switch 语句中标记条件的值。

    6. catch: 用于捕获 try 语句中的异常。

    7. char: 用于声明一个可以容纳无符号 16 位比特的 Unicode 字符open in new window的变量。

    8. class: 用于声明一个类。

    9. continue: 用于继续下一个循环,可以在指定条件下跳过其余代码。

    10. default: 用于指定 switch 语句中除去 case 条件之外的默认代码块。

    11. do: 通常和 while 关键字配合使用,do 后紧跟循环体。

    12. double: 用于声明一个可以容纳 64 位浮点数的变量。

    13. else: 用于指示 if 语句中的备用分支。

    14. enum: 用于定义一组固定的常量(枚举)。

    15. extends: 用于指示一个类是从另一个类或接口继承的。

    16. final: 用于指示该变量是不可更改的。

    17. finally:try-catch 配合使用,表示无论是否处理异常,总是执行 finally 块中的代码。

    18. float: 用于声明一个可以容纳 32 位浮点数的变量。

    19. for: 用于声明一个 for 循环,如果循环次数是固定的,建议使用 for 循环。

    20. if: 用于指定条件,如果条件为真,则执行对应代码。

    21. implements: 用于实现接口。

    22. import: 用于导入对应的类或者接口。

    23. instanceof: 用于判断对象是否属于某个类型(class)。

    24. int: 用于声明一个可以容纳 32 位带符号的整数变量。

    25. interface: 用于声明接口。

    26. long: 用于声明一个可以容纳 64 位整数的变量。

    27. native: 用于指定一个方法是通过调用本机接口(非 Java)实现的。

    28. new: 用于创建一个新的对象。

    29. null: 如果一个变量是空的(什么引用也没有指向),就可以将它赋值为 null,和空指针异常息息相关。

    30. package: 用于声明类所在的包。

    31. private: 一个访问权限修饰符,表示方法或变量只对当前类可见。

    32. protected: 一个访问权限修饰符,表示方法或变量对同一包内的类和所有子类可见。

    33. public: 一个访问权限修饰符,除了可以声明方法和变量(所有类可见),还可以声明类。main() 方法必须声明为 public。

    34. return: 用于在代码执行完成后返回(一个值)。

    35. short: 用于声明一个可以容纳 16 位整数的变量。

    36. static: 表示该变量或方法是静态变量或静态方法。

    37. strictfp: 并不常见,通常用于修饰一个方法,确保方法体内的浮点数运算在每个平台上执行的结果相同。

    38. super: 可用于调用父类的方法或者字段。

    39. switch: 通常用于三个(以上)的条件判断。

    40. synchronized: 用于指定多线程代码中的同步方法、变量或者代码块。

    41. this: 可用于在方法或构造函数中引用当前对象。

    42. throw: 主动抛出异常。

    43. throws: 用于声明异常。

    44. transient: 修饰的字段不会被序列化。

    45. try: 于包裹要捕获异常的代码块。

    46. void: 用于指定方法没有返回值。

    47. volatile: 保证不同线程对它修饰的变量进行操作时的可见性,即一个线程修改了某个变量的值,新值对其他线程来说是立即可见的。

    48. while: 如果循环次数不固定,建议使用 while 循环。

    “好了,三妹,关于 Java 中的关键字就先说这 48 个吧,这只是一个大概的介绍,后面还会对一些特殊的关键字单独拎出来详细地讲,比如说重要的 static、final 等。”转动了一下僵硬的脖子后,我对三妹说。

    “二哥,你辛苦了,足足 48 个啊,容我好好消化一下。”

    - +

    Java中常用的48个关键字

    沉默王二2021年10月22日
    • Java核心
    • Java
    大约 4 分钟

    Java中常用的48个关键字

    “二哥,就我之前学过的这些 Java 代码中,有 public、static、void、main 等等,它们应该都是关键字吧?”三妹的脸上泛着甜甜的笑容,我想她在学习 Java 方面已经变得越来越自信了。

    “是的,三妹。Java 中的关键字可不少呢!你一下子可能记不了那么多,不过,先保留个印象吧,对以后的学习会很有帮助。”

    PS:按照首字母的自然顺序排列。

    1. abstract: 用于声明抽象类,以及抽象方法。

    2. boolean: 用于将变量声明为布尔值类型,只有 true 和 false 两个值。

    3. break: 用于中断循环或 switch 语句。

    4. byte: 用于声明一个可以容纳 8 个比特的变量。

    5. case: 用于在 switch 语句中标记条件的值。

    6. catch: 用于捕获 try 语句中的异常。

    7. char: 用于声明一个可以容纳无符号 16 位比特的 Unicode 字符open in new window的变量。

    8. class: 用于声明一个类。

    9. continue: 用于继续下一个循环,可以在指定条件下跳过其余代码。

    10. default: 用于指定 switch 语句中除去 case 条件之外的默认代码块。

    11. do: 通常和 while 关键字配合使用,do 后紧跟循环体。

    12. double: 用于声明一个可以容纳 64 位浮点数的变量。

    13. else: 用于指示 if 语句中的备用分支。

    14. enum: 用于定义一组固定的常量(枚举)。

    15. extends: 用于指示一个类是从另一个类或接口继承的。

    16. final: 用于指示该变量是不可更改的。

    17. finally:try-catch 配合使用,表示无论是否处理异常,总是执行 finally 块中的代码。

    18. float: 用于声明一个可以容纳 32 位浮点数的变量。

    19. for: 用于声明一个 for 循环,如果循环次数是固定的,建议使用 for 循环。

    20. if: 用于指定条件,如果条件为真,则执行对应代码。

    21. implements: 用于实现接口。

    22. import: 用于导入对应的类或者接口。

    23. instanceof: 用于判断对象是否属于某个类型(class)。

    24. int: 用于声明一个可以容纳 32 位带符号的整数变量。

    25. interface: 用于声明接口。

    26. long: 用于声明一个可以容纳 64 位整数的变量。

    27. native: 用于指定一个方法是通过调用本机接口(非 Java)实现的。

    28. new: 用于创建一个新的对象。

    29. null: 如果一个变量是空的(什么引用也没有指向),就可以将它赋值为 null,和空指针异常息息相关。

    30. package: 用于声明类所在的包。

    31. private: 一个访问权限修饰符,表示方法或变量只对当前类可见。

    32. protected: 一个访问权限修饰符,表示方法或变量对同一包内的类和所有子类可见。

    33. public: 一个访问权限修饰符,除了可以声明方法和变量(所有类可见),还可以声明类。main() 方法必须声明为 public。

    34. return: 用于在代码执行完成后返回(一个值)。

    35. short: 用于声明一个可以容纳 16 位整数的变量。

    36. static: 表示该变量或方法是静态变量或静态方法。

    37. strictfp: 并不常见,通常用于修饰一个方法,确保方法体内的浮点数运算在每个平台上执行的结果相同。

    38. super: 可用于调用父类的方法或者字段。

    39. switch: 通常用于三个(以上)的条件判断。

    40. synchronized: 用于指定多线程代码中的同步方法、变量或者代码块。

    41. this: 可用于在方法或构造函数中引用当前对象。

    42. throw: 主动抛出异常。

    43. throws: 用于声明异常。

    44. transient: 修饰的字段不会被序列化。

    45. try: 于包裹要捕获异常的代码块。

    46. void: 用于指定方法没有返回值。

    47. volatile: 保证不同线程对它修饰的变量进行操作时的可见性,即一个线程修改了某个变量的值,新值对其他线程来说是立即可见的。

    48. while: 如果循环次数不固定,建议使用 while 循环。

    “好了,三妹,关于 Java 中的关键字就先说这 48 个吧,这只是一个大概的介绍,后面还会对一些特殊的关键字单独拎出来详细地讲,比如说重要的 static、final 等。”转动了一下僵硬的脖子后,我对三妹说。

    “二哥,你辛苦了,足足 48 个啊,容我好好消化一下。”

    + diff --git a/dist/basic-extra-meal/Overriding.html b/dist/basic-extra-meal/Overriding.html index f46827a9..5fcc9567 100644 --- a/dist/basic-extra-meal/Overriding.html +++ b/dist/basic-extra-meal/Overriding.html @@ -39,10 +39,10 @@ } - + -

    Java重写(Overriding)时应当遵守的11条规则

    沉默王二2022年3月15日
    • Java核心
    • Java
    大约 7 分钟

    Java重写(Overriding)时应当遵守的11条规则

    重写(Overriding)算是 Java 中一个非常重要的概念,理解重写到底是什么对每个 Java 程序员来说都至关重要,这篇文章就来给大家说说重写过程中应当遵守的 12 条规则。

    01、什么是重写?

    重写带来了一种非常重要的能力,可以让子类重新实现从超类那继承过来的方法。在下面这幅图中,Animal 是父类,Dog 是子类,Dog 重新实现了 move() 方法用来和父类进行区分,毕竟狗狗跑起来还是比较有特色的。

    重写的方法和被重写的方法,不仅方法名相同,参数也相同,只不过,方法体有所不同。

    02、哪些方法可以被重写?

    规则一:只能重写继承过来的方法

    因为重写是在子类重新实现从父类继承过来的方法时发生的,所以只能重写继承过来的方法,这很好理解。这就意味着,只能重写那些被 public、protected 或者 default 修饰的方法,private 修饰的方法无法被重写。

    Animal 类有 move()eat()sleep() 三个方法:

    public class Animal {
    +    

    Java重写(Overriding)时应当遵守的11条规则

    沉默王二2022年3月15日
    • Java核心
    • Java
    大约 7 分钟

    Java重写(Overriding)时应当遵守的11条规则

    重写(Overriding)算是 Java 中一个非常重要的概念,理解重写到底是什么对每个 Java 程序员来说都至关重要,这篇文章就来给大家说说重写过程中应当遵守的 12 条规则。

    01、什么是重写?

    重写带来了一种非常重要的能力,可以让子类重新实现从超类那继承过来的方法。在下面这幅图中,Animal 是父类,Dog 是子类,Dog 重新实现了 move() 方法用来和父类进行区分,毕竟狗狗跑起来还是比较有特色的。

    重写的方法和被重写的方法,不仅方法名相同,参数也相同,只不过,方法体有所不同。

    02、哪些方法可以被重写?

    规则一:只能重写继承过来的方法

    因为重写是在子类重新实现从父类继承过来的方法时发生的,所以只能重写继承过来的方法,这很好理解。这就意味着,只能重写那些被 public、protected 或者 default 修饰的方法,private 修饰的方法无法被重写。

    Animal 类有 move()eat()sleep() 三个方法:

    public class Animal {
         public void move() { }
     
         protected void eat() { }
    @@ -137,6 +137,6 @@
         protected void bark() {}
     }
     

    08、重写和 synchronized 方法

    规则十:synchronized 关键字对重写规则没有任何影响

    synchronized 关键字用于在多线程环境中获取和释放监听对象,因此它对重写规则没有任何影响,这就意味着 synchronized 方法可以去重写一个非同步方法。

    09、重写和 strictfp 方法

    规则十一:strictfp 关键字对重写规则没有任何影响

    如果你想让浮点运算更加精确,而且不会因为硬件平台的不同导致执行的结果不一致的话,可以在方法上添加 strictfp 关键字。因此 strictfp 关键和重写规则无关。

    - + diff --git a/dist/basic-extra-meal/annotation.html b/dist/basic-extra-meal/annotation.html index 27704328..d881541e 100644 --- a/dist/basic-extra-meal/annotation.html +++ b/dist/basic-extra-meal/annotation.html @@ -39,10 +39,10 @@ } - + -

    深入理解Java注解

    沉默王二2021年10月22日
    • Java核心
    • Java
    大约 6 分钟

    深入理解Java注解

    “二哥,这节讲注解吗?”三妹问。

    “是的。”我说,“注解是 Java 中非常重要的一部分,但经常被忽视也是真的。之所以这么说是因为我们更倾向成为一名注解的使用者而不是创建者。@Override 注解用过吧?但你知道怎么自定义一个注解吗?”

    三妹毫不犹豫地摇摇头,摆摆手,不好意思地承认自己的确没有自定义过。

    “好吧,哥来告诉你吧。”

    注解(Annotation)是在 Java 1.5 时引入的概念,同 class 和 interface 一样,也属于一种类型。注解提供了一系列数据用来装饰程序代码(类、方法、字段等),但是注解并不是所装饰代码的一部分,它对代码的运行效果没有直接影响,由编译器决定该执行哪些操作。

    来看一段代码。

    public class AutowiredTest {
    +    

    深入理解Java注解

    沉默王二2021年10月22日
    • Java核心
    • Java
    大约 6 分钟

    深入理解Java注解

    “二哥,这节讲注解吗?”三妹问。

    “是的。”我说,“注解是 Java 中非常重要的一部分,但经常被忽视也是真的。之所以这么说是因为我们更倾向成为一名注解的使用者而不是创建者。@Override 注解用过吧?但你知道怎么自定义一个注解吗?”

    三妹毫不犹豫地摇摇头,摆摆手,不好意思地承认自己的确没有自定义过。

    “好吧,哥来告诉你吧。”

    注解(Annotation)是在 Java 1.5 时引入的概念,同 class 和 interface 一样,也属于一种类型。注解提供了一系列数据用来装饰程序代码(类、方法、字段等),但是注解并不是所装饰代码的一部分,它对代码的运行效果没有直接影响,由编译器决定该执行哪些操作。

    来看一段代码。

    public class AutowiredTest {
         @Autowired
         private String name;
     
    @@ -119,6 +119,6 @@
     }
     

    程序输出结果如下:

    {"bookName":"Web全栈开发进阶之路","writerName":"沉默王二"}
     

    从结果上来看:

    1)Writer 类的 age 字段没有装饰 @JsonField 注解,所以没有序列化。

    2)Writer 类的 name 字段装饰了 @JsonField 注解,并且显示指定了字符串“writerName”,所以序列化后变成了 writerName。

    3)Writer 类的 bookName 字段装饰了 @JsonField 注解,但没有显式指定值,所以序列化后仍然是 bookName。

    “怎么样,三妹,是不是也不是特别难?”我对三妹说。

    “撸个注解好像真没什么难度,但你接下来的那个 JsonSerializer 我还需要再消化一下。”三妹很认真地说。

    “嗯,你好好复习下,我看会《编译原理》。”说完我拿起桌子边上的一本书就走了。

    - + diff --git a/dist/basic-extra-meal/box.html b/dist/basic-extra-meal/box.html index 683d9e41..731acbf6 100644 --- a/dist/basic-extra-meal/box.html +++ b/dist/basic-extra-meal/box.html @@ -39,10 +39,10 @@ } - + -

    深入剖析Java中的拆箱和装箱

    沉默王二2021年10月22日
    • Java核心
    • Java
    大约 9 分钟

    深入剖析Java中的拆箱和装箱

    “哥,听说 Java 的每个基本类型都对应了一个包装类型,比如说 int 的包装类型为 Integer,double 的包装类型为 Double,是这样吗?”从三妹这句话当中,能听得出来,她已经提前预习这块内容了。

    “是的,三妹。基本类型和包装类型的区别主要有以下 4 点,我来带你学习一下。”我回答说。我们家的斜对面刚好是一所小学,所以时不时还能听到朗朗的读书声,让人心情非常愉快。

    “三妹,你准备好了吗?我们开始吧。”

    “第一,包装类型可以为 null,而基本类型不可以。别小看这一点区别,它使得包装类型可以应用于 POJO 中,而基本类型则不行。”

    “POJO 是什么呢?”遇到不会的就问,三妹在这一点上还是非常兢兢业业的。

    “POJO 的英文全称是 Plain Ordinary Java Object,翻译一下就是,简单无规则的 Java 对象,只有字段以及对应的 setter 和 getter 方法。”

    class Writer {
    +    

    深入剖析Java中的拆箱和装箱

    沉默王二2021年10月22日
    • Java核心
    • Java
    大约 9 分钟

    深入剖析Java中的拆箱和装箱

    “哥,听说 Java 的每个基本类型都对应了一个包装类型,比如说 int 的包装类型为 Integer,double 的包装类型为 Double,是这样吗?”从三妹这句话当中,能听得出来,她已经提前预习这块内容了。

    “是的,三妹。基本类型和包装类型的区别主要有以下 4 点,我来带你学习一下。”我回答说。我们家的斜对面刚好是一所小学,所以时不时还能听到朗朗的读书声,让人心情非常愉快。

    “三妹,你准备好了吗?我们开始吧。”

    “第一,包装类型可以为 null,而基本类型不可以。别小看这一点区别,它使得包装类型可以应用于 POJO 中,而基本类型则不行。”

    “POJO 是什么呢?”遇到不会的就问,三妹在这一点上还是非常兢兢业业的。

    “POJO 的英文全称是 Plain Ordinary Java Object,翻译一下就是,简单无规则的 Java 对象,只有字段以及对应的 setter 和 getter 方法。”

    class Writer {
     	private Integer age;
     	private String name;
     
    @@ -135,6 +135,6 @@ d = 200long t2 = System.currentTimeMillis();        
     System.out.println(t2-t1);
     

    “知道为什么吗?三妹。”

    “难道是因为 sum 被声明成了包装类型 Long 而不是基本类型 long。”三妹若有所思。

    “是滴,由于 sum 是个 Long 型,而 i 为 int 类型,sum += i 在执行的时候,会先把 i 强转为 long 型,然后再把 sum 拆箱为 long 型进行相加操作,之后再自动装箱为 Long 型赋值给 sum。”

    “三妹,你可以试一下,把 sum 换成 long 型比较一下它们运行的时间。”

    。。。。。。

    “哇,sum 为 Long 型的时候,足足运行了 5825 毫秒;sum 为 long 型的时候,只需要 679 毫秒。”

    “好了,三妹,今天的主题就先讲到这吧。我再去来根华子。”

    - + diff --git a/dist/basic-extra-meal/class-object.html b/dist/basic-extra-meal/class-object.html index 890db6f6..f7194fa6 100644 --- a/dist/basic-extra-meal/class-object.html +++ b/dist/basic-extra-meal/class-object.html @@ -39,10 +39,10 @@ } - + -

    先有Class还是先有Object?

    沉默王二2022年4月13日
    • Java核心
    • Java
    大约 5 分钟

    先有Class还是先有Object?

    Java 对象模型中:

    • 所有的类都是Class类的实例,Object是类,那么Object也是Class类的一个实例。
    • 所有的类都最终继承自Object类,Class是类,那么Class也继承自Object。

    那到底是先有Class还是先有Object? JVM 是怎么处理这个“鸡·蛋”问题呢?

    针对这个问题,我在知乎上看到了 R 大的一个回答,正好解答了我心中的疑惑,就分享出来给各位小伙伴一个参考和启发~

    作者:RednaxelaFX,整理:沉默王二,参考链接:https://www.zhihu.com/question/30301819/answer/47539163


    “鸡・蛋”问题通常都是通过一种叫“自举”(bootstrap)的过程来解决的。

    “鸡蛋问题”的根本矛盾就在于假定了“鸡”或“蛋”的其中一个要先进入“完全可用”的状态。而许多现实中被简化为“鸡蛋问题”的情况实际可以在“混沌”中把“鸡”和“蛋”都初始化好,而不存在先后问题;在它们初始化的过程中,两者都不处于“完全可用”状态,而完成初始化后它们就同时都进入了可用状态。

    打个比方,番茄炒蛋。并不是要先把番茄完全炒好,然后把鸡蛋完全炒好,然后把它们混起来;而是先炒番茄炒到半熟,再炒鸡蛋炒到半熟,然后把两个半熟的部分混在一起同时炒熟。

    对于先有Class还是先有Object这个问题来说,题主假设所有的类都是Class类的实例,Object是类,那么Object也是Class类的一个实例,这个假设就是错的。

    java.lang.Object是一个Java类,但并不是java.lang.Class的一个实例。后者只是一个用于描述Java类与接口的、用于支持反射操作的类型。这点上Java跟其它一些更纯粹的面向对象语言(例如Python和Ruby)不同。

    第二个假设“所有的类都最终继承自Object类,Class是类,那么Class也继承自Object”是对的,java.lang.Classjava.lang.Object的派生类,前者继承自后者。

    虽然第1个假设不对,但“鸡蛋问题”仍然存在:在一个已经启动完毕、可以使用的Java对象系统里,必须要有一个java.lang.Class实例对应java.lang.Object这个类;而java.lang.Classjava.lang.Object的派生类,按“一般思维”,前者应该要在后者完成初始化之后才可以初始化…

    事实是:这些相互依赖的核心类型完全可以在“混沌”中一口气都初始化好,然后对象系统的状态才叫做完成了“bootstrap”,后面就可以按照Java对象系统的一般规则去运行。JVM、JavaScript、Python、Ruby等的运行时都有这样的bootstrap过程。

    在“混沌”(boostrap过程)里,JVM可以为对象系统中最重要的一些核心类型先分配好内存空间,让它们进入[已分配空间]但[尚未完全初始化]状态。

    此时这些对象虽然已经分配了空间,但因为状态还不完整所以尚不可使用。然后,通过这些分配好的空间把这些核心类型之间的引用关系串好。

    到此为止所有动作都由JVM完成,尚未执行任何Java字节码。然后这些核心类型就进入了[完全初始化]状态,对象系统就可以开始自我运行下去,也就是可以开始执行Java字节码来进一步完成Java系统的初始化了。

    在HotSpot VM里,有一个叫做“Universe”的C++类用于记录对象系统的总体状态。它有这么两个有趣的字段记录当前是处于bootstrapping阶段还是已经完全初始化好:

    static bool is_bootstrapping()                      { return _bootstrapping; }
    +    

    先有Class还是先有Object?

    沉默王二2022年4月13日
    • Java核心
    • Java
    大约 5 分钟

    先有Class还是先有Object?

    Java 对象模型中:

    • 所有的类都是Class类的实例,Object是类,那么Object也是Class类的一个实例。
    • 所有的类都最终继承自Object类,Class是类,那么Class也继承自Object。

    那到底是先有Class还是先有Object? JVM 是怎么处理这个“鸡·蛋”问题呢?

    针对这个问题,我在知乎上看到了 R 大的一个回答,正好解答了我心中的疑惑,就分享出来给各位小伙伴一个参考和启发~

    作者:RednaxelaFX,整理:沉默王二,参考链接:https://www.zhihu.com/question/30301819/answer/47539163


    “鸡・蛋”问题通常都是通过一种叫“自举”(bootstrap)的过程来解决的。

    “鸡蛋问题”的根本矛盾就在于假定了“鸡”或“蛋”的其中一个要先进入“完全可用”的状态。而许多现实中被简化为“鸡蛋问题”的情况实际可以在“混沌”中把“鸡”和“蛋”都初始化好,而不存在先后问题;在它们初始化的过程中,两者都不处于“完全可用”状态,而完成初始化后它们就同时都进入了可用状态。

    打个比方,番茄炒蛋。并不是要先把番茄完全炒好,然后把鸡蛋完全炒好,然后把它们混起来;而是先炒番茄炒到半熟,再炒鸡蛋炒到半熟,然后把两个半熟的部分混在一起同时炒熟。

    对于先有Class还是先有Object这个问题来说,题主假设所有的类都是Class类的实例,Object是类,那么Object也是Class类的一个实例,这个假设就是错的。

    java.lang.Object是一个Java类,但并不是java.lang.Class的一个实例。后者只是一个用于描述Java类与接口的、用于支持反射操作的类型。这点上Java跟其它一些更纯粹的面向对象语言(例如Python和Ruby)不同。

    第二个假设“所有的类都最终继承自Object类,Class是类,那么Class也继承自Object”是对的,java.lang.Classjava.lang.Object的派生类,前者继承自后者。

    虽然第1个假设不对,但“鸡蛋问题”仍然存在:在一个已经启动完毕、可以使用的Java对象系统里,必须要有一个java.lang.Class实例对应java.lang.Object这个类;而java.lang.Classjava.lang.Object的派生类,按“一般思维”,前者应该要在后者完成初始化之后才可以初始化…

    事实是:这些相互依赖的核心类型完全可以在“混沌”中一口气都初始化好,然后对象系统的状态才叫做完成了“bootstrap”,后面就可以按照Java对象系统的一般规则去运行。JVM、JavaScript、Python、Ruby等的运行时都有这样的bootstrap过程。

    在“混沌”(boostrap过程)里,JVM可以为对象系统中最重要的一些核心类型先分配好内存空间,让它们进入[已分配空间]但[尚未完全初始化]状态。

    此时这些对象虽然已经分配了空间,但因为状态还不完整所以尚不可使用。然后,通过这些分配好的空间把这些核心类型之间的引用关系串好。

    到此为止所有动作都由JVM完成,尚未执行任何Java字节码。然后这些核心类型就进入了[完全初始化]状态,对象系统就可以开始自我运行下去,也就是可以开始执行Java字节码来进一步完成Java系统的初始化了。

    在HotSpot VM里,有一个叫做“Universe”的C++类用于记录对象系统的总体状态。它有这么两个有趣的字段记录当前是处于bootstrapping阶段还是已经完全初始化好:

    static bool is_bootstrapping()                      { return _bootstrapping; }
     static bool is_fully_initialized()                  { return _fully_initialized; }
     

    然后Universe::genesis()函数会在bootstrap阶段中创建核心类型的对象模型,其中会调用SystemDictionary::initialize()来初始化对象系统的核心类型,其中会进一步跑到SystemDictionary::initialize_preloaded_classes()来创建java.lang.Objectjava.lang.Class等核心类型。

    这个函数在加载了java.lang.Objectjava.lang.Class等核心类型后会调用Universe::fixup_mirrors()来完成前面说的“把引用关系串起来”的动作:

    // Fixup mirrors for classes loaded before java.lang.Class.
     // These calls iterate over the objects currently in the perm gen
    @@ -64,6 +64,6 @@ void Universe::fixup_mirrors(TRAPS) {
     http://hg.openjdk.java.net/jdk8u/jdk8u/hotspot/file/ade5be2b1758/src/share/vm/memory/universe.cpp#l259
     http://hg.openjdk.java.net/jdk8u/jdk8u/hotspot/file/ade5be2b1758/src/share/vm/classfile/systemDictionary.cpp#l1814
     

    分享的最后,二哥要简单说两句,每次看 R 大的内容,总是感觉膝盖忍不住要跪一下,只能说写过 JVM 的男人就是不一样。喜欢研究 CPP 源码的话小伙伴可以再深入学习下,一定会有所收获。

    - + diff --git a/dist/basic-extra-meal/comparable-omparator.html b/dist/basic-extra-meal/comparable-omparator.html index f318a1f3..ee14759c 100644 --- a/dist/basic-extra-meal/comparable-omparator.html +++ b/dist/basic-extra-meal/comparable-omparator.html @@ -39,10 +39,10 @@ } - + -

    详解Java中Comparable和Comparator的区别

    沉默王二2021年11月8日
    • Java核心
    • Java
    大约 4 分钟

    详解Java中Comparable和Comparator的区别

    那天,小二去马蜂窝面试,面试官老王一上来就甩给了他一道面试题:请问Comparable和Comparator有什么区别?小二差点笑出声,因为三年前,也就是 2021 年,他在《Java 程序员进阶之路》专栏上看到过这题😆。

    Comparable 和 Comparator 是 Java 的两个接口,从名字上我们就能够读出来它们俩的相似性:以某种方式来比较两个对象。但它们之间到底有什么区别呢?请随我来,打怪进阶喽!

    01、Comparable

    Comparable 接口的定义非常简单,源码如下所示。

    public interface Comparable<T> {
    +    

    详解Java中Comparable和Comparator的区别

    沉默王二2021年11月8日
    • Java核心
    • Java
    大约 4 分钟

    详解Java中Comparable和Comparator的区别

    那天,小二去马蜂窝面试,面试官老王一上来就甩给了他一道面试题:请问Comparable和Comparator有什么区别?小二差点笑出声,因为三年前,也就是 2021 年,他在《Java 程序员进阶之路》专栏上看到过这题😆。

    Comparable 和 Comparator 是 Java 的两个接口,从名字上我们就能够读出来它们俩的相似性:以某种方式来比较两个对象。但它们之间到底有什么区别呢?请随我来,打怪进阶喽!

    01、Comparable

    Comparable 接口的定义非常简单,源码如下所示。

    public interface Comparable<T> {
         int compareTo(T t);
     }
     

    如果一个类实现了 Comparable 接口(只需要干一件事,重写 compareTo() 方法),就可以按照自己制定的规则将由它创建的对象进行比较。下面给出一个例子。

    public class Cmower implements Comparable<Cmower> {
    @@ -118,6 +118,6 @@ list.sort

    这意味着沉默王三的年纪比沉默王二小,排在第一位;沉默王一的年纪比沉默王二大,排在第三位。和我们的预期完全符合。

    03、到底该用哪一个呢?

    通过上面的两个例子可以比较出 Comparable 和 Comparator 两者之间的区别:

    • 一个类实现了 Comparable 接口,意味着该类的对象可以直接进行比较(排序),但比较(排序)的方式只有一种,很单一。
    • 一个类如果想要保持原样,又需要进行不同方式的比较(排序),就可以定制比较器(实现 Comparator 接口)。
    • Comparable 接口在 java.lang 包下,而 Comparator 接口在 java.util 包下,算不上是亲兄弟,但可以称得上是表(堂)兄弟。

    举个不恰当的例子。我想从洛阳出发去北京看长城,体验一下好汉的感觉,要么坐飞机,要么坐高铁;但如果是孙悟空的话,翻个筋斗就到了。我和孙悟空之间有什么区别呢?孙悟空自己实现了 Comparable 接口(他那年代也没有飞机和高铁,没得选),而我可以借助 Comparator 接口(现代化的交通工具)。


    好了,关于 Comparable 和 Comparator 我们就先聊这么多。总而言之,如果对象的排序需要基于自然顺序,请选择 Comparable,如果需要按照对象的不同属性进行排序,请选择 Comparator

    - + diff --git a/dist/basic-extra-meal/deep-copy.html b/dist/basic-extra-meal/deep-copy.html index ec09204c..4563a17d 100644 --- a/dist/basic-extra-meal/deep-copy.html +++ b/dist/basic-extra-meal/deep-copy.html @@ -39,10 +39,10 @@ } - + -

    彻底讲明白的Java浅拷贝与深拷贝

    沉默王二2021年10月22日
    • Java核心
    • Java
    大约 9 分钟

    彻底讲明白的Java浅拷贝与深拷贝

    “哥,听说浅拷贝和深拷贝是 Java 面试中经常会被问到的一个问题,是这样吗?”

    “还真的是,而且了解浅拷贝和深拷贝的原理,对 Java 是值传递还是引用传递也会有更深的理解。”我肯定地回答。

    “不管是浅拷贝还是深拷贝,都可以通过调用 Object 类的 clone() 方法来完成。”我一边说,一边打开 Intellij IDEA,并找到了 clone() 方法的源码。

    @HotSpotIntrinsicCandidate
    +    

    彻底讲明白的Java浅拷贝与深拷贝

    沉默王二2021年10月22日
    • Java核心
    • Java
    大约 9 分钟

    彻底讲明白的Java浅拷贝与深拷贝

    “哥,听说浅拷贝和深拷贝是 Java 面试中经常会被问到的一个问题,是这样吗?”

    “还真的是,而且了解浅拷贝和深拷贝的原理,对 Java 是值传递还是引用传递也会有更深的理解。”我肯定地回答。

    “不管是浅拷贝还是深拷贝,都可以通过调用 Object 类的 clone() 方法来完成。”我一边说,一边打开 Intellij IDEA,并找到了 clone() 方法的源码。

    @HotSpotIntrinsicCandidate
     protected native Object clone() throws CloneNotSupportedException;
     

    其中 @HotSpotIntrinsicCandidate 是 Java 9 引入的一个注解,被它标注的方法,在 HotSpot 虚拟机中会有一套高效的实现。需要注意的是,clone() 方法同时是一个本地(native)方法,它的具体实现会交给 HotSpot 虚拟机,那就意味着虚拟机在运行该方法的时候,会将其替换为更高效的 C/C++ 代码,进而调用操作系统去完成对象的克隆工作。

    “哥,那你就先说浅拷贝吧!”

    “好的呀。直接上实战代码。”

    class Writer implements Cloneable{
         private int age;
    @@ -287,6 +287,6 @@ writer2.book 变更后:
     writer1:Writer@9629756 age=18, name='二哥', book=Book@735b5592 bookName='编译原理', price=100}}
     writer2:Writer@544fe44c age=18, name='二哥', book=Book@31610302 bookName='永恒的图灵', price=70}}
     

    测试结果和之前用 clone() 方法实现的深拷贝类似。

    “不过,三妹,需要注意,由于是序列化涉及到输入流和输出流的读写,在性能上要比 HotSpot 虚拟机实现的 clone() 方法差很多。”我语重心长地说。

    “好的,二哥,你先去休息吧,让我来琢磨一会,总结一下浅拷贝和深拷贝之间的差异。”

    “嗯嗯。”

    - + diff --git a/dist/basic-extra-meal/enum.html b/dist/basic-extra-meal/enum.html index 96efadcc..96d707e0 100644 --- a/dist/basic-extra-meal/enum.html +++ b/dist/basic-extra-meal/enum.html @@ -39,10 +39,10 @@ } - + -

    Java枚举(enum)

    沉默王二2021年10月22日
    • Java核心
    • Java
    大约 6 分钟

    Java枚举(enum)

    “今天我们来学习枚举吧,三妹!”我说,“同学让你去她家玩了两天,感觉怎么样呀?”

    “心情放松了不少。”三妹说,“可以开始学 Java 了,二哥。”

    “OK。”

    “枚举(enum),是 Java 1.5 时引入的关键字,它表示一种特殊类型的类,继承自 java.lang.Enum。”

    “我们来新建一个枚举 PlayerType。”

    public enum PlayerType {
    +    

    Java枚举(enum)

    沉默王二2021年10月22日
    • Java核心
    • Java
    大约 6 分钟

    Java枚举(enum)

    “今天我们来学习枚举吧,三妹!”我说,“同学让你去她家玩了两天,感觉怎么样呀?”

    “心情放松了不少。”三妹说,“可以开始学 Java 了,二哥。”

    “OK。”

    “枚举(enum),是 Java 1.5 时引入的关键字,它表示一种特殊类型的类,继承自 java.lang.Enum。”

    “我们来新建一个枚举 PlayerType。”

    public enum PlayerType {
         TENNIS,
         FOOTBALL,
         BASKETBALL
    @@ -176,6 +176,6 @@ true
         INSTANCE;
     }
     

    “就这?”三妹睁大了眼睛。

    “对啊,枚举默认实现了 Serializable 接口,因此 Java 虚拟机可以保证该类为单例,这与传统的实现方式不大相同。传统方式中,我们必须确保单例在反序列化期间不能创建任何新实例。”我说。

    “好了,关于枚举就讲这么多吧,三妹,你把这些代码都手敲一遍吧!”

    “好勒,这就安排。二哥,你去休息吧。”

    “嗯嗯。”讲了这么多,必须跑去抽烟机那里安排一根华子了。

    - + diff --git a/dist/basic-extra-meal/equals-hashcode.html b/dist/basic-extra-meal/equals-hashcode.html index d5569ad9..cb1f3394 100644 --- a/dist/basic-extra-meal/equals-hashcode.html +++ b/dist/basic-extra-meal/equals-hashcode.html @@ -39,10 +39,10 @@ } - + -

    一次性搞清楚equals和hashCode

    沉默王二2021年10月22日
    • Java核心
    • Java
    大约 6 分钟

    一次性搞清楚equals和hashCode

    “二哥,我在读《Effective Java》 的时候,第 11 条规约说重写 equals 的时候必须要重写 hashCode 方法,这是为什么呀?”三妹单刀直入地问。

    “三妹啊,这个问题问得非常好,因为它也是面试中经常考的一个知识点。今天哥就带你来梳理一下。”我说。

    Java 是一门面向对象的编程语言,所有的类都会默认继承自 Object 类,而 Object 的中文意思就是“对象”。

    Object 类中有这么两个方法:

    public native int hashCode();
    +    

    一次性搞清楚equals和hashCode

    沉默王二2021年10月22日
    • Java核心
    • Java
    大约 6 分钟

    一次性搞清楚equals和hashCode

    “二哥,我在读《Effective Java》 的时候,第 11 条规约说重写 equals 的时候必须要重写 hashCode 方法,这是为什么呀?”三妹单刀直入地问。

    “三妹啊,这个问题问得非常好,因为它也是面试中经常考的一个知识点。今天哥就带你来梳理一下。”我说。

    Java 是一门面向对象的编程语言,所有的类都会默认继承自 Object 类,而 Object 的中文意思就是“对象”。

    Object 类中有这么两个方法:

    public native int hashCode();
     
     public boolean equals(Object obj) {
             return (this == obj);
    @@ -135,6 +135,6 @@
     

    第二次循环:

    result = (31*1 + Integer(18).hashCode()) * 31 + String("张三").hashCode();
     

    针对姓名年纪不同的对象,这样计算后的哈希值很难很难很难重复的;针对姓名年纪相同的对象,哈希值保持一致。

    再次执行 main 方法,结果如下所示:

    98
     

    因为此时 s1 和 s2 对象的哈希值都为 776408。

    “每当重写 equals 方法时,hashCode 方法也需要重写,原因就是为了保证:如果两个对象调用 equals 方法返回的结果为 true,那么两个对象调用 hashCode 方法返回的结果也必然相同。”我点题了。

    “OK,get 了。”三妹开心地点了点头,看得出来,今天学到了不少。

    - + diff --git a/dist/basic-extra-meal/fanshe.html b/dist/basic-extra-meal/fanshe.html index 3c056ae1..8ae27b06 100644 --- a/dist/basic-extra-meal/fanshe.html +++ b/dist/basic-extra-meal/fanshe.html @@ -39,10 +39,10 @@ } - + -

    大白话说Java反射:入门、使用、原理

    沉默王二2021年10月22日
    • Java核心
    • Java
    大约 7 分钟

    大白话说Java反射:入门、使用、原理

    “二哥,什么是反射呀?”三妹开门见山地问。

    “要想知道什么是反射,就需要先来了解什么是‘正射’。”我笑着对三妹说,“一般情况下,我们在使用某个类之前已经确定它到底是个什么类了,拿到手就直接可以使用 new 关键字来调用构造方法进行初始化,之后使用这个类的对象来进行操作。”

    Writer writer = new Writer();
    +    

    大白话说Java反射:入门、使用、原理

    沉默王二2021年10月22日
    • Java核心
    • Java
    大约 7 分钟

    大白话说Java反射:入门、使用、原理

    “二哥,什么是反射呀?”三妹开门见山地问。

    “要想知道什么是反射,就需要先来了解什么是‘正射’。”我笑着对三妹说,“一般情况下,我们在使用某个类之前已经确定它到底是个什么类了,拿到手就直接可以使用 new 关键字来调用构造方法进行初始化,之后使用这个类的对象来进行操作。”

    Writer writer = new Writer();
     writer.setName("沉默王二");
     

    像上面这个例子,就可以理解为“正射”。而反射就意味着一开始我们不知道要初始化的类到底是什么,也就没法直接使用 new 关键字创建对象了。

    我们只知道这个类的一些基本信息,就好像我们看电影的时候,为了抓住一个犯罪嫌疑人,警察就会问一些目击证人,根据这些证人提供的信息,找专家把犯罪嫌疑人的样貌给画出来——这个过程,就可以称之为反射

    Class clazz = Class.forName("com.itwanger.s39.Writer");
     Method method = clazz.getMethod("setName", String.class);
    @@ -155,6 +155,6 @@ java.lang.String[][]
     

    5)获取方法

    大体上和获取构造方法类似,把关键字 Constructor 换成 Method 即可。

    Method[] methods1 = System.class.getDeclaredMethods();
     Method[] methods2 = System.class.getMethods();
     

    “注意,三妹,如果你想反射访问私有字段和(构造)方法的话,需要使用 Constructor/Field/Method.setAccessible(true) 来绕开 Java 语言的访问限制。”我说。

    “好的,二哥。还有资料可以参考吗?”三妹问。

    “有的,有两篇文章写得非常不错,你在学习反射的时候可以作为参考。”我说。

    第一篇:深入理解 Java 反射和动态代理

    链接:https://dunwu.github.io/javacore/basics/java-reflection.html#_1-%E5%8F%8D%E5%B0%84%E7%AE%80%E4%BB%8B

    第二篇:大白话说Java反射:入门、使用、原理:

    链接:https://www.cnblogs.com/chanshuyi/p/head_first_of_reflection.html

    - + diff --git a/dist/basic-extra-meal/generic.html b/dist/basic-extra-meal/generic.html index e6f55351..b6eeed82 100644 --- a/dist/basic-extra-meal/generic.html +++ b/dist/basic-extra-meal/generic.html @@ -39,10 +39,10 @@ } - + -

    深入理解Java泛型

    沉默王二2021年10月22日
    • Java核心
    • Java
    大约 9 分钟

    深入理解Java泛型

    “二哥,为什么要设计泛型啊?”三妹开门见山地问。

    “三妹啊,听哥慢慢给你讲啊。”我说。

    Java 在 1.5 时增加了泛型机制,据说专家们为此花费了 5 年左右的时间(听起来很不容易)。有了泛型之后,尤其是对集合类的使用,就变得更规范了。

    看下面这段简单的代码。

    ArrayList<String> list = new ArrayList<String>();
    +    

    深入理解Java泛型

    沉默王二2021年10月22日
    • Java核心
    • Java
    大约 9 分钟

    深入理解Java泛型

    “二哥,为什么要设计泛型啊?”三妹开门见山地问。

    “三妹啊,听哥慢慢给你讲啊。”我说。

    Java 在 1.5 时增加了泛型机制,据说专家们为此花费了 5 年左右的时间(听起来很不容易)。有了泛型之后,尤其是对集合类的使用,就变得更规范了。

    看下面这段简单的代码。

    ArrayList<String> list = new ArrayList<String>();
     list.add("沉默王二");
     String str = list.get(0);
     

    “三妹,你能想象到在没有泛型之前该怎么办吗?”

    “嗯,想不到,还是二哥你说吧。”

    嗯,我们可以使用 Object 数组来设计 Arraylist 类。

    class Arraylist {
    @@ -309,6 +309,6 @@ list3.add// Wanger w3 = list3.get(0);
     

    需要注意的是,无法从 Arraylist<? super Wanger> 这样类型的 list3 中取出数据。

    “三妹,关于泛型,这里还有一篇很不错的文章,你等会去看一下。”我说。

    https://www.pdai.tech/md/java/basic/java-basic-x-generic.html

    “对泛型机制讲的也很透彻,你结合二哥给你讲的这些,再深入的学习一下。”

    “好的,二哥。”

    - + diff --git a/dist/basic-extra-meal/hashcode.html b/dist/basic-extra-meal/hashcode.html index 1a36b789..a1786b2a 100644 --- a/dist/basic-extra-meal/hashcode.html +++ b/dist/basic-extra-meal/hashcode.html @@ -39,10 +39,10 @@ } - + -

    深入理解Java中的hashCode方法

    沉默王二2022年3月15日
    • Java核心
    • Java
    大约 9 分钟

    深入理解Java中的hashCode方法

    假期结束了,需要快速切换到工作的状态投入到新的一天当中。放假的时候痛快地玩耍,上班的时候积极的工作,这应该是我们大多数“现代人”该有的生活状态。

    我之所以费尽心思铺垫了前面这段话,就是想告诉大家,技术文虽迟但到,来吧,学起来~

    今天我们来谈谈 Java 中的 hashCode() 方法。众所周知,Java 是一门面向对象的编程语言,所有的类都会默认继承自 Object 类,而 Object 的中文意思就是“对象”。

    Object 类中就包含了 hashCode() 方法:

    @HotSpotIntrinsicCandidate
    +    

    深入理解Java中的hashCode方法

    沉默王二2022年3月15日
    • Java核心
    • Java
    大约 9 分钟

    深入理解Java中的hashCode方法

    假期结束了,需要快速切换到工作的状态投入到新的一天当中。放假的时候痛快地玩耍,上班的时候积极的工作,这应该是我们大多数“现代人”该有的生活状态。

    我之所以费尽心思铺垫了前面这段话,就是想告诉大家,技术文虽迟但到,来吧,学起来~

    今天我们来谈谈 Java 中的 hashCode() 方法。众所周知,Java 是一门面向对象的编程语言,所有的类都会默认继承自 Object 类,而 Object 的中文意思就是“对象”。

    Object 类中就包含了 hashCode() 方法:

    @HotSpotIntrinsicCandidate
     public native int hashCode();
     

    意味着所有的类都会有一个 hashCode() 方法,该方法会返回一个 int 类型的值。由于 hashCode() 方法是一个本地方法(native 关键字修饰的方法,用 C/C++ 语言实现,由 Java 调用),意味着 Object 类中并没有给出具体的实现。

    具体的实现可以参考 jdk/src/hotspot/share/runtime/synchronizer.cpp(源码可以到 GitHub 上 OpenJDK 的仓库中下载)。get_next_hash() 方法会根据 hashCode 的取值来决定采用哪一种哈希值的生成策略。

    并且 hashCode() 方法被 @HotSpotIntrinsicCandidate 注解修饰,说明它在 HotSpot 虚拟机中有一套高效的实现,基于 CPU 指令。

    那大家有没有想过这样一个问题:为什么 Object 类需要一个 hashCode() 方法呢?

    在 Java 中,hashCode() 方法的主要作用就是为了配合哈希表使用的。

    哈希表(Hash Table),也叫散列表,是一种可以通过关键码值(key-value)直接访问的数据结构,它最大的特点就是可以快速实现查找、插入和删除。其中用到的算法叫做哈希,就是把任意长度的输入,变换成固定长度的输出,该输出就是哈希值。像 MD5、SHA1 都用的是哈希算法。

    像 Java 中的 HashSet、Hashtable(注意是小写的 t)、HashMap 都是基于哈希表的具体实现。其中的 HashMap 就是最典型的代表,不仅面试官经常问,工作中的使用频率也非常的高。

    大家想一下,如果没有哈希表,但又需要这样一个数据结构,它里面存放的数据是不允许重复的,该怎么办呢?

    要不使用 equals() 方法进行逐个比较?这种方案当然是可行的。但如果数据量特别特别大,采用 equals() 方法进行逐个对比的效率肯定很低很低,最好的解决方案就是哈希表。

    拿 HashMap 来说吧。当我们要在它里面添加对象时,先调用这个对象的 hashCode() 方法,得到对应的哈希值,然后将哈希值和对象一起放到 HashMap 中。当我们要再添加一个新的对象时:

    • 获取对象的哈希值;
    • 和之前已经存在的哈希值进行比较,如果不相等,直接存进去;
    • 如果有相等的,再调用 equals() 方法进行对象之间的比较,如果相等,不存了;
    • 如果不等,说明哈希冲突了,增加一个链表,存放新的对象;
    • 如果链表的长度大于 8,转为红黑树来处理。

    就这么一套下来,调用 equals() 方法的频率就大大降低了。也就是说,只要哈希算法足够的高效,把发生哈希冲突的频率降到最低,哈希表的效率就特别的高。

    来看一下 HashMap 的哈希算法:

    static final int hash(Object key) {
         int h;
    @@ -144,6 +144,6 @@
       return value;
     }
     

    如果没有 C++ 基础的话,不用细致去看每一行代码,我们只通过表面去了解一下 get_next_hash() 这个方法就行。其中的 hashCode 变量是 JVM 启动时的一个全局参数,可以通过它来切换哈希值的生成策略。

    • hashCode==0,调用操作系统 OS 的 random() 方法返回随机数。
    • hashCode == 1,在 STW(stop-the-world)操作中,这种策略通常用于同步方案中。利用对象地址进行计算,使用不经常更新的随机数(GVars.stw_random)参与其中。
    • hashCode == 2,使用返回 1,用于某些情况下的测试。
    • hashCode == 3,从 0 开始计算哈希值,不是线程安全的,多个线程可能会得到相同的哈希值。
    • hashCode == 4,与创建对象的内存位置有关,原样输出。
    • hashCode == 5,默认值,支持多线程,使用了 Marsaglia 的 xor-shift 算法产生伪随机数。所谓的 xor-shift 算法,简单来说,看起来就是一个移位寄存器,每次移入的位由寄存器中若干位取异或生成。所谓的伪随机数,不是完全随机的,但是真随机生成比较困难,所以只要能通过一定的随机数统计检测,就可以当作真随机数来使用。

    - + diff --git a/dist/basic-extra-meal/immutable.html b/dist/basic-extra-meal/immutable.html index fbb5be1f..c71d26d9 100644 --- a/dist/basic-extra-meal/immutable.html +++ b/dist/basic-extra-meal/immutable.html @@ -39,10 +39,10 @@ } - + -

    深入理解Java中的不可变对象

    沉默王二2021年11月8日
    • Java核心
    • Java
    大约 6 分钟

    深入理解Java中的不可变对象

    二哥,你能给我说说为什么 String 是 immutable 类(不可变对象)吗?我想研究它,想知道为什么它就不可变了,这种强烈的愿望就像想研究浩瀚的星空一样。但无奈自身功力有限,始终觉得雾里看花终隔一层。二哥你的文章总是充满趣味性,我想一定能够说明白,我也一定能够看明白,能在接下来写一写吗?

    收到读者小 R 的私信后,我就总感觉自己有一种义不容辞的责任,非要把 immutable 类说明白不可!

    01、什么是不可变类

    一个类的对象在通过构造方法创建后如果状态不会再被改变,那么它就是一个不可变(immutable)类。它的所有成员变量的赋值仅在构造方法中完成,不会提供任何 setter 方法供外部类去修改。

    还记得《神雕侠侣》中小龙女的古墓吗?随着那一声巨响,仅有的通道就被无情地关闭了。别较真那个密道,我这么说只是为了打开你的想象力,让你对不可变类有一个更直观的印象。

    自从有了多线程,生产力就被无限地放大了,所有的程序员都爱它,因为强大的硬件能力被充分地利用了。但与此同时,所有的程序员都对它心生忌惮,因为一不小心,多线程就会把对象的状态变得混乱不堪。

    为了保护状态的原子性、可见性、有序性,我们程序员可以说是竭尽所能。其中,synchronized(同步)关键字是最简单最入门的一种解决方案。

    假如说类是不可变的,那么对象的状态就也是不可变的。这样的话,每次修改对象的状态,就会产生一个新的对象供不同的线程使用,我们程序员就不必再担心并发问题了。

    02、常见的不可变类

    提到不可变类,几乎所有的程序员第一个想到的,就是 String 类。那为什么 String 类要被设计成不可变的呢?

    1)常量池的需要

    字符串常量池是 Java 堆内存中一个特殊的存储区域,当创建一个 String 对象时,假如此字符串在常量池中不存在,那么就创建一个;假如已经存,就不会再创建了,而是直接引用已经存在的对象。这样做能够减少 JVM 的内存开销,提高效率。

    2)hashCode 的需要

    因为字符串是不可变的,所以在它创建的时候,其 hashCode 就被缓存了,因此非常适合作为哈希值(比如说作为 HashMap 的键),多次调用只返回同一个值,来提高效率。

    3)线程安全

    就像之前说的那样,如果对象的状态是可变的,那么在多线程环境下,就很容易造成不可预期的结果。而 String 是不可变的,就可以在多个线程之间共享,不需要同步处理。

    因此,当我们调用 String 类的任何方法(比如说 trim()substring()toLowerCase())时,总会返回一个新的对象,而不影响之前的值。

    String cmower = "沉默王二,一枚有趣的程序员";
    +    

    深入理解Java中的不可变对象

    沉默王二2021年11月8日
    • Java核心
    • Java
    大约 6 分钟

    深入理解Java中的不可变对象

    二哥,你能给我说说为什么 String 是 immutable 类(不可变对象)吗?我想研究它,想知道为什么它就不可变了,这种强烈的愿望就像想研究浩瀚的星空一样。但无奈自身功力有限,始终觉得雾里看花终隔一层。二哥你的文章总是充满趣味性,我想一定能够说明白,我也一定能够看明白,能在接下来写一写吗?

    收到读者小 R 的私信后,我就总感觉自己有一种义不容辞的责任,非要把 immutable 类说明白不可!

    01、什么是不可变类

    一个类的对象在通过构造方法创建后如果状态不会再被改变,那么它就是一个不可变(immutable)类。它的所有成员变量的赋值仅在构造方法中完成,不会提供任何 setter 方法供外部类去修改。

    还记得《神雕侠侣》中小龙女的古墓吗?随着那一声巨响,仅有的通道就被无情地关闭了。别较真那个密道,我这么说只是为了打开你的想象力,让你对不可变类有一个更直观的印象。

    自从有了多线程,生产力就被无限地放大了,所有的程序员都爱它,因为强大的硬件能力被充分地利用了。但与此同时,所有的程序员都对它心生忌惮,因为一不小心,多线程就会把对象的状态变得混乱不堪。

    为了保护状态的原子性、可见性、有序性,我们程序员可以说是竭尽所能。其中,synchronized(同步)关键字是最简单最入门的一种解决方案。

    假如说类是不可变的,那么对象的状态就也是不可变的。这样的话,每次修改对象的状态,就会产生一个新的对象供不同的线程使用,我们程序员就不必再担心并发问题了。

    02、常见的不可变类

    提到不可变类,几乎所有的程序员第一个想到的,就是 String 类。那为什么 String 类要被设计成不可变的呢?

    1)常量池的需要

    字符串常量池是 Java 堆内存中一个特殊的存储区域,当创建一个 String 对象时,假如此字符串在常量池中不存在,那么就创建一个;假如已经存,就不会再创建了,而是直接引用已经存在的对象。这样做能够减少 JVM 的内存开销,提高效率。

    2)hashCode 的需要

    因为字符串是不可变的,所以在它创建的时候,其 hashCode 就被缓存了,因此非常适合作为哈希值(比如说作为 HashMap 的键),多次调用只返回同一个值,来提高效率。

    3)线程安全

    就像之前说的那样,如果对象的状态是可变的,那么在多线程环境下,就很容易造成不可预期的结果。而 String 是不可变的,就可以在多个线程之间共享,不需要同步处理。

    因此,当我们调用 String 类的任何方法(比如说 trim()substring()toLowerCase())时,总会返回一个新的对象,而不影响之前的值。

    String cmower = "沉默王二,一枚有趣的程序员";
     cmower.substring(0,4);
     System.out.println(cmower);// 沉默王二,一枚有趣的程序员
     

    虽然调用 substring() 方法对 cmower 进行了截取,但 cmower 的值没有改变。

    除了 String 类,包装器类 Integer、Long 等也是不可变类。

    03、手撸不可变类

    看懂一个不可变类也许容易,但要创建一个自定义的不可变类恐怕就有点难了。但知难而进是我们作为一名优秀的程序员不可或缺的品质,正因为不容易,我们才能真正地掌握它。

    接下来,就请和我一起,来自定义一个不可变类吧。一个不可变类,必须要满足以下 4 个条件:

    1)确保类是 final 的,不允许被其他类继承。

    2)确保所有的成员变量(字段)是 final 的,这样的话,它们就只能在构造方法中初始化值,并且不会在随后被修改。

    3)不要提供任何 setter 方法。

    4)如果要修改类的状态,必须返回一个新的对象。

    按照以上条件,我们来自定义一个简单的不可变类 Writer。

    public final class Writer {
    @@ -136,6 +136,6 @@ cmower.subst
     

    这样的话,构造方法初始化后的 Book 对象就不会再被修改了。此时,运行 WriterDemo,就会发现价格不再发生变化了。

    定价:Book{name='Web全栈开发进阶之路', price=79}
     促销价:Book{name='Web全栈开发进阶之路', price=79}
     

    04、总结

    不可变类有很多优点,就像之前提到的 String 类那样,尤其是在多线程环境下,它非常的安全。尽管每次修改都会创建一个新的对象,增加了内存的消耗,但这个缺点相比它带来的优点,显然是微不足道的——无非就是捡了西瓜,丢了芝麻。

    - + diff --git a/dist/basic-extra-meal/instanceof-jvm.html b/dist/basic-extra-meal/instanceof-jvm.html index 365eeffe..90980ecf 100644 --- a/dist/basic-extra-meal/instanceof-jvm.html +++ b/dist/basic-extra-meal/instanceof-jvm.html @@ -39,10 +39,10 @@ } - + -

    instanceof关键字是如何实现的?

    沉默王二2022年4月13日
    • Java核心
    • Java
    大约 4 分钟

    instanceof关键字是如何实现的?

    小二那天去面试,碰到了这个问题:“instanceof 关键字是如何实现的?”面试官希望他能从底层来分析一下,结果小二没答上来,就来问我。

    我唯唯诺诺,强装镇定,只好把 R 大的一篇回答甩给了他,并且叮嘱他:“认认真真看,玩完后要是还不明白,再来问我。。。”

    作者:RednaxelaFX,整理:沉默王二,链接:https://www.zhihu.com/question/21574535/answer/18998914


    场景一:月薪 3000 元一下的码农职位

    用 Java 伪代码来表现instanceof关键字在Java语言规范所描述的运行时语义,是这样的:

    // obj instanceof T
    +    

    instanceof关键字是如何实现的?

    沉默王二2022年4月13日
    • Java核心
    • Java
    大约 4 分钟

    instanceof关键字是如何实现的?

    小二那天去面试,碰到了这个问题:“instanceof 关键字是如何实现的?”面试官希望他能从底层来分析一下,结果小二没答上来,就来问我。

    我唯唯诺诺,强装镇定,只好把 R 大的一篇回答甩给了他,并且叮嘱他:“认认真真看,玩完后要是还不明白,再来问我。。。”

    作者:RednaxelaFX,整理:沉默王二,链接:https://www.zhihu.com/question/21574535/answer/18998914


    场景一:月薪 3000 元一下的码农职位

    用 Java 伪代码来表现instanceof关键字在Java语言规范所描述的运行时语义,是这样的:

    // obj instanceof T
     boolean result;
     if (obj == null) {
       result = false;
    @@ -66,6 +66,6 @@
       return false;
     }
     

    HotSpot VM的两个编译器,Client Compiler (C1) 与 Server Compiler (C2) 各自对子类型判断的实现有更进一步的优化。实际上在JVM里,instanceof的功能就实现了4份,VM runtime、解释器、C1、C2各一份。

    VM runtime的:

    http://hg.openjdk.java.net/jdk7u/jdk7u/hotspot/file/tip/src/share/vm/oops/oop.inline.hpp

    分享的最后,二哥简单来说一下。

    这个问题涉及语法细节,涉及jvm实现,涉及编译器,还涉及一点点数据结构设计,比较考验一个 Java 程序员的内功,如果要回答到论文的程度,那真的是,面试官也得提前备好知识点,不然应聘者的回答啥也听不懂就挺尴尬的。

    反正 R 大回答里的很多细节我都是第一次听,逃了逃了。。。。。。

    - + diff --git a/dist/basic-extra-meal/int-cache.html b/dist/basic-extra-meal/int-cache.html index 95f460b5..c1f32bf3 100644 --- a/dist/basic-extra-meal/int-cache.html +++ b/dist/basic-extra-meal/int-cache.html @@ -39,10 +39,10 @@ } - + -

    Java中int、Integer、new Integer之间的区别

    沉默王二2021年10月22日
    • Java核心
    • Java
    大约 4 分钟

    Java中int、Integer、new Integer之间的区别

    “三妹,今天我们来补一个小的知识点:Java 数据类型缓存池。”我喝了一口枸杞泡的茶后对三妹说,“考你一个问题哈:new Integer(18) 与 Integer.valueOf(18) 的区别是什么?”

    “难道不一样吗?”三妹有点诧异。

    “不一样的。”我笑着说。

    • new Integer(18) 每次都会新建一个对象;
    • Integer.valueOf(18) 会使⽤用缓存池中的对象,多次调用只会取同⼀一个对象的引用。

    来看下面这段代码:

    Integer x = new Integer(18);
    +    

    Java中int、Integer、new Integer之间的区别

    沉默王二2021年10月22日
    • Java核心
    • Java
    大约 4 分钟

    Java中int、Integer、new Integer之间的区别

    “三妹,今天我们来补一个小的知识点:Java 数据类型缓存池。”我喝了一口枸杞泡的茶后对三妹说,“考你一个问题哈:new Integer(18) 与 Integer.valueOf(18) 的区别是什么?”

    “难道不一样吗?”三妹有点诧异。

    “不一样的。”我笑着说。

    • new Integer(18) 每次都会新建一个对象;
    • Integer.valueOf(18) 会使⽤用缓存池中的对象,多次调用只会取同⼀一个对象的引用。

    来看下面这段代码:

    Integer x = new Integer(18);
     Integer y = new Integer(18);
     System.out.println(x == y);
     
    @@ -105,6 +105,6 @@ false
     

    “呀,报错了呀。”三妹喊道。

    Exception in thread "main" java.lang.AssertionError
             at com.itwanger.s51.AssertTest.main(AssertTest.java:9)
     

    “是滴,因为 126 小于 127。”我回答道。

    “原来 assert 是这样用的啊,我明白了。”三妹表示学会了。

    “那,缓存池之所以存在的原因也是因为这样做可以提高程序的整体性能,因为相对来说,比如说 Integer,-128~127 这个范围内的 256 个数字使用的频率会高一点。”我总结道。

    “get 了!二哥你真棒,又学到了。”三妹很开心~

    - + diff --git a/dist/basic-extra-meal/java-naming.html b/dist/basic-extra-meal/java-naming.html index e04365df..5fa8fc2a 100644 --- a/dist/basic-extra-meal/java-naming.html +++ b/dist/basic-extra-meal/java-naming.html @@ -39,10 +39,10 @@ } - + -

    Java命名规范(非常全面,可以收藏)

    沉默王二2021年10月22日
    • Java核心
    • Java
    大约 6 分钟

    Java命名规范(非常全面,可以收藏)

    “二哥,Java 中的命名约定都有哪些呢?”三妹的脸上泛着甜甜的笑容,她开始对接下来要学习的内容充满期待了,这正是我感到欣慰的地方。

    “对于我们中国人来说,名字也是有讲究的,比如说我叫沉默王二,你就叫沉默王三,哈哈。”我笑着对三妹说。

    命名约定决定我们使用什么样的标识符来命名包、类、字段、方法等等,虽然这个规则不是强制的,可以遵守,也可以不遵守,但如果不遵守的话,就会带来很多不必要的麻烦。

    起个好的名字,就好像穿一件得体的衣服,呈现给人的用户体验是完全不一样的。

    好的命名可以让你的代码更易读,包括你自己和你的小伙伴,看一眼,不用想太多,就能明白代码是干嘛的。

    拿我这个笔名“沉默王二”来举例吧,读起来我就觉得朗朗上口,读者看到这个笔名就知道我是一个什么样的人——对不熟的人保持沉默,对熟的人妙语连珠,哈哈。

    01、包(package)

    包的命名应该遵守以下规则:

    • 应该全部是小写字母

    • 点分隔符之间有且仅有一个自然语义的英语单词

    • 包名统一使用单数形式,比如说 com.itwanger.util 不能是 com.itwanger.utils

    • 在最新的 Java 编程规范中,要求开发人员在自己定义的包名前加上唯一的前缀。由于互联网上的域名是不会重复的,所以多数开发人员采用自己公司(或者个人博客)在互联网上的域名称作为包的唯一前缀。比如我文章中出现的代码示例的包名就是 package com.itwanger

    02、类(class)

    类的命名应该遵守以下规则:

    • 必须以大写字母开头

    • 最好是一个名词,比如说 System

    • 类名使用 UpperCamelCase(驼峰式命名)风格

    • 尽量不要省略成单词的首字母,但以下情形例外:DO/BO/DTO/VO/AO/ PO / UID 等

    另外,如果是抽象类的话,使用 Abstract 或 Base 开头;如果是异常类的话,使用 Exception 结尾;如果是测试类的话,使用 Test 结尾。

    03、接口(interface)

    接口的命名应该遵守以下规则:

    • 必须以大写字母开头

    • 最好是一个形容词,比如说 Runnable

    • 尽量不要省略成单词的首字母

    来看个例子:

    interface Printable {}
    +    

    Java命名规范(非常全面,可以收藏)

    沉默王二2021年10月22日
    • Java核心
    • Java
    大约 6 分钟

    Java命名规范(非常全面,可以收藏)

    “二哥,Java 中的命名约定都有哪些呢?”三妹的脸上泛着甜甜的笑容,她开始对接下来要学习的内容充满期待了,这正是我感到欣慰的地方。

    “对于我们中国人来说,名字也是有讲究的,比如说我叫沉默王二,你就叫沉默王三,哈哈。”我笑着对三妹说。

    命名约定决定我们使用什么样的标识符来命名包、类、字段、方法等等,虽然这个规则不是强制的,可以遵守,也可以不遵守,但如果不遵守的话,就会带来很多不必要的麻烦。

    起个好的名字,就好像穿一件得体的衣服,呈现给人的用户体验是完全不一样的。

    好的命名可以让你的代码更易读,包括你自己和你的小伙伴,看一眼,不用想太多,就能明白代码是干嘛的。

    拿我这个笔名“沉默王二”来举例吧,读起来我就觉得朗朗上口,读者看到这个笔名就知道我是一个什么样的人——对不熟的人保持沉默,对熟的人妙语连珠,哈哈。

    01、包(package)

    包的命名应该遵守以下规则:

    • 应该全部是小写字母

    • 点分隔符之间有且仅有一个自然语义的英语单词

    • 包名统一使用单数形式,比如说 com.itwanger.util 不能是 com.itwanger.utils

    • 在最新的 Java 编程规范中,要求开发人员在自己定义的包名前加上唯一的前缀。由于互联网上的域名是不会重复的,所以多数开发人员采用自己公司(或者个人博客)在互联网上的域名称作为包的唯一前缀。比如我文章中出现的代码示例的包名就是 package com.itwanger

    02、类(class)

    类的命名应该遵守以下规则:

    • 必须以大写字母开头

    • 最好是一个名词,比如说 System

    • 类名使用 UpperCamelCase(驼峰式命名)风格

    • 尽量不要省略成单词的首字母,但以下情形例外:DO/BO/DTO/VO/AO/ PO / UID 等

    另外,如果是抽象类的话,使用 Abstract 或 Base 开头;如果是异常类的话,使用 Exception 结尾;如果是测试类的话,使用 Test 结尾。

    03、接口(interface)

    接口的命名应该遵守以下规则:

    • 必须以大写字母开头

    • 最好是一个形容词,比如说 Runnable

    • 尽量不要省略成单词的首字母

    来看个例子:

    interface Printable {}
     

    接口和实现类之间也有一些规则:

    • 实现类用 Impl 的后缀与接口区别,比如说 CacheServiceImpl 实现 CacheService 接口

    • 或者,AbstractTranslator 实现 Translatable 接口

    04、字段(field)和变量(variable)

    字段和变量的命名应该遵守以下规则:

    • 必须以小写字母开头

    • 可以包含多个单词,第一个单词的首字母小写,其他的单词首字母大写,比如说 firstName

    • 最好不要使用单个字符,比如说 int a,除非是局部变量

    • 类型与中括号紧挨相连来表示数组,比如说 int[] arrayDemo,main 方法中字符串数组参数不应该写成 String args[]

    • POJO 类中的任何布尔类型的变量,都不要加 is 前缀,否则部分框架解析会引起序列化错误,我自己知道的有 fastjson

    • 避免在子类和父类的成员变量之间、或者不同代码块的局部变量之间采用完全相同的命名,使可理解性降低。子类、父类成员变量名相同,即使是 public 类型的变量也能够通过编译,另外,局部变量在同一方法内的不同代码块中同名也是合法的,这些情况都要避免。

    反例:

    public class ConfusingName {
         public int stock;
     
    @@ -65,6 +65,6 @@
     

    05、常量(constant)

    常量的命名应该遵守以下规则:

    • 应该全部是大写字母

    • 可以包含多个单词,单词之间使用“_”连接,比如说 MAX_PRIORITY,力求语义表达完整清楚,不要嫌名字长

    • 可以包含数字,但不能以数字开头

    来看个例子:

    static final int MIN_AGE = 18;  
     

    06、方法(method)

    方法的命名应该遵守以下规则:

    • 必须以小写字母开头

    • 最好是一个动词,比如说 print()

    • 可以包含多个单词,第一个单词的首字母小写,其他的单词首字母大写,比如说 actionPerformed()

    来看个例子:

    void writeBook(){}
     

    Service/DAO 层的方法命名规约:

    • 获取单个对象的方法用 get 做前缀

    • 获取多个对象的方法用 list 做前缀,复数结尾,如:listObjects

    • 获取统计值的方法用 count 做前缀

    • 插入的方法用 save/insert 做前缀

    • 删除的方法用 remove/delete 做前缀

    • 修改的方法用 update 做前缀

    07、总结

    除了以上这些规则以外,还有一些共同的规则需要遵守,比如说:

    • 代码中的命名均不能以下划线或美元符号开始,也不能以下划线或美元符号结束。反例:_name / __name / $name / name_ / name$ / name__
    • 所有编程相关的命名严禁使用拼音与英文混合的方式,更不允许直接使用中文的方式。反例:DaZhePromotion [打折] / getPingfenByName() [评分] / String fw[福娃] / int 某变量 = 3
    • 代码和注释中都要避免使用任何语言的种族歧视性词语。反例:RIBENGUIZI / Asan / blackList / whiteList / slave
    • 方法名、参数名、成员变量、局部变量都统一使用 lowerCamelCase 风格。
    • 杜绝完全不规范的缩写,避免望文不知义。反例:AbstractClass “缩写”成 AbsClass;condition “缩写”成 condi;Function 缩写”成 Fu,此类随意缩写严重降低了代码的可阅读性。
    • 为了达到代码自解释的目标,任何自定义编程元素在命名时,使用尽量完整的单词组合来表达。
    • 在常量与变量的命名时,表示类型的名词放在词尾,以提升辨识度。正例:startTime / workQueue / nameList / TERMINATED_THREAD_COUNT
    • 如果模块、接口、类、方法使用了设计模式,在命名时需体现出具体模式。 将设计模式体现在名字中,有利于阅读者快速理解架构设计理念。比如说:public class OrderFactory;public class LoginProxy;public class ResourceObserver;
    • 枚举类名带上 Enum 后缀,枚举成员名称需要全大写,单词间用下划线隔开。枚举其实就是特殊的常量类,且构造方法被默认强制是私有。比如说:枚举名字为 ProcessStatusEnum 的成员名称:SUCCESS / UNKNOWN_REASON

    - + diff --git a/dist/basic-extra-meal/java-unicode.html b/dist/basic-extra-meal/java-unicode.html index 9614759d..dd59df95 100644 --- a/dist/basic-extra-meal/java-unicode.html +++ b/dist/basic-extra-meal/java-unicode.html @@ -39,10 +39,10 @@ } - + -

    彻底弄懂Java中的Unicode和UTF-8编码

    沉默王二2021年10月22日
    • Java核心
    • Java
    大约 9 分钟

    彻底弄懂Java中的Unicode和UTF-8编码

    “二哥,上一篇open in new window文章中提到了 Unicode,说 Java 中的 char 类型之所以占 2 个字节,是因为 Java 使用的是 Unicode 字符集而不是 ASCII 字符集,我有点迷,想了解一下,能细致给我说说吗?”

    “当然没问题啊,三妹。”

    1)ASCII

    对于计算机来说,只认 0 和 1,所有的信息最终都是一个二进制数。一个二进制数要么是 0,要么是 1,所以 8 个二进制数放在一起(一个字节),就会组合出 256 种状态,也就是 2 的 8 次方(2^8),从 00000000 到 11111111。

    ASCII 码由电报码发展而来,第一版标准发布于 1963 年,最后一次更新则是在1986 年,至今为止共定义了 128 个字符。其中 33 个字符无法显示在一般的设备上,需要用特殊的设备才能显示。

    ASCII 码的局限在于只能显示 26 个基本拉丁字母、阿拉伯数字和英式标点符号,因此只能用于显示现代美国英语,对于其他一些语言则无能无力,比如在法语中,字母上方有注音符号,它就无法用 ASCII 码表示。

    PS:拉丁字母(也称为罗马字母)是多数欧洲语言采用的字母系统,是世界上最通行的字母文字系统,是罗马文明的成果之一。

    虽然名称上叫作拉丁字母,但拉丁文中并没有用 J、U 和 W 这三个字母。

    在我们的印象中,可能说拉丁字母多少有些陌生,说英语字母可能就有直观的印象了。

    PPS:阿拉伯数字,我们都很熟悉了。

    但是,阿拉伯数字并非起源于阿拉伯,而是起源于古印度。学过历史的我们应该有一些印象,阿拉伯分布于西亚和北非,以阿拉伯语为主要语言,以伊斯兰教为主要信仰。

    处在这样的地理位置,做起东亚和欧洲的一些生意就很有优势,于是阿拉伯数字就由阿拉伯人传到了欧洲,因此得名。

    PPPS:英式标点符号,也叫英文标点符号,和中文标点符号很相近。标点符号是辅助文字记录语言的符号,是书面语的组成部分,用来表示停顿、加强语气等。

    英文标点符号在 16 世纪时,分为朗诵学派和句法学派,主要由古典时期的希腊文和拉丁文演变而来,在 17 世纪后进入稳定阶段。俄文的标点符号依据希腊文而来,到了 18 世纪后也采用了英文标点符号。

    在很多人的印象中,古文是没有标点符号的,但管锡华博士研究指出,中国早在先秦时代就有标点符号了,后来融合了一些英文标点符号后,逐渐形成了现在的中文标点符号。

    2)Unicode

    这个世界上,除了英语,还有法语、葡萄牙语、西班牙语、德语、俄语、阿拉伯语、韩语、日语等等等等。ASCII 码用来表示英语是绰绰有余的,但其他这些语言就没办法了。

    像我们的母语,博大精深,汉字的数量很多很多,东汉的《说文解字》收字 9353 个,清朝《康熙字典》收字 47035 个,当代的《汉语大字典》收字 60370 个。1994 年中华书局、中国友谊出版公司出版的《中华字海》收字 85568 个。

    PS:常用字大概 2500 个,次常用字 1000 个。

    一个字节只能表示 256 种符号,所以如果拿 ASCII 码来表示汉字的话,是远远不够用的,那就必须要用更多的字节。简体中文常见的编码方式是 GB2312,使用两个字节表示一个汉字,理论上最多可以表示 256 x 256 = 65536 个符号。

    要知道,世界上存在着多种编码方式,同一个二进制数字可以被解释成不同的符号。因此,要想打开一个文本文件,就必须知道它的编码方式,否则用错误的编码方式解读,就会出现乱码。

    PPS:这“锟斤拷”价格挺公道的啊!!!(逃

    如果有一种编码,将世界上所有的符号都纳入其中。每一个符号都给予一个独一无二的编码,那么乱码问题就会彻底消失。

    这个艰巨的任务有谁来完成呢?Unicode,中文译作万国码、国际码、统一码、单一码,就像它的名字都表示的,这是一种所有符号的编码。

    Unicode 至今仍在不断增修,每个新版本都会加入更多新的字符。目前最新的版本为 2020 年 3 月公布的 13.0,收录了 13 万个字符。

    Unicode 是一个很大的集合,现在的规模可以容纳 100 多万个符号。每个符号的编码都不一样,比如,U+0639表示阿拉伯字母 AinU+0041 表示英语的大写字母 AU+4E25 表示汉字

    具体的符号对应表,可以查询 unicode.orgopen in new window,或者专门的汉字对应表open in new window

    曾有人这样说:

    Unicode 支持的字符上限是 65536 个,Unicode 字符必须占两个字节。

    但这是一种误解,记住,Unicode 只是一个用来映射字符和数字的标准。它对支持字符的数量没有限制,也不要求字符必须占两个、三个或者其它任意数量的字节,所以它可以无穷大。

    Unicode 虽然统一了全世界字符的编码,但没有规定如何存储。如果统一规定的话,每个符号就要用 3 个或 4 个字节表示,因为 2 个字节只能表示 65536 个,根本表示不全。

    那怎么办呢?

    UTF(Unicode Transformation Formats,Unicode 的编码方式)来了!最常见的就是 UTF-8 和 UTF-16。

    在 UTF-8 中,0-127 号的字符用 1 个字节来表示,使用和 ASCII 相同的编码。只有 128 号及以上的字符才用 2 个、3 个或者 4 个字节来表示。

    如果只有一个字节,那么最高的比特位为 0;如果有多个字节,那么第一个字节从最高位开始,连续有几个比特位的值为 1,就使用几个字节编码,剩下的字节均以 10 开头。

    具体的表现形式为:

    0xxxxxxx:一个字节; 110xxxxx 10xxxxxx:两个字节编码形式(开始两个 1); 1110xxxx 10xxxxxx 10xxxxxx:三字节编码形式(开始三个 1); 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx:四字节编码形式(开始四个 1)。

    也就是说,UTF-8 是一种可变长度的编码方式——这是它的优势也是劣势。

    怎么讲呢?优势就是它包罗万象,劣势就是浪费空间。举例来说吧,UTF-8 采用了 3 个字节(256256256=16777216)来编码常用的汉字,但常用的汉字没有这么多,这对于计算机来说,就是一种严重的资源浪费。

    基于这样的考虑,中国国家标准总局于 1980 年发布了 GB 2312 编码,即中华人民共和国国家标准简体中文字符集。GB 2312 标准共收录 6763 个汉字(2 个字节就够用了),其中一级汉字 3755 个,二级汉字 3008 个;同时收录了包括拉丁字母、希腊字母、日文平假名及片假名字母、俄语西里尔字母在内的 682 个字符。

    GB 2312 的出现,基本满足了汉字的计算机处理需求。对于人名、古汉语等方面出现的罕用字和繁体字,GB 2312 不能处理,就有了 GBK(K 为“扩展”的汉语拼音(kuòzhǎn)第一个声母)。

    来看一段代码:

    public class Demo {
    +    

    彻底弄懂Java中的Unicode和UTF-8编码

    沉默王二2021年10月22日
    • Java核心
    • Java
    大约 9 分钟

    彻底弄懂Java中的Unicode和UTF-8编码

    “二哥,上一篇open in new window文章中提到了 Unicode,说 Java 中的 char 类型之所以占 2 个字节,是因为 Java 使用的是 Unicode 字符集而不是 ASCII 字符集,我有点迷,想了解一下,能细致给我说说吗?”

    “当然没问题啊,三妹。”

    1)ASCII

    对于计算机来说,只认 0 和 1,所有的信息最终都是一个二进制数。一个二进制数要么是 0,要么是 1,所以 8 个二进制数放在一起(一个字节),就会组合出 256 种状态,也就是 2 的 8 次方(2^8),从 00000000 到 11111111。

    ASCII 码由电报码发展而来,第一版标准发布于 1963 年,最后一次更新则是在1986 年,至今为止共定义了 128 个字符。其中 33 个字符无法显示在一般的设备上,需要用特殊的设备才能显示。

    ASCII 码的局限在于只能显示 26 个基本拉丁字母、阿拉伯数字和英式标点符号,因此只能用于显示现代美国英语,对于其他一些语言则无能无力,比如在法语中,字母上方有注音符号,它就无法用 ASCII 码表示。

    PS:拉丁字母(也称为罗马字母)是多数欧洲语言采用的字母系统,是世界上最通行的字母文字系统,是罗马文明的成果之一。

    虽然名称上叫作拉丁字母,但拉丁文中并没有用 J、U 和 W 这三个字母。

    在我们的印象中,可能说拉丁字母多少有些陌生,说英语字母可能就有直观的印象了。

    PPS:阿拉伯数字,我们都很熟悉了。

    但是,阿拉伯数字并非起源于阿拉伯,而是起源于古印度。学过历史的我们应该有一些印象,阿拉伯分布于西亚和北非,以阿拉伯语为主要语言,以伊斯兰教为主要信仰。

    处在这样的地理位置,做起东亚和欧洲的一些生意就很有优势,于是阿拉伯数字就由阿拉伯人传到了欧洲,因此得名。

    PPPS:英式标点符号,也叫英文标点符号,和中文标点符号很相近。标点符号是辅助文字记录语言的符号,是书面语的组成部分,用来表示停顿、加强语气等。

    英文标点符号在 16 世纪时,分为朗诵学派和句法学派,主要由古典时期的希腊文和拉丁文演变而来,在 17 世纪后进入稳定阶段。俄文的标点符号依据希腊文而来,到了 18 世纪后也采用了英文标点符号。

    在很多人的印象中,古文是没有标点符号的,但管锡华博士研究指出,中国早在先秦时代就有标点符号了,后来融合了一些英文标点符号后,逐渐形成了现在的中文标点符号。

    2)Unicode

    这个世界上,除了英语,还有法语、葡萄牙语、西班牙语、德语、俄语、阿拉伯语、韩语、日语等等等等。ASCII 码用来表示英语是绰绰有余的,但其他这些语言就没办法了。

    像我们的母语,博大精深,汉字的数量很多很多,东汉的《说文解字》收字 9353 个,清朝《康熙字典》收字 47035 个,当代的《汉语大字典》收字 60370 个。1994 年中华书局、中国友谊出版公司出版的《中华字海》收字 85568 个。

    PS:常用字大概 2500 个,次常用字 1000 个。

    一个字节只能表示 256 种符号,所以如果拿 ASCII 码来表示汉字的话,是远远不够用的,那就必须要用更多的字节。简体中文常见的编码方式是 GB2312,使用两个字节表示一个汉字,理论上最多可以表示 256 x 256 = 65536 个符号。

    要知道,世界上存在着多种编码方式,同一个二进制数字可以被解释成不同的符号。因此,要想打开一个文本文件,就必须知道它的编码方式,否则用错误的编码方式解读,就会出现乱码。

    PPS:这“锟斤拷”价格挺公道的啊!!!(逃

    如果有一种编码,将世界上所有的符号都纳入其中。每一个符号都给予一个独一无二的编码,那么乱码问题就会彻底消失。

    这个艰巨的任务有谁来完成呢?Unicode,中文译作万国码、国际码、统一码、单一码,就像它的名字都表示的,这是一种所有符号的编码。

    Unicode 至今仍在不断增修,每个新版本都会加入更多新的字符。目前最新的版本为 2020 年 3 月公布的 13.0,收录了 13 万个字符。

    Unicode 是一个很大的集合,现在的规模可以容纳 100 多万个符号。每个符号的编码都不一样,比如,U+0639表示阿拉伯字母 AinU+0041 表示英语的大写字母 AU+4E25 表示汉字

    具体的符号对应表,可以查询 unicode.orgopen in new window,或者专门的汉字对应表open in new window

    曾有人这样说:

    Unicode 支持的字符上限是 65536 个,Unicode 字符必须占两个字节。

    但这是一种误解,记住,Unicode 只是一个用来映射字符和数字的标准。它对支持字符的数量没有限制,也不要求字符必须占两个、三个或者其它任意数量的字节,所以它可以无穷大。

    Unicode 虽然统一了全世界字符的编码,但没有规定如何存储。如果统一规定的话,每个符号就要用 3 个或 4 个字节表示,因为 2 个字节只能表示 65536 个,根本表示不全。

    那怎么办呢?

    UTF(Unicode Transformation Formats,Unicode 的编码方式)来了!最常见的就是 UTF-8 和 UTF-16。

    在 UTF-8 中,0-127 号的字符用 1 个字节来表示,使用和 ASCII 相同的编码。只有 128 号及以上的字符才用 2 个、3 个或者 4 个字节来表示。

    如果只有一个字节,那么最高的比特位为 0;如果有多个字节,那么第一个字节从最高位开始,连续有几个比特位的值为 1,就使用几个字节编码,剩下的字节均以 10 开头。

    具体的表现形式为:

    0xxxxxxx:一个字节; 110xxxxx 10xxxxxx:两个字节编码形式(开始两个 1); 1110xxxx 10xxxxxx 10xxxxxx:三字节编码形式(开始三个 1); 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx:四字节编码形式(开始四个 1)。

    也就是说,UTF-8 是一种可变长度的编码方式——这是它的优势也是劣势。

    怎么讲呢?优势就是它包罗万象,劣势就是浪费空间。举例来说吧,UTF-8 采用了 3 个字节(256256256=16777216)来编码常用的汉字,但常用的汉字没有这么多,这对于计算机来说,就是一种严重的资源浪费。

    基于这样的考虑,中国国家标准总局于 1980 年发布了 GB 2312 编码,即中华人民共和国国家标准简体中文字符集。GB 2312 标准共收录 6763 个汉字(2 个字节就够用了),其中一级汉字 3755 个,二级汉字 3008 个;同时收录了包括拉丁字母、希腊字母、日文平假名及片假名字母、俄语西里尔字母在内的 682 个字符。

    GB 2312 的出现,基本满足了汉字的计算机处理需求。对于人名、古汉语等方面出现的罕用字和繁体字,GB 2312 不能处理,就有了 GBK(K 为“扩展”的汉语拼音(kuòzhǎn)第一个声母)。

    来看一段代码:

    public class Demo {
         public static void main(String[] args) {
             String wanger = "沉默王二";
             byte[] bytes = wanger.getBytes(Charset.forName("GBK"));
    @@ -60,6 +60,6 @@
     // 输出锟斤拷
     System.out.println(testResult);
     

    PPPS:hutool 的使用方法可以参照我的另外一篇文章open in new window

    所以,以后再见到锟斤拷,第一时间想到 UTF-8 和 GBK 的转换问题准没错。

    UTF-16 使用 2 个或者 4 个字节来存储字符。

    • 对于 Unicode 编号范围在 0 ~ FFFF 之间的字符,UTF-16 使用两个字节存储。

    • 对于 Unicode 编号范围在 10000 ~ 10FFFF 之间的字符,UTF-16 使用四个字节存储,具体来说就是:将字符编号的所有比特位分成两部分,较高的一些比特位用一个值介于 D800~DBFF 之间的双字节存储,较低的一些比特位(剩下的比特位)用一个值介于 DC00~DFFF 之间的双字节存储。

    3)char

    搞清楚了 Unicode 之后,再回头来看 char 为什么是两个字节的问题,就很容易搞明白了。

    在 Unicode 的设计之初,人们认为两个字节足以对世界上各种语言的所有字符进行编码,在 1991 年发布的 Unicode 1.0 中,仅用了 65536 个代码值中不到一半的部分。

    所以,Java 决定采用 16 位的 Unicode 字符集(诞生于 90 年代open in new window)。也就是说,当时的 char 类型可以表示任意一个 Unicode 字符。

    但是,不可避免的事情发生了,Unicode 收录的字符越来越多,超过了 65536 个(2 个字节的最大表示范围)。超过的部分怎么办呢?只能用两个 char 来表示了。

    这个 𐐷 字符很特殊,Unicode 编码是 U+10437,它就无法使用一个 char 来表示,当你尝试用 char 来表示时,它会被 IDEA 转成 UTF-16 十六进制字符代码 \uD801\uDC37(与此同时,编译器会提醒你最好把它声明成 String 类型)。

    也就是说,在 Java 中,char 会占用两个字节,超出 char 的承受范围('\u0000'(0)和 '\uffff'(65,535))的字符,都将无法表示。

    “好了,三妹,关于 Unicode 就先说这么多吧,你是不是已经清楚了?”转动了一下僵硬的脖子后,我对三妹说。

    - + diff --git a/dist/basic-extra-meal/jdk-while-for-wuxian-xunhuan.html b/dist/basic-extra-meal/jdk-while-for-wuxian-xunhuan.html index a04dea05..3b5f036f 100644 --- a/dist/basic-extra-meal/jdk-while-for-wuxian-xunhuan.html +++ b/dist/basic-extra-meal/jdk-while-for-wuxian-xunhuan.html @@ -39,10 +39,10 @@ } - + -

    为什么JDK源码中,无限循环大多使用for(;;)而不是while(true)?

    沉默王二2022年3月22日
    • Java核心
    • Java
    大约 3 分钟

    为什么JDK源码中,无限循环大多使用for(;;)而不是while(true)?

    在知乎上看到 R 大的这篇回答,着实感觉需要分享给在座的各位 javaer 们,真心透彻。

    https://www.zhihu.com/question/52311366/answer/130090347


    首先是先问是不是再问为什么系列。

    在JDK8u的jdk项目下做个很粗略的搜索:

    mymbp:/Users/me/workspace/jdk8u/jdk/src
    +    

    为什么JDK源码中,无限循环大多使用for(;;)而不是while(true)?

    沉默王二2022年3月22日
    • Java核心
    • Java
    大约 3 分钟

    为什么JDK源码中,无限循环大多使用for(;;)而不是while(true)?

    在知乎上看到 R 大的这篇回答,着实感觉需要分享给在座的各位 javaer 们,真心透彻。

    https://www.zhihu.com/question/52311366/answer/130090347


    首先是先问是不是再问为什么系列。

    在JDK8u的jdk项目下做个很粗略的搜索:

    mymbp:/Users/me/workspace/jdk8u/jdk/src
     $ egrep -nr "for \\(\\s?;\\s?;" . | wc -l
          369
     mymbp:/Users/me/workspace/jdk8u/jdk/src
    @@ -80,6 +80,6 @@ $ egrep -nr "while \\(true" . | wc -l
              5: goto          2
     */
     

    连javac这种几乎什么优化都不做(只做了Java语言规范规定一定要做的常量折叠,和非常少量别的优化)的编译器,对上面俩版本的代码都生成了一样的字节码。后面到解释执行、JIT编译之类的就不用说了,输入都一样,输出也不会不同。


    分享的最后,二哥简单说几句。

    可能在我们普通人眼中,这种问题完全没有求真的必要性,但 R大认真去研究了,并且得出了非常令人信服的答案。

    所以,牛逼之人必有三连之处啊。

    以后就可以放心大胆在代码里写 for(;;) while(true) 这样的死循环了。

    - + diff --git a/dist/basic-extra-meal/jdk9-char-byte-string.html b/dist/basic-extra-meal/jdk9-char-byte-string.html index 4f8c0294..1e4c9455 100644 --- a/dist/basic-extra-meal/jdk9-char-byte-string.html +++ b/dist/basic-extra-meal/jdk9-char-byte-string.html @@ -39,10 +39,10 @@ } - + -

    jdk9为何要将String的底层实现由char[]改成了byte[]?

    沉默王二2022年3月22日
    • Java核心
    • Java
    大约 5 分钟

    jdk9为何要将String的底层实现由char[]改成了byte[]?

    大家好,我是二哥呀!如果你不是 Java8 的钉子户,你应该早就发现了:String 类的源码已经由 char[] 优化为了 byte[] 来存储字符串内容,为什么要这样做呢?

    开门见山地说,从 char[]byte[],最主要的目的是为了节省字符串占用的内存。内存占用减少带来的另外一个好处,就是 GC 次数也会减少。

    一、为什么要优化 String 节省内存空间

    我们使用 jmap -histo:live pid | head -n 10 命令就可以查看到堆内对象示例的统计信息、查看 ClassLoader 的信息以及 finalizer 队列。

    以我正在运行着的编程喵喵项目实例(基于 Java 8)来说,结果是这样的。

    其中 String 对象有 17638 个,占用了 423312 个字节的内存,排在第三位。

    由于 Java 8 的 String 内部实现仍然是 char[],所以我们可以看到内存占用排在第 1 位的就是 char 数组。

    char[] 对象有 17673 个,占用了 1621352 个字节的内存,排在第一位。

    那也就是说优化 String 节省内存空间是非常有必要的,如果是去优化一个使用频率没有 String 这么高的类库,就显得非常的鸡肋。

    二、byte[] 为什么就能节省内存空间呢?

    众所周知,char 类型的数据在 JVM 中是占用两个字节的,并且使用的是 UTF-8 编码,其值范围在 '\u0000'(0)和 '\uffff'(65,535)(包含)之间。

    也就是说,使用 char[] 来表示 String 就导致了即使 String 中的字符只用一个字节就能表示,也得占用两个字节。

    而实际开发中,单字节的字符使用频率仍然要高于双字节的。

    当然了,仅仅将 char[] 优化为 byte[] 是不够的,还要配合 Latin-1 的编码方式,该编码方式是用单个字节来表示字符的,这样就比 UTF-8 编码节省了更多的空间。

    换句话说,对于:

    String name = "jack";
    +    

    jdk9为何要将String的底层实现由char[]改成了byte[]?

    沉默王二2022年3月22日
    • Java核心
    • Java
    大约 5 分钟

    jdk9为何要将String的底层实现由char[]改成了byte[]?

    大家好,我是二哥呀!如果你不是 Java8 的钉子户,你应该早就发现了:String 类的源码已经由 char[] 优化为了 byte[] 来存储字符串内容,为什么要这样做呢?

    开门见山地说,从 char[]byte[],最主要的目的是为了节省字符串占用的内存。内存占用减少带来的另外一个好处,就是 GC 次数也会减少。

    一、为什么要优化 String 节省内存空间

    我们使用 jmap -histo:live pid | head -n 10 命令就可以查看到堆内对象示例的统计信息、查看 ClassLoader 的信息以及 finalizer 队列。

    以我正在运行着的编程喵喵项目实例(基于 Java 8)来说,结果是这样的。

    其中 String 对象有 17638 个,占用了 423312 个字节的内存,排在第三位。

    由于 Java 8 的 String 内部实现仍然是 char[],所以我们可以看到内存占用排在第 1 位的就是 char 数组。

    char[] 对象有 17673 个,占用了 1621352 个字节的内存,排在第一位。

    那也就是说优化 String 节省内存空间是非常有必要的,如果是去优化一个使用频率没有 String 这么高的类库,就显得非常的鸡肋。

    二、byte[] 为什么就能节省内存空间呢?

    众所周知,char 类型的数据在 JVM 中是占用两个字节的,并且使用的是 UTF-8 编码,其值范围在 '\u0000'(0)和 '\uffff'(65,535)(包含)之间。

    也就是说,使用 char[] 来表示 String 就导致了即使 String 中的字符只用一个字节就能表示,也得占用两个字节。

    而实际开发中,单字节的字符使用频率仍然要高于双字节的。

    当然了,仅仅将 char[] 优化为 byte[] 是不够的,还要配合 Latin-1 的编码方式,该编码方式是用单个字节来表示字符的,这样就比 UTF-8 编码节省了更多的空间。

    换句话说,对于:

    String name = "jack";
     

    这样的,使用 Latin-1 编码,占用 4 个字节就够了。

    但对于:

    String name = "小二";
     

    这种,木的办法,只能使用 UTF16 来编码。

    针对 JDK 9 的 String 源码里,为了区别编码方式,追加了一个 coder 字段来区分。

    /**
      * The identifier of the encoding used to encode the bytes in
    @@ -57,6 +57,6 @@
      */
     private final byte coder;
     

    Java 会根据字符串的内容自动设置为相应的编码,要么 Latin-1 要么 UTF16。

    也就是说,从 char[]byte[]中文是两个字节,纯英文是一个字节,在此之前呢,中文是两个字节,应为也是两个字节

    三、为什么用UTF-16而不用UTF-8呢?

    在 UTF-8 中,0-127 号的字符用 1 个字节来表示,使用和 ASCII 相同的编码。只有 128 号及以上的字符才用 2 个、3 个或者 4 个字节来表示。

    • 如果只有一个字节,那么最高的比特位为 0;
    • 如果有多个字节,那么第一个字节从最高位开始,连续有几个比特位的值为 1,就使用几个字节编码,剩下的字节均以 10 开头。

    具体的表现形式为:

    • 0xxxxxxx:一个字节;
    • 110xxxxx 10xxxxxx:两个字节编码形式(开始两个 1); - 1110xxxx 10xxxxxx 10xxxxxx:三字节编码形式(开始三个 1);
    • 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx:四字节编码形式(开始四个 1)。

    关于字符编码,我在《Java 程序员进阶之路》里曾讲到过,想要深入了解的小伙伴查看下面的链接🔗:

    https://tobebetterjavaer.com/basic-extra-meal/java-unicode.html

    也就是说,UTF-8 是变长的,那对于 String 这种有随机访问方法的类来说,就很不方便。所谓的随机访问,就是charAt、subString这种方法,随便指定一个数字,String要能给出结果。如果字符串中的每个字符占用的内存是不定长的,那么进行随机访问的时候,就需要从头开始数每个字符的长度,才能找到你想要的字符。

    那有小伙伴可能会问,UTF-16也是变长的呢?一个字符还可能占用 4 个字节呢?

    的确,UTF-16 使用 2 个或者 4 个字节来存储字符。

    • 对于 Unicode 编号范围在 0 ~ FFFF 之间的字符,UTF-16 使用两个字节存储。
    • 对于 Unicode 编号范围在 10000 ~ 10FFFF 之间的字符,UTF-16 使用四个字节存储,具体来说就是:将字符编号的所有比特位分成两部分,较高的一些比特位用一个值介于 D800~DBFF 之间的双字节存储,较低的一些比特位(剩下的比特位)用一个值介于 DC00~DFFF 之间的双字节存储。

    但是在 Java 中,一个字符(char)就是 2 个字节,占 4 个字节的字符,在 Java 里也是用两个 char 来存储的,而String的各种操作,都是以Java的字符(char)为单位的,charAt是取得第几个char,subString取的也是第几个到第几个char组成的子串,甚至length返回的都是char的个数。

    所以UTF-16在Java的世界里,就可以视为一个定长的编码。

    参考链接:https://www.zhihu.com/question/447224628

    - + diff --git a/dist/basic-extra-meal/override-overload.html b/dist/basic-extra-meal/override-overload.html index 14577035..90bab365 100644 --- a/dist/basic-extra-meal/override-overload.html +++ b/dist/basic-extra-meal/override-overload.html @@ -39,10 +39,10 @@ } - + -

    Java重写(Override)与重载(Overload)

    沉默王二2021年10月22日
    • Java核心
    • Java
    大约 9 分钟

    Java重写(Override)与重载(Overload)

    01、开篇

    入冬的夜,总是来得特别的早。我静静地站在阳台,目光所及之处,不过是若隐若现的钢筋混凝土,还有那毫无情调的灯光。

    “哥,别站在那发呆了。今天学啥啊,七点半我就要回学校了,留给你的时间不多了,你要抓紧哦。”三妹傲娇的声音一下子把我从游离的状态拉回到了现实。

    “今天要学习 Java 中的方法重载与方法重写。”我迅速地走到电脑前面,打开一份 Excel 文档,看了一下《教妹学 Java》的进度,然后对三妹说。

    “如果一个类有多个名字相同但参数个数不同的方法,我们通常称这些方法为方法重载。 ”我面带着朴实无华的微笑继续说,“如果方法的功能是一样的,但参数不同,使用相同的名字可以提高程序的可读性。”

    “如果子类具有和父类一样的方法(参数相同、返回类型相同、方法名相同,但方法体可能不同),我们称之为方法重写。 方法重写用于提供父类已经声明的方法的特殊实现,是实现多态的基础条件。”

    “只不过,方法重载与方法重写在名字上很相似,就像是兄弟俩,导致初学者经常把它们俩搞混。”

    “方法重载的英文名叫 Overloading,方法重写的英文名叫 Overriding,因此,不仅中文名很相近,英文名之间也很相近,这就更容易让初学者搞混了。”

    “但两者其实是完全不同的!通过下面这张图,你就能看得一清二楚。”

    话音刚落,我就在 IDEA 中噼里啪啦地敲了起来。两段代码,分别是方法重写和方法重载。然后,把这两段代码截图到 draw.io(一个很漂亮的在线画图网站)上,加了一些文字说明。最后,打开 Photoscape X,把两张图片合并到了一起。

    02、方法重载

    “三妹,你仔细听哦。”我缓了一口气后继续说道。

    “在 Java 中,有两种方式可以达到方法重载的目的。”

    “第一,改变参数的数目。来看下面这段代码。”

    public class OverloadingByParamNum {
    +    

    Java重写(Override)与重载(Overload)

    沉默王二2021年10月22日
    • Java核心
    • Java
    大约 9 分钟

    Java重写(Override)与重载(Overload)

    01、开篇

    入冬的夜,总是来得特别的早。我静静地站在阳台,目光所及之处,不过是若隐若现的钢筋混凝土,还有那毫无情调的灯光。

    “哥,别站在那发呆了。今天学啥啊,七点半我就要回学校了,留给你的时间不多了,你要抓紧哦。”三妹傲娇的声音一下子把我从游离的状态拉回到了现实。

    “今天要学习 Java 中的方法重载与方法重写。”我迅速地走到电脑前面,打开一份 Excel 文档,看了一下《教妹学 Java》的进度,然后对三妹说。

    “如果一个类有多个名字相同但参数个数不同的方法,我们通常称这些方法为方法重载。 ”我面带着朴实无华的微笑继续说,“如果方法的功能是一样的,但参数不同,使用相同的名字可以提高程序的可读性。”

    “如果子类具有和父类一样的方法(参数相同、返回类型相同、方法名相同,但方法体可能不同),我们称之为方法重写。 方法重写用于提供父类已经声明的方法的特殊实现,是实现多态的基础条件。”

    “只不过,方法重载与方法重写在名字上很相似,就像是兄弟俩,导致初学者经常把它们俩搞混。”

    “方法重载的英文名叫 Overloading,方法重写的英文名叫 Overriding,因此,不仅中文名很相近,英文名之间也很相近,这就更容易让初学者搞混了。”

    “但两者其实是完全不同的!通过下面这张图,你就能看得一清二楚。”

    话音刚落,我就在 IDEA 中噼里啪啦地敲了起来。两段代码,分别是方法重写和方法重载。然后,把这两段代码截图到 draw.io(一个很漂亮的在线画图网站)上,加了一些文字说明。最后,打开 Photoscape X,把两张图片合并到了一起。

    02、方法重载

    “三妹,你仔细听哦。”我缓了一口气后继续说道。

    “在 Java 中,有两种方式可以达到方法重载的目的。”

    “第一,改变参数的数目。来看下面这段代码。”

    public class OverloadingByParamNum {
         public static void main(String[] args) {
             System.out.println(Adder.add(10, 19));
             System.out.println(Adder.add(10, 19, 20));
    @@ -171,6 +171,6 @@
     }
     

    我把鼠标移动到 Bike 类的 run() 方法,对三妹说:“你看,在方法重写的时候,IDEA 会建议使用 @Override 注解,显式的表示这是一个重写后的方法,尽管可以缺省。”

    “来看一下程序的输出结果。”

    自行车在跑
     

    “Bike 重写了 run() 方法,也就意味着,Bike 可以跑出自己的风格。”

    04、总结

    “好了,三妹,我来简单做个总结。”我瞥了一眼电脑右上角的时钟,离三妹离开的时间不到 10 分钟了。

    “首先来说一下方法重载时的注意事项,‘两同一不同’。”

    “‘两同’:在同一个类,方法名相同。”

    “‘一不同’:参数不同。”

    “再来说一下方法重写时的注意事项,‘两同一小一大’。”

    “‘两同’:方法名相同,参数相同。”

    “‘一小’:子类方法声明的异常类型要比父类小一些或者相等。”

    “‘一大’:子类方法的访问权限应该比父类的更大或者相等。”

    “记住了吧?三妹。带上口罩,拿好手机,咱准备出门吧。”今天限号,没法开车送三妹去学校了。

    - + diff --git a/dist/basic-extra-meal/pass-by-value.html b/dist/basic-extra-meal/pass-by-value.html index c472c481..ab79e2e9 100644 --- a/dist/basic-extra-meal/pass-by-value.html +++ b/dist/basic-extra-meal/pass-by-value.html @@ -39,10 +39,10 @@ } - + -

    Java到底是值传递还是引用传递?

    沉默王二2021年10月22日
    • Java核心
    • Java
    大约 5 分钟

    Java到底是值传递还是引用传递?

    “哥,说说 Java 到底是值传递还是引用传递吧?”三妹一脸的困惑,看得出来她被这个问题折磨得不轻。

    “说实在的,我在一开始学 Java 的时候也被这个问题折磨得够呛,总以为基本数据类型在传参的时候是值传递,而引用类型是引用传递。”我对三妹袒露了心声,为的就是让她不再那么焦虑,她哥当年也是这么过来的。

    C 语言是很多编程语言的母胎,包括 Java,那么对于 C 语言来说,所有的方法参数都是“通过值”传递的,也就是说,传递给被调用方法的参数值存放在临时变量中,而不是存放在原来的变量中。这就意味着,被调用的方法不能修改调用方法中变量的值,而只能修改其私有变量的临时副本的值。

    Java 继承了 C 语言这一特性,因此 Java 是按照值来传递的。

    接下来,我们必须得搞清楚,到底什么是值传递(pass by value),什么是引用传递(pass by reference),否则,讨论 Java 到底是值传递还是引用传递就显得毫无意义。

    当一个参数按照值的方式在两个方法之间传递时,调用者和被调用者其实是用的两个不同的变量——被调用者中的变量(原始值)是调用者中变量的一份拷贝,对它们当中的任何一个变量修改都不会影响到另外一个变量,据说 Fortran 语言是通过引用传递的。

    “Fortran 语言?”三妹睁大了双眼,似乎听见了什么新的名词。

    “是的,Fortran 语言,1957 年由 IBM 公司开发,是世界上第一个被正式采用并流传至今的高级编程语言。”

    当一个参数按照引用传递的方式在两个方法之间传递时,调用者和被调用者其实用的是同一个变量,当该变量被修改时,双方都是可见的。

    “我们之所以容易搞不清楚 Java 到底是值传递还是引用传递,主要是因为 Java 中的两类数据类型的叫法容易引发误会,比如说 int 是基本类型,说它是值传递的,我们就很容易理解;但对于引用类型,比如说 String,说它也是值传递的时候,我们就容易弄不明白。”

    我们来看看基本数据类型和引用数据类型之间的差别。

    int age = 18;
    +    

    Java到底是值传递还是引用传递?

    沉默王二2021年10月22日
    • Java核心
    • Java
    大约 5 分钟

    Java到底是值传递还是引用传递?

    “哥,说说 Java 到底是值传递还是引用传递吧?”三妹一脸的困惑,看得出来她被这个问题折磨得不轻。

    “说实在的,我在一开始学 Java 的时候也被这个问题折磨得够呛,总以为基本数据类型在传参的时候是值传递,而引用类型是引用传递。”我对三妹袒露了心声,为的就是让她不再那么焦虑,她哥当年也是这么过来的。

    C 语言是很多编程语言的母胎,包括 Java,那么对于 C 语言来说,所有的方法参数都是“通过值”传递的,也就是说,传递给被调用方法的参数值存放在临时变量中,而不是存放在原来的变量中。这就意味着,被调用的方法不能修改调用方法中变量的值,而只能修改其私有变量的临时副本的值。

    Java 继承了 C 语言这一特性,因此 Java 是按照值来传递的。

    接下来,我们必须得搞清楚,到底什么是值传递(pass by value),什么是引用传递(pass by reference),否则,讨论 Java 到底是值传递还是引用传递就显得毫无意义。

    当一个参数按照值的方式在两个方法之间传递时,调用者和被调用者其实是用的两个不同的变量——被调用者中的变量(原始值)是调用者中变量的一份拷贝,对它们当中的任何一个变量修改都不会影响到另外一个变量,据说 Fortran 语言是通过引用传递的。

    “Fortran 语言?”三妹睁大了双眼,似乎听见了什么新的名词。

    “是的,Fortran 语言,1957 年由 IBM 公司开发,是世界上第一个被正式采用并流传至今的高级编程语言。”

    当一个参数按照引用传递的方式在两个方法之间传递时,调用者和被调用者其实用的是同一个变量,当该变量被修改时,双方都是可见的。

    “我们之所以容易搞不清楚 Java 到底是值传递还是引用传递,主要是因为 Java 中的两类数据类型的叫法容易引发误会,比如说 int 是基本类型,说它是值传递的,我们就很容易理解;但对于引用类型,比如说 String,说它也是值传递的时候,我们就容易弄不明白。”

    我们来看看基本数据类型和引用数据类型之间的差别。

    int age = 18;
     String name = "二哥";
     

    age 是基本类型,值就保存在变量中,而 name 是引用类型,变量中保存的是对象的地址。一般称这种变量为对象的引用,引用存放在栈中,而对象存放在堆中。

    这里说的栈和堆,是指内存中的一块区域,和数据结构中的栈和堆不一样。栈是由编译器自动分配释放的,所以适合存放编译期就确定生命周期的数据;而堆中存放的数据,编译器是不需要知道生命周期的,创建后的回收工作由垃圾收集器来完成。

    “画幅图。”

    当用 = 赋值运算符改变 age 和 name 的值时。

    age = 16;
     name = "三妹";
    @@ -81,6 +81,6 @@ name = "三
         }
     }
     

    在调用 modify() 方法的时候,形参 name1 复制了 name 的地址,指向的是堆中“二哥”的位置。

    modify() 方法调用结束后,改变了形参 name1 的地址,但 main() 方法中 name 并没有发生改变。

    总结:

    • Java 中的参数传递是按值传递的。
    • 如果参数是基本类型,传递的是基本类型的字面量值的拷贝。
    • 如果参数是引用类型,传递的是引用的对象在堆中地址的拷贝。

    “好了,三妹,今天的学习就到这吧。”

    - + diff --git a/dist/basic-extra-meal/true-generic.html b/dist/basic-extra-meal/true-generic.html index 839a396a..343f73e8 100644 --- a/dist/basic-extra-meal/true-generic.html +++ b/dist/basic-extra-meal/true-generic.html @@ -39,10 +39,10 @@ } - + -

    Java不能实现真正泛型的原因是什么?

    沉默王二2021年10月22日
    • Java核心
    • Java
    大约 7 分钟

    Java不能实现真正泛型的原因是什么?

    “二哥,为啥 Java 不能实现真正泛型啊?”三妹开门见山地问。

    简单来回顾一下类型擦除,看下面这段代码。

    public class Cmower {
    +    

    Java不能实现真正泛型的原因是什么?

    沉默王二2021年10月22日
    • Java核心
    • Java
    大约 7 分钟

    Java不能实现真正泛型的原因是什么?

    “二哥,为啥 Java 不能实现真正泛型啊?”三妹开门见山地问。

    简单来回顾一下类型擦除,看下面这段代码。

    public class Cmower {
         public static void method(ArrayList<String> list) {
             System.out.println("Arraylist<String> list");
         }
    @@ -100,6 +100,6 @@ list.add= ints;
     list = strs;
     

    “兼容性表现在上面这段代码必须得能够编译运行。怎么办呢?”我扭头看了一下旁边的三妹,继续说。

    “只能搞类型擦除了!”我妹肯定地回答。

    “是滴。”

    编译前进行泛型检测,ArrayList<Integer> 只能放 Integer,ArrayList<String> 只能放 String,取的时候就不用担心类型强转出错了。

    但编译后的字节码文件里,是没有泛型的,放的都是 Object。

    Java 神奇就神奇在这,表面上万物皆对象,但为了性能上的考量,又存在 int、double 这种原始类型,但原始类型又没办法和 Object 兼容,于是我们就只能写 ArrayList<Integer> 这样很占用内存空间的代码。

    这恐怕也是 Java 泛型被吐槽的原因之一了。

    一个好消息是 Valhalla 项目正在努力解决这些因为泛型擦除带来的历史遗留问题。

    Project Valhalla:正在进行当中的 OpenJDK 项目,计划给未来的 Java 添加改进的泛型支持。

    源码地址:http://openjdk.java.net/projects/valhalla/

    让我们拭目以待吧!

    “怎么样?三妹,这下全部都明白了吧!”我问。

    “嗯嗯。二哥,你讲得可真棒👍”三妹夸奖得我有点小开心,嘿嘿。

    - + diff --git a/dist/basic-extra-meal/varables.html b/dist/basic-extra-meal/varables.html index 3598f5e1..8cdd62ef 100644 --- a/dist/basic-extra-meal/varables.html +++ b/dist/basic-extra-meal/varables.html @@ -39,10 +39,10 @@ } - + -

    Java中可变参数的使用

    沉默王二2021年11月8日
    • Java核心
    • Java
    大约 4 分钟

    Java中可变参数的使用

    为了让铁粉们能白票到阿里云的服务器,老王当了整整两天的客服,真正体验到了什么叫做“为人民群众谋福利”的不易和辛酸。正在他眼睛红肿打算要休息之际,小二跑过来问他:“Java 的可变参数究竟是怎么一回事?”老王一下子又清醒了,他爱 Java,他爱传道解惑,他爱这群尊敬他的读者。

    可变参数是 Java 1.5 的时候引入的功能,它允许方法使用任意多个、类型相同(is-a)的值作为参数。就像下面这样。

    public static void main(String[] args) {
    +    

    Java中可变参数的使用

    沉默王二2021年11月8日
    • Java核心
    • Java
    大约 4 分钟

    Java中可变参数的使用

    为了让铁粉们能白票到阿里云的服务器,老王当了整整两天的客服,真正体验到了什么叫做“为人民群众谋福利”的不易和辛酸。正在他眼睛红肿打算要休息之际,小二跑过来问他:“Java 的可变参数究竟是怎么一回事?”老王一下子又清醒了,他爱 Java,他爱传道解惑,他爱这群尊敬他的读者。

    可变参数是 Java 1.5 的时候引入的功能,它允许方法使用任意多个、类型相同(is-a)的值作为参数。就像下面这样。

    public static void main(String[] args) {
         print("沉");
         print("沉", "默");
         print("沉", "默", "王");
    @@ -101,6 +101,6 @@ logger.debug
     public static void print(Integer... ints) {
     }
     

    上面这段代码是可以编译通过的。因为编译器知道参数是 String 类型还是 Integer 类型,只不过为了运行时不抛出 NullPointerException,两个 print() 方法的内部要做好判空操作。

    - + diff --git a/dist/basic-grammar/basic-data-type.html b/dist/basic-grammar/basic-data-type.html index c46a15b3..6deeb80b 100644 --- a/dist/basic-grammar/basic-data-type.html +++ b/dist/basic-grammar/basic-data-type.html @@ -39,10 +39,10 @@ } - + -

    Java 支持的 8 种基本数据类型

    沉默王二2021年10月22日
    • Java核心
    • Java
    大约 9 分钟

    Java 支持的 8 种基本数据类型

    “二哥,上一节open in new window提到了 Java 变量的数据类型,是不是指定了类型就限定了变量的取值范围啊?”三妹吸了一口麦香可可奶茶后对我说。

    “三妹,你不得了啊,长进很大嘛,都学会推理判断了。Java 是一种静态类型的编程语言,这意味着所有变量必须在使用之前声明好,也就是必须得先指定变量的类型和名称。”

    Java 中的数据类型可分为 2 种:

    1)基本数据类型

    基本数据类型是 Java 语言操作数据的基础,包括 boolean、char、byte、short、int、long、float 和 double,共 8 种。

    2)引用数据类型

    除了基本数据类型以外的类型,都是所谓的引用类型。常见的有数组(对,没错,数组是引用类型)、class(也就是类),以及接口(指向的是实现接口的类的对象)。

    来个思维导图,感受下。

    通过上一节open in new window的学习,我们知道变量可以分为局部变量、成员变量、静态变量。

    当变量是局部变量的时候,必须得先初始化,否则编译器不允许你使用它。拿 int 来举例吧,看下图。

    当变量是成员变量或者静态变量时,可以不进行初始化,它们会有一个默认值,仍然以 int 为例,来看代码:

    /**
    +    

    Java 支持的 8 种基本数据类型

    沉默王二2021年10月22日
    • Java核心
    • Java
    大约 9 分钟

    Java 支持的 8 种基本数据类型

    “二哥,上一节open in new window提到了 Java 变量的数据类型,是不是指定了类型就限定了变量的取值范围啊?”三妹吸了一口麦香可可奶茶后对我说。

    “三妹,你不得了啊,长进很大嘛,都学会推理判断了。Java 是一种静态类型的编程语言,这意味着所有变量必须在使用之前声明好,也就是必须得先指定变量的类型和名称。”

    Java 中的数据类型可分为 2 种:

    1)基本数据类型

    基本数据类型是 Java 语言操作数据的基础,包括 boolean、char、byte、short、int、long、float 和 double,共 8 种。

    2)引用数据类型

    除了基本数据类型以外的类型,都是所谓的引用类型。常见的有数组(对,没错,数组是引用类型)、class(也就是类),以及接口(指向的是实现接口的类的对象)。

    来个思维导图,感受下。

    通过上一节open in new window的学习,我们知道变量可以分为局部变量、成员变量、静态变量。

    当变量是局部变量的时候,必须得先初始化,否则编译器不允许你使用它。拿 int 来举例吧,看下图。

    当变量是成员变量或者静态变量时,可以不进行初始化,它们会有一个默认值,仍然以 int 为例,来看代码:

    /**
      * @author 微信搜「沉默王二」,回复关键字 PDF
      */
     public class LocalVar {
    @@ -113,6 +113,6 @@ null
             implements List<E>, RandomAccess, Cloneable, java.io.Serializable
     {}
     

    对于接口类型的引用变量来说,你没法直接 new 一个:

    只能 new 一个实现它的类的对象——那自然接口也是引用数据类型了。

    来看一下基本数据类型和引用数据类型之间最大的差别。

    基本数据类型:

    • 1、变量名指向具体的数值。
    • 2、基本数据类型存储在栈上。

    引用数据类型:

    • 1、变量名指向的是存储对象的内存地址,在栈上。
    • 2、内存地址指向的对象存储在堆上。

    看到这,三妹是不是又要问,“堆是什么,栈又是什么?”

    堆是堆(heap),栈是栈(stack),如果看到“堆栈”的话,请不要怀疑自己,那是翻译的错,堆栈也是栈,反正我很不喜欢“堆栈”这种叫法,容易让新人掉坑里。

    堆是在程序运行时在内存中申请的空间(可理解为动态的过程);切记,不是在编译时;因此,Java 中的对象就放在这里,这样做的好处就是:

    当需要一个对象时,只需要通过 new 关键字写一行代码即可,当执行这行代码时,会自动在内存的“堆”区分配空间——这样就很灵活。

    栈,能够和处理器(CPU,也就是脑子)直接关联,因此访问速度更快。既然访问速度快,要好好利用啊!Java 就把对象的引用放在栈里。为什么呢?因为引用的使用频率高吗?

    不是的,因为 Java 在编译程序时,必须明确的知道存储在栈里的东西的生命周期,否则就没法释放旧的内存来开辟新的内存空间存放引用——空间就那么大,前浪要把后浪拍死在沙滩上啊。

    这么说就理解了吧?

    “好了,三妹,关于 Java 中的数据类型就先说这么多吧,你是不是已经清楚了?”转动了一下僵硬的脖子后,我对三妹说。

    - + diff --git a/dist/basic-grammar/flow-control.html b/dist/basic-grammar/flow-control.html index 4757637e..7441cd87 100644 --- a/dist/basic-grammar/flow-control.html +++ b/dist/basic-grammar/flow-control.html @@ -39,10 +39,10 @@ } - + -

    Java流程控制语句

    沉默王二2021年10月22日
    • Java核心
    • Java
    大约 10 分钟

    Java流程控制语句

    “二哥,流程控制语句都有哪些呢?”三妹的脸上泛着甜甜的笑容,她开始对接下来要学习的内容充满期待了,这正是我感到欣慰的地方。

    “比如说 if-else、switch、for、while、do-while、return、break、continue 等等,接下来,我们一个个来了解下。”

    01、if-else 相关

    1)if 语句

    if 语句的格式如下:

    if(布尔表达式){  
    +    

    Java流程控制语句

    沉默王二2021年10月22日
    • Java核心
    • Java
    大约 10 分钟

    Java流程控制语句

    “二哥,流程控制语句都有哪些呢?”三妹的脸上泛着甜甜的笑容,她开始对接下来要学习的内容充满期待了,这正是我感到欣慰的地方。

    “比如说 if-else、switch、for、while、do-while、return、break、continue 等等,接下来,我们一个个来了解下。”

    01、if-else 相关

    1)if 语句

    if 语句的格式如下:

    if(布尔表达式){  
     // 如果条件为 true,则执行这块代码
     } 
     

    画个流程图表示一下:

    来写个示例:

    public class IfExample {
    @@ -468,6 +468,6 @@
     9
     10
     

    注意:同样的,如果把 if 条件中的“i++”省略掉的话,程序就会进入死循环,一直在 continue。

    - + diff --git a/dist/basic-grammar/javadoc.html b/dist/basic-grammar/javadoc.html index a5cae67b..ae0ae117 100644 --- a/dist/basic-grammar/javadoc.html +++ b/dist/basic-grammar/javadoc.html @@ -39,10 +39,10 @@ } - + -

    Java注释:单行、多行和文档注释

    沉默王二2021年10月22日
    • Java核心
    • Java
    大约 4 分钟

    Java注释:单行、多行和文档注释

    “二哥,Java 中的注释好像真没什么可讲的,我已经提前预习了,不过是单行注释,多行注释,还有文档注释。”三妹的脸上泛着甜甜的笑容,她竟然提前预习了接下来要学习的知识,有一种“士别三日,当刮目相看”的感觉。

    “注释的种类确实不多,但还是挺有意思的,且听哥来给你说道说道。”

    01、单行注释

    单行注释通常用于解释方法内某单行代码的作用。

    public void method() {
    +    

    Java注释:单行、多行和文档注释

    沉默王二2021年10月22日
    • Java核心
    • Java
    大约 4 分钟

    Java注释:单行、多行和文档注释

    “二哥,Java 中的注释好像真没什么可讲的,我已经提前预习了,不过是单行注释,多行注释,还有文档注释。”三妹的脸上泛着甜甜的笑容,她竟然提前预习了接下来要学习的知识,有一种“士别三日,当刮目相看”的感觉。

    “注释的种类确实不多,但还是挺有意思的,且听哥来给你说道说道。”

    01、单行注释

    单行注释通常用于解释方法内某单行代码的作用。

    public void method() {
         int age = 18; // age 用于表示年龄
     }
     

    但如果写在行尾的话,其实是不符合阿里巴巴的开发规约的

    正确的单行注释如上图中所说,在被注释语句上方另起一行,使用 // 注释。

    public void method() {
    @@ -91,6 +91,6 @@ name 用于表示姓名
     public class Test {
     }
     

    4)所有的枚举类型字段必须要有注释,说明每个数据项的用途。

    5)代码修改的同时,注释也要进行相应的修改。

    “好了,三妹,关于 Java 中的注释就先说这么多吧。”转动了一下僵硬的脖子后,我对三妹说。“记住一点,注释是程序固有的一部分。”

    第一、注释要能够准确反映设计思想和代码逻辑;第二、注释要能够描述业务含 义,使别的程序员能够迅速了解到代码背后的信息。完全没有注释的大段代码对于阅读者形同 天书,注释是给自己看的,即使隔很长时间,也能清晰理解当时的思路;注释也是给继任者看 的,使其能够快速接替自己的工作。


    - + diff --git a/dist/basic-grammar/operator.html b/dist/basic-grammar/operator.html index 80f7ce31..5b927f44 100644 --- a/dist/basic-grammar/operator.html +++ b/dist/basic-grammar/operator.html @@ -39,10 +39,10 @@ } - + -

    Java运算符

    沉默王二2021年10月22日
    • Java核心
    • Java
    大约 8 分钟

    Java运算符

    “二哥,让我盲猜一下哈,运算符是不是指的就是加减乘除啊?”三妹的脸上泛着甜甜的笑容,我想她一定对提出的问题很有自信。

    “是的,三妹。运算符在 Java 中占据着重要的位置,对程序的执行有着很大的帮助。除了常见的加减乘除,还有许多其他类型的运算符,来看下面这张思维导图。”

    01、算数运算符

    算术运算符除了最常见的加减乘除,还有一个取余的运算符,用于得到除法运算后的余数,来串代码感受下。

    /**
    +    

    Java运算符

    沉默王二2021年10月22日
    • Java核心
    • Java
    大约 8 分钟

    Java运算符

    “二哥,让我盲猜一下哈,运算符是不是指的就是加减乘除啊?”三妹的脸上泛着甜甜的笑容,我想她一定对提出的问题很有自信。

    “是的,三妹。运算符在 Java 中占据着重要的位置,对程序的执行有着很大的帮助。除了常见的加减乘除,还有许多其他类型的运算符,来看下面这张思维导图。”

    01、算数运算符

    算术运算符除了最常见的加减乘除,还有一个取余的运算符,用于得到除法运算后的余数,来串代码感受下。

    /**
      * 微信搜索「沉默王二」,回复 Java
      */
     public class ArithmeticOperator {
    @@ -245,6 +245,6 @@ public class BigIntMulti {
         }
     }
     

    如果 ? 前面的条件为 true,则结果为 : 前的值,否则为 : 后的值。

    “好了,三妹,关于 Java 运算符就先说这么多吧,你是不是已经清楚了?”转动了一下僵硬的脖子后,我对三妹说。

    “差不多,二哥,我需要写点 demo 练习会。”

    - + diff --git a/dist/cityselect/beijing.html b/dist/cityselect/beijing.html index aa5838b1..7d8bfe4c 100644 --- a/dist/cityselect/beijing.html +++ b/dist/cityselect/beijing.html @@ -5,7 +5,7 @@ - 北京都有哪些牛逼的互联网公司? | Java 程序员进阶之路 + 北京都有哪些值得加入的IT互联网公司? | Java 程序员进阶之路 + + + + + +

    济南都有哪些值得加入的IT互联网公司?

    沉默王二2022年6月11日
    • 求职面试
    • 城市选择
    大约 7 分钟

    Part1 工作机会

    经过调查发现,济南的互联网环境是挺差的,大的公司几乎不会在济南成规模的招程序员。

    如果你是一个应届毕业生,拿到济南阿里、华为、海康、铁路局等 offer 的话,想要离家近生活比较舒服那么值得去。其余的公司我不建议校招直接去,想去可以先去外面的大公司干几年,社招再回来。除非是没有更好的 offer。

    另外,如果你想一直待在济南,不如去个有编制的地方,虽然我对技术有执念,但是也不得不承认在山东还是去个有编制的地方香。

    阿里巴巴

    阿里巴巴在济南招开发的部门是本地生活,开发的业务是商家运营和餐饮供应链以及扫码点餐,薪资水平会比杭州北京等地低一些。因为阿里在济南就那么多人,所以 hc 的数量非常有限,我写这篇文章的时候又去阿里招聘网站上搜了下就没岗位信息了,大家有意的多盯着点。另外阿里云在济南也有岗位,不过这种岗位招的都是高 p,名额都是一个两个的招。

    浪潮

    济南是浪潮的大本营,浪潮在济南的岗位非常多,软件、硬件、算法都有。校招待遇方面受岗位和学历的影响很大,硕士会比本科生高一两千,算法,ic 类岗位的薪资会比软件开发多不少。月薪基本在 9-15k 之间, 如果你是本科且做软件开发,基本上就是 9-10k 了,好一些学校的硕士且岗位是算法之类的月薪差不多会在15k 左右。另外浪潮每月有加起来 1k 的房补,公积金满额。工作强度方面,浪潮加班很猛,但是除了法定节假日有加班费外,平时加班就没加班费了。

    华为

    对,你没看错,华为在济南是招开发岗的,不过 hc 不多。在济南的华为每年校招的 hc 就是个位数,社招想进去的话基本上就是通过华为 OD 了。

    很多同学好奇华为OD 和华为正式 offer 的区别,我也就这个问题请教了下在华为工作的我的同学。听到的说法是,目前华为社招卡的很严,除非是 17 或 18 以上的高职级,否则都需要以 OD 的形式进华为。

    如果你校招曾经拿过华为的 offer 但是没去,那么以后社招也是有可能直接给你正式 offer 的。华为 OD 是和外企德科签(外企德科这个名字确实有点逗,虽然他叫外企德科但是他不是外企),OD 和华为正式员工是同工同酬,不过没有股票,稳定性也和正式职工差点。

    这点和软通动力、中软国际等派到华为工作的不太一样,软通动力和中软国际有一套自己的薪资体系。华为 OD 每年会有一次变成正式职工的机会。

    济南这边的华为貌似是一个研发中心的分部(好像是南京研发中心的分部),公司注册地不在济南,无法领取济南市政府的人才补贴(硕士每月有一千左右的人才补贴)。我看济南这边有校招 14 级的同学爆料薪资是 19k x 14,其中每月有 4k 是绩效,公积金按工资的 5%交。

    海康威视

    海康威视也是济南程序员比较不错的去处了,硕士大部分月薪是 13k ,少量能到 15k,本科生进海康貌似统一价都是 9k,每年13-15 个月的薪资。每天有 45 的餐补,10块钱的交通补,通讯补贴每月 200。月薪的20% 是绩效,按基本工资的 12% 缴纳住房公积金。工作制度是大小周。虽然海康有很多槽点,但是技术还是不错的,有不少值得学习的地方,另外能在济南给到这个薪资,我觉得还是不错的。

    联通软件研究院

    目前看爆料济南的联通软件研究院情况的基本都是硕士,税前 9k(本科还要少一点),每年 15-16个月的薪资,额外还会有一些补贴。摆明说要加班,工作制度基本 996,且加班没有加班费。目前网上的评价不是太好。在所有的联通软件研究院里算比较卷的。

    中国重汽

    重汽招的软件开发的岗位也不少,校招进去月薪是 15-20k x 12,年终奖很少,就几千。另外第二年会把薪资的一部分转化成绩效,绩效不达标薪资就发不满了,相当于变相降薪。重汽虽然是国企,但不太像国企的作风,有末尾淘汰,周末经常加班。好像前几个月还要轮岗,上流水线跟工人一块组装汽车。

    铁路局济南信息所

    hr 说的税前年薪总包是 15 w,网上的信息比较少,盲猜风格应该和郑州铁路局的信息所差不多,应该是会有加班,但工作稳定。

    齐鲁空天信息研究院

    薪资差不多是税前 12k x 14 的样子,但是每月工资里面一部分是绩效,如果项目不多的话绩效拿不满。另外出差很多,感觉性价比一般。

    济南我了解到的大型的公司且招程序员的只有这么多了。倒是还有很多小型公司,大家可以在 boss 、拉钩等招聘网站直接搜,因为这些公司信息很少,我没了解到什么有效信息,就不介绍了。大家如果还知道哪些不错的济南的程序员的工作机会,也欢迎跟我说。对了,我了解到山东高速会招一些程序员,待遇不错,大家可以去详细了解下。

    Part2 生活

    房价

    相比于济南的工资水平,济南的房价真的是有点高啊。济南的房价前段时间一直跌,但目前在同类型二线城市中,依然算房价偏高的了。我在网上找了个图,不是太准,大家可以做个参考。在济南工资的背景下,在济南年轻人买房压力是挺大呀!

    教育

    教育上不用我多说,山东的教育真的是太卷了,山东的高考难度真的是地狱级。我身边的山东同学都学习挺不错的,也难怪,在山东杀出重围考上好一点大学的,当年在山东那都是英雄一般的人物。读研时带我的师兄,以及好几个关系不错的同学,还有我现在的组长都是山东的,他们都给我一种很努力,肯吃苦,且很踏实的感觉。我是挺喜欢和山东人相处的。

    高校的计算机专业资源方面,感觉济南不如青岛,中国海洋大学和中国石油大学都在青岛,山东大学的计算机专业一部分也放在了青岛。这样感觉济南今后计算机人才的积累肯定不如青岛。所以计算机相关行业发展我还是更看好青岛了。

    风景 and 交通 and 美食

    济南的风景很漂亮,趵突泉,大明湖,黑虎泉,千佛山,百花洲这些景点都是我从小就听说过的,周末去转一转也是很惬意的事情。交通方面济南是挺堵的,感觉交通的规划上存在问题,所以刚上班租房的时候,宁可租的房子小一点,破一点,也要住的离公司近一点,不然上班时候堵车可真难顶。饮食方面,鲁菜爱倒酱油,口味会偏咸,不过济南对饭菜口味的包容性很强,各种菜系都能找到。

    作者:大白,转载链接:https://mp.weixin.qq.com/s/5rjqpY4Wxs0wEw7VuHXIpgopen in new window

    + + + diff --git a/dist/cityselect/nanjing.html b/dist/cityselect/nanjing.html index 924a9e96..1cf62549 100644 --- a/dist/cityselect/nanjing.html +++ b/dist/cityselect/nanjing.html @@ -5,7 +5,7 @@ - 南京有哪些靠谱的互联网公司? | Java 程序员进阶之路 + 南京都有哪些值得加入的IT互联网公司? | Java 程序员进阶之路 + + + + + +

    沉默王二2022年6月10日小于 1 分钟

    user www www; worker_processes auto; error_log /www/wwwlogs/nginx_error.log crit; pid /www/server/nginx/logs/nginx.pid; worker_rlimit_nofile 51200;

    events { use epoll; worker_connections 51200; multi_accept on; }

    http { include mime.types; #include luawaf.conf;

        include proxy.conf;
    +
    +    default_type  application/octet-stream;
    +
    +    server_names_hash_bucket_size 512;
    +    client_header_buffer_size 32k;
    +    large_client_header_buffers 4 32k;
    +    client_max_body_size 50m;
    +
    +    sendfile   on;
    +    tcp_nopush on;
    +
    +    keepalive_timeout 60;
    +
    +    tcp_nodelay on;
    +
    +    fastcgi_connect_timeout 300;
    +    fastcgi_send_timeout 300;
    +    fastcgi_read_timeout 300;
    +    fastcgi_buffer_size 64k;
    +    fastcgi_buffers 4 64k;
    +    fastcgi_busy_buffers_size 128k;
    +    fastcgi_temp_file_write_size 256k;
    +    fastcgi_intercept_errors on;
    +
    +    gzip on; # 开启Gzip
    +    gzip_static on; # 开启静态文件压缩
    +    gzip_min_length  1k; # 不压缩临界值,大于1K的才压缩
    +    gzip_buffers     4 16k;
    +    gzip_http_version 1.1;
    +    gzip_comp_level 2;
    +    gzip_types     text/plain application/javascript application/x-javascript text/javascript text/css application/xml;
    +    gzip_vary on;
    +    gzip_proxied   expired no-cache no-store private auth;
    +    gzip_disable   "MSIE [1-6]\.";
    +
    +    limit_conn_zone $binary_remote_addr zone=perip:10m;
    +    limit_conn_zone $server_name zone=perserver:10m;
    +
    +    server_tokens off;
    +    access_log off;
    +    
    +upstream codingmore_web_pool{
    +    server 127.0.0.1:8081;
    +}
    +
    +upstream codingmore_admin_pool{
    +    server 127.0.0.1:9002;
    +}
    +
    +server {
    +    listen       80;
    +    server_name  codingmore.top;
    +    access_log /home/www/codingmore_web.log;
    +    error_log /home/www/codingmore_web.error;
    +
    +    location /admin/ {
    +        alias /www/wwwroot/itwanger/dist/; # 根目录
    +        index index.html;
    +    }
    +
    +    location /api/ {
    +        proxy_set_header Host $host;
    +        proxy_set_header X-Forwarded-For  $proxy_add_x_forwarded_for;
    +        proxy_pass http://codingmore_admin_pool/;
    +    }
    +    
    +    #将所有请求转发给pool池的应用处理
    +    location / {
    +        proxy_set_header Host $host;
    +        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    +        proxy_pass http://codingmore_web_pool;
    +    }
    +}
    +
    +server
    +    {
    +    listen 888;
    +    server_name phpmyadmin;
    +    index index.html index.htm index.php;
    +    root  /www/server/phpmyadmin;
    +        location ~ /tmp/ {
    +            return 403;
    +        }
    +
    +    #error_page   404   /404.html;
    +    include enable-php.conf;
    +
    +    location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$
    +    {
    +        expires      30d;
    +    }
    +
    +    location ~ .*\.(js|css)?$
    +    {
    +        expires      12h;
    +    }
    +
    +    location ~ /\.
    +    {
    +        deny all;
    +    }
    +
    +    access_log  /www/wwwlogs/access.log;
    +}
    +
    +include /www/server/panel/vhost/nginx/*.conf;
    +

    }

    + + + diff --git a/dist/nice-article/weixin-bagwpdf.html b/dist/nice-article/weixin-bagwpdf.html new file mode 100644 index 00000000..c28b1d7d --- /dev/null +++ b/dist/nice-article/weixin-bagwpdf.html @@ -0,0 +1,48 @@ + + + + + + + + 👏下载→最全最硬核的Java面试 “备战” 资料 | Java 程序员进阶之路 + + + + + + +

    👏下载→最全最硬核的Java面试 “备战” 资料

    沉默王二2022年6月11日
    • 学习资源
    • PDF
    大约 2 分钟

    大家好,我是二哥呀!分享一下今天整理汇总的一些 Java 面试相关的 PDF 资料,希望对需要的小伙伴有帮助!

    大家可以扫描下方的二维码发送关键字「00」获取下载链接。

    也可以直接微信搜索「沉默王二」关注后回复【00】

    1、《JavaGuide 面试突击最新版》

    Github 110k+ star 开源项目 JavaGuide 的面试版本,涵盖 Java 基础、Java 并发、JVM、计算机基础、数据库、常用框架(Spring、MyBatis、Netty 等等)、系统设计、大厂面经等内容。

    2、《Java 工程师进阶知识完全扫盲》

    Github 标星 58k+ star 开源项目的 PDF 版本,涵盖消息队列、搜索引擎、缓存、分库分表、读写分离、分布式事务、熔断限流、微服务等内容。

    3、《Java 面试资料》

    4、《分布式相关面试题汇总》

    这是一份专门讲分布式事务的文档,内容非常全面,一共 141 页,基本把分布式事务比较重要的知识点和面试题都概括到了。

    5、《Java 八股文》113 道,背诵版

    我总结出来的这份 Java 八股文,共计 113 道,包括 Java 基础、Java 并发编程、Java 虚拟机三大部分,全都是高频面试题,“吊打”面试官绝不是问题。

    如何获取?

    直接长按扫码关注下方二维码,回复 「00」 下载这10份 PDF 吧!

    ············  END  ··············

    + + + diff --git a/dist/nice-article/weixin-chengxwjdwzhqcgxm.html b/dist/nice-article/weixin-chengxwjdwzhqcgxm.html index 41a8f75d..0e99d7de 100644 --- a/dist/nice-article/weixin-chengxwjdwzhqcgxm.html +++ b/dist/nice-article/weixin-chengxwjdwzhqcgxm.html @@ -39,10 +39,10 @@ } - + -

    程序汪接的8万智慧取餐柜项目

    程序汪2022年6月8日
    • 优质文章
    大约 9 分钟

    本文章来自程序汪背后的私活小团队,开发智慧取餐柜的项目,本项目非常类似快递柜项目,本项目的完整解决方案跟大家分享一下,希望给大家一些参考

    B站 我是程序汪 点最下方原文链接进入

    这是取餐柜成品的样子,硬件厂家提供的不用程序汪去开发硬件哦,我们只开发的软件部分(小程序,PC端,APP)

    下面是厂家快递过来的测试机器4口,别问我为什么跟上面的不一样,上面的那个实在太大了啊,测试联调只要接口OK就行

    流程图先晒下,画的很简单

    B站【我是程序汪】

    现在开发项目都喜欢前面加个智慧,程序汪的这个项目也是智慧XXX

    说白了就是一个外卖项目的升级版本

    这图是用processon画的

    开发人员情况(1人)

    • uniapp 前端 技术栈 vue 主要任务 小程序及PC端页面,APP (存取 餐)

    • 后端   技术栈  springboot

    • 开发周期40天(设计+开发)

    • 开发人数 1人

    • 整体费用是8万(不含硬件部分),这是一期的开发费用

    • 付款模式 5:4:1 首付:验收:尾款

    • 走的正规公司合同

    • 云服务器1台 4核8G,经费有限先就安排1台,不够后面升级

    • 维护费用 项目总款项10%

    • 售后维护 | 域名 | 服务器 | 日常运维 |

    技术选型

    • 核心框架:Spring Boot
    • 数据库连接池:Druid
    • 缓存:redis
    • 前端:Vue
    • APP 小程序 Uniapp
    • 数据库:mysql
    • 服务器配置 4核8G
    • 硬件接口开发联调(云打印机 取餐柜)

    项目背景

    大城市里公司上班族,经常交通通勤都1个多小时,购买早餐也经常需要排很长的队,很浪费时间,本系统就是为了解决上班族购买早餐难的痛点而诞生的。程序汪上海上班时,吃早餐就很头疼,办公大厦楼下早餐店排队很夸张的,浪费了我很多写代码的时间呀。

    小程序

    程序汪把核心页面截图出来

    本小程序主要功能就这些

    • 用户下订单
    • 骑手存餐

    下面是我们的测试体验版小程序,初始数据有点随意

    跟普通下单外卖不同的地方就是可以选择取餐时间和机柜

    骑手进入本页面点击【存餐】触发 取餐柜

    下单成功会短信通知用户 取餐码

    PC端

    目前主要功能,说白了在外卖系统二开的,分系统管理员和商家角色

    • 商品管理 -分系统和商家

    • 订单管理   -分系统和商家

    • 店铺管理   -分系统和商家

    • 会员权限管理

    • 售后管理

    • 统计报表

    • 订单物流

    • 财务管理

    • 骑手管理

    下面截图就是开源系统上面二开的,别问我为啥管理系统页面都长了差不多,前端是Vue

    系统管理员角色

    商家角色

    硬件部分(取餐柜)

    主要硬件是取餐柜,这个是找的第三方现成的硬件厂家,对方会提供接口文档具体的SDK包,我们的工作量就是接口开发然后联调一波。

    取餐接口(取餐柜)

    下面我把核心的存餐接口给大家列出来下

    创建存餐订单

    使用场景

    创建存餐订单

    操作名称

    createOrder

    请求字段

    {  
    +    

    程序汪接的8万智慧取餐柜项目

    程序汪2022年6月8日
    • 优质文章
    大约 9 分钟

    本文章来自程序汪背后的私活小团队,开发智慧取餐柜的项目,本项目非常类似快递柜项目,本项目的完整解决方案跟大家分享一下,希望给大家一些参考

    B站 我是程序汪 点最下方原文链接进入

    这是取餐柜成品的样子,硬件厂家提供的不用程序汪去开发硬件哦,我们只开发的软件部分(小程序,PC端,APP)

    下面是厂家快递过来的测试机器4口,别问我为什么跟上面的不一样,上面的那个实在太大了啊,测试联调只要接口OK就行

    流程图先晒下,画的很简单

    B站【我是程序汪】

    现在开发项目都喜欢前面加个智慧,程序汪的这个项目也是智慧XXX

    说白了就是一个外卖项目的升级版本

    这图是用processon画的

    开发人员情况(1人)

    • uniapp 前端 技术栈 vue 主要任务 小程序及PC端页面,APP (存取 餐)

    • 后端   技术栈  springboot

    • 开发周期40天(设计+开发)

    • 开发人数 1人

    • 整体费用是8万(不含硬件部分),这是一期的开发费用

    • 付款模式 5:4:1 首付:验收:尾款

    • 走的正规公司合同

    • 云服务器1台 4核8G,经费有限先就安排1台,不够后面升级

    • 维护费用 项目总款项10%

    • 售后维护 | 域名 | 服务器 | 日常运维 |

    技术选型

    • 核心框架:Spring Boot
    • 数据库连接池:Druid
    • 缓存:redis
    • 前端:Vue
    • APP 小程序 Uniapp
    • 数据库:mysql
    • 服务器配置 4核8G
    • 硬件接口开发联调(云打印机 取餐柜)

    项目背景

    大城市里公司上班族,经常交通通勤都1个多小时,购买早餐也经常需要排很长的队,很浪费时间,本系统就是为了解决上班族购买早餐难的痛点而诞生的。程序汪上海上班时,吃早餐就很头疼,办公大厦楼下早餐店排队很夸张的,浪费了我很多写代码的时间呀。

    小程序

    程序汪把核心页面截图出来

    本小程序主要功能就这些

    • 用户下订单
    • 骑手存餐

    下面是我们的测试体验版小程序,初始数据有点随意

    跟普通下单外卖不同的地方就是可以选择取餐时间和机柜

    骑手进入本页面点击【存餐】触发 取餐柜

    下单成功会短信通知用户 取餐码

    PC端

    目前主要功能,说白了在外卖系统二开的,分系统管理员和商家角色

    • 商品管理 -分系统和商家

    • 订单管理   -分系统和商家

    • 店铺管理   -分系统和商家

    • 会员权限管理

    • 售后管理

    • 统计报表

    • 订单物流

    • 财务管理

    • 骑手管理

    下面截图就是开源系统上面二开的,别问我为啥管理系统页面都长了差不多,前端是Vue

    系统管理员角色

    商家角色

    硬件部分(取餐柜)

    主要硬件是取餐柜,这个是找的第三方现成的硬件厂家,对方会提供接口文档具体的SDK包,我们的工作量就是接口开发然后联调一波。

    取餐接口(取餐柜)

    下面我把核心的存餐接口给大家列出来下

    创建存餐订单

    使用场景

    创建存餐订单

    操作名称

    createOrder

    请求字段

    {  
     
         "deviceId":"xxxxxxxxxxx",   // 必传,设备ID  
     
    @@ -186,6 +186,6 @@ timestamp|int|当前服务器时间戳(10位)|是|
     **▲**回复「****743****」**▲**
     
     **点下方原文链接观看B站视频版本**
    - + diff --git a/dist/nice-article/weixin-githubxbkdjavajccjyh.html b/dist/nice-article/weixin-githubxbkdjavajccjyh.html new file mode 100644 index 00000000..98dc6ee8 --- /dev/null +++ b/dist/nice-article/weixin-githubxbkdjavajccjyh.html @@ -0,0 +1,48 @@ + + + + + + + + 👏下载→GitHub星标115k+的Java教程 | Java 程序员进阶之路 + + + + + + +

    👏下载→GitHub星标115k+的Java教程

    沉默王二2022年6月11日
    • 学习资源
    • PDF
    大约 1 分钟

    学 Java 其实不难,重要的是找到好的学习资料和学习方法,然后就是付诸实践。

    我不太建议大家一上来就阅读《Java 核心技术卷》这些书,因为书太厚,对于初学者来说不是特别友好,如果没耐心可能就直接劝退了。我也不太建议大家一上来就去看视频,因为视频一般比较啰嗦,抓不住重点。

    大家先看看我整理的这份 GitHub 上星标 115k+ 的 Java 教程,里面涵盖了 Java 所有的知识点,包括 Java 语法、Java 集合框架、Java IO、Java 并发编程和 Java 虚拟机,内容不多,只讲重点

    可以扫描下方的二维码发送关键字「001」获取下载链接。

    也可以直接微信搜索「沉默王二」关注后回复【001】

    来看一下目录吧!

    为了整理这份 PDF,我可是费了老大劲,希望大家能珍惜。目前这份 PDF 已经放在百度网盘上,下载数量有三万一千多次,说明得到了很多人的认同。

    可以微信搜索「沉默王二」或者扫描下面的二维码关注后回复「001」关键字拉取离线版 PDF 的下载地址。

    GitHub 地址我也贴一下:

    https://github.com/CyC2018/CS-Notesopen in new window

    + + + diff --git a/dist/nice-article/weixin-liaoliaoxianliu.html b/dist/nice-article/weixin-liaoliaoxianliu.html index d6d4fe47..6482f14f 100644 --- a/dist/nice-article/weixin-liaoliaoxianliu.html +++ b/dist/nice-article/weixin-liaoliaoxianliu.html @@ -39,10 +39,10 @@ } - + -

    聊聊限流

    楼仔2022年6月2日
    • 优质文章
    大约 11 分钟

    大家好,我是楼仔!

    在电商高并发场景下,我们经常会使用一些常用方法,去应对流量高峰,比如限流、熔断、降级,今天我们聊聊限流。

    什么是限流呢?限流是限制到达系统的并发请求数量,保证系统能够正常响应部分用户请求,而对于超过限制的流量,则通过拒绝服务的方式保证整体系统的可用性。

    根据限流作用范围,可以分为单机限流和分布式限流;根据限流方式,又分为计数器、滑动窗口、漏桶和令牌桶限流,下面我们对这块详细进行讲解。

    文章大部分内容参考  TPaper 的《Go 实现各类限流算法》open in new window,特此说明!

    常用限流方式

    计数器

    计数器是一种最简单限流算法,其原理就是:在一段时间间隔内,对请求进行计数,与阀值进行比较判断是否需要限流,一旦到了时间临界点,将计数器清零。

    这个就像你去坐车一样,车厢规定了多少个位置,满了就不让上车了,不然就是超载了,被交警叔叔抓到了就要罚款的,如果我们的系统那就不是罚款的事情了,可能直接崩掉了。

    程序执行逻辑:

    • 可以在程序中设置一个变量 count,当过来一个请求我就将这个数 +1,同时记录请求时间。
    • 当下一个请求来的时候判断 count 的计数值是否超过设定的频次,以及当前请求的时间和第一次请求时间是否在 1 分钟内。
    • 如果在 1 分钟内并且超过设定的频次则证明请求过多,后面的请求就拒绝掉。
    • 如果该请求与第一个请求的间隔时间大于计数周期,且 count 值还在限流范围内,就重置 count。

    那么问题来了,如果有个需求对于某个接口 /query 每分钟最多允许访问 200 次,假设有个用户在第 59 秒的最后几毫秒瞬间发送 200 个请求,当 59 秒结束后 Counter 清零了,他在下一秒的时候又发送 200 个请求。

    那么在 1 秒钟内这个用户发送了 2 倍的请求,这个是符合我们的设计逻辑的,这也是计数器方法的设计缺陷,系统可能会承受恶意用户的大量请求,甚至击穿系统。这种方法虽然简单,但也有个大问题就是没有很好的处理单位时间的边界。

    不过说实话,这个计数引用了锁,在高并发场景,这个方式可能不太实用,我建议将锁去掉,然后将 l.count++ 的逻辑通过原子计数处理,这样就可以保证 l.count 自增时不会被多个线程同时执行,即通过原子计数的方式实现限流。

    为了不影响阅读,代码详见:https://github.com/lml200701158/go_demo/blob/master/current_limit/count.go

    滑动窗口

    滑动窗口是针对计数器存在的临界点缺陷,所谓滑动窗口(Sliding window)是一种流量控制技术,这个词出现在 TCP 协议中。滑动窗口把固定时间片进行划分,并且随着时间的流逝,进行移动,固定数量的可以移动的格子,进行计数并判断阀值。

    上图中我们用红色的虚线代表一个时间窗口(一分钟),每个时间窗口有 6 个格子,每个格子是 10 秒钟。每过 10 秒钟时间窗口向右移动一格,可以看红色箭头的方向。我们为每个格子都设置一个独立的计数器 Counter,假如一个请求在 0:45 访问了那么我们将第五个格子的计数器 +1(也是就是 0:40~0:50),在判断限流的时候需要把所有格子的计数加起来和设定的频次进行比较即可。

    那么滑动窗口如何解决我们上面遇到的问题呢?来看下面的图:

    当用户在 0:59 秒钟发送了 200 个请求就会被第六个格子的计数器记录 +200,当下一秒的时候时间窗口向右移动了一个,此时计数器已经记录了该用户发送的 200 个请求,所以再发送的话就会触发限流,则拒绝新的请求。

    其实计数器就是滑动窗口啊,只不过只有一个格子而已,所以想让限流做的更精确只需要划分更多的格子就可以了,为了更精确我们也不知道到底该设置多少个格子,格子的数量影响着滑动窗口算法的精度,依然有时间片的概念,无法根本解决临界点问题。

    为了不影响阅读,代码详见:https://github.com/RussellLuo/slidingwindow

    漏桶

    漏桶算法(Leaky Bucket),原理就是一个固定容量的漏桶,按照固定速率流出水滴。

    用过水龙头都知道,打开龙头开关水就会流下滴到水桶里,而漏桶指的是水桶下面有个漏洞可以出水,如果水龙头开的特别大那么水流速就会过大,这样就可能导致水桶的水满了然后溢出。

    图片如果看不清,可单击图片并放大。

    一个固定容量的桶,有水流进来,也有水流出去。对于流进来的水来说,我们无法预计一共有多少水会流进来,也无法预计水流的速度。但是对于流出去的水来说,这个桶可以固定水流出的速率(处理速度),从而达到流量整形和流量控制的效果。

    漏桶算法有以下特点:

    • 漏桶具有固定容量,出水速率是固定常量(流出请求)
    • 如果桶是空的,则不需流出水滴
    • 可以以任意速率流入水滴到漏桶(流入请求)
    • 如果流入水滴超出了桶的容量,则流入的水滴溢出(新请求被拒绝)

    漏桶限制的是常量流出速率(即流出速率是一个固定常量值),所以最大的速率就是出水的速率,不能出现突发流量。

    为了不影响阅读,代码详见:https://github.com/lml200701158/go_demo/blob/master/current_limit/leaky_bucket.go

    令牌桶

    令牌桶算法(Token Bucket)是网络流量整形(Traffic Shaping)和速率限制(Rate Limiting)中最常使用的一种算法。典型情况下,令牌桶算法用来控制发送到网络上的数据的数目,并允许突发数据的发送。

    图片如果看不清,可单击图片并放大。

    我们有一个固定的桶,桶里存放着令牌(token)。一开始桶是空的,系统按固定的时间(rate)往桶里添加令牌,直到桶里的令牌数满,多余的请求会被丢弃。当请求来的时候,从桶里移除一个令牌,如果桶是空的则拒绝请求或者阻塞。

    令牌桶有以下特点:

    • 令牌按固定的速率被放入令牌桶中
    • 桶中最多存放 B 个令牌,当桶满时,新添加的令牌被丢弃或拒绝
    • 如果桶中的令牌不足 N 个,则不会删除令牌,且请求将被限流(丢弃或阻塞等待)

    令牌桶限制的是平均流入速率(允许突发请求,只要有令牌就可以处理,支持一次拿3个令牌,4个令牌...),并允许一定程度突发流量,所以也是非常常用的限流算法。

    为了不影响阅读,代码详见:https://github.com/lml200701158/go_demo/blob/master/current_limit/token_bucket.go

    Redis + Lua 分布式限流

    单机版限流仅能保护自身节点,但无法保护应用依赖的各种服务,并且在进行节点扩容、缩容时也无法准确控制整个服务的请求限制。

    而分布式限流,以集群为维度,可以方便的控制这个集群的请求限制,从而保护下游依赖的各种服务资源。

    分布式限流最关键的是要将限流服务做成原子化,我们可以借助 Redis 的计数器,Lua 执行的原子性,进行分布式限流,大致的 Lua 脚本代码如下:

    local key = "rate.limit:" .. KEYS[1] --限流KEY  
    +    

    聊聊限流

    楼仔2022年6月2日
    • 优质文章
    大约 11 分钟

    大家好,我是楼仔!

    在电商高并发场景下,我们经常会使用一些常用方法,去应对流量高峰,比如限流、熔断、降级,今天我们聊聊限流。

    什么是限流呢?限流是限制到达系统的并发请求数量,保证系统能够正常响应部分用户请求,而对于超过限制的流量,则通过拒绝服务的方式保证整体系统的可用性。

    根据限流作用范围,可以分为单机限流和分布式限流;根据限流方式,又分为计数器、滑动窗口、漏桶和令牌桶限流,下面我们对这块详细进行讲解。

    文章大部分内容参考  TPaper 的《Go 实现各类限流算法》open in new window,特此说明!

    常用限流方式

    计数器

    计数器是一种最简单限流算法,其原理就是:在一段时间间隔内,对请求进行计数,与阀值进行比较判断是否需要限流,一旦到了时间临界点,将计数器清零。

    这个就像你去坐车一样,车厢规定了多少个位置,满了就不让上车了,不然就是超载了,被交警叔叔抓到了就要罚款的,如果我们的系统那就不是罚款的事情了,可能直接崩掉了。

    程序执行逻辑:

    • 可以在程序中设置一个变量 count,当过来一个请求我就将这个数 +1,同时记录请求时间。
    • 当下一个请求来的时候判断 count 的计数值是否超过设定的频次,以及当前请求的时间和第一次请求时间是否在 1 分钟内。
    • 如果在 1 分钟内并且超过设定的频次则证明请求过多,后面的请求就拒绝掉。
    • 如果该请求与第一个请求的间隔时间大于计数周期,且 count 值还在限流范围内,就重置 count。

    那么问题来了,如果有个需求对于某个接口 /query 每分钟最多允许访问 200 次,假设有个用户在第 59 秒的最后几毫秒瞬间发送 200 个请求,当 59 秒结束后 Counter 清零了,他在下一秒的时候又发送 200 个请求。

    那么在 1 秒钟内这个用户发送了 2 倍的请求,这个是符合我们的设计逻辑的,这也是计数器方法的设计缺陷,系统可能会承受恶意用户的大量请求,甚至击穿系统。这种方法虽然简单,但也有个大问题就是没有很好的处理单位时间的边界。

    不过说实话,这个计数引用了锁,在高并发场景,这个方式可能不太实用,我建议将锁去掉,然后将 l.count++ 的逻辑通过原子计数处理,这样就可以保证 l.count 自增时不会被多个线程同时执行,即通过原子计数的方式实现限流。

    为了不影响阅读,代码详见:https://github.com/lml200701158/go_demo/blob/master/current_limit/count.go

    滑动窗口

    滑动窗口是针对计数器存在的临界点缺陷,所谓滑动窗口(Sliding window)是一种流量控制技术,这个词出现在 TCP 协议中。滑动窗口把固定时间片进行划分,并且随着时间的流逝,进行移动,固定数量的可以移动的格子,进行计数并判断阀值。

    上图中我们用红色的虚线代表一个时间窗口(一分钟),每个时间窗口有 6 个格子,每个格子是 10 秒钟。每过 10 秒钟时间窗口向右移动一格,可以看红色箭头的方向。我们为每个格子都设置一个独立的计数器 Counter,假如一个请求在 0:45 访问了那么我们将第五个格子的计数器 +1(也是就是 0:40~0:50),在判断限流的时候需要把所有格子的计数加起来和设定的频次进行比较即可。

    那么滑动窗口如何解决我们上面遇到的问题呢?来看下面的图:

    当用户在 0:59 秒钟发送了 200 个请求就会被第六个格子的计数器记录 +200,当下一秒的时候时间窗口向右移动了一个,此时计数器已经记录了该用户发送的 200 个请求,所以再发送的话就会触发限流,则拒绝新的请求。

    其实计数器就是滑动窗口啊,只不过只有一个格子而已,所以想让限流做的更精确只需要划分更多的格子就可以了,为了更精确我们也不知道到底该设置多少个格子,格子的数量影响着滑动窗口算法的精度,依然有时间片的概念,无法根本解决临界点问题。

    为了不影响阅读,代码详见:https://github.com/RussellLuo/slidingwindow

    漏桶

    漏桶算法(Leaky Bucket),原理就是一个固定容量的漏桶,按照固定速率流出水滴。

    用过水龙头都知道,打开龙头开关水就会流下滴到水桶里,而漏桶指的是水桶下面有个漏洞可以出水,如果水龙头开的特别大那么水流速就会过大,这样就可能导致水桶的水满了然后溢出。

    图片如果看不清,可单击图片并放大。

    一个固定容量的桶,有水流进来,也有水流出去。对于流进来的水来说,我们无法预计一共有多少水会流进来,也无法预计水流的速度。但是对于流出去的水来说,这个桶可以固定水流出的速率(处理速度),从而达到流量整形和流量控制的效果。

    漏桶算法有以下特点:

    • 漏桶具有固定容量,出水速率是固定常量(流出请求)
    • 如果桶是空的,则不需流出水滴
    • 可以以任意速率流入水滴到漏桶(流入请求)
    • 如果流入水滴超出了桶的容量,则流入的水滴溢出(新请求被拒绝)

    漏桶限制的是常量流出速率(即流出速率是一个固定常量值),所以最大的速率就是出水的速率,不能出现突发流量。

    为了不影响阅读,代码详见:https://github.com/lml200701158/go_demo/blob/master/current_limit/leaky_bucket.go

    令牌桶

    令牌桶算法(Token Bucket)是网络流量整形(Traffic Shaping)和速率限制(Rate Limiting)中最常使用的一种算法。典型情况下,令牌桶算法用来控制发送到网络上的数据的数目,并允许突发数据的发送。

    图片如果看不清,可单击图片并放大。

    我们有一个固定的桶,桶里存放着令牌(token)。一开始桶是空的,系统按固定的时间(rate)往桶里添加令牌,直到桶里的令牌数满,多余的请求会被丢弃。当请求来的时候,从桶里移除一个令牌,如果桶是空的则拒绝请求或者阻塞。

    令牌桶有以下特点:

    • 令牌按固定的速率被放入令牌桶中
    • 桶中最多存放 B 个令牌,当桶满时,新添加的令牌被丢弃或拒绝
    • 如果桶中的令牌不足 N 个,则不会删除令牌,且请求将被限流(丢弃或阻塞等待)

    令牌桶限制的是平均流入速率(允许突发请求,只要有令牌就可以处理,支持一次拿3个令牌,4个令牌...),并允许一定程度突发流量,所以也是非常常用的限流算法。

    为了不影响阅读,代码详见:https://github.com/lml200701158/go_demo/blob/master/current_limit/token_bucket.go

    Redis + Lua 分布式限流

    单机版限流仅能保护自身节点,但无法保护应用依赖的各种服务,并且在进行节点扩容、缩容时也无法准确控制整个服务的请求限制。

    而分布式限流,以集群为维度,可以方便的控制这个集群的请求限制,从而保护下游依赖的各种服务资源。

    分布式限流最关键的是要将限流服务做成原子化,我们可以借助 Redis 的计数器,Lua 执行的原子性,进行分布式限流,大致的 Lua 脚本代码如下:

    local key = "rate.limit:" .. KEYS[1] --限流KEY  
     
     local limit = tonumber(ARGV[1])        --限流大小  
     
    @@ -91,6 +91,6 @@ end
     }  
     
     

    聊聊其它

    上面的限流方式,主要是针对服务器进行限流,我们也可以对容器进行限流,比如 Tomcat、Nginx 等限流手段。

    Tomcat 可以设置最大线程数(maxThreads),当并发超过最大线程数会排队等待执行;而 Nginx 提供了两种限流手段:一是控制速率,二是控制并发连接数。

    对于 Java 语言,我们其实有相关的限流组件,比如大家常用的 RateLimiter,其实就是基于令牌桶算法,大家知道为什么唯独选用令牌桶么?

    对于 Go 语言,也有该语言特定的限流方式,比如可以通过 channel 实现并发控制限流,也支持第三方库 httpserver 实现限流,详见这篇 《Go 限流的常见方法》open in new window

    在实际的限流场景中,我们也可以控制单个 IP、城市、渠道、设备 id、用户 id 等在一定时间内发送的请求数;如果是开放平台,需要为每个 appkey 设置独立的访问速率规则。

    限流对比

    下面我们就对常用的线程策略,总结它们的优缺点,便于以后选型。

    计数器:

    • 优点:固定时间段计数,实现简单,适用不太精准的场景;
    • 缺点:对边界没有很好处理,导致限流不能精准控制。

    滑动窗口:

    • 优点:将固定时间段分块,时间比“计数器”复杂,适用于稍微精准的场景;
    • 缺点:实现稍微复杂,还是不能彻底解决“计数器”存在的边界问题。

    漏桶:

    • 优点:可以很好的控制消费频率;
    • 缺点:实现稍微复杂,单位时间内,不能多消费,感觉不太灵活。

    令牌桶:

    • 优点:可以解决“漏桶”不能灵活消费的问题,又能避免过渡消费,强烈推荐;
    • 缺点:实现稍微复杂,其它缺点没有想到。

    Redis + Lua 分布式限流:

    • 优点:支持分布式限流,有效保护下游依赖的服务资源;
    • 缺点:依赖 Redis,对边界没有很好处理,导致限流不能精准控制。

    尽信书则不如无书,因个人能力有限,难免有疏漏和错误之处,如发现bug或者有更好的建议,欢迎批评指正,不吝感激。

    往期精选:

    - + diff --git a/dist/nice-article/weixin-likbj.html b/dist/nice-article/weixin-likbj.html new file mode 100644 index 00000000..37fa2e51 --- /dev/null +++ b/dist/nice-article/weixin-likbj.html @@ -0,0 +1,48 @@ + + + + + + + + 离开北京? | Java 程序员进阶之路 + + + + + + +

    离开北京?

    公子龙2022年6月9日
    • 优质文章
    大约 5 分钟

    某脉上有个字节员工发的热帖

    今天和高中同学聊了聊,当初同样的分数去了某 985,他自动化我计算机。毕业的时候我们宿舍各个大厂几十万,他们宿舍都读研留在了二线,进了国企十万出头,对我们学院羡慕不已。

    六年过去了,我们宿舍的人还都在一线租房加班,焦虑 35 危机,没有一个结婚的。他们宿舍的都已经在二线买房生娃,整天开车钓鱼遛狗,这一波我们输麻了。


    看了这段话,有些触动,想了想,本科毕业到现在,也差不多五年了,在北京这种竞争压力比较大的环境中谋生存。

    如果当时本科毕业,或者两年前研究生毕业,回到离家近的城市,估计也会如同帖子中所说的,安心上班,攒钱买房成家生子,一步步的发展精确到年龄。

    但现实是,我选择了毕业后还是留在北京,还想再拼一把。从之前到现在,留下来的原因,一直没有大的改变,主要有三个:高工资、高自由、爱情/家庭

    1

    最直接的,为了北京的高工资,心甘情愿留了下来,成为千万新时代农民工中普通的一员。

    还在读大二的时候,在食堂吃饭,听到隔座的师兄们聊拿到的 offer,其中一位说,工作定了,月薪是 9800 元,那是 2014 年,这个工资直接震撼到我了。

    那时的我对于工资没有太多概念,每个月的花费仅在六七百元左右,平时做家教一小时能够拿到五十元已经非常开心。当我听到师兄月入近万,心情还是非常激动的,因为这意味着我毕业时也能够拿到万元月薪,毕竟都是一个学校的差距应该不会太大。

    试想,那时候的年薪十来万,对于我便具有如此般的诱惑力。等到我研究生毕业时,面对互联网提供的几十万的年薪,怎么可能不动心。

    这种情况,大多只有家境富足,见过钱,也了解各类工资的性价比和长期发展的人,才能做出明智的选择,不会被眼前的利益冲昏头脑。很明显,我不属于这波人,大部分同学也不属于这波人,毕竟,有钱人的孩子是少数的。

    2

    此外,除了高工资,打心底里,还是对于等级严明的公司制度有一种排斥。虽然互联网公司也存在这种等级,但程度会缓和很多,大家一起交流的氛围自在很多。

    在传统的「企业」中,无论是事业单位,还是国企,给了员工更多的保障,也就是大家口中常说的稳定,为之的代价就是需要牺牲个人的部分自由,需要尊重各类规则。

    我的性格从小就是很活泼,想法特别多,读书的时候不安分,工作的时候也不安分。导师给我一个任务,我如果有自己的想法,总会偷偷的去尝试下,这种性格,倘若我是领导,也大概率不会喜欢,注定在等级森严的企业内是很难长期发展的,说实话,这也是目前困扰我的一个问题,慢慢的调整自己,学会改进和妥协。

    人成年之后,基本就是在挣扎和妥协中度过的,慢慢学会和自己和解。

    3

    最重要的一点,也就是和女朋友,也就是现在的妻子,从上大学开始,就一直在北京这座城市打拼,快十年的时间了,基本是完整的青春岁月,一起经历过太多太多,已经很难离开这座城市了。

    试想,有一天我们也许会离开北京,有两种情况,第一种是好的,我们有了更好的去处,去到一个更适合我们的城市,无论大小,家庭的生活质量会提高,焦虑会减少,生活起来欣欣向荣。

    第二种是坏的,就是被动离开,我们承受不了这座都市带来的压力,不再年轻了,只能拿着这些年积攒的积蓄,选择另外一个地方重新开始。

    最终,到底哪种情况会发生呢,我们不知道。但可以知道的是,现在的动作,会影响未来的走势,还是需要关注此刻的投入和付出,多学些本事,多积攒些资产,在认知上不断的提升自己,这样,当好的、坏的未来到来时,才能心平气和的坦然面对。

    你好,我是公子龙,毕业于中科院,前大型计算机竞赛冠军,现大厂工程师,拿过九家大厂的 offer 。

    北漂七年,从小白到计算机竞赛冠军,读研时通过实习和比赛收入 50 万,点击蓝字查看我的编程之路open in new window

    同时,我也是 b 站 up 主:公子龙龙龙,日常分享高质量资料,输出面试、工作经验,欢迎围观。

    + + + diff --git a/dist/nice-article/weixin-mozdsdzfjavableetcodetxxk.html b/dist/nice-article/weixin-mozdsdzfjavableetcodetxxk.html new file mode 100644 index 00000000..f90f1e1f --- /dev/null +++ b/dist/nice-article/weixin-mozdsdzfjavableetcodetxxk.html @@ -0,0 +1,48 @@ + + + + + + + + 👏下载→Java版LeetCode刷题笔记 | Java 程序员进阶之路 + + + + + + +

    👏下载→Java版LeetCode刷题笔记

    沉默王二2022年6月11日
    • 学习资源
    • PDF
    大约 4 分钟

    不经意间,在 GitHub 上发现了一个 1G 棒的 LeetCode 刷题笔记,重点来了,是纯正的 Java 版。我见过很多牛逼的刷题笔记,有 Go 版的,有 C++ 版的,唯独没有 Java 版的,所以这次,我感觉找到了宝藏!

    这次一次性把 C/C++、Java、Go 版的刷题笔记全部贡献出来,需要刷题笔记PDF文档的小伙伴可以直接长按扫码关注下方二维码,回复 「刷题笔记」 四个字自取:

    (长按扫码识别)

    其实私下里很多小伙伴问我有没有 Java 版的,一开始我觉得刷题嘛,用啥语言刷题根本不重要,重要的是解题的思路。但看到这份 Java 版的刷题笔记后,我明白了,原来使用自己熟悉的编程语言来刷题,真的会提高刷题的幸福指数~

    随便打开一道题解感受下,作者真的做到了图文并茂,不只是干巴巴的解题代码。这些手绘图让我感受到了作者的良苦用心,并且很多题都给出了多种解题思路,让我们能从不同的角度去思考,去得出最优解,而最优解,在面试的时候也是加分项。

    作者从大一就知道了 LeetCode,但刷题总是三天打鱼两天晒网,隔断时间再去看之前刷过的题总是会想不起来,于是就萌发了刷一道题总结一题的想法。另外一方面,LeetCode 上的一些题解讲解得很少,有些只是简单的丢一些代码,对菜鸟很不友好,于是作者就想借这个机会把自己的各种解题方法都梳理清楚,然后详细地总结出来,也能方便其他小伙伴更好的理解,可谓一举多得。

    作者在大一的时候就参加过 ACM 集训,但当时基础太差了,栈和队列都不清楚,所以 ACM 之路也就搁浅了。再准备刷题的时候已经是大四毕业的时候了。

    作者在刷前几道题的时候也很慢,很多都没有思路,只能靠别人的解题思路才勉强过关。尤其是第 5 题求最长回文序列,用了好多天才把所有解法都总结了出来。

    等到作者刷完 100 道题之后,发现真的是爱上了刷题。基本上后面的每道题都可以想出一种思路,甚至就是最优解,还会萌生一些别人没想到过的解法——哈哈,一种打游戏超神的感觉~

    所以呢,我劝大家,不要怕自己基础不好,不要担心自己想不到解题思路,一开始就是借钱嘛,不不不,借鉴嘛,借的多了,自然就不用还了,成自己的了。重要的是开始和坚持。

    GitHub 地址:https://github.com/wind-liang/leetcode

    除了 Java 版的,还有 Go 版的。这份笔记里面共包含作者刷LeetCode算法题后整理的数百道题,每道题均附有详细题解过程。很多人表示刷数据结构和算法题效率不高,甚是痛苦。有了这个笔记的总结,对校招和社招的算法刷题帮助之大不言而喻,果断收藏了。

    GitHub 地址:https://github.com/halfrost/LeetCode-Goopen in new window

    还有 C/C++ 版的,光看这份笔记的目录就觉得非常的震撼,相信你和我一样,都有这种强烈的感受。

    全书总共 143 页篇幅,详细讲解算法的内容有十五个章节。每个章节都是一些重要的知识点,伴有基础讲解和例题介绍,当然,也有一些推荐的练习题。

    第 7 章是讲动态规划的,这里摘取了一点内容,大家可以看到作者对于知识点的讲解是非常透彻且细致的。

    需要这三份刷题笔记PDF文档(包括 C/C++、Java、Go 版)的小伙伴可以直接长按扫码关注下方二维码,回复 「刷题笔记」 四个字自取:

    (长按扫码识别)

    没有什么使我停留——除了目的,纵然岸旁有玫瑰、有绿荫、有宁静的港湾,我是不系之舟

    + + + diff --git a/dist/nice-article/weixin-piaolwzjztqdtskwlzfpdf.html b/dist/nice-article/weixin-piaolwzjztqdtskwlzfpdf.html new file mode 100644 index 00000000..da744f3a --- /dev/null +++ b/dist/nice-article/weixin-piaolwzjztqdtskwlzfpdf.html @@ -0,0 +1,48 @@ + + + + + + + + 👏下载→给操作系统捋条线 | Java 程序员进阶之路 + + + + + + +

    👏下载→给操作系统捋条线

    沉默王二2022年6月11日
    • 学习资源
    • PDF
    大约 3 分钟

    最近认识个硬核读者,说是看了二哥的一些文章和心得后,很有收获,迫切地想要和二哥做朋友。言谈之中,能感受出来他的真诚。

    前几天,他又发私信说自己手撸了一份操作系统的学习资料,根据 MIT 6.828 教学操作系统 XV6 写出来的。

    我认真看了他这份学习资料,看完后的感受是:“只怪自己没文化,一句牛逼走天下。”

    这份资料细致到了各个部分,每个章节基本上可分为理论和代码两个部分,讲述的代码覆盖了源代码的百分之90以上。真的给操作系统捋了“一条线”出来,从硬件到软件将各个方面都给串起来了,能够让大家知道一个操作系统是如何设计的,从上电那一刻开始是如何一步步运行起来的

    讲真,这样的好东西,二哥真想偷偷地藏起来,然后悄悄的学,最后惊艳所有人😁!

    不过,大家都知道二哥是个古道热肠的人,巴不得把自己所学到的全部知识一股脑的输出给在座的各位读者朋友们。

    那还卖什么关子,直接长按扫码关注下方二维码,回复 「操作系统」 下载这份 PDF 吧:

    (长按扫码识别)

    PDF 因为要分页,加之图片大小不一,格式可能差点,所以读者还准备了一份 HTML 格式的:

    另外,xv6.zip 是有注释的版本源码,xv6从启动到运行涉及到的所有部分是讲述了的。

    XV6 这个教学系统我之前在 B 站录的一期视频里有提到过:

    这期视频的收藏比点赞多了一百多,足见里面内容是非常值得回味的。没看过的读者可以去刷一遍,应该收获会非常大:

    https://www.bilibili.com/video/BV1th411b7in/

    这期视频下面贴了非常多的硬核学习资料,再加上读者的这份《给操作系统捋条线》的 PDF,可以说是学习操作系统的最全攻略了!

    就像评论区的小伙伴说的那样:学好操作系统  就和普通增删改查的菜鸟程序员就不是一个层次了[doge]

    有一说一,读者在大学阶段就能操作系统学到这种程度,基本上可以说是非常非常非常厉害了,是最近我遇到的那种为数不多的、未来可期的大学生之一。

    来关注二哥的都是肯踏踏实实学习的小伙伴,那咱就不能掉队,对吧?必须得把操作系统给整起来了~

    好了,今天就分享到这里吧!后续如果遇到有用的工具或者资源,依然会持续分享,也欢迎大家多多安利和交流,千万不要藏着掖着哦。


    没有什么使我停留——除了目的,纵然岸旁有玫瑰、有绿荫、有宁静的港湾,我是不系之舟

    推荐阅读

    + + + diff --git a/dist/nice-article/weixin-quoppomspwml.html b/dist/nice-article/weixin-quoppomspwml.html new file mode 100644 index 00000000..418ef69e --- /dev/null +++ b/dist/nice-article/weixin-quoppomspwml.html @@ -0,0 +1,96 @@ + + + + + + + + 去 OPPO 面试, 被问麻了。。。 | Java 程序员进阶之路 + + + + + + +

    去 OPPO 面试, 被问麻了。。。

    捡田螺的小男孩2022年6月10日
    • 优质文章
    大约 27 分钟

    前言

    大家好,我是鱼皮。

    最近有粉丝私信说被oppo的后端面试问麻了,所以今天给大家推荐一篇整理了16道oppo面试真题答案的文章。希望对大家有帮助哈,一起学习,一起进步。

    1. 聊聊你印象最深刻的项目,或者做了什么优化。
    2. 你项目提到分布式锁,你们是怎么使用分布式锁的?
    3. 常见分布式事务解决方案
    4. 你们的接口幂等是如何保证的?
    5. 你们的MySQL架构是怎样的?
    6. 常见的索引结构有?哈希表结构属于哪种场景?
    7. 给你ab,ac,abc字段,你是如何加索引的?
    8. 数据库隔离级别是否了解?你们的数据库默认隔离级别是?为什么选它?
    9. RR隔离级别实现原理,它是如何解决不可重复读的?
    10. 你们项目使用了RocketMQ对吧?那你知道如何保证消息不丢失吗?
    11. 事务消息是否了解?场景题:比如下单清空购物车,你是如何设计的?
    12. 如何快速判断一个数是奇数还是偶数,除开对2取余呢。
    13. Spring声明式事务原理?哪些场景事务会失效?
    14. 你们是微服务架构嘛?如果你来设计一个类似淘宝的系统,你怎么划分微服务?
    15. 你们是怎么分库分表的?分布式ID如何生成?
    16. 所有异常的共同祖先是?运行时异常有哪几个?

    1. 聊聊你印象最深刻的项目,或者做了什么优化。

    大家平时做的项目,如果很多知识点跟面试八股文相关的话,就可以相对条理清晰地写到简历去。

    • 比如缓存数据库相关的,查询为空,你设置了一个-1到缓存,代表数据库没记录。下次判断-1,就不查库了,以解决缓存穿透问题。
    • 又比如你设置缓存过期时间比较分散,解决缓存击穿问题,都可以条理清晰写到简历去,这样面试官很可能会问你相关的问题,这时候就对答如流啦。

    还有平时你做的项目,有一些比较好的设计,都可以说一下哈,比如你是如何保证数据一致性的,怎么优化接口性能的。

    • 如果是讲优化接口这一块的话,其实就是缓存、分批、并发调用、异步等那几个关键知识点。
    • 如果是代码优化细节,你可以挑个简单的来讲,比如复杂的if逻辑条件,可以调整顺序,让程序更高效,这样会让面试官眼前一亮哦。

    2. 你项目提到分布式锁,你们是怎么使用分布式锁的?

    一般你讲述你做的项目时,面试官会根据你项目涉及的一些面试点,然后抽他感兴趣的一两个来问。所以大家对哪些知识点熟悉,讲述项目时,就说你用该知识点,解决了什么问题。

    3. 常见分布式事务解决方案

    分布式事务:就是指事务的参与者、支持事务的服务器、资源服务器以及事务管理器分别位于不同的分布式系统的不同节点之上。简单来说,分布式事务指的就是分布式系统中的事务,它的存在就是为了保证不同数据库节点的数据一致性。

    聊到分布式事务,大家记得这两个理论哈:CAP理论 和 BASE 理论

    分布式事务的几种解决方案:

    • 2PC(二阶段提交)方案、3PC
    • TCC(Try、Confirm、Cancel)
    • 本地消息表
    • 最大努力通知
    • seata

    2PC(二阶段提交)方案

    2PC,即两阶段提交,它将分布式事务的提交拆分为2个阶段:prepare和commit/rollback,即准备阶段和提交执行阶段。在prepare准备阶段需要等待所有参与子事务的反馈,因此可能造成数据库资源锁定时间过长,不适合并发高以及子事务生命周长较长的业务场景。并且协调者宕机的话,所有的参与者都收不到提交或回滚指令。

    3PC

    两阶段提交分别是:CanCommit,PreCommit 和 doCommit,这里不再详述。3PC 利用超时机制解决了 2PC 的同步阻塞问题,避免资源被永久锁定,进一步加强了整个事务过程的可靠性。但是 3PC 同样无法应对类似的宕机问题,只不过出现多数据源中数据不一致问题的概率更小。

    TCC

    TCC 采用了补偿机制,其核心思想是:针对每个操作,都要注册一个与其对应的确认和补偿(撤销)操作。它分为三个阶段:Try-Confirm-Cancel

    • try阶段:尝试去执行,完成所有业务的一致性检查,预留必须的业务资源。
    • Confirm阶段:该阶段对业务进行确认提交,不做任何检查,因为try阶段已经检查过了,默认Confirm阶段是不会出错的。
    • Cancel 阶段:若业务执行失败,则进入该阶段,它会释放try阶段占用的所有业务资源,并回滚Confirm阶段执行的所有操作。

    TCC方案让应用可以自定义数据库操作的粒度,降低了锁冲突,可以提升性能。但是应用侵入性强,try、confirm、cancel三个阶段都需要业务逻辑实现。

    本地消息表

    ebay最初提出本地消息表这个方案,来解决分布式事务问题。业界目前使用这种方案是比较多的,它的核心思想就是将分布式事务拆分成本地事务进行处理。可以看一下基本的实现流程图:

    最大努力通知

    最大努力通知方案的目标,就是发起通知方通过一定的机制,最大努力将业务处理结果通知到接收方。

    seata

    Saga 模式是 Seata 提供的长事务解决方案。核心思想是将长事务拆分为多个本地短事务,由Saga事务协调器协调,如果正常结束那就正常完成,如果某个步骤失败,则根据相反顺序一次调用补偿操作。

    Saga的并发度高,但是一致性弱,对于转账,可能发生用户已扣款,最后转账又失败的情况。

    4. 你们的接口幂等是如何保证的?

    如果你调用下游接口超时了,是不是考虑重试?如果重试,下游接口就需要支持幂等啦。

    实现幂等一般有这8种方案:

    • select+insert+主键/唯一索引冲突
    • 直接insert + 主键/唯一索引冲突
    • 状态机幂等
    • 抽取防重表
    • token令牌
    • 悲观锁(如select for update,很少用)
    • 乐观锁
    • 分布式锁

    大家平时是用哪个方案解决幂等的,最后结合工作实际讲讲哈。

    5. 你们的mySQL架构是怎样的?

    大家可以结合自己公司的MySQL架构聊聊。

    数据的库高可用方案

    • 双机主备
    • 一主一从
    • 一主多从
    • MariaDB同步多主机
    • 数据库中间件

    5.1 双机主备

    • 优点:一个机器故障了可以自动切换,操作比较简单。
    • 缺点:只有一个库在工作,读写压力大,未能实现读写分离,并发也有一定限制

    5.2 一主一从

    • 优点:从库支持读,分担了主库的压力,提升了并发度。一个机器故障了可以自动切换,操作比较简单。
    • 缺点:一台从库,并发支持还是不够,并且一共两台机器,还是存在同时故障的机率,不够高可用。

    5.3 一主多从

    • 优点:多个从库支持读,分担了主库的压力,明显提升了读的并发度。
    • 缺点:只有一台主机写,因此写的并发度不高

    5.4 MariaDB同步多主机集群

    • 有代理层实现负载均衡,多个数据库可以同时进行读写操作;各个数据库之间可以通过Galera Replication方法进行数据同步,每个库理论上数据是完全一致的。
    • 优点:读写的并发度都明显提升,可以任意节点读写,可以自动剔除故障节点,具有较高的可靠性。
    • 缺点:数据量不支持特别大。要避免大事务卡死,如果集群节点一个变慢,其他节点也会跟着变慢。

    5.5 数据库中间件

    • mycat分片存储,每个分片配置一主多从的集群。
    • 优点:解决高并发高数据量的高可用方案
    • 缺点:维护成本比较大。

    6. 常见的索引结构有?哈希表结构属于哪种场景?

    哈希表、有序数组和搜索树。

    • 哈希表这种结构适用于只有等值查询的场景
    • 有序数组适合范围查询,用二分法快速得到,时间复杂度为 O(log(N))。查询还好,如果是插入,就得挪动后面所有的记录,成本太高。因此它一般只适用静态存储引擎,比如保存2018年某个城市的所有人口信息。
    • B+树适合范围查询,我们一般建的索引结构都是B+树。

    7.给你ab,ac,abc字段,你是如何加索引的?

    这主要考察联合索引的最左前缀原则知识点。

    • 这个最左前缀可以是联合索引的最左N个字段。比如组合索引(a,b,c)可以相当于建了(a),(a,b),(a,b,c)三个索引,大大提高了索引复用能力。
    • 最左前缀也可以是字符串索引的最左M个字符。

    因此给你ab,ac,abc字段,你可以直接加abc联合索引和ac联合索引即可。

    8. 数据库隔离级别是否了解?你们的数据库默认隔离级别是?为什么选它?

    四大数据库隔离级别,分别是读未提交,读已提交,可重复读,串行化(Serializable)

    • 读未提交:事务即使未提交,却可以被别的事务读取到的,这级别的事务隔离有脏读、重复读、幻读的问题。
    • 读已提交:当前事务只能读取到其他事务提交的数据,这种事务的隔离级别解决了脏读问题,但还是会存在不可重复读、幻读问题;
    • 可重复读:限制了读取数据的时候,不可以进行修改,所以解决了不可重复读的问题,但是读取范围数据的时候,是可以插入数据,所以还会存在幻读问题。
    • 串行化:事务最高的隔离级别,在该级别下,所有事务都是进行串行化顺序执行的。可以避免脏读、不可重复读与幻读所有并发问题。但是这种事务隔离级别下,事务执行很耗性能。

    MySQL选择Repeatable Read(可重复读)作为默认隔离级别,我们的数据库隔离级别选的是读已提交

    8.1 为什么MySQL的默认隔离离别是RR?

    binlog的格式也有三种:statement,row,mixed。设置为statement格式,binlog记录的是SQL的原文。又因为MySQL在主从复制的过程是通过binlog进行数据同步,如果设置为读已提交(RC)隔离级别,当出现事务乱序的时候,就会导致备库在 SQL 回放之后,结果和主库内容不一致。

    比如一个表t,表中有两条记录:

      
    +
    +CREATE TABLE t (    
    +
    +     a int(11) DEFAULT NULL,    
    +
    +     b int(11) DEFAULT NULL,    
    +
    +     PRIMARY KEY a (a),  
    +
    +     KEY b(b)  
    +
    +   ) ENGINE=InnoDB DEFAULT CHARSET=latin1;    
    +
    +   insert into t1 values(10,666),(20,233);   
    +
    +

    两个事务并发写操作,如下:

    读已提交(RC)隔离级别下,两个事务执行完后,数据库的两条记录就变成了(30,666)、(20,666)。这两个事务执行完后,binlog也就有两条记录,因为事务binlog用的是statement格式,事务2先提交,因此update t set b=666 where b=233优先记录,而update t set a=30 where b=666记录在后面。

    bin log同步到从库后,执行update t set b=666 where b=233update t set a=30 where b=666记录,数据库的记录就变成(30,666)、(30,666),这时候主从数据不一致啦。

    因此MySQL的默认隔离离别选择了RR而不是RCRR隔离级别下,更新数据的时候不仅对更新的行加行级锁,还会加间隙锁(gap lock)。事务2要执行时,因为事务1增加了间隙锁,就会导致事务2执行被卡住,只有等事务1提交或者回滚后才能继续执行。

    并且,MySQL还禁止在使用statement格式的binlog的情况下,使用READ COMMITTED作为事务隔离级别。

    我们的数据库隔离级别最后选的是读已提交(RC)。

    那为什么MySQL官方默认隔离级别是RR,而有些大厂选择了RC作为默认的隔离级别呢?

    • 提升并发

    RC 在加锁的过程中,不需要添加Gap LockNext-Key Lock 的,只对要修改的记录添加行级锁就行了。因此RC的支持的并发度比RR高得多,

    • 减少死锁

    正是因为RR隔离级别增加了Gap LockNext-Key Lock 锁,因此它相对于RC,更容易产生死锁。

    9. RR隔离级别实现原理,它是如何解决不可重复读的?

    9.1 什么是不可重复读

    先回忆下什么是不可重复读。假设现在有两个事务A和B:

    • 事务A先查询Jay的余额,查到结果是100
    • 这时候事务B 对Jay的账户余额进行扣减,扣去10后,提交事务
    • 事务A再去查询Jay的账户余额发现变成了90

    事务A被事务B干扰到了!在事务A范围内,两个相同的查询,读取同一条记录,却返回了不同的数据,这就是不可重复读

    9.2 undo log版本链 + Read View可见性规则

    RR隔离级别实现原理,就是MVCC多版本并发控制,而MVCC是是通过Read View+ Undo Log实现的,Undo Log 保存了历史快照,Read View可见性规则帮助判断当前版本的数据是否可见。

    Undo Log版本链长这样:

    Read view 的几个重要属性

    • m_ids:当前系统中那些活跃(未提交)的读写事务ID, 它数据结构为一个List。
    • min_limit_id:表示在生成Read View时,当前系统中活跃的读写事务中最小的事务id,即m_ids中的最小值。
    • max_limit_id:表示生成Read View时,系统中应该分配给下一个事务的id值。
    • creator_trx_id: 创建当前Read View的事务ID

    Read view 可见性规则如下:

    1. 如果数据事务IDtrx_id < min_limit_id,表明生成该版本的事务在生成Read View前,已经提交(因为事务ID是递增的),所以该版本可以被当前事务访问。
    2. 如果trx_id>= max_limit_id,表明生成该版本的事务在生成Read View后才生成,所以该版本不可以被当前事务访问。
    3. 如果min_limit_id =<trx_id< max_limit_id,需要分3种情况讨论
    • 3.1 如果m_ids包含trx_id,则代表Read View生成时刻,这个事务还未提交,但是如果数据的trx_id等于creator_trx_id的话,表明数据是自己生成的,因此是可见的。
    • 3.2 如果m_ids包含trx_id,并且trx_id不等于creator_trx_id,则Read View生成时,事务未提交,并且不是自己生产的,所以当前事务也是看不见的;
    • 3.3 如果m_ids不包含trx_id,则说明你这个事务在Read View生成之前就已经提交了,修改的结果,当前事务是能看见的。

    9.3 RR 如何解决不可重复读

    查询一条记录,基于MVCC,是怎样的流程

    1. 获取事务自己的版本号,即事务ID
    2. 获取Read View
    3. 查询得到的数据,然后Read View中的事务版本号进行比较。
    4. 如果不符合Read View的可见性规则, 即就需要Undo log中历史快照;
    5. 最后返回符合规则的数据

    假设存在事务A和B,SQL执行流程如下

    在可重复读(RR)隔离级别下,一个事务里只会获取一次Read View,都是副本共用的,从而保证每次查询的数据都是一样的。

    假设当前有一张core_user表,插入一条初始化数据,如下:

    基于MVCC,我们来看看执行流程

    1. A开启事务,首先得到一个事务ID为100
    2. B开启事务,得到事务ID为101
    3. 事务A生成一个Read View,read view对应的值如下
    变量
    m_ids100,101
    max_limit_id102
    min_limit_id100
    creator_trx_id100

    然后回到版本链:开始从版本链中挑选可见的记录:

    由图可以看出,最新版本的列name的内容是孙权,该版本的trx_id值为100。开始执行read view可见性规则校验:

    min_limit_id(100)=<trx_id(100)<102;  
    +
    +creator_trx_id = trx_id =100;  
    +
    +

    由此可得,trx_id=100的这个记录,当前事务是可见的。所以查到是name为孙权的记录。

    1. 事务B进行修改操作,把名字改为曹操。把原数据拷贝到undo log,然后对数据进行修改,标记事务ID和上一个数据版本在undo log的地址。

    1. 事务B提交事务
    2. 事务A再次执行查询操作,因为是RR(可重复读)隔离级别,因此会复用老的Read View副本,Read View对应的值如下
    变量
    m_ids100,101
    max_limit_id102
    min_limit_id100
    creator_trx_id100

    然后再次回到版本链:从版本链中挑选可见的记录:

    从图可得,最新版本的列name的内容是曹操,该版本的trx_id值为101。开始执行read view可见性规则校验:

    min_limit_id(100)=<trx_id(101)<max_limit_id(102);  
    +
    +因为m_ids{100,101}包含trx_id(101),  
    +
    +并且creator_trx_id (100) 不等于trx_id(101)  
    +
    +

    所以,trx_id=101这个记录,对于当前事务是不可见的。这时候呢,版本链roll_pointer跳到下一个版本,trx_id=100这个记录,再次校验是否可见:

    min_limit_id(100)=<trx_id(100)< max_limit_id(102);  
    +
    +因为m_ids{100,101}包含trx_id(100),  
    +
    +并且creator_trx_id (100) 等于trx_id(100)  
    +
    +

    所以,trx_id=100这个记录,对于当前事务是可见的,所以两次查询结果,都是name=孙权的那个记录。即在可重复读(RR)隔离级别下,复用老的Read View副本,解决了不可重复读的问题。

    10. 你们项目使用了RocketMQ对吧?那你知道如何保证消息不丢失吗?

    一个消息从生产者产生,到被消费者消费,主要经过这3个过程:

    1. 生产者产生消息
    2. 消息发送到存储端,保存下来
    3. 消息推送到消费者,消费者消费完,ack应答。

    因此如何保证MQ不丢失消息,可以从这三个阶段阐述:

    • 生产者保证不丢消息
    • 存储端不丢消息
    • 消费者不丢消息

    10.1 生产者保证不丢消息

    生产端如何保证不丢消息呢?确保生产的消息能顺利到达存储端。

    如果是RocketMQ消息中间件的话,Producer生产者提供了三种发送消息的方式,分别是:

    • 同步发送
    • 异步发送
    • 单向发送

    生产者要想发消息时保证消息不丢失,可以:

    • 采用同步方式发送,send消息方法返回成功状态,即消息正常到达了存储端Broker
    • 如果send消息异常或者返回非成功状态,可以发起重试。
    • 可以使用事务消息,RocketMQ的事务消息机制就是为了保证零丢失来设计的

    10.2 存储端不丢消息

    如何保证存储端的消息不丢失呢?确保消息持久化到磁盘,那就是刷盘机制嘛。

    刷盘机制分同步刷盘和异步刷盘

    • 同步刷盘:生产者消息发过来时,只有持久化到磁盘,RocketMQ的存储端Broker才返回一个成功的ACK响应。它保证消息不丢失,但是影响了性能。
    • 异步刷盘:只要消息写入PageCache缓存,就返回一个成功的ACK响应。这样提高了MQ的性能,但是如果这时候机器断电了,就会丢失消息。

    除了同步刷盘机制,还有一个维度需要考虑。Broker一般是集群部署的,有主节点和从节点。消息到Broker存储端,只有主节点和从节点都写入成功,才反馈成功的ack给生产者。这就是同步复制,它保证了消息不丢失,但是降低了系统的吞吐量。与之对应即是异步复制,只要消息写入主节点成功,就返回成功的ack,它速度快,但是会有性能问题。

    10.3 消费阶段不丢消息

    消费者执行完业务逻辑,再反馈会Broker说消费成功,这样才可以保证消费阶段不丢消息。

    11. 事务消息是否了解?场景题:比如下单清空购物车,你是如何设计的?

    事务消息主要用来解决消息生产者和消息消费者的数据一致性问题。我们先来回忆一下:一条普通的消息队列消息,从产生到被消费,经历的流程:

    1. 生产者产生消息,发送到MQ服务器
    2. MQ收到消息后,将消息持久化到存储系统。
    3. MQ服务器返回ACk到生产者。
    4. MQ服务器把消息push给消费者
    5. 消费者消费完消息,响应ACK
    6. MQ服务器收到ACK,认为消息消费成功,即在存储中删除消息。

    消息队列的事务消息流程是怎样的呢?

    1. 生产者产生消息,发送一条半事务消息到MQ服务器
    2. MQ收到消息后,将消息持久化到存储系统,这条消息的状态是待发送状态。
    3. MQ服务器返回ACK确认到生产者,此时MQ不会触发消息推送事件
    4. 生产者执行本地事务
    5. 如果本地事务执行成功,即commit执行结果到MQ服务器;如果执行失败,发送rollback。
    6. 如果是正常的commit,MQ服务器更新消息状态为可发送;如果是rollback,即删除消息。
    7. 如果消息状态更新为可发送,则MQ服务器会push消息给消费者。消费者消费完就回ACK。
    8. 如果MQ服务器长时间没有收到生产者的commit或者rollback,它会反查生产者,然后根据查询到的结果执行最终状态。

    我们举个下订单清空购物车的例子吧。订单系统创建完订单后,然后发消息给下游系统购物车系统,清空购物车。

    1. 生产者(订单系统)产生消息,发送一条半事务消息到MQ服务器
    2. MQ收到消息后,将消息持久化到存储系统,这条消息的状态是待发送状态。
    3. MQ服务器返回ACK确认到生产者,此时MQ不会触发消息推送事件
    4. 生产者执行本地事务(订单创建成功,提交事务消息)
    5. 如果本地事务执行成功,即commit执行结果到MQ服务器;如果执行失败,发送rollback。
    6. 如果是commit正常提交,MQ服务器更新消息状态为可发送;如果是rollback,即删除消息
    7. 如果消息状态更新为可发送,则MQ服务器会push消息给消费者(购物车系统)。消费者消费完(即拿到订单消息,清空购物车成功)就应答ACK。
    8. 如果MQ服务器长时间没有收到生产者的commit或者rollback,它会反查生产者,然后根据查询到的结果(回滚操作或者重新发送消息)执行最终状态。

    有些伙伴可能有疑惑,如果消费者消费失败怎么办呢?那数据是不是不一致啦?所以就需要消费者消费成功,执行业务逻辑成功,再反馈ack嘛。如果消费者消费失败,那就自动重试嘛,接口支持幂等即可。

    12. 如何快速判断一个数是奇数还是偶数,除开对2取余呢。

    判断一个数是奇数还是偶数,我们最容易想到的就是对2取余。

    if( x % 2 )  
    +
    +// 奇数  
    +
    +else  
    +
    +// 偶数  
    +
    +

    还有一种方法,就是与1相与( &1),具体实现如下:

    if( x & 1 )  
    +
    +// 奇数  
    +
    +else  
    +
    +// 偶数  
    +
    +

    13. Spring声明式事务原理?哪些场景事务会失效?

    13.1 声明式事务原理

    spring声明式事务,即@Transactional,它可以帮助我们把事务开启、提交或者回滚的操作,通过Aop的方式进行管理。

    在spring的bean的初始化过程中,就需要对实例化的bean进行代理,并且生成代理对象。生成代理对象的代理逻辑中,进行方法调用时,需要先获取切面逻辑,@Transactional注解的切面逻辑类似于@Around,在spring中是实现一种类似代理逻辑。

    13.2 spring声明式事务哪些场景会失效

    • 方法的访问权限必须是public,其他private等权限,事务失效
    • 方法被定义成了final的,这样会导致事务失效。
    • 在同一个类中的方法直接内部调用,会导致事务失效。
    • 一个方法如果没交给spring管理,就不会生成spring事务。
    • 多线程调用,两个方法不在同一个线程中,获取到的数据库连接不一样的。
    • 表的存储引擎不支持事务
    • 如果自己try...catch误吞了异常,事务失效。
    • 错误的传播

    14. 你们是微服务架构嘛?如果你来设计一个类似淘宝的系统,你怎么划分微服务?

    可以按业务领域、功能、重要程度进行划分。

    • 可以按业务领域,把用户、社区、商品信息、消息等模块等划分。
    • 单一功能职责,按功能拆分,比如订单、支付、物流、权限。
    • 按重要程度划分,区分核心和非核心功能,比如支付、订单就是核心功能。

    15. 你们是怎么分库分表的?分布式ID如何生成?

    如果是我们公司的话,使用了水平分库的方式,就是一个用户注册时,就划分了属于哪个数据库,然后具体的表结构是一样的。

    业界还有垂直分库,就是按照不同的系统中的不同业务进行拆分,比如拆分成用户库、订单库、积分库、商品库,把它们部署在不同的数据库服务器。

    分表的话也有水平分表和垂直分表,垂直分表就是将一些不常用的、数据较大或者长度较长的列拆分到另外一张表,水平分表就是可以按照某种规则(如hash取模、range),把数据切分到多张表去。一张订单表,按时间range拆分如下:

    range划分利于数据迁移,但是存在数据热点问题。hash取模划分,不会存在明显的热点问题,但是不利于扩容。可以range+hash取模结合使用。

    分布式ID可以使用雪花算法生成

    雪花算法是一种生成分布式全局唯一ID的算法,生成的ID称为Snowflake IDs。这种算法由Twitter创建,并用于推文的ID。

    一个Snowflake ID有64位。

    • 第1位:Java中long的最高位是符号位代表正负,正数是0,负数是1,一般生成ID都为正数,所以默认为0。
    • 接下来前41位是时间戳,表示了自选定的时期以来的毫秒数。
    • 接下来的10位代表计算机ID,防止冲突。
    • 其余12位代表每台机器上生成ID的序列号,这允许在同一毫秒内创建多个Snowflake ID。

    16. 所有异常的共同的祖先是?运行时异常有哪几个?

    Java 异常的顶层父类是Throwable,它生了两个儿子,大儿子叫Error,二儿子叫Exception

    • Error:是程序⽆法处理的错误,一般表示系统错误,例如虚拟机相关的错误OutOfMemoryError
    • Exception:程序本身可以处理的异常。它可以分为RuntimeException(运行时异常)和CheckedException(可检查的异常)。

    什么是RuntimeException(运行时异常)

    运行时异常是不检查异常,程序中可以选择捕获处理,也可以不处理。这些异常一般是由程序逻辑错误引起的,程序应该从逻辑角度尽可能避免这类异常的发生。

    常见的RuntimeException异常

    • NullPointerException:空指针异常
    • ArithmeticException:出现异常的运算条件时,抛出此异常
    • IndexOutOfBoundsException:数组索引越界异常
    • ClassNotFoundException:找不到类异常
    • IllegalArgumentException(非法参数异常)

    什么是CheckedException(可检查的异常)

    从程序语法角度讲是必须进行处理的异常,如果不处理,程序就不能编译通过。如IOException、SQLException等。

    常见的 Checked Exception 异常:

    • IOException:(操作输入流和输出流时可能出现的异常)
    • SQLException

    以上就是本期分享了。

    最后,欢迎加入 鱼皮的编程知识星球open in new window(点击了解详情),和 8200 多名小伙伴们一起交流学习,向鱼皮和大厂同学 1 对 1 提问、帮你制定学习计划不迷茫、跟着鱼皮直播做项目(往期项目可无限回看)、领取鱼皮原创编程学习/求职资料等。

    往期推荐

    [

    几个对程序员的误解,害人不浅!

    ](https://mp.weixin.qq.com/s?__biz=MzI1NDczNTAwMA==&mid=2247509151&idx=1&sn=113246153900f18be1134697457f909c&chksm=e9c24368deb5ca7e662c1bd7d2acf52df662c284ace43f2bc3bbb4a378da0340113d428fe6f4&scene=21#wechat_redirect)

    [

    编程导航,火了!

    ](https://mp.weixin.qq.com/s?__biz=MzI1NDczNTAwMA==&mid=2247508640&idx=1&sn=b02fff3533f18b5d0bfbf714b127c140&chksm=e9c24557deb5cc41b1f2ecefdd23eb1370e261a47c23ad89b1d1428537fd1e8fe39762e707e1&scene=21#wechat_redirect)

    [

    Gitee 很无奈!

    ](https://mp.weixin.qq.com/s?__biz=MzI1NDczNTAwMA==&mid=2247508861&idx=1&sn=4716ac7fd1199541e15c080f38657dad&chksm=e9c2448adeb5cd9cd4b5f617c413024173ce47f29c0d4b14a092798a53d6be8d58d96883a7a3&scene=21#wechat_redirect)

    [

    我的 IP 归属地,是咋被挖出来的?

    ](https://mp.weixin.qq.com/s?__biz=MzI1NDczNTAwMA==&mid=2247508780&idx=1&sn=6481896d7d4310e1bae435ddb3ee72cc&chksm=e9c244dbdeb5cdcd509a68a18eca5e822ca21789b0ccafd26f9f7939a04e5f91648165e19322&scene=21#wechat_redirect)

    我造了个轮子,完整开源!open in new window

    + + + diff --git a/dist/nice-article/weixin-shejmsnb.html b/dist/nice-article/weixin-shejmsnb.html new file mode 100644 index 00000000..fb40607b --- /dev/null +++ b/dist/nice-article/weixin-shejmsnb.html @@ -0,0 +1,114 @@ + + + + + + + + 👏下载→重学Java设计模式 | Java 程序员进阶之路 + + + + + + +

    👏下载→重学Java设计模式

    沉默王二2022年6月11日
    • 学习资源
    • PDF
    大约 4 分钟

    时不时就有读者私信我,“二哥,我的代码写得很烂,该怎么办呀?”

    写代码确实是门手艺活,这是我们程序员不得不承认的一个事实,毕竟要用手指头来敲啊!不是手艺活是啥(笑)

    简单来分析一下代码写得烂的原因哈。其一,可能是刚入门,代码写得少,如果我们满打满算只写过一两千行代码,是不可能写出多优雅的代码的。其二,可能我们不懂设计模式,设计模式是软件设计中常见问题的典型解决方案,它们就像能根据需求进行调整的预制蓝图, 可用于解决代码中反复出现的设计问题,如果不懂设计模式的话,遇到这些问题就只能抓瞎了。

    这么说吧,设计模式玩得炉火纯青,写出的代码就更优雅,阅读起来也会更加舒服,可维护性、可扩展性就更强

    说到这,我确信大家已经了解设计模式的重要性了!这里给大家推荐一份全网阅读超过 500 万次的设计模式 PDF,持续霸榜 GitHub Trending。

    微信搜索「沉默王二」发送「10」关键字领取即可领取,也可以扫描下面的二维码关注后发送10」关键字**。**

    再来推荐一个网站:Refactoring Guru。

    网址如下所示:

    https://refactoring.guru

    这虽然是一个国外的网站,却神奇的实现了中文化国际化,爱了爱了,无情地爱了。据作者说,他建站的初衷就是为了帮助我们程序员,快速地掌握设计模式,但把网站做到这种用心的程度,我只能情不自禁地点赞了!

    来看一下设计模式的目录吧(下图中只展现了创建型模式和结构型模式中的一部分,还有行为模式):

    每个模式都会对应一篇图文并茂的文章,阅读起来就好像在读绘本一样,生动有趣,令人印象深刻,学起来就没有半点枯燥的感觉。来看一下工厂方法模式的一部分内容截图,这图片的质量,确实高啊,不服不行!

    配套的代码示例也非常完整,来看一下 Java 版的:

    public class WindowsButton implements Button {  
    +
    +    JPanel panel = new JPanel();  
    +
    +    JFrame frame = new JFrame();  
    +
    +    JButton button;  
    +
    +  
    +
    +    public void render() {  
    +
    +        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);  
    +
    +        JLabel label = new JLabel("Hello World!");  
    +
    +        label.setOpaque(true);  
    +
    +        label.setBackground(new Color(235, 233, 126));  
    +
    +        label.setFont(new Font("Dialog", Font.BOLD, 44));  
    +
    +        label.setHorizontalAlignment(SwingConstants.CENTER);  
    +
    +        panel.setLayout(new FlowLayout(FlowLayout.CENTER));  
    +
    +        frame.getContentPane().add(panel);  
    +
    +        panel.add(label);  
    +
    +        onClick();  
    +
    +        panel.add(button);  
    +
    +  
    +
    +        frame.setSize(320, 200);  
    +
    +        frame.setVisible(true);  
    +
    +        onClick();  
    +
    +    }  
    +
    +  
    +
    +    public void onClick() {  
    +
    +        button = new JButton("Exit");  
    +
    +        button.addActionListener(new ActionListener() {  
    +
    +            public void actionPerformed(ActionEvent e) {  
    +
    +                frame.setVisible(false);  
    +
    +                System.exit(0);  
    +
    +            }  
    +
    +        });  
    +
    +    }  
    +
    +}  
    +
    +

    当然了,代码示例不只有 Java 版的,还有 C#、C++、Python、Go 等 8 种常见的编程语言。

    这种图文并茂 + 代码示例的学习方式,极大地加深了我们程序员对知识的吸收。还有什么赞美的词语?学富五车的我竟然有点词穷了。总之,如果大家也想学好设计模式,赶快点吧!

    离线版的 PDF 我也贡献出来了,截取一部分内容供大家预览下。

    里面有不少图文参照了 Refactoring Guru 这个网站,但也加入了作者自己的思考和理解,读起来也更接地气一点。按照作者说的:

    很高兴你能拿到这本书,如果你能坚持看完并按照书中的例⼦进行实践,那么在编程开发的世界里,就⼜多了了⼀个可以写出良好代码的⼈,同时也为架构师培养储备了了⼀个⼈才。

    如果大家对这份 PDF 感兴趣的话,可以微信搜索「沉默王二」发送关键字「设计模式」获取下载链接:

    也可以扫描上面的二维码关注后发送 「10 」获取下载链接

    一起成为牛逼的程序员!

    + + + diff --git a/dist/nice-article/weixin-shenrjcjavabfbchwjdhl.html b/dist/nice-article/weixin-shenrjcjavabfbchwjdhl.html new file mode 100644 index 00000000..a3e3673c --- /dev/null +++ b/dist/nice-article/weixin-shenrjcjavabfbchwjdhl.html @@ -0,0 +1,48 @@ + + + + + + + + 👏下载→深入浅出Java多线程 | Java 程序员进阶之路 + + + + + + +

    👏下载→深入浅出Java多线程

    沉默王二2022年6月11日
    • 学习资源
    • PDF
    大约 4 分钟

    你好,我是二哥。对于一个 Java 程序员而言,能否熟练掌握并发编程是判断他优秀与否的重要标准之一。因为并发编程是 Java 语言中最为晦涩的知识点,它涉及操作系统、内存、CPU、编程语言等多方面的基础能力,更能考验一个程序员的内功。

    尤其是大数据时代的来临,高并发更成为了家常便饭,工作中,你总是绕不开并发编程的任务,比如说,你想写个程序,一边从文件中读取数据,一边还要做实时计算…所以,想成为一名资深的 Java 后端工程师,想进大厂,并发编程必须要牢牢把握

    微信搜索「沉默王二」关注后,在后台回复「并发」即可获取《深入浅出 Java 多线程》小册一本,文末有详细介绍。

    也可以截图后,微信扫码关注后回复「006

    一、掌握基础概念

    学习 Java 并发编程,第一步就是要打下坚实的基础,把涉及的相关基础概念都搞清楚。比如,深度认识 Java 内存模型、死锁产生的原因和解决方案、线程间的协作机制,等等。

    二、拿下常见的并发工具类

    把并发编程核心的问题搞清楚,回过头来看 Java SDK 并发包,你才会有种豁然开朗的感觉:它不过是针对并发问题开发出来的工具而已。而此时的 SDK 并发包就可以任你“盘”了。

    三、并发编程全景图

    学习最忌讳的就是“盲人摸象”,只看到局部,而没有看到全局。所以,你需要从一个个单一的知识和技术中“跳出来”,高屋建瓴地看并发编程。当然,这首要之事就是你建立起一张全景图。

    结合我多年的工作经验来看,并发编程领域可以抽象成三个核心问题:分工、同步和互斥。以下是我根据这三个核心问题制作的「并发编程全景图」,可以让你的知识成体系,所学知识也融汇贯通起来,由点成线,由线及面。

    但是光跳出来还不够,还需要下一步,就是在某个问题上钻进去,深入理解,找到本质。比如,当看到 Java SDK 里面的条件变量 Condition 的时候,我会下意识地问,“它是从哪儿来的?是 Java 的特有概念,还是一个通用的编程概念?”当我知道他来自管程的时候,我又会问,“管程被提出的背景和解决的问题是什么?”这样一路探索下来,我发现 Java 语言里的并发技术基本都是有理论基础的,并且这些理论在其他编程语言里也有类似的实现。

    四、深入浅出 Java 多线程

    学习 Java 并发编程,有一本书是跳不过去的,那就是《Java 并发编程实战》,但这本书往往读起来会感觉比较深奥,怎么办呢?

    几位阿里的大佬偷偷写了一本《深入浅出 Java 多线程》,并且在 GitHub 上开源了。

    先说说这几名作者哈。

    给力吧,都是大佬,所以他们的作品也非常值得信赖。再给你看一下大致的内容,就 Java 内存模型这块的知识点,就讲的非常透彻。

    除了这本,我这还屯了不少 Java 并发编程方面的电子书。

    微信搜索「沉默王二」关注后,在后台回复「书单」即可获取本文书单链接。

    回复「pdf」即可获取本文提到的书籍电子版pdf

    也可以截图后,微信扫码关注

    + + + diff --git a/dist/nice-article/weixin-xinllgjszjszzpojozsyjbsjlxyhjfyll.html b/dist/nice-article/weixin-xinllgjszjszzpojozsyjbsjlxyhjfyll.html index d3a060f2..74ef5ad8 100644 --- a/dist/nice-article/weixin-xinllgjszjszzpojozsyjbsjlxyhjfyll.html +++ b/dist/nice-article/weixin-xinllgjszjszzpojozsyjbsjlxyhjfyll.html @@ -39,10 +39,10 @@ } - + -

    新来了个技术总监:谁再在 POJO 中使用基本数据类型,以后就不用来了!

    Hollis2022年6月6日
    • 优质文章
    大约 4 分钟

    大家好,我是程序汪

    程序员编码时一些不经意的细节可能导致一些很难察觉的BUG,上生产运行一段时间后才发现,真的很头疼。

    在《阿里巴巴Java开发手册》中,对于POJO中如何选择变量的类型以及 RPC 接口中的返回值类型也有着一些规定:

    这里强制要求使用包装类型,原因是什么呢?

    我们来看一段简单的代码

    /**  
    +    

    新来了个技术总监:谁再在 POJO 中使用基本数据类型,以后就不用来了!

    Hollis2022年6月6日
    • 优质文章
    大约 4 分钟

    大家好,我是程序汪

    程序员编码时一些不经意的细节可能导致一些很难察觉的BUG,上生产运行一段时间后才发现,真的很头疼。

    在《阿里巴巴Java开发手册》中,对于POJO中如何选择变量的类型以及 RPC 接口中的返回值类型也有着一些规定:

    这里强制要求使用包装类型,原因是什么呢?

    我们来看一段简单的代码

    /**  
     
      * @author Hollis  
     
    @@ -109,6 +109,6 @@ class Model {
     

    以上代码输出结果为:

    default model : Model[success=null, failure=false]  
     
     

    可以看到,当我们没有设置Model对象的字段的值的时候,Boolean类型的变量会设置默认值为null,而boolean类型的变量会设置默认值为false。

    即Boolean对象的默认值是nullboolean基本数据类型的默认值是false

    也就是说,包装类型的默认值都是null,而基本数据类型的默认值是一个固定值,如boolean是false,byte、short、int、long是0,float是0.0f等;

    我们再举一个扣费的例子,我们做一个扣费系统,扣费时需要从外部的定价系统中通过 RPC 请求读取一个费率的值,我们预期该接口的返回值中会包含一个浮点型的费率字段。当我们取到这个值得时候就使用公式:金额*费率=费用 进行计算,计算结果进行划扣。

    如果由于计费系统异常,他可能会返回个默认值,如果这个字段是Double类型的话,该默认值为null,如果该字段是double类型的话,该默认值为0.0。

    如果扣费系统对于该费率返回值没做特殊处理的话,拿到null值进行计算会直接报错,阻断程序。拿到0.0可能就直接进行计算,得出接口为0后进行扣费了。这种异常情况就无法被感知。

    有人说,那我可以对0.0做特殊判断,如果是0一样可以阻断报错啊。但是,这时候就会产生一个问题,如果允许费率是0的场景又怎么处理呢?

    所以,使用基本数据类型只会让方案越来越复杂,坑越来越多。

    这种使用包装类型定义变量的方式,通过异常来阻断程序,进而可以被识别到这种线上问题。如果使用基本数据类型的话,系统可能不会报错,进而认为无异常。

    当然,以上的选择是针对一些电商、支付、金融等场景,可以牺牲暂时的可用性的场景,如果是对于某些软件系统,可以容忍数据不准,但是不能系统不可用的情况要另当别论。

    以上,就是要求在POJO和RPC的返回值中使用包装类型的原因。

    程序汪资料链接

    程序汪接的7个私活都在这里,经验整理open in new window

    Java项目分享  最新整理全集,找项目不累啦 07版open in new window

    堪称神级的Spring Boot手册,从基础入门到实战进阶open in new window

    卧槽!字节跳动《算法中文手册》火了,完整版 PDF 开放下载!open in new window

    卧槽!阿里大佬总结的《图解Java》火了,完整版PDF开放下载!open in new window

    字节跳动总结的设计模式 PDF 火了,完整版开放下载!open in new window

    欢迎添加程序汪个人微信 itwang009  进粉丝群或围观朋友圈

    - + diff --git a/dist/nice-article/weixin-zaixsfdnavicatzkkydsjkglgjjmgxk.html b/dist/nice-article/weixin-zaixsfdnavicatzkkydsjkglgjjmgxk.html new file mode 100644 index 00000000..8e7aaf15 --- /dev/null +++ b/dist/nice-article/weixin-zaixsfdnavicatzkkydsjkglgjjmgxk.html @@ -0,0 +1,48 @@ + + + + + + + + 再见收费的Navicat!这款开源的数据库管理工具界面更炫酷! | Java 程序员进阶之路 + + + + + + +

    再见收费的Navicat!这款开源的数据库管理工具界面更炫酷!

    梦想de星空2022年6月10日
    • 优质文章
    大约 4 分钟

    数据库管理工具,是后端程序员使用频率非常高的的工具。Navicat、DataGrip虽然很好用,但都是收费的。最近在逛Github的时候,无意间发现了一款开源的数据库管理工具Beekeeper Studio,界面非常炫酷推荐给大家!

    Beekeeper Studio 简介

    Beekeeper Studio 是一款跨平台的数据库管理工具,支持Linux、Mac、 Windows系统,目前在Github上已有9.8K+Star

    一看到它的深色模式主题时,我就感觉它的界面很炫酷,非常符合程序员的审美,大家可以看下。

    下载安装

    Beekeeper Studio 有免费的社区版可以使用,不想安装的小伙伴可以下载便携版,下载地址:https://www.beekeeperstudio.io/get

    下载完成后双击.exe文件即可运行,运行成功后效果如下,默认是浅色主题。

    使用

    下面我们来体验下Beekeeper Studio,看看它是不是够好用!

    外观设置

    我们可以通过顶部的View菜单按钮进行字体大小和主题设置,我们把它切换到更炫酷的深色主题。

    创建数据源

    • 我们可以通过顶部的New Connection按钮来创建数据源,这里我们可以发现Beekeeper Studio仅支持常用的几种关系型数据库;

    • 这里我们创建一个MySQL连接,输入连接信息,然后点击保存按钮即可;

    • 再点击Connect按钮,连接后选择好数据库就可以开始管理了,操作快捷键已经在下方提示了。

    管理表操作

    • 右键表名点击菜单可以选择查看表中的数据;

    • 支持快捷查询各个字段相关数据,这功能还是挺实用的;

    • 右键菜单还可以查看表结构,管理字段还是挺方便的;

    • 右键菜单还可以查看表的创建语句,这SQL主题样式,确实挺漂亮的;

    • 右键菜单还支持导出表中数据,支持多种格式。

    SQL操作

    • 在使用Beekeeper Studio的编辑器写SQL的时候,支持SQL语法高亮,对数据库表和字段都可以自动提示;

    • 我们还可以通过保存按钮来保存需要的SQL语句;

    • 然后点击左侧按钮就可以查看保存的SQL语句了;

    • 通过左侧按钮我们还可以查看执行SQL的历史记录。

    总结

    刚看到Beekeeper Studio有点被惊艳到了,界面确实很炫酷,功能也基本够用。但是SQL提示能力比起DataGrip和Navicat来,确实有点弱。不能自动提示SQL语法,只能提示数据库表和字段,对于SQL老手来说应该问题不大。总的来说,Beekeeper Studio在开源数据库管理工具中,还是非常好用的一款,喜欢它界面的朋友可以试试!

    项目地址

    https://github.com/beekeeper-studio/beekeeper-studio/


    微信8.0将好友放开到了一万,小伙伴可以加我大号了,先到先得,再满就真没了

    扫描下方二维码即可加我微信啦,2022,抱团取暖,一起牛逼。

    推荐阅读

    + + + diff --git a/dist/nice-article/weixin-zhongxcwbztashjjavahdmj.html b/dist/nice-article/weixin-zhongxcwbztashjjavahdmj.html index 6eeef200..1fe4751e 100644 --- a/dist/nice-article/weixin-zhongxcwbztashjjavahdmj.html +++ b/dist/nice-article/weixin-zhongxcwbztashjjavahdmj.html @@ -39,10 +39,10 @@ } - + -

    中小厂(五八、中通、安硕、浩鲸...) Java 后端面经

    Guide2022年6月8日
    • 优质文章
    大约 7 分钟

    《Java 面试指北》open in new window来啦!这是一份教你如何更高效地准备面试的小册,涵盖常见八股文(系统设计、常见框架、分布式、高并发 ......)、优质面经等内容。

    JavaGuide 在线阅读网站:https://javaguide.cn/

    你好,我是 Guide。

    简单对知识星球open in new window的球友分享的一些中小厂面经做了一下总结,准备面试或者想要跳槽的朋友可以拿来自测一下。

    由于问题太多,我这里就不贴参考答案了,需要参考答案的朋友可以在下面 3 个资料中找到:

    以下面经来自知识星球open in new window的 W 同学。

    五八同城

    1. 自我介绍。
    2. 说一下项目的技术栈。
    3. 项目中遇到了什么困难?怎么解决的?
    4. MySQL 和 Redis 怎么保持数据一致?
    5. RocketMQ 广播消息 丢失消息怎么办?
    6. 分布式事务了解吗?
    7. 说一下怎么实现的分布式事务?还有没有其他的解决方案?
    8. RocketMQ 能做分布式事务吗?
    9. 并发事务带来了哪些问题?
    10. 问一下 MySQL 默认隔离级别,可以解决幻读吗?(考察 当前读 快照读 间隙锁 等)
    11. MySQL 的隔离级别是基于锁实现的吗?
    12. 多个人给一个主播打赏怎么设计?我说是一个高并发写的操作,对一个记录频繁写,分批操作,比如 10 个记录 操作一次。他说这个方案可以 但是有 100 个记录 怎么去做一个一个操作呢?我说如果在一个进程可以 分多个线程分批。他说还是不够快 我们是用的 MQ 多个消费者 一个打赏就发一个消息
    13. synchronizedvolatile 区别?
    14. synchronized 有了为什么还要 ReentranLock ,有啥不一样?
    15. 接口和抽象类有什么区别?
    16. 泛型有啥用?泛型擦除是啥?

    总结:整体上 先问项目问项目依赖的中间件,问技术方案怎么设计,比较符合开发场景,MysSQL 间隙锁需要补充一下

    最后点评:项目和技术广度很好 但是深度不够,说 MySQL 间隙锁不是很熟悉

    上海中通

    1. 讲一下 ArrayListHashMap 底层数据结构,优缺点,使用方式。
    2. ConcurrentHashMap有用过吗?
    3. CAS 设计思路和原理?
    4. ThreadLocal 底层原理?什么场景使用的 ThreadLocal
    5. 用到了 Java 8 的哪些新特性?
    6. Lambda 怎么用的,Stream 的实现原理?
    7. 除了刚刚的场景 还有什么场景使用过异步任务,并发任务计算结果后做聚合 么做?
    8. 网络编程用过吗?IO 讲一下
    9. 你开发中都用到了什么设计模式?
    10. 工厂模式的设计理念是什么?有什么好处?体现了什么编程思想?
    11. 适配器模式了解吗?策略和适配器模式有什么区别,你为什么选择用策略模式而不是适配器原因是什么?
    12. JVM 调优经验 说一下做了什么?
    13. Spring 事务注解 Transaction 实现原理?
    14. A 方法调用 B 方法,如果 B 方法开启事务 则直接用 B 方法的事务,如果是你,你怎么设计怎么做?
    15. InnoDB 的默认隔离级别,可重复读,解决了什么问题,没有解决什么问题?
    16. 什么场景下使用了 ES?
    17. 倒排索引 是什么讲一下?
    18. 为什么 ES 检索比较快?
    19. 你使用 MQ(RocketMQ 和 Kafka)的应用场景什么?
    20. 你说系统单接口 qps 达到了 8W 你做了性能优化,这个是怎么做的?本地缓存用了什么删除策略?本地缓存设置了多大?
    21. 做了重试保证订单的最终一致性 这个是怎么做的重试?
    22. MQ 消息积压遇到过吗?你是怎么处理这个?

    以下面经来自知识星球open in new window的傅晓海同学。

    上海安硕信息

    1. Dubbo 使用的注册中心和推荐的协议
    2. Redis 的具体应用
    3. Spring 的常用注解
    4. MySQL 的默认数据库引擎
    5. MySQL 支持哪些存储引擎?默认使用哪个?
    6. MyISAM 和 InnoDB 的区别是什么?
    7. 看毕设

    上海地听

    1. 什么是多态?
    2. JSP 内置对象有哪些?
    3. 什么是跨域问题?如何解决?
    4. 一个 Tomcat 上发布两个项目,一个端口 80,一个 81,相互之间调用算不算跨域
    5. 说说索引和主键的用途。
    6. MyBatis 中 #{}${} 的区别?
    7. 单例模式的实现。
    8. 链表和队列的特点,查询和增删改的时间复杂度。
    9. Spring 的常用注解
    10. @Required 注解的作用
    11. 如果有一条 SQL 语句执行的很慢,怎么进行优化?
    12. 存储过程是什么,有什么特点?

    南京浩鲸科技

    1. 常用的数据结构有哪些?
    2. 数组和链表的区别,以及获取元素的时间复杂度
    3. 线程池的特点和具体实现,线程的状态,
    4. notify()notifyall() 的区别
    5. MySQL 索引的分类
    6. 什么是视图
    7. 事务的隔离级别以及解决了哪些问题
    8. IOC 源码
    9. Spring 常用注解和作用
    10. AoP 的具体应用
    11. Spring 事务

    上海华讯

    1. 接口和抽象类的区别
    2. 内部类有哪些以及特点和应用
    3. 数组和链表
    4. 快速排序算法
    5. 异常的处理方式
    6. HashMap 的底层数据结构
    7. hashcode 的作用,如果 hashcode 相同,怎么存入元素
    8. 内连接和外连接的区别
    9. 分组查询的关键字
    10. 如何开启慢查询日志
    11. 数据库优化技巧
    12. 索引的分类
    13. 主键索引和唯一索引的区别
    14. Spring 通过注解实现 DI 的原理
    15. 什么是 RESTful 风格
    16. Spring 和 Mybatis 整合的步骤
    17. Mybatis 执行流程

    ·········· END ··············

    欢迎加入我的知识星球open in new window获取更多面试干货,《Java 面试指北》open in new window持续更新完善中!

    《Java 面试指北》目录

    近期文章精选 :

    如果本文对你有帮助的话,欢迎点赞&在看&分享,这对我继续分享&创作优质文章非常重要。感谢🙏🏻

    - +

    中小厂(五八、中通、安硕、浩鲸...) Java 后端面经

    Guide2022年6月8日
    • 优质文章
    大约 7 分钟

    《Java 面试指北》open in new window来啦!这是一份教你如何更高效地准备面试的小册,涵盖常见八股文(系统设计、常见框架、分布式、高并发 ......)、优质面经等内容。

    JavaGuide 在线阅读网站:https://javaguide.cn/

    你好,我是 Guide。

    简单对知识星球open in new window的球友分享的一些中小厂面经做了一下总结,准备面试或者想要跳槽的朋友可以拿来自测一下。

    由于问题太多,我这里就不贴参考答案了,需要参考答案的朋友可以在下面 3 个资料中找到:

    以下面经来自知识星球open in new window的 W 同学。

    五八同城

    1. 自我介绍。
    2. 说一下项目的技术栈。
    3. 项目中遇到了什么困难?怎么解决的?
    4. MySQL 和 Redis 怎么保持数据一致?
    5. RocketMQ 广播消息 丢失消息怎么办?
    6. 分布式事务了解吗?
    7. 说一下怎么实现的分布式事务?还有没有其他的解决方案?
    8. RocketMQ 能做分布式事务吗?
    9. 并发事务带来了哪些问题?
    10. 问一下 MySQL 默认隔离级别,可以解决幻读吗?(考察 当前读 快照读 间隙锁 等)
    11. MySQL 的隔离级别是基于锁实现的吗?
    12. 多个人给一个主播打赏怎么设计?我说是一个高并发写的操作,对一个记录频繁写,分批操作,比如 10 个记录 操作一次。他说这个方案可以 但是有 100 个记录 怎么去做一个一个操作呢?我说如果在一个进程可以 分多个线程分批。他说还是不够快 我们是用的 MQ 多个消费者 一个打赏就发一个消息
    13. synchronizedvolatile 区别?
    14. synchronized 有了为什么还要 ReentranLock ,有啥不一样?
    15. 接口和抽象类有什么区别?
    16. 泛型有啥用?泛型擦除是啥?

    总结:整体上 先问项目问项目依赖的中间件,问技术方案怎么设计,比较符合开发场景,MysSQL 间隙锁需要补充一下

    最后点评:项目和技术广度很好 但是深度不够,说 MySQL 间隙锁不是很熟悉

    上海中通

    1. 讲一下 ArrayListHashMap 底层数据结构,优缺点,使用方式。
    2. ConcurrentHashMap有用过吗?
    3. CAS 设计思路和原理?
    4. ThreadLocal 底层原理?什么场景使用的 ThreadLocal
    5. 用到了 Java 8 的哪些新特性?
    6. Lambda 怎么用的,Stream 的实现原理?
    7. 除了刚刚的场景 还有什么场景使用过异步任务,并发任务计算结果后做聚合 么做?
    8. 网络编程用过吗?IO 讲一下
    9. 你开发中都用到了什么设计模式?
    10. 工厂模式的设计理念是什么?有什么好处?体现了什么编程思想?
    11. 适配器模式了解吗?策略和适配器模式有什么区别,你为什么选择用策略模式而不是适配器原因是什么?
    12. JVM 调优经验 说一下做了什么?
    13. Spring 事务注解 Transaction 实现原理?
    14. A 方法调用 B 方法,如果 B 方法开启事务 则直接用 B 方法的事务,如果是你,你怎么设计怎么做?
    15. InnoDB 的默认隔离级别,可重复读,解决了什么问题,没有解决什么问题?
    16. 什么场景下使用了 ES?
    17. 倒排索引 是什么讲一下?
    18. 为什么 ES 检索比较快?
    19. 你使用 MQ(RocketMQ 和 Kafka)的应用场景什么?
    20. 你说系统单接口 qps 达到了 8W 你做了性能优化,这个是怎么做的?本地缓存用了什么删除策略?本地缓存设置了多大?
    21. 做了重试保证订单的最终一致性 这个是怎么做的重试?
    22. MQ 消息积压遇到过吗?你是怎么处理这个?

    以下面经来自知识星球open in new window的傅晓海同学。

    上海安硕信息

    1. Dubbo 使用的注册中心和推荐的协议
    2. Redis 的具体应用
    3. Spring 的常用注解
    4. MySQL 的默认数据库引擎
    5. MySQL 支持哪些存储引擎?默认使用哪个?
    6. MyISAM 和 InnoDB 的区别是什么?
    7. 看毕设

    上海地听

    1. 什么是多态?
    2. JSP 内置对象有哪些?
    3. 什么是跨域问题?如何解决?
    4. 一个 Tomcat 上发布两个项目,一个端口 80,一个 81,相互之间调用算不算跨域
    5. 说说索引和主键的用途。
    6. MyBatis 中 #{}${} 的区别?
    7. 单例模式的实现。
    8. 链表和队列的特点,查询和增删改的时间复杂度。
    9. Spring 的常用注解
    10. @Required 注解的作用
    11. 如果有一条 SQL 语句执行的很慢,怎么进行优化?
    12. 存储过程是什么,有什么特点?

    南京浩鲸科技

    1. 常用的数据结构有哪些?
    2. 数组和链表的区别,以及获取元素的时间复杂度
    3. 线程池的特点和具体实现,线程的状态,
    4. notify()notifyall() 的区别
    5. MySQL 索引的分类
    6. 什么是视图
    7. 事务的隔离级别以及解决了哪些问题
    8. IOC 源码
    9. Spring 常用注解和作用
    10. AoP 的具体应用
    11. Spring 事务

    上海华讯

    1. 接口和抽象类的区别
    2. 内部类有哪些以及特点和应用
    3. 数组和链表
    4. 快速排序算法
    5. 异常的处理方式
    6. HashMap 的底层数据结构
    7. hashcode 的作用,如果 hashcode 相同,怎么存入元素
    8. 内连接和外连接的区别
    9. 分组查询的关键字
    10. 如何开启慢查询日志
    11. 数据库优化技巧
    12. 索引的分类
    13. 主键索引和唯一索引的区别
    14. Spring 通过注解实现 DI 的原理
    15. 什么是 RESTful 风格
    16. Spring 和 Mybatis 整合的步骤
    17. Mybatis 执行流程

    ·········· END ··············

    欢迎加入我的知识星球open in new window获取更多面试干货,《Java 面试指北》open in new window持续更新完善中!

    《Java 面试指北》目录

    近期文章精选 :

    如果本文对你有帮助的话,欢迎点赞&在看&分享,这对我继续分享&创作优质文章非常重要。感谢🙏🏻

    + diff --git a/dist/nice-article/weixin-zuixinbujiabandigongsimingdan.html b/dist/nice-article/weixin-zuixinbujiabandigongsimingdan.html index e0aa3f6d..da6eca7f 100644 --- a/dist/nice-article/weixin-zuixinbujiabandigongsimingdan.html +++ b/dist/nice-article/weixin-zuixinbujiabandigongsimingdan.html @@ -39,10 +39,10 @@ } - + -

    最新 955 不加班的公司名单

    沉默王二2022年5月30日
    • 优质文章
    大约 3 分钟

    这是github上的一个开源项目:955.WLB,上面列举了程序员们汇总的 955 作息的公司名单,旨在促进码农的工作生活平衡,文末「阅读原文」附上了 github 项目地址,感兴趣可以看看。

    • 996 工作制:即每天早 9 点到岗,一直工作到晚上 9 点。每周工作 6 天。
    • 955 工作制:即每天早 9 点到岗,一直工作到下午 5 点。每周工作 5 天。
    • 944 工作制:即每天上午 9 点到岗,一直工作到下午 4 点。每周工作 4 天。

    说明

    以下公司名单,基本不属于 996 的公司,相对接近 955/965 的水平,但是依旧要看部门和地区,不能保证完全准确性。

    • 不能保证所有部门都是 955/10-6-5/965/10-7-5 的水平
    • 就算部门的平均水平是 955/10-6-5/965/10-7-5,也有可能部分时间要加班
    • 名单中部分公司的部分部门可能有 975 甚至 985 的情况,不要以偏概全
    • 名单中部分公司的部分甚至较多部门可能有 945、10-5-5 或者 11-6-5 的情况,我们也把他们加入在名单中

    另外,统计一定不完全,欢迎各位同行留言补充,务求真实!

    955 的公司名单

    • Afterpay - 上海
    • Amazon - 北京/上海
    • AMD - 上海
    • ARM - 上海
    • Airbnb - 北京
    • Apple - 北京/上海
    • ArcSoft - 杭州
    • Autodesk - 北京/上海

    -Booking - 上海

    • Calix - 南京
    • Citrix - 南京
    • Cisco - 北京/上海/杭州/苏州
    • Coolapk (酷安) - 北京/深圳
    • Coupang - 北京/上海
    • CSTC (花旗金融) - 上海
    • Dell - 上海
    • Douban (豆瓣) - 北京
    • eBay - 上海
    • eHealth - 厦门
    • Electronic Arts - 上海
    • EMC - 上海
    • Ericsson - 上海
    • Flexport - 上海/深圳
    • FreeWheel - 北京
    • GE - 上海
    • Google - 北京/上海
    • Grab - 北京
    • Honeywell - 上海
    • HP - 上海
    • HSBC - 上海/广州/西安
    • Hulu - 北京
    • IBM (GBS除外) - 上海
    • iHerb - 上海
    • Intel - 上海/深圳
    • LeetCode - 上海
    • Linkedin - 北京
    • Micro Focus - 上海
    • Microsoft - 北京/上海/苏州
    • MicroStrategy - 杭州
    • National Instruments - 上海
    • Nokia - 南京/杭州
    • NVIDIA - 北京/上海
    • Oracle - 上海
    • PayPal - 上海
    • Pivotal - 北京/上海
    • Qualcomm - 北京/上海
    • Red Hat - 北京/上海/深圳/西安/remote
    • RingCentral - 厦门/杭州/香港
    • SAP - 上海
    • Shopee - 北京/上海/深圳
    • SmartNews - 北京/上海
    • Snap - 北京/深圳
    • State Street - 杭州
    • SUSE - 北京/上海/深圳
    • ThoughtWorks - 西安/北京/深圳/成都/武汉/上海/香港
    • Trend Micro - 南京
    • TuSimple - 北京/上海
    • Ubisoft - 上海
    • Unity - 上海
    • Vipshop (唯品会) - 上海
    • VMware - 北京/上海
    • WeWork - 上海
    • Wish - 上海
    • Works Applications - 上海
    • XMind - 深圳
    • Zhihu (知乎) - 北京
    • Zoom - 合肥/杭州/苏州

    良好的行业风气有助于各位同行发展,为这类企业点赞!

    你好,我是公子龙,毕业于中科院,前大型计算机竞赛冠军,现大厂工程师,拿过九家大厂的 offer 。

    北漂七年,从小白到计算机竞赛冠军,读研时通过实习和比赛收入 50 万,点击蓝字查看我的编程之路open in new window

    同时,我也是 b 站 up 主:公子龙龙龙,日常分享高质量资料,输出面试、工作经验,欢迎围观。

    - +

    最新 955 不加班的公司名单

    沉默王二2022年5月30日
    • 优质文章
    大约 3 分钟

    这是github上的一个开源项目:955.WLB,上面列举了程序员们汇总的 955 作息的公司名单,旨在促进码农的工作生活平衡,文末「阅读原文」附上了 github 项目地址,感兴趣可以看看。

    • 996 工作制:即每天早 9 点到岗,一直工作到晚上 9 点。每周工作 6 天。
    • 955 工作制:即每天早 9 点到岗,一直工作到下午 5 点。每周工作 5 天。
    • 944 工作制:即每天上午 9 点到岗,一直工作到下午 4 点。每周工作 4 天。

    说明

    以下公司名单,基本不属于 996 的公司,相对接近 955/965 的水平,但是依旧要看部门和地区,不能保证完全准确性。

    • 不能保证所有部门都是 955/10-6-5/965/10-7-5 的水平
    • 就算部门的平均水平是 955/10-6-5/965/10-7-5,也有可能部分时间要加班
    • 名单中部分公司的部分部门可能有 975 甚至 985 的情况,不要以偏概全
    • 名单中部分公司的部分甚至较多部门可能有 945、10-5-5 或者 11-6-5 的情况,我们也把他们加入在名单中

    另外,统计一定不完全,欢迎各位同行留言补充,务求真实!

    955 的公司名单

    • Afterpay - 上海
    • Amazon - 北京/上海
    • AMD - 上海
    • ARM - 上海
    • Airbnb - 北京
    • Apple - 北京/上海
    • ArcSoft - 杭州
    • Autodesk - 北京/上海

    -Booking - 上海

    • Calix - 南京
    • Citrix - 南京
    • Cisco - 北京/上海/杭州/苏州
    • Coolapk (酷安) - 北京/深圳
    • Coupang - 北京/上海
    • CSTC (花旗金融) - 上海
    • Dell - 上海
    • Douban (豆瓣) - 北京
    • eBay - 上海
    • eHealth - 厦门
    • Electronic Arts - 上海
    • EMC - 上海
    • Ericsson - 上海
    • Flexport - 上海/深圳
    • FreeWheel - 北京
    • GE - 上海
    • Google - 北京/上海
    • Grab - 北京
    • Honeywell - 上海
    • HP - 上海
    • HSBC - 上海/广州/西安
    • Hulu - 北京
    • IBM (GBS除外) - 上海
    • iHerb - 上海
    • Intel - 上海/深圳
    • LeetCode - 上海
    • Linkedin - 北京
    • Micro Focus - 上海
    • Microsoft - 北京/上海/苏州
    • MicroStrategy - 杭州
    • National Instruments - 上海
    • Nokia - 南京/杭州
    • NVIDIA - 北京/上海
    • Oracle - 上海
    • PayPal - 上海
    • Pivotal - 北京/上海
    • Qualcomm - 北京/上海
    • Red Hat - 北京/上海/深圳/西安/remote
    • RingCentral - 厦门/杭州/香港
    • SAP - 上海
    • Shopee - 北京/上海/深圳
    • SmartNews - 北京/上海
    • Snap - 北京/深圳
    • State Street - 杭州
    • SUSE - 北京/上海/深圳
    • ThoughtWorks - 西安/北京/深圳/成都/武汉/上海/香港
    • Trend Micro - 南京
    • TuSimple - 北京/上海
    • Ubisoft - 上海
    • Unity - 上海
    • Vipshop (唯品会) - 上海
    • VMware - 北京/上海
    • WeWork - 上海
    • Wish - 上海
    • Works Applications - 上海
    • XMind - 深圳
    • Zhihu (知乎) - 北京
    • Zoom - 合肥/杭州/苏州

    良好的行业风气有助于各位同行发展,为这类企业点赞!

    你好,我是公子龙,毕业于中科院,前大型计算机竞赛冠军,现大厂工程师,拿过九家大厂的 offer 。

    北漂七年,从小白到计算机竞赛冠军,读研时通过实习和比赛收入 50 万,点击蓝字查看我的编程之路open in new window

    同时,我也是 b 站 up 主:公子龙龙龙,日常分享高质量资料,输出面试、工作经验,欢迎围观。

    + diff --git a/dist/nice-article/zhihu-jisjkyynxzdtjdyj.html b/dist/nice-article/zhihu-jisjkyynxzdtjdyj.html new file mode 100644 index 00000000..6ea529fa --- /dev/null +++ b/dist/nice-article/zhihu-jisjkyynxzdtjdyj.html @@ -0,0 +1,48 @@ + + + + + + + + 计算机考研有哪些值得推荐的院校? | Java 程序员进阶之路 + + + + + + +

    计算机考研有哪些值得推荐的院校?

    重庆搬砖喵2022年6月11日
    • 优质文章
    大约 3 分钟

    2022年更新

    前排高赞的回答比较适合科班大佬和本科出身好又数学好的同学。对于数学一般同学,或者本科差的同学,别刚热门985了,真的求稳吧。

    西安电子科技大学(计算机学院、人工院很卷,但是光电工程学院、电子工程学院不怎么卷,空间院还年年校内调剂)其他学院就业照样很好,性价比很高的。

    open in new window

    注意:别只盯着计院和软院,只要是信息技术类专业就业都挺好,毕竟编程能力主要靠自己自学的。

    哈尔滨工程大学(工科院校名额多,几个学院都招计算机)

    河北工业大学

    中国地质大学武汉(要优秀生源?)

    中国矿业大学(徐州)

    福州大学(保护一志愿,进面试基本不刷人)

    西南财经(名额少)

    西南大学(往年复试只有面试,没有机试)

    云南大学软件学院

    广西大学

    华中农业大学

    大连海事大学

    收调剂的新一流:宁波大学 天津工业 上海海洋

    211师范类、文科类院校女生多:

    华南师范大学

    南京师范大学

    西北大学的现代教育技术中心

    陕西师范大学

    辽宁大学(名额较多)

    华中师范大学的教育数据工程中心(两年制)

    华中师范大学伍伦贡联合学院(中外合作办学,两年制、一年8万,学费相对较低)

    往年好考的985:西北工业大学软件学院(评论区说很卷了)。中央民族 中国海洋 西北农林 兰州大学 都是年年收调剂。

    中国科学院大学下面的各个计算机研究所全国都有,比985好考,实力强,待遇好,比如:人工智能院和深圳先进技术研究院,但是不喜欢跨考。

    尽量选择水区省份。冷知识:京沪压个20分正常。

    收调剂或者竞争小的双非:

    重庆邮电大学(就业不输211,别看报名人数两三千个,但是并不卷,最终录取分都不算高,专业课也不难

    桂林电子科技大学(年年收调剂,在珠三角就业很好

    西安邮电大学(虽然比不得西电,但是就业也很好,平均薪资排序大概是:西电、西交、西工大、西邮、长安大学、西北大学)

    广东工业大学

    广州大学(方院士了解一下)

    汕头大学(年年收调剂

    昆明理工大学(名额多)

    中国民航大学(调剂很火)

    西安理工大学

    杭州师范大学

    浙江师范大学

    浙江工业大学

    南京工业大学

    华侨大学(调剂名额多,调剂火)

    北京语言大学(自然语言处理方向)

    考研应届生与二战生的比例差几乎一比一,希望学弟学妹一步到位,别二战。考研不易,竞争越来越大,求稳,求稳,求稳,结合本科出身和学习能力(尤其数学)别盯着热门985不放。

    尽量选专业课简单的学校,因为总分高好调剂,专业课简单可以把更多精力放在数学上。调剂很看本科出身,双非的同学更要求稳。

    跨考担心复试的机试:先过初试,初试完准备来得及的。

    求赞……求赞……求赞……

    数二的内容是数一的七成,同样实力下,英二可以比英一多考个十二分

    科班大佬及自控力好学习能力好的学霸忽略以上。

    + + + diff --git a/dist/nice-article/zhihu-weismyrsyxkjgscxyzhdjyxz.html b/dist/nice-article/zhihu-weismyrsyxkjgscxyzhdjyxz.html new file mode 100644 index 00000000..6f6ed270 --- /dev/null +++ b/dist/nice-article/zhihu-weismyrsyxkjgscxyzhdjyxz.html @@ -0,0 +1,48 @@ + + + + + + + + 为什么有人说银行科技岗是程序员最好的就业选择? | Java 程序员进阶之路 + + + + + + +

    为什么有人说银行科技岗是程序员最好的就业选择?

    重庆搬砖喵2022年6月11日
    • 优质文章
    大约 5 分钟

    本人20年秋招时投的银行还比较多,就是图稳定,钱少一点无所谓。目前已入职某银行总行科技信息部。

    总结一下就是3点:稳定+薪资还行+没有营销压力

    证券公司同理:西部证券,西南证券,长江证券,华泰证券,广发证券等等(基本每省都有一所证券公司)

    **温馨提醒:**各省的证券公司IT部门待遇更高哦。

    待遇上:

    1、整体上大银行的待遇>中小银行

    2、地方性银行总行的待遇>国有行省级分行

    稳定性:

    3家政策行>6大国有行(总行+省级分行+市级支行)+地方城市银行、地方农商行>12家股份制商业银行+科技子公司

    一、银行分类

    首先银行主要分为如下5类

    3家政策性银行(国家开发银行、进出口银行、农业发展银行),总行+各省的省级分行

    6家中央管辖的国有行(中农工建交+邮储),结构为:总行+各省的省级分行

    12家全国性股份制商业银行(中信、华夏、招商、深发、光大、民生、浦发、渤海、广发、兴业、恒丰、浙商),结构为:总行+各省的省级分行

    已完成股份制改制的各省地方性城市银行+农村商业银行。

    144家城市商业银行(南京银行、杭州银行、宁波银行、重庆银行、中原银行、北京银行、上海银行,四川银行等等),

    212家农村商业银行(北京农商银行、重庆农村商业银行、深圳农村商业银行、广州农村商业银行、上海农商银行等等),经营范围基本只在本省。

    25家未改制省级农信联社(贵州省农村信用社、河北省农村信用社联合社,辽宁省农村信用社联合社等),经营范围只在本省。

    二、根据层级分类

    银行科技信息岗分为以下几类

    整体上,总行下属科技信息部>总行下属研发中心>=省级分行>=省会城市支行>=科技子公司>其他地级市支行。

    还有些信用卡中心,数据中心我不了解就不说了。

    1、总行下属的科技信息部。很少写代码,主要是做技术规划,做管理(管理外包)和运维,所以招人比研发中心少。

    **招聘要求:**一般211硕士起步,学历要求最高。

    稳定与待遇:稳定,拿总行平均绩效,待遇不差,看银行盈利水平,每个银行差异较大,入职税前15-28万之间,后续30万+。基本不加班,朝九晚五。

    2、总行部门下属的软件研发中心专职写代码,招人比较多的:工行研发中心(西安成都珠海广州杭州北京),中行研发中心(西安合肥),农业银行研发中心(天津北京成都)。

    招聘要求:一般211硕士起步,211&985本科也可以,本科进去性价比高,学校好,基本上去了就要。

    稳定与待遇:稳定,但是待遇不太高,转正后大概税前15万-25万,根据职称涨薪资。要加班,加班多少看部门。

    3、全国性银行省分行的科技岗。全国性银行在每个省都有省分行,多数要写代码

    **招聘要求:**硕士起步,或者211本科起步,每个省可能不一样。

    **稳定与待遇:**稳定,薪资大概拿省分行平均工资,待遇看当地的经济情况(效益),一般12-20万。广州和深圳,转正后就20多万,干三年,职级上去了,一年总包应该也是30万左右吧。加班看具体情况。

    4、省会城市支行的科技信息岗位。省分行下属管理各个地级市支行,地级市里当然省会城市待遇最好。一般不写代码

    招聘要求:本科起步,省会城市竞争最大。

    稳定与待遇:稳定,薪资大概12万-20万。待遇看当地的盈利情况。省会支行待遇可能高于省分行。比如杭州支行待遇可能高于浙江省分行待遇。

    5、总行下属的科技子公司。银行内部的外包公司。比如招银网络科技,建信金融科技,中银金科,浙商银行的子公司“易企银”,兴业数金,专职写代码。

    招聘要求:本科起步。

    稳定与待遇:稳定性肯定是下降了,但是待遇上去了,转正后一般税前20-28万。加班会比较多。优点:薪酬较高(20-30万),招聘量大。缺点:稳定性差,无行员编制,加班多,技术一般

    6、非省会地级市分支行的科技岗。非省会地级市&区县的科技岗,不写代码,干运维提需求这些。

    招聘要求:本科。

    **稳定与待遇:**稳定,待遇比较一般了,税前10万左右吧,看当地分行的效益拿平均绩效,一般在当地还是中上水平。

    **求职推荐:**3家政策性银行总部(国开行、农发行、进出口银行),最稳定。

    农业银行,邮储银行(不是子公司同时待遇又高),渤海银行(天津有额外**20%**补充公积金)

    杭州银行,宁波银行,四川银行。

    深圳农商行,广州农商行,重庆农商行。

    工行广东省分行,广州支行、深圳支行。

    不同银行、不同地区、不同部门差异很大的,具体问题具体分析,多上牛客,多看offershow,还有脉脉。想尽办法问到内部情况。

    + + + diff --git a/dist/nice-article/zhihu-younxzdjsjzyxsjrdgq.html b/dist/nice-article/zhihu-younxzdjsjzyxsjrdgq.html new file mode 100644 index 00000000..347771dd --- /dev/null +++ b/dist/nice-article/zhihu-younxzdjsjzyxsjrdgq.html @@ -0,0 +1,48 @@ + + + + + + + + 有哪些值得计算机专业学生加入的国企? | Java 程序员进阶之路 + + + + + + +

    有哪些值得计算机专业学生加入的国企?

    重庆搬砖喵2022年6月11日
    • 优质文章
    大约 3 分钟

    一、首选证券公司

    各省基本都有一所证券公司,沿海省份集中在税前30-40万左右,内地集中在20-30万。很少加班,多数为国企,一般要求硕士。

    然后还有些公募和私募基金的技术岗,比如易方达基金,华安基金、汇添富基金,比较看中学历,待遇比券商更高。

    我认识的一个中部211硕去了上海***资产(私募),22k*18=39.6,在基金公司里算是比较低的了。

    二、各大银行

    总结一下就是3点:稳定+薪资还行+没有营销压力。

    整体上大银行的待遇>中小银行

    地方性银行总行的待遇>国有行省级分行

    银行是个比较大的话题:3家政策行(稳定+高薪),6大国有行,12家全国股份行。

    每个省的地方性城市银行,地方性农商行,未改制的省联社,还有一批地级市小银行。

    在这个回答介绍得很详细了:

    open in new window

    三、烟草+国家电网+中石油+铁路集团

    烟草公司:分为各省烟草专卖局和各省中烟工业(卷烟厂),属于闷声发大财的代表,懂的都懂。

    电网是个很大的话题,首选是输电卖电的国家电网、南方电网

    还有发电的央企(煤电、水电、风电、核电、光伏):

    国家能源、大唐集团、中国华能、华电集团、国家电投、三峡集团、华润集团、国投集团、中广核集团、中核集团、

    最后是电力装备制造的新央企:中国电气装备集团(可能待遇不如前面的)

    每个省都有中石油分公司

    铁路招聘网:

    open in new window

    提一句三大运营商,税前8-15万之间,工作氛围褒贬不一看部门和岗位,适合家境好无赚钱压力的。

    同理还有各大航空公司

    各省高速路集团

    四、军工相关的三家央企:航天科技+航天科工+电子科技集团

    岗位多集中在北京、上海、西安、成都,其余很多省会也有子公司。

    不同所差别很大,待遇看盈利情况,加班情况看部门,一般要求硕士。

    五、军队

    军队文职和直招军官(偏题了)。

    军官直招岗位查询地址:

    open in new window

    六、医院信息科

    医疗信息化,当甲方,不写代码,很爽的好吧。

    open in new window

    七、地方政府的平台公司

    这个懂的都懂,比较小众,招聘要求比较高,待遇很好,也很稳定,不懂的就了解下城投公司。

    大公司一般都有技术岗,登陆本省或本市的国资委官网查询。

    信息化是大潮流,各行各业都需要,大公司基本都有信息岗,但是职业前景比较窄。

    只收藏不点赞是几个意思?本文持续更新,欢迎补充。

    总结:没找到满意工作,读研吧,选择会多很多:

    open in new window

    + + + diff --git a/dist/oo/abstract.html b/dist/oo/abstract.html index 3ec20dc8..78a306df 100644 --- a/dist/oo/abstract.html +++ b/dist/oo/abstract.html @@ -39,10 +39,10 @@ } - + -

    Java抽象类

    沉默王二2021年10月22日
    • Java核心
    • Java
    大约 5 分钟

    Java抽象类

    “二哥,你这明显加快了更新的频率呀!”三妹对于我最近的肝劲由衷的佩服了起来。

    “哈哈,是呀,这次不能再断更了,我要再更 175 篇,总计 200 篇,给广大的学弟学妹们一个完整的 Java 学习体系。”我对未来充满了信心。

    “那就开始吧。”三妹说。


    定义抽象类的时候需要用到关键字 abstract,放在 class 关键字前,就像下面这样。

    abstract class AbstractPlayer {
    +    

    Java抽象类

    沉默王二2021年10月22日
    • Java核心
    • Java
    大约 5 分钟

    Java抽象类

    “二哥,你这明显加快了更新的频率呀!”三妹对于我最近的肝劲由衷的佩服了起来。

    “哈哈,是呀,这次不能再断更了,我要再更 175 篇,总计 200 篇,给广大的学弟学妹们一个完整的 Java 学习体系。”我对未来充满了信心。

    “那就开始吧。”三妹说。


    定义抽象类的时候需要用到关键字 abstract,放在 class 关键字前,就像下面这样。

    abstract class AbstractPlayer {
     }
     

    关于抽象类的命名,《阿里的 Java 开发手册》上有强调,“抽象类命名要使用 Abstract 或 Base 开头”,这条规约还是值得遵守的。

    抽象类是不能实例化的,尝试通过 new 关键字实例化的话,编译器会报错,提示“类是抽象的,不能实例化”。

    虽然抽象类不能实例化,但可以有子类。子类通过 extends 关键字来继承抽象类。就像下面这样。

    public class BasketballPlayer extends AbstractPlayer {
     }
    @@ -134,6 +134,6 @@ footballPlayer.

    在项目的 resource 目录下建一个文本文件,名字叫 helloworld.txt,里面的内容就是“Hello World”。文件的具体位置如下图所示,我用的集成开发环境是 Intellij IDEA。

    在 resource 目录下的文件可以通过 ClassLoader.getResource() 的方式获取到 URI 路径,然后就可以取到文本内容了。

    输出结果如下所示:

    [hello world]
     [HELLO WORLD]
     

    “完了吗?二哥”三妹似乎还沉浸在聆听教诲的快乐中。

    “是滴,这次我们系统化的学习了抽象类,可以说面面俱到了。三妹你可以把代码敲一遍,加强了一些印象,电脑交给你了。”说完,我就跑到阳台去抽烟了。

    “呼。。。。。”一个大大的眼圈飘散开来,又是愉快的一天~

    - + diff --git a/dist/oo/code-init.html b/dist/oo/code-init.html index 709293a7..24c2ae57 100644 --- a/dist/oo/code-init.html +++ b/dist/oo/code-init.html @@ -39,10 +39,10 @@ } - + -

    Java代码初始化块

    沉默王二2021年10月22日
    • Java核心
    • Java
    大约 3 分钟

    Java代码初始化块

    “哥,今天我们要学习的内容是‘代码初始化块’,对吧?”看来三妹已经提前预习了我上次留给她的作业。

    “是的,三妹。代码初始化块用于初始化一些成员变量。 ”我面带着朴实无华的微笑回答着她,“对象在创建的时候会执行代码初始化块。”

    “可以直接通过‘=’操作符对成员变量进行初始化,但通过代码初始化块可以做更多的事情,比如说打印出成员变量初始化后的值。”

    “三妹,来看下面的代码,我们可以直接通过 = 操作符对成员变量进行初始化。”

    class Bike{  
    +    

    Java代码初始化块

    沉默王二2021年10月22日
    • Java核心
    • Java
    大约 3 分钟

    Java代码初始化块

    “哥,今天我们要学习的内容是‘代码初始化块’,对吧?”看来三妹已经提前预习了我上次留给她的作业。

    “是的,三妹。代码初始化块用于初始化一些成员变量。 ”我面带着朴实无华的微笑回答着她,“对象在创建的时候会执行代码初始化块。”

    “可以直接通过‘=’操作符对成员变量进行初始化,但通过代码初始化块可以做更多的事情,比如说打印出成员变量初始化后的值。”

    “三妹,来看下面的代码,我们可以直接通过 = 操作符对成员变量进行初始化。”

    class Bike{  
         int speed=100;  
     }  
     

    “哥,那为什么还需要代码初始化块呢?”三妹眨了眨眼睛,不解地问。

    “我们可以通过代码初始化块执行一个更复杂的操作,比如为集合填充值。来看下面这段代码。”

    public class Bike {
    @@ -95,6 +95,6 @@
     代码初始化块
     子类构造方法
     

    “在默认情况下,子类的构造方法在执行的时候会主动去调用父类的构造方法。也就是说,其实是构造方法先执行的,再执行的代码初始化块。”

    “这个例子再次印证了之前的第二条规则:代码初始化块是放在构造方法中执行的,只不过比较靠前。”

    - + diff --git a/dist/oo/construct.html b/dist/oo/construct.html index ad529ad4..5800b63f 100644 --- a/dist/oo/construct.html +++ b/dist/oo/construct.html @@ -39,10 +39,10 @@ } - + -

    Java构造方法

    沉默王二2021年10月22日
    • Java核心
    • Java
    大约 7 分钟

    Java构造方法

    我对三妹说,“上一节open in new window学了 Java 中的方法,接着学构造方法的话,难度就小很多了。”

    “在 Java 中,构造方法是一种特殊的方法,当一个类被实例化的时候,就会调用构造方法。只有在构造方法被调用的时候,对象才会被分配内存空间。每次使用 new 关键字创建对象的时候,构造方法至少会被调用一次。”

    “如果你在一个类中没有看见构造方法,并不是因为构造方法不存在,而是被缺省了,编译器会给这个类提供一个默认的构造方法。往大的方面说,就是,Java 有两种类型的构造方法:无参构造方法和有参构造方法。”

    “注意,之所以叫它构造方法,是因为对象在创建的时候,需要通过构造方法初始化值——就是描写对象的那些状态,对应的是类中的字段。”

    01、创建构造方法的规则有哪些

    构造方法必须符合以下规则:

    • 构造方法的名字必须和类名一样;
    • 构造方法没有返回类型,包括 void;
    • 构造方法不能是抽象的、静态的、最终的、同步的,也就是说,构造方法不能通过 abstract、static、final、synchronized 关键字修饰。

    简单解析一下最后一条规则。

    • 由于构造方法不能被子类继承,所以用 final 和 abstract 修饰没有意义;
    • 构造方法用于初始化一个对象,所以用 static 修饰没有意义;
    • 多个线程不会同时创建内存地址相同的同一个对象,所以用 synchronized 修饰没有必要。

    构造方法的语法格式如下:

    class class_name {
    +    

    Java构造方法

    沉默王二2021年10月22日
    • Java核心
    • Java
    大约 7 分钟

    Java构造方法

    我对三妹说,“上一节open in new window学了 Java 中的方法,接着学构造方法的话,难度就小很多了。”

    “在 Java 中,构造方法是一种特殊的方法,当一个类被实例化的时候,就会调用构造方法。只有在构造方法被调用的时候,对象才会被分配内存空间。每次使用 new 关键字创建对象的时候,构造方法至少会被调用一次。”

    “如果你在一个类中没有看见构造方法,并不是因为构造方法不存在,而是被缺省了,编译器会给这个类提供一个默认的构造方法。往大的方面说,就是,Java 有两种类型的构造方法:无参构造方法和有参构造方法。”

    “注意,之所以叫它构造方法,是因为对象在创建的时候,需要通过构造方法初始化值——就是描写对象的那些状态,对应的是类中的字段。”

    01、创建构造方法的规则有哪些

    构造方法必须符合以下规则:

    • 构造方法的名字必须和类名一样;
    • 构造方法没有返回类型,包括 void;
    • 构造方法不能是抽象的、静态的、最终的、同步的,也就是说,构造方法不能通过 abstract、static、final、synchronized 关键字修饰。

    简单解析一下最后一条规则。

    • 由于构造方法不能被子类继承,所以用 final 和 abstract 修饰没有意义;
    • 构造方法用于初始化一个对象,所以用 static 修饰没有意义;
    • 多个线程不会同时创建内存地址相同的同一个对象,所以用 synchronized 修饰没有必要。

    构造方法的语法格式如下:

    class class_name {
         public class_name(){}    // 默认无参构造方法
         public ciass_name([paramList]){}    // 定义有参数列表的构造方法
         …
    @@ -236,6 +236,6 @@
         }
     }
     

    通过 clone() 方法复制对象的时候,ClonePerson 必须先实现 Cloneable 接口的 clone() 方法,然后再调用 clone() 方法(ClonePerson p2 = (ClonePerson) p1.clone())。

    07、ending

    “二哥,我能问一些问题吗?”三妹精神焕发,没有丝毫的疲惫。

    “当然可以啊,你问。”我很欣赏三妹孜孜不倦的态度。

    “构造方法真的不返回任何值吗?”

    “构造方法虽然没有返回值,但返回的是类的对象。”

    “构造方法只能完成字段初始化的工作吗?”

    “初始化字段只是构造方法的一种工作,它还可以做更多,比如启动线程,调用其他方法等。”

    “好的,二哥,我的问题问完了,今天的学习可以结束了!”三妹一脸得意的样子。

    “那你记得复习下一节的内容哦。”感受到三妹已经学到了知识,我也很欣慰。

    - + diff --git a/dist/oo/final.html b/dist/oo/final.html index 988e1d40..807553ed 100644 --- a/dist/oo/final.html +++ b/dist/oo/final.html @@ -39,10 +39,10 @@ } - + -

    浅析Java中的final关键字

    沉默王二2021年10月22日
    • Java核心
    • Java
    大约 5 分钟

    浅析Java中的final关键字

    “哥,今天学什么呢?”

    “今天学一个重要的关键字——final。 ”我面带着朴实无华的微笑回答着她,“对了,三妹,你打算考研吗?”

    “还没想过,我今年才大一呢,到时候再说吧,你决定。”

    “好吧。”我摊摊手,表示很无辜,真的是所有的决定都交给我这个哥哥了,如果决定错了,锅得背上。

    01、final 变量

    “好了,我们先来看 final 修饰的变量吧!”

    “被 final 修饰的变量无法重新赋值。换句话说,final 变量一旦初始化,就无法更改。”

    “来看这行代码。”

    final int age = 18;
    +    

    浅析Java中的final关键字

    沉默王二2021年10月22日
    • Java核心
    • Java
    大约 5 分钟

    浅析Java中的final关键字

    “哥,今天学什么呢?”

    “今天学一个重要的关键字——final。 ”我面带着朴实无华的微笑回答着她,“对了,三妹,你打算考研吗?”

    “还没想过,我今年才大一呢,到时候再说吧,你决定。”

    “好吧。”我摊摊手,表示很无辜,真的是所有的决定都交给我这个哥哥了,如果决定错了,锅得背上。

    01、final 变量

    “好了,我们先来看 final 修饰的变量吧!”

    “被 final 修饰的变量无法重新赋值。换句话说,final 变量一旦初始化,就无法更改。”

    “来看这行代码。”

    final int age = 18;
     

    “当尝试将 age 的值修改为 30 的时候,编译器就生气了。”

    “再来看这段代码。”

    public class Pig {
        private String name;
     
    @@ -95,6 +95,6 @@ pig.setName<
     writer.setName("沉默王二");
     System.out.println(writer.getName()); // 沉默王二
     

    “Writer 的 name 字段的默认值是 null,但可以通过 settter 方法将其更改为沉默王二。也就是说,如果一个类只是 final 的,那么它并不是不可变的全部条件。”

    “关于不可变类,我之前也单独讲过一篇,你一会去看看。”

    不可变类open in new window

    “把一个类设计成 final 的,有其安全方面的考虑,但不应该故意为之,因为把一个类定义成 final 的,意味着它没办法继承,假如这个类的一些方法存在一些问题的话,我们就无法通过重写的方式去修复它。”


    “三妹,final 关键字我们就学到这里吧,你一会再学习一下 Java 字符串为什么是不可变的和不可变类。”我揉一揉犯困的双眼,疲惫地给三妹说,“学完这两个知识点,你会对 final 的认知更清晰一些。”

    “好的,二哥,我这就去学习去。你去休息会。”

    我起身站到阳台上,看着窗外的车水马龙,不一会儿,就发起来呆。

    “好想去再看一场周杰伦的演唱会,不知道 2021 有没有这个机会。”

    我心里这样想着,天渐渐地暗了下来。

    - + diff --git a/dist/oo/inner-class.html b/dist/oo/inner-class.html index 852a65c3..245cab6f 100644 --- a/dist/oo/inner-class.html +++ b/dist/oo/inner-class.html @@ -39,10 +39,10 @@ } - + -

    Java 内部类

    沉默王二2022年4月29日
    • Java核心
    • Java
    大约 4 分钟

    Java 内部类

    内部类简介

    在 Java 中,可以将一个类定义在另外一个类里面或者一个方法里面,这样的类叫做内部类。

    一般来说,内部类分为成员内部类、局部内部类、匿名内部类和静态内部类。

    1)成员内部类

    成员内部类是最常见的内部类,看下面的代码:

    class Wanger {
    +    

    Java 内部类

    沉默王二2022年4月29日
    • Java核心
    • Java
    大约 4 分钟

    Java 内部类

    内部类简介

    在 Java 中,可以将一个类定义在另外一个类里面或者一个方法里面,这样的类叫做内部类。

    一般来说,内部类分为成员内部类、局部内部类、匿名内部类和静态内部类。

    1)成员内部类

    成员内部类是最常见的内部类,看下面的代码:

    class Wanger {
         int age = 18;
         
         class Wangxiaoer {
    @@ -135,6 +135,6 @@
         }
     }
     

    由于 static 关键字的存在,静态内部类是不允许访问外部类中非 static 的变量和方法的,这一点也非常好理解:你一个静态的内部类访问我非静态的成员变量干嘛?

    总结

    为什么要使用内部类?

    在《Think in java》中有这样一句话:

    使用内部类最吸引人的原因是:每个内部类都能独立地继承一个(接口的)实现,所以无论外围类是否已经继承了某个(接口的)实现,对于内部类都没有影响。

    在我们程序设计中有时候会存在一些使用接口很难解决的问题,这个时候我们可以利用内部类提供的、可以继承多个具体的或者抽象的类的能力来解决这些程序设计问题。可以这样说,接口只是解决了部分问题,而内部类使得多重继承的解决方案变得更加完整。

    使用内部类还能够为我们带来如下特性(摘自《Think in java》):

    • 1、内部类可以使用多个实例,每个实例都有自己的状态信息,并且与其他外围对象的信息相互独立。
    • 2、在单个外部类中,可以让多个内部类以不同的方式实现同一个接口,或者继承同一个类。
    • 3、创建内部类对象的时刻并不依赖于外部类对象的创建。
    • 4、内部类并没有令人迷惑的“is-a”关系,他就是一个独立的实体。
    • 5、内部类提供了更好的封装,除了该外围类,其他类都不能访问。

    - + diff --git a/dist/oo/instanceof.html b/dist/oo/instanceof.html index dddd5c70..4ad0b2aa 100644 --- a/dist/oo/instanceof.html +++ b/dist/oo/instanceof.html @@ -39,10 +39,10 @@ } - + -

    Java instanceof关键字用法

    沉默王二2021年10月22日
    • Java核心
    • Java
    大约 3 分钟

    Java instanceof关键字用法

    instanceof 关键字的用法其实很简单:

    (object) instanceof (type)
    +    

    Java instanceof关键字用法

    沉默王二2021年10月22日
    • Java核心
    • Java
    大约 3 分钟

    Java instanceof关键字用法

    instanceof 关键字的用法其实很简单:

    (object) instanceof (type)
     

    用意也非常简单,判断对象是否符合指定的类型,结果要么是 true,要么是 false。在反序列化的时候,instanceof 操作符还是蛮常用的,因为这时候我们不太确定对象属不属于指定的类型,如果不进行判断的话,就容易抛出 ClassCastException 异常。

    我们来建这样一个简单的类 Round:

    class Round {
     }
     

    然后新增一个扩展类 Ring:

    class Ring extends Round {
    @@ -74,6 +74,6 @@
         // 如果类型匹配 直接使用 s
     }
     

    可以直接在 if 条件判断类型的时候添加一个变量,就不需要再强转和声明新的变量了。

    “哇,这样就简洁了呀!”三妹不仅惊叹到!

    好了,关于 instanceof 操作符我们就先讲到这吧,难是一点都不难,希望各位同学也能够很好的掌握。

    - + diff --git a/dist/oo/interface.html b/dist/oo/interface.html index 519d3c6d..2c849825 100644 --- a/dist/oo/interface.html +++ b/dist/oo/interface.html @@ -39,10 +39,10 @@ } - + -

    Java接口

    沉默王二2021年10月22日
    • Java核心
    • Java
    大约 9 分钟

    Java接口

    “哥,我看你朋友圈说《Java 程序员进阶之路》专栏收到了第一笔赞赏呀,虽然只有一块钱,但我也替你感到开心。”三妹的脸上洋溢着自信的微笑,仿佛这钱是打给她的一样。

    “是啊,早上起来的时候看到这条信息,还真的是挺开心的,虽然只有一块钱,但是开源的第一笔,也是我人生当中的第一笔,真的非常感谢这个读者,值得纪念的一天。”我自己也掩饰不住内心的激动。

    “有了这份鼓励,我相信你更新下去的动力更足了!”三妹今天说的话真的是特别令人喜欢。

    “是啊是啊,所以,今天要更新第 26 讲了——接口。”我接着说,“对于面向对象编程来说,抽象是一个极具魅力的特征。如果一个程序员的抽象思维很差,那他在编程中就会遇到很多困难,无法把业务变成具体的代码。在 Java 中,可以通过两种形式来达到抽象的目的,一种上一篇的主角——抽象类open in new window,另外一种就是今天的主角——接口。”


    “接口是什么呀?”三妹顺着我的话题及时的插话到。

    接口通过 interface 关键字来定义,它可以包含一些常量和方法,来看下面这个示例。

    public interface Electronic {
    +    

    Java接口

    沉默王二2021年10月22日
    • Java核心
    • Java
    大约 9 分钟

    Java接口

    “哥,我看你朋友圈说《Java 程序员进阶之路》专栏收到了第一笔赞赏呀,虽然只有一块钱,但我也替你感到开心。”三妹的脸上洋溢着自信的微笑,仿佛这钱是打给她的一样。

    “是啊,早上起来的时候看到这条信息,还真的是挺开心的,虽然只有一块钱,但是开源的第一笔,也是我人生当中的第一笔,真的非常感谢这个读者,值得纪念的一天。”我自己也掩饰不住内心的激动。

    “有了这份鼓励,我相信你更新下去的动力更足了!”三妹今天说的话真的是特别令人喜欢。

    “是啊是啊,所以,今天要更新第 26 讲了——接口。”我接着说,“对于面向对象编程来说,抽象是一个极具魅力的特征。如果一个程序员的抽象思维很差,那他在编程中就会遇到很多困难,无法把业务变成具体的代码。在 Java 中,可以通过两种形式来达到抽象的目的,一种上一篇的主角——抽象类open in new window,另外一种就是今天的主角——接口。”


    “接口是什么呀?”三妹顺着我的话题及时的插话到。

    接口通过 interface 关键字来定义,它可以包含一些常量和方法,来看下面这个示例。

    public interface Electronic {
         // 常量
         String LED = "LED";
     
    @@ -162,6 +162,6 @@ shapes.add

    这就实现了多态,变量 circleShape、squareShape 的引用类型都是 Shape,但执行 shape.name() 方法的时候,Java 虚拟机知道该去调用 Circle 的 name() 方法还是 Square 的 name() 方法。

    说一下多态存在的 3 个前提:

    1、要有继承关系,比如说 Circle 和 Square 都实现了 Shape 接口。 2、子类要重写父类的方法,Circle 和 Square 都重写了 name() 方法。 3、父类引用指向子类对象,circleShape 和 squareShape 的类型都为 Shape,但前者指向的是 Circle 对象,后者指向的是 Square 对象。

    然后,我们来看一下测试结果:

    圆
     正方形
     

    也就意味着,尽管在 for 循环中,shape 的类型都为 Shape,但在调用 name() 方法的时候,它知道 Circle 对象应该调用 Circle 类的 name() 方法,Square 对象应该调用 Square 类的 name() 方法。

    “哦,我理解了哥。那我再问一下,抽象类和接口有什么差别呢?”

    “哇,三妹呀,你这个问题恰到好处,问到了点子上。”我不由得为三妹竖起了大拇指。

    1)语法层面上

    • 接口中不能有 private 和 protected 修饰的方法,抽象类中可以有。
    • 接口中的变量只能是隐式的常量,抽象类中可以有任意类型的变量。
    • 一个类只能继承一个抽象类,但却可以实现多个接口。

    2)设计层面上

    抽象类是对类的一种抽象,继承抽象类的子类和抽象类本身是一种 is-a 的关系。

    接口是对类的某种行为的一种抽象,接口和类之间并没有很强的关联关系,举个例子来说,所有的类都可以实现 Serializable 接口,从而具有序列化的功能,但不能说所有的类和 Serializable 之间是 is-a 的关系。

    - + diff --git a/dist/oo/method.html b/dist/oo/method.html index 50df71b5..9e53fd72 100644 --- a/dist/oo/method.html +++ b/dist/oo/method.html @@ -39,10 +39,10 @@ } - + -

    Java方法

    沉默王二2021年10月22日
    • Java核心
    • Java
    大约 6 分钟

    Java方法

    “二哥,上一节open in new window学了对象和类,这一节我们学什么呢?”三妹满是期待的问我。

    “这一节我们来了解一下 Java 中的方法——什么是方法?如何声明方法?方法有哪几种?什么是实例方法?什么是抽象方法?”我笑着对三妹说,“我开始了啊,你不要闪啊。”

    01、Java 中的方法是什么?

    方法用来实现代码的可重用性,我们编写一次方法,并多次使用它。通过增加或者删除方法中的一部分代码,就可以提高整体代码的可读性。

    只有方法被调用时,它才会执行。Java 中最有名的方法当属 main() 方法,点击下面的链接可以阅读更多关于 main() 方法的知识点。

    零基础学 Java 第 4 讲:Hello Worldopen in new window

    02、如何声明方法?

    方法的声明反映了方法的一些信息,比如说可见性、返回类型、方法名和参数。如下图所示。

    访问权限:它指定了方法的可见性。Java 提供了四种访问权限修饰符:

    • public:该方法可以被所有类访问。
    • private:该方法只能在定义它的类中访问。
    • protected:该方法可以被同一个包中的类,或者不同包中的子类访问。
    • default:该方法如果没有使用任何访问权限修饰符,Java 默认它使用 default 修饰符,该方法只能被同一个包中类可见。

    返回类型:方法返回的数据类型,可以是基本数据类型、对象和集合,如果不需要返回数据,则使用 void 关键字。

    方法名:方法名最好反应出方法的功能,比如,我们要创建一个将两个数字相减的方法,那么方法名最好是 subtract。

    方法名最好是一个动词,并且以小写字母开头。如果方法名包含两个以上单词,那么第一个单词最好是动词,然后是形容词或者名词,并且要以驼峰式的命名方式命名。比如:

    • 一个单词的方法名:sum()
    • 多个单词的方法名:stringComparision()

    一个方法可能与同一个类中的另外一个方法同名,这被称为方法重载。

    参数:参数被放在一个圆括号内,如果有多个参数,可以使用逗号隔开。参数包含两个部分,参数类型和参数名。如果方法没有参数,圆括号是空的。

    方法签名:每一个方法都有一个签名,包括方法名和参数。

    方法体:方法体放在一对花括号内,把一些代码放在一起,用来执行特定的任务。

    02、方法有哪几种?

    方法可以分为两种,一种叫预先定义方法,一种叫用户自定义方法。

    1)预先定义方法

    Java 提供了大量预先定义好的方法供我们调用,也称为标准类库方法,或者内置方法。比如说 String 类的 length()equals()compare() 方法,以及我们在初学 Java 阶段最常用的 println() 方法,用来在控制台打印信息。

    /**
    +    

    Java方法

    沉默王二2021年10月22日
    • Java核心
    • Java
    大约 6 分钟

    Java方法

    “二哥,上一节open in new window学了对象和类,这一节我们学什么呢?”三妹满是期待的问我。

    “这一节我们来了解一下 Java 中的方法——什么是方法?如何声明方法?方法有哪几种?什么是实例方法?什么是抽象方法?”我笑着对三妹说,“我开始了啊,你不要闪啊。”

    01、Java 中的方法是什么?

    方法用来实现代码的可重用性,我们编写一次方法,并多次使用它。通过增加或者删除方法中的一部分代码,就可以提高整体代码的可读性。

    只有方法被调用时,它才会执行。Java 中最有名的方法当属 main() 方法,点击下面的链接可以阅读更多关于 main() 方法的知识点。

    零基础学 Java 第 4 讲:Hello Worldopen in new window

    02、如何声明方法?

    方法的声明反映了方法的一些信息,比如说可见性、返回类型、方法名和参数。如下图所示。

    访问权限:它指定了方法的可见性。Java 提供了四种访问权限修饰符:

    • public:该方法可以被所有类访问。
    • private:该方法只能在定义它的类中访问。
    • protected:该方法可以被同一个包中的类,或者不同包中的子类访问。
    • default:该方法如果没有使用任何访问权限修饰符,Java 默认它使用 default 修饰符,该方法只能被同一个包中类可见。

    返回类型:方法返回的数据类型,可以是基本数据类型、对象和集合,如果不需要返回数据,则使用 void 关键字。

    方法名:方法名最好反应出方法的功能,比如,我们要创建一个将两个数字相减的方法,那么方法名最好是 subtract。

    方法名最好是一个动词,并且以小写字母开头。如果方法名包含两个以上单词,那么第一个单词最好是动词,然后是形容词或者名词,并且要以驼峰式的命名方式命名。比如:

    • 一个单词的方法名:sum()
    • 多个单词的方法名:stringComparision()

    一个方法可能与同一个类中的另外一个方法同名,这被称为方法重载。

    参数:参数被放在一个圆括号内,如果有多个参数,可以使用逗号隔开。参数包含两个部分,参数类型和参数名。如果方法没有参数,圆括号是空的。

    方法签名:每一个方法都有一个签名,包括方法名和参数。

    方法体:方法体放在一对花括号内,把一些代码放在一起,用来执行特定的任务。

    02、方法有哪几种?

    方法可以分为两种,一种叫预先定义方法,一种叫用户自定义方法。

    1)预先定义方法

    Java 提供了大量预先定义好的方法供我们调用,也称为标准类库方法,或者内置方法。比如说 String 类的 length()equals()compare() 方法,以及我们在初学 Java 阶段最常用的 println() 方法,用来在控制台打印信息。

    /**
      * @author 微信搜「沉默王二」,回复关键字 PDF
      */
     public class PredefinedMethodDemo {
    @@ -141,6 +141,6 @@
     }
     

    输出结果如下所示:

    重写了抽象方法
     

    - + diff --git a/dist/oo/object-class.html b/dist/oo/object-class.html index 13619a52..58e4ce65 100644 --- a/dist/oo/object-class.html +++ b/dist/oo/object-class.html @@ -39,10 +39,10 @@ } - + -

    怎么理解Java中类和对象的概念?

    沉默王二2021年10月22日
    • Java核心
    • Java
    大约 10 分钟

    怎么理解Java中类和对象的概念?

    “二哥,我那天在图书馆复习上一节open in new window你讲的内容,刚好碰见一个学长,他问我有没有‘对象’,我说还没有啊。结果你猜他说什么,‘要不要我给你 new 一个啊?’我当时就懵了,new 是啥意思啊,二哥?”三妹满是疑惑的问我。

    “哈哈,三妹,你学长还挺幽默啊。new 是 Java 中的一个关键字,用来把类变成对象。”我笑着对三妹说,“对象和类是 Java 中最基本的两个概念,可以说撑起了面向对象编程(OOP)的一片天。”

    01、面向过程和面向对象

    三妹是不是要问,什么是 OOP?

    OOP 的英文全称是 Object Oriented Programming,要理解它的话,就要先理解面向对象,要想理解面向对象的话,就要先理解面向过程,因为一开始没有面向对象的编程语言,都是面向过程。

    举个简单点的例子来区分一下面向过程和面向对象。

    有一天,你想吃小碗汤了,怎么办呢?有两个选择:

    1)自己买食材,豆腐皮啊、肉啊、蒜苔啊等等,自己动手做。

    2)到饭店去,只需要对老板喊一声,“来份小碗汤。”

    第一种就是面向过程,第二种就是面向对象。

    面向过程有什么劣势呢?假如你买了小碗汤的食材,临了又想吃宫保鸡丁了,你是不是还得重新买食材?

    面向对象有什么优势呢?假如你不想吃小碗汤了,你只需要对老板说,“我那个小碗汤如果没做的话,换成宫保鸡丁吧!”

    面向过程是流程化的,一步一步,上一步做完了,再做下一步。

    面向对象是模块化的,我做我的,你做你的,我需要你做的话,我就告诉你一声。我不需要知道你到底怎么做,只看功劳不看苦劳。

    不过,如果追到底的话,面向对象的底层其实还是面向过程,只不过把面向过程进行了抽象化,封装成了类,方便我们的调用。

    02、类

    对象可以是现实中看得见的任何物体,比如说,一只特立独行的猪;也可以是想象中的任何虚拟物体,比如说能七十二变的孙悟空。

    Java 通过类(class)来定义这些物体,这些物体有什么状态,通过字段来定义,比如说比如说猪的颜色是纯色还是花色;这些物体有什么行为,通过方法来定义,比如说猪会吃,会睡觉。

    来,定义一个简单的类给你看看。

    /**
    +    

    怎么理解Java中类和对象的概念?

    沉默王二2021年10月22日
    • Java核心
    • Java
    大约 10 分钟

    怎么理解Java中类和对象的概念?

    “二哥,我那天在图书馆复习上一节open in new window你讲的内容,刚好碰见一个学长,他问我有没有‘对象’,我说还没有啊。结果你猜他说什么,‘要不要我给你 new 一个啊?’我当时就懵了,new 是啥意思啊,二哥?”三妹满是疑惑的问我。

    “哈哈,三妹,你学长还挺幽默啊。new 是 Java 中的一个关键字,用来把类变成对象。”我笑着对三妹说,“对象和类是 Java 中最基本的两个概念,可以说撑起了面向对象编程(OOP)的一片天。”

    01、面向过程和面向对象

    三妹是不是要问,什么是 OOP?

    OOP 的英文全称是 Object Oriented Programming,要理解它的话,就要先理解面向对象,要想理解面向对象的话,就要先理解面向过程,因为一开始没有面向对象的编程语言,都是面向过程。

    举个简单点的例子来区分一下面向过程和面向对象。

    有一天,你想吃小碗汤了,怎么办呢?有两个选择:

    1)自己买食材,豆腐皮啊、肉啊、蒜苔啊等等,自己动手做。

    2)到饭店去,只需要对老板喊一声,“来份小碗汤。”

    第一种就是面向过程,第二种就是面向对象。

    面向过程有什么劣势呢?假如你买了小碗汤的食材,临了又想吃宫保鸡丁了,你是不是还得重新买食材?

    面向对象有什么优势呢?假如你不想吃小碗汤了,你只需要对老板说,“我那个小碗汤如果没做的话,换成宫保鸡丁吧!”

    面向过程是流程化的,一步一步,上一步做完了,再做下一步。

    面向对象是模块化的,我做我的,你做你的,我需要你做的话,我就告诉你一声。我不需要知道你到底怎么做,只看功劳不看苦劳。

    不过,如果追到底的话,面向对象的底层其实还是面向过程,只不过把面向过程进行了抽象化,封装成了类,方便我们的调用。

    02、类

    对象可以是现实中看得见的任何物体,比如说,一只特立独行的猪;也可以是想象中的任何虚拟物体,比如说能七十二变的孙悟空。

    Java 通过类(class)来定义这些物体,这些物体有什么状态,通过字段来定义,比如说比如说猪的颜色是纯色还是花色;这些物体有什么行为,通过方法来定义,比如说猪会吃,会睡觉。

    来,定义一个简单的类给你看看。

    /**
      * 微信搜索「沉默王二」,回复 Java
      *
      * @author 沉默王二
    @@ -221,6 +221,6 @@
     

    运行结果:

    线
     圆形
     

    在测试类中,shape1 的类型为 Shape,shape2 的类型也为 Shape,但调用 draw() 方法后,却能自动调用子类 Line 和 Circle 的 draw() 方法,这是为什么呢?

    其实就是 Java 中的多态。


    更多 Java 对象和类的知识,请移步下一篇。

    - + diff --git a/dist/oo/static.html b/dist/oo/static.html index 6935a262..0f9517b9 100644 --- a/dist/oo/static.html +++ b/dist/oo/static.html @@ -39,10 +39,10 @@ } - + -

    Java中的static关键字解析

    沉默王二2021年10月22日
    • Java核心
    • Java
    大约 10 分钟

    Java中的static关键字解析

    “哥,你牙龈肿痛轻点没?周一的教妹学 Java 你都没有更新,偷懒了呀!”三妹关心地问我。

    “今天周四了,吃了三天的药,疼痛已经减轻不少,咱妈还给我打了电话,让我买点牛黄解毒片下下火。”我面带着微笑对三妹说,“学习可不能落下,今天我们来学 Java 中 static 关键字吧。”

    “static 是 Java 中比较难以理解的一个关键字,也是各大公司的面试官最喜欢问到的一个知识点之一。”我喝了一口咖啡继续说道。

    “既然是面试重点,那我可得好好学习下。”三妹连忙说。

    “static 关键字的作用可以用一句话来描述:‘方便在没有创建对象的情况下进行调用,包括变量和方法’。也就是说,只要类被加载了,就可以通过类名进行访问。”我扶了扶沉重眼镜,继续说到,“static 可以用来修饰类的成员变量,以及成员方法。我们一个个来看。”

    01、静态变量

    “如果在声明变量的时候使用了 static 关键字,那么这个变量就被称为静态变量。静态变量只在类加载的时候获取一次内存空间,这使得静态变量很节省内存空间。”家里的暖气有点足,我跑去开了一点窗户后继续说道。

    “来考虑这样一个 Student 类。”话音刚落,我就在键盘上噼里啪啦一阵敲。

    public class Student {
    +    

    Java中的static关键字解析

    沉默王二2021年10月22日
    • Java核心
    • Java
    大约 10 分钟

    Java中的static关键字解析

    “哥,你牙龈肿痛轻点没?周一的教妹学 Java 你都没有更新,偷懒了呀!”三妹关心地问我。

    “今天周四了,吃了三天的药,疼痛已经减轻不少,咱妈还给我打了电话,让我买点牛黄解毒片下下火。”我面带着微笑对三妹说,“学习可不能落下,今天我们来学 Java 中 static 关键字吧。”

    “static 是 Java 中比较难以理解的一个关键字,也是各大公司的面试官最喜欢问到的一个知识点之一。”我喝了一口咖啡继续说道。

    “既然是面试重点,那我可得好好学习下。”三妹连忙说。

    “static 关键字的作用可以用一句话来描述:‘方便在没有创建对象的情况下进行调用,包括变量和方法’。也就是说,只要类被加载了,就可以通过类名进行访问。”我扶了扶沉重眼镜,继续说到,“static 可以用来修饰类的成员变量,以及成员方法。我们一个个来看。”

    01、静态变量

    “如果在声明变量的时候使用了 static 关键字,那么这个变量就被称为静态变量。静态变量只在类加载的时候获取一次内存空间,这使得静态变量很节省内存空间。”家里的暖气有点足,我跑去开了一点窗户后继续说道。

    “来考虑这样一个 Student 类。”话音刚落,我就在键盘上噼里啪啦一阵敲。

    public class Student {
         String name;
         int age;
         String school = "郑州大学";
    @@ -172,6 +172,6 @@ main 方法
         }
     }
     

    “三妹,打起精神,马上就结束了。”

    “哦哦,这段代码看起来很别致啊,哥。”

    “是的,三妹,这段代码在以后创建单例的时候还会见到。”

    “第一次加载 Singleton 类时并不会初始化 instance,只有第一次调用 getInstance() 方法时 Java 虚拟机才开始加载 SingletonHolder 并初始化 instance,这样不仅能确保线程安全,也能保证 Singleton 类的唯一性。不过,创建单例更优雅的一种方式是使用枚举,以后再讲给你听。”

    “需要注意的是。第一,静态内部类不能访问外部类的所有成员变量;第二,静态内部类可以访问外部类的所有静态变量,包括私有静态变量。第三,外部类不能声明为 static。”

    “三妹,你看,在 Singleton 类上加 static 后,编译器就提示错误了。”

    三妹点了点头,所有所思。

    - + diff --git a/dist/oo/this-super.html b/dist/oo/this-super.html index 58bef14b..42cc1a39 100644 --- a/dist/oo/this-super.html +++ b/dist/oo/this-super.html @@ -39,10 +39,10 @@ } - + -

    Java中this和super的用法总结

    沉默王二2021年10月22日
    • Java核心
    • Java
    大约 10 分钟

    Java中this和super的用法总结

    “哥,被喊大舅子的感觉怎么样啊?”三妹不怀好意地对我说,她眼睛里充满着不屑。

    “说实话,这种感觉还不错。”我有点难为情的回答她,“不过,有一点令我感到些许失落。大家的焦点似乎都是你的颜值,完全忽略了我的盛世美颜啊!”

    “哥,你想啥呢,那是因为你文章写得好,不然谁认识我是谁啊!有你这样的哥哥,我还是挺自豪的。”三妹郑重其事地说,“话说今天咱学啥呢?”

    “三妹啊,你这句话说得我喜欢。今天来学习一下 Java 中的 this 关键字吧。”喝了一口农夫山泉后,我对三妹说。

    “this 关键字有很多种用法,其中最常用的一个是,它可以作为引用变量,指向当前对象。”我面带着朴实无华的微笑继续说,“除此之外, this 关键字还可以完成以下工作。”

    • 调用当前类的方法;
    • this() 可以调用当前类的构造方法;
    • this 可以作为参数在方法中传递;
    • this 可以作为参数在构造方法中传递;
    • this 可以作为方法的返回值,返回当前类的对象。

    01、 指向当前对象

    “三妹,来看下面这段代码。”话音刚落,我就在键盘上噼里啪啦一阵敲。

    public class WithoutThisStudent {
    +    

    Java中this和super的用法总结

    沉默王二2021年10月22日
    • Java核心
    • Java
    大约 10 分钟

    Java中this和super的用法总结

    “哥,被喊大舅子的感觉怎么样啊?”三妹不怀好意地对我说,她眼睛里充满着不屑。

    “说实话,这种感觉还不错。”我有点难为情的回答她,“不过,有一点令我感到些许失落。大家的焦点似乎都是你的颜值,完全忽略了我的盛世美颜啊!”

    “哥,你想啥呢,那是因为你文章写得好,不然谁认识我是谁啊!有你这样的哥哥,我还是挺自豪的。”三妹郑重其事地说,“话说今天咱学啥呢?”

    “三妹啊,你这句话说得我喜欢。今天来学习一下 Java 中的 this 关键字吧。”喝了一口农夫山泉后,我对三妹说。

    “this 关键字有很多种用法,其中最常用的一个是,它可以作为引用变量,指向当前对象。”我面带着朴实无华的微笑继续说,“除此之外, this 关键字还可以完成以下工作。”

    • 调用当前类的方法;
    • this() 可以调用当前类的构造方法;
    • this 可以作为参数在方法中传递;
    • this 可以作为参数在构造方法中传递;
    • this 可以作为方法的返回值,返回当前类的对象。

    01、 指向当前对象

    “三妹,来看下面这段代码。”话音刚落,我就在键盘上噼里啪啦一阵敲。

    public class WithoutThisStudent {
         String name;
         int age;
     
    @@ -316,6 +316,6 @@ com.itwanger.twentyseven.ThisAsParam@77459877
     }
     

    “Emp 类继承了 Person 类,也就继承了 id 和 name 字段,当在 Emp 中新增了 salary 字段后,构造方法中就可以使用 super(id, name) 来调用父类的有参构造方法。”

    “来看一下输出结果。”

    1 沉默王二 20000.0
     

    三妹点了点头,所有所思。

    - + diff --git a/dist/oo/var.html b/dist/oo/var.html index eb239a23..55f49faf 100644 --- a/dist/oo/var.html +++ b/dist/oo/var.html @@ -39,10 +39,10 @@ } - + -

    Java变量的作用域:局部变量、成员变量、静态变量、常量

    沉默王二2021年10月22日
    • Java核心
    • Java
    大约 5 分钟

    Java变量的作用域:局部变量、成员变量、静态变量、常量

    “二哥,听说 Java 变量在以后的日子里经常用,能不能提前给我透露透露?”三妹咪了一口麦香可可奶茶后对我说。

    “三妹啊,搬个凳子坐我旁边,听二哥来给你慢慢说啊。”

    Java 变量就好像一个容器,可以保存程序在运行过程中的值,它在声明的时候会定义对应的数据类型(Java 分为两种数据类型:基本数据类型和引用数据类型)。变量按照作用域的范围又可分为三种类型:局部变量,成员变量和静态变量。

    比如说,int data = 88;,其中 data 就是一个变量,它的值为 88,类型为整型(int)。

    01、局部变量

    在方法体内声明的变量被称为局部变量,该变量只能在该方法内使用,类中的其他方法并不知道该变量。来看下面这个示例:

    /**
    +    

    Java变量的作用域:局部变量、成员变量、静态变量、常量

    沉默王二2021年10月22日
    • Java核心
    • Java
    大约 5 分钟

    Java变量的作用域:局部变量、成员变量、静态变量、常量

    “二哥,听说 Java 变量在以后的日子里经常用,能不能提前给我透露透露?”三妹咪了一口麦香可可奶茶后对我说。

    “三妹啊,搬个凳子坐我旁边,听二哥来给你慢慢说啊。”

    Java 变量就好像一个容器,可以保存程序在运行过程中的值,它在声明的时候会定义对应的数据类型(Java 分为两种数据类型:基本数据类型和引用数据类型)。变量按照作用域的范围又可分为三种类型:局部变量,成员变量和静态变量。

    比如说,int data = 88;,其中 data 就是一个变量,它的值为 88,类型为整型(int)。

    01、局部变量

    在方法体内声明的变量被称为局部变量,该变量只能在该方法内使用,类中的其他方法并不知道该变量。来看下面这个示例:

    /**
      * @author 微信搜「沉默王二」,回复关键字 PDF
      */
     public class LocalVariable {
    @@ -86,6 +86,6 @@
         }
     }
     

    “好了,三妹,关于 Java 变量就先说这么多吧,你是不是已经清楚了?”转动了一下僵硬的脖子后,我对三妹说。

    “是啊,二哥,我想以后还会再见到它们吧?”

    “那见的次数可就多了,就好像你每天眨眼的次数一样多。”

    - + diff --git a/dist/overview/hello-world.html b/dist/overview/hello-world.html index 460107a2..b4c7faab 100644 --- a/dist/overview/hello-world.html +++ b/dist/overview/hello-world.html @@ -39,10 +39,10 @@ } - + -

    第一个Java程序:Hello World

    沉默王二2019年1月1日
    • Java核心
    • Java
    大约 7 分钟

    第一个Java程序:Hello World

    一、安装集成开发环境Intellij IDEA

    IntelliJ IDEA 简称 IDEA,是业界公认为最好的 Java 集成开发工具,尤其是在代码自动提示、代码重构、代码版本管理、单元测试、代码分析等方面有着亮眼的发挥。

    IDEA 产于捷克,开发人员以严谨著称的东欧程序员为主,分为社区版和付费版两个版本。我们在学习阶段,社区版就足够用了。

    回想起我最初学 Java 的时候,老师要求我们在记事本上敲代码,在命令行中编译和执行 Java 代码,搞得全班三分之二的同学都做好了放弃学习 Java 的打算。

    鉴于此,我强烈推荐大家使用集成开发工具,比如说 IntelliJ IDEA 来学习。

    IDEA 分为社区版和付费版两个版本。

    01、下载 IDEA

    IntelliJ IDEA 的官方下载地址为:https://www.jetbrains.com/idea/download/open in new window

    UItimate 为付费版,可以免费试用,主要针对的是 Web 和企业开发用户;Community 为免费版,可以免费使用,主要针对的是 Java 初学者和安卓开发用户。

    功能上的差别如下图所示。

    本篇教程主要针对的是 Java 初学者,所以选择免费版为例,点击「Download」进行下载。

    稍等一分钟时间,大概 580M。

    02、安装 IDEA

    双击运行 IDEA 安装程序,一步步傻瓜式的下一步就行了。

    为了方便启动 IDEA,可以勾选【64-bit launcher】复选框。为了关联 Java 源文件,可以勾选【.java】复选框。

    点击【Install】后,需要静静地等待一会,大概一分钟的时间,趁机休息一下眼睛。

    安装完成后的界面如下图所示。

    03、启动 IDEA

    回到桌面,双击运行 IDEA 的快捷方式,启动 IDEA。

    假装阅读完条款后,勾选同意复选框,点击【Continue】

    如果想要帮助 IDEA 收集改进信息,可以点击【Send Usage Statistics】;否则点击【Don't send】。

    到此,Intellij IDEA 的安装就完成了,很简单。

    二、Hello World

    第一个 Java 程序非常简单,代码如下:

    /**
    +    

    第一个Java程序:Hello World

    沉默王二2019年1月1日
    • Java核心
    • Java
    大约 7 分钟

    第一个Java程序:Hello World

    一、安装集成开发环境Intellij IDEA

    IntelliJ IDEA 简称 IDEA,是业界公认为最好的 Java 集成开发工具,尤其是在代码自动提示、代码重构、代码版本管理、单元测试、代码分析等方面有着亮眼的发挥。

    IDEA 产于捷克,开发人员以严谨著称的东欧程序员为主,分为社区版和付费版两个版本。我们在学习阶段,社区版就足够用了。

    回想起我最初学 Java 的时候,老师要求我们在记事本上敲代码,在命令行中编译和执行 Java 代码,搞得全班三分之二的同学都做好了放弃学习 Java 的打算。

    鉴于此,我强烈推荐大家使用集成开发工具,比如说 IntelliJ IDEA 来学习。

    IDEA 分为社区版和付费版两个版本。

    01、下载 IDEA

    IntelliJ IDEA 的官方下载地址为:https://www.jetbrains.com/idea/download/open in new window

    UItimate 为付费版,可以免费试用,主要针对的是 Web 和企业开发用户;Community 为免费版,可以免费使用,主要针对的是 Java 初学者和安卓开发用户。

    功能上的差别如下图所示。

    本篇教程主要针对的是 Java 初学者,所以选择免费版为例,点击「Download」进行下载。

    稍等一分钟时间,大概 580M。

    02、安装 IDEA

    双击运行 IDEA 安装程序,一步步傻瓜式的下一步就行了。

    为了方便启动 IDEA,可以勾选【64-bit launcher】复选框。为了关联 Java 源文件,可以勾选【.java】复选框。

    点击【Install】后,需要静静地等待一会,大概一分钟的时间,趁机休息一下眼睛。

    安装完成后的界面如下图所示。

    03、启动 IDEA

    回到桌面,双击运行 IDEA 的快捷方式,启动 IDEA。

    假装阅读完条款后,勾选同意复选框,点击【Continue】

    如果想要帮助 IDEA 收集改进信息,可以点击【Send Usage Statistics】;否则点击【Don't send】。

    到此,Intellij IDEA 的安装就完成了,很简单。

    二、Hello World

    第一个 Java 程序非常简单,代码如下:

    /**
      * @author 微信搜「沉默王二」,回复关键字 PDF
      */
     public class HelloWorld {
    @@ -52,6 +52,6 @@
     }
     

    IDEA 会自动保存,在代码编辑面板中右键,在弹出的菜单中选择「Run 'HelloWorld.main()'」,如下图所示:

    等代码编译结束后,就可以在 Run 面板里看到下面的内容:

    三妹,少看手机少打游戏,好好学,美美哒。
     

    “二哥,上面这段代码的输出结果虽然令我非常开心,但是有好多生疏的关键字令我感到困惑,能给我解释一下吗?”

    “当然没问题啊。”

    • class 关键字:用于在 Java 中声明一个类。

    • public 关键字:一个表示可见性的访问修饰符。

    • static 关键字:我们可以用它来声明任何一个方法,被 static 修饰后的方法称之为静态方法。静态方法不需要为其创建对象就能调用。

    • void 关键字:表示该方法不返回任何值。

    • main 关键字:表示该方法为主方法,也就是程序运行的入口。main() 方法由 Java 虚拟机执行,配合上 static 关键字后,可以不用创建对象就可以调用,可以节省不少内存空间。

    • String [] argsmain() 方法的参数,类型为 String 数组,参数名为 args。

    • System.out.println():一个 Java 语句,一般情况下是将传递的参数打印到控制台。System 是 java.lang 包中的一个 final 类,该类提供的设施包括标准输入,标准输出和错误输出流等等。out 是 System 类的静态成员字段,类型为 PrintStream,它与主机的标准输出控制台进行映射。println 是 PrintStream 类的一个方法,通过调用 print 方法并添加一个换行符实现的。

    三、JDK和JRE有什么区别?

    01、JDK

    JDK 是 Java Development Kit 的首字母缩写,是提供给 Java 程序员的开发工具包,换句话说,没有 JDK,Java 程序员就无法使用 Java 语言编写 Java 程序。也就是说,JDK 是用于开发 Java 程序的最小环境。

    想要成为一名 Java 程序员,首先就需要在电脑上安装 JDK。当然了,新版的 Intellij IDEA(公认最好用的集成开发环境)已经支持直接下载 JDK 了。

    并且支持下载不同版本的 JDK,除了 Oracle 的 OpenJDK,还有社区维护版 AdoptOpenJDK,里面包含了目前使用范围最广的 HotSpot 虚拟机。

    如果下载比较慢的话,可以直接在 AdoptOpenJDK 官网上下载。

    如果还是比较慢的话,通过 Oracle 官网下载吧!

    https://www.oracle.com/java/technologies/javase-jdk11-downloads.html

    JDK 安装成功后,就可以编写 Java 代码了,小伙伴们可以参照上一篇文章《Hello Worldopen in new window》。

    JDK 包含了 JRE,同时还包含了编译 Java 源码的编译器 javac,以及其他的一些重要工具:

    • keytool:用于操作 keystore 密钥;
    • javap:class 类文件的最基础的反编译器;
    • jstack:用于打印 Java 线程栈踪迹的工具;
    • jconsole:用于监视 Java 程序的工具;
    • jhat:用于 Java 堆分析的工具
    • jar:用于打包 Java 程序的工具;
    • javadoc:用于生成 Java 文档的工具;

    02、JRE

    JRE 是 Java Runtime Environment 的首字母缩写,是提供给 Java 程序运行的最小环境,换句话说,没有 JRE,Java 程序就无法运行。

    Java 程序运行的正式环境一般会选择 Linux 服务器,因为更安全、更高效、更稳定。我们只需要在 Linux 服务器上安装 JRE 就可以运行 Java 程序,而不必安装 JDK,因为我们不需要在服务器上编译和调试 Java 源代码。

    刚好我有一台闲置的阿里云服务器,这里就给小伙伴们演示一下 JRE 的安装过程。

    第一步:使用以下命令列出服务器上可以安装的 Java 环境:

    yum list java*

    可以看到有这么一些(只列出 Java 11 的部分——最近一个 LTS 版本):

    其中 JRE 为 java-11-openjdk.x86_64,JDK 为 java-11-openjdk-devel.x86_64。

    第二步,使用以下命令安装 JRE:

    yum install java-11-openjdk.x86_64

    第三步,使用以下命令测试是否安装成功:

    java -version

    如果出现以下结果,则表明安装成功:

    由于 JRE 中不包含 javac,所以 javac -version 的结果如下所示:

    那既然服务器上的 JRE 环境已经 OK 了,那我们就把之前的“Hello World”程序打成 jar 上传过去,让它跑起来。

    第一步,Maven clean(对项目清理):

    第二步,Maven package(对项目打包):

    可以在 Run 面板中看到以下信息:

    说明项目打包成功了。

    第三步,使用 FileZilla 工具将 jar 包上传到服务器指定目录。

    第四步,使用 iTerm2 工具连接服务器。

    第五步,执行以下命令:

    java -cp TechSister-1.0-SNAPSHOT.jar com.itwanger.five.HelloWorld

    可以看到以下结果:

    “搞定了,三妹,今天我们就学到这吧。”转动了一下僵硬的脖子后,我对三妹说,“开发环境需要安装 JDK,因为既需要编写源代码,还需要打包和测试;生产环境只需要安装 JRE,因为只需要运行编译打包好的 jar 包即可。”

    - + diff --git a/dist/overview/what-is-java.html b/dist/overview/what-is-java.html index 4ab2e75f..ccbcd591 100644 --- a/dist/overview/what-is-java.html +++ b/dist/overview/what-is-java.html @@ -39,15 +39,15 @@ } - + -

    什么是Java?

    沉默王二2021年7月30日
    • Java核心
    • Java
    大约 15 分钟

    什么是Java?

    01、什么是 Java?

    “二哥,到底什么是 Java?给我说说呗。”

    “三妹啊,这就直奔主题了啊,先去给哥买包烟吧,哥先考验考验你的诚心。”

    (五分钟过后)

    “三妹啊,你怎么还不去?”

    “二哥,掏钱啊。”

    (真实亲妹子啊,买包烟还得我掏钱,关键是还得给跑腿费。十分钟后,三妹从楼下小卖部买了一包熊猫回来了,我用 Zippo 火机点了一支——这火机是 21 岁生日的时候初恋女友送我的,质量确实不错,现在还在用。)

    “三妹啊,听我慢慢来给你解释。”

    Java 是一门计算机编程语言,高级、健壮、面向对象,并且非常安全。它由 Sun 公司在 1995 年开发,主力开发叫 James Gosling,被称为 Java 之父,就是下图这位,头秃的厉害。

    “三妹啊,你要不要再考虑考虑?做程序员不容易啊”

    “二哥,你咋没有秃呢?是因为你不够厉害吗?”

    (这孩子,嘴咋这么损呢?)

    Java 在叫“Java”之前,其实叫 Oak(橡树的意思,我感觉好像比 Java 好听一些)。怎么想到呢?James Gosling 坐在办公室,望向窗外,视野里出现了一颗橡树。不过,遗憾的是,Oak 已经被 另外一家公司注册了,因此 1995 年 5 月 23 日,Oak 语言改名为 Java。

    Java 起初并不是 James Gosling 的首选,也不是命名团队的首选。团队其他人员更青睐 Silk(丝绸),但 Gosling 不喜欢,他本人喜欢的是 Lyric(抒情诗),但没通过律师这一关。最后,排在第四位的“Java”脱颖而出。是不是像极了婴儿没生下来之前,家人就着急着起名的那种感觉。

    James Gosling 回忆说,“Java”是一个叫 Mark Opperman 的人提议的,他是在一家咖啡店得到灵感的,“Java”是印度尼西亚爪哇岛的英文名,因生产咖啡而闻名。

    使用十六进制编辑器打开由 Java 源代码编译出的二进制文件(.class 文件),就可以看得到,最前面的 8 个字符是 CA FE BA BE(定义文件类型的魔数),即词组“CAFE BABE”(咖啡屋宝贝)。

    “二哥,能给我展示一段 Java 代码吗?我想感受一下。”

    “三妹啊,马上就来。”

    (我噼里啪啦一阵在键盘上一阵狂按)

    public class HelloWorld {
    +    

    什么是Java?

    沉默王二2021年7月30日
    • Java核心
    • Java
    大约 15 分钟

    什么是Java?

    01、什么是 Java?

    “二哥,到底什么是 Java?给我说说呗。”

    “三妹啊,这就直奔主题了啊,先去给哥买包烟吧,哥先考验考验你的诚心。”

    (五分钟过后)

    “三妹啊,你怎么还不去?”

    “二哥,掏钱啊。”

    (真实亲妹子啊,买包烟还得我掏钱,关键是还得给跑腿费。十分钟后,三妹从楼下小卖部买了一包熊猫回来了,我用 Zippo 火机点了一支——这火机是 21 岁生日的时候初恋女友送我的,质量确实不错,现在还在用。)

    “三妹啊,听我慢慢来给你解释。”

    Java 是一门计算机编程语言,高级、健壮、面向对象,并且非常安全。它由 Sun 公司在 1995 年开发,主力开发叫 James Gosling,被称为 Java 之父,就是下图这位,头秃的厉害。

    “三妹啊,你要不要再考虑考虑?做程序员不容易啊”

    “二哥,你咋没有秃呢?是因为你不够厉害吗?”

    (这孩子,嘴咋这么损呢?)

    Java 在叫“Java”之前,其实叫 Oak(橡树的意思,我感觉好像比 Java 好听一些)。怎么想到呢?James Gosling 坐在办公室,望向窗外,视野里出现了一颗橡树。不过,遗憾的是,Oak 已经被 另外一家公司注册了,因此 1995 年 5 月 23 日,Oak 语言改名为 Java。

    Java 起初并不是 James Gosling 的首选,也不是命名团队的首选。团队其他人员更青睐 Silk(丝绸),但 Gosling 不喜欢,他本人喜欢的是 Lyric(抒情诗),但没通过律师这一关。最后,排在第四位的“Java”脱颖而出。是不是像极了婴儿没生下来之前,家人就着急着起名的那种感觉。

    James Gosling 回忆说,“Java”是一个叫 Mark Opperman 的人提议的,他是在一家咖啡店得到灵感的,“Java”是印度尼西亚爪哇岛的英文名,因生产咖啡而闻名。

    使用十六进制编辑器打开由 Java 源代码编译出的二进制文件(.class 文件),就可以看得到,最前面的 8 个字符是 CA FE BA BE(定义文件类型的魔数),即词组“CAFE BABE”(咖啡屋宝贝)。

    “二哥,能给我展示一段 Java 代码吗?我想感受一下。”

    “三妹啊,马上就来。”

    (我噼里啪啦一阵在键盘上一阵狂按)

    public class HelloWorld {
         public static void main(String[] args) {
             System.out.println("Hello World");
         }
     }
     

    “二哥,这都什么跟什么啊,看得一头雾水。”

    “三妹啊,先不要着急,Hello World 这段代码以后再慢慢消化,现在就是让它来给你打个招呼。”

    “好吧。”

    “二哥,学 Java 到底有没有前途啊?我毕业以后能不能找到工作啊?”

    “三妹啊,就目前来说,Java 不仅仅是一门编程语言,它还是一个由一系列计算机软件和规范组成的技术体系,这个技术体系提供了完整的用于软件开发和跨平台部署的支持环境,并广泛应用于以下这些场合。”

    1)桌面应用程序; 2)Web 应用程序; 3)企业应用程序,体现了 Java 的安全性、负载均衡和集群的优势; 4)移动端应用程序,主要就是安卓; 5)嵌入式系统; 6)机器人技术; 7)游戏。

    时至今日,Java 技术体系已经吸引了 600 多万软件开发者,是全球最大的软件开发团队。Java 能够获得如此广泛的认可,除了它是一门结构严谨、面向对象的编程语言之外,还有很多其他不可忽视的优点:

    • 摆脱了硬件平台的束缚,实现了“一次编写,处处运行”的理念;
    • 内存管理相对安全,避免了绝大部分内存泄露和指针越界的问题;
    • 实现了热点代码检测和运行时编译,使得 Java 应用能随着运行时间的增长而获得更高的性能;
    • 有一套完善的应用程序接口,还有无数来自商业机构和开源社区的第三方类库。

    这一切的一切,都让软件开发的效率大大的提高。所以,学习 Java 还是很有“钱”“秃”的。

    02、Java的发展简史

    20 世纪 90 年代,单片式计算机系统诞生。单片式计算机系统不仅廉价(之前的计算机非常庞大,并且昂贵),而且功能强大,可以大幅度提升消费性电子产品的智能化程度。

    Sun 公司为了抢占市场先机,在 1991 年成立了一个由詹姆斯·高斯林(James Gosling)领导的,名为“Green”的项目组,目的是开发一种能够在各种消费性电子产品上运行的程序架构。

    项目组首先考虑的是采用 C++ 来编写程序,但 C++ 过于复杂和庞大,再加上消费电子产品所采用的嵌入式处理器芯片的种类繁杂,需要让编写的程序能够跨平台运行并不容易——C++ 在跨平台方面做得并不好。

    思前想后,项目组最后决定:在 C++ 的基础上创建一种新的编程语言,既能够剔除 C++ 复杂的指针和内存管理,还能够兼容各种设备。这语言最初的名字叫做 Greentalk,文件扩展名为 .gt。这个名字叫的比较随意,就因为项目组叫 Green,没什么特殊的寓意。

    Oak 是“Java”的第二个名字,这次就有点意义了。Oak(橡树)是力量的象征,被美国、法国、德国等许多欧美国家选为国树。橡树长下面这样。

    1992 年,Oak 的雏形有了,但项目组在向硬件生产商进行商演的时候,并没有获得认可,于是 Oak 就被搁置一旁了。

    1994 年,项目组发现 Java 更适合进行 Internet 编程。随后,项目组用 Oak 语言研发了一种能将小程序嵌入到网页中执行的技术——Applet。Applet 不仅能嵌入网页,还能够随同网页在网络上进行传输。

    不得不感慨一下,技术的更新迭代是真的快,Applet 拯救了 Oak,并使其蜕变成顶天立地的 Java,但很早之前就被无情地拍死在了沙滩上。是不是很残酷?

    1995 年,Oak 被重新命名为“Java”,因为 Oak 被别的公司注册过了。新的名字最好能够表达出技术的本质:dynamic(动态的)、revolutionary(革命性的)、Silk(像丝绸一样柔软的)、Cool(炫酷的)等等。另外,名字一定要容易拼写,念起来也比较有趣。

    选来选去,项目组最后选择了“Java”,中文叫“爪哇”。细心的小伙伴可能会发现,Java 这个单词里有一个敏感词,所以有段时间微信(文章专辑名这块)为了禁敏感词,竟然把 Java 都禁了,我当时就只能用爪哇来代替 Java,手动狗头。

    “Java”是印度尼西亚爪哇岛的英文名,因生产咖啡而闻名,所以,小伙伴也看到了,Java 这个单词经常和一杯冒着热气的咖啡一起出现。

    同年,Sun 公司在 SunWorld 大会上正式发布了 Java 1.0 版本,第一次提出了“Write Once, Run anywhere”的口号。《时代》杂志将 Java 评为 1995 年十大最佳产品之一。

    1996 年 1 月 23 日,JDK 1.0 发布,Java 语言有了第一个正式版本的运行环境。JDK 1.0 是一个纯解释执行的 Java 虚拟机,代表技术有:Java 虚拟机、AWT(图形化界面)、Applet。

    4 月,十个主要的操作系统和计算机供应商宣称将在产品中嵌入 Java 技术。9 月,已有大约 8.3 万网页应用采用了 Java 来制作。5 月底,第一届 JavaOne 大会在旧金山举行,从此,JavaOne 成为全世界数百万 Java 语言开发者的技术盛会。

    1997 年 2 月 19 日,JDK 1.1 发布,代表技术有:JAR 文件格式、JDBC、JavaBeans、RMI(远程方法调用)。

    1998 年 12 月 4 日,JDK 1.2 发布,这是一个里程碑式的版本。Sun 在这个版本中把 Java 拆分为三个方向:面向桌面开发的 J2SE、面向企业开发的 J2EE,面向移动开发的 J2ME。代表技术有:EJB、Swing。

    2000 年 5 月 8 日,JDK 1.3 发布,对 Java 2D 做了大幅修改。

    2002 年 2 月 13 日,JDK 1.4 发布,这是 Java 真正走向成熟的一个版本,IBM、富士通等著名公司都有参与。代表技术有:正则表达式、NIO。

    2004 年 9 月 30 日,JDK 5 发布,注意 Sun 把“1.x”的命名方式抛弃了。JDK 5 在 Java 语法的易用性上做出了非常大的改进,比如说:自动装箱、泛型、动态注解、枚举、可变参数、foreach 循环。

    2006 年 12 月 11 日,JDK 6 发布,J2SE 变成了 Java SE 6,J2EE 变成了 Java EE 6,J2ME 变成了 Java ME 6。JDK 6 恐怕是 Java 历史上使用寿命最长的一个版本了。主要的原因有:代码复杂性的增加、世界经济危机、Oracle 对 Sun 的收购。

    JDK 6 的最后一个升级补丁为 Java SE 6 Update 211, 于 2018 年 10 月 18 日发布——12 年的跨度啊!

    2009 年 2 月 19 日,JDK 7 发布,但功能是阉割。很多翘首以盼的功能都没有完成,比如说 Lambda 表达式。主要是因为 Sun 公司在商业上陷入了泥沼,已经无力推动 JDK 7 的研发工作。

    2009 年 4 月 20 日,Oracle 以 74 亿美元的价格收购了市值曾超过 2000 亿美元的 Sun 公司——太阳终究还是落山了。对于 Java 语言这个孩子来说,可以说是好事,也可以说是坏事。好事是 Oracle 有钱,能够注入资金推动 Java 的发展;坏处就是 Oracle 是后爸,对 Java 肯定没有 Sun 那么亲,走的是极具商业化的道路。

    2014 年 3 月 18 日,JDK 8 终于来了,步伐是那么蹒跚,但终究还是来了。带着最强有力的武器——Lambda 表达式而来。虽然 JDK 15 已经发布了,但“新版任你发,我用 Java 8”的梗至今还流传着。

    2017 年 9 月 21 日,JDK 9 发布。从此以后,JDK 更新版本的速度令开发者应接不暇,半年一个版本,虽然 Oracle 的目的是好的,为了避免因功能增加而引发的跳票风险,但不得不承认,版本更新的节奏实在是有点过于频繁。

    这就导致一个问题,好不容易更新一个版本,用了六个月后,Oracle 不维护了。针对这个问题,Oracle 给出的解决方案挺奇葩的,每六个 JDK 大版本才会被长期支持(Long Term Support,LTS)。

    JDK 8 是 LTS 版,2018 年 9 月 25 日发布的 JDK 11 是 LTS 版, 2018 年 3 月 20 日发布的 JDK 10 就可以一笔带过了。按照这个节奏算下去的话,下一个 LTS 版就是 2021 年发布的 JDK 17 了。

    JDK 12、JDK 13、JDK 14、JDK 15、JDK 16 都是过渡产品,就好像是试验品一样,不太受开发者待见。

    Java 发展到今天已经 20 多年了,作为一个编程语言确实不简单,Java 代表的面向对象思想确实给工程领域带来了革命性的变化,关键是 Java 一直在拥抱变化。

    大数据方面,有 Apache Kafka、Apache Samza、Apache Storm、Apache Spark、Apache Flink,除了 Spark 是基于 JVM 的函数语言 Scala 编写的,其余都是 Java 编写的。

    Java 在云时代面临着以 Go 语言为主的容器(Docker 等技术)生态圈的挑战,但是,Java 的大型分布式系统越来越多,Java 在云计算与分布式系统中还是扮演着主要角色,并且形成了一个大型的生态圈。

    虽然 Java 和 C++,C 一样,都“老”了,被其他语言不断地挑战,但只有强者才有机会接受挑战,对吧?我相信,Java 的未来依然很光明。

    03、Java的优势

    尽管 Java 已经 25 岁了,但仍然“宝刀未老”。在 Stack Overflow 2019 年流行编程语言调查报告中,Java 位居第 5 位,有 41% 的受调开发者认为 Java 仍然是一门受欢迎的编程语言。

    很多大型的互联网公司都在使用 Java,国内最有名的当属阿里巴巴,国外最有名的当属谷歌。那为什么 Java 如此流行呢?

    1)简单性

    Java 为开发者提供了简单易用的用户体验,与其他面向对象编程语言相比,Java 的设计和生态库具有巨大的优势。Java 剔除了 C++ 中很少使用、难以理解、易混淆的特别,比如说指针运算、操作符重载,内存管理等。

    Java 可以做到堆栈分配、垃圾回收和自动内存管理,在一定程度上为开发者减轻了入门的难度。

    2)可移植性

    如果 Java 直接编译成操作系统能识的二进制码,可能一个标识在 Windows 操作系统下是1100,而 Linux 下是 1001,这样的话,在 Windows 操作系统下可以运行的程序到了 Linux 环境下就无法运行。

    为了解决这个问题,Java 先编译生成字节码,再由 JVM(Java 虚拟机)来解释执行,目的就是将统一的字节码转成操作系统可以识别的二进制码,然后执行。而针对不同的操作系统,都有相应版本的 JVM,所以 Java 就实现了可移植性。

    3)安全性

    Java 适用于网络/分布式环境,为了达到这个目标,在安全方面投入了巨大的精力。使用 Java 可以构建防病毒、防篡改的程序。

    从一开始,Java 就设计了很多可以防范攻击的机制,比如说:

    • 运行时堆栈溢出,这是蠕虫病毒常用的攻击手段。
    • 字节码验证,可以确保代码符合 JVM 规范并防止恶意代码破坏运行时环境。
    • 安全的类加载,可以防止不受信任的代码干扰 Java 程序的运行。
    • 全面的 API 支持广泛的加密服务,包括数字签名、消息摘要、(对称、非对称)密码、密钥生成器。
    • 安全通信,支持 HTTPS、SSL,保护传输的数据完整性和隐私性。

    4)并发性

    Java 在多线程方面做得非常突出,只要操作系统支持,Java 中的线程就可以利用多个处理器,带来了更好的交互响应和实时行为。

    “二哥,那 Java 还会继续流行下去吗?”三妹眨了眨她的长睫毛,对我说。

    “当然。”我斩钉截铁地回答到。

    大数据领域:

    与 Python 一样,Java 在大数据领域占据着主导地位,很多用于处理大规模数据的框架都是基于 Java 开发的。

    • Apache Hadoop,用于在分布式环境中处理大规模数据集。Hadoop 采用了主副架构模式,其中主节点负责控制整个分布式计算栈。Hadoop 在需要处理和分析大规模数据的公司当中很流行。

    • Apache Spark,大型的 ETL(数据仓库技术)、预测分析和报表程序经常使用到 Spark。

    • Apache Mahout,用于机器学习,比如分类、聚类和推荐。

    • JFreechart,用于可视化数据,可以用它制作各种图表,比如饼图、柱状图、线图、散点图、盒状图、直方图等等。

    • Deeplearning4j,用于构建各种类型的神经网络,可以与 Spark 集成,运行在 GPU(图形处理器)上。

    • Apache Storm,用于处理实时数据流,一个 Storm 节点可以在秒级处理数百万个作业。

    物联网(IoT)领域:

    Oracle 表示,灵活性和流行度是 IoT 程序员选择 Java 的主要原因。Java 提供了大量的 API 库,可以很容易应用到嵌入式应用程序中。相比其他编程语言,比如 C 语言,Java 在切换平台时更加顺畅,不容易出错。

    金融服务领域:

    • 聊天机器人,由于可移植性、可维护性、可视化等诸多方面的因素,Java 成了开发聊天机器人最好的工具。

    • 欺诈检测和管理,银行和金融公司使用 AI(人工智能)工具来进行金融欺诈和信用卡欺诈检测,而 Java 常用来开发这些 AI 工具。

    • 交易系统,Java 虚拟机提供的动态运行时编译优化在很多情况下比编译型语言(如 C++)具有更好的性能,让交易系统运行得更顺畅。

    • 移动钱包,基于 AI 和 Java 算法开发的移动钱包,可以帮助用户在花钱时做出更智能的决策。

    Web 领域:

    Java 技术对 Web 领域的发展注入了强大的动力,主流的 Java Web 开发框架有很多:

    • Spring 框架,一个轻量级的控制反转(IoC)和面向切面(AOP)的容器框架,渗透了 Java EE 技术的方方面面,绝大部分 Java 应用都可以从 Spring 框架中受益。

    • Spring MVC 框架,是一种基于 Java 实现的 MVC(Model-View-Controller)设计模式的请求驱动类型的轻量级 Web 框架。

    • MyBatis 框架,一个优秀的数据持久层框架,可在实体类和 SQL 语句之间建立映射关系,是一种半自动化的 ORM(Object Relational Mapping,对象关系映射)实现。

    • JavaServer Faces 框架,由 Oracle 开发,能够将表示层与应用程序代码轻松连接,它提供了一个 API 集,用于表示和管理 UI 组件。

    总之,Oracle 宣称,Java 正运行在 97% 的企业计算机上——有点厉害的样子。

    - + diff --git a/dist/redis/redis-springboot.html b/dist/redis/redis-springboot.html index 5327c132..5f8f8907 100644 --- a/dist/redis/redis-springboot.html +++ b/dist/redis/redis-springboot.html @@ -5,7 +5,7 @@ - - + -

    Spring Boot 整合 Redis 缓存

    沉默王二2022年4月29日
    • Java企业级开发
    • Spring Boot
    • Redis
    大约 13 分钟

    作为开发者,相信大家都知道 Redis 的重要性。Redis 是使用 C 语言开发的一个高性能键值对数据库,是互联网技术领域使用最为广泛的存储中间件,它是「Remote Dictionary Service」的首字母缩写,也就是「远程字典服务」。

    Redis 以超高的性能、完美的文档、简洁的源码著称,国内外很多大型互联网公司都在用,比如说阿里、腾讯、GitHub、Stack Overflow 等等。当然了,中小型公司也都在用。

    安装 Redis

    Redis 的官网提供了各种平台的安装包,Linux、macOS、Windows 的都有。

    官方地址:https://redis.io/docs/getting-started/open in new window

    我目前用的是 macOS,直接执行 brew install redis 就可以完成安装了。

    完成安装后执行 redis-server 就可以启动 Redis 服务了。

    Windows 用户可以通过我之前提到的 chocolatey 命令行软件管理神器open in new window安装(可以戳链接了解详情),只需要一行命令 choco install redis 就可以完成安装了,非常方便。

    生产环境中,我们通常会在 Linux 上安装 Redis。我的服务器上安装了宝塔面板,可以直接在软件商店里搜「Redis」关键字,然后直接安装(我已经安装过了)。

    顺带安装一下 Redis 客户端工具,推荐 GitHub 星标 20k+ 的 AnotherRedisDesktopManager,一款 🚀🚀🚀 更快、更好、更稳定的Redis桌面(GUI)管理客户端,支持 Windows、macOS 和 Linux,性能出众,可以轻松加载海量键值。

    https://github.com/qishibo/AnotherRedisDesktopManageropen in new window

    安装完成后,链接 Redis 服务:

    Redis 数据类型

    Redis支持五种数据类型:string(字符串),hash(哈希),list(列表),set(集合)及zset(sorted set:有序集合)。

    Redis 教程:https://www.redis.net.cn/tutorial/3508.htmlopen in new window

    1)string

    string 是 Redis 最基本的数据类型,一个key对应一个value。

    我们可以通过 AnotherRedisDesktopManager 客户端来练习一下基本的 set、get 命令(参考 Redis 文档,客户端会有提示,所以命令完全不用死记硬背)。

    对应文本命令:

    ### 增加一个 key 为 name,value 为 沉默王二
    +    

    Spring Boot 整合 Redis 缓存

    沉默王二2022年4月29日
    • Java企业级开发
    • Spring Boot
    • Redis
    大约 13 分钟

    作为开发者,相信大家都知道 Redis 的重要性。Redis 是使用 C 语言开发的一个高性能键值对数据库,是互联网技术领域使用最为广泛的存储中间件,它是「Remote Dictionary Service」的首字母缩写,也就是「远程字典服务」。

    Redis 以超高的性能、完美的文档、简洁的源码著称,国内外很多大型互联网公司都在用,比如说阿里、腾讯、GitHub、Stack Overflow 等等。当然了,中小型公司也都在用。

    安装 Redis

    Redis 的官网提供了各种平台的安装包,Linux、macOS、Windows 的都有。

    官方地址:https://redis.io/docs/getting-started/open in new window

    我目前用的是 macOS,直接执行 brew install redis 就可以完成安装了。

    完成安装后执行 redis-server 就可以启动 Redis 服务了。

    Windows 用户可以通过我之前提到的 chocolatey 命令行软件管理神器open in new window安装(可以戳链接了解详情),只需要一行命令 choco install redis 就可以完成安装了,非常方便。

    生产环境中,我们通常会在 Linux 上安装 Redis。我的服务器上安装了宝塔面板,可以直接在软件商店里搜「Redis」关键字,然后直接安装(我已经安装过了)。

    顺带安装一下 Redis 客户端工具,推荐 GitHub 星标 20k+ 的 AnotherRedisDesktopManager,一款 🚀🚀🚀 更快、更好、更稳定的Redis桌面(GUI)管理客户端,支持 Windows、macOS 和 Linux,性能出众,可以轻松加载海量键值。

    https://github.com/qishibo/AnotherRedisDesktopManageropen in new window

    安装完成后,链接 Redis 服务:

    Redis 数据类型

    Redis支持五种数据类型:string(字符串),hash(哈希),list(列表),set(集合)及zset(sorted set:有序集合)。

    Redis 教程:https://www.redis.net.cn/tutorial/3508.htmlopen in new window

    1)string

    string 是 Redis 最基本的数据类型,一个key对应一个value。

    我们可以通过 AnotherRedisDesktopManager 客户端来练习一下基本的 set、get 命令(参考 Redis 文档,客户端会有提示,所以命令完全不用死记硬背)。

    对应文本命令:

    ## 增加一个 key 为 name,value 为 沉默王二
     > set name '沉默王二'
     OK
    -### 获取
    +## 获取
     > get name
     沉默王二
     > set name '沉默王三'
     OK
     > get name
     沉默王三
    -### 删除
    +## 删除
     > del name
     1
     > get name
     null
    -### 测试是否存在 name
    +## 测试是否存在 name
     > EXISTS key
     0
     > EXISTS name
     0
    -

    2)hash

    Redis hash 是一个键值对集合,值可以看成是一个 Map。

    ### 清除数据库
    +

    2)hash

    Redis hash 是一个键值对集合,值可以看成是一个 Map。

    ## 清除数据库
     > flushdb
     OK
    -### 创建 hash,key 为 user_hset 字段为 user1,值为 沉默王二
    +## 创建 hash,key 为 user_hset 字段为 user1,值为 沉默王二
     > hset user_hset user1 沉默王二
     1
     > hset user_hset user2 沉默王三
     1
    -### 字段长度
    +## 字段长度
     > hlen user_hset
     2
    -### 所有字段
    +## 所有字段
     > HKEYS user_hset
     user1
     user2
    -### 所有值
    +## 所有值
     > hvals user_hset
     沉默王二
     沉默王三
    -### 字段 user1 的值
    +## 字段 user1 的值
     > hget user_hset user1
     沉默王二
    -### 获取 key 为 user_hset 的所有字段和值
    +## 获取 key 为 user_hset 的所有字段和值
     > hgetall user_hset
     user1
     沉默王二
     user2
     沉默王三
    -### 更新字段
    +## 更新字段
     > hset user_hset user1 沉默王四
     0
     > hgetall user_hset
    @@ -103,17 +103,17 @@ user2
     > hgetall user_hset
     user2
     沉默王三
    -

    3)list

    list 是一个简单的字符串列表,按照插入顺序排序。

    ### 添加 key 为 user_list value 为 沉默王二、沉默万三的集合
    +

    3)list

    list 是一个简单的字符串列表,按照插入顺序排序。

    ## 添加 key 为 user_list value 为 沉默王二、沉默万三的集合
     > lpush user_list 沉默王二 沉默王三
     2
    -### 查询
    +## 查询
     > lrange user_list 0 -1
     沉默王三
     沉默王二
    -### 往尾部添加
    +## 往尾部添加
     > rpush user_list 沉默王二是沙比
     3
    -### 头部添加
    +## 头部添加
     > lpush user_list 沉默王二是傻叉
     4
     > lrange user_list 0 -1
    @@ -121,7 +121,7 @@ user2
     沉默王三
     沉默王二
     沉默王二是沙比
    -### 更新 index 为 0 的值
    +## 更新 index 为 0 的值
     > lset user_list 0 沉默王四
     OK
     > lrange user_list 0 -1
    @@ -129,28 +129,28 @@ OK
     沉默王三
     沉默王二
     沉默王二是沙比
    -### 删除 index 为 0 的值
    +## 删除 index 为 0 的值
     > lrem user_list 0 沉默王四
     1
     > lrange user_list 0 -1
     沉默王三
     沉默王二
     沉默王二是沙比
    -

    4)set

    set 是 string 类型的无序集合,不允许有重复的元素。

    ### 添加 key 为 user_set value 为沉默王二 沉默王三 沉默王二的狗腿子的集合
    +

    4)set

    set 是 string 类型的无序集合,不允许有重复的元素。

    ## 添加 key 为 user_set value 为沉默王二 沉默王三 沉默王二的狗腿子的集合
     > sadd user_set 沉默王二 沉默王三 沉默王二的狗腿子
     3
    -### 查询
    +## 查询
     > smembers user_set
     沉默王二
     沉默王二的狗腿子
     沉默王三
    -### 删除 value 为沉默王二的元素
    +## 删除 value 为沉默王二的元素
     > srem user_set 沉默王二
     1
     > smembers user_set
     沉默王二的狗腿子
     沉默王三
    -### 添加
    +## 添加
     > sadd user_set 沉默王二
     1
     > smembers user_set
    @@ -159,23 +159,23 @@ OK
     沉默王三
     

    5)sorted set

    sorted set 是 string 类型的有序集合,不允许有重复的元素。

    > FLUSHDB
     OK
    -### 添加 key 为 user_zset 分数为 1 值为沉默王二、分数为 2 值为沉默王三、分数为 3 值为沉默王二的狗腿子
    +## 添加 key 为 user_zset 分数为 1 值为沉默王二、分数为 2 值为沉默王三、分数为 3 值为沉默王二的狗腿子
     > zadd user_zset 1 沉默王二 2 沉默王三 3 沉默王二的狗腿子
     3
    -### 查询
    +## 查询
     > zrange user_zset 0 -1
     沉默王二
     沉默王三
     沉默王二的狗腿子
    -### 反转
    +## 反转
     > zrevrange user_zset 0 -1
     沉默王二的狗腿子
     沉默王三
     沉默王二
    -### 查询元素沉默王二的分数
    +## 查询元素沉默王二的分数
     > zscore user_zset 沉默王二
     1
    -

    Spring Boot 整合 Redis

    第一步,在 pom.xml 文件中添加 Redis 的 starter。

    <dependency>
    +

    Spring Boot 整合 Redis

    第一步,在 pom.xml 文件中添加 Redis 的 starter。

    <dependency>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter-data-redis</artifactId>
     </dependency>
    @@ -220,7 +220,7 @@ OK
         }
     
     }
    -

    RedisTemplate 和 StringRedisTemplate 都是 Spring Data Redis 提供的模板类,可以对 Redis 进行操作,后者针对键值对都是 String 类型的数据,前者可以是任何类型的对象。

    RedisTemplate 和 StringRedisTemplate 除了提供 opsForValue 方法来操作字符串之外,还提供了以下方法:

    • opsForList:操作 list
    • opsForSet:操作 set
    • opsForZSet:操作有序 set
    • opsForHash:操作 hash

    运行测试类后可以在控制台看到以下输出信息:

    也可以通过 AnotherRedisDesktopManager 客户端查看 Redis 数据库中的数据。

    编程喵整合 Redis

    编程喵是一个 Spring Boot + Vue 的前后端分离项目,要整合 Redis 的话,最好的方式是使用 Spring Cache,仅仅通过 @Cacheable、@CachePut、@CacheEvict、@EnableCaching 等注解就可以轻松使用 Redis 做缓存了。

    1)@EnableCaching,开启缓存功能。

    2)@Cacheable,调用方法前,去缓存中找,找到就返回,找不到就执行方法,并将返回值放到缓存中。

    3)@CachePut,方法调用前不会去缓存中找,无论如何都会执行方法,执行完将返回值放到缓存中。

    4)@CacheEvict,清理缓存中的一个或多个记录。

    Spring Cache 是 Spring 提供的一套完整的缓存解决方案,虽然它本身没有提供缓存的实现,但它提供的一整套接口、规范、配置、注解等,可以让我们无缝衔接 Redis、Ehcache 等缓存实现。

    Spring Cache 的注解(前面提到的四个)会在调用方法之后,去缓存方法返回的最终结果;或者在方法调用之前拿缓存中的结果,当然还有删除缓存中的结果。

    这些读写操作不用我们手动再去写代码实现了,直接交给 Spring Cache 来打理就 OK 了,是不是非常贴心?

    第一步,在 pom.xml 文件中追加 Redis 的 starter。

    <dependency>
    +

    RedisTemplate 和 StringRedisTemplate 都是 Spring Data Redis 提供的模板类,可以对 Redis 进行操作,后者针对键值对都是 String 类型的数据,前者可以是任何类型的对象。

    RedisTemplate 和 StringRedisTemplate 除了提供 opsForValue 方法来操作字符串之外,还提供了以下方法:

    • opsForList:操作 list
    • opsForSet:操作 set
    • opsForZSet:操作有序 set
    • opsForHash:操作 hash

    运行测试类后可以在控制台看到以下输出信息:

    也可以通过 AnotherRedisDesktopManager 客户端查看 Redis 数据库中的数据。

    编程喵整合 Redis

    编程喵是一个 Spring Boot + Vue 的前后端分离项目,要整合 Redis 的话,最好的方式是使用 Spring Cache,仅仅通过 @Cacheable、@CachePut、@CacheEvict、@EnableCaching 等注解就可以轻松使用 Redis 做缓存了。

    1)@EnableCaching,开启缓存功能。

    2)@Cacheable,调用方法前,去缓存中找,找到就返回,找不到就执行方法,并将返回值放到缓存中。

    3)@CachePut,方法调用前不会去缓存中找,无论如何都会执行方法,执行完将返回值放到缓存中。

    4)@CacheEvict,清理缓存中的一个或多个记录。

    Spring Cache 是 Spring 提供的一套完整的缓存解决方案,虽然它本身没有提供缓存的实现,但它提供的一整套接口、规范、配置、注解等,可以让我们无缝衔接 Redis、Ehcache 等缓存实现。

    Spring Cache 的注解(前面提到的四个)会在调用方法之后,去缓存方法返回的最终结果;或者在方法调用之前拿缓存中的结果,当然还有删除缓存中的结果。

    这些读写操作不用我们手动再去写代码实现了,直接交给 Spring Cache 来打理就 OK 了,是不是非常贴心?

    第一步,在 pom.xml 文件中追加 Redis 的 starter。

    <dependency>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter-data-redis</artifactId>
     </dependency>
    @@ -314,7 +314,7 @@ OK
         }
     }
     

    注意看 @CachePut 注解这行代码:

    @CachePut(value = "codingmore", key = "'codingmore:postags:'+#postAddTagParam.postTagId")
    -
    • value:缓存名称,也就是缓存的命名空间,value 这里应该换成 namespace 更好一点;
    • key:用于在命名空间中缓存的 key 值,可以使用 SpEL 表达式,比如说 'codingmore:postags:'+#postAddTagParam.postTagId
    • 还有两个属性 unless 和 condition 暂时没用到,分别表示条件符合则不缓存,条件符合则缓存。

    第五步,启动服务器端,启动客户端,修改标签进行测试。

    通过 Red 客户端(一款 macOS 版的 Redis 桌面工具),可以看到刚刚更新的返回值已经添加到 Redis 中了。

    使用 Redis 连接池

    Redis 是基于内存的数据库,本来是为了提高程序性能的,但如果不使用 Redis 连接池的话,建立连接、断开连接就需要消耗大量的时间。

    用了连接池,就可以实现在客户端建立多个连接,需要的时候从连接池拿,用完了再放回去,这样就节省了连接建立、断开的时间。

    要使用连接池,我们得先了解 Redis 的客户端,常用的有两种:Jedis 和 Lettuce。

    • Jedis:Spring Boot 1.5.x 版本时默认的 Redis 客户端,实现上是直接连接 Redis Server,如果在多线程环境下是非线程安全的,这时候要使用连接池为每个 jedis 实例增加物理连接;
    • Lettuce:Spring Boot 2.x 版本后默认的 Redis 客户端,基于 Netty 实现,连接实例可以在多个线程间并发访问,一个连接实例不够的情况下也可以按需要增加连接实例。

    它俩在 GitHub 上都挺受欢迎的,大家可以按需选用。

    我这里把两种客户端的情况都演示一下,方便小伙伴们参考。

    1)Lettuce

    第一步,修改 application-dev.yml,添加 Lettuce 连接池配置(pool 节点)。

    spring:
    +
    • value:缓存名称,也就是缓存的命名空间,value 这里应该换成 namespace 更好一点;
    • key:用于在命名空间中缓存的 key 值,可以使用 SpEL 表达式,比如说 'codingmore:postags:'+#postAddTagParam.postTagId
    • 还有两个属性 unless 和 condition 暂时没用到,分别表示条件符合则不缓存,条件符合则缓存。

    第五步,启动服务器端,启动客户端,修改标签进行测试。

    通过 Red 客户端(一款 macOS 版的 Redis 桌面工具),可以看到刚刚更新的返回值已经添加到 Redis 中了。

    使用 Redis 连接池

    Redis 是基于内存的数据库,本来是为了提高程序性能的,但如果不使用 Redis 连接池的话,建立连接、断开连接就需要消耗大量的时间。

    用了连接池,就可以实现在客户端建立多个连接,需要的时候从连接池拿,用完了再放回去,这样就节省了连接建立、断开的时间。

    要使用连接池,我们得先了解 Redis 的客户端,常用的有两种:Jedis 和 Lettuce。

    • Jedis:Spring Boot 1.5.x 版本时默认的 Redis 客户端,实现上是直接连接 Redis Server,如果在多线程环境下是非线程安全的,这时候要使用连接池为每个 jedis 实例增加物理连接;
    • Lettuce:Spring Boot 2.x 版本后默认的 Redis 客户端,基于 Netty 实现,连接实例可以在多个线程间并发访问,一个连接实例不够的情况下也可以按需要增加连接实例。

    它俩在 GitHub 上都挺受欢迎的,大家可以按需选用。

    我这里把两种客户端的情况都演示一下,方便小伙伴们参考。

    1)Lettuce

    第一步,修改 application-dev.yml,添加 Lettuce 连接池配置(pool 节点)。

    spring:
         redis:
             lettuce:
               pool:
    @@ -358,7 +358,7 @@ OK
                 max-idle: 8 # 连接池最大空闲连接数
                 min-idle: 0 # 连接池最小空闲连接数
                 max-wait: -1ms # 连接池最大阻塞等待时间,负值表示没有限制
    -

    启动服务后,观察 redisTemplate 的 clientConfiguration 节点,可以看到它的值已经变成 DefaultJedisClientConfiguration 对象了。

    当然了,也可以不配置 Jedis 客户端的连接池,走默认的连接池配置。因为 Jedis 客户端默认增加了连接池的依赖包,在 pom.xml 文件中点开 Jedis 客户端依赖可以查看到。

    自由操作 Redis

    Spring Cache 虽然提供了操作 Redis 的便捷方法,比如我们前面演示的 @CachePut 注解,但注解提供的操作非常有限,比如说它只能保存返回值到缓存中,而返回值并不一定是我们想要保存的结果。

    与其保存这个返回给客户端的 JSON 信息,我们更想保存的是更新后的标签。那该怎么自由地操作 Redis 呢?

    第一步,增加 RedisService 接口:

    public interface RedisService {
    +

    启动服务后,观察 redisTemplate 的 clientConfiguration 节点,可以看到它的值已经变成 DefaultJedisClientConfiguration 对象了。

    当然了,也可以不配置 Jedis 客户端的连接池,走默认的连接池配置。因为 Jedis 客户端默认增加了连接池的依赖包,在 pom.xml 文件中点开 Jedis 客户端依赖可以查看到。

    自由操作 Redis

    Spring Cache 虽然提供了操作 Redis 的便捷方法,比如我们前面演示的 @CachePut 注解,但注解提供的操作非常有限,比如说它只能保存返回值到缓存中,而返回值并不一定是我们想要保存的结果。

    与其保存这个返回给客户端的 JSON 信息,我们更想保存的是更新后的标签。那该怎么自由地操作 Redis 呢?

    第一步,增加 RedisService 接口:

    public interface RedisService {
     
         /**
          * 保存属性
    @@ -402,7 +402,7 @@ OK
     
         // 更多代码参考:https://github.com/itwanger/coding-more/blob/main/codingmore-mbg/src/main/java/com/codingmore/service/impl/RedisServiceImpl.java
     }
    -

    第三步,在标签 PostTagController 中增加 Redis 测试用接口 simpleTest :


    更多内容,只针对《Java 程序员进阶之路》星球用户开放,需要的小伙伴可以戳链接🔗加入我们的星球,一起学习,一起卷。。编程喵🐱是一个 Spring Boot+Vue 的前后端分离项目,融合了市面上绝大多数流行的技术要点。通过学习实战项目,你可以将所学的知识通过实践进行检验、你可以拓宽自己的技术边界,你可以掌握一个真正的实战项目是如何从 0 到 1 的。


    项目源码

    - +

    第三步,在标签 PostTagController 中增加 Redis 测试用接口 simpleTest :


    更多内容,只针对《Java 程序员进阶之路》星球用户开放,需要的小伙伴可以戳链接🔗open in new window加入我们的星球,一起学习,一起卷。。编程喵🐱是一个 Spring Boot+Vue 的前后端分离项目,融合了市面上绝大多数流行的技术要点。通过学习实战项目,你可以将所学的知识通过实践进行检验、你可以拓宽自己的技术边界,你可以掌握一个真正的实战项目是如何从 0 到 1 的。


    项目源码

    + diff --git a/dist/redis/rumen.html b/dist/redis/rumen.html index 72a31e2f..80cd7df3 100644 --- a/dist/redis/rumen.html +++ b/dist/redis/rumen.html @@ -39,10 +39,10 @@ } - + -

    Redis入门(适合新手)

    沉默王二2022年3月17日
    • 数据库
    • Redis
    大约 8 分钟

    Redis入门(适合新手)

    说起来,可能有些小伙伴会不相信,我是第一次用 Redis,真的。因为公司小,业务量小,Redis 根本派不上用场。不过,最近打算把系统升级一下,顺带把当下时髦的技术入个门,“与时俱进”嘛,虽然进的有“一点点”晚(注意双引号)。

    作为一名富有责任心的技术博主,我觉得有必要把我入门 Redis 的过程分享出来,供一些小伙伴作为参考。要是我哪里写错了,别客气,过来给我一巴掌,就行了(温柔点,别打肿,影响颜值就不好了)。

    01、Redis 是什么

    Redis 是互联网技术领域中使用最广泛的存储中间件,它是 Remote Dictionary Service 三个单词中加粗字母的组合。你别说,组合起来后念着挺自然的。

    Redis 以超高的性能、完美的文档、简洁的源码著称,国内外很多大型互联网公司都在用,比如说阿里、腾讯、GitHub、Stack Overflow 等等。它的版本更新非常的快,功能也越来越强大,最初只是用来作为缓存数据库,现在已经可以用它来实现消息队列了。

    可以这么说吧,掌握 Redis 已经变成了一项后端工程师必须具备的基础技能。

    Redis 的作者是一名意大利人,网名 Antirez,长相还是过得去的,感兴趣的小伙伴可以 Google 一下。知道为什么 Redis 的默认端口是 6379 吗?

    据说是手机键盘上“MERZ”的位置决定的,小伙伴们可以打开自己手机上九宫格键盘感受一下。“MERZ”是什么意思呢?据说是“愚蠢”的意思。这?是不是感觉程序员的生活中还是有蛮多神秘色彩的?

    02、安装 Redis

    Redis 针对不同的操作系统有不同的安装方式,我们这篇入门的文章就以 Windows 为例吧。

    下载地址如下:

    https://github.com/MicrosoftArchive/redis/releasesopen in new window

    Windows 最新的版本是 3.2.100。从下图中可以看得出,Redis 的体积非常的轻量级,还不到 6 M。体积越小,让我感觉 Redis 越牛逼,你是不是也有这种感觉?

    有两种安装方式,第一种是 msi 的方式,双击运行后安装;第二种是免安装,绿色版,只需要把 zip 包解压就可以了。

    里面有一份英文版的文档——Windows Service Documentation.docx,教我们如何安装 Redis 服务、如何启动、如何关闭,以及如何使用自定义端口启动服务。

    打开命令行,进入到当前解压后的目录,输入启动命令:

    redis-server redis.windows.conf
    +    

    Redis入门(适合新手)

    沉默王二2022年3月17日
    • 数据库
    • Redis
    大约 8 分钟

    Redis入门(适合新手)

    说起来,可能有些小伙伴会不相信,我是第一次用 Redis,真的。因为公司小,业务量小,Redis 根本派不上用场。不过,最近打算把系统升级一下,顺带把当下时髦的技术入个门,“与时俱进”嘛,虽然进的有“一点点”晚(注意双引号)。

    作为一名富有责任心的技术博主,我觉得有必要把我入门 Redis 的过程分享出来,供一些小伙伴作为参考。要是我哪里写错了,别客气,过来给我一巴掌,就行了(温柔点,别打肿,影响颜值就不好了)。

    01、Redis 是什么

    Redis 是互联网技术领域中使用最广泛的存储中间件,它是 Remote Dictionary Service 三个单词中加粗字母的组合。你别说,组合起来后念着挺自然的。

    Redis 以超高的性能、完美的文档、简洁的源码著称,国内外很多大型互联网公司都在用,比如说阿里、腾讯、GitHub、Stack Overflow 等等。它的版本更新非常的快,功能也越来越强大,最初只是用来作为缓存数据库,现在已经可以用它来实现消息队列了。

    可以这么说吧,掌握 Redis 已经变成了一项后端工程师必须具备的基础技能。

    Redis 的作者是一名意大利人,网名 Antirez,长相还是过得去的,感兴趣的小伙伴可以 Google 一下。知道为什么 Redis 的默认端口是 6379 吗?

    据说是手机键盘上“MERZ”的位置决定的,小伙伴们可以打开自己手机上九宫格键盘感受一下。“MERZ”是什么意思呢?据说是“愚蠢”的意思。这?是不是感觉程序员的生活中还是有蛮多神秘色彩的?

    02、安装 Redis

    Redis 针对不同的操作系统有不同的安装方式,我们这篇入门的文章就以 Windows 为例吧。

    下载地址如下:

    https://github.com/MicrosoftArchive/redis/releasesopen in new window

    Windows 最新的版本是 3.2.100。从下图中可以看得出,Redis 的体积非常的轻量级,还不到 6 M。体积越小,让我感觉 Redis 越牛逼,你是不是也有这种感觉?

    有两种安装方式,第一种是 msi 的方式,双击运行后安装;第二种是免安装,绿色版,只需要把 zip 包解压就可以了。

    里面有一份英文版的文档——Windows Service Documentation.docx,教我们如何安装 Redis 服务、如何启动、如何关闭,以及如何使用自定义端口启动服务。

    打开命令行,进入到当前解压后的目录,输入启动命令:

    redis-server redis.windows.conf
     

    然后你就会看到 Redis 启动后的欢迎画面,左边这个盒子感觉好有艺术感啊!有小伙伴知道是怎么生成的吗?

    还有一些其他的提示信息:

    • Redis 当前的版本号为 3.2.100
    • 端口是 6379
    • 进程 ID,也就是 PID 为 12636
    • Redis 官方地址为:http://redis.io

    那如何停止服务呢?可以直接按下 Ctrl+C 组合键——粗暴、壁咚(当然可以直接点右上角的叉号)。

    PS:本来想用 Linux 版或者 OSX 版的,怕入门的小伙伴没有环境。后面可以整一个。

    03、Redis 的数据结构

    Redis 有 5 种基础数据结构,String、Hash、List、Set、SortedSet,也是学 Redis 必须掌握的。除此之外,还有 HyperLogLog、Geo、Pub/Sub,算是高级数据结构了。我们这篇入门的文章就以 String 为例吧。

    String 结构使用非常广泛,比如说把用户的登陆信息转成 JSON 字符串后缓存起来,等需要取出的时候再反序列化一次。

    小伙伴们应该都知道,Java 的 String 是不可变的,无法修改。Redis 的 String 是动态的,可以修改的,两者不同哦。关于 Redis 的 String 结构,我觉得老钱的 Redis 教程上讲得非常明白,大家一起拜读下。

    Redis 的 String 在内部结构实现上类似于 Java 的 ArrayList,采用预分配冗余空间的方式来减少内存的频繁分配。如上图所示,当前字符串实际分配的空间为 capacity,一般高于实际的字符串长度 len。当字符串长度小于 1M 时,扩容是对现有空间的成倍增长;如果长度超过 1M 时,扩容一次只会多增加 1M 的空间。最大长度为 512M。

    04、实操 Redis

    好了好了,我估计很多小伙伴们已经整装待发,准备实操一把了。这就来。

    Redis 的解压目录下有一个名叫 redis-cli.exe 的文件,这是 Redis 自带的一个客户端工具,可以用来连接之前我们启动好的 Redis 服务。双击启动它。

    这个客户端还是非常智能的,当键入命令的时候,会跳出对应的提示

    当按下空格跟进关键字的时候,对应位置上的提示会自动消失。

    以下是完整的键值对测试命令,小伙伴们可以按照格式动手实操一把。

    > set name cmower
     OK
     > get name
    @@ -107,6 +107,6 @@ exists:true
     del:1
     get:null
     

    完全符合我们的预期,perfect!

    06、鸣谢

    好了,我亲爱的小伙伴们,以上就是本文的全部内容了,是不是看完后很想实操一把 Redis,赶快行动吧!如果你在学习的过程中遇到了问题,欢迎随时和我交流,虽然我也是个菜鸟,但我有热情啊。

    另外,如果你想写入门级别的文章,这篇就是最好的范例。

    - + diff --git a/dist/redis/xuebeng-chuantou-jichuan.html b/dist/redis/xuebeng-chuantou-jichuan.html index 64319100..8c67bc8f 100644 --- a/dist/redis/xuebeng-chuantou-jichuan.html +++ b/dist/redis/xuebeng-chuantou-jichuan.html @@ -39,10 +39,10 @@ } - + -

    简单聊聊缓存雪崩、穿透、击穿

    沉默王二2022年3月31日
    • 数据库
    • Redis
    大约 7 分钟

    简单聊聊缓存雪崩、穿透、击穿

    大家好,我是二哥呀。作为后端开发,我想缓存是大家再熟悉不过的东西了。

    本文会介绍出现缓存雪崩、穿透和击穿的业务背景、解决方案和对业务可靠性处理。事先说明,最佳解决方案一定需要结合实际业务调整,不同业务的处理不完全相同

    其实我在网上也看过不少关于缓存雪崩、穿透、击穿介绍,不知道是不是大家所做业务的不同,发现有不少小伙伴有以下疑问,比如:

    • 加随机时间过期后,如果访问时间刚好就是加了随机时间后的数据,这样岂不是白加了随机时间?
    • 热点数据不过期,那岂不是有越来越多的脏数据?

    就以上问题,我都会在文中一一解释,以下说的缓存都指 Redis。

    我争取把这一高频面试题讲明白,如果大家看后能在这块内容和面试官面前谈笑风生,那你就是最靓的仔。

    下面,我就开始进入正题啦。

    1. 缓存雪崩

    即缓存同一时间大面积的失效,这个时候来了一大波请求,都怼到数据库上,最后数据库处理不过来崩了。

    1.1 业务场景举例

    APP 首页有大量热点数据,在某大型活动期间,针对不同时间段需要展示不同的首页数据。

    比如在 0 点时需要替换新的首页数据,此时旧首页数据过期,新首页数据刚开始加载。

    而 0 点正在有个小活动开始,大批请求涌入。因为新数据刚开始加载,请求多数没有命中缓存,请求到了数据库,最后就把数据库打挂了。

    1.2 解决方案

    再强调一下,所谓的解决方案是需要根据实际业务调整,不同业务的处理不完全相同

    1.2.1 方法一

    常见方式就是给过期时间加个随机时间。

    注意这个随机时间不是几秒哈,可以长达几分钟。因为如果数据量很大,按照上述例子,加上 Redis 是单线程处理数据的。那么几秒的缓冲不一定能够保证新数据都被加载完成。

    所以过期时间宁愿设置长一点,也好过短一点。反正最后都是会过期掉,最终效果是一样的。

    而且过期时间范围加大,key 会更加分散,这样也是一定程度缩短 Redis 在过期 key 时候的阻塞时间。

    而至于文章开头说的:「如果访问时间刚好就是加了随机时间后的数据,这样岂不是白加了随机时间」。

    现在你结合上例活动的例子,它还会是一个问题吗?结合业务,一定要结合业务。

    1.2.2 方法二

    加互斥锁,但这个方案会导致吞吐量明显下降。所以还是要看实际业务,像上述例子就不合适用

    1.2.3 方法三

    热点数据不设置过期。不过期的话,正常业务请求自然就不会打到数据库了。

    那新的问题又来了,不过期有脏数据,怎么办?

    很简单,活动整体结束后再删除嘛。

    那像上述例子,可以怎么处理呢?—— 选择方法一;或者提前把 0 点需要的新数据加载进 Redis,不必等到 0 点才去加载,这样也是可以的

    2. 缓存击穿

    缓存击穿是指一个热点 key 过期或被删除后,导致线上原本能命中该热点 key 的请求,瞬间大量地打到数据库上,最终导致数据库被击垮。

    有种千里之堤,溃于蚁穴的感觉。

    2.1 业务场景举例

    出现情况一般是误操作,比如设置错了过期时间、误删除导致的。

    谁还没误操作过呢,删库跑路了解一下。反正我误删过测试库的数据,幸好人没事,狗头保命。

    2.2 解决方案

    方法一

    代码问题,该 review 的 review。

    热点数据到底要不要过期,什么时候过期要明确

    既然是热点数据,大概率是核心流程。那么该保证的核心功能还是需要保证的,减少犯错机会。万一出问题,那就是用户的一波输出了。

    方法二

    线上误操作的事情,该加强权限管理的加强,特别是线上权限,一定需要审核,以防手抖。

    3. 缓存穿透

    缓存穿透是指:客户端请求缓存和数据库中不存在的数据,导致所有的请求都打到数据库上。如果请求很多,数据库依旧会挂得明明白白。

    3.1 业务场景举例

    • 数据库主键 id 都是正数,然后客户端发起了 id = -1 的查询
    • 一个查询接口,有一个状态字段 status,其实 0 表示开始、1 表示结束。结果有请求一直发 status=3 的请求过来

    3.2 解决方案

    3.2.1 方法一

    做好参数校验,对于不合理的参数要及时 return 结束

    这点非常重点,做任何业务都一样,对于后端来说,要有互不信任原则

    简单来说,就是不要信任来自前端、客户端和上游服务的请求数据,该做的校验还是要做。

    因为我们永远都不知道用户会写什么奇奇怪怪的数据;又或者即使你和对接的开发约定好了要怎么传参数,但你保不准他就没遵守呢;退一步来说,万一接口被破解呢。

    你要保护好自己,不然到时出问题时,你和老大说,因为谁谁不遵守约定传参导致,或者因为没想到用户会这么填,你看看你老大会这么说(狗头.jpg)

    3.2.2 方法二

    对于查不到数据的 key,也将其短暂缓存起来。

    比如 30s。这样能避免大量相同请求瞬间打到数据库上,减轻压力。

    但是后面肯定要去看为什么会有这样的数据,从根本上解决问题,该方法只是缓解问题而已。

    如果发现就是某些 ip 在请求,并且这些数据非法,那可以在网关层限制这些 ip 访问

    3.2.3 方法三

    提供一个能迅速判断请求是否有效的拦截机制,比如布隆过滤器,Redis 本身就具有这个功能。

    让它维护所有合法的 key,如果请求参数不合法,则直接返回。否则就从缓存或数据库中获取。

    关于布隆过滤器可以看我之前写的文章:xxx

    4. 业务可靠性处理

    如开头所说,缓存指 Redis。

    • 提高 Redis 可用性:Redis 要么用集群架构,要么用主从 + 哨兵。保证 Redis 的可用性。

    没有哨兵的主从不能自动故障转移,所以只有主从,万一高峰期或者在关键的活动时间节点挂了。

    那么等出现线上告警、定位问题、沟通信息、等运维解决,一套操作下来,估计黄花菜都凉了。

    • 减少对缓存的依赖

    对于热点数据,是不是可以考虑加上本地缓存,比如:Guava、Ehcache,更简单点,hashMap、List 什么也可以。

    减少对 Redis 压力的同时,还能提高性能,一举两得。

    • 业务降级

    从保护下游(接口或数据库)的角度考虑,针对大流量场景是不是可以做下限流。这样即使缓存崩了,也不至于把下游全部拖垮。

    以及该降级的功能是不是可以降级,提前写好降级开关和降级逻辑,关键时候全靠它稳住。


    作者:七淅,转载链接:https://mp.weixin.qq.com/s/juUzaf1TQYMuJFbw7Y3SXgopen in new window

    - +

    简单聊聊缓存雪崩、穿透、击穿

    沉默王二2022年3月31日
    • 数据库
    • Redis
    大约 7 分钟

    简单聊聊缓存雪崩、穿透、击穿

    大家好,我是二哥呀。作为后端开发,我想缓存是大家再熟悉不过的东西了。

    本文会介绍出现缓存雪崩、穿透和击穿的业务背景、解决方案和对业务可靠性处理。事先说明,最佳解决方案一定需要结合实际业务调整,不同业务的处理不完全相同

    其实我在网上也看过不少关于缓存雪崩、穿透、击穿介绍,不知道是不是大家所做业务的不同,发现有不少小伙伴有以下疑问,比如:

    • 加随机时间过期后,如果访问时间刚好就是加了随机时间后的数据,这样岂不是白加了随机时间?
    • 热点数据不过期,那岂不是有越来越多的脏数据?

    就以上问题,我都会在文中一一解释,以下说的缓存都指 Redis。

    我争取把这一高频面试题讲明白,如果大家看后能在这块内容和面试官面前谈笑风生,那你就是最靓的仔。

    下面,我就开始进入正题啦。

    1. 缓存雪崩

    即缓存同一时间大面积的失效,这个时候来了一大波请求,都怼到数据库上,最后数据库处理不过来崩了。

    1.1 业务场景举例

    APP 首页有大量热点数据,在某大型活动期间,针对不同时间段需要展示不同的首页数据。

    比如在 0 点时需要替换新的首页数据,此时旧首页数据过期,新首页数据刚开始加载。

    而 0 点正在有个小活动开始,大批请求涌入。因为新数据刚开始加载,请求多数没有命中缓存,请求到了数据库,最后就把数据库打挂了。

    1.2 解决方案

    再强调一下,所谓的解决方案是需要根据实际业务调整,不同业务的处理不完全相同

    1.2.1 方法一

    常见方式就是给过期时间加个随机时间。

    注意这个随机时间不是几秒哈,可以长达几分钟。因为如果数据量很大,按照上述例子,加上 Redis 是单线程处理数据的。那么几秒的缓冲不一定能够保证新数据都被加载完成。

    所以过期时间宁愿设置长一点,也好过短一点。反正最后都是会过期掉,最终效果是一样的。

    而且过期时间范围加大,key 会更加分散,这样也是一定程度缩短 Redis 在过期 key 时候的阻塞时间。

    而至于文章开头说的:「如果访问时间刚好就是加了随机时间后的数据,这样岂不是白加了随机时间」。

    现在你结合上例活动的例子,它还会是一个问题吗?结合业务,一定要结合业务。

    1.2.2 方法二

    加互斥锁,但这个方案会导致吞吐量明显下降。所以还是要看实际业务,像上述例子就不合适用

    1.2.3 方法三

    热点数据不设置过期。不过期的话,正常业务请求自然就不会打到数据库了。

    那新的问题又来了,不过期有脏数据,怎么办?

    很简单,活动整体结束后再删除嘛。

    那像上述例子,可以怎么处理呢?—— 选择方法一;或者提前把 0 点需要的新数据加载进 Redis,不必等到 0 点才去加载,这样也是可以的

    2. 缓存击穿

    缓存击穿是指一个热点 key 过期或被删除后,导致线上原本能命中该热点 key 的请求,瞬间大量地打到数据库上,最终导致数据库被击垮。

    有种千里之堤,溃于蚁穴的感觉。

    2.1 业务场景举例

    出现情况一般是误操作,比如设置错了过期时间、误删除导致的。

    谁还没误操作过呢,删库跑路了解一下。反正我误删过测试库的数据,幸好人没事,狗头保命。

    2.2 解决方案

    方法一

    代码问题,该 review 的 review。

    热点数据到底要不要过期,什么时候过期要明确

    既然是热点数据,大概率是核心流程。那么该保证的核心功能还是需要保证的,减少犯错机会。万一出问题,那就是用户的一波输出了。

    方法二

    线上误操作的事情,该加强权限管理的加强,特别是线上权限,一定需要审核,以防手抖。

    3. 缓存穿透

    缓存穿透是指:客户端请求缓存和数据库中不存在的数据,导致所有的请求都打到数据库上。如果请求很多,数据库依旧会挂得明明白白。

    3.1 业务场景举例

    • 数据库主键 id 都是正数,然后客户端发起了 id = -1 的查询
    • 一个查询接口,有一个状态字段 status,其实 0 表示开始、1 表示结束。结果有请求一直发 status=3 的请求过来

    3.2 解决方案

    3.2.1 方法一

    做好参数校验,对于不合理的参数要及时 return 结束

    这点非常重点,做任何业务都一样,对于后端来说,要有互不信任原则

    简单来说,就是不要信任来自前端、客户端和上游服务的请求数据,该做的校验还是要做。

    因为我们永远都不知道用户会写什么奇奇怪怪的数据;又或者即使你和对接的开发约定好了要怎么传参数,但你保不准他就没遵守呢;退一步来说,万一接口被破解呢。

    你要保护好自己,不然到时出问题时,你和老大说,因为谁谁不遵守约定传参导致,或者因为没想到用户会这么填,你看看你老大会这么说(狗头.jpg)

    3.2.2 方法二

    对于查不到数据的 key,也将其短暂缓存起来。

    比如 30s。这样能避免大量相同请求瞬间打到数据库上,减轻压力。

    但是后面肯定要去看为什么会有这样的数据,从根本上解决问题,该方法只是缓解问题而已。

    如果发现就是某些 ip 在请求,并且这些数据非法,那可以在网关层限制这些 ip 访问

    3.2.3 方法三

    提供一个能迅速判断请求是否有效的拦截机制,比如布隆过滤器,Redis 本身就具有这个功能。

    让它维护所有合法的 key,如果请求参数不合法,则直接返回。否则就从缓存或数据库中获取。

    关于布隆过滤器可以看我之前写的文章:xxx

    4. 业务可靠性处理

    如开头所说,缓存指 Redis。

    • 提高 Redis 可用性:Redis 要么用集群架构,要么用主从 + 哨兵。保证 Redis 的可用性。

    没有哨兵的主从不能自动故障转移,所以只有主从,万一高峰期或者在关键的活动时间节点挂了。

    那么等出现线上告警、定位问题、沟通信息、等运维解决,一套操作下来,估计黄花菜都凉了。

    • 减少对缓存的依赖

    对于热点数据,是不是可以考虑加上本地缓存,比如:Guava、Ehcache,更简单点,hashMap、List 什么也可以。

    减少对 Redis 压力的同时,还能提高性能,一举两得。

    • 业务降级

    从保护下游(接口或数据库)的角度考虑,针对大流量场景是不是可以做下限流。这样即使缓存崩了,也不至于把下游全部拖垮。

    以及该降级的功能是不是可以降级,提前写好降级开关和降级逻辑,关键时候全靠它稳住。


    作者:七淅,转载链接:https://mp.weixin.qq.com/s/juUzaf1TQYMuJFbw7Y3SXgopen in new window

    + diff --git a/dist/service-worker.js b/dist/service-worker.js index 64174d88..a308b5fe 100644 --- a/dist/service-worker.js +++ b/dist/service-worker.js @@ -1,2 +1,2 @@ -if(!self.define){let s,e={};const a=(a,i)=>(a=new URL(a+".js",i).href,e[a]||new Promise((e=>{if("document"in self){const s=document.createElement("script");s.src=a,s.onload=e,document.head.appendChild(s)}else s=a,importScripts(a),e()})).then((()=>{let s=e[a];if(!s)throw new Error(`Module ${a} didn’t register its module`);return s})));self.define=(i,c)=>{const d=s||("document"in self?document.currentScript.src:"")||location.href;if(e[d])return;let b={};const f=s=>a(s,d),r={module:{uri:d},exports:b,require:f};e[d]=Promise.all(i.map((s=>r[s]||f(s)))).then((s=>(c(...s),b)))}}define(["./workbox-2572b17b"],(function(s){"use strict";s.setCacheNameDetails({prefix:"Java 程序员进阶之路"}),self.addEventListener("message",(s=>{s.data&&"SKIP_WAITING"===s.data.type&&self.skipWaiting()})),s.clientsClaim(),s.precacheAndRoute([{url:"assets/100-budiushi.html.c3040dbf.js",revision:"5e2fdf602f4f9cfe989cd2ecee4c6e1b"},{url:"assets/100-budiushi.html.f74d8841.js",revision:"3ecbc7c722366afc8037045b36b4f1e2"},{url:"assets/4-debug-skill.html.1e235b0a.js",revision:"d92033e1e0091d504c0db9c120c399dd"},{url:"assets/4-debug-skill.html.9bd076fc.js",revision:"bdd75149e13482f9c53f9ea3e0a36927"},{url:"assets/40-interview.html.2cb0fe6c.js",revision:"b73bdbdbc6bdccce1a2a65eb0e4a34ba"},{url:"assets/40-interview.html.cb9b99de.js",revision:"5983f28d781024f4491d454565e80cb4"},{url:"assets/404.5ae72665.js",revision:"3cc56698b4404bdc4312d24fe9ed4311"},{url:"assets/404.html.5c274669.js",revision:"268ea93907c83188e07ccbac7c112472"},{url:"assets/404.html.e75684b7.js",revision:"19f495e79edd1b6a31d59cc9804d8602"},{url:"assets/48-keywords.html.34eb30fe.js",revision:"8a98efeede1397e547a45922575057ac"},{url:"assets/48-keywords.html.e76832ee.js",revision:"0f28937c5f2199e1fb19617c0169cc05"},{url:"assets/abstract.html.3094fdb5.js",revision:"3f1e0182c50046175b9a0df0660d37e9"},{url:"assets/abstract.html.60b3966f.js",revision:"4031b3f9ba7030578715f84aaeea8eff"},{url:"assets/algorithm.html.14390f00.js",revision:"cbe7a405e3cfcc0ad60ef4bffc3765fb"},{url:"assets/algorithm.html.66d3e273.js",revision:"050bae691af2e4da0060297a7d505462"},{url:"assets/ali-executors.html.988adc8e.js",revision:"84812d38cd71487938d2a8511d0b7225"},{url:"assets/ali-executors.html.e9951d8a.js",revision:"0d4e4dcc2651eea56f65cc332390a1ba"},{url:"assets/aliyun-shuaiguo-gongchengshi.html.80a83c0a.js",revision:"8712ab388dee7c78bfed77536c312cea"},{url:"assets/aliyun-shuaiguo-gongchengshi.html.e4346151.js",revision:"97ea58e96d96f1afd5bb00e2f3b35fcb"},{url:"assets/annotation.html.14064668.js",revision:"b8c310fbc00430fd403dedfcffd9e496"},{url:"assets/annotation.html.b0fc1ba0.js",revision:"63a677b83353ca3eff074889dad11445"},{url:"assets/aop-log.html.390b071a.js",revision:"4d14cfeb7c0b409467bb60a83463cd8a"},{url:"assets/aop-log.html.f3df7d62.js",revision:"9169d18e23e3603a08699453af417171"},{url:"assets/api-wangguan.html.9f0edd64.js",revision:"96affaf79170b91a3f6fe3af5d39044e"},{url:"assets/api-wangguan.html.c2b18262.js",revision:"82f0406d65453e8eb1a5ad59ca30ecb0"},{url:"assets/app.a0271b9c.js",revision:"c67d329e17fa0244204bed8ba3c8dee4"},{url:"assets/aqs.html.d6a8f5b4.js",revision:"625d292bc1a70d1e7405da97b6029523"},{url:"assets/aqs.html.e6bd9611.js",revision:"6a368249313dc9131a7521e95aed30dc"},{url:"assets/array.html.77525f56.js",revision:"c7cc1063f8abb40eb5a6e6bb3a220431"},{url:"assets/array.html.97a807b4.js",revision:"a6f79d638eabb85c97c90b71ad600583"},{url:"assets/arraylist.html.0dcdca73.js",revision:"381a5a48e521e35dda79e367eac116a1"},{url:"assets/arraylist.html.804615c1.js",revision:"e4cb8c73d720fb02db354fa1d8fdf224"},{url:"assets/arrays.html.13de83ef.js",revision:"f94fd5d206d6d69e88a138d19ce76dfd"},{url:"assets/arrays.html.7944f961.js",revision:"c15f2d6bcb85818880f6f8383f9dbc61"},{url:"assets/asm.html.0e0abd8b.js",revision:"072c730bffd7fc1a8a611ddd1c5da23e"},{url:"assets/asm.html.deedcff5.js",revision:"61c27e4accd210a0387f4455886819ac"},{url:"assets/atomic.html.1dc322e5.js",revision:"198e7d55f80be469859f72f0647ace36"},{url:"assets/atomic.html.93391f09.js",revision:"0a81ec041fa27d2b5cff824a647d20a1"},{url:"assets/auto-generator.html.79ba5c06.js",revision:"d364fb71af23e516dd0b1fa7b7abee61"},{url:"assets/auto-generator.html.edd07e0d.js",revision:"459b8e54b7d592596c99df653773d8e9"},{url:"assets/basic-data-type.html.52152cd3.js",revision:"42a3549d7841190a92927b56e6bb3ba3"},{url:"assets/basic-data-type.html.6be3e7e2.js",revision:"926a54b4618afc77e58598cb1f53e6ed"},{url:"assets/bat-shuati.html.adba9635.js",revision:"95b1c08b506d1bdc59d0cef79d439039"},{url:"assets/bat-shuati.html.bf129827.js",revision:"c4f631aa6f12d534db680124dcfdef0e"},{url:"assets/beijing.html.5436f34b.js",revision:"541c49a82e9b4823be52a7c5dcf738c4"},{url:"assets/beijing.html.ac5b087b.js",revision:"eb8232a3c67f62d1daabadc762fc0267"},{url:"assets/BIONIOAIO.html.27d4fa22.js",revision:"c138b5cdd8c3d0555fe27a74da4ee71e"},{url:"assets/BIONIOAIO.html.ea89d11f.js",revision:"1e4874dbc0370df66e2880da25a688ca"},{url:"assets/BlockingQueue.html.5fa0f03a.js",revision:"5a17077091b6bf9f5a67382c1132a0f7"},{url:"assets/BlockingQueue.html.9ccd9ba0.js",revision:"ceeda89af92173a6e837c5a077c9d909"},{url:"assets/bokeyuan-jianxijavazhongdifangwenquanxiankongzhi.html.95de7e08.js",revision:"9fdcfd9383a500542735132539a3c662"},{url:"assets/bokeyuan-jianxijavazhongdifangwenquanxiankongzhi.html.bc8753e4.js",revision:"e407e843972f36f357c6600a48c11379"},{url:"assets/bokeyuan-ruhegaoxiaodixuexijishu.html.b64706b8.js",revision:"a50adcc55132fb174135a0fac156f545"},{url:"assets/bokeyuan-ruhegaoxiaodixuexijishu.html.e9d4ca36.js",revision:"1a48b0e99830900cbfeb4437a51aae72"},{url:"assets/BOKEYUANruhegaoxiaodixuexijishu.html.54dd2a4d.js",revision:"e410b4653746a1f3a29de7315e67451d"},{url:"assets/BOKEYUANruhegaoxiaodixuexijishu.html.bdd4e19a.js",revision:"d889094d96aeb06c47c6db4b994fc898"},{url:"assets/box.html.54cc70a2.js",revision:"09778d260a2bd54390c5df81ae5c0a4c"},{url:"assets/box.html.9c8b69db.js",revision:"49c9f66c159e83373c6215e1402270f7"},{url:"assets/buy-cloud-server.html.595deaa6.js",revision:"bea7becb36dcf02d7c5215fc19797c6e"},{url:"assets/buy-cloud-server.html.d200b8bc.js",revision:"caeca61f089ac012663ae00f5425f72d"},{url:"assets/buy-domain.html.1227af51.js",revision:"2084929626a6e80923df3997bea07231"},{url:"assets/buy-domain.html.4406ff12.js",revision:"6ec3445b674b953c65f069e2ef67f0f2"},{url:"assets/bytecode.html.09a0585c.js",revision:"ef6f78bd725da1837b302e3c7241e490"},{url:"assets/bytecode.html.ba8f00b6.js",revision:"c0d1e7ef23332326dc90ce1d81d5d05f"},{url:"assets/bzhan-10wan.html.98f8ba37.js",revision:"d68d1bd3dddf462db72f205b33e3eeb5"},{url:"assets/bzhan-10wan.html.b3906807.js",revision:"14f64220fb9957467710377a0dbbfc9f"},{url:"assets/c.html.1f2463e6.js",revision:"22c6d4776333d8bc0c48d24cc2122703"},{url:"assets/c.html.5983fe89.js",revision:"cee3031a57cc138acc6d11755802b30e"},{url:"assets/cas.html.4534d702.js",revision:"8bc80781d9d2bdde974c66d01343caf9"},{url:"assets/cas.html.ff0123d4.js",revision:"8aead092c977c22a92060b941af56e40"},{url:"assets/ccc.html.0a777341.js",revision:"506d7bf9c04b695b62f010d03b304c93"},{url:"assets/ccc.html.51a24970.js",revision:"e724b888cc455ff547b84535af17a324"},{url:"assets/chadiansanhuo.html.78becde9.js",revision:"f425b866097150767f32355073fc1b66"},{url:"assets/chadiansanhuo.html.e9cc0b99.js",revision:"3ae54e43d8b55c9b07f8b96eb885ddfd"},{url:"assets/chengdu.html.09b27f2f.js",revision:"a57af5b30fd47338e387bc3f6df009bf"},{url:"assets/chengdu.html.8c0a9616.js",revision:"58e48254752fa8b92853deee07bfd5cd"},{url:"assets/chengxuyuannv-chonghui-java.html.b2dd4108.js",revision:"0487f286d80446b156f7fe6f4abe3294"},{url:"assets/chengxuyuannv-chonghui-java.html.b9de6702.js",revision:"eae9b017adb086faa22ac24423ebc287"},{url:"assets/chiner.html.13c55607.js",revision:"82785120402bceab024e50887e5714d1"},{url:"assets/chiner.html.5580190e.js",revision:"d0da5776acb158ea6ddecd3795cceb88"},{url:"assets/choco.html.8857968e.js",revision:"a7274435a5211b4ea1a31360b2d413a4"},{url:"assets/choco.html.f8923e81.js",revision:"f1ecf9c1e645995f595ae0192eef1f6c"},{url:"assets/Chocolatey-Homebrew.html.a0b23720.js",revision:"92a4c97d2e1182191ce3fa2abc40ded7"},{url:"assets/Chocolatey-Homebrew.html.ad256880.js",revision:"f27f5ffe5e873f37caae308cd3f7c800"},{url:"assets/class-file-jiegou.html.3dff0326.js",revision:"96c0ab54ea6bd0c20cc027807b9c0117"},{url:"assets/class-file-jiegou.html.63f6ec81.js",revision:"1f0cdde61a4cd67bf4299d62a8f4af0a"},{url:"assets/class-load.html.6a788fca.js",revision:"1b73773905c7665af8d92be86ff7c93c"},{url:"assets/class-load.html.ac3b08f8.js",revision:"eaf1ab0b5573d73ae0575c33da5d70ab"},{url:"assets/class-object.html.2cd0dbd5.js",revision:"903aeb8d4c192cb9e6b4ae0bc6e54f73"},{url:"assets/class-object.html.c43412d3.js",revision:"95d854056dbe7d047f22d73d03c0c4bf"},{url:"assets/code-init.html.16081b84.js",revision:"6297f1cde9dd90188e3afc300bd5279f"},{url:"assets/code-init.html.70ef628a.js",revision:"818831e291e49a1121d4867cbbf34e7b"},{url:"assets/collection.html.42c40509.js",revision:"3e9a280a2708f759c09967d7f84b7b1c"},{url:"assets/collection.html.d1a47d1f.js",revision:"90fcb9209f7e71a63d6d00e26a74f49b"},{url:"assets/collections.html.2e6479a3.js",revision:"2a8ef3d4cdfea297d8e08d2e1767a0f6"},{url:"assets/collections.html.b7f2022a.js",revision:"391b0c8300f7e571785b19e64183591f"},{url:"assets/comparable-omparator.html.397dc2ff.js",revision:"4fc9d5e6efa5df02a669384c67c775c4"},{url:"assets/comparable-omparator.html.c8fb7fdb.js",revision:"ba24f9070ad3e1b591f507e5842b2fce"},{url:"assets/compile-jdk.html.2e638e51.js",revision:"65162150c690bd0452a034e058b27703"},{url:"assets/compile-jdk.html.531caac0.js",revision:"cfb5cd6a34b5696dec2ff5c2cf32665b"},{url:"assets/computer-base.html.1ca00f7c.js",revision:"be3c376caa78632880fff3bdb7963f59"},{url:"assets/computer-base.html.f469b424.js",revision:"1f6ecd345516bff8d501b14e1594704b"},{url:"assets/ConcurrentHashMap.html.127182e6.js",revision:"3485ba56346c6110176e86ca3aa23068"},{url:"assets/ConcurrentHashMap.html.e7f83c81.js",revision:"0d28e48bc1568ebab9dcc835e29ba876"},{url:"assets/ConcurrentLinkedQueue.html.ad944043.js",revision:"579f73cebbd40f2e6637cdcd59e84c7e"},{url:"assets/ConcurrentLinkedQueue.html.da4bfec1.js",revision:"23433f93339dc43427ba24cee5941137"},{url:"assets/condition.html.a41bdc76.js",revision:"d7d34d6a2e7d5506b58e1b72264aad0c"},{url:"assets/condition.html.dcd667af.js",revision:"70d5365eb60b25646264be86110e9b6a"},{url:"assets/constant-pool.html.c79f5c21.js",revision:"61e5fe3195c6360d58f87a081108d8b3"},{url:"assets/constant-pool.html.e2d85914.js",revision:"af37ee862cb4d200937bdc808566d076"},{url:"assets/construct.html.5ae3e6eb.js",revision:"e6248e5666fb845c81737f955adcee8e"},{url:"assets/construct.html.ebfac9f1.js",revision:"ccb60ea2843fd836ff1739d72a65b8a4"},{url:"assets/CopyOnWriteArrayList.html.375356c8.js",revision:"f1029953b3360d14cad73e2cb431d76c"},{url:"assets/CopyOnWriteArrayList.html.b8e564c2.js",revision:"f2f383f2d43d94ceccdbe96b2b1c6440"},{url:"assets/cors.html.32e975b9.js",revision:"da33a1e03c3d08e3a0f1da68f3b74a8f"},{url:"assets/cors.html.b8f51585.js",revision:"7439fe2677e95d97a601cf2a34e91040"},{url:"assets/CountDownLatch.html.db5e5e87.js",revision:"f1ea7ca00771124ce05aa6ea2d011e1c"},{url:"assets/CountDownLatch.html.f036fab2.js",revision:"26b7d176d09b3669f790cd3526ef5132"},{url:"assets/cpu-percent-100.html.3a56db8e.js",revision:"b89e1f110cc02b04a4e1faab591a7c5d"},{url:"assets/cpu-percent-100.html.f6bd745b.js",revision:"ad8a7d92c2d6b25c044333bc25f9537a"},{url:"assets/csdn-1000wan.html.2e52cd37.js",revision:"8877c4736d9509cbc13e8c13cb4822f9"},{url:"assets/csdn-1000wan.html.438218cb.js",revision:"259561af8e4bdd5fd3e6a009bb23fb74"},{url:"assets/daxue-nuli-jisuanji.html.2b1074e1.js",revision:"269b99461af7c8e4de2b6672a6db1ed6"},{url:"assets/daxue-nuli-jisuanji.html.5d9f6906.js",revision:"736ba5c69ba7cab3b8a9a472ce7fdd90"},{url:"assets/DBeaver.html.75fbe8f6.js",revision:"d453149ad3ea09402d8efd2ec3cbdb5f"},{url:"assets/DBeaver.html.8a022161.js",revision:"537c5a4247d6224d55a6ad7e6374de7a"},{url:"assets/deep-copy.html.b367f078.js",revision:"e0a2406e1b6499e88721b8e21f44c004"},{url:"assets/deep-copy.html.b6383852.js",revision:"a0c4aa6756f54be9d03e8f998cc5e19a"},{url:"assets/deletedb-binlog-weiguanjishu.html.114e51d7.js",revision:"1d95322e12cb6a6db197eb093565edae"},{url:"assets/deletedb-binlog-weiguanjishu.html.605b28a5.js",revision:"bd5a5b97f531ad34a84c30fb9af6a895"},{url:"assets/electron-information-engineering.html.365eb9fa.js",revision:"2bc05cecd720fb5401ff5b1729639d06"},{url:"assets/electron-information-engineering.html.b3d4a3e7.js",revision:"1c61717566865bff4cfc9ca4721007c0"},{url:"assets/enum.html.21e74b14.js",revision:"812d1c9d0547cbd890fb5bc8f3cf78e3"},{url:"assets/enum.html.e72022eb.js",revision:"5c0d872a8b0247760f069e3151147baf"},{url:"assets/equals-hashcode.html.6e080022.js",revision:"cc07f78eeb7f5488a81f70e37aaa55be"},{url:"assets/equals-hashcode.html.cd3210fa.js",revision:"063e16ab8d211c0c61299a99bf635de1"},{url:"assets/equals.html.2fb94b25.js",revision:"46208de98557b94b1aa23d2d106371fb"},{url:"assets/equals.html.b49827b6.js",revision:"3f4f95c44c82dd067dfc5e39f2dcc6fc"},{url:"assets/fail-fast.html.4b8a884f.js",revision:"8f5872231ff04b187d0ad54370d91c4b"},{url:"assets/fail-fast.html.613c56f6.js",revision:"f915ae8570f88f7bacaf387886caeb5a"},{url:"assets/fanshe.html.13ada7e7.js",revision:"7b7c5fe2868eee1782f53b121e74b12f"},{url:"assets/fanshe.html.c9e51464.js",revision:"be7e84e923fc2908878786d5cb7c2ab6"},{url:"assets/fastjson.html.ac85dfcc.js",revision:"0069aa2791ea3b6ce0f8d3822bc9d48d"},{url:"assets/fastjson.html.f97ae6fd.js",revision:"a8326b550ef22ce4e613c3042cae5cb2"},{url:"assets/Filter-Interceptor-Listener.html.61c686d0.js",revision:"81596195f64c7a27e56c9004407ac9f8"},{url:"assets/Filter-Interceptor-Listener.html.d4211e38.js",revision:"8c4bcbc295b3a96eceb05bd1a0e36451"},{url:"assets/final.html.c83d9074.js",revision:"c726701bca64c1974ecb054822c85377"},{url:"assets/final.html.de436e22.js",revision:"e7a4ea72c149774b072285fa4fd9cfd6"},{url:"assets/flow-control.html.1f719486.js",revision:"eb20f449c3102a7a6a159bfe86f0ed93"},{url:"assets/flow-control.html.f6c60ead.js",revision:"40ec7db6a6132bc01f51bcdbea3fa717"},{url:"assets/forest.html.18099f01.js",revision:"8b97817fc4c133816bf6c76bd9ad8e83"},{url:"assets/forest.html.79a7cfed.js",revision:"5f057f53de7ba5b74e96f1ec60ffb21e"},{url:"assets/fork-join.html.148dd105.js",revision:"d7a62864947a9330caf495f2be574e89"},{url:"assets/fork-join.html.f967d485.js",revision:"26f31bc4133e61588d3e1ab2966e722b"},{url:"assets/fumutuanju.html.577491d1.js",revision:"d2f0d6831711758976a8c940798c4f4f"},{url:"assets/fumutuanju.html.d5b695cc.js",revision:"e376c786d472726b54bd69af3e10856e"},{url:"assets/gailan.html.87d77185.js",revision:"838f7f94a9e88620b46b4e6e7a790e1d"},{url:"assets/gailan.html.89a0a128.js",revision:"2173ae38867d7d0402473053c22ff09d"},{url:"assets/gailan.html.a5bab427.js",revision:"52ecb8199d93f479c824bea35322ffb0"},{url:"assets/gailan.html.fee068f9.js",revision:"656821687243257a5d84494525d3219d"},{url:"assets/gc.html.10f470a0.js",revision:"20aa9dc63a32b23dc46c3e2c96fc9c12"},{url:"assets/gc.html.cec6db87.js",revision:"818e2a3e352aea0b7dcfee09455162c7"},{url:"assets/generic.html.47649dca.js",revision:"21efbba6585f30fa61af2fc4c5396c58"},{url:"assets/generic.html.7ec41e80.js",revision:"2ff01c60d7d59252cfd4d4d55d0467ff"},{url:"assets/git-qiyuan.html.054515ab.js",revision:"308020a99661a2530c8989e89c509403"},{url:"assets/git-qiyuan.html.1b827703.js",revision:"35d293835ab02f0dffd2bb2a311ea1bc"},{url:"assets/go.html.528d4a75.js",revision:"0ce9693e8631b976ca6f1a55edae0f70"},{url:"assets/go.html.712c93cd.js",revision:"2ac8c637060f2eed18c6b4379a6d96b1"},{url:"assets/gson.html.da4ecf62.js",revision:"ad5c64040c19daedc3257cdf418fd5d2"},{url:"assets/gson.html.e79a454d.js",revision:"01fedf3f3911791ead09eedd7e5f410a"},{url:"assets/guangzhou.html.14bc2637.js",revision:"53d8b0cf336a5513a709252a5495d0ba"},{url:"assets/guangzhou.html.ce1033cd.js",revision:"769606116ba4a3c644639cc9d45a050b"},{url:"assets/guava.html.1f12859a.js",revision:"83816f06ae896fa50ab4d9cf0b41c572"},{url:"assets/guava.html.e73aaedd.js",revision:"9d698d9f891d7c22f3ac477808b8f998"},{url:"assets/haibukuaiyongmybatisplusshoubashoujiaoni.html.4769ffdb.js",revision:"8b1f46e7be3e7116c325dc37149193ef"},{url:"assets/haibukuaiyongmybatisplusshoubashoujiaoni.html.5f5e650f.js",revision:"928b694b6fca9b5ae2c53559b4e8647a"},{url:"assets/hangzhou.html.9719a0ea.js",revision:"a8664cfac4636b022d5588da361936d8"},{url:"assets/hangzhou.html.b80d450d.js",revision:"75901d5a04025f7d0b4ae343ab991b14"},{url:"assets/hashcode.html.24290486.js",revision:"343281510b0998fa1d048d3c5bf2b144"},{url:"assets/hashcode.html.94e85992.js",revision:"211e4f0ab2cb151c1b6bfc9bbaaebb48"},{url:"assets/hashmap-interview.html.2609e519.js",revision:"73a76b988878f178ac5f8190dcbb769b"},{url:"assets/hashmap-interview.html.307a5634.js",revision:"fe897032d2207465583c5a2783cc6364"},{url:"assets/hashmap.html.cd5a497b.js",revision:"0eff8cc7029cc583f16454f99777db5d"},{url:"assets/hashmap.html.f8e12ca4.js",revision:"64a8ec255cab16b059484b8930e0338e"},{url:"assets/hello-world.html.504deafe.js",revision:"94965ca60a6acb39f1733b4dcaebe8f7"},{url:"assets/hello-world.html.d0d5adf0.js",revision:"edf374e50da38d8b82c8dad4c5f2a9c9"},{url:"assets/highlight.esm.d982e650.js",revision:"3457767fb4f7fe757ad6fb071f162a85"},{url:"assets/history.html.6bcd3b59.js",revision:"4bb5ecbef225f144c01f31b469fc0db0"},{url:"assets/history.html.6df608e4.js",revision:"edafea3f3bb61548faac24d804cae17c"},{url:"assets/home.html.4301cc35.js",revision:"d758970d0af285d84bae538387578048"},{url:"assets/home.html.c8d9ace7.js",revision:"9a2fea3e8b91d21a04e78e8f4fff4722"},{url:"assets/how-jvm-run-zijiema-zhiling.html.400c699c.js",revision:"a1e65b5f2c56245fb14f3e212611d505"},{url:"assets/how-jvm-run-zijiema-zhiling.html.4c09b054.js",revision:"feea05b20570c3db671d2a5993af9026"},{url:"assets/how-run-java-code.html.1867de4d.js",revision:"5cf492e41232393c8b14781f521b0932"},{url:"assets/how-run-java-code.html.5a48d5a6.js",revision:"248828e5c0fe3208f8fe06a99e1e35d2"},{url:"assets/hsdb.html.18e11779.js",revision:"df785efdcc53f871f2a6a60c3117ed46"},{url:"assets/hsdb.html.e06d55d6.js",revision:"ad7a87fc50d8515780225b075b58f367"},{url:"assets/https-domain.html.847eb117.js",revision:"bf28a27b383cee8995274c7489f6c532"},{url:"assets/https-domain.html.86fa1a27.js",revision:"627dc3a525264fe4c466f4d4607a9047"},{url:"assets/hutool.html.06e72427.js",revision:"10ab5d7054f66e38c5a99dbed60d31f9"},{url:"assets/hutool.html.3a80c8b8.js",revision:"4dea5be9c2e3715cb0bb2fdc1d6577bd"},{url:"assets/image-yasuo.html.8853b749.js",revision:"f81cd85d277b957d04fd25be2cabe9df"},{url:"assets/image-yasuo.html.d1e70eaf.js",revision:"51f90fc1081296185f76fd50f8411b42"},{url:"assets/immutable.html.36fadfba.js",revision:"2c68404981e3db1079eaf013a6d08bb4"},{url:"assets/immutable.html.923c43ef.js",revision:"91365a7e046a7246c78ec6998cf2d4e7"},{url:"assets/immutable.html.e7e4c546.js",revision:"09d806a7ba458245b380ecbfbbd33163"},{url:"assets/immutable.html.fdd47709.js",revision:"55e538731a82b55cc7f6e72e291a0844"},{url:"assets/index.html.17715b69.js",revision:"9765077677330d361b2254e7b7197782"},{url:"assets/index.html.23006160.js",revision:"5eb9d1468cfdec9b1f5fa9ad2e97fc78"},{url:"assets/index.html.2971f84c.js",revision:"dcf54918ced8418b27d97f411c4896e8"},{url:"assets/index.html.698aa818.js",revision:"9c38fccd3fc6dbdfc7314582ff98359c"},{url:"assets/index.html.8360409e.js",revision:"81ef16e38cc5d294d521594523ff6b56"},{url:"assets/index.html.a4bb5c6e.js",revision:"98c0a3ad6498080673df4a2c64bbaf8f"},{url:"assets/index.html.af7b50d7.js",revision:"7cfee9d75653d5da427262a91f694572"},{url:"assets/index.html.bb2bcc18.js",revision:"5e05257eb3586e82ad59157b474d376b"},{url:"assets/index.html.ece7c54d.js",revision:"779c6c39fd36d1ca19db103ebbb20305"},{url:"assets/index.html.fd879420.js",revision:"7ffb229fbb962ecfa398ce80c7fe95ec"},{url:"assets/initializr.html.8cd24dbb.js",revision:"9fae5fceda5b5c53750e0b030633977d"},{url:"assets/initializr.html.ae05e8c2.js",revision:"3ca6703ba1f988f61fd0380b02f8d5ef"},{url:"assets/inner-class.html.5b071786.js",revision:"cc39a13e7d9b4ee3a59d309e4c269324"},{url:"assets/inner-class.html.f2dd62ed.js",revision:"9e4441914142103b191b8443b65259f1"},{url:"assets/install-baota-mianban.html.4c7a95c4.js",revision:"1e8a0627c8ad1bc1185742369b5cc5e5"},{url:"assets/install-baota-mianban.html.822010d2.js",revision:"276bbd9dc29a1fc6767713e49d2876c7"},{url:"assets/instanceof-jvm.html.845ed78f.js",revision:"943acb44bce021b556febc8afee2fdb3"},{url:"assets/instanceof-jvm.html.c9e8e080.js",revision:"492b245de203075d06ba29702c4dcde8"},{url:"assets/instanceof.html.d3be3510.js",revision:"516855dcbfebdd16e0becfbb9bd85955"},{url:"assets/instanceof.html.d3f5b0d7.js",revision:"f40cb81679cb844a227588c1d2abd1ec"},{url:"assets/int-cache.html.0d30900e.js",revision:"26b2072adfd383782dd52f78abcee302"},{url:"assets/int-cache.html.c609a3a6.js",revision:"1d50386f4ba5c89b3dcc4344345f369c"},{url:"assets/interface.html.60cd9cd7.js",revision:"129feeb8cd20f8a2ee7927ee5030b3e6"},{url:"assets/interface.html.7833e904.js",revision:"0843bf51c814ca573607ae40640f3ab4"},{url:"assets/intern.html.3d87fa6f.js",revision:"cdb3dcb855cbe196e3c21a87f9bc130b"},{url:"assets/intern.html.57f3b131.js",revision:"95d97f7770ffca894d32dd5b77405777"},{url:"assets/ioc.html.00ef348c.js",revision:"0bb230624d4ab215d0d15e3465944d9c"},{url:"assets/ioc.html.1c4cca00.js",revision:"1a2ed922af9e8cbbed111c0155a3acb5"},{url:"assets/iterator-iterable.html.967b5cf7.js",revision:"f1abd8a084a08c39689395506befb003"},{url:"assets/iterator-iterable.html.df321c38.js",revision:"c78826996742c09ebce9600eba87ef8e"},{url:"assets/jackson.html.ded110ad.js",revision:"b8bb83b89a37fee5fba205945be76cce"},{url:"assets/jackson.html.f9f2bbfc.js",revision:"4c12db7769d491fb044df2ff8aadfa4a"},{url:"assets/java-basic-34.html.70be78f8.js",revision:"237c8c8244c63138dcdf0c90c93ccf04"},{url:"assets/java-basic-34.html.ff9af0e4.js",revision:"8ebd12dc5db9f1ddaba287aaf7dfa26c"},{url:"assets/java-basic.html.0b10b00c.js",revision:"d0844d7170d4f9f021f1919d05751f67"},{url:"assets/java-basic.html.52bd7f06.js",revision:"c3eddf2b32eebe6b50723c9ac936ea4b"},{url:"assets/java-mianshi-zhinan.html.e2de50f8.js",revision:"1c19da2bdac8f0a2c359940566746c4b"},{url:"assets/java-mianshi-zhinan.html.f1a349c4.js",revision:"27ed524714e36e6f747e11622961463d"},{url:"assets/java-naming.html.cc154c6b.js",revision:"79c29d32cef2d6d5683538b29f6f268e"},{url:"assets/java-naming.html.de2604a0.js",revision:"d0f0b1a247ac19647b2a902effa60733"},{url:"assets/java-thread.html.4a99fb0e.js",revision:"7bbbed0ab8e420e38b4c2732b0814144"},{url:"assets/java-thread.html.52bdf4b1.js",revision:"a9d2f36559f90f38438bd8904264894d"},{url:"assets/java-unicode.html.17dea1e9.js",revision:"5e5b7dc64d1742c1b492b612a8947119"},{url:"assets/java-unicode.html.9e4e93b1.js",revision:"bd70784e55f2c80f63364553a992eb8b"},{url:"assets/java.html.74ed2cc3.js",revision:"d863f51d53e69896395d7e36c3cb7ba7"},{url:"assets/java.html.c5bee727.js",revision:"ff92d7c3c6e29c0a85f6a287fd0fd258"},{url:"assets/javadoc.html.6c8ace88.js",revision:"a5f77689301721a6fb08763bad174f8b"},{url:"assets/javadoc.html.b34e8efb.js",revision:"c31af3f9ce5f9fd518305e3fcdb225f0"},{url:"assets/javase.html.811355dc.js",revision:"fef28aa68cd1afd5477935b6b0a650e6"},{url:"assets/javase.html.d7cb534c.js",revision:"7ed30cd3440cc5e1d4b41c946c5e8e59"},{url:"assets/javathread.html.1bcda474.js",revision:"7f4f00e58b30cfc68de124c2100571b9"},{url:"assets/javathread.html.7f11e6a6.js",revision:"2d1ff791098e5ad42b34f76302134e29"},{url:"assets/javaxuexidaoshemechengduokeyizhaodiyifengongzuo.html.2958c9b6.js",revision:"52b7b5020f6834510875813a050532a7"},{url:"assets/javaxuexidaoshemechengduokeyizhaodiyifengongzuo.html.3289a228.js",revision:"12d21d02683e4aa784f8c9e41146d8b5"},{url:"assets/jdk-while-for-wuxian-xunhuan.html.a0c2087a.js",revision:"377ec0011e4500ccabf3598873666f28"},{url:"assets/jdk-while-for-wuxian-xunhuan.html.e352d875.js",revision:"cfbb94a92733eeb5dc75e736e4271136"},{url:"assets/jdk9-char-byte-string.html.27d20839.js",revision:"5426ec47310e95d8a1f844bda6f09f8b"},{url:"assets/jdk9-char-byte-string.html.e81be44e.js",revision:"fc680ffbdb61274f773a8c78c167bfcb"},{url:"assets/jiagoushizenyanghuizhijitongjiagoulantu.html.964131a6.js",revision:"bf1638ec69d69e3b50623bc5ea1c28b0"},{url:"assets/jiagoushizenyanghuizhijitongjiagoulantu.html.980a677a.js",revision:"e16ace455638e83fe29e4f986fdb9ed5"},{url:"assets/jianli.html.5f109d9a.js",revision:"15d97b74970a9ed75460c987d13e424a"},{url:"assets/jianli.html.75854f37.js",revision:"c55ac105b7a9147551065effa9f884ae"},{url:"assets/jibenjieshao.html.98a7aaac.js",revision:"2edfa3b02152b2341c90be667ed88b39"},{url:"assets/jibenjieshao.html.b8a08842.js",revision:"9a038bd09178c6aa49186884410c43ab"},{url:"assets/jielehenduosihuodiganchu.html.0ffa8f43.js",revision:"38131d5037ed9703e9ef9af66411768f"},{url:"assets/jielehenduosihuodiganchu.html.fa573110.js",revision:"a46912b04d963bcf87def1cc85ae2dd0"},{url:"assets/jishuzongjianbeikaichuliao.html.1774b950.js",revision:"be2f9d2b137baf32b040518ed3c3a4dd"},{url:"assets/jishuzongjianbeikaichuliao.html.1b7e52c1.js",revision:"16fba1920863afdcfe7142774cbd4425"},{url:"assets/jit.html.4cb31299.js",revision:"50f3aa2acbeee2542688d22c6a68089e"},{url:"assets/jit.html.a14bdfce.js",revision:"f6d96dbfd5dcf11323c34d5dcc7335fc"},{url:"assets/jmm.html.6df91381.js",revision:"77c3ec49a53eac6df33c65cc8a550aa3"},{url:"assets/jmm.html.7be72db5.js",revision:"f110edd5e2f6a34351d4711a3df6e513"},{url:"assets/join.html.18a0e9f8.js",revision:"f063cb40dc0cbe22866c48e5f21bd92f"},{url:"assets/join.html.bb336f49.js",revision:"42a931af30f514619d1a1efb40c96591"},{url:"assets/jpa.html.8adce5f1.js",revision:"5fcdd83233758ff2afb30ad920f7c45b"},{url:"assets/jpa.html.c4109873.js",revision:"6cf15565023a47313a765b64a89cb28d"},{url:"assets/junit.html.2436284c.js",revision:"f3af71d5609908b52eef886f9e995418"},{url:"assets/junit.html.a79d9c04.js",revision:"32794839b36ccd19cf04903dfaf361a1"},{url:"assets/jvm.html.1b4e3107.js",revision:"8f36d3c8758d9fedb2dcea99714dadcd"},{url:"assets/jvm.html.49208e4a.js",revision:"ae588fea19815644b1c028a676055a4b"},{url:"assets/jvm.html.86668e04.js",revision:"1f8b93137c686aa03c7e2c2a6a239f41"},{url:"assets/jvm.html.d7d28727.js",revision:"f251769784a32de9498129fd3ca571a4"},{url:"assets/jvm.html.dd68f45e.js",revision:"5a942829e5fa038171516b43c4953270"},{url:"assets/jvm.html.e2246150.js",revision:"15d92e60efac774585f4869d3e5bb427"},{url:"assets/jwt.html.b4f208bb.js",revision:"ccd1e1cf1ba2d50e4abd7ee39cd0ae5f"},{url:"assets/jwt.html.e910af0e.js",revision:"a3780a9458370ad9b482537d1523cded"},{url:"assets/knife4j.html.44253ad0.js",revision:"385a5caa23eda5eff1ace58f296a2a3e"},{url:"assets/knife4j.html.fe2f8e7d.js",revision:"c0ac4a924dda5665b7417f7a2a6401bc"},{url:"assets/Lambda.html.16e88b8a.js",revision:"2baff2891bd9c1c3990a0313478465fb"},{url:"assets/Lambda.html.997b367a.js",revision:"52eb395fd4e37f0de01811421653e900"},{url:"assets/lanqiaobei.html.17699093.js",revision:"5d54156cabbd398cd05a10f3531bb1f1"},{url:"assets/lanqiaobei.html.489bde40.js",revision:"a4d7068d010bc0535408397d8058b7d4"},{url:"assets/Layout.fbcb8daf.js",revision:"57a7b7742bad3b26bc61ff85610fca1d"},{url:"assets/learn-jianyi.html.1b72d4e2.js",revision:"7d563c363a3d4debd307277bf1a00e67"},{url:"assets/learn-jianyi.html.453bb02b.js",revision:"6595bb01076909c24eb0c8fe6dc47111"},{url:"assets/linkedlist.html.4b75cd4d.js",revision:"6090cbb008975cdb58a40f0fa0be1d54"},{url:"assets/linkedlist.html.8ede144e.js",revision:"e2adcd892b90191c375cf979328cb124"},{url:"assets/list-war-2.html.96808d02.js",revision:"3b86913919e7dcefe3e3ed56acf603bc"},{url:"assets/list-war-2.html.b8fa44fb.js",revision:"cf2ab3c2e799ec10f657d9e2f4dfb65a"},{url:"assets/lock.html.5385ecc8.js",revision:"894e93c8012594ae038f4cd857ff50af"},{url:"assets/lock.html.a13afff5.js",revision:"4e14aba7725bc02a1d30bac119afc09e"},{url:"assets/LockSupport.html.55f27ea8.js",revision:"4509c39f21dc1b7794fa184580b902fa"},{url:"assets/LockSupport.html.c7d00cfa.js",revision:"86fdd35f48637ac9a5971fb6e44211d5"},{url:"assets/log4j.html.14af993a.js",revision:"fa18ccbd6f734f1b12871ec7f9101f6f"},{url:"assets/log4j.html.dbbf9c72.js",revision:"67e430c30df558f23615642855b86b4b"},{url:"assets/log4j2.html.17000ac4.js",revision:"90e9aafd35dcfe703a98405ea81e76fb"},{url:"assets/log4j2.html.9b5a6f13.js",revision:"74f7162c5d876ef41a09955483435f9e"},{url:"assets/log4j2.html.b3fd06a7.js",revision:"88ff3344444cc2680ddf3e4964c09932"},{url:"assets/log4j2.html.f846d981.js",revision:"315c6425ff5e422ac48ce864e480c556"},{url:"assets/logback.html.65200f68.js",revision:"99ff0e11926dffeb463547098f575415"},{url:"assets/logback.html.869073f6.js",revision:"d5223d64f50889bdc9d50d965e70ee25"},{url:"assets/logback.html.a9628274.js",revision:"5f741c93179b5d8653029776f2026245"},{url:"assets/logback.html.bd3bc959.js",revision:"e0c83478a6edc7cfb4c9293828805a67"},{url:"assets/macos-codingmore-run.html.984613a6.js",revision:"432697905076a8fbb164a4c562d60153"},{url:"assets/macos-codingmore-run.html.f9eb5e90.js",revision:"65ac7cb80f7fc73e7c725acffb01d60a"},{url:"assets/map.html.61b4c4d9.js",revision:"ee7b54575d224a18084ced9daef43bef"},{url:"assets/map.html.ae80f8e6.js",revision:"4caefbc89b1e006c195441565f03be8c"},{url:"assets/markdown.esm.832a189d.js",revision:"4aa467006f9d51cf40293b9b69a0f27a"},{url:"assets/math.esm.a3f84b6f.js",revision:"cbf844f27edbc061c86ae840d70389f6"},{url:"assets/maven.html.9abc8500.js",revision:"130269025dfd59613d1fff9792147291"},{url:"assets/maven.html.abe414c5.js",revision:"076fa6654bcdb82ab1f5d1713ee11a4e"},{url:"assets/meituan-9-gc.html.26985c28.js",revision:"4a5771024009b0a739e52737ae65e694"},{url:"assets/meituan-9-gc.html.f5a5b89a.js",revision:"244a3f55b6939ca3553511b02032c9dd"},{url:"assets/method.html.4d951864.js",revision:"561b699c5536ab7660ef94c27166a830"},{url:"assets/method.html.67a1e169.js",revision:"81adfc29a24683c32d90cc8794268020"},{url:"assets/mybatis.html.7c33d756.js",revision:"64a1c8c0d21437565c6f4ed7e5b6adff"},{url:"assets/mybatis.html.a18a9ce2.js",revision:"35392edbf862d52bb9cc537e3051fd6d"},{url:"assets/mysql-druid.html.adb4afdf.js",revision:"49b00ed5b34555978e93954f0b80284c"},{url:"assets/mysql-druid.html.bf232591.js",revision:"08d563c142cd060746812f72c1e847ac"},{url:"assets/mysql.html.99fca397.js",revision:"f74dbe6f78163ad33b0c9a819ebfc3ca"},{url:"assets/mysql.html.ecb0e241.js",revision:"b37542a34de8a33a5ab7d015f9642c30"},{url:"assets/nanjing.html.0381e4b6.js",revision:"f82603d61971f03e213bec489f7483b8"},{url:"assets/nanjing.html.df603525.js",revision:"4dc3142c0b3fb0716fecb72338e2e04c"},{url:"assets/neicun-jiegou.html.e6842a53.js",revision:"0e8cd7e0860ae65966f8f9f9e7d8860b"},{url:"assets/neicun-jiegou.html.f0fca3bb.js",revision:"6daf0b5605744cbaf3254818812ac171"},{url:"assets/nginx.html.30b3f8bd.js",revision:"e56a026b92bb238559dfb22897ba34d4"},{url:"assets/nginx.html.baa53af7.js",revision:"cac80db53f25790ef648e13b4e453d30"},{url:"assets/nicearticle.html.aa656631.js",revision:"c208a0b05c0ce03a2204e5247614f16b"},{url:"assets/nicearticle.html.b56e678a.js",revision:"e7e94ff20e83310751fc0c814a6b1e7c"},{url:"assets/nixi.html.8b48857f.js",revision:"b1837463dfbce0768edd5bc0c3d8aa2b"},{url:"assets/nixi.html.c022f9fe.js",revision:"045fae1de49d81b344c5fb968595c21b"},{url:"assets/notes.esm.3c361cb7.js",revision:"eda65c99450fe02da90bde90cc614a56"},{url:"assets/npe.html.01d29f9c.js",revision:"8134ca774480ebc279a182e672a77470"},{url:"assets/npe.html.a94a2b73.js",revision:"66e85fa3c9bd617e71aef72c2fc50721"},{url:"assets/object-class.html.85420110.js",revision:"bc2a562c613c3bb7f2f64d53055c00b4"},{url:"assets/object-class.html.96fd3d4e.js",revision:"7c0d8c62872d08455d76420035ad64d0"},{url:"assets/oom.html.23228526.js",revision:"0ac9680baff3b41388b27b97b55c779a"},{url:"assets/oom.html.d0512b48.js",revision:"93efae323573b93b0f9515ce535c48e2"},{url:"assets/operator.html.783e87f0.js",revision:"067632a95ff14350a9c0dbaa8043a081"},{url:"assets/operator.html.9431d9fc.js",revision:"dd2606884797f6115086577981cdf630"},{url:"assets/optional.html.23c0a140.js",revision:"841574f000bebb802ad9b5fb7622fb98"},{url:"assets/optional.html.d38ec385.js",revision:"f005ae616fadd25c6a691cce822177a2"},{url:"assets/os.html.2d6bc714.js",revision:"f5854cb64198e2a1343936759eaabefb"},{url:"assets/os.html.34768944.js",revision:"2a3c72e94e5fea9ccc7c3521fd120a18"},{url:"assets/os.html.5e6a959a.js",revision:"0d3240c88a18a8d4ba5ab1f0deb2ed9f"},{url:"assets/os.html.e10e307f.js",revision:"909af4697ba5591c1f135378ed615ec3"},{url:"assets/oss.html.977b34d5.js",revision:"0d465fc3df511397ec1edf06998aee67"},{url:"assets/oss.html.b690f015.js",revision:"b7a47348483781616244a67c37f83f98"},{url:"assets/others.html.214194b1.js",revision:"8d7ba5f70bee9e9a63930a914433a630"},{url:"assets/others.html.ed8fcf05.js",revision:"e6fd1a8c5da4b15d4670159a24ef9506"},{url:"assets/override-overload.html.853755f9.js",revision:"d45c9a74558064478148d168cd9079ff"},{url:"assets/override-overload.html.f7d74176.js",revision:"3ee9ca1d6b6aefe5fb57084f0cc15e15"},{url:"assets/Overriding.html.14f830f8.js",revision:"782d5974e1b4f6d2acc30324bd737ad1"},{url:"assets/Overriding.html.e0ccdfe1.js",revision:"0b6076e487741b3805b15c5b98911313"},{url:"assets/pass-by-value.html.c65b64be.js",revision:"7d694685a0fc4be50eb207ca1ffded4a"},{url:"assets/pass-by-value.html.e26c3cdc.js",revision:"3010545820acbe8927e256f4ae13fecd"},{url:"assets/pdf.html.0610fb03.js",revision:"b565bdf33dc4037ef563d75eae673328"},{url:"assets/pdf.html.a28195f1.js",revision:"2878368c7793e0fab9367fd05c73e020"},{url:"assets/photoswipe.esm.92018b73.js",revision:"442a3264b1db7eb84ffc880407e7565d"},{url:"assets/plugin-vue_export-helper.21dcd24c.js",revision:"b29b145139fc88e89a46af507277557d"},{url:"assets/pool.html.1918e02b.js",revision:"837fd39732d9eb3df1e143bd77b9e1cb"},{url:"assets/pool.html.79813894.js",revision:"bc2c2fe355c3cf059f48487593389bd5"},{url:"assets/print.html.6fe8360d.js",revision:"7a5cd0b01b2c354dccd58c55ccc7af88"},{url:"assets/print.html.f0b4f56c.js",revision:"76117f8b201814952dd41406c9dcd329"},{url:"assets/problem-tools.html.c2bda786.js",revision:"bed221d11bfdeb435b34f98d164eb40d"},{url:"assets/problem-tools.html.fab08888.js",revision:"8abd2eb80f2525872d9d8f8d2480a0d2"},{url:"assets/progit.html.3b6ba984.js",revision:"022afdb6ab50022afca061f3ddca45bd"},{url:"assets/progit.html.66c47307.js",revision:"6ba948e6b6bc2ecd1d41a55150294f11"},{url:"assets/progit.html.a119468c.js",revision:"ff8fc203f93f6c67a16915eb0c9b6659"},{url:"assets/progit.html.de3011f5.js",revision:"46f03fd0dac1d5629b10a3960488eead"},{url:"assets/python.html.a467fb74.js",revision:"73ccde0eecc64ad7696411f289412dce"},{url:"assets/python.html.e5ae48ee.js",revision:"9b8d3fc3b99b58da0837193ad81b5fd2"},{url:"assets/qianduan.html.60a6bdee.js",revision:"35978d85c765d5d8cd1639200f5caecd"},{url:"assets/qianduan.html.61a4f111.js",revision:"80491ad5e938d271d8cd2be59f02e2fb"},{url:"assets/qingdao.html.026cf757.js",revision:"9c22c7aebf13970e1de6b7c414f98913"},{url:"assets/qingdao.html.08ca70e9.js",revision:"bb859290ac3fc12eba26e75fe8f5b802"},{url:"assets/rabbitmq-rumen.html.1f0066c6.js",revision:"67e3b3b57c9a055c1f7ddd6a077fd788"},{url:"assets/rabbitmq-rumen.html.719aebed.js",revision:"c46e205bc4c973750050da2f087881cf"},{url:"assets/read-csapp.html.23c82cf4.js",revision:"a7fd47941c0303f526d229d22bc5bebe"},{url:"assets/read-csapp.html.f8f796e3.js",revision:"e9e918d773fb5536fe0513b71db19461"},{url:"assets/record-domain.html.19eb33ac.js",revision:"ae3885dae0dfab43a95aec90eb42ad05"},{url:"assets/record-domain.html.9b78d780.js",revision:"25073fcf5de280aa941a16587e155c35"},{url:"assets/redis-shuju-yizhixing.html.0d2d7824.js",revision:"af7f27a164f234c07500ae1210fe53bf"},{url:"assets/redis-shuju-yizhixing.html.7e461ea4.js",revision:"10ef9457c692f9195709abcc5a8b7ab2"},{url:"assets/redis-springboot.html.5e59844d.js",revision:"dea925fe16de704907dcabf395abd223"},{url:"assets/redis-springboot.html.7783ee99.js",revision:"e922581e78ef66064910118caf756706"},{url:"assets/redis.html.7543ed9c.js",revision:"7cef164fb0c3fff043d1779afd9b10ff"},{url:"assets/redis.html.b039ba47.js",revision:"250ee45056172fee92c332e9bb8f2fdf"},{url:"assets/redis12question.html.58f0e7e0.js",revision:"1ca878de7522dd7bd5f7d4780449386b"},{url:"assets/redis12question.html.bab032b9.js",revision:"28a1a6ef3eb9871a2b25b6e778f76c62"},{url:"assets/reentrantLock.html.002f84e4.js",revision:"475486341b8257def0a182f7945de2b6"},{url:"assets/reentrantLock.html.d3a77dd6.js",revision:"dc734975ea206c4e54f66084b0fbaf18"},{url:"assets/ReentrantReadWriteLock.html.b8dcb20a.js",revision:"90326681a60b10eddd78a6858f1d801c"},{url:"assets/ReentrantReadWriteLock.html.d1bd972f.js",revision:"95da940d4221ddc04eec2e3b5ae8996f"},{url:"assets/reveal.esm.b96f05d8.js",revision:"f78a424fad98faac5d5ca8ebfbebe94b"},{url:"assets/rumen.html.28382740.js",revision:"bbb73cc8ff60526c113c7b1d16cc8eaf"},{url:"assets/rumen.html.4002e397.js",revision:"bde6352cc806daae21f11801b204396a"},{url:"assets/rumen.html.439110fe.js",revision:"f9d14e2ffb8e54b030f7d1c3067c183f"},{url:"assets/rumen.html.9cc17590.js",revision:"d296a715b51d7987e19356f118decea2"},{url:"assets/rumen.html.e13dbda5.js",revision:"9f529477271a37fdf0fbaec594e6d279"},{url:"assets/rumen.html.f241efd5.js",revision:"1fe77771f6461d4ae08440f61b884db6"},{url:"assets/ScheduledThreadPoolExecutor.html.8d668046.js",revision:"b29b0a101162737afa347106c650739f"},{url:"assets/ScheduledThreadPoolExecutor.html.e216d19d.js",revision:"d7cac3e2bd93d4a33022269f57ea1c61"},{url:"assets/search.esm.80da4a02.js",revision:"690b84c66badd2f8fa69d57bc7cdad19"},{url:"assets/shanganaliyun.html.04eee07a.js",revision:"f74774689b9aa40eb6a262a3cc4e9ae6"},{url:"assets/shanganaliyun.html.fc60e761.js",revision:"7a547e4cebb9442d2d55264730cb69b4"},{url:"assets/shangtou.html.dd79a90f.js",revision:"e491b924cd35190389b7819a21f19b1c"},{url:"assets/shangtou.html.fc7b3e84.js",revision:"99ebcada07953a03647797ca8ac78d6d"},{url:"assets/shengchanzhe-xiaofeizhe.html.0915b865.js",revision:"ee8bb756f0323bf506becbb4280e574f"},{url:"assets/shengchanzhe-xiaofeizhe.html.920a9bd9.js",revision:"66646c5a3419d9abf637bd65e65f42b6"},{url:"assets/shenzhen.html.037e48a5.js",revision:"0b7bf5142143caa172281b8e0ad836e0"},{url:"assets/shenzhen.html.48307e94.js",revision:"08f6a9737e76ef1fb3fabc1d5d079a9e"},{url:"assets/shijian.html.0924a1ec.js",revision:"326c95b32e23cf74836881972d518432"},{url:"assets/shijian.html.84eb0eab.js",revision:"4dbc437b451a39b90d4a74a0bdc97b98"},{url:"assets/SkipLink.e761490e.js",revision:"54521e1d60b624f654367c68da84b3de"},{url:"assets/slf4j.html.2fd3dca6.js",revision:"c2fc64d88ebde1e5685aabe77a9ac3c1"},{url:"assets/slf4j.html.a17cdf5a.js",revision:"bae89fe3c0cb150a3fb11eae01652b58"},{url:"assets/Slide.a2a8944b.js",revision:"cd582e08e9af7c3d7fc6abe34adf3aaf"},{url:"assets/split.html.0ff2ce60.js",revision:"782e517f1be73a462dbb3572b55d8b68"},{url:"assets/split.html.dbaed6aa.js",revision:"89085a9e4a896659a73fa7fe1cbc4a22"},{url:"assets/spring.html.26f406c7.js",revision:"758c9ad3fcab916d834f646a448d0338"},{url:"assets/spring.html.75b19ea2.js",revision:"ce83e6c73d54a4eb2d2be0d6b78add4d"},{url:"assets/springtask.html.0afe6499.js",revision:"a171cf83881da1c96a2393ede86661e6"},{url:"assets/springtask.html.406633ab.js",revision:"2c8469c8fef9182a9019ffeab34e427e"},{url:"assets/static.html.1a009c06.js",revision:"3d3bdf938d69191f52064821d34cda66"},{url:"assets/static.html.8ee519bc.js",revision:"67e5eaf877e1d15b4e0f59a90601207e"},{url:"assets/stream.html.214aab27.js",revision:"02b20169ec8176d859a10ee4b41683b8"},{url:"assets/stream.html.db791f6b.js",revision:"8fee3aa06ed24c86079dc71ef48deabb"},{url:"assets/style.aa7884a9.css",revision:"b50231da484889a39c0d651cca018162"},{url:"assets/suzhou.html.1f658a4a.js",revision:"846af1d45e4efd0c3660b7c5e1173317"},{url:"assets/suzhou.html.e601b996.js",revision:"3f034c9d682616a27c5ef859ea60bb66"},{url:"assets/swagger.html.03ed15b7.js",revision:"7d4ae48935211839162f9171080c9388"},{url:"assets/swagger.html.d41c975f.js",revision:"a61c6105c7f8b9bb9bdea8633a103010"},{url:"assets/synchronized.html.2e0681cb.js",revision:"7b7fbb1e7c45aa1baed8b65e0f3ddeb4"},{url:"assets/synchronized.html.6094d556.js",revision:"50bb92e6064fb1eeace2b8badcce12ec"},{url:"assets/tabby.html.5c93d604.js",revision:"8bd45d10a90dce8fbd27dea748fb8f4e"},{url:"assets/tabby.html.8b43d084.js",revision:"fede60fdff4466bc0faa5a7c3f40a97e"},{url:"assets/this-super.html.5e8e4dee.js",revision:"6959318dceb1280c4921ad145cb6e999"},{url:"assets/this-super.html.65fa5da3.js",revision:"db3b96963f5594951739fe2924632a42"},{url:"assets/thread-bring-some-problem.html.b2f11eb4.js",revision:"00349bd3d5d9eab7436c7f71a6265f21"},{url:"assets/thread-bring-some-problem.html.c8ae3e7a.js",revision:"d30408042adbdeca4ce50a59c6901032"},{url:"assets/thread-group-and-thread-priority.html.041c72b9.js",revision:"a580897167d73be0081440f27ebb6953"},{url:"assets/thread-group-and-thread-priority.html.873709ce.js",revision:"4e54397c857c1341cd41f1cfff69ebb1"},{url:"assets/thread-state-and-method.html.70b8e2e8.js",revision:"99fbdee5498a36cf4161dea3e2aebd57"},{url:"assets/thread-state-and-method.html.a628789d.js",revision:"38caa39040618ad8817192498aba1490"},{url:"assets/thread.html.34ab4613.js",revision:"1ed2cba245361944bd4249f6f3efe4fd"},{url:"assets/thread.html.a2ddbdf4.js",revision:"e26707f39be07566aa9dd5ed981203fc"},{url:"assets/ThreadLocal.html.284cf60c.js",revision:"db18156b7915ff973693738f5cdca36e"},{url:"assets/ThreadLocal.html.f9a6fed8.js",revision:"e5f398cec6e9663ba5b58fe6a2a1ba63"},{url:"assets/thymeleaf.html.1a24ed99.js",revision:"82ebee28f65a7bb4d977a64f989cb51d"},{url:"assets/thymeleaf.html.be244969.js",revision:"16117c12383d9c9563d228a33b1f87c0"},{url:"assets/tobebetterjavaer-wangzhan-shangxian.html.88c8d82b.js",revision:"3f845205eb517c8545f12eb97dc2c6e6"},{url:"assets/tobebetterjavaer-wangzhan-shangxian.html.a80895d2.js",revision:"1023c6d0dadb6420952b89fd749a6adc"},{url:"assets/tomcat.html.3d86b543.js",revision:"1f99f1e50589817b662b845d4400fb7e"},{url:"assets/tomcat.html.73ec3645.js",revision:"7a7b107c1633a13d2190549cb6e03310"},{url:"assets/transaction.html.89e3579f.js",revision:"4ad31c0173126490d2c7fb5240de5189"},{url:"assets/transaction.html.c6ea47a0.js",revision:"42993d04a7f1aaf48e535999dea1ae9a"},{url:"assets/true-generic.html.ce09d792.js",revision:"7b33c1c5dbde75dd4deedd61ff4ffbb0"},{url:"assets/true-generic.html.dbcaca38.js",revision:"5387bcf38d38f6f8241d942780beaab0"},{url:"assets/try-with-resouces.html.8dcef913.js",revision:"7803c62919343844326660cb01e85fd9"},{url:"assets/try-with-resouces.html.c242816c.js",revision:"728d91bf8ced750a35cdc7b9574451aa"},{url:"assets/tujie-gc.html.70c281f0.js",revision:"ce356633834f92c1cd1da052ae68744b"},{url:"assets/tujie-gc.html.ca2dffab.js",revision:"a7928789b0d96cef153aaf643807441e"},{url:"assets/tupian-zhuanlian.html.7ab13c07.js",revision:"11bbf9bb17b695c73038945d2d3ff5e3"},{url:"assets/tupian-zhuanlian.html.7e57c89c.js",revision:"7e1674d2805cf5ee44fe8ba3c61ff9ae"},{url:"assets/var.html.7a0cfd0f.js",revision:"44e56a632667ab8dc6fda19d2e951b8a"},{url:"assets/var.html.d8139bc5.js",revision:"ed904714ae226b2decffa24f2eacbe5d"},{url:"assets/varables.html.4e32dd4f.js",revision:"6bed702dc516532db5a9dc96b36cb612"},{url:"assets/varables.html.6a80fc0e.js",revision:"b5d838edc69034b99358140c53b3dacb"},{url:"assets/volatile.html.26279f7f.js",revision:"8b7c26f79da9fab23d11327674fb4d5e"},{url:"assets/volatile.html.e6448db8.js",revision:"390f312d9aff6c5ee73f4923775645f4"},{url:"assets/waibao-1geyue.html.1edb2375.js",revision:"62cfe898d4bd30af9a99ab2227e16707"},{url:"assets/waibao-1geyue.html.fbddc89c.js",revision:"e015d6b16e709b6ccb97dce4163bb984"},{url:"assets/wangluo.html.b41cb57f.js",revision:"57732b795849149a6667300feb6a38da"},{url:"assets/wangluo.html.bd9e0045.js",revision:"cc49e89fa88e4a25617ed12742bf7e35"},{url:"assets/wangzhe-thread.html.6222c220.js",revision:"1d9c4b8cf884c8ae50113e0f2266de1f"},{url:"assets/wangzhe-thread.html.dda72253.js",revision:"a93511501818791c302deaac765b4e15"},{url:"assets/warp.html.4380b228.js",revision:"1c7cd7539426cb69c99eefa6ad943b27"},{url:"assets/warp.html.f8427955.js",revision:"a8147515ec33c33e597146b09fde6819"},{url:"assets/weixin-chengxwjdwzhqcgxm.html.18dc866d.js",revision:"b566da699481353a4ad2423995f7d8eb"},{url:"assets/weixin-chengxwjdwzhqcgxm.html.63b423d3.js",revision:"08f08725340b7914634d931e9565eee1"},{url:"assets/weixin-liaoliaoxianliu.html.3a09df17.js",revision:"dae2d4600f6c3291f9a9b226fbb2ed94"},{url:"assets/weixin-liaoliaoxianliu.html.624e17ae.js",revision:"6f5c07a29b2398416dfc5164c9f08d11"},{url:"assets/weixin-xinllgjszjszzpojozsyjbsjlxyhjfyll.html.5d76cb3c.js",revision:"d6d2c77b978c31bbdf8dc4844d8904e2"},{url:"assets/weixin-xinllgjszjszzpojozsyjbsjlxyhjfyll.html.8f640dc9.js",revision:"873bcfb3534b542706c75db73ec1afeb"},{url:"assets/weixin-zhongxcwbztashjjavahdmj.html.844aa3a1.js",revision:"7003350e84221429c44952436b05dd9a"},{url:"assets/weixin-zhongxcwbztashjjavahdmj.html.c99fcea1.js",revision:"a052baeca51a1b5135bcbeabb668c02b"},{url:"assets/weixin-zuixinbujiabandigongsimingdan.html.4000ddf4.js",revision:"9eed8a4a102a4cc78d122a3e011e7049"},{url:"assets/weixin-zuixinbujiabandigongsimingdan.html.bf87a7d5.js",revision:"6b31f97d80d9263648f800c7917b6bb4"},{url:"assets/what-happen-when-javac.html.a3ce0b44.js",revision:"42c7e44c613574a578d74096efe01d2f"},{url:"assets/what-happen-when-javac.html.ab4282c1.js",revision:"aec391454b1d49aea2d1ca364b27bbad"},{url:"assets/what-is-java.html.b724e432.js",revision:"ea158f9a6749d586eb5eb1a5fe867369"},{url:"assets/what-is-java.html.e968650c.js",revision:"cc20699b18eeea54e34295ba931c47fa"},{url:"assets/what-is-jvm.html.0a353155.js",revision:"edd246cd16496858099299f0696c1087"},{url:"assets/what-is-jvm.html.5131a239.js",revision:"2428430ef6fd17693a8d67d339efdbaf"},{url:"assets/whereis-the-object.html.c695df3e.js",revision:"40f9a605c5d9174441138c22b4df9205"},{url:"assets/whereis-the-object.html.f6879982.js",revision:"ca5a79eb3f6ed2aa0ab81ec83b5bba2a"},{url:"assets/why-need-thread.html.08014ce1.js",revision:"6c01c036dc648c890fbfdd5e28f87e4d"},{url:"assets/why-need-thread.html.507a940d.js",revision:"d4a7d960b4a4125ab55a9d577d1e8360"},{url:"assets/windows-codingmore-run.html.4fb12f5d.js",revision:"f04ddd8be0190d2ab997ba3fb27c8269"},{url:"assets/windows-codingmore-run.html.dcfb09e6.js",revision:"63df4f9d6bc0fe10f59d0ffde6a98199"},{url:"assets/xian.html.4603b6ae.js",revision:"88e71576d1ffd5bf997516b27b15af5d"},{url:"assets/xian.html.4a14941e.js",revision:"a5aa79b165040c96a5e1df77243832e6"},{url:"assets/xuebeng-chuantou-jichuan.html.26ef04a3.js",revision:"c10aab87bc0050f68ba50c3693861364"},{url:"assets/xuebeng-chuantou-jichuan.html.37293204.js",revision:"ea40dd88aa8d13e3dbd82e8f9a979d23"},{url:"assets/yanjiusuo-20wan.html.76b660c5.js",revision:"6cb110df442468ed54c8c39e2aed9685"},{url:"assets/yanjiusuo-20wan.html.a3e5343d.js",revision:"4a563a9c75147dfef1746b4389d8b71e"},{url:"assets/yitiaolong.html.0ffd862a.js",revision:"740513e76f9f97d6e3f30dfbddf7ace9"},{url:"assets/yitiaolong.html.6c191a66.js",revision:"acb3a943f46a1d68702ca75a03393220"},{url:"assets/yuanyifeng-c-language.html.1d18c5bc.js",revision:"a5306018e680b76dd88b44e8c84eec13"},{url:"assets/yuanyifeng-c-language.html.869263b3.js",revision:"bde02e954e45c225526b4d850ce69208"},{url:"assets/yuneban-wangyiyunyinyue.html.275a589e.js",revision:"02439e9c34e5ddec3bd616d8d036bb42"},{url:"assets/yuneban-wangyiyunyinyue.html.df2c1c62.js",revision:"acc4d0a3460f9e2fa8a12a055dc88a84"},{url:"assets/zhengzhou.html.43c30f38.js",revision:"2e4816d18e8f7f517b7c9e4c505990ef"},{url:"assets/zhengzhou.html.5cf8ec33.js",revision:"90e422e005b09a42e236f9a026fb9ebd"},{url:"assets/zhihu-1000wan.html.4bf2b6f4.js",revision:"677db386556c4a3b1c5368584a949dde"},{url:"assets/zhihu-1000wan.html.6f71965a.js",revision:"3a8e4ddc6b42095726232265b937f2fa"},{url:"assets/ZHIHUjavaxuexidaoshemechengduokeyizhaodiyifengongzuo.html.9b7b6461.js",revision:"766ece7f596b094402ebd363b7150acd"},{url:"assets/ZHIHUjavaxuexidaoshemechengduokeyizhaodiyifengongzuo.html.e4fead09.js",revision:"c265404944c7ef4afe301786011a3ab7"},{url:"assets/zijiema-zhiling.html.34c655bc.js",revision:"203ba55ffb1e89f9bb2fe0482a78a416"},{url:"assets/zijiema-zhiling.html.9c4d95e9.js",revision:"81c3019459f46aaa852c4110f3f4794d"},{url:"assets/zongjie.html.0af46efc.js",revision:"e52012e5b38812dd1a06d5656f2acd45"},{url:"assets/zongjie.html.c9e5e3c3.js",revision:"bfa15e84daf91ca3742016d07bbb8252"},{url:"assets/zoom.esm.8514a202.js",revision:"8b3ee4f6f71ef2a7c85901cba6d23344"},{url:"logo.svg",revision:"d7efe218a18b0891e803f61130d971ea"},{url:"assets/league-gothic.38fcc721.ttf",revision:"91295fa87df918411b49b7531da5d558"},{url:"assets/league-gothic.5eef6df8.woff",revision:"cd382dc8a9d6317864b5810a320effc5"},{url:"assets/league-gothic.8802c66a.eot",revision:"9900a4643cc63c5d8f969d2196f72572"},{url:"assets/source-sans-pro-italic.05d3615f.woff",revision:"e74f0128884561828ce8c9cf5c284ab8"},{url:"assets/source-sans-pro-italic.ad4b0799.eot",revision:"72217712eb8d28872e7069322f3fda23"},{url:"assets/source-sans-pro-italic.d13268af.ttf",revision:"8256cfd7e4017a7690814879409212cd"},{url:"assets/source-sans-pro-regular.c1865d89.ttf",revision:"2da39ecf9246383937da11b44b7bd9b4"},{url:"assets/source-sans-pro-regular.d4eaa48b.woff",revision:"e7acc589bb558fe58936a853f570193c"},{url:"assets/source-sans-pro-regular.dce8869d.eot",revision:"1d71438462d532b62b05cdd7e6d7197d"},{url:"assets/source-sans-pro-semibold.a53e2723.ttf",revision:"f3565095e6c9158140444970f5a2c5ed"},{url:"assets/source-sans-pro-semibold.b0abd273.woff",revision:"1cb8e94f1185f1131a0c895165998f2b"},{url:"assets/source-sans-pro-semibold.ebb8918d.eot",revision:"0f3da1edf1b5c6a94a6ad948a7664451"},{url:"assets/source-sans-pro-semibolditalic.7225cacc.woff",revision:"6b058fc2634b01d837c3432316c3141f"},{url:"assets/source-sans-pro-semibolditalic.dfe0b47a.eot",revision:"58153ac7194e141d1e73ea88c6b63861"},{url:"assets/source-sans-pro-semibolditalic.e8ec22b6.ttf",revision:"c7e698a4d0956f4a939f42a05685bbf5"},{url:"index.html",revision:"bd822ecbc08f5808bb04831910c814f2"},{url:"404.html",revision:"a0e3d4269fde8726e34d81a073eee7f8"},{url:"assets/icon/apple-icon-152.png",revision:"d78854fc622a0bfa2a44a79ec8b6e561"},{url:"assets/icon/chrome-192.png",revision:"eaab382db5bb589c74e2720a777454c3"},{url:"assets/icon/chrome-512.png",revision:"5db9d4a587b378f0b283191e379d85fa"},{url:"assets/icon/chrome-mask-192.png",revision:"eaab382db5bb589c74e2720a777454c3"},{url:"assets/icon/chrome-mask-512.png",revision:"5db9d4a587b378f0b283191e379d85fa"},{url:"assets/icon/itwanger-282.png",revision:"85592fba02d1228f8ca3e842cef07b7c"},{url:"assets/icon/itwanger-maskable.png",revision:"ca6a86caa8171a39adfd0f53f10cdaf2"},{url:"assets/icon/itwanger-monochrome.png",revision:"ca6a86caa8171a39adfd0f53f10cdaf2"},{url:"assets/icon/ms-icon-144.png",revision:"983a00416fc5f5469a79611440389396"},{url:"logo.png",revision:"d30ac8bc232973da730e934321ffeb7f"}],{}),s.cleanupOutdatedCaches()})); +if(!self.define){let s,e={};const a=(a,i)=>(a=new URL(a+".js",i).href,e[a]||new Promise((e=>{if("document"in self){const s=document.createElement("script");s.src=a,s.onload=e,document.head.appendChild(s)}else s=a,importScripts(a),e()})).then((()=>{let s=e[a];if(!s)throw new Error(`Module ${a} didn’t register its module`);return s})));self.define=(i,c)=>{const d=s||("document"in self?document.currentScript.src:"")||location.href;if(e[d])return;let b={};const f=s=>a(s,d),r={module:{uri:d},exports:b,require:f};e[d]=Promise.all(i.map((s=>r[s]||f(s)))).then((s=>(c(...s),b)))}}define(["./workbox-2572b17b"],(function(s){"use strict";s.setCacheNameDetails({prefix:"Java 程序员进阶之路"}),self.addEventListener("message",(s=>{s.data&&"SKIP_WAITING"===s.data.type&&self.skipWaiting()})),s.clientsClaim(),s.precacheAndRoute([{url:"assets/100-budiushi.html.281fc989.js",revision:"e5349f110a8223b768c7073e1c050248"},{url:"assets/100-budiushi.html.c3040dbf.js",revision:"5e2fdf602f4f9cfe989cd2ecee4c6e1b"},{url:"assets/4-debug-skill.html.0c72ed75.js",revision:"8f688bdfdb736a05c83bbb082378b4b1"},{url:"assets/4-debug-skill.html.9bd076fc.js",revision:"bdd75149e13482f9c53f9ea3e0a36927"},{url:"assets/40-interview.html.2cb0fe6c.js",revision:"b73bdbdbc6bdccce1a2a65eb0e4a34ba"},{url:"assets/40-interview.html.e460eeeb.js",revision:"59d292b1b8fd01e114ec8b92c60aa830"},{url:"assets/404.c61acaed.js",revision:"28aa9123b38d4a0ac28fbf5ff1462d67"},{url:"assets/404.html.6cb935de.js",revision:"12251408caddfaa21efe1731e77d78f4"},{url:"assets/404.html.e75684b7.js",revision:"19f495e79edd1b6a31d59cc9804d8602"},{url:"assets/48-keywords.html.c30c9b30.js",revision:"1018ecb3e0471868b71b0be0edceb6f4"},{url:"assets/48-keywords.html.e76832ee.js",revision:"0f28937c5f2199e1fb19617c0169cc05"},{url:"assets/abstract.html.3094fdb5.js",revision:"3f1e0182c50046175b9a0df0660d37e9"},{url:"assets/abstract.html.e17df797.js",revision:"5d861ea8503b0e335a5e76b1c3e784ff"},{url:"assets/algorithm.html.14390f00.js",revision:"cbe7a405e3cfcc0ad60ef4bffc3765fb"},{url:"assets/algorithm.html.8d44122f.js",revision:"81cb024c205170c12555c527fff76bc4"},{url:"assets/ali-executors.html.3e2ae653.js",revision:"6ee3e51399ba5c81a51cc756465de7d2"},{url:"assets/ali-executors.html.988adc8e.js",revision:"84812d38cd71487938d2a8511d0b7225"},{url:"assets/aliyun-shuaiguo-gongchengshi.html.af9a0166.js",revision:"c9f49241edf377bd52e5f179bdd3ea39"},{url:"assets/aliyun-shuaiguo-gongchengshi.html.e4346151.js",revision:"97ea58e96d96f1afd5bb00e2f3b35fcb"},{url:"assets/annotation.html.14064668.js",revision:"b8c310fbc00430fd403dedfcffd9e496"},{url:"assets/annotation.html.3a9fcfe1.js",revision:"16271f73264a861a848a398ad776a22c"},{url:"assets/aop-log.html.390b071a.js",revision:"4d14cfeb7c0b409467bb60a83463cd8a"},{url:"assets/aop-log.html.ec10c829.js",revision:"d3613c7a4e7a24b84cbf479b4b1662c3"},{url:"assets/api-wangguan.html.c2b18262.js",revision:"82f0406d65453e8eb1a5ad59ca30ecb0"},{url:"assets/api-wangguan.html.ec8dd3f1.js",revision:"7d2ca1dad41875acc0823b5d04c06316"},{url:"assets/app.615e41d8.js",revision:"462a39b9884283fc8e4efdbb3190ca73"},{url:"assets/aqs.html.58976faa.js",revision:"1e899d61bac85c459b062217b1faffcb"},{url:"assets/aqs.html.d6a8f5b4.js",revision:"625d292bc1a70d1e7405da97b6029523"},{url:"assets/array.html.19972859.js",revision:"c7041e95b8141255c15d85bdc25add03"},{url:"assets/array.html.77525f56.js",revision:"c7cc1063f8abb40eb5a6e6bb3a220431"},{url:"assets/arraylist.html.0dcdca73.js",revision:"381a5a48e521e35dda79e367eac116a1"},{url:"assets/arraylist.html.f57cbfa7.js",revision:"20006ece67610ce4fc11f63bb6a06c21"},{url:"assets/arrays.html.7944f961.js",revision:"c15f2d6bcb85818880f6f8383f9dbc61"},{url:"assets/arrays.html.ea4b1150.js",revision:"a68d0b598d5b2f18cd4b2caab0c33ac0"},{url:"assets/asm.html.0e0abd8b.js",revision:"072c730bffd7fc1a8a611ddd1c5da23e"},{url:"assets/asm.html.43e7fd57.js",revision:"fbdf1e03ba81fa6de251a8f57dfbfbbd"},{url:"assets/atomic.html.08ec5c1f.js",revision:"e436e5a1a1d9e7f8b478cc0da7455b8a"},{url:"assets/atomic.html.93391f09.js",revision:"0a81ec041fa27d2b5cff824a647d20a1"},{url:"assets/auto-generator.html.341a868e.js",revision:"ef2dd2da21763df827704142a85df600"},{url:"assets/auto-generator.html.7efe2473.js",revision:"9ebf50d78e0b0c93dd2b94e4e6c93c93"},{url:"assets/basic-data-type.html.20d3399e.js",revision:"30131e0f8a59beb06a01e64bd482ca55"},{url:"assets/basic-data-type.html.6be3e7e2.js",revision:"926a54b4618afc77e58598cb1f53e6ed"},{url:"assets/bat-shuati.html.01dded07.js",revision:"b27249fdf907cce09c7ed8036c1ca2c6"},{url:"assets/bat-shuati.html.214e49f5.js",revision:"230a0084e5f06e7621b3f9ae60c6b782"},{url:"assets/beijing.html.78adaacf.js",revision:"5c6eeabb99c1bae2683df89bcdecf679"},{url:"assets/beijing.html.a011f671.js",revision:"a9bcedf1d92d4670b81886c82152a899"},{url:"assets/BIONIOAIO.html.4c184e72.js",revision:"ab0c38e3b6718606cae3c583575c138f"},{url:"assets/BIONIOAIO.html.ea89d11f.js",revision:"1e4874dbc0370df66e2880da25a688ca"},{url:"assets/BlockingQueue.html.76b31f3c.js",revision:"87a004312a99cb938d30df25abd521a1"},{url:"assets/BlockingQueue.html.9ccd9ba0.js",revision:"ceeda89af92173a6e837c5a077c9d909"},{url:"assets/bokeyuan-jianxijavazhongdifangwenquanxiankongzhi.html.5212785d.js",revision:"3a2e1826d21d67cf8cfe912d952867d8"},{url:"assets/bokeyuan-jianxijavazhongdifangwenquanxiankongzhi.html.bc8753e4.js",revision:"e407e843972f36f357c6600a48c11379"},{url:"assets/bokeyuan-ruhegaoxiaodixuexijishu.html.e50696a0.js",revision:"a0dd1192c35e2a51b30705cce3ba9536"},{url:"assets/bokeyuan-ruhegaoxiaodixuexijishu.html.e9d4ca36.js",revision:"1a48b0e99830900cbfeb4437a51aae72"},{url:"assets/BOKEYUANruhegaoxiaodixuexijishu.html.54dd2a4d.js",revision:"e410b4653746a1f3a29de7315e67451d"},{url:"assets/BOKEYUANruhegaoxiaodixuexijishu.html.665a0cbe.js",revision:"de93c74f41f78e68ddbd04e19033c227"},{url:"assets/box.html.03f96a13.js",revision:"fb5f92bbfef8cfc68c6d988cc8857035"},{url:"assets/box.html.54cc70a2.js",revision:"09778d260a2bd54390c5df81ae5c0a4c"},{url:"assets/buy-cloud-server.html.5057ae50.js",revision:"15698e403fc258d6cd037e628885e4aa"},{url:"assets/buy-cloud-server.html.595deaa6.js",revision:"bea7becb36dcf02d7c5215fc19797c6e"},{url:"assets/buy-domain.html.1227af51.js",revision:"2084929626a6e80923df3997bea07231"},{url:"assets/buy-domain.html.e087e5aa.js",revision:"c00bf58acd8e46e3c6651617563ad248"},{url:"assets/bytecode.html.568c5a04.js",revision:"fff64b976e81c22c8dd0910ea34daa2e"},{url:"assets/bytecode.html.ba8f00b6.js",revision:"c0d1e7ef23332326dc90ce1d81d5d05f"},{url:"assets/bzhan-10wan.html.98f8ba37.js",revision:"d68d1bd3dddf462db72f205b33e3eeb5"},{url:"assets/bzhan-10wan.html.e0ad4af0.js",revision:"e5ad1bf8da307454b5dd5854770ab026"},{url:"assets/c.html.5983fe89.js",revision:"cee3031a57cc138acc6d11755802b30e"},{url:"assets/c.html.6387955f.js",revision:"c4fa4867ea58a30d4f28ba980fd74aec"},{url:"assets/cas.html.4534d702.js",revision:"8bc80781d9d2bdde974c66d01343caf9"},{url:"assets/cas.html.68e07dc8.js",revision:"df931dbc91cb8dbfa0b32f9243e74caa"},{url:"assets/ccc.html.51a24970.js",revision:"e724b888cc455ff547b84535af17a324"},{url:"assets/ccc.html.bf391d30.js",revision:"d75b8ae3f1e9b634c8055ff6d2c2413c"},{url:"assets/chadiansanhuo.html.e9cc0b99.js",revision:"3ae54e43d8b55c9b07f8b96eb885ddfd"},{url:"assets/chadiansanhuo.html.fc173db8.js",revision:"b2d1f3e61ae5215e0dad8546be908155"},{url:"assets/chengdu.html.7221dfab.js",revision:"238d2b06754f63f80055cfd770b492db"},{url:"assets/chengdu.html.c9264a1d.js",revision:"0a8271ba09b166b120fc54b0528a40e7"},{url:"assets/chengxuyuannv-chonghui-java.html.01f1b5cf.js",revision:"1da632940ee5b0e968caa14e10a23da1"},{url:"assets/chengxuyuannv-chonghui-java.html.b9de6702.js",revision:"eae9b017adb086faa22ac24423ebc287"},{url:"assets/chiner.html.13c55607.js",revision:"82785120402bceab024e50887e5714d1"},{url:"assets/chiner.html.daf0adff.js",revision:"637c3a7a711bdb0632f7a8444340e941"},{url:"assets/choco.html.2c7d8900.js",revision:"fa9b65d877ed86d6367a61da0d7c949c"},{url:"assets/choco.html.f8923e81.js",revision:"f1ecf9c1e645995f595ae0192eef1f6c"},{url:"assets/Chocolatey-Homebrew.html.5637171d.js",revision:"353690c435a883fa4f1de692cd3eef52"},{url:"assets/Chocolatey-Homebrew.html.ad256880.js",revision:"f27f5ffe5e873f37caae308cd3f7c800"},{url:"assets/class-file-jiegou.html.3aa9524b.js",revision:"5c367ebfd7097dcace533c9109a06d4e"},{url:"assets/class-file-jiegou.html.3dff0326.js",revision:"96c0ab54ea6bd0c20cc027807b9c0117"},{url:"assets/class-load.html.07c5abca.js",revision:"f25528ca369bd71d97047a371ba891d1"},{url:"assets/class-load.html.6a788fca.js",revision:"1b73773905c7665af8d92be86ff7c93c"},{url:"assets/class-object.html.a22a09d8.js",revision:"4cf232e219ad73ed0249959ef8dab224"},{url:"assets/class-object.html.c43412d3.js",revision:"95d854056dbe7d047f22d73d03c0c4bf"},{url:"assets/code-init.html.58676afd.js",revision:"acc4ac90fdef3e8d9aa4ce8a82ceae3f"},{url:"assets/code-init.html.70ef628a.js",revision:"818831e291e49a1121d4867cbbf34e7b"},{url:"assets/collection.html.42c40509.js",revision:"3e9a280a2708f759c09967d7f84b7b1c"},{url:"assets/collection.html.e1c47b4b.js",revision:"26a8766807c7e70d2a9e2554930f097a"},{url:"assets/collections.html.2e6479a3.js",revision:"2a8ef3d4cdfea297d8e08d2e1767a0f6"},{url:"assets/collections.html.37777ec8.js",revision:"74a0523028638b08bc131be57df3af6a"},{url:"assets/comparable-omparator.html.1a3bff07.js",revision:"f3e803b044d4c357a2173e77dca2dd05"},{url:"assets/comparable-omparator.html.397dc2ff.js",revision:"4fc9d5e6efa5df02a669384c67c775c4"},{url:"assets/compile-jdk.html.531caac0.js",revision:"cfb5cd6a34b5696dec2ff5c2cf32665b"},{url:"assets/compile-jdk.html.fddb4940.js",revision:"929c5f27ada1ab44c0da3cd67c1780d0"},{url:"assets/computer-base.html.ca77cdaf.js",revision:"23ed32d0c469a503e711fcbb51e070de"},{url:"assets/computer-base.html.f469b424.js",revision:"1f6ecd345516bff8d501b14e1594704b"},{url:"assets/ConcurrentHashMap.html.77d65cc9.js",revision:"2a3eb940b8d8b2bac223fb97dbbe09fc"},{url:"assets/ConcurrentHashMap.html.e7f83c81.js",revision:"0d28e48bc1568ebab9dcc835e29ba876"},{url:"assets/ConcurrentLinkedQueue.html.da4bfec1.js",revision:"23433f93339dc43427ba24cee5941137"},{url:"assets/ConcurrentLinkedQueue.html.f8564dd9.js",revision:"e21bcb2150039fb7036df909a85f9e08"},{url:"assets/condition.html.4a44859a.js",revision:"ed0cb025b0f9bce6b82ab7a65dfdb70c"},{url:"assets/condition.html.a41bdc76.js",revision:"d7d34d6a2e7d5506b58e1b72264aad0c"},{url:"assets/constant-pool.html.81e697ea.js",revision:"cd016050bb3a5ede4bb1f78d179e756d"},{url:"assets/constant-pool.html.c79f5c21.js",revision:"61e5fe3195c6360d58f87a081108d8b3"},{url:"assets/construct.html.0a38a577.js",revision:"a389eb8410e37a49fdbffcdf7f197f89"},{url:"assets/construct.html.5ae3e6eb.js",revision:"e6248e5666fb845c81737f955adcee8e"},{url:"assets/CopyOnWriteArrayList.html.2fa1badd.js",revision:"d9bc9b1e089216a91befc69530c20daa"},{url:"assets/CopyOnWriteArrayList.html.b8e564c2.js",revision:"f2f383f2d43d94ceccdbe96b2b1c6440"},{url:"assets/cors.html.b1e575b3.js",revision:"8116ced69938f777925c3268adb9bfe3"},{url:"assets/cors.html.b8f51585.js",revision:"7439fe2677e95d97a601cf2a34e91040"},{url:"assets/CountDownLatch.html.79c0b80e.js",revision:"3619d00b6aee569568a30bbd0a77afa3"},{url:"assets/CountDownLatch.html.f036fab2.js",revision:"26b7d176d09b3669f790cd3526ef5132"},{url:"assets/cpu-percent-100.html.30d9234e.js",revision:"f7f5bf5be6fd4ca92e37b482b539e210"},{url:"assets/cpu-percent-100.html.f6bd745b.js",revision:"ad8a7d92c2d6b25c044333bc25f9537a"},{url:"assets/csdn-1000wan.html.22ddf17a.js",revision:"a6214a6bf8e8aea0073c36c8471d2e6d"},{url:"assets/csdn-1000wan.html.438218cb.js",revision:"259561af8e4bdd5fd3e6a009bb23fb74"},{url:"assets/daxue-nuli-jisuanji.html.2b1074e1.js",revision:"269b99461af7c8e4de2b6672a6db1ed6"},{url:"assets/daxue-nuli-jisuanji.html.ad13ab16.js",revision:"6ba002a8a6c21d267f17cb546aacf1cd"},{url:"assets/DBeaver.html.16c02541.js",revision:"432147c6fb5bea87ca0a3021323d9f1c"},{url:"assets/DBeaver.html.75fbe8f6.js",revision:"d453149ad3ea09402d8efd2ec3cbdb5f"},{url:"assets/deep-copy.html.1b203746.js",revision:"506b9406d44b88b4785ff80460f1007b"},{url:"assets/deep-copy.html.b367f078.js",revision:"e0a2406e1b6499e88721b8e21f44c004"},{url:"assets/deletedb-binlog-weiguanjishu.html.0dd5fe85.js",revision:"79b04df8ceabe08cbafaeb5d04f7d5e2"},{url:"assets/deletedb-binlog-weiguanjishu.html.605b28a5.js",revision:"bd5a5b97f531ad34a84c30fb9af6a895"},{url:"assets/electron-information-engineering.html.16bd5754.js",revision:"8b57afa640a9da11164ff4c4f64a4111"},{url:"assets/electron-information-engineering.html.6411b062.js",revision:"d7730e3aaf3c4a3145c07c1c4aa3eea8"},{url:"assets/enum.html.21e74b14.js",revision:"812d1c9d0547cbd890fb5bc8f3cf78e3"},{url:"assets/enum.html.637c7ac9.js",revision:"448da93dff935241a4cda1c544242570"},{url:"assets/equals-hashcode.html.033e729f.js",revision:"9cf97c1f7a4780b063681534f9b0bcf9"},{url:"assets/equals-hashcode.html.cd3210fa.js",revision:"063e16ab8d211c0c61299a99bf635de1"},{url:"assets/equals.html.2fb94b25.js",revision:"46208de98557b94b1aa23d2d106371fb"},{url:"assets/equals.html.f7e52978.js",revision:"bc945798e26b263c822af465deddd663"},{url:"assets/fail-fast.html.4b8a884f.js",revision:"8f5872231ff04b187d0ad54370d91c4b"},{url:"assets/fail-fast.html.dca676b6.js",revision:"756713d835a37e78076e810cc8f8b031"},{url:"assets/fanshe.html.13ada7e7.js",revision:"7b7c5fe2868eee1782f53b121e74b12f"},{url:"assets/fanshe.html.e42ba18d.js",revision:"76a2dd57cce8c3acbcaa914d94568e0b"},{url:"assets/fastjson.html.bf5a0ad8.js",revision:"3ae1af529161b2dfcf73f5f74975a4eb"},{url:"assets/fastjson.html.f97ae6fd.js",revision:"a8326b550ef22ce4e613c3042cae5cb2"},{url:"assets/Filter-Interceptor-Listener.html.3a5897a3.js",revision:"360c10b180b2ca9a1aabd5ff6f1a581b"},{url:"assets/Filter-Interceptor-Listener.html.7803e9df.js",revision:"8a32f4cfd150818a0bab909ce7444428"},{url:"assets/final.html.c83d9074.js",revision:"c726701bca64c1974ecb054822c85377"},{url:"assets/final.html.e625665e.js",revision:"31c6a883281f40da43c0001f8415b852"},{url:"assets/flow-control.html.5046ff0c.js",revision:"4ada85c9151a658cdeff21a4da64c702"},{url:"assets/flow-control.html.f6c60ead.js",revision:"40ec7db6a6132bc01f51bcdbea3fa717"},{url:"assets/forest.html.3141000b.js",revision:"8f3a7a84b28c79f58b273af0173db459"},{url:"assets/forest.html.79a7cfed.js",revision:"5f057f53de7ba5b74e96f1ec60ffb21e"},{url:"assets/fork-join.html.e8674cdb.js",revision:"f99f20ffed6ba458af53398fb0bc06d1"},{url:"assets/fork-join.html.f967d485.js",revision:"26f31bc4133e61588d3e1ab2966e722b"},{url:"assets/fumutuanju.html.577491d1.js",revision:"d2f0d6831711758976a8c940798c4f4f"},{url:"assets/fumutuanju.html.ca0f5d88.js",revision:"a9f7cd91afeb896a244c8d8b6f3b9089"},{url:"assets/gailan.html.0ea3f7da.js",revision:"ffaad458f1c5db7a1297481a8f8005b6"},{url:"assets/gailan.html.50f82bf5.js",revision:"f2a2eb4ef5b853a6b97912f83a8523ca"},{url:"assets/gailan.html.87d77185.js",revision:"838f7f94a9e88620b46b4e6e7a790e1d"},{url:"assets/gailan.html.fee068f9.js",revision:"656821687243257a5d84494525d3219d"},{url:"assets/gc.html.714d0f7b.js",revision:"1abc61c8701406a5ebb447dcf75a4ec9"},{url:"assets/gc.html.cec6db87.js",revision:"818e2a3e352aea0b7dcfee09455162c7"},{url:"assets/generic.html.7ec41e80.js",revision:"2ff01c60d7d59252cfd4d4d55d0467ff"},{url:"assets/generic.html.df9c6eb8.js",revision:"082c06442ae74b2378b87d1d39de8f4a"},{url:"assets/git-qiyuan.html.054515ab.js",revision:"308020a99661a2530c8989e89c509403"},{url:"assets/git-qiyuan.html.085fb4bc.js",revision:"267a7945ca850f4a441212e1a92552fa"},{url:"assets/go.html.528d4a75.js",revision:"0ce9693e8631b976ca6f1a55edae0f70"},{url:"assets/go.html.dbab658a.js",revision:"278fa7f23a08bf0111b3d608469784e9"},{url:"assets/gson.html.a359eddd.js",revision:"13f1ababdf79fd44dc9d36900c7a0d00"},{url:"assets/gson.html.e79a454d.js",revision:"01fedf3f3911791ead09eedd7e5f410a"},{url:"assets/guangzhou.html.58700f92.js",revision:"07c08132e98a5bb9a589884a132be8e4"},{url:"assets/guangzhou.html.c44755f8.js",revision:"bdf0eff158e2ecc338a17d981cf08252"},{url:"assets/guava.html.bbc48258.js",revision:"f29ee74d7b7b8ce3bd03bc072aabf7e2"},{url:"assets/guava.html.e73aaedd.js",revision:"9d698d9f891d7c22f3ac477808b8f998"},{url:"assets/haibukuaiyongmybatisplusshoubashoujiaoni.html.4769ffdb.js",revision:"8b1f46e7be3e7116c325dc37149193ef"},{url:"assets/haibukuaiyongmybatisplusshoubashoujiaoni.html.6feacfb3.js",revision:"93f1f1d514b136a4d4704e9c12011405"},{url:"assets/hangzhou.html.52f2ce43.js",revision:"7723a4ad6abdd887cc602cdbf230936c"},{url:"assets/hangzhou.html.a9b39480.js",revision:"f43ec1548ed8cd34e82a8b5d8973091e"},{url:"assets/hashcode.html.24290486.js",revision:"343281510b0998fa1d048d3c5bf2b144"},{url:"assets/hashcode.html.6a0e81d9.js",revision:"46a0e2cd2db39ca4ef3ab57aff0fa978"},{url:"assets/hashmap-interview.html.307a5634.js",revision:"fe897032d2207465583c5a2783cc6364"},{url:"assets/hashmap-interview.html.36f118fd.js",revision:"64bad08264419e936a82c84cf2647465"},{url:"assets/hashmap.html.e3590cbb.js",revision:"4f977a72e39a337787a9902fde12b2e6"},{url:"assets/hashmap.html.f8e12ca4.js",revision:"64a8ec255cab16b059484b8930e0338e"},{url:"assets/hello-world.html.26946542.js",revision:"8c51974459c33607c8f425f01d22abf1"},{url:"assets/hello-world.html.d0d5adf0.js",revision:"edf374e50da38d8b82c8dad4c5f2a9c9"},{url:"assets/highlight.esm.d982e650.js",revision:"3457767fb4f7fe757ad6fb071f162a85"},{url:"assets/history.html.57bb6aeb.js",revision:"a6ea2f8cf75bca6abe687f5f12ca30aa"},{url:"assets/history.html.6df608e4.js",revision:"edafea3f3bb61548faac24d804cae17c"},{url:"assets/home.html.1fffdb8f.js",revision:"d809ae5f00c553d32c88021c5c455b59"},{url:"assets/home.html.25268b5b.js",revision:"64d92bd8d652d3552ab2a30f2aef3c1c"},{url:"assets/how-jvm-run-zijiema-zhiling.html.400c699c.js",revision:"a1e65b5f2c56245fb14f3e212611d505"},{url:"assets/how-jvm-run-zijiema-zhiling.html.f5dbcd2c.js",revision:"0b4deaf852f5eb8840789c8b2dfad978"},{url:"assets/how-run-java-code.html.1867de4d.js",revision:"5cf492e41232393c8b14781f521b0932"},{url:"assets/how-run-java-code.html.5154cace.js",revision:"9da78cf0ad75ce8adb3f9db0fea9627f"},{url:"assets/hsdb.html.4b8d1063.js",revision:"0f961228688a0ca619b45f75775f73e6"},{url:"assets/hsdb.html.e06d55d6.js",revision:"ad7a87fc50d8515780225b075b58f367"},{url:"assets/https-domain.html.81185a29.js",revision:"6735adc409780df1d219600baba6102b"},{url:"assets/https-domain.html.847eb117.js",revision:"bf28a27b383cee8995274c7489f6c532"},{url:"assets/hutool.html.06e72427.js",revision:"10ab5d7054f66e38c5a99dbed60d31f9"},{url:"assets/hutool.html.5bf70ca7.js",revision:"c8738259a8043d99dc356643a8af822d"},{url:"assets/image-yasuo.html.0e3ff54c.js",revision:"9f6f881e4bb3b94b7e61a7487e2a86a1"},{url:"assets/image-yasuo.html.8853b749.js",revision:"f81cd85d277b957d04fd25be2cabe9df"},{url:"assets/immutable.html.36fadfba.js",revision:"2c68404981e3db1079eaf013a6d08bb4"},{url:"assets/immutable.html.aab5b4ed.js",revision:"491a901473c08c83dc1020708c930a99"},{url:"assets/immutable.html.acff64d4.js",revision:"c550e285d2b7f1918cccfeb819c856f2"},{url:"assets/immutable.html.fdd47709.js",revision:"55e538731a82b55cc7f6e72e291a0844"},{url:"assets/index.html.698aa818.js",revision:"9c38fccd3fc6dbdfc7314582ff98359c"},{url:"assets/index.html.96eac070.js",revision:"4d01170a8705186df15296e8d463d893"},{url:"assets/index.html.9c1a7487.js",revision:"9c3531c49a986fa241f13ae8a1b8be42"},{url:"assets/index.html.9ee0e417.js",revision:"41aa8c21d4af70e4e12b73e21cc88429"},{url:"assets/index.html.a4bb5c6e.js",revision:"98c0a3ad6498080673df4a2c64bbaf8f"},{url:"assets/index.html.b90a750c.js",revision:"b5446123534ec2f5777814813a362858"},{url:"assets/index.html.bc31ce34.js",revision:"fc2bb694151bf0ac25e94e8c9ceeb51a"},{url:"assets/index.html.c95125a9.js",revision:"be60e47a38ed7dcaedc47b72624cc1ec"},{url:"assets/index.html.efbaa943.js",revision:"396d059ce674449e0e1c8cbab9e4bb99"},{url:"assets/index.html.fd879420.js",revision:"7ffb229fbb962ecfa398ce80c7fe95ec"},{url:"assets/initializr.html.47ddf572.js",revision:"e64adae0afad82ea02bdeb579b8f5be8"},{url:"assets/initializr.html.8afcbffb.js",revision:"269861d3115e13d0c7285a2e42b06557"},{url:"assets/inner-class.html.858a9fd0.js",revision:"d2b65b6c7e88bbba4d596c81172ddd60"},{url:"assets/inner-class.html.f2dd62ed.js",revision:"9e4441914142103b191b8443b65259f1"},{url:"assets/install-baota-mianban.html.822010d2.js",revision:"276bbd9dc29a1fc6767713e49d2876c7"},{url:"assets/install-baota-mianban.html.fc940506.js",revision:"38b991a892897e57b412912a14f56b7e"},{url:"assets/instanceof-jvm.html.84099ac1.js",revision:"13cf64169a7f7570b520f07b075559f1"},{url:"assets/instanceof-jvm.html.845ed78f.js",revision:"943acb44bce021b556febc8afee2fdb3"},{url:"assets/instanceof.html.d3be3510.js",revision:"516855dcbfebdd16e0becfbb9bd85955"},{url:"assets/instanceof.html.edc709c7.js",revision:"5d7a30cdc88e64610cd4f9c54269521b"},{url:"assets/int-cache.html.0d30900e.js",revision:"26b2072adfd383782dd52f78abcee302"},{url:"assets/int-cache.html.bb142a51.js",revision:"5887c3796f479978f812cb144a849eac"},{url:"assets/interface.html.7833e904.js",revision:"0843bf51c814ca573607ae40640f3ab4"},{url:"assets/interface.html.de30e51e.js",revision:"fd250ec4307908c1f18024247099ee84"},{url:"assets/intern.html.3d87fa6f.js",revision:"cdb3dcb855cbe196e3c21a87f9bc130b"},{url:"assets/intern.html.cb5b47c3.js",revision:"b9faaa75ca0de583f7cc91a4b42c134b"},{url:"assets/ioc.html.1c4cca00.js",revision:"1a2ed922af9e8cbbed111c0155a3acb5"},{url:"assets/ioc.html.a79e951b.js",revision:"d89ccf3cefa1919274809c410fce14f4"},{url:"assets/iterator-iterable.html.7a5374e3.js",revision:"986c10bdbaeb487a9879f74a46e8e157"},{url:"assets/iterator-iterable.html.967b5cf7.js",revision:"f1abd8a084a08c39689395506befb003"},{url:"assets/jackson.html.ded110ad.js",revision:"b8bb83b89a37fee5fba205945be76cce"},{url:"assets/jackson.html.f4471baf.js",revision:"57e3411f85b93fd8c531a1ee99106eb1"},{url:"assets/java-basic-34.html.70be78f8.js",revision:"237c8c8244c63138dcdf0c90c93ccf04"},{url:"assets/java-basic-34.html.c0108ee7.js",revision:"232e87ffc59aec91ecb20fec451b3ba8"},{url:"assets/java-basic.html.34b72317.js",revision:"5ecf4a33cf14fcca3610083f86d66063"},{url:"assets/java-basic.html.52bd7f06.js",revision:"c3eddf2b32eebe6b50723c9ac936ea4b"},{url:"assets/java-mianshi-zhinan.html.9c0ece4d.js",revision:"291a4f21a5df7a55040cbb02d7d7f015"},{url:"assets/java-mianshi-zhinan.html.f1a349c4.js",revision:"27ed524714e36e6f747e11622961463d"},{url:"assets/java-naming.html.1100d2ca.js",revision:"0cdbea57df887cd24d70a56e28d43794"},{url:"assets/java-naming.html.de2604a0.js",revision:"d0f0b1a247ac19647b2a902effa60733"},{url:"assets/java-thread.html.4a99fb0e.js",revision:"7bbbed0ab8e420e38b4c2732b0814144"},{url:"assets/java-thread.html.87abce4b.js",revision:"5685a8a8992f08d9ab18de33bf3137ad"},{url:"assets/java-unicode.html.9e4e93b1.js",revision:"bd70784e55f2c80f63364553a992eb8b"},{url:"assets/java-unicode.html.c63853a0.js",revision:"669a79673f1a378cbe0e80d138c1cbca"},{url:"assets/java.html.8cfce3ac.js",revision:"9a9ee538241c31f2c0ac88e0f0907fcf"},{url:"assets/java.html.9104a10d.js",revision:"5d1fbc3f94eb92343d78cde14dc18b92"},{url:"assets/javadoc.html.435ee8ec.js",revision:"7798dde0507b72a78857ac4900b757b6"},{url:"assets/javadoc.html.b34e8efb.js",revision:"c31af3f9ce5f9fd518305e3fcdb225f0"},{url:"assets/javase.html.4c6f74ba.js",revision:"ecfbf2388cf8f4c8cf8dc48daab4fe9d"},{url:"assets/javase.html.811355dc.js",revision:"fef28aa68cd1afd5477935b6b0a650e6"},{url:"assets/javathread.html.1bcda474.js",revision:"7f4f00e58b30cfc68de124c2100571b9"},{url:"assets/javathread.html.9fc70ce0.js",revision:"5711f168b6c19372886c558e4c4575b2"},{url:"assets/javaxuexidaoshemechengduokeyizhaodiyifengongzuo.html.3289a228.js",revision:"12d21d02683e4aa784f8c9e41146d8b5"},{url:"assets/javaxuexidaoshemechengduokeyizhaodiyifengongzuo.html.6e4f2abd.js",revision:"df8453e460b559735b578fbedb1ad93b"},{url:"assets/jdk-while-for-wuxian-xunhuan.html.a5707bd9.js",revision:"76facd70dec52ac3e5881829b2fb6b8a"},{url:"assets/jdk-while-for-wuxian-xunhuan.html.e352d875.js",revision:"cfbb94a92733eeb5dc75e736e4271136"},{url:"assets/jdk9-char-byte-string.html.884765a3.js",revision:"cbfb31f9ba066498adb513f0f7ba45fb"},{url:"assets/jdk9-char-byte-string.html.e81be44e.js",revision:"fc680ffbdb61274f773a8c78c167bfcb"},{url:"assets/jiagoushizenyanghuizhijitongjiagoulantu.html.980a677a.js",revision:"e16ace455638e83fe29e4f986fdb9ed5"},{url:"assets/jiagoushizenyanghuizhijitongjiagoulantu.html.aafe265c.js",revision:"a39a5b308c11200a865fc5e6951abab8"},{url:"assets/jianli.html.28361c8b.js",revision:"b26df3f5afa922b44d528cd7329cff48"},{url:"assets/jianli.html.2cde4ea0.js",revision:"71194a48c1d5367fa3f9ae995975032b"},{url:"assets/jibenjieshao.html.6a5f31db.js",revision:"642688e0cb2bbd4702477951d8fa576c"},{url:"assets/jibenjieshao.html.b8a08842.js",revision:"9a038bd09178c6aa49186884410c43ab"},{url:"assets/jielehenduosihuodiganchu.html.0ffa8f43.js",revision:"38131d5037ed9703e9ef9af66411768f"},{url:"assets/jielehenduosihuodiganchu.html.576b64a2.js",revision:"b527d749b4bd825b17a02275fe7e2c65"},{url:"assets/jinan.html.95982728.js",revision:"8bb545a674ac21a6ee8d105fd64047ca"},{url:"assets/jinan.html.d4c22f59.js",revision:"5a29016c0a21263aac901651eeecd017"},{url:"assets/jishuzongjianbeikaichuliao.html.1b7e52c1.js",revision:"16fba1920863afdcfe7142774cbd4425"},{url:"assets/jishuzongjianbeikaichuliao.html.6397e62a.js",revision:"092f54422ef8fe6a017873fea9a42c7c"},{url:"assets/jit.html.a14bdfce.js",revision:"f6d96dbfd5dcf11323c34d5dcc7335fc"},{url:"assets/jit.html.cd04156f.js",revision:"a5ae31399538df2d6198ae259db11d6f"},{url:"assets/jmm.html.2560457a.js",revision:"a06abfac52e7671ca13674aa36e1ef71"},{url:"assets/jmm.html.7be72db5.js",revision:"f110edd5e2f6a34351d4711a3df6e513"},{url:"assets/join.html.50d59b6e.js",revision:"376c267b3a77d18369021e8e46d436b4"},{url:"assets/join.html.bb336f49.js",revision:"42a931af30f514619d1a1efb40c96591"},{url:"assets/jpa.html.c491ef74.js",revision:"59b8e6a2ea59aafe06aa3c4a7ad30317"},{url:"assets/jpa.html.cb4e1f80.js",revision:"3b773ecba585d413510cd3dd8c716b8d"},{url:"assets/junit.html.2436284c.js",revision:"f3af71d5609908b52eef886f9e995418"},{url:"assets/junit.html.9c832cdc.js",revision:"bebfc226fa864bad8eddf161c6b7815e"},{url:"assets/jvm.html.1b4e3107.js",revision:"8f36d3c8758d9fedb2dcea99714dadcd"},{url:"assets/jvm.html.375475cb.js",revision:"6fe0c7a77105af7ef92d0600e7a09448"},{url:"assets/jvm.html.49208e4a.js",revision:"ae588fea19815644b1c028a676055a4b"},{url:"assets/jvm.html.c049e00d.js",revision:"c0592a53f76f0fce0e437013f36ad79b"},{url:"assets/jvm.html.cb0eace1.js",revision:"bbf53c29a2f7000981aede503a5afccc"},{url:"assets/jvm.html.dd68f45e.js",revision:"5a942829e5fa038171516b43c4953270"},{url:"assets/jwt.html.2aed3523.js",revision:"e76f3a16539733fd1bdd8f1274f4fa60"},{url:"assets/jwt.html.b4f208bb.js",revision:"ccd1e1cf1ba2d50e4abd7ee39cd0ae5f"},{url:"assets/knife4j.html.4fbb94b8.js",revision:"e81295e651e26fce78186ee530efe8a2"},{url:"assets/knife4j.html.a18b3a85.js",revision:"e3995f55e02c655c20900b1e5e63065b"},{url:"assets/Lambda.html.997b367a.js",revision:"52eb395fd4e37f0de01811421653e900"},{url:"assets/Lambda.html.bd1566d3.js",revision:"eea28c312cc307db6b11540fa5473737"},{url:"assets/lanqiaobei.html.17699093.js",revision:"5d54156cabbd398cd05a10f3531bb1f1"},{url:"assets/lanqiaobei.html.e24944e8.js",revision:"105b406a2605e7cfd908e370450eb111"},{url:"assets/Layout.2f241dd5.js",revision:"8304c3e5d083d8c2aea7966c9225096e"},{url:"assets/learn-jianyi.html.1b72d4e2.js",revision:"7d563c363a3d4debd307277bf1a00e67"},{url:"assets/learn-jianyi.html.2486d715.js",revision:"671a0284de2c61a77499c33770aa2f5f"},{url:"assets/linkedlist.html.8ede144e.js",revision:"e2adcd892b90191c375cf979328cb124"},{url:"assets/linkedlist.html.e021186b.js",revision:"3d9c4ed38f5d614623bd2b6225a8497e"},{url:"assets/linux-codingmore-run.html.6ac5d933.js",revision:"8c505e7c59609f7f2fa3abb9102f9f7a"},{url:"assets/linux-codingmore-run.html.d96d85b1.js",revision:"5740c246775c5cdc78359f921d26eedd"},{url:"assets/list-war-2.html.4306ceaf.js",revision:"4614b86ad0b9063c13357295f2728036"},{url:"assets/list-war-2.html.b8fa44fb.js",revision:"cf2ab3c2e799ec10f657d9e2f4dfb65a"},{url:"assets/lock.html.5385ecc8.js",revision:"894e93c8012594ae038f4cd857ff50af"},{url:"assets/lock.html.707d5244.js",revision:"c4ff30cabea577f06cbcc00a6018a134"},{url:"assets/LockSupport.html.5ea98b89.js",revision:"572b7ed89410d5b2483ad25a829d0179"},{url:"assets/LockSupport.html.c7d00cfa.js",revision:"86fdd35f48637ac9a5971fb6e44211d5"},{url:"assets/log4j.html.0b4fd542.js",revision:"b9e30456bef646a1702caff5695777f2"},{url:"assets/log4j.html.14af993a.js",revision:"fa18ccbd6f734f1b12871ec7f9101f6f"},{url:"assets/log4j2.html.066d10f7.js",revision:"46389b220e18124b0d5055c18c74974d"},{url:"assets/log4j2.html.9b5a6f13.js",revision:"74f7162c5d876ef41a09955483435f9e"},{url:"assets/log4j2.html.b3fd06a7.js",revision:"88ff3344444cc2680ddf3e4964c09932"},{url:"assets/log4j2.html.d1682823.js",revision:"392b5f6e36b164ce2f6c315b2089c38c"},{url:"assets/logback.html.28ab1df5.js",revision:"408757b6fbc3d0bbf7246c98de577994"},{url:"assets/logback.html.806b8b11.js",revision:"04c0f7ede5cb1f3a0da739ad154d31b7"},{url:"assets/logback.html.a9628274.js",revision:"5f741c93179b5d8653029776f2026245"},{url:"assets/logback.html.ce19f5e4.js",revision:"b760fa26c3bb5fe9fd6099bdd0dc66a2"},{url:"assets/macos-codingmore-run.html.100361aa.js",revision:"f6780c87ed575010cf5483fa53bedd45"},{url:"assets/macos-codingmore-run.html.f9eb5e90.js",revision:"65ac7cb80f7fc73e7c725acffb01d60a"},{url:"assets/map.html.6ee85b94.js",revision:"837fed237def3e30bb0cd2aef910dd27"},{url:"assets/map.html.ae80f8e6.js",revision:"4caefbc89b1e006c195441565f03be8c"},{url:"assets/markdown.esm.832a189d.js",revision:"4aa467006f9d51cf40293b9b69a0f27a"},{url:"assets/math.esm.a3f84b6f.js",revision:"cbf844f27edbc061c86ae840d70389f6"},{url:"assets/maven.html.abe414c5.js",revision:"076fa6654bcdb82ab1f5d1713ee11a4e"},{url:"assets/maven.html.d13a0dbf.js",revision:"9ce0de892e93f26a9ffea8cef2164c24"},{url:"assets/meituan-9-gc.html.7173ffd4.js",revision:"fe8fa6b143a3dbc5735542403249c11e"},{url:"assets/meituan-9-gc.html.f5a5b89a.js",revision:"244a3f55b6939ca3553511b02032c9dd"},{url:"assets/method.html.1f147cbd.js",revision:"1c99a665cd5628faa625183fba4fcf36"},{url:"assets/method.html.4d951864.js",revision:"561b699c5536ab7660ef94c27166a830"},{url:"assets/mybatis.html.41ff93f4.js",revision:"d9c8df8bd36f2f55b36e8358447306fd"},{url:"assets/mybatis.html.7c33d756.js",revision:"64a1c8c0d21437565c6f4ed7e5b6adff"},{url:"assets/mysql-druid.html.1c47eb57.js",revision:"1a9d22afa107c770c66615a38b97f6ac"},{url:"assets/mysql-druid.html.9707dc06.js",revision:"03e85b61f41594ca8ac3433433f3da81"},{url:"assets/mysql.html.1afcd596.js",revision:"c0ad6261090ab4fd3debd9d30e5e14fb"},{url:"assets/mysql.html.99fca397.js",revision:"f74dbe6f78163ad33b0c9a819ebfc3ca"},{url:"assets/nanjing.html.099e9844.js",revision:"260596f3179d1eed861e1288208be92e"},{url:"assets/nanjing.html.44d630fa.js",revision:"3d25b3c20c05461b274c1cfddecb5d40"},{url:"assets/neicun-jiegou.html.f0fca3bb.js",revision:"6daf0b5605744cbaf3254818812ac171"},{url:"assets/neicun-jiegou.html.fee2587a.js",revision:"cc35a0899ec5029bdecd24422d3a5200"},{url:"assets/nginx-setting.html.3934a533.js",revision:"f98408b462ec69cb20f92d9cdff09464"},{url:"assets/nginx-setting.html.68b3250b.js",revision:"36daa9eff3e0f65428f051701d26f283"},{url:"assets/nginx.html.25ed8525.js",revision:"6db7667d5f4d25d414e14d21a35f76bf"},{url:"assets/nginx.html.baa53af7.js",revision:"cac80db53f25790ef648e13b4e453d30"},{url:"assets/nicearticle.html.4730077f.js",revision:"e334ce4fce0b951d1515dcdffac5640d"},{url:"assets/nicearticle.html.b56e678a.js",revision:"e7e94ff20e83310751fc0c814a6b1e7c"},{url:"assets/nixi.html.c022f9fe.js",revision:"045fae1de49d81b344c5fb968595c21b"},{url:"assets/nixi.html.de6f9361.js",revision:"fb143508dcc92a8f2c24c0f5bd222b45"},{url:"assets/notes.esm.3c361cb7.js",revision:"eda65c99450fe02da90bde90cc614a56"},{url:"assets/npe.html.297684ef.js",revision:"f34420e5e61e95f975372be39e71a808"},{url:"assets/npe.html.a94a2b73.js",revision:"66e85fa3c9bd617e71aef72c2fc50721"},{url:"assets/object-class.html.698d849f.js",revision:"c52eb91b6d96a7d3f8354fd3eae42715"},{url:"assets/object-class.html.85420110.js",revision:"bc2a562c613c3bb7f2f64d53055c00b4"},{url:"assets/oom.html.23228526.js",revision:"0ac9680baff3b41388b27b97b55c779a"},{url:"assets/oom.html.cbfa1fb6.js",revision:"557f65b3ef7e34e159c07edbbf356171"},{url:"assets/operator.html.152cf4bc.js",revision:"034fe53f2cbba60dd6774374cbf7cb55"},{url:"assets/operator.html.9431d9fc.js",revision:"dd2606884797f6115086577981cdf630"},{url:"assets/optional.html.23c0a140.js",revision:"841574f000bebb802ad9b5fb7622fb98"},{url:"assets/optional.html.775157f3.js",revision:"54e19ed9dd841ae5c31dc18f35b22941"},{url:"assets/os.html.1d208877.js",revision:"d6ea19295d438cb210377fd3b8fcebef"},{url:"assets/os.html.34768944.js",revision:"2a3c72e94e5fea9ccc7c3521fd120a18"},{url:"assets/os.html.5e6a959a.js",revision:"0d3240c88a18a8d4ba5ab1f0deb2ed9f"},{url:"assets/os.html.781c26b2.js",revision:"fcf329f5df93c283630362191cf85aeb"},{url:"assets/oss.html.8b1ce1ec.js",revision:"2a579ce6c8ff22b07221e05c326669a0"},{url:"assets/oss.html.e3216442.js",revision:"f478455fa6bb9bd76597cdea808244ea"},{url:"assets/others.html.63b5af1f.js",revision:"7a32a3369509ef63ce3b444ebb411118"},{url:"assets/others.html.ed8fcf05.js",revision:"e6fd1a8c5da4b15d4670159a24ef9506"},{url:"assets/override-overload.html.1c9aaf26.js",revision:"22a791e22c920f9708385a97a173476c"},{url:"assets/override-overload.html.f7d74176.js",revision:"3ee9ca1d6b6aefe5fb57084f0cc15e15"},{url:"assets/Overriding.html.14f830f8.js",revision:"782d5974e1b4f6d2acc30324bd737ad1"},{url:"assets/Overriding.html.d8235770.js",revision:"b9d59dbe8977046d7f3b77b8db8582ad"},{url:"assets/pass-by-value.html.cf8023d5.js",revision:"51748cf216f6de59f32ef703ef641d0d"},{url:"assets/pass-by-value.html.e26c3cdc.js",revision:"3010545820acbe8927e256f4ae13fecd"},{url:"assets/pdf.html.79c228f5.js",revision:"bcb0a579db98a5d402c588741d592d85"},{url:"assets/pdf.html.a28195f1.js",revision:"2878368c7793e0fab9367fd05c73e020"},{url:"assets/photoswipe.esm.92018b73.js",revision:"442a3264b1db7eb84ffc880407e7565d"},{url:"assets/plugin-vue_export-helper.21dcd24c.js",revision:"b29b145139fc88e89a46af507277557d"},{url:"assets/pool.html.1918e02b.js",revision:"837fd39732d9eb3df1e143bd77b9e1cb"},{url:"assets/pool.html.7274870a.js",revision:"744d526c3827d84eb1fedfe20f459576"},{url:"assets/print.html.4135561a.js",revision:"c5f91f379b8e7d36e0c2a19e4f8c1ac5"},{url:"assets/print.html.6fe8360d.js",revision:"7a5cd0b01b2c354dccd58c55ccc7af88"},{url:"assets/problem-tools.html.c0e0819e.js",revision:"acb5a33c88833eadf8cac3018054aaca"},{url:"assets/problem-tools.html.fab08888.js",revision:"8abd2eb80f2525872d9d8f8d2480a0d2"},{url:"assets/progit.html.284a6498.js",revision:"ef6f0f435bc317320968befbe3677cb0"},{url:"assets/progit.html.95158ac7.js",revision:"36b37c641df735698d5e48e97a93e10d"},{url:"assets/progit.html.a119468c.js",revision:"ff8fc203f93f6c67a16915eb0c9b6659"},{url:"assets/progit.html.df477a55.js",revision:"72b64f8670a1b79e9a8c6258c25a644d"},{url:"assets/python.html.6ba47e37.js",revision:"c5282276586042c86148f9cf3caef564"},{url:"assets/python.html.a467fb74.js",revision:"73ccde0eecc64ad7696411f289412dce"},{url:"assets/qianduan.html.61a4f111.js",revision:"80491ad5e938d271d8cd2be59f02e2fb"},{url:"assets/qianduan.html.ef57d5d5.js",revision:"71f054a948e371176c1b0b90159a69a1"},{url:"assets/qingdao.html.826f4cb2.js",revision:"5a4f3a9855d2bc27049e9cd9a16b10bb"},{url:"assets/qingdao.html.c4a4c2c4.js",revision:"e73ea57aaf951c40c0dc06c4adf0cc12"},{url:"assets/rabbitmq-rumen.html.1f0066c6.js",revision:"67e3b3b57c9a055c1f7ddd6a077fd788"},{url:"assets/rabbitmq-rumen.html.5bf7bc58.js",revision:"91b8c4c9ce8a4614f95e26e2e0f17f18"},{url:"assets/read-csapp.html.768012b7.js",revision:"a6363af149e24bc7b4dd9162161e726c"},{url:"assets/read-csapp.html.c0e758ea.js",revision:"b966877b6d1aab734ae853babf191dbf"},{url:"assets/record-domain.html.3a82f73e.js",revision:"937ad5182d910144e272c75aa29177dd"},{url:"assets/record-domain.html.667d7982.js",revision:"e6d8405b67a89e4ab26245a177550252"},{url:"assets/redis-shuju-yizhixing.html.0d2d7824.js",revision:"af7f27a164f234c07500ae1210fe53bf"},{url:"assets/redis-shuju-yizhixing.html.480d5fea.js",revision:"0e298ffaa13403ee710eb1db2d5d5665"},{url:"assets/redis-springboot.html.3faa6adc.js",revision:"2a8a407124af8dcb1bf76ae390ac7706"},{url:"assets/redis-springboot.html.44044d02.js",revision:"cfa6b26eb76aa5b720c5c0c123cab248"},{url:"assets/redis.html.b039ba47.js",revision:"250ee45056172fee92c332e9bb8f2fdf"},{url:"assets/redis.html.bcbe4235.js",revision:"09e244b1960ac2f1463c2481bfc90cf4"},{url:"assets/redis12question.html.58f0e7e0.js",revision:"1ca878de7522dd7bd5f7d4780449386b"},{url:"assets/redis12question.html.f0270e84.js",revision:"600dc76e4c00eda1f2b3e84ad2e2c223"},{url:"assets/reentrantLock.html.002f84e4.js",revision:"475486341b8257def0a182f7945de2b6"},{url:"assets/reentrantLock.html.8b519bdc.js",revision:"e8241c5b308baa417992c4657f61a400"},{url:"assets/ReentrantReadWriteLock.html.140f1c3e.js",revision:"ac3dc90c553309bcb8767717a01b77d6"},{url:"assets/ReentrantReadWriteLock.html.d1bd972f.js",revision:"95da940d4221ddc04eec2e3b5ae8996f"},{url:"assets/reveal.esm.b96f05d8.js",revision:"f78a424fad98faac5d5ca8ebfbebe94b"},{url:"assets/rumen.html.27e01d35.js",revision:"a511f6c5f6172908f99e5000521404bc"},{url:"assets/rumen.html.28382740.js",revision:"bbb73cc8ff60526c113c7b1d16cc8eaf"},{url:"assets/rumen.html.3f2b5ec9.js",revision:"a1e6645af910fa32a8eb130d14e8eddb"},{url:"assets/rumen.html.9cc17590.js",revision:"d296a715b51d7987e19356f118decea2"},{url:"assets/rumen.html.e13dbda5.js",revision:"9f529477271a37fdf0fbaec594e6d279"},{url:"assets/rumen.html.ee21a790.js",revision:"ec7bcc5e5e477600686051e08466b86f"},{url:"assets/ScheduledThreadPoolExecutor.html.73744e7a.js",revision:"f220816aaef20fc0ac9946b6d31af4bf"},{url:"assets/ScheduledThreadPoolExecutor.html.8d668046.js",revision:"b29b0a101162737afa347106c650739f"},{url:"assets/search.esm.80da4a02.js",revision:"690b84c66badd2f8fa69d57bc7cdad19"},{url:"assets/shanganaliyun.html.04eee07a.js",revision:"f74774689b9aa40eb6a262a3cc4e9ae6"},{url:"assets/shanganaliyun.html.802605a1.js",revision:"bf2a7abff579a4b1982b65c3ef81e0c6"},{url:"assets/shangtou.html.d25e4bab.js",revision:"805f1501299b1edd864368e95c7cd7c1"},{url:"assets/shangtou.html.dd79a90f.js",revision:"e491b924cd35190389b7819a21f19b1c"},{url:"assets/shengchanzhe-xiaofeizhe.html.0915b865.js",revision:"ee8bb756f0323bf506becbb4280e574f"},{url:"assets/shengchanzhe-xiaofeizhe.html.b76e11fd.js",revision:"b20f5f14c425c8cd1fb12a8fd5f11d6a"},{url:"assets/shenzhen.html.61178979.js",revision:"2f58532175c0e9944a3da199bee0416b"},{url:"assets/shenzhen.html.98e7f6e9.js",revision:"97da1d26f3b24c007c6e7d9fabc39484"},{url:"assets/shijian.html.0924a1ec.js",revision:"326c95b32e23cf74836881972d518432"},{url:"assets/shijian.html.d1dfaaba.js",revision:"75662f0d9b3a3eb59e65cdb011ac3534"},{url:"assets/SkipLink.a2c3a90f.js",revision:"7c17b4281e8dc33f75ea9e355ed48a3a"},{url:"assets/slf4j.html.2fd3dca6.js",revision:"c2fc64d88ebde1e5685aabe77a9ac3c1"},{url:"assets/slf4j.html.f772534d.js",revision:"d519cb199feeb1661cb0bb7c64c1ae63"},{url:"assets/Slide.39e63deb.js",revision:"7cc031de25acac5f5e36a181475e3a0d"},{url:"assets/split.html.0ff2ce60.js",revision:"782e517f1be73a462dbb3572b55d8b68"},{url:"assets/split.html.b69d2cd1.js",revision:"98d0fdc5ae0f62d9de6a7aaa6838410f"},{url:"assets/spring.html.40b7b2ff.js",revision:"b609dae395c92a166bc41aee4e7b51bb"},{url:"assets/spring.html.75b19ea2.js",revision:"ce83e6c73d54a4eb2d2be0d6b78add4d"},{url:"assets/springtask.html.04deb6a0.js",revision:"79726149afec024f359dc783dc39aa3c"},{url:"assets/springtask.html.6f8efcf6.js",revision:"d6db8b09832b8485e9d63f7c7262706f"},{url:"assets/static.html.1a009c06.js",revision:"3d3bdf938d69191f52064821d34cda66"},{url:"assets/static.html.c9732093.js",revision:"968f3bdfc954039ba6a67d9440ed75ba"},{url:"assets/stream.html.02d08777.js",revision:"bd6b5a8e735b3700733b69640c4a807b"},{url:"assets/stream.html.214aab27.js",revision:"02b20169ec8176d859a10ee4b41683b8"},{url:"assets/style.aa7884a9.css",revision:"b50231da484889a39c0d651cca018162"},{url:"assets/suzhou.html.428c3730.js",revision:"a9ddf78eaac3ba6158593f0abb45799f"},{url:"assets/suzhou.html.b2ed5bbc.js",revision:"ad6b7c2e3bc4ccec8f0df69b0244e82c"},{url:"assets/swagger.html.1142f08f.js",revision:"402a89ba70a79688243b2e02b71f33bc"},{url:"assets/swagger.html.e13d1880.js",revision:"a113ed5764a0ee922db84f0edf6fa01b"},{url:"assets/synchronized.html.0249091e.js",revision:"0efb9296805b3b1f82608783a3bdb980"},{url:"assets/synchronized.html.6094d556.js",revision:"50bb92e6064fb1eeace2b8badcce12ec"},{url:"assets/tabby.html.8b43d084.js",revision:"fede60fdff4466bc0faa5a7c3f40a97e"},{url:"assets/tabby.html.c3b44c08.js",revision:"c81b9570dd8d07ca19fe54488d0c9820"},{url:"assets/this-super.html.65fa5da3.js",revision:"db3b96963f5594951739fe2924632a42"},{url:"assets/this-super.html.ff84e809.js",revision:"d52d1026b3cc4f6b8385b6150fcb859f"},{url:"assets/thread-bring-some-problem.html.891141f3.js",revision:"f6c29adc867ff6055c6389e5cc6f7a2b"},{url:"assets/thread-bring-some-problem.html.c8ae3e7a.js",revision:"d30408042adbdeca4ce50a59c6901032"},{url:"assets/thread-group-and-thread-priority.html.777c962b.js",revision:"aaf93443fed92c2a2c1b33c8f25950cf"},{url:"assets/thread-group-and-thread-priority.html.873709ce.js",revision:"4e54397c857c1341cd41f1cfff69ebb1"},{url:"assets/thread-state-and-method.html.70b8e2e8.js",revision:"99fbdee5498a36cf4161dea3e2aebd57"},{url:"assets/thread-state-and-method.html.a816be26.js",revision:"80d24fe42475ee6ee78ce1986764ea82"},{url:"assets/thread.html.34ab4613.js",revision:"1ed2cba245361944bd4249f6f3efe4fd"},{url:"assets/thread.html.4fcef02c.js",revision:"73676ab811effc7ca8466789ef3325bc"},{url:"assets/ThreadLocal.html.2993d4fd.js",revision:"1d04492707df70770666d10cb1d17b8d"},{url:"assets/ThreadLocal.html.f9a6fed8.js",revision:"e5f398cec6e9663ba5b58fe6a2a1ba63"},{url:"assets/thymeleaf.html.943910b5.js",revision:"a7a28429dce19f8027435507cbc57929"},{url:"assets/thymeleaf.html.b2ef505e.js",revision:"0e388a370a0ad657e60ba4ee5b47aeab"},{url:"assets/tobebetterjavaer-wangzhan-shangxian.html.a80895d2.js",revision:"1023c6d0dadb6420952b89fd749a6adc"},{url:"assets/tobebetterjavaer-wangzhan-shangxian.html.eb4a3068.js",revision:"0dfa3ae0bf98341875631534988ca34b"},{url:"assets/tomcat.html.73ec3645.js",revision:"7a7b107c1633a13d2190549cb6e03310"},{url:"assets/tomcat.html.af3e6ee8.js",revision:"cbda5ecb3fe9d3df6734f1bd0f403b7a"},{url:"assets/transaction.html.1d6a1548.js",revision:"a63bad9390bb54bf489b53e21f4c2dd5"},{url:"assets/transaction.html.9982a65f.js",revision:"a05d82344f35ba095b68c0cb7171933e"},{url:"assets/true-generic.html.a683e7b2.js",revision:"05dc4400bf38521b7ae923ac45277317"},{url:"assets/true-generic.html.ce09d792.js",revision:"7b33c1c5dbde75dd4deedd61ff4ffbb0"},{url:"assets/try-with-resouces.html.52a831d4.js",revision:"424a42ea24d029ae216cb9c41fa74e6f"},{url:"assets/try-with-resouces.html.8dcef913.js",revision:"7803c62919343844326660cb01e85fd9"},{url:"assets/tujie-gc.html.3ec6a37b.js",revision:"413aba6dc2daf9e9bd2013114cb17ed7"},{url:"assets/tujie-gc.html.ca2dffab.js",revision:"a7928789b0d96cef153aaf643807441e"},{url:"assets/tupian-zhuanlian.html.7ab13c07.js",revision:"11bbf9bb17b695c73038945d2d3ff5e3"},{url:"assets/tupian-zhuanlian.html.cc248511.js",revision:"67d582065436fe31c14e0bf91e5ac931"},{url:"assets/var.html.6e7f16a9.js",revision:"fcb3f82378d0cdc042066452ab0572b9"},{url:"assets/var.html.7a0cfd0f.js",revision:"44e56a632667ab8dc6fda19d2e951b8a"},{url:"assets/varables.html.3f84ac76.js",revision:"65b5434110402fac647879544d65adaa"},{url:"assets/varables.html.6a80fc0e.js",revision:"b5d838edc69034b99358140c53b3dacb"},{url:"assets/volatile.html.26279f7f.js",revision:"8b7c26f79da9fab23d11327674fb4d5e"},{url:"assets/volatile.html.4f34c8de.js",revision:"3f2dce960dbb5cfaccdb33226e081581"},{url:"assets/waibao-1geyue.html.31a36346.js",revision:"cee888b3465be2dd6d68694dc6793192"},{url:"assets/waibao-1geyue.html.fbddc89c.js",revision:"e015d6b16e709b6ccb97dce4163bb984"},{url:"assets/wangluo.html.b41cb57f.js",revision:"57732b795849149a6667300feb6a38da"},{url:"assets/wangluo.html.bf2e0885.js",revision:"c538dbc8a3dfeae6b57e2ca2604db68c"},{url:"assets/wangzhe-thread.html.752a4836.js",revision:"076f9ce43e6e8e0f88c214c918ca40f0"},{url:"assets/wangzhe-thread.html.dda72253.js",revision:"a93511501818791c302deaac765b4e15"},{url:"assets/warp.html.4380b228.js",revision:"1c7cd7539426cb69c99eefa6ad943b27"},{url:"assets/warp.html.8ae8cc83.js",revision:"99a539d31ad52d3991e0bb0d24113f7e"},{url:"assets/weixin-bagwpdf.html.a32b4b3a.js",revision:"77ab2bd1cd9b2019c156c83b89a74419"},{url:"assets/weixin-bagwpdf.html.e485fe14.js",revision:"7ed33ecaf7d743517285fb8573acfe11"},{url:"assets/weixin-chengxwjdwzhqcgxm.html.18dc866d.js",revision:"b566da699481353a4ad2423995f7d8eb"},{url:"assets/weixin-chengxwjdwzhqcgxm.html.5c788b1b.js",revision:"612bf1b6a51320c24d60912c479e1be6"},{url:"assets/weixin-githubxbkdjavajccjyh.html.11c03a69.js",revision:"f5f9cb416746799870bafd61c9085196"},{url:"assets/weixin-githubxbkdjavajccjyh.html.be4183ae.js",revision:"fd1c1112078fbc8ef0041114686ce158"},{url:"assets/weixin-liaoliaoxianliu.html.624e17ae.js",revision:"6f5c07a29b2398416dfc5164c9f08d11"},{url:"assets/weixin-liaoliaoxianliu.html.fa1a5a6a.js",revision:"d7adca67a7d381f6981cb817175944c4"},{url:"assets/weixin-likbj.html.4138e613.js",revision:"6395e20d8d24f4bcc933e75894fac268"},{url:"assets/weixin-likbj.html.a9767504.js",revision:"67265416eb31f31606416a0baafd2475"},{url:"assets/weixin-mozdsdzfjavableetcodetxxk.html.10059c85.js",revision:"6473a9bdd950392244f60e71df774de5"},{url:"assets/weixin-mozdsdzfjavableetcodetxxk.html.62ab0a25.js",revision:"0f190ae7e34f0e8ad471ee7809cfe761"},{url:"assets/weixin-piaolwzjztqdtskwlzfpdf.html.0792de0c.js",revision:"f035ffaff7e88d572d2c460ad84db23d"},{url:"assets/weixin-piaolwzjztqdtskwlzfpdf.html.ef3235a6.js",revision:"e3e8e581a5586b56de5c4d2085795f8a"},{url:"assets/weixin-quoppomspwml.html.03c9aa24.js",revision:"c001602f7147046efdac7de37c6de20c"},{url:"assets/weixin-quoppomspwml.html.27944449.js",revision:"1dd56bd3060a835f37fb980c0264913a"},{url:"assets/weixin-shejmsnb.html.1f9c172b.js",revision:"a66e546674efd8231e15dd9ad790ef38"},{url:"assets/weixin-shejmsnb.html.5a6a099f.js",revision:"ef87f2f1d3dd2bdb2068c1618d70f79f"},{url:"assets/weixin-shenrjcjavabfbchwjdhl.html.8fda2ac2.js",revision:"fbf8fe141f102c839715523a885e99d9"},{url:"assets/weixin-shenrjcjavabfbchwjdhl.html.ca182283.js",revision:"941b26ddeff96e2a49395aef68f7a5e2"},{url:"assets/weixin-xinllgjszjszzpojozsyjbsjlxyhjfyll.html.8f640dc9.js",revision:"873bcfb3534b542706c75db73ec1afeb"},{url:"assets/weixin-xinllgjszjszzpojozsyjbsjlxyhjfyll.html.b7b8ec57.js",revision:"854f359a6cb733a4efd07ed379ad7a37"},{url:"assets/weixin-zaixsfdnavicatzkkydsjkglgjjmgxk.html.ad8c7107.js",revision:"dc56c59218a15872112cc8942807b8ea"},{url:"assets/weixin-zaixsfdnavicatzkkydsjkglgjjmgxk.html.bcbd11eb.js",revision:"a70fc393a3bb18ba3eaa747e1fc8fea7"},{url:"assets/weixin-zhongxcwbztashjjavahdmj.html.2296ba72.js",revision:"48b175c2111f71995268f7183440b23d"},{url:"assets/weixin-zhongxcwbztashjjavahdmj.html.844aa3a1.js",revision:"7003350e84221429c44952436b05dd9a"},{url:"assets/weixin-zuixinbujiabandigongsimingdan.html.bf87a7d5.js",revision:"6b31f97d80d9263648f800c7917b6bb4"},{url:"assets/weixin-zuixinbujiabandigongsimingdan.html.d0426aa9.js",revision:"5504be78015703d138372586dace33bd"},{url:"assets/what-happen-when-javac.html.a24cf79e.js",revision:"8d987c500b7bf591d1f295525267a6c3"},{url:"assets/what-happen-when-javac.html.ab4282c1.js",revision:"aec391454b1d49aea2d1ca364b27bbad"},{url:"assets/what-is-java.html.b724e432.js",revision:"ea158f9a6749d586eb5eb1a5fe867369"},{url:"assets/what-is-java.html.efbb701f.js",revision:"e8e1bc913028977370b0593e7598e054"},{url:"assets/what-is-jvm.html.3177cd0e.js",revision:"696737b7be3e43dc6f2a8fc9eb4c5e7b"},{url:"assets/what-is-jvm.html.5131a239.js",revision:"2428430ef6fd17693a8d67d339efdbaf"},{url:"assets/whereis-the-object.html.5fa8d65e.js",revision:"1861acd01f60ab6cd59dcf238a943a84"},{url:"assets/whereis-the-object.html.c695df3e.js",revision:"40f9a605c5d9174441138c22b4df9205"},{url:"assets/why-need-thread.html.507a940d.js",revision:"d4a7d960b4a4125ab55a9d577d1e8360"},{url:"assets/why-need-thread.html.8e1db849.js",revision:"40bfd1d12d1e47eb85f6f578c0c8d4f1"},{url:"assets/windows-codingmore-run.html.225f6c56.js",revision:"135ab97e1dba75841e3f8b9d5be28f80"},{url:"assets/windows-codingmore-run.html.6d49b8aa.js",revision:"cc7b3b5d03ff06b212bd4154eafe2dc7"},{url:"assets/xian.html.b0d9fb64.js",revision:"c3b5f93959ba571c644a777d483db7e6"},{url:"assets/xian.html.badb133a.js",revision:"480724a731e95bf9d96e534d7146a281"},{url:"assets/xuebeng-chuantou-jichuan.html.26ef04a3.js",revision:"c10aab87bc0050f68ba50c3693861364"},{url:"assets/xuebeng-chuantou-jichuan.html.ffa86b85.js",revision:"079052f7ac584ae433e7b88a65a56af2"},{url:"assets/yanjiusuo-20wan.html.4b71b495.js",revision:"ac7087c137f0ec882510a72efd8bcb22"},{url:"assets/yanjiusuo-20wan.html.76b660c5.js",revision:"6cb110df442468ed54c8c39e2aed9685"},{url:"assets/yitiaolong.html.0ffd862a.js",revision:"740513e76f9f97d6e3f30dfbddf7ace9"},{url:"assets/yitiaolong.html.277dddb2.js",revision:"61cd35b123aa09db4ac2cda634ed7036"},{url:"assets/yuanyifeng-c-language.html.90250cb3.js",revision:"0877c195976395eeaca785ebb029c7ab"},{url:"assets/yuanyifeng-c-language.html.dbcc3d40.js",revision:"beb494651a64cdd304ba312be66de182"},{url:"assets/yuneban-wangyiyunyinyue.html.275a589e.js",revision:"02439e9c34e5ddec3bd616d8d036bb42"},{url:"assets/yuneban-wangyiyunyinyue.html.83ef1711.js",revision:"2e422246050a3d4fbe7e14fccfcf7e76"},{url:"assets/zhengzhou.html.bee29209.js",revision:"160ee95c89836a2d601659660d598a31"},{url:"assets/zhengzhou.html.c309c263.js",revision:"c4bf65e9d1458f8065a23c080a3a2ca4"},{url:"assets/zhihu-1000wan.html.4bf2b6f4.js",revision:"677db386556c4a3b1c5368584a949dde"},{url:"assets/zhihu-1000wan.html.51362a9b.js",revision:"fe3ce6427c608033cc2379bb2e7559b4"},{url:"assets/zhihu-jisjkyynxzdtjdyj.html.468f166c.js",revision:"b1ae892dd90147cb90a8a275f1dadbcc"},{url:"assets/zhihu-jisjkyynxzdtjdyj.html.8094217b.js",revision:"d5bb4c3b4257d9d451d8e4a52cfa6ade"},{url:"assets/zhihu-weismyrsyxkjgscxyzhdjyxz.html.98987909.js",revision:"22c49d6f5a97022f58b7b209e5061ad9"},{url:"assets/zhihu-weismyrsyxkjgscxyzhdjyxz.html.ec5fcad9.js",revision:"782767c646a8c40c4526244127448d35"},{url:"assets/zhihu-younxzdjsjzyxsjrdgq.html.c66976c6.js",revision:"e90dad3972a10bc0a21ea85481951f66"},{url:"assets/zhihu-younxzdjsjzyxsjrdgq.html.e644f706.js",revision:"8e28a5bf14351bb13a94e3500f0416a4"},{url:"assets/ZHIHUjavaxuexidaoshemechengduokeyizhaodiyifengongzuo.html.e4fead09.js",revision:"c265404944c7ef4afe301786011a3ab7"},{url:"assets/ZHIHUjavaxuexidaoshemechengduokeyizhaodiyifengongzuo.html.ef1e0c27.js",revision:"6758277cedc73bb0f2d6f20ada4b6a90"},{url:"assets/zijiema-zhiling.html.34c655bc.js",revision:"203ba55ffb1e89f9bb2fe0482a78a416"},{url:"assets/zijiema-zhiling.html.60db7eb3.js",revision:"7f1a8037a4e2922723645d7622235ae1"},{url:"assets/zongjie.html.1ee2edb6.js",revision:"f23bdac3926858be84a5ef0eb4856e0b"},{url:"assets/zongjie.html.c9e5e3c3.js",revision:"bfa15e84daf91ca3742016d07bbb8252"},{url:"assets/zoom.esm.8514a202.js",revision:"8b3ee4f6f71ef2a7c85901cba6d23344"},{url:"logo.svg",revision:"d7efe218a18b0891e803f61130d971ea"},{url:"assets/league-gothic.38fcc721.ttf",revision:"91295fa87df918411b49b7531da5d558"},{url:"assets/league-gothic.5eef6df8.woff",revision:"cd382dc8a9d6317864b5810a320effc5"},{url:"assets/league-gothic.8802c66a.eot",revision:"9900a4643cc63c5d8f969d2196f72572"},{url:"assets/source-sans-pro-italic.05d3615f.woff",revision:"e74f0128884561828ce8c9cf5c284ab8"},{url:"assets/source-sans-pro-italic.ad4b0799.eot",revision:"72217712eb8d28872e7069322f3fda23"},{url:"assets/source-sans-pro-italic.d13268af.ttf",revision:"8256cfd7e4017a7690814879409212cd"},{url:"assets/source-sans-pro-regular.c1865d89.ttf",revision:"2da39ecf9246383937da11b44b7bd9b4"},{url:"assets/source-sans-pro-regular.d4eaa48b.woff",revision:"e7acc589bb558fe58936a853f570193c"},{url:"assets/source-sans-pro-regular.dce8869d.eot",revision:"1d71438462d532b62b05cdd7e6d7197d"},{url:"assets/source-sans-pro-semibold.a53e2723.ttf",revision:"f3565095e6c9158140444970f5a2c5ed"},{url:"assets/source-sans-pro-semibold.b0abd273.woff",revision:"1cb8e94f1185f1131a0c895165998f2b"},{url:"assets/source-sans-pro-semibold.ebb8918d.eot",revision:"0f3da1edf1b5c6a94a6ad948a7664451"},{url:"assets/source-sans-pro-semibolditalic.7225cacc.woff",revision:"6b058fc2634b01d837c3432316c3141f"},{url:"assets/source-sans-pro-semibolditalic.dfe0b47a.eot",revision:"58153ac7194e141d1e73ea88c6b63861"},{url:"assets/source-sans-pro-semibolditalic.e8ec22b6.ttf",revision:"c7e698a4d0956f4a939f42a05685bbf5"},{url:"index.html",revision:"e9cf88a2938b1c751cfa6d8383867883"},{url:"404.html",revision:"52f839eb7af6c3ded982b8d1fb1f0823"},{url:"assets/icon/apple-icon-152.png",revision:"d78854fc622a0bfa2a44a79ec8b6e561"},{url:"assets/icon/chrome-192.png",revision:"eaab382db5bb589c74e2720a777454c3"},{url:"assets/icon/chrome-512.png",revision:"5db9d4a587b378f0b283191e379d85fa"},{url:"assets/icon/chrome-mask-192.png",revision:"eaab382db5bb589c74e2720a777454c3"},{url:"assets/icon/chrome-mask-512.png",revision:"5db9d4a587b378f0b283191e379d85fa"},{url:"assets/icon/itwanger-282.png",revision:"85592fba02d1228f8ca3e842cef07b7c"},{url:"assets/icon/itwanger-maskable.png",revision:"ca6a86caa8171a39adfd0f53f10cdaf2"},{url:"assets/icon/itwanger-monochrome.png",revision:"ca6a86caa8171a39adfd0f53f10cdaf2"},{url:"assets/icon/ms-icon-144.png",revision:"983a00416fc5f5469a79611440389396"},{url:"logo.png",revision:"d30ac8bc232973da730e934321ffeb7f"}],{}),s.cleanupOutdatedCaches()})); //# sourceMappingURL=service-worker.js.map diff --git a/dist/service-worker.js.map b/dist/service-worker.js.map index d3f71acd..c0207fbe 100644 --- a/dist/service-worker.js.map +++ b/dist/service-worker.js.map @@ -1 +1 @@ -{"version":3,"file":"service-worker.js","sources":["../../../../../private/var/folders/6b/ysj769_d2gddttlwzw0nmhyc0000gn/T/f938b5572b2751d4aeaac6c397c7ba46/service-worker.js"],"sourcesContent":["import {setCacheNameDetails as workbox_core_setCacheNameDetails} from '/Users/maweiqing/Documents/GitHub/toBeBetterJavaer/node_modules/workbox-core/setCacheNameDetails.mjs';\nimport {clientsClaim as workbox_core_clientsClaim} from '/Users/maweiqing/Documents/GitHub/toBeBetterJavaer/node_modules/workbox-core/clientsClaim.mjs';\nimport {precacheAndRoute as workbox_precaching_precacheAndRoute} from '/Users/maweiqing/Documents/GitHub/toBeBetterJavaer/node_modules/workbox-precaching/precacheAndRoute.mjs';\nimport {cleanupOutdatedCaches as workbox_precaching_cleanupOutdatedCaches} from '/Users/maweiqing/Documents/GitHub/toBeBetterJavaer/node_modules/workbox-precaching/cleanupOutdatedCaches.mjs';/**\n * Welcome to your Workbox-powered service worker!\n *\n * You'll need to register this file in your web app.\n * See https://goo.gl/nhQhGp\n *\n * The rest of the code is auto-generated. Please don't update this file\n * directly; instead, make changes to your Workbox build configuration\n * and re-run your build process.\n * See https://goo.gl/2aRDsh\n */\n\n\n\n\n\nworkbox_core_setCacheNameDetails({prefix: \"Java 程序员进阶之路\"});\n\n\nself.addEventListener('message', (event) => {\n if (event.data && event.data.type === 'SKIP_WAITING') {\n self.skipWaiting();\n }\n});\n\nworkbox_core_clientsClaim();\n\n\n/**\n * The precacheAndRoute() method efficiently caches and responds to\n * requests for URLs in the manifest.\n * See https://goo.gl/S9QRab\n */\nworkbox_precaching_precacheAndRoute([\n {\n \"url\": \"assets/100-budiushi.html.c3040dbf.js\",\n \"revision\": \"5e2fdf602f4f9cfe989cd2ecee4c6e1b\"\n },\n {\n \"url\": \"assets/100-budiushi.html.f74d8841.js\",\n \"revision\": \"3ecbc7c722366afc8037045b36b4f1e2\"\n },\n {\n \"url\": \"assets/4-debug-skill.html.1e235b0a.js\",\n \"revision\": \"d92033e1e0091d504c0db9c120c399dd\"\n },\n {\n \"url\": \"assets/4-debug-skill.html.9bd076fc.js\",\n \"revision\": \"bdd75149e13482f9c53f9ea3e0a36927\"\n },\n {\n \"url\": \"assets/40-interview.html.2cb0fe6c.js\",\n \"revision\": \"b73bdbdbc6bdccce1a2a65eb0e4a34ba\"\n },\n {\n \"url\": \"assets/40-interview.html.cb9b99de.js\",\n \"revision\": \"5983f28d781024f4491d454565e80cb4\"\n },\n {\n \"url\": \"assets/404.5ae72665.js\",\n \"revision\": \"3cc56698b4404bdc4312d24fe9ed4311\"\n },\n {\n \"url\": \"assets/404.html.5c274669.js\",\n \"revision\": \"268ea93907c83188e07ccbac7c112472\"\n },\n {\n \"url\": \"assets/404.html.e75684b7.js\",\n \"revision\": \"19f495e79edd1b6a31d59cc9804d8602\"\n },\n {\n \"url\": \"assets/48-keywords.html.34eb30fe.js\",\n \"revision\": \"8a98efeede1397e547a45922575057ac\"\n },\n {\n \"url\": \"assets/48-keywords.html.e76832ee.js\",\n \"revision\": \"0f28937c5f2199e1fb19617c0169cc05\"\n },\n {\n \"url\": \"assets/abstract.html.3094fdb5.js\",\n \"revision\": \"3f1e0182c50046175b9a0df0660d37e9\"\n },\n {\n \"url\": \"assets/abstract.html.60b3966f.js\",\n \"revision\": \"4031b3f9ba7030578715f84aaeea8eff\"\n },\n {\n \"url\": \"assets/algorithm.html.14390f00.js\",\n \"revision\": \"cbe7a405e3cfcc0ad60ef4bffc3765fb\"\n },\n {\n \"url\": \"assets/algorithm.html.66d3e273.js\",\n \"revision\": \"050bae691af2e4da0060297a7d505462\"\n },\n {\n \"url\": \"assets/ali-executors.html.988adc8e.js\",\n \"revision\": \"84812d38cd71487938d2a8511d0b7225\"\n },\n {\n \"url\": \"assets/ali-executors.html.e9951d8a.js\",\n \"revision\": \"0d4e4dcc2651eea56f65cc332390a1ba\"\n },\n {\n \"url\": \"assets/aliyun-shuaiguo-gongchengshi.html.80a83c0a.js\",\n \"revision\": \"8712ab388dee7c78bfed77536c312cea\"\n },\n {\n \"url\": \"assets/aliyun-shuaiguo-gongchengshi.html.e4346151.js\",\n \"revision\": \"97ea58e96d96f1afd5bb00e2f3b35fcb\"\n },\n {\n \"url\": \"assets/annotation.html.14064668.js\",\n \"revision\": \"b8c310fbc00430fd403dedfcffd9e496\"\n },\n {\n \"url\": \"assets/annotation.html.b0fc1ba0.js\",\n \"revision\": \"63a677b83353ca3eff074889dad11445\"\n },\n {\n \"url\": \"assets/aop-log.html.390b071a.js\",\n \"revision\": \"4d14cfeb7c0b409467bb60a83463cd8a\"\n },\n {\n \"url\": \"assets/aop-log.html.f3df7d62.js\",\n \"revision\": \"9169d18e23e3603a08699453af417171\"\n },\n {\n \"url\": \"assets/api-wangguan.html.9f0edd64.js\",\n \"revision\": \"96affaf79170b91a3f6fe3af5d39044e\"\n },\n {\n \"url\": \"assets/api-wangguan.html.c2b18262.js\",\n \"revision\": \"82f0406d65453e8eb1a5ad59ca30ecb0\"\n },\n {\n \"url\": \"assets/app.a0271b9c.js\",\n \"revision\": \"c67d329e17fa0244204bed8ba3c8dee4\"\n },\n {\n \"url\": \"assets/aqs.html.d6a8f5b4.js\",\n \"revision\": \"625d292bc1a70d1e7405da97b6029523\"\n },\n {\n \"url\": \"assets/aqs.html.e6bd9611.js\",\n \"revision\": \"6a368249313dc9131a7521e95aed30dc\"\n },\n {\n \"url\": \"assets/array.html.77525f56.js\",\n \"revision\": \"c7cc1063f8abb40eb5a6e6bb3a220431\"\n },\n {\n \"url\": \"assets/array.html.97a807b4.js\",\n \"revision\": \"a6f79d638eabb85c97c90b71ad600583\"\n },\n {\n \"url\": \"assets/arraylist.html.0dcdca73.js\",\n \"revision\": \"381a5a48e521e35dda79e367eac116a1\"\n },\n {\n \"url\": \"assets/arraylist.html.804615c1.js\",\n \"revision\": \"e4cb8c73d720fb02db354fa1d8fdf224\"\n },\n {\n \"url\": \"assets/arrays.html.13de83ef.js\",\n \"revision\": \"f94fd5d206d6d69e88a138d19ce76dfd\"\n },\n {\n \"url\": \"assets/arrays.html.7944f961.js\",\n \"revision\": \"c15f2d6bcb85818880f6f8383f9dbc61\"\n },\n {\n \"url\": \"assets/asm.html.0e0abd8b.js\",\n \"revision\": \"072c730bffd7fc1a8a611ddd1c5da23e\"\n },\n {\n \"url\": \"assets/asm.html.deedcff5.js\",\n \"revision\": \"61c27e4accd210a0387f4455886819ac\"\n },\n {\n \"url\": \"assets/atomic.html.1dc322e5.js\",\n \"revision\": \"198e7d55f80be469859f72f0647ace36\"\n },\n {\n \"url\": \"assets/atomic.html.93391f09.js\",\n \"revision\": \"0a81ec041fa27d2b5cff824a647d20a1\"\n },\n {\n \"url\": \"assets/auto-generator.html.79ba5c06.js\",\n \"revision\": \"d364fb71af23e516dd0b1fa7b7abee61\"\n },\n {\n \"url\": \"assets/auto-generator.html.edd07e0d.js\",\n \"revision\": \"459b8e54b7d592596c99df653773d8e9\"\n },\n {\n \"url\": \"assets/basic-data-type.html.52152cd3.js\",\n \"revision\": \"42a3549d7841190a92927b56e6bb3ba3\"\n },\n {\n \"url\": \"assets/basic-data-type.html.6be3e7e2.js\",\n \"revision\": \"926a54b4618afc77e58598cb1f53e6ed\"\n },\n {\n \"url\": \"assets/bat-shuati.html.adba9635.js\",\n \"revision\": \"95b1c08b506d1bdc59d0cef79d439039\"\n },\n {\n \"url\": \"assets/bat-shuati.html.bf129827.js\",\n \"revision\": \"c4f631aa6f12d534db680124dcfdef0e\"\n },\n {\n \"url\": \"assets/beijing.html.5436f34b.js\",\n \"revision\": \"541c49a82e9b4823be52a7c5dcf738c4\"\n },\n {\n \"url\": \"assets/beijing.html.ac5b087b.js\",\n \"revision\": \"eb8232a3c67f62d1daabadc762fc0267\"\n },\n {\n \"url\": \"assets/BIONIOAIO.html.27d4fa22.js\",\n \"revision\": \"c138b5cdd8c3d0555fe27a74da4ee71e\"\n },\n {\n \"url\": \"assets/BIONIOAIO.html.ea89d11f.js\",\n \"revision\": \"1e4874dbc0370df66e2880da25a688ca\"\n },\n {\n \"url\": \"assets/BlockingQueue.html.5fa0f03a.js\",\n \"revision\": \"5a17077091b6bf9f5a67382c1132a0f7\"\n },\n {\n \"url\": \"assets/BlockingQueue.html.9ccd9ba0.js\",\n \"revision\": \"ceeda89af92173a6e837c5a077c9d909\"\n },\n {\n \"url\": \"assets/bokeyuan-jianxijavazhongdifangwenquanxiankongzhi.html.95de7e08.js\",\n \"revision\": \"9fdcfd9383a500542735132539a3c662\"\n },\n {\n \"url\": \"assets/bokeyuan-jianxijavazhongdifangwenquanxiankongzhi.html.bc8753e4.js\",\n \"revision\": \"e407e843972f36f357c6600a48c11379\"\n },\n {\n \"url\": \"assets/bokeyuan-ruhegaoxiaodixuexijishu.html.b64706b8.js\",\n \"revision\": \"a50adcc55132fb174135a0fac156f545\"\n },\n {\n \"url\": \"assets/bokeyuan-ruhegaoxiaodixuexijishu.html.e9d4ca36.js\",\n \"revision\": \"1a48b0e99830900cbfeb4437a51aae72\"\n },\n {\n \"url\": \"assets/BOKEYUANruhegaoxiaodixuexijishu.html.54dd2a4d.js\",\n \"revision\": \"e410b4653746a1f3a29de7315e67451d\"\n },\n {\n \"url\": \"assets/BOKEYUANruhegaoxiaodixuexijishu.html.bdd4e19a.js\",\n \"revision\": \"d889094d96aeb06c47c6db4b994fc898\"\n },\n {\n \"url\": \"assets/box.html.54cc70a2.js\",\n \"revision\": \"09778d260a2bd54390c5df81ae5c0a4c\"\n },\n {\n \"url\": \"assets/box.html.9c8b69db.js\",\n \"revision\": \"49c9f66c159e83373c6215e1402270f7\"\n },\n {\n \"url\": \"assets/buy-cloud-server.html.595deaa6.js\",\n \"revision\": \"bea7becb36dcf02d7c5215fc19797c6e\"\n },\n {\n \"url\": \"assets/buy-cloud-server.html.d200b8bc.js\",\n \"revision\": \"caeca61f089ac012663ae00f5425f72d\"\n },\n {\n \"url\": \"assets/buy-domain.html.1227af51.js\",\n \"revision\": \"2084929626a6e80923df3997bea07231\"\n },\n {\n \"url\": \"assets/buy-domain.html.4406ff12.js\",\n \"revision\": \"6ec3445b674b953c65f069e2ef67f0f2\"\n },\n {\n \"url\": \"assets/bytecode.html.09a0585c.js\",\n \"revision\": \"ef6f78bd725da1837b302e3c7241e490\"\n },\n {\n \"url\": \"assets/bytecode.html.ba8f00b6.js\",\n \"revision\": \"c0d1e7ef23332326dc90ce1d81d5d05f\"\n },\n {\n \"url\": \"assets/bzhan-10wan.html.98f8ba37.js\",\n \"revision\": \"d68d1bd3dddf462db72f205b33e3eeb5\"\n },\n {\n \"url\": \"assets/bzhan-10wan.html.b3906807.js\",\n \"revision\": \"14f64220fb9957467710377a0dbbfc9f\"\n },\n {\n \"url\": \"assets/c.html.1f2463e6.js\",\n \"revision\": \"22c6d4776333d8bc0c48d24cc2122703\"\n },\n {\n \"url\": \"assets/c.html.5983fe89.js\",\n \"revision\": \"cee3031a57cc138acc6d11755802b30e\"\n },\n {\n \"url\": \"assets/cas.html.4534d702.js\",\n \"revision\": \"8bc80781d9d2bdde974c66d01343caf9\"\n },\n {\n \"url\": \"assets/cas.html.ff0123d4.js\",\n \"revision\": \"8aead092c977c22a92060b941af56e40\"\n },\n {\n \"url\": \"assets/ccc.html.0a777341.js\",\n \"revision\": \"506d7bf9c04b695b62f010d03b304c93\"\n },\n {\n \"url\": \"assets/ccc.html.51a24970.js\",\n \"revision\": \"e724b888cc455ff547b84535af17a324\"\n },\n {\n \"url\": \"assets/chadiansanhuo.html.78becde9.js\",\n \"revision\": \"f425b866097150767f32355073fc1b66\"\n },\n {\n \"url\": \"assets/chadiansanhuo.html.e9cc0b99.js\",\n \"revision\": \"3ae54e43d8b55c9b07f8b96eb885ddfd\"\n },\n {\n \"url\": \"assets/chengdu.html.09b27f2f.js\",\n \"revision\": \"a57af5b30fd47338e387bc3f6df009bf\"\n },\n {\n \"url\": \"assets/chengdu.html.8c0a9616.js\",\n \"revision\": \"58e48254752fa8b92853deee07bfd5cd\"\n },\n {\n \"url\": \"assets/chengxuyuannv-chonghui-java.html.b2dd4108.js\",\n \"revision\": \"0487f286d80446b156f7fe6f4abe3294\"\n },\n {\n \"url\": \"assets/chengxuyuannv-chonghui-java.html.b9de6702.js\",\n \"revision\": \"eae9b017adb086faa22ac24423ebc287\"\n },\n {\n \"url\": \"assets/chiner.html.13c55607.js\",\n \"revision\": \"82785120402bceab024e50887e5714d1\"\n },\n {\n \"url\": \"assets/chiner.html.5580190e.js\",\n \"revision\": \"d0da5776acb158ea6ddecd3795cceb88\"\n },\n {\n \"url\": \"assets/choco.html.8857968e.js\",\n \"revision\": \"a7274435a5211b4ea1a31360b2d413a4\"\n },\n {\n \"url\": \"assets/choco.html.f8923e81.js\",\n \"revision\": \"f1ecf9c1e645995f595ae0192eef1f6c\"\n },\n {\n \"url\": \"assets/Chocolatey-Homebrew.html.a0b23720.js\",\n \"revision\": \"92a4c97d2e1182191ce3fa2abc40ded7\"\n },\n {\n \"url\": \"assets/Chocolatey-Homebrew.html.ad256880.js\",\n \"revision\": \"f27f5ffe5e873f37caae308cd3f7c800\"\n },\n {\n \"url\": \"assets/class-file-jiegou.html.3dff0326.js\",\n \"revision\": \"96c0ab54ea6bd0c20cc027807b9c0117\"\n },\n {\n \"url\": \"assets/class-file-jiegou.html.63f6ec81.js\",\n \"revision\": \"1f0cdde61a4cd67bf4299d62a8f4af0a\"\n },\n {\n \"url\": \"assets/class-load.html.6a788fca.js\",\n \"revision\": \"1b73773905c7665af8d92be86ff7c93c\"\n },\n {\n \"url\": \"assets/class-load.html.ac3b08f8.js\",\n \"revision\": \"eaf1ab0b5573d73ae0575c33da5d70ab\"\n },\n {\n \"url\": \"assets/class-object.html.2cd0dbd5.js\",\n \"revision\": \"903aeb8d4c192cb9e6b4ae0bc6e54f73\"\n },\n {\n \"url\": \"assets/class-object.html.c43412d3.js\",\n \"revision\": \"95d854056dbe7d047f22d73d03c0c4bf\"\n },\n {\n \"url\": \"assets/code-init.html.16081b84.js\",\n \"revision\": \"6297f1cde9dd90188e3afc300bd5279f\"\n },\n {\n \"url\": \"assets/code-init.html.70ef628a.js\",\n \"revision\": \"818831e291e49a1121d4867cbbf34e7b\"\n },\n {\n \"url\": \"assets/collection.html.42c40509.js\",\n \"revision\": \"3e9a280a2708f759c09967d7f84b7b1c\"\n },\n {\n \"url\": \"assets/collection.html.d1a47d1f.js\",\n \"revision\": \"90fcb9209f7e71a63d6d00e26a74f49b\"\n },\n {\n \"url\": \"assets/collections.html.2e6479a3.js\",\n \"revision\": \"2a8ef3d4cdfea297d8e08d2e1767a0f6\"\n },\n {\n \"url\": \"assets/collections.html.b7f2022a.js\",\n \"revision\": \"391b0c8300f7e571785b19e64183591f\"\n },\n {\n \"url\": \"assets/comparable-omparator.html.397dc2ff.js\",\n \"revision\": \"4fc9d5e6efa5df02a669384c67c775c4\"\n },\n {\n \"url\": \"assets/comparable-omparator.html.c8fb7fdb.js\",\n \"revision\": \"ba24f9070ad3e1b591f507e5842b2fce\"\n },\n {\n \"url\": \"assets/compile-jdk.html.2e638e51.js\",\n \"revision\": \"65162150c690bd0452a034e058b27703\"\n },\n {\n \"url\": \"assets/compile-jdk.html.531caac0.js\",\n \"revision\": \"cfb5cd6a34b5696dec2ff5c2cf32665b\"\n },\n {\n \"url\": \"assets/computer-base.html.1ca00f7c.js\",\n \"revision\": \"be3c376caa78632880fff3bdb7963f59\"\n },\n {\n \"url\": \"assets/computer-base.html.f469b424.js\",\n \"revision\": \"1f6ecd345516bff8d501b14e1594704b\"\n },\n {\n \"url\": \"assets/ConcurrentHashMap.html.127182e6.js\",\n \"revision\": \"3485ba56346c6110176e86ca3aa23068\"\n },\n {\n \"url\": \"assets/ConcurrentHashMap.html.e7f83c81.js\",\n \"revision\": \"0d28e48bc1568ebab9dcc835e29ba876\"\n },\n {\n \"url\": \"assets/ConcurrentLinkedQueue.html.ad944043.js\",\n \"revision\": \"579f73cebbd40f2e6637cdcd59e84c7e\"\n },\n {\n \"url\": \"assets/ConcurrentLinkedQueue.html.da4bfec1.js\",\n \"revision\": \"23433f93339dc43427ba24cee5941137\"\n },\n {\n \"url\": \"assets/condition.html.a41bdc76.js\",\n \"revision\": \"d7d34d6a2e7d5506b58e1b72264aad0c\"\n },\n {\n \"url\": \"assets/condition.html.dcd667af.js\",\n \"revision\": \"70d5365eb60b25646264be86110e9b6a\"\n },\n {\n \"url\": \"assets/constant-pool.html.c79f5c21.js\",\n \"revision\": \"61e5fe3195c6360d58f87a081108d8b3\"\n },\n {\n \"url\": \"assets/constant-pool.html.e2d85914.js\",\n \"revision\": \"af37ee862cb4d200937bdc808566d076\"\n },\n {\n \"url\": \"assets/construct.html.5ae3e6eb.js\",\n \"revision\": \"e6248e5666fb845c81737f955adcee8e\"\n },\n {\n \"url\": \"assets/construct.html.ebfac9f1.js\",\n \"revision\": \"ccb60ea2843fd836ff1739d72a65b8a4\"\n },\n {\n \"url\": \"assets/CopyOnWriteArrayList.html.375356c8.js\",\n \"revision\": \"f1029953b3360d14cad73e2cb431d76c\"\n },\n {\n \"url\": \"assets/CopyOnWriteArrayList.html.b8e564c2.js\",\n \"revision\": \"f2f383f2d43d94ceccdbe96b2b1c6440\"\n },\n {\n \"url\": \"assets/cors.html.32e975b9.js\",\n \"revision\": \"da33a1e03c3d08e3a0f1da68f3b74a8f\"\n },\n {\n \"url\": \"assets/cors.html.b8f51585.js\",\n \"revision\": \"7439fe2677e95d97a601cf2a34e91040\"\n },\n {\n \"url\": \"assets/CountDownLatch.html.db5e5e87.js\",\n \"revision\": \"f1ea7ca00771124ce05aa6ea2d011e1c\"\n },\n {\n \"url\": \"assets/CountDownLatch.html.f036fab2.js\",\n \"revision\": \"26b7d176d09b3669f790cd3526ef5132\"\n },\n {\n \"url\": \"assets/cpu-percent-100.html.3a56db8e.js\",\n \"revision\": \"b89e1f110cc02b04a4e1faab591a7c5d\"\n },\n {\n \"url\": \"assets/cpu-percent-100.html.f6bd745b.js\",\n \"revision\": \"ad8a7d92c2d6b25c044333bc25f9537a\"\n },\n {\n \"url\": \"assets/csdn-1000wan.html.2e52cd37.js\",\n \"revision\": \"8877c4736d9509cbc13e8c13cb4822f9\"\n },\n {\n \"url\": \"assets/csdn-1000wan.html.438218cb.js\",\n \"revision\": \"259561af8e4bdd5fd3e6a009bb23fb74\"\n },\n {\n \"url\": \"assets/daxue-nuli-jisuanji.html.2b1074e1.js\",\n \"revision\": \"269b99461af7c8e4de2b6672a6db1ed6\"\n },\n {\n \"url\": \"assets/daxue-nuli-jisuanji.html.5d9f6906.js\",\n \"revision\": \"736ba5c69ba7cab3b8a9a472ce7fdd90\"\n },\n {\n \"url\": \"assets/DBeaver.html.75fbe8f6.js\",\n \"revision\": \"d453149ad3ea09402d8efd2ec3cbdb5f\"\n },\n {\n \"url\": \"assets/DBeaver.html.8a022161.js\",\n \"revision\": \"537c5a4247d6224d55a6ad7e6374de7a\"\n },\n {\n \"url\": \"assets/deep-copy.html.b367f078.js\",\n \"revision\": \"e0a2406e1b6499e88721b8e21f44c004\"\n },\n {\n \"url\": \"assets/deep-copy.html.b6383852.js\",\n \"revision\": \"a0c4aa6756f54be9d03e8f998cc5e19a\"\n },\n {\n \"url\": \"assets/deletedb-binlog-weiguanjishu.html.114e51d7.js\",\n \"revision\": \"1d95322e12cb6a6db197eb093565edae\"\n },\n {\n \"url\": \"assets/deletedb-binlog-weiguanjishu.html.605b28a5.js\",\n \"revision\": \"bd5a5b97f531ad34a84c30fb9af6a895\"\n },\n {\n \"url\": \"assets/electron-information-engineering.html.365eb9fa.js\",\n \"revision\": \"2bc05cecd720fb5401ff5b1729639d06\"\n },\n {\n \"url\": \"assets/electron-information-engineering.html.b3d4a3e7.js\",\n \"revision\": \"1c61717566865bff4cfc9ca4721007c0\"\n },\n {\n \"url\": \"assets/enum.html.21e74b14.js\",\n \"revision\": \"812d1c9d0547cbd890fb5bc8f3cf78e3\"\n },\n {\n \"url\": \"assets/enum.html.e72022eb.js\",\n \"revision\": \"5c0d872a8b0247760f069e3151147baf\"\n },\n {\n \"url\": \"assets/equals-hashcode.html.6e080022.js\",\n \"revision\": \"cc07f78eeb7f5488a81f70e37aaa55be\"\n },\n {\n \"url\": \"assets/equals-hashcode.html.cd3210fa.js\",\n \"revision\": \"063e16ab8d211c0c61299a99bf635de1\"\n },\n {\n \"url\": \"assets/equals.html.2fb94b25.js\",\n \"revision\": \"46208de98557b94b1aa23d2d106371fb\"\n },\n {\n \"url\": \"assets/equals.html.b49827b6.js\",\n \"revision\": \"3f4f95c44c82dd067dfc5e39f2dcc6fc\"\n },\n {\n \"url\": \"assets/fail-fast.html.4b8a884f.js\",\n \"revision\": \"8f5872231ff04b187d0ad54370d91c4b\"\n },\n {\n \"url\": \"assets/fail-fast.html.613c56f6.js\",\n \"revision\": \"f915ae8570f88f7bacaf387886caeb5a\"\n },\n {\n \"url\": \"assets/fanshe.html.13ada7e7.js\",\n \"revision\": \"7b7c5fe2868eee1782f53b121e74b12f\"\n },\n {\n \"url\": \"assets/fanshe.html.c9e51464.js\",\n \"revision\": \"be7e84e923fc2908878786d5cb7c2ab6\"\n },\n {\n \"url\": \"assets/fastjson.html.ac85dfcc.js\",\n \"revision\": \"0069aa2791ea3b6ce0f8d3822bc9d48d\"\n },\n {\n \"url\": \"assets/fastjson.html.f97ae6fd.js\",\n \"revision\": \"a8326b550ef22ce4e613c3042cae5cb2\"\n },\n {\n \"url\": \"assets/Filter-Interceptor-Listener.html.61c686d0.js\",\n \"revision\": \"81596195f64c7a27e56c9004407ac9f8\"\n },\n {\n \"url\": \"assets/Filter-Interceptor-Listener.html.d4211e38.js\",\n \"revision\": \"8c4bcbc295b3a96eceb05bd1a0e36451\"\n },\n {\n \"url\": \"assets/final.html.c83d9074.js\",\n \"revision\": \"c726701bca64c1974ecb054822c85377\"\n },\n {\n \"url\": \"assets/final.html.de436e22.js\",\n \"revision\": \"e7a4ea72c149774b072285fa4fd9cfd6\"\n },\n {\n \"url\": \"assets/flow-control.html.1f719486.js\",\n \"revision\": \"eb20f449c3102a7a6a159bfe86f0ed93\"\n },\n {\n \"url\": \"assets/flow-control.html.f6c60ead.js\",\n \"revision\": \"40ec7db6a6132bc01f51bcdbea3fa717\"\n },\n {\n \"url\": \"assets/forest.html.18099f01.js\",\n \"revision\": \"8b97817fc4c133816bf6c76bd9ad8e83\"\n },\n {\n \"url\": \"assets/forest.html.79a7cfed.js\",\n \"revision\": \"5f057f53de7ba5b74e96f1ec60ffb21e\"\n },\n {\n \"url\": \"assets/fork-join.html.148dd105.js\",\n \"revision\": \"d7a62864947a9330caf495f2be574e89\"\n },\n {\n \"url\": \"assets/fork-join.html.f967d485.js\",\n \"revision\": \"26f31bc4133e61588d3e1ab2966e722b\"\n },\n {\n \"url\": \"assets/fumutuanju.html.577491d1.js\",\n \"revision\": \"d2f0d6831711758976a8c940798c4f4f\"\n },\n {\n \"url\": \"assets/fumutuanju.html.d5b695cc.js\",\n \"revision\": \"e376c786d472726b54bd69af3e10856e\"\n },\n {\n \"url\": \"assets/gailan.html.87d77185.js\",\n \"revision\": \"838f7f94a9e88620b46b4e6e7a790e1d\"\n },\n {\n \"url\": \"assets/gailan.html.89a0a128.js\",\n \"revision\": \"2173ae38867d7d0402473053c22ff09d\"\n },\n {\n \"url\": \"assets/gailan.html.a5bab427.js\",\n \"revision\": \"52ecb8199d93f479c824bea35322ffb0\"\n },\n {\n \"url\": \"assets/gailan.html.fee068f9.js\",\n \"revision\": \"656821687243257a5d84494525d3219d\"\n },\n {\n \"url\": \"assets/gc.html.10f470a0.js\",\n \"revision\": \"20aa9dc63a32b23dc46c3e2c96fc9c12\"\n },\n {\n \"url\": \"assets/gc.html.cec6db87.js\",\n \"revision\": \"818e2a3e352aea0b7dcfee09455162c7\"\n },\n {\n \"url\": \"assets/generic.html.47649dca.js\",\n \"revision\": \"21efbba6585f30fa61af2fc4c5396c58\"\n },\n {\n \"url\": \"assets/generic.html.7ec41e80.js\",\n \"revision\": \"2ff01c60d7d59252cfd4d4d55d0467ff\"\n },\n {\n \"url\": \"assets/git-qiyuan.html.054515ab.js\",\n \"revision\": \"308020a99661a2530c8989e89c509403\"\n },\n {\n \"url\": \"assets/git-qiyuan.html.1b827703.js\",\n \"revision\": \"35d293835ab02f0dffd2bb2a311ea1bc\"\n },\n {\n \"url\": \"assets/go.html.528d4a75.js\",\n \"revision\": \"0ce9693e8631b976ca6f1a55edae0f70\"\n },\n {\n \"url\": \"assets/go.html.712c93cd.js\",\n \"revision\": \"2ac8c637060f2eed18c6b4379a6d96b1\"\n },\n {\n \"url\": \"assets/gson.html.da4ecf62.js\",\n \"revision\": \"ad5c64040c19daedc3257cdf418fd5d2\"\n },\n {\n \"url\": \"assets/gson.html.e79a454d.js\",\n \"revision\": \"01fedf3f3911791ead09eedd7e5f410a\"\n },\n {\n \"url\": \"assets/guangzhou.html.14bc2637.js\",\n \"revision\": \"53d8b0cf336a5513a709252a5495d0ba\"\n },\n {\n \"url\": \"assets/guangzhou.html.ce1033cd.js\",\n \"revision\": \"769606116ba4a3c644639cc9d45a050b\"\n },\n {\n \"url\": \"assets/guava.html.1f12859a.js\",\n \"revision\": \"83816f06ae896fa50ab4d9cf0b41c572\"\n },\n {\n \"url\": \"assets/guava.html.e73aaedd.js\",\n \"revision\": \"9d698d9f891d7c22f3ac477808b8f998\"\n },\n {\n \"url\": \"assets/haibukuaiyongmybatisplusshoubashoujiaoni.html.4769ffdb.js\",\n \"revision\": \"8b1f46e7be3e7116c325dc37149193ef\"\n },\n {\n \"url\": \"assets/haibukuaiyongmybatisplusshoubashoujiaoni.html.5f5e650f.js\",\n \"revision\": \"928b694b6fca9b5ae2c53559b4e8647a\"\n },\n {\n \"url\": \"assets/hangzhou.html.9719a0ea.js\",\n \"revision\": \"a8664cfac4636b022d5588da361936d8\"\n },\n {\n \"url\": \"assets/hangzhou.html.b80d450d.js\",\n \"revision\": \"75901d5a04025f7d0b4ae343ab991b14\"\n },\n {\n \"url\": \"assets/hashcode.html.24290486.js\",\n \"revision\": \"343281510b0998fa1d048d3c5bf2b144\"\n },\n {\n \"url\": \"assets/hashcode.html.94e85992.js\",\n \"revision\": \"211e4f0ab2cb151c1b6bfc9bbaaebb48\"\n },\n {\n \"url\": \"assets/hashmap-interview.html.2609e519.js\",\n \"revision\": \"73a76b988878f178ac5f8190dcbb769b\"\n },\n {\n \"url\": \"assets/hashmap-interview.html.307a5634.js\",\n \"revision\": \"fe897032d2207465583c5a2783cc6364\"\n },\n {\n \"url\": \"assets/hashmap.html.cd5a497b.js\",\n \"revision\": \"0eff8cc7029cc583f16454f99777db5d\"\n },\n {\n \"url\": \"assets/hashmap.html.f8e12ca4.js\",\n \"revision\": \"64a8ec255cab16b059484b8930e0338e\"\n },\n {\n \"url\": \"assets/hello-world.html.504deafe.js\",\n \"revision\": \"94965ca60a6acb39f1733b4dcaebe8f7\"\n },\n {\n \"url\": \"assets/hello-world.html.d0d5adf0.js\",\n \"revision\": \"edf374e50da38d8b82c8dad4c5f2a9c9\"\n },\n {\n \"url\": \"assets/highlight.esm.d982e650.js\",\n \"revision\": \"3457767fb4f7fe757ad6fb071f162a85\"\n },\n {\n \"url\": \"assets/history.html.6bcd3b59.js\",\n \"revision\": \"4bb5ecbef225f144c01f31b469fc0db0\"\n },\n {\n \"url\": \"assets/history.html.6df608e4.js\",\n \"revision\": \"edafea3f3bb61548faac24d804cae17c\"\n },\n {\n \"url\": \"assets/home.html.4301cc35.js\",\n \"revision\": \"d758970d0af285d84bae538387578048\"\n },\n {\n \"url\": \"assets/home.html.c8d9ace7.js\",\n \"revision\": \"9a2fea3e8b91d21a04e78e8f4fff4722\"\n },\n {\n \"url\": \"assets/how-jvm-run-zijiema-zhiling.html.400c699c.js\",\n \"revision\": \"a1e65b5f2c56245fb14f3e212611d505\"\n },\n {\n \"url\": \"assets/how-jvm-run-zijiema-zhiling.html.4c09b054.js\",\n \"revision\": \"feea05b20570c3db671d2a5993af9026\"\n },\n {\n \"url\": \"assets/how-run-java-code.html.1867de4d.js\",\n \"revision\": \"5cf492e41232393c8b14781f521b0932\"\n },\n {\n \"url\": \"assets/how-run-java-code.html.5a48d5a6.js\",\n \"revision\": \"248828e5c0fe3208f8fe06a99e1e35d2\"\n },\n {\n \"url\": \"assets/hsdb.html.18e11779.js\",\n \"revision\": \"df785efdcc53f871f2a6a60c3117ed46\"\n },\n {\n \"url\": \"assets/hsdb.html.e06d55d6.js\",\n \"revision\": \"ad7a87fc50d8515780225b075b58f367\"\n },\n {\n \"url\": \"assets/https-domain.html.847eb117.js\",\n \"revision\": \"bf28a27b383cee8995274c7489f6c532\"\n },\n {\n \"url\": \"assets/https-domain.html.86fa1a27.js\",\n \"revision\": \"627dc3a525264fe4c466f4d4607a9047\"\n },\n {\n \"url\": \"assets/hutool.html.06e72427.js\",\n \"revision\": \"10ab5d7054f66e38c5a99dbed60d31f9\"\n },\n {\n \"url\": \"assets/hutool.html.3a80c8b8.js\",\n \"revision\": \"4dea5be9c2e3715cb0bb2fdc1d6577bd\"\n },\n {\n \"url\": \"assets/image-yasuo.html.8853b749.js\",\n \"revision\": \"f81cd85d277b957d04fd25be2cabe9df\"\n },\n {\n \"url\": \"assets/image-yasuo.html.d1e70eaf.js\",\n \"revision\": \"51f90fc1081296185f76fd50f8411b42\"\n },\n {\n \"url\": \"assets/immutable.html.36fadfba.js\",\n \"revision\": \"2c68404981e3db1079eaf013a6d08bb4\"\n },\n {\n \"url\": \"assets/immutable.html.923c43ef.js\",\n \"revision\": \"91365a7e046a7246c78ec6998cf2d4e7\"\n },\n {\n \"url\": \"assets/immutable.html.e7e4c546.js\",\n \"revision\": \"09d806a7ba458245b380ecbfbbd33163\"\n },\n {\n \"url\": \"assets/immutable.html.fdd47709.js\",\n \"revision\": \"55e538731a82b55cc7f6e72e291a0844\"\n },\n {\n \"url\": \"assets/index.html.17715b69.js\",\n \"revision\": \"9765077677330d361b2254e7b7197782\"\n },\n {\n \"url\": \"assets/index.html.23006160.js\",\n \"revision\": \"5eb9d1468cfdec9b1f5fa9ad2e97fc78\"\n },\n {\n \"url\": \"assets/index.html.2971f84c.js\",\n \"revision\": \"dcf54918ced8418b27d97f411c4896e8\"\n },\n {\n \"url\": \"assets/index.html.698aa818.js\",\n \"revision\": \"9c38fccd3fc6dbdfc7314582ff98359c\"\n },\n {\n \"url\": \"assets/index.html.8360409e.js\",\n \"revision\": \"81ef16e38cc5d294d521594523ff6b56\"\n },\n {\n \"url\": \"assets/index.html.a4bb5c6e.js\",\n \"revision\": \"98c0a3ad6498080673df4a2c64bbaf8f\"\n },\n {\n \"url\": \"assets/index.html.af7b50d7.js\",\n \"revision\": \"7cfee9d75653d5da427262a91f694572\"\n },\n {\n \"url\": \"assets/index.html.bb2bcc18.js\",\n \"revision\": \"5e05257eb3586e82ad59157b474d376b\"\n },\n {\n \"url\": \"assets/index.html.ece7c54d.js\",\n \"revision\": \"779c6c39fd36d1ca19db103ebbb20305\"\n },\n {\n \"url\": \"assets/index.html.fd879420.js\",\n \"revision\": \"7ffb229fbb962ecfa398ce80c7fe95ec\"\n },\n {\n \"url\": \"assets/initializr.html.8cd24dbb.js\",\n \"revision\": \"9fae5fceda5b5c53750e0b030633977d\"\n },\n {\n \"url\": \"assets/initializr.html.ae05e8c2.js\",\n \"revision\": \"3ca6703ba1f988f61fd0380b02f8d5ef\"\n },\n {\n \"url\": \"assets/inner-class.html.5b071786.js\",\n \"revision\": \"cc39a13e7d9b4ee3a59d309e4c269324\"\n },\n {\n \"url\": \"assets/inner-class.html.f2dd62ed.js\",\n \"revision\": \"9e4441914142103b191b8443b65259f1\"\n },\n {\n \"url\": \"assets/install-baota-mianban.html.4c7a95c4.js\",\n \"revision\": \"1e8a0627c8ad1bc1185742369b5cc5e5\"\n },\n {\n \"url\": \"assets/install-baota-mianban.html.822010d2.js\",\n \"revision\": \"276bbd9dc29a1fc6767713e49d2876c7\"\n },\n {\n \"url\": \"assets/instanceof-jvm.html.845ed78f.js\",\n \"revision\": \"943acb44bce021b556febc8afee2fdb3\"\n },\n {\n \"url\": \"assets/instanceof-jvm.html.c9e8e080.js\",\n \"revision\": \"492b245de203075d06ba29702c4dcde8\"\n },\n {\n \"url\": \"assets/instanceof.html.d3be3510.js\",\n \"revision\": \"516855dcbfebdd16e0becfbb9bd85955\"\n },\n {\n \"url\": \"assets/instanceof.html.d3f5b0d7.js\",\n \"revision\": \"f40cb81679cb844a227588c1d2abd1ec\"\n },\n {\n \"url\": \"assets/int-cache.html.0d30900e.js\",\n \"revision\": \"26b2072adfd383782dd52f78abcee302\"\n },\n {\n \"url\": \"assets/int-cache.html.c609a3a6.js\",\n \"revision\": \"1d50386f4ba5c89b3dcc4344345f369c\"\n },\n {\n \"url\": \"assets/interface.html.60cd9cd7.js\",\n \"revision\": \"129feeb8cd20f8a2ee7927ee5030b3e6\"\n },\n {\n \"url\": \"assets/interface.html.7833e904.js\",\n \"revision\": \"0843bf51c814ca573607ae40640f3ab4\"\n },\n {\n \"url\": \"assets/intern.html.3d87fa6f.js\",\n \"revision\": \"cdb3dcb855cbe196e3c21a87f9bc130b\"\n },\n {\n \"url\": \"assets/intern.html.57f3b131.js\",\n \"revision\": \"95d97f7770ffca894d32dd5b77405777\"\n },\n {\n \"url\": \"assets/ioc.html.00ef348c.js\",\n \"revision\": \"0bb230624d4ab215d0d15e3465944d9c\"\n },\n {\n \"url\": \"assets/ioc.html.1c4cca00.js\",\n \"revision\": \"1a2ed922af9e8cbbed111c0155a3acb5\"\n },\n {\n \"url\": \"assets/iterator-iterable.html.967b5cf7.js\",\n \"revision\": \"f1abd8a084a08c39689395506befb003\"\n },\n {\n \"url\": \"assets/iterator-iterable.html.df321c38.js\",\n \"revision\": \"c78826996742c09ebce9600eba87ef8e\"\n },\n {\n \"url\": \"assets/jackson.html.ded110ad.js\",\n \"revision\": \"b8bb83b89a37fee5fba205945be76cce\"\n },\n {\n \"url\": \"assets/jackson.html.f9f2bbfc.js\",\n \"revision\": \"4c12db7769d491fb044df2ff8aadfa4a\"\n },\n {\n \"url\": \"assets/java-basic-34.html.70be78f8.js\",\n \"revision\": \"237c8c8244c63138dcdf0c90c93ccf04\"\n },\n {\n \"url\": \"assets/java-basic-34.html.ff9af0e4.js\",\n \"revision\": \"8ebd12dc5db9f1ddaba287aaf7dfa26c\"\n },\n {\n \"url\": \"assets/java-basic.html.0b10b00c.js\",\n \"revision\": \"d0844d7170d4f9f021f1919d05751f67\"\n },\n {\n \"url\": \"assets/java-basic.html.52bd7f06.js\",\n \"revision\": \"c3eddf2b32eebe6b50723c9ac936ea4b\"\n },\n {\n \"url\": \"assets/java-mianshi-zhinan.html.e2de50f8.js\",\n \"revision\": \"1c19da2bdac8f0a2c359940566746c4b\"\n },\n {\n \"url\": \"assets/java-mianshi-zhinan.html.f1a349c4.js\",\n \"revision\": \"27ed524714e36e6f747e11622961463d\"\n },\n {\n \"url\": \"assets/java-naming.html.cc154c6b.js\",\n \"revision\": \"79c29d32cef2d6d5683538b29f6f268e\"\n },\n {\n \"url\": \"assets/java-naming.html.de2604a0.js\",\n \"revision\": \"d0f0b1a247ac19647b2a902effa60733\"\n },\n {\n \"url\": \"assets/java-thread.html.4a99fb0e.js\",\n \"revision\": \"7bbbed0ab8e420e38b4c2732b0814144\"\n },\n {\n \"url\": \"assets/java-thread.html.52bdf4b1.js\",\n \"revision\": \"a9d2f36559f90f38438bd8904264894d\"\n },\n {\n \"url\": \"assets/java-unicode.html.17dea1e9.js\",\n \"revision\": \"5e5b7dc64d1742c1b492b612a8947119\"\n },\n {\n \"url\": \"assets/java-unicode.html.9e4e93b1.js\",\n \"revision\": \"bd70784e55f2c80f63364553a992eb8b\"\n },\n {\n \"url\": \"assets/java.html.74ed2cc3.js\",\n \"revision\": \"d863f51d53e69896395d7e36c3cb7ba7\"\n },\n {\n \"url\": \"assets/java.html.c5bee727.js\",\n \"revision\": \"ff92d7c3c6e29c0a85f6a287fd0fd258\"\n },\n {\n \"url\": \"assets/javadoc.html.6c8ace88.js\",\n \"revision\": \"a5f77689301721a6fb08763bad174f8b\"\n },\n {\n \"url\": \"assets/javadoc.html.b34e8efb.js\",\n \"revision\": \"c31af3f9ce5f9fd518305e3fcdb225f0\"\n },\n {\n \"url\": \"assets/javase.html.811355dc.js\",\n \"revision\": \"fef28aa68cd1afd5477935b6b0a650e6\"\n },\n {\n \"url\": \"assets/javase.html.d7cb534c.js\",\n \"revision\": \"7ed30cd3440cc5e1d4b41c946c5e8e59\"\n },\n {\n \"url\": \"assets/javathread.html.1bcda474.js\",\n \"revision\": \"7f4f00e58b30cfc68de124c2100571b9\"\n },\n {\n \"url\": \"assets/javathread.html.7f11e6a6.js\",\n \"revision\": \"2d1ff791098e5ad42b34f76302134e29\"\n },\n {\n \"url\": \"assets/javaxuexidaoshemechengduokeyizhaodiyifengongzuo.html.2958c9b6.js\",\n \"revision\": \"52b7b5020f6834510875813a050532a7\"\n },\n {\n \"url\": \"assets/javaxuexidaoshemechengduokeyizhaodiyifengongzuo.html.3289a228.js\",\n \"revision\": \"12d21d02683e4aa784f8c9e41146d8b5\"\n },\n {\n \"url\": \"assets/jdk-while-for-wuxian-xunhuan.html.a0c2087a.js\",\n \"revision\": \"377ec0011e4500ccabf3598873666f28\"\n },\n {\n \"url\": \"assets/jdk-while-for-wuxian-xunhuan.html.e352d875.js\",\n \"revision\": \"cfbb94a92733eeb5dc75e736e4271136\"\n },\n {\n \"url\": \"assets/jdk9-char-byte-string.html.27d20839.js\",\n \"revision\": \"5426ec47310e95d8a1f844bda6f09f8b\"\n },\n {\n \"url\": \"assets/jdk9-char-byte-string.html.e81be44e.js\",\n \"revision\": \"fc680ffbdb61274f773a8c78c167bfcb\"\n },\n {\n \"url\": \"assets/jiagoushizenyanghuizhijitongjiagoulantu.html.964131a6.js\",\n \"revision\": \"bf1638ec69d69e3b50623bc5ea1c28b0\"\n },\n {\n \"url\": \"assets/jiagoushizenyanghuizhijitongjiagoulantu.html.980a677a.js\",\n \"revision\": \"e16ace455638e83fe29e4f986fdb9ed5\"\n },\n {\n \"url\": \"assets/jianli.html.5f109d9a.js\",\n \"revision\": \"15d97b74970a9ed75460c987d13e424a\"\n },\n {\n \"url\": \"assets/jianli.html.75854f37.js\",\n \"revision\": \"c55ac105b7a9147551065effa9f884ae\"\n },\n {\n \"url\": \"assets/jibenjieshao.html.98a7aaac.js\",\n \"revision\": \"2edfa3b02152b2341c90be667ed88b39\"\n },\n {\n \"url\": \"assets/jibenjieshao.html.b8a08842.js\",\n \"revision\": \"9a038bd09178c6aa49186884410c43ab\"\n },\n {\n \"url\": \"assets/jielehenduosihuodiganchu.html.0ffa8f43.js\",\n \"revision\": \"38131d5037ed9703e9ef9af66411768f\"\n },\n {\n \"url\": \"assets/jielehenduosihuodiganchu.html.fa573110.js\",\n \"revision\": \"a46912b04d963bcf87def1cc85ae2dd0\"\n },\n {\n \"url\": \"assets/jishuzongjianbeikaichuliao.html.1774b950.js\",\n \"revision\": \"be2f9d2b137baf32b040518ed3c3a4dd\"\n },\n {\n \"url\": \"assets/jishuzongjianbeikaichuliao.html.1b7e52c1.js\",\n \"revision\": \"16fba1920863afdcfe7142774cbd4425\"\n },\n {\n \"url\": \"assets/jit.html.4cb31299.js\",\n \"revision\": \"50f3aa2acbeee2542688d22c6a68089e\"\n },\n {\n \"url\": \"assets/jit.html.a14bdfce.js\",\n \"revision\": \"f6d96dbfd5dcf11323c34d5dcc7335fc\"\n },\n {\n \"url\": \"assets/jmm.html.6df91381.js\",\n \"revision\": \"77c3ec49a53eac6df33c65cc8a550aa3\"\n },\n {\n \"url\": \"assets/jmm.html.7be72db5.js\",\n \"revision\": \"f110edd5e2f6a34351d4711a3df6e513\"\n },\n {\n \"url\": \"assets/join.html.18a0e9f8.js\",\n \"revision\": \"f063cb40dc0cbe22866c48e5f21bd92f\"\n },\n {\n \"url\": \"assets/join.html.bb336f49.js\",\n \"revision\": \"42a931af30f514619d1a1efb40c96591\"\n },\n {\n \"url\": \"assets/jpa.html.8adce5f1.js\",\n \"revision\": \"5fcdd83233758ff2afb30ad920f7c45b\"\n },\n {\n \"url\": \"assets/jpa.html.c4109873.js\",\n \"revision\": \"6cf15565023a47313a765b64a89cb28d\"\n },\n {\n \"url\": \"assets/junit.html.2436284c.js\",\n \"revision\": \"f3af71d5609908b52eef886f9e995418\"\n },\n {\n \"url\": \"assets/junit.html.a79d9c04.js\",\n \"revision\": \"32794839b36ccd19cf04903dfaf361a1\"\n },\n {\n \"url\": \"assets/jvm.html.1b4e3107.js\",\n \"revision\": \"8f36d3c8758d9fedb2dcea99714dadcd\"\n },\n {\n \"url\": \"assets/jvm.html.49208e4a.js\",\n \"revision\": \"ae588fea19815644b1c028a676055a4b\"\n },\n {\n \"url\": \"assets/jvm.html.86668e04.js\",\n \"revision\": \"1f8b93137c686aa03c7e2c2a6a239f41\"\n },\n {\n \"url\": \"assets/jvm.html.d7d28727.js\",\n \"revision\": \"f251769784a32de9498129fd3ca571a4\"\n },\n {\n \"url\": \"assets/jvm.html.dd68f45e.js\",\n \"revision\": \"5a942829e5fa038171516b43c4953270\"\n },\n {\n \"url\": \"assets/jvm.html.e2246150.js\",\n \"revision\": \"15d92e60efac774585f4869d3e5bb427\"\n },\n {\n \"url\": \"assets/jwt.html.b4f208bb.js\",\n \"revision\": \"ccd1e1cf1ba2d50e4abd7ee39cd0ae5f\"\n },\n {\n \"url\": \"assets/jwt.html.e910af0e.js\",\n \"revision\": \"a3780a9458370ad9b482537d1523cded\"\n },\n {\n \"url\": \"assets/knife4j.html.44253ad0.js\",\n \"revision\": \"385a5caa23eda5eff1ace58f296a2a3e\"\n },\n {\n \"url\": \"assets/knife4j.html.fe2f8e7d.js\",\n \"revision\": \"c0ac4a924dda5665b7417f7a2a6401bc\"\n },\n {\n \"url\": \"assets/Lambda.html.16e88b8a.js\",\n \"revision\": \"2baff2891bd9c1c3990a0313478465fb\"\n },\n {\n \"url\": \"assets/Lambda.html.997b367a.js\",\n \"revision\": \"52eb395fd4e37f0de01811421653e900\"\n },\n {\n \"url\": \"assets/lanqiaobei.html.17699093.js\",\n \"revision\": \"5d54156cabbd398cd05a10f3531bb1f1\"\n },\n {\n \"url\": \"assets/lanqiaobei.html.489bde40.js\",\n \"revision\": \"a4d7068d010bc0535408397d8058b7d4\"\n },\n {\n \"url\": \"assets/Layout.fbcb8daf.js\",\n \"revision\": \"57a7b7742bad3b26bc61ff85610fca1d\"\n },\n {\n \"url\": \"assets/learn-jianyi.html.1b72d4e2.js\",\n \"revision\": \"7d563c363a3d4debd307277bf1a00e67\"\n },\n {\n \"url\": \"assets/learn-jianyi.html.453bb02b.js\",\n \"revision\": \"6595bb01076909c24eb0c8fe6dc47111\"\n },\n {\n \"url\": \"assets/linkedlist.html.4b75cd4d.js\",\n \"revision\": \"6090cbb008975cdb58a40f0fa0be1d54\"\n },\n {\n \"url\": \"assets/linkedlist.html.8ede144e.js\",\n \"revision\": \"e2adcd892b90191c375cf979328cb124\"\n },\n {\n \"url\": \"assets/list-war-2.html.96808d02.js\",\n \"revision\": \"3b86913919e7dcefe3e3ed56acf603bc\"\n },\n {\n \"url\": \"assets/list-war-2.html.b8fa44fb.js\",\n \"revision\": \"cf2ab3c2e799ec10f657d9e2f4dfb65a\"\n },\n {\n \"url\": \"assets/lock.html.5385ecc8.js\",\n \"revision\": \"894e93c8012594ae038f4cd857ff50af\"\n },\n {\n \"url\": \"assets/lock.html.a13afff5.js\",\n \"revision\": \"4e14aba7725bc02a1d30bac119afc09e\"\n },\n {\n \"url\": \"assets/LockSupport.html.55f27ea8.js\",\n \"revision\": \"4509c39f21dc1b7794fa184580b902fa\"\n },\n {\n \"url\": \"assets/LockSupport.html.c7d00cfa.js\",\n \"revision\": \"86fdd35f48637ac9a5971fb6e44211d5\"\n },\n {\n \"url\": \"assets/log4j.html.14af993a.js\",\n \"revision\": \"fa18ccbd6f734f1b12871ec7f9101f6f\"\n },\n {\n \"url\": \"assets/log4j.html.dbbf9c72.js\",\n \"revision\": \"67e430c30df558f23615642855b86b4b\"\n },\n {\n \"url\": \"assets/log4j2.html.17000ac4.js\",\n \"revision\": \"90e9aafd35dcfe703a98405ea81e76fb\"\n },\n {\n \"url\": \"assets/log4j2.html.9b5a6f13.js\",\n \"revision\": \"74f7162c5d876ef41a09955483435f9e\"\n },\n {\n \"url\": \"assets/log4j2.html.b3fd06a7.js\",\n \"revision\": \"88ff3344444cc2680ddf3e4964c09932\"\n },\n {\n \"url\": \"assets/log4j2.html.f846d981.js\",\n \"revision\": \"315c6425ff5e422ac48ce864e480c556\"\n },\n {\n \"url\": \"assets/logback.html.65200f68.js\",\n \"revision\": \"99ff0e11926dffeb463547098f575415\"\n },\n {\n \"url\": \"assets/logback.html.869073f6.js\",\n \"revision\": \"d5223d64f50889bdc9d50d965e70ee25\"\n },\n {\n \"url\": \"assets/logback.html.a9628274.js\",\n \"revision\": \"5f741c93179b5d8653029776f2026245\"\n },\n {\n \"url\": \"assets/logback.html.bd3bc959.js\",\n \"revision\": \"e0c83478a6edc7cfb4c9293828805a67\"\n },\n {\n \"url\": \"assets/macos-codingmore-run.html.984613a6.js\",\n \"revision\": \"432697905076a8fbb164a4c562d60153\"\n },\n {\n \"url\": \"assets/macos-codingmore-run.html.f9eb5e90.js\",\n \"revision\": \"65ac7cb80f7fc73e7c725acffb01d60a\"\n },\n {\n \"url\": \"assets/map.html.61b4c4d9.js\",\n \"revision\": \"ee7b54575d224a18084ced9daef43bef\"\n },\n {\n \"url\": \"assets/map.html.ae80f8e6.js\",\n \"revision\": \"4caefbc89b1e006c195441565f03be8c\"\n },\n {\n \"url\": \"assets/markdown.esm.832a189d.js\",\n \"revision\": \"4aa467006f9d51cf40293b9b69a0f27a\"\n },\n {\n \"url\": \"assets/math.esm.a3f84b6f.js\",\n \"revision\": \"cbf844f27edbc061c86ae840d70389f6\"\n },\n {\n \"url\": \"assets/maven.html.9abc8500.js\",\n \"revision\": \"130269025dfd59613d1fff9792147291\"\n },\n {\n \"url\": \"assets/maven.html.abe414c5.js\",\n \"revision\": \"076fa6654bcdb82ab1f5d1713ee11a4e\"\n },\n {\n \"url\": \"assets/meituan-9-gc.html.26985c28.js\",\n \"revision\": \"4a5771024009b0a739e52737ae65e694\"\n },\n {\n \"url\": \"assets/meituan-9-gc.html.f5a5b89a.js\",\n \"revision\": \"244a3f55b6939ca3553511b02032c9dd\"\n },\n {\n \"url\": \"assets/method.html.4d951864.js\",\n \"revision\": \"561b699c5536ab7660ef94c27166a830\"\n },\n {\n \"url\": \"assets/method.html.67a1e169.js\",\n \"revision\": \"81adfc29a24683c32d90cc8794268020\"\n },\n {\n \"url\": \"assets/mybatis.html.7c33d756.js\",\n \"revision\": \"64a1c8c0d21437565c6f4ed7e5b6adff\"\n },\n {\n \"url\": \"assets/mybatis.html.a18a9ce2.js\",\n \"revision\": \"35392edbf862d52bb9cc537e3051fd6d\"\n },\n {\n \"url\": \"assets/mysql-druid.html.adb4afdf.js\",\n \"revision\": \"49b00ed5b34555978e93954f0b80284c\"\n },\n {\n \"url\": \"assets/mysql-druid.html.bf232591.js\",\n \"revision\": \"08d563c142cd060746812f72c1e847ac\"\n },\n {\n \"url\": \"assets/mysql.html.99fca397.js\",\n \"revision\": \"f74dbe6f78163ad33b0c9a819ebfc3ca\"\n },\n {\n \"url\": \"assets/mysql.html.ecb0e241.js\",\n \"revision\": \"b37542a34de8a33a5ab7d015f9642c30\"\n },\n {\n \"url\": \"assets/nanjing.html.0381e4b6.js\",\n \"revision\": \"f82603d61971f03e213bec489f7483b8\"\n },\n {\n \"url\": \"assets/nanjing.html.df603525.js\",\n \"revision\": \"4dc3142c0b3fb0716fecb72338e2e04c\"\n },\n {\n \"url\": \"assets/neicun-jiegou.html.e6842a53.js\",\n \"revision\": \"0e8cd7e0860ae65966f8f9f9e7d8860b\"\n },\n {\n \"url\": \"assets/neicun-jiegou.html.f0fca3bb.js\",\n \"revision\": \"6daf0b5605744cbaf3254818812ac171\"\n },\n {\n \"url\": \"assets/nginx.html.30b3f8bd.js\",\n \"revision\": \"e56a026b92bb238559dfb22897ba34d4\"\n },\n {\n \"url\": \"assets/nginx.html.baa53af7.js\",\n \"revision\": \"cac80db53f25790ef648e13b4e453d30\"\n },\n {\n \"url\": \"assets/nicearticle.html.aa656631.js\",\n \"revision\": \"c208a0b05c0ce03a2204e5247614f16b\"\n },\n {\n \"url\": \"assets/nicearticle.html.b56e678a.js\",\n \"revision\": \"e7e94ff20e83310751fc0c814a6b1e7c\"\n },\n {\n \"url\": \"assets/nixi.html.8b48857f.js\",\n \"revision\": \"b1837463dfbce0768edd5bc0c3d8aa2b\"\n },\n {\n \"url\": \"assets/nixi.html.c022f9fe.js\",\n \"revision\": \"045fae1de49d81b344c5fb968595c21b\"\n },\n {\n \"url\": \"assets/notes.esm.3c361cb7.js\",\n \"revision\": \"eda65c99450fe02da90bde90cc614a56\"\n },\n {\n \"url\": \"assets/npe.html.01d29f9c.js\",\n \"revision\": \"8134ca774480ebc279a182e672a77470\"\n },\n {\n \"url\": \"assets/npe.html.a94a2b73.js\",\n \"revision\": \"66e85fa3c9bd617e71aef72c2fc50721\"\n },\n {\n \"url\": \"assets/object-class.html.85420110.js\",\n \"revision\": \"bc2a562c613c3bb7f2f64d53055c00b4\"\n },\n {\n \"url\": \"assets/object-class.html.96fd3d4e.js\",\n \"revision\": \"7c0d8c62872d08455d76420035ad64d0\"\n },\n {\n \"url\": \"assets/oom.html.23228526.js\",\n \"revision\": \"0ac9680baff3b41388b27b97b55c779a\"\n },\n {\n \"url\": \"assets/oom.html.d0512b48.js\",\n \"revision\": \"93efae323573b93b0f9515ce535c48e2\"\n },\n {\n \"url\": \"assets/operator.html.783e87f0.js\",\n \"revision\": \"067632a95ff14350a9c0dbaa8043a081\"\n },\n {\n \"url\": \"assets/operator.html.9431d9fc.js\",\n \"revision\": \"dd2606884797f6115086577981cdf630\"\n },\n {\n \"url\": \"assets/optional.html.23c0a140.js\",\n \"revision\": \"841574f000bebb802ad9b5fb7622fb98\"\n },\n {\n \"url\": \"assets/optional.html.d38ec385.js\",\n \"revision\": \"f005ae616fadd25c6a691cce822177a2\"\n },\n {\n \"url\": \"assets/os.html.2d6bc714.js\",\n \"revision\": \"f5854cb64198e2a1343936759eaabefb\"\n },\n {\n \"url\": \"assets/os.html.34768944.js\",\n \"revision\": \"2a3c72e94e5fea9ccc7c3521fd120a18\"\n },\n {\n \"url\": \"assets/os.html.5e6a959a.js\",\n \"revision\": \"0d3240c88a18a8d4ba5ab1f0deb2ed9f\"\n },\n {\n \"url\": \"assets/os.html.e10e307f.js\",\n \"revision\": \"909af4697ba5591c1f135378ed615ec3\"\n },\n {\n \"url\": \"assets/oss.html.977b34d5.js\",\n \"revision\": \"0d465fc3df511397ec1edf06998aee67\"\n },\n {\n \"url\": \"assets/oss.html.b690f015.js\",\n \"revision\": \"b7a47348483781616244a67c37f83f98\"\n },\n {\n \"url\": \"assets/others.html.214194b1.js\",\n \"revision\": \"8d7ba5f70bee9e9a63930a914433a630\"\n },\n {\n \"url\": \"assets/others.html.ed8fcf05.js\",\n \"revision\": \"e6fd1a8c5da4b15d4670159a24ef9506\"\n },\n {\n \"url\": \"assets/override-overload.html.853755f9.js\",\n \"revision\": \"d45c9a74558064478148d168cd9079ff\"\n },\n {\n \"url\": \"assets/override-overload.html.f7d74176.js\",\n \"revision\": \"3ee9ca1d6b6aefe5fb57084f0cc15e15\"\n },\n {\n \"url\": \"assets/Overriding.html.14f830f8.js\",\n \"revision\": \"782d5974e1b4f6d2acc30324bd737ad1\"\n },\n {\n \"url\": \"assets/Overriding.html.e0ccdfe1.js\",\n \"revision\": \"0b6076e487741b3805b15c5b98911313\"\n },\n {\n \"url\": \"assets/pass-by-value.html.c65b64be.js\",\n \"revision\": \"7d694685a0fc4be50eb207ca1ffded4a\"\n },\n {\n \"url\": \"assets/pass-by-value.html.e26c3cdc.js\",\n \"revision\": \"3010545820acbe8927e256f4ae13fecd\"\n },\n {\n \"url\": \"assets/pdf.html.0610fb03.js\",\n \"revision\": \"b565bdf33dc4037ef563d75eae673328\"\n },\n {\n \"url\": \"assets/pdf.html.a28195f1.js\",\n \"revision\": \"2878368c7793e0fab9367fd05c73e020\"\n },\n {\n \"url\": \"assets/photoswipe.esm.92018b73.js\",\n \"revision\": \"442a3264b1db7eb84ffc880407e7565d\"\n },\n {\n \"url\": \"assets/plugin-vue_export-helper.21dcd24c.js\",\n \"revision\": \"b29b145139fc88e89a46af507277557d\"\n },\n {\n \"url\": \"assets/pool.html.1918e02b.js\",\n \"revision\": \"837fd39732d9eb3df1e143bd77b9e1cb\"\n },\n {\n \"url\": \"assets/pool.html.79813894.js\",\n \"revision\": \"bc2c2fe355c3cf059f48487593389bd5\"\n },\n {\n \"url\": \"assets/print.html.6fe8360d.js\",\n \"revision\": \"7a5cd0b01b2c354dccd58c55ccc7af88\"\n },\n {\n \"url\": \"assets/print.html.f0b4f56c.js\",\n \"revision\": \"76117f8b201814952dd41406c9dcd329\"\n },\n {\n \"url\": \"assets/problem-tools.html.c2bda786.js\",\n \"revision\": \"bed221d11bfdeb435b34f98d164eb40d\"\n },\n {\n \"url\": \"assets/problem-tools.html.fab08888.js\",\n \"revision\": \"8abd2eb80f2525872d9d8f8d2480a0d2\"\n },\n {\n \"url\": \"assets/progit.html.3b6ba984.js\",\n \"revision\": \"022afdb6ab50022afca061f3ddca45bd\"\n },\n {\n \"url\": \"assets/progit.html.66c47307.js\",\n \"revision\": \"6ba948e6b6bc2ecd1d41a55150294f11\"\n },\n {\n \"url\": \"assets/progit.html.a119468c.js\",\n \"revision\": \"ff8fc203f93f6c67a16915eb0c9b6659\"\n },\n {\n \"url\": \"assets/progit.html.de3011f5.js\",\n \"revision\": \"46f03fd0dac1d5629b10a3960488eead\"\n },\n {\n \"url\": \"assets/python.html.a467fb74.js\",\n \"revision\": \"73ccde0eecc64ad7696411f289412dce\"\n },\n {\n \"url\": \"assets/python.html.e5ae48ee.js\",\n \"revision\": \"9b8d3fc3b99b58da0837193ad81b5fd2\"\n },\n {\n \"url\": \"assets/qianduan.html.60a6bdee.js\",\n \"revision\": \"35978d85c765d5d8cd1639200f5caecd\"\n },\n {\n \"url\": \"assets/qianduan.html.61a4f111.js\",\n \"revision\": \"80491ad5e938d271d8cd2be59f02e2fb\"\n },\n {\n \"url\": \"assets/qingdao.html.026cf757.js\",\n \"revision\": \"9c22c7aebf13970e1de6b7c414f98913\"\n },\n {\n \"url\": \"assets/qingdao.html.08ca70e9.js\",\n \"revision\": \"bb859290ac3fc12eba26e75fe8f5b802\"\n },\n {\n \"url\": \"assets/rabbitmq-rumen.html.1f0066c6.js\",\n \"revision\": \"67e3b3b57c9a055c1f7ddd6a077fd788\"\n },\n {\n \"url\": \"assets/rabbitmq-rumen.html.719aebed.js\",\n \"revision\": \"c46e205bc4c973750050da2f087881cf\"\n },\n {\n \"url\": \"assets/read-csapp.html.23c82cf4.js\",\n \"revision\": \"a7fd47941c0303f526d229d22bc5bebe\"\n },\n {\n \"url\": \"assets/read-csapp.html.f8f796e3.js\",\n \"revision\": \"e9e918d773fb5536fe0513b71db19461\"\n },\n {\n \"url\": \"assets/record-domain.html.19eb33ac.js\",\n \"revision\": \"ae3885dae0dfab43a95aec90eb42ad05\"\n },\n {\n \"url\": \"assets/record-domain.html.9b78d780.js\",\n \"revision\": \"25073fcf5de280aa941a16587e155c35\"\n },\n {\n \"url\": \"assets/redis-shuju-yizhixing.html.0d2d7824.js\",\n \"revision\": \"af7f27a164f234c07500ae1210fe53bf\"\n },\n {\n \"url\": \"assets/redis-shuju-yizhixing.html.7e461ea4.js\",\n \"revision\": \"10ef9457c692f9195709abcc5a8b7ab2\"\n },\n {\n \"url\": \"assets/redis-springboot.html.5e59844d.js\",\n \"revision\": \"dea925fe16de704907dcabf395abd223\"\n },\n {\n \"url\": \"assets/redis-springboot.html.7783ee99.js\",\n \"revision\": \"e922581e78ef66064910118caf756706\"\n },\n {\n \"url\": \"assets/redis.html.7543ed9c.js\",\n \"revision\": \"7cef164fb0c3fff043d1779afd9b10ff\"\n },\n {\n \"url\": \"assets/redis.html.b039ba47.js\",\n \"revision\": \"250ee45056172fee92c332e9bb8f2fdf\"\n },\n {\n \"url\": \"assets/redis12question.html.58f0e7e0.js\",\n \"revision\": \"1ca878de7522dd7bd5f7d4780449386b\"\n },\n {\n \"url\": \"assets/redis12question.html.bab032b9.js\",\n \"revision\": \"28a1a6ef3eb9871a2b25b6e778f76c62\"\n },\n {\n \"url\": \"assets/reentrantLock.html.002f84e4.js\",\n \"revision\": \"475486341b8257def0a182f7945de2b6\"\n },\n {\n \"url\": \"assets/reentrantLock.html.d3a77dd6.js\",\n \"revision\": \"dc734975ea206c4e54f66084b0fbaf18\"\n },\n {\n \"url\": \"assets/ReentrantReadWriteLock.html.b8dcb20a.js\",\n \"revision\": \"90326681a60b10eddd78a6858f1d801c\"\n },\n {\n \"url\": \"assets/ReentrantReadWriteLock.html.d1bd972f.js\",\n \"revision\": \"95da940d4221ddc04eec2e3b5ae8996f\"\n },\n {\n \"url\": \"assets/reveal.esm.b96f05d8.js\",\n \"revision\": \"f78a424fad98faac5d5ca8ebfbebe94b\"\n },\n {\n \"url\": \"assets/rumen.html.28382740.js\",\n \"revision\": \"bbb73cc8ff60526c113c7b1d16cc8eaf\"\n },\n {\n \"url\": \"assets/rumen.html.4002e397.js\",\n \"revision\": \"bde6352cc806daae21f11801b204396a\"\n },\n {\n \"url\": \"assets/rumen.html.439110fe.js\",\n \"revision\": \"f9d14e2ffb8e54b030f7d1c3067c183f\"\n },\n {\n \"url\": \"assets/rumen.html.9cc17590.js\",\n \"revision\": \"d296a715b51d7987e19356f118decea2\"\n },\n {\n \"url\": \"assets/rumen.html.e13dbda5.js\",\n \"revision\": \"9f529477271a37fdf0fbaec594e6d279\"\n },\n {\n \"url\": \"assets/rumen.html.f241efd5.js\",\n \"revision\": \"1fe77771f6461d4ae08440f61b884db6\"\n },\n {\n \"url\": \"assets/ScheduledThreadPoolExecutor.html.8d668046.js\",\n \"revision\": \"b29b0a101162737afa347106c650739f\"\n },\n {\n \"url\": \"assets/ScheduledThreadPoolExecutor.html.e216d19d.js\",\n \"revision\": \"d7cac3e2bd93d4a33022269f57ea1c61\"\n },\n {\n \"url\": \"assets/search.esm.80da4a02.js\",\n \"revision\": \"690b84c66badd2f8fa69d57bc7cdad19\"\n },\n {\n \"url\": \"assets/shanganaliyun.html.04eee07a.js\",\n \"revision\": \"f74774689b9aa40eb6a262a3cc4e9ae6\"\n },\n {\n \"url\": \"assets/shanganaliyun.html.fc60e761.js\",\n \"revision\": \"7a547e4cebb9442d2d55264730cb69b4\"\n },\n {\n \"url\": \"assets/shangtou.html.dd79a90f.js\",\n \"revision\": \"e491b924cd35190389b7819a21f19b1c\"\n },\n {\n \"url\": \"assets/shangtou.html.fc7b3e84.js\",\n \"revision\": \"99ebcada07953a03647797ca8ac78d6d\"\n },\n {\n \"url\": \"assets/shengchanzhe-xiaofeizhe.html.0915b865.js\",\n \"revision\": \"ee8bb756f0323bf506becbb4280e574f\"\n },\n {\n \"url\": \"assets/shengchanzhe-xiaofeizhe.html.920a9bd9.js\",\n \"revision\": \"66646c5a3419d9abf637bd65e65f42b6\"\n },\n {\n \"url\": \"assets/shenzhen.html.037e48a5.js\",\n \"revision\": \"0b7bf5142143caa172281b8e0ad836e0\"\n },\n {\n \"url\": \"assets/shenzhen.html.48307e94.js\",\n \"revision\": \"08f6a9737e76ef1fb3fabc1d5d079a9e\"\n },\n {\n \"url\": \"assets/shijian.html.0924a1ec.js\",\n \"revision\": \"326c95b32e23cf74836881972d518432\"\n },\n {\n \"url\": \"assets/shijian.html.84eb0eab.js\",\n \"revision\": \"4dbc437b451a39b90d4a74a0bdc97b98\"\n },\n {\n \"url\": \"assets/SkipLink.e761490e.js\",\n \"revision\": \"54521e1d60b624f654367c68da84b3de\"\n },\n {\n \"url\": \"assets/slf4j.html.2fd3dca6.js\",\n \"revision\": \"c2fc64d88ebde1e5685aabe77a9ac3c1\"\n },\n {\n \"url\": \"assets/slf4j.html.a17cdf5a.js\",\n \"revision\": \"bae89fe3c0cb150a3fb11eae01652b58\"\n },\n {\n \"url\": \"assets/Slide.a2a8944b.js\",\n \"revision\": \"cd582e08e9af7c3d7fc6abe34adf3aaf\"\n },\n {\n \"url\": \"assets/split.html.0ff2ce60.js\",\n \"revision\": \"782e517f1be73a462dbb3572b55d8b68\"\n },\n {\n \"url\": \"assets/split.html.dbaed6aa.js\",\n \"revision\": \"89085a9e4a896659a73fa7fe1cbc4a22\"\n },\n {\n \"url\": \"assets/spring.html.26f406c7.js\",\n \"revision\": \"758c9ad3fcab916d834f646a448d0338\"\n },\n {\n \"url\": \"assets/spring.html.75b19ea2.js\",\n \"revision\": \"ce83e6c73d54a4eb2d2be0d6b78add4d\"\n },\n {\n \"url\": \"assets/springtask.html.0afe6499.js\",\n \"revision\": \"a171cf83881da1c96a2393ede86661e6\"\n },\n {\n \"url\": \"assets/springtask.html.406633ab.js\",\n \"revision\": \"2c8469c8fef9182a9019ffeab34e427e\"\n },\n {\n \"url\": \"assets/static.html.1a009c06.js\",\n \"revision\": \"3d3bdf938d69191f52064821d34cda66\"\n },\n {\n \"url\": \"assets/static.html.8ee519bc.js\",\n \"revision\": \"67e5eaf877e1d15b4e0f59a90601207e\"\n },\n {\n \"url\": \"assets/stream.html.214aab27.js\",\n \"revision\": \"02b20169ec8176d859a10ee4b41683b8\"\n },\n {\n \"url\": \"assets/stream.html.db791f6b.js\",\n \"revision\": \"8fee3aa06ed24c86079dc71ef48deabb\"\n },\n {\n \"url\": \"assets/style.aa7884a9.css\",\n \"revision\": \"b50231da484889a39c0d651cca018162\"\n },\n {\n \"url\": \"assets/suzhou.html.1f658a4a.js\",\n \"revision\": \"846af1d45e4efd0c3660b7c5e1173317\"\n },\n {\n \"url\": \"assets/suzhou.html.e601b996.js\",\n \"revision\": \"3f034c9d682616a27c5ef859ea60bb66\"\n },\n {\n \"url\": \"assets/swagger.html.03ed15b7.js\",\n \"revision\": \"7d4ae48935211839162f9171080c9388\"\n },\n {\n \"url\": \"assets/swagger.html.d41c975f.js\",\n \"revision\": \"a61c6105c7f8b9bb9bdea8633a103010\"\n },\n {\n \"url\": \"assets/synchronized.html.2e0681cb.js\",\n \"revision\": \"7b7fbb1e7c45aa1baed8b65e0f3ddeb4\"\n },\n {\n \"url\": \"assets/synchronized.html.6094d556.js\",\n \"revision\": \"50bb92e6064fb1eeace2b8badcce12ec\"\n },\n {\n \"url\": \"assets/tabby.html.5c93d604.js\",\n \"revision\": \"8bd45d10a90dce8fbd27dea748fb8f4e\"\n },\n {\n \"url\": \"assets/tabby.html.8b43d084.js\",\n \"revision\": \"fede60fdff4466bc0faa5a7c3f40a97e\"\n },\n {\n \"url\": \"assets/this-super.html.5e8e4dee.js\",\n \"revision\": \"6959318dceb1280c4921ad145cb6e999\"\n },\n {\n \"url\": \"assets/this-super.html.65fa5da3.js\",\n \"revision\": \"db3b96963f5594951739fe2924632a42\"\n },\n {\n \"url\": \"assets/thread-bring-some-problem.html.b2f11eb4.js\",\n \"revision\": \"00349bd3d5d9eab7436c7f71a6265f21\"\n },\n {\n \"url\": \"assets/thread-bring-some-problem.html.c8ae3e7a.js\",\n \"revision\": \"d30408042adbdeca4ce50a59c6901032\"\n },\n {\n \"url\": \"assets/thread-group-and-thread-priority.html.041c72b9.js\",\n \"revision\": \"a580897167d73be0081440f27ebb6953\"\n },\n {\n \"url\": \"assets/thread-group-and-thread-priority.html.873709ce.js\",\n \"revision\": \"4e54397c857c1341cd41f1cfff69ebb1\"\n },\n {\n \"url\": \"assets/thread-state-and-method.html.70b8e2e8.js\",\n \"revision\": \"99fbdee5498a36cf4161dea3e2aebd57\"\n },\n {\n \"url\": \"assets/thread-state-and-method.html.a628789d.js\",\n \"revision\": \"38caa39040618ad8817192498aba1490\"\n },\n {\n \"url\": \"assets/thread.html.34ab4613.js\",\n \"revision\": \"1ed2cba245361944bd4249f6f3efe4fd\"\n },\n {\n \"url\": \"assets/thread.html.a2ddbdf4.js\",\n \"revision\": \"e26707f39be07566aa9dd5ed981203fc\"\n },\n {\n \"url\": \"assets/ThreadLocal.html.284cf60c.js\",\n \"revision\": \"db18156b7915ff973693738f5cdca36e\"\n },\n {\n \"url\": \"assets/ThreadLocal.html.f9a6fed8.js\",\n \"revision\": \"e5f398cec6e9663ba5b58fe6a2a1ba63\"\n },\n {\n \"url\": \"assets/thymeleaf.html.1a24ed99.js\",\n \"revision\": \"82ebee28f65a7bb4d977a64f989cb51d\"\n },\n {\n \"url\": \"assets/thymeleaf.html.be244969.js\",\n \"revision\": \"16117c12383d9c9563d228a33b1f87c0\"\n },\n {\n \"url\": \"assets/tobebetterjavaer-wangzhan-shangxian.html.88c8d82b.js\",\n \"revision\": \"3f845205eb517c8545f12eb97dc2c6e6\"\n },\n {\n \"url\": \"assets/tobebetterjavaer-wangzhan-shangxian.html.a80895d2.js\",\n \"revision\": \"1023c6d0dadb6420952b89fd749a6adc\"\n },\n {\n \"url\": \"assets/tomcat.html.3d86b543.js\",\n \"revision\": \"1f99f1e50589817b662b845d4400fb7e\"\n },\n {\n \"url\": \"assets/tomcat.html.73ec3645.js\",\n \"revision\": \"7a7b107c1633a13d2190549cb6e03310\"\n },\n {\n \"url\": \"assets/transaction.html.89e3579f.js\",\n \"revision\": \"4ad31c0173126490d2c7fb5240de5189\"\n },\n {\n \"url\": \"assets/transaction.html.c6ea47a0.js\",\n \"revision\": \"42993d04a7f1aaf48e535999dea1ae9a\"\n },\n {\n \"url\": \"assets/true-generic.html.ce09d792.js\",\n \"revision\": \"7b33c1c5dbde75dd4deedd61ff4ffbb0\"\n },\n {\n \"url\": \"assets/true-generic.html.dbcaca38.js\",\n \"revision\": \"5387bcf38d38f6f8241d942780beaab0\"\n },\n {\n \"url\": \"assets/try-with-resouces.html.8dcef913.js\",\n \"revision\": \"7803c62919343844326660cb01e85fd9\"\n },\n {\n \"url\": \"assets/try-with-resouces.html.c242816c.js\",\n \"revision\": \"728d91bf8ced750a35cdc7b9574451aa\"\n },\n {\n \"url\": \"assets/tujie-gc.html.70c281f0.js\",\n \"revision\": \"ce356633834f92c1cd1da052ae68744b\"\n },\n {\n \"url\": \"assets/tujie-gc.html.ca2dffab.js\",\n \"revision\": \"a7928789b0d96cef153aaf643807441e\"\n },\n {\n \"url\": \"assets/tupian-zhuanlian.html.7ab13c07.js\",\n \"revision\": \"11bbf9bb17b695c73038945d2d3ff5e3\"\n },\n {\n \"url\": \"assets/tupian-zhuanlian.html.7e57c89c.js\",\n \"revision\": \"7e1674d2805cf5ee44fe8ba3c61ff9ae\"\n },\n {\n \"url\": \"assets/var.html.7a0cfd0f.js\",\n \"revision\": \"44e56a632667ab8dc6fda19d2e951b8a\"\n },\n {\n \"url\": \"assets/var.html.d8139bc5.js\",\n \"revision\": \"ed904714ae226b2decffa24f2eacbe5d\"\n },\n {\n \"url\": \"assets/varables.html.4e32dd4f.js\",\n \"revision\": \"6bed702dc516532db5a9dc96b36cb612\"\n },\n {\n \"url\": \"assets/varables.html.6a80fc0e.js\",\n \"revision\": \"b5d838edc69034b99358140c53b3dacb\"\n },\n {\n \"url\": \"assets/volatile.html.26279f7f.js\",\n \"revision\": \"8b7c26f79da9fab23d11327674fb4d5e\"\n },\n {\n \"url\": \"assets/volatile.html.e6448db8.js\",\n \"revision\": \"390f312d9aff6c5ee73f4923775645f4\"\n },\n {\n \"url\": \"assets/waibao-1geyue.html.1edb2375.js\",\n \"revision\": \"62cfe898d4bd30af9a99ab2227e16707\"\n },\n {\n \"url\": \"assets/waibao-1geyue.html.fbddc89c.js\",\n \"revision\": \"e015d6b16e709b6ccb97dce4163bb984\"\n },\n {\n \"url\": \"assets/wangluo.html.b41cb57f.js\",\n \"revision\": \"57732b795849149a6667300feb6a38da\"\n },\n {\n \"url\": \"assets/wangluo.html.bd9e0045.js\",\n \"revision\": \"cc49e89fa88e4a25617ed12742bf7e35\"\n },\n {\n \"url\": \"assets/wangzhe-thread.html.6222c220.js\",\n \"revision\": \"1d9c4b8cf884c8ae50113e0f2266de1f\"\n },\n {\n \"url\": \"assets/wangzhe-thread.html.dda72253.js\",\n \"revision\": \"a93511501818791c302deaac765b4e15\"\n },\n {\n \"url\": \"assets/warp.html.4380b228.js\",\n \"revision\": \"1c7cd7539426cb69c99eefa6ad943b27\"\n },\n {\n \"url\": \"assets/warp.html.f8427955.js\",\n \"revision\": \"a8147515ec33c33e597146b09fde6819\"\n },\n {\n \"url\": \"assets/weixin-chengxwjdwzhqcgxm.html.18dc866d.js\",\n \"revision\": \"b566da699481353a4ad2423995f7d8eb\"\n },\n {\n \"url\": \"assets/weixin-chengxwjdwzhqcgxm.html.63b423d3.js\",\n \"revision\": \"08f08725340b7914634d931e9565eee1\"\n },\n {\n \"url\": \"assets/weixin-liaoliaoxianliu.html.3a09df17.js\",\n \"revision\": \"dae2d4600f6c3291f9a9b226fbb2ed94\"\n },\n {\n \"url\": \"assets/weixin-liaoliaoxianliu.html.624e17ae.js\",\n \"revision\": \"6f5c07a29b2398416dfc5164c9f08d11\"\n },\n {\n \"url\": \"assets/weixin-xinllgjszjszzpojozsyjbsjlxyhjfyll.html.5d76cb3c.js\",\n \"revision\": \"d6d2c77b978c31bbdf8dc4844d8904e2\"\n },\n {\n \"url\": \"assets/weixin-xinllgjszjszzpojozsyjbsjlxyhjfyll.html.8f640dc9.js\",\n \"revision\": \"873bcfb3534b542706c75db73ec1afeb\"\n },\n {\n \"url\": \"assets/weixin-zhongxcwbztashjjavahdmj.html.844aa3a1.js\",\n \"revision\": \"7003350e84221429c44952436b05dd9a\"\n },\n {\n \"url\": \"assets/weixin-zhongxcwbztashjjavahdmj.html.c99fcea1.js\",\n \"revision\": \"a052baeca51a1b5135bcbeabb668c02b\"\n },\n {\n \"url\": \"assets/weixin-zuixinbujiabandigongsimingdan.html.4000ddf4.js\",\n \"revision\": \"9eed8a4a102a4cc78d122a3e011e7049\"\n },\n {\n \"url\": \"assets/weixin-zuixinbujiabandigongsimingdan.html.bf87a7d5.js\",\n \"revision\": \"6b31f97d80d9263648f800c7917b6bb4\"\n },\n {\n \"url\": \"assets/what-happen-when-javac.html.a3ce0b44.js\",\n \"revision\": \"42c7e44c613574a578d74096efe01d2f\"\n },\n {\n \"url\": \"assets/what-happen-when-javac.html.ab4282c1.js\",\n \"revision\": \"aec391454b1d49aea2d1ca364b27bbad\"\n },\n {\n \"url\": \"assets/what-is-java.html.b724e432.js\",\n \"revision\": \"ea158f9a6749d586eb5eb1a5fe867369\"\n },\n {\n \"url\": \"assets/what-is-java.html.e968650c.js\",\n \"revision\": \"cc20699b18eeea54e34295ba931c47fa\"\n },\n {\n \"url\": \"assets/what-is-jvm.html.0a353155.js\",\n \"revision\": \"edd246cd16496858099299f0696c1087\"\n },\n {\n \"url\": \"assets/what-is-jvm.html.5131a239.js\",\n \"revision\": \"2428430ef6fd17693a8d67d339efdbaf\"\n },\n {\n \"url\": \"assets/whereis-the-object.html.c695df3e.js\",\n \"revision\": \"40f9a605c5d9174441138c22b4df9205\"\n },\n {\n \"url\": \"assets/whereis-the-object.html.f6879982.js\",\n \"revision\": \"ca5a79eb3f6ed2aa0ab81ec83b5bba2a\"\n },\n {\n \"url\": \"assets/why-need-thread.html.08014ce1.js\",\n \"revision\": \"6c01c036dc648c890fbfdd5e28f87e4d\"\n },\n {\n \"url\": \"assets/why-need-thread.html.507a940d.js\",\n \"revision\": \"d4a7d960b4a4125ab55a9d577d1e8360\"\n },\n {\n \"url\": \"assets/windows-codingmore-run.html.4fb12f5d.js\",\n \"revision\": \"f04ddd8be0190d2ab997ba3fb27c8269\"\n },\n {\n \"url\": \"assets/windows-codingmore-run.html.dcfb09e6.js\",\n \"revision\": \"63df4f9d6bc0fe10f59d0ffde6a98199\"\n },\n {\n \"url\": \"assets/xian.html.4603b6ae.js\",\n \"revision\": \"88e71576d1ffd5bf997516b27b15af5d\"\n },\n {\n \"url\": \"assets/xian.html.4a14941e.js\",\n \"revision\": \"a5aa79b165040c96a5e1df77243832e6\"\n },\n {\n \"url\": \"assets/xuebeng-chuantou-jichuan.html.26ef04a3.js\",\n \"revision\": \"c10aab87bc0050f68ba50c3693861364\"\n },\n {\n \"url\": \"assets/xuebeng-chuantou-jichuan.html.37293204.js\",\n \"revision\": \"ea40dd88aa8d13e3dbd82e8f9a979d23\"\n },\n {\n \"url\": \"assets/yanjiusuo-20wan.html.76b660c5.js\",\n \"revision\": \"6cb110df442468ed54c8c39e2aed9685\"\n },\n {\n \"url\": \"assets/yanjiusuo-20wan.html.a3e5343d.js\",\n \"revision\": \"4a563a9c75147dfef1746b4389d8b71e\"\n },\n {\n \"url\": \"assets/yitiaolong.html.0ffd862a.js\",\n \"revision\": \"740513e76f9f97d6e3f30dfbddf7ace9\"\n },\n {\n \"url\": \"assets/yitiaolong.html.6c191a66.js\",\n \"revision\": \"acb3a943f46a1d68702ca75a03393220\"\n },\n {\n \"url\": \"assets/yuanyifeng-c-language.html.1d18c5bc.js\",\n \"revision\": \"a5306018e680b76dd88b44e8c84eec13\"\n },\n {\n \"url\": \"assets/yuanyifeng-c-language.html.869263b3.js\",\n \"revision\": \"bde02e954e45c225526b4d850ce69208\"\n },\n {\n \"url\": \"assets/yuneban-wangyiyunyinyue.html.275a589e.js\",\n \"revision\": \"02439e9c34e5ddec3bd616d8d036bb42\"\n },\n {\n \"url\": \"assets/yuneban-wangyiyunyinyue.html.df2c1c62.js\",\n \"revision\": \"acc4d0a3460f9e2fa8a12a055dc88a84\"\n },\n {\n \"url\": \"assets/zhengzhou.html.43c30f38.js\",\n \"revision\": \"2e4816d18e8f7f517b7c9e4c505990ef\"\n },\n {\n \"url\": \"assets/zhengzhou.html.5cf8ec33.js\",\n \"revision\": \"90e422e005b09a42e236f9a026fb9ebd\"\n },\n {\n \"url\": \"assets/zhihu-1000wan.html.4bf2b6f4.js\",\n \"revision\": \"677db386556c4a3b1c5368584a949dde\"\n },\n {\n \"url\": \"assets/zhihu-1000wan.html.6f71965a.js\",\n \"revision\": \"3a8e4ddc6b42095726232265b937f2fa\"\n },\n {\n \"url\": \"assets/ZHIHUjavaxuexidaoshemechengduokeyizhaodiyifengongzuo.html.9b7b6461.js\",\n \"revision\": \"766ece7f596b094402ebd363b7150acd\"\n },\n {\n \"url\": \"assets/ZHIHUjavaxuexidaoshemechengduokeyizhaodiyifengongzuo.html.e4fead09.js\",\n \"revision\": \"c265404944c7ef4afe301786011a3ab7\"\n },\n {\n \"url\": \"assets/zijiema-zhiling.html.34c655bc.js\",\n \"revision\": \"203ba55ffb1e89f9bb2fe0482a78a416\"\n },\n {\n \"url\": \"assets/zijiema-zhiling.html.9c4d95e9.js\",\n \"revision\": \"81c3019459f46aaa852c4110f3f4794d\"\n },\n {\n \"url\": \"assets/zongjie.html.0af46efc.js\",\n \"revision\": \"e52012e5b38812dd1a06d5656f2acd45\"\n },\n {\n \"url\": \"assets/zongjie.html.c9e5e3c3.js\",\n \"revision\": \"bfa15e84daf91ca3742016d07bbb8252\"\n },\n {\n \"url\": \"assets/zoom.esm.8514a202.js\",\n \"revision\": \"8b3ee4f6f71ef2a7c85901cba6d23344\"\n },\n {\n \"url\": \"logo.svg\",\n \"revision\": \"d7efe218a18b0891e803f61130d971ea\"\n },\n {\n \"url\": \"assets/league-gothic.38fcc721.ttf\",\n \"revision\": \"91295fa87df918411b49b7531da5d558\"\n },\n {\n \"url\": \"assets/league-gothic.5eef6df8.woff\",\n \"revision\": \"cd382dc8a9d6317864b5810a320effc5\"\n },\n {\n \"url\": \"assets/league-gothic.8802c66a.eot\",\n \"revision\": \"9900a4643cc63c5d8f969d2196f72572\"\n },\n {\n \"url\": \"assets/source-sans-pro-italic.05d3615f.woff\",\n \"revision\": \"e74f0128884561828ce8c9cf5c284ab8\"\n },\n {\n \"url\": \"assets/source-sans-pro-italic.ad4b0799.eot\",\n \"revision\": \"72217712eb8d28872e7069322f3fda23\"\n },\n {\n \"url\": \"assets/source-sans-pro-italic.d13268af.ttf\",\n \"revision\": \"8256cfd7e4017a7690814879409212cd\"\n },\n {\n \"url\": \"assets/source-sans-pro-regular.c1865d89.ttf\",\n \"revision\": \"2da39ecf9246383937da11b44b7bd9b4\"\n },\n {\n \"url\": \"assets/source-sans-pro-regular.d4eaa48b.woff\",\n \"revision\": \"e7acc589bb558fe58936a853f570193c\"\n },\n {\n \"url\": \"assets/source-sans-pro-regular.dce8869d.eot\",\n \"revision\": \"1d71438462d532b62b05cdd7e6d7197d\"\n },\n {\n \"url\": \"assets/source-sans-pro-semibold.a53e2723.ttf\",\n \"revision\": \"f3565095e6c9158140444970f5a2c5ed\"\n },\n {\n \"url\": \"assets/source-sans-pro-semibold.b0abd273.woff\",\n \"revision\": \"1cb8e94f1185f1131a0c895165998f2b\"\n },\n {\n \"url\": \"assets/source-sans-pro-semibold.ebb8918d.eot\",\n \"revision\": \"0f3da1edf1b5c6a94a6ad948a7664451\"\n },\n {\n \"url\": \"assets/source-sans-pro-semibolditalic.7225cacc.woff\",\n \"revision\": \"6b058fc2634b01d837c3432316c3141f\"\n },\n {\n \"url\": \"assets/source-sans-pro-semibolditalic.dfe0b47a.eot\",\n \"revision\": \"58153ac7194e141d1e73ea88c6b63861\"\n },\n {\n \"url\": \"assets/source-sans-pro-semibolditalic.e8ec22b6.ttf\",\n \"revision\": \"c7e698a4d0956f4a939f42a05685bbf5\"\n },\n {\n \"url\": \"index.html\",\n \"revision\": \"bd822ecbc08f5808bb04831910c814f2\"\n },\n {\n \"url\": \"404.html\",\n \"revision\": \"a0e3d4269fde8726e34d81a073eee7f8\"\n },\n {\n \"url\": \"assets/icon/apple-icon-152.png\",\n \"revision\": \"d78854fc622a0bfa2a44a79ec8b6e561\"\n },\n {\n \"url\": \"assets/icon/chrome-192.png\",\n \"revision\": \"eaab382db5bb589c74e2720a777454c3\"\n },\n {\n \"url\": \"assets/icon/chrome-512.png\",\n \"revision\": \"5db9d4a587b378f0b283191e379d85fa\"\n },\n {\n \"url\": \"assets/icon/chrome-mask-192.png\",\n \"revision\": \"eaab382db5bb589c74e2720a777454c3\"\n },\n {\n \"url\": \"assets/icon/chrome-mask-512.png\",\n \"revision\": \"5db9d4a587b378f0b283191e379d85fa\"\n },\n {\n \"url\": \"assets/icon/itwanger-282.png\",\n \"revision\": \"85592fba02d1228f8ca3e842cef07b7c\"\n },\n {\n \"url\": \"assets/icon/itwanger-maskable.png\",\n \"revision\": \"ca6a86caa8171a39adfd0f53f10cdaf2\"\n },\n {\n \"url\": \"assets/icon/itwanger-monochrome.png\",\n \"revision\": \"ca6a86caa8171a39adfd0f53f10cdaf2\"\n },\n {\n \"url\": \"assets/icon/ms-icon-144.png\",\n \"revision\": \"983a00416fc5f5469a79611440389396\"\n },\n {\n \"url\": \"logo.png\",\n \"revision\": \"d30ac8bc232973da730e934321ffeb7f\"\n }\n], {});\nworkbox_precaching_cleanupOutdatedCaches();\n\n\n\n\n\n\n\n"],"names":["workbox_core_setCacheNameDetails","prefix","self","addEventListener","event","data","type","skipWaiting","workbox_core_clientsClaim","workbox_precaching_precacheAndRoute","url","revision","workbox_precaching_cleanupOutdatedCaches"],"mappings":"0nBAmBAA,EAAAA,oBAAiC,CAACC,OAAQ,iBAG1CC,KAAKC,iBAAiB,WAAYC,IAC5BA,EAAMC,MAA4B,iBAApBD,EAAMC,KAAKC,MAC3BJ,KAAKK,iBAITC,EAAAA,eAQAC,EAAAA,iBAAoC,CAClC,CACEC,IAAO,uCACKC,SAAA,oCAEd,CACED,IAAO,uCACKC,SAAA,oCAEd,CACED,IAAO,wCACKC,SAAA,oCAEd,CACED,IAAO,wCACKC,SAAA,oCAEd,CACED,IAAO,uCACKC,SAAA,oCAEd,CACED,IAAO,uCACKC,SAAA,oCAEd,CACED,IAAO,yBACKC,SAAA,oCAEd,CACED,IAAO,8BACKC,SAAA,oCAEd,CACED,IAAO,8BACKC,SAAA,oCAEd,CACED,IAAO,sCACKC,SAAA,oCAEd,CACED,IAAO,sCACKC,SAAA,oCAEd,CACED,IAAO,mCACKC,SAAA,oCAEd,CACED,IAAO,mCACKC,SAAA,oCAEd,CACED,IAAO,oCACKC,SAAA,oCAEd,CACED,IAAO,oCACKC,SAAA,oCAEd,CACED,IAAO,wCACKC,SAAA,oCAEd,CACED,IAAO,wCACKC,SAAA,oCAEd,CACED,IAAO,uDACKC,SAAA,oCAEd,CACED,IAAO,uDACKC,SAAA,oCAEd,CACED,IAAO,qCACKC,SAAA,oCAEd,CACED,IAAO,qCACKC,SAAA,oCAEd,CACED,IAAO,kCACKC,SAAA,oCAEd,CACED,IAAO,kCACKC,SAAA,oCAEd,CACED,IAAO,uCACKC,SAAA,oCAEd,CACED,IAAO,uCACKC,SAAA,oCAEd,CACED,IAAO,yBACKC,SAAA,oCAEd,CACED,IAAO,8BACKC,SAAA,oCAEd,CACED,IAAO,8BACKC,SAAA,oCAEd,CACED,IAAO,gCACKC,SAAA,oCAEd,CACED,IAAO,gCACKC,SAAA,oCAEd,CACED,IAAO,oCACKC,SAAA,oCAEd,CACED,IAAO,oCACKC,SAAA,oCAEd,CACED,IAAO,iCACKC,SAAA,oCAEd,CACED,IAAO,iCACKC,SAAA,oCAEd,CACED,IAAO,8BACKC,SAAA,oCAEd,CACED,IAAO,8BACKC,SAAA,oCAEd,CACED,IAAO,iCACKC,SAAA,oCAEd,CACED,IAAO,iCACKC,SAAA,oCAEd,CACED,IAAO,yCACKC,SAAA,oCAEd,CACED,IAAO,yCACKC,SAAA,oCAEd,CACED,IAAO,0CACKC,SAAA,oCAEd,CACED,IAAO,0CACKC,SAAA,oCAEd,CACED,IAAO,qCACKC,SAAA,oCAEd,CACED,IAAO,qCACKC,SAAA,oCAEd,CACED,IAAO,kCACKC,SAAA,oCAEd,CACED,IAAO,kCACKC,SAAA,oCAEd,CACED,IAAO,oCACKC,SAAA,oCAEd,CACED,IAAO,oCACKC,SAAA,oCAEd,CACED,IAAO,wCACKC,SAAA,oCAEd,CACED,IAAO,wCACKC,SAAA,oCAEd,CACED,IAAO,2EACKC,SAAA,oCAEd,CACED,IAAO,2EACKC,SAAA,oCAEd,CACED,IAAO,2DACKC,SAAA,oCAEd,CACED,IAAO,2DACKC,SAAA,oCAEd,CACED,IAAO,0DACKC,SAAA,oCAEd,CACED,IAAO,0DACKC,SAAA,oCAEd,CACED,IAAO,8BACKC,SAAA,oCAEd,CACED,IAAO,8BACKC,SAAA,oCAEd,CACED,IAAO,2CACKC,SAAA,oCAEd,CACED,IAAO,2CACKC,SAAA,oCAEd,CACED,IAAO,qCACKC,SAAA,oCAEd,CACED,IAAO,qCACKC,SAAA,oCAEd,CACED,IAAO,mCACKC,SAAA,oCAEd,CACED,IAAO,mCACKC,SAAA,oCAEd,CACED,IAAO,sCACKC,SAAA,oCAEd,CACED,IAAO,sCACKC,SAAA,oCAEd,CACED,IAAO,4BACKC,SAAA,oCAEd,CACED,IAAO,4BACKC,SAAA,oCAEd,CACED,IAAO,8BACKC,SAAA,oCAEd,CACED,IAAO,8BACKC,SAAA,oCAEd,CACED,IAAO,8BACKC,SAAA,oCAEd,CACED,IAAO,8BACKC,SAAA,oCAEd,CACED,IAAO,wCACKC,SAAA,oCAEd,CACED,IAAO,wCACKC,SAAA,oCAEd,CACED,IAAO,kCACKC,SAAA,oCAEd,CACED,IAAO,kCACKC,SAAA,oCAEd,CACED,IAAO,sDACKC,SAAA,oCAEd,CACED,IAAO,sDACKC,SAAA,oCAEd,CACED,IAAO,iCACKC,SAAA,oCAEd,CACED,IAAO,iCACKC,SAAA,oCAEd,CACED,IAAO,gCACKC,SAAA,oCAEd,CACED,IAAO,gCACKC,SAAA,oCAEd,CACED,IAAO,8CACKC,SAAA,oCAEd,CACED,IAAO,8CACKC,SAAA,oCAEd,CACED,IAAO,4CACKC,SAAA,oCAEd,CACED,IAAO,4CACKC,SAAA,oCAEd,CACED,IAAO,qCACKC,SAAA,oCAEd,CACED,IAAO,qCACKC,SAAA,oCAEd,CACED,IAAO,uCACKC,SAAA,oCAEd,CACED,IAAO,uCACKC,SAAA,oCAEd,CACED,IAAO,oCACKC,SAAA,oCAEd,CACED,IAAO,oCACKC,SAAA,oCAEd,CACED,IAAO,qCACKC,SAAA,oCAEd,CACED,IAAO,qCACKC,SAAA,oCAEd,CACED,IAAO,sCACKC,SAAA,oCAEd,CACED,IAAO,sCACKC,SAAA,oCAEd,CACED,IAAO,+CACKC,SAAA,oCAEd,CACED,IAAO,+CACKC,SAAA,oCAEd,CACED,IAAO,sCACKC,SAAA,oCAEd,CACED,IAAO,sCACKC,SAAA,oCAEd,CACED,IAAO,wCACKC,SAAA,oCAEd,CACED,IAAO,wCACKC,SAAA,oCAEd,CACED,IAAO,4CACKC,SAAA,oCAEd,CACED,IAAO,4CACKC,SAAA,oCAEd,CACED,IAAO,gDACKC,SAAA,oCAEd,CACED,IAAO,gDACKC,SAAA,oCAEd,CACED,IAAO,oCACKC,SAAA,oCAEd,CACED,IAAO,oCACKC,SAAA,oCAEd,CACED,IAAO,wCACKC,SAAA,oCAEd,CACED,IAAO,wCACKC,SAAA,oCAEd,CACED,IAAO,oCACKC,SAAA,oCAEd,CACED,IAAO,oCACKC,SAAA,oCAEd,CACED,IAAO,+CACKC,SAAA,oCAEd,CACED,IAAO,+CACKC,SAAA,oCAEd,CACED,IAAO,+BACKC,SAAA,oCAEd,CACED,IAAO,+BACKC,SAAA,oCAEd,CACED,IAAO,yCACKC,SAAA,oCAEd,CACED,IAAO,yCACKC,SAAA,oCAEd,CACED,IAAO,0CACKC,SAAA,oCAEd,CACED,IAAO,0CACKC,SAAA,oCAEd,CACED,IAAO,uCACKC,SAAA,oCAEd,CACED,IAAO,uCACKC,SAAA,oCAEd,CACED,IAAO,8CACKC,SAAA,oCAEd,CACED,IAAO,8CACKC,SAAA,oCAEd,CACED,IAAO,kCACKC,SAAA,oCAEd,CACED,IAAO,kCACKC,SAAA,oCAEd,CACED,IAAO,oCACKC,SAAA,oCAEd,CACED,IAAO,oCACKC,SAAA,oCAEd,CACED,IAAO,uDACKC,SAAA,oCAEd,CACED,IAAO,uDACKC,SAAA,oCAEd,CACED,IAAO,2DACKC,SAAA,oCAEd,CACED,IAAO,2DACKC,SAAA,oCAEd,CACED,IAAO,+BACKC,SAAA,oCAEd,CACED,IAAO,+BACKC,SAAA,oCAEd,CACED,IAAO,0CACKC,SAAA,oCAEd,CACED,IAAO,0CACKC,SAAA,oCAEd,CACED,IAAO,iCACKC,SAAA,oCAEd,CACED,IAAO,iCACKC,SAAA,oCAEd,CACED,IAAO,oCACKC,SAAA,oCAEd,CACED,IAAO,oCACKC,SAAA,oCAEd,CACED,IAAO,iCACKC,SAAA,oCAEd,CACED,IAAO,iCACKC,SAAA,oCAEd,CACED,IAAO,mCACKC,SAAA,oCAEd,CACED,IAAO,mCACKC,SAAA,oCAEd,CACED,IAAO,sDACKC,SAAA,oCAEd,CACED,IAAO,sDACKC,SAAA,oCAEd,CACED,IAAO,gCACKC,SAAA,oCAEd,CACED,IAAO,gCACKC,SAAA,oCAEd,CACED,IAAO,uCACKC,SAAA,oCAEd,CACED,IAAO,uCACKC,SAAA,oCAEd,CACED,IAAO,iCACKC,SAAA,oCAEd,CACED,IAAO,iCACKC,SAAA,oCAEd,CACED,IAAO,oCACKC,SAAA,oCAEd,CACED,IAAO,oCACKC,SAAA,oCAEd,CACED,IAAO,qCACKC,SAAA,oCAEd,CACED,IAAO,qCACKC,SAAA,oCAEd,CACED,IAAO,iCACKC,SAAA,oCAEd,CACED,IAAO,iCACKC,SAAA,oCAEd,CACED,IAAO,iCACKC,SAAA,oCAEd,CACED,IAAO,iCACKC,SAAA,oCAEd,CACED,IAAO,6BACKC,SAAA,oCAEd,CACED,IAAO,6BACKC,SAAA,oCAEd,CACED,IAAO,kCACKC,SAAA,oCAEd,CACED,IAAO,kCACKC,SAAA,oCAEd,CACED,IAAO,qCACKC,SAAA,oCAEd,CACED,IAAO,qCACKC,SAAA,oCAEd,CACED,IAAO,6BACKC,SAAA,oCAEd,CACED,IAAO,6BACKC,SAAA,oCAEd,CACED,IAAO,+BACKC,SAAA,oCAEd,CACED,IAAO,+BACKC,SAAA,oCAEd,CACED,IAAO,oCACKC,SAAA,oCAEd,CACED,IAAO,oCACKC,SAAA,oCAEd,CACED,IAAO,gCACKC,SAAA,oCAEd,CACED,IAAO,gCACKC,SAAA,oCAEd,CACED,IAAO,mEACKC,SAAA,oCAEd,CACED,IAAO,mEACKC,SAAA,oCAEd,CACED,IAAO,mCACKC,SAAA,oCAEd,CACED,IAAO,mCACKC,SAAA,oCAEd,CACED,IAAO,mCACKC,SAAA,oCAEd,CACED,IAAO,mCACKC,SAAA,oCAEd,CACED,IAAO,4CACKC,SAAA,oCAEd,CACED,IAAO,4CACKC,SAAA,oCAEd,CACED,IAAO,kCACKC,SAAA,oCAEd,CACED,IAAO,kCACKC,SAAA,oCAEd,CACED,IAAO,sCACKC,SAAA,oCAEd,CACED,IAAO,sCACKC,SAAA,oCAEd,CACED,IAAO,mCACKC,SAAA,oCAEd,CACED,IAAO,kCACKC,SAAA,oCAEd,CACED,IAAO,kCACKC,SAAA,oCAEd,CACED,IAAO,+BACKC,SAAA,oCAEd,CACED,IAAO,+BACKC,SAAA,oCAEd,CACED,IAAO,sDACKC,SAAA,oCAEd,CACED,IAAO,sDACKC,SAAA,oCAEd,CACED,IAAO,4CACKC,SAAA,oCAEd,CACED,IAAO,4CACKC,SAAA,oCAEd,CACED,IAAO,+BACKC,SAAA,oCAEd,CACED,IAAO,+BACKC,SAAA,oCAEd,CACED,IAAO,uCACKC,SAAA,oCAEd,CACED,IAAO,uCACKC,SAAA,oCAEd,CACED,IAAO,iCACKC,SAAA,oCAEd,CACED,IAAO,iCACKC,SAAA,oCAEd,CACED,IAAO,sCACKC,SAAA,oCAEd,CACED,IAAO,sCACKC,SAAA,oCAEd,CACED,IAAO,oCACKC,SAAA,oCAEd,CACED,IAAO,oCACKC,SAAA,oCAEd,CACED,IAAO,oCACKC,SAAA,oCAEd,CACED,IAAO,oCACKC,SAAA,oCAEd,CACED,IAAO,gCACKC,SAAA,oCAEd,CACED,IAAO,gCACKC,SAAA,oCAEd,CACED,IAAO,gCACKC,SAAA,oCAEd,CACED,IAAO,gCACKC,SAAA,oCAEd,CACED,IAAO,gCACKC,SAAA,oCAEd,CACED,IAAO,gCACKC,SAAA,oCAEd,CACED,IAAO,gCACKC,SAAA,oCAEd,CACED,IAAO,gCACKC,SAAA,oCAEd,CACED,IAAO,gCACKC,SAAA,oCAEd,CACED,IAAO,gCACKC,SAAA,oCAEd,CACED,IAAO,qCACKC,SAAA,oCAEd,CACED,IAAO,qCACKC,SAAA,oCAEd,CACED,IAAO,sCACKC,SAAA,oCAEd,CACED,IAAO,sCACKC,SAAA,oCAEd,CACED,IAAO,gDACKC,SAAA,oCAEd,CACED,IAAO,gDACKC,SAAA,oCAEd,CACED,IAAO,yCACKC,SAAA,oCAEd,CACED,IAAO,yCACKC,SAAA,oCAEd,CACED,IAAO,qCACKC,SAAA,oCAEd,CACED,IAAO,qCACKC,SAAA,oCAEd,CACED,IAAO,oCACKC,SAAA,oCAEd,CACED,IAAO,oCACKC,SAAA,oCAEd,CACED,IAAO,oCACKC,SAAA,oCAEd,CACED,IAAO,oCACKC,SAAA,oCAEd,CACED,IAAO,iCACKC,SAAA,oCAEd,CACED,IAAO,iCACKC,SAAA,oCAEd,CACED,IAAO,8BACKC,SAAA,oCAEd,CACED,IAAO,8BACKC,SAAA,oCAEd,CACED,IAAO,4CACKC,SAAA,oCAEd,CACED,IAAO,4CACKC,SAAA,oCAEd,CACED,IAAO,kCACKC,SAAA,oCAEd,CACED,IAAO,kCACKC,SAAA,oCAEd,CACED,IAAO,wCACKC,SAAA,oCAEd,CACED,IAAO,wCACKC,SAAA,oCAEd,CACED,IAAO,qCACKC,SAAA,oCAEd,CACED,IAAO,qCACKC,SAAA,oCAEd,CACED,IAAO,8CACKC,SAAA,oCAEd,CACED,IAAO,8CACKC,SAAA,oCAEd,CACED,IAAO,sCACKC,SAAA,oCAEd,CACED,IAAO,sCACKC,SAAA,oCAEd,CACED,IAAO,sCACKC,SAAA,oCAEd,CACED,IAAO,sCACKC,SAAA,oCAEd,CACED,IAAO,uCACKC,SAAA,oCAEd,CACED,IAAO,uCACKC,SAAA,oCAEd,CACED,IAAO,+BACKC,SAAA,oCAEd,CACED,IAAO,+BACKC,SAAA,oCAEd,CACED,IAAO,kCACKC,SAAA,oCAEd,CACED,IAAO,kCACKC,SAAA,oCAEd,CACED,IAAO,iCACKC,SAAA,oCAEd,CACED,IAAO,iCACKC,SAAA,oCAEd,CACED,IAAO,qCACKC,SAAA,oCAEd,CACED,IAAO,qCACKC,SAAA,oCAEd,CACED,IAAO,0EACKC,SAAA,oCAEd,CACED,IAAO,0EACKC,SAAA,oCAEd,CACED,IAAO,uDACKC,SAAA,oCAEd,CACED,IAAO,uDACKC,SAAA,oCAEd,CACED,IAAO,gDACKC,SAAA,oCAEd,CACED,IAAO,gDACKC,SAAA,oCAEd,CACED,IAAO,kEACKC,SAAA,oCAEd,CACED,IAAO,kEACKC,SAAA,oCAEd,CACED,IAAO,iCACKC,SAAA,oCAEd,CACED,IAAO,iCACKC,SAAA,oCAEd,CACED,IAAO,uCACKC,SAAA,oCAEd,CACED,IAAO,uCACKC,SAAA,oCAEd,CACED,IAAO,mDACKC,SAAA,oCAEd,CACED,IAAO,mDACKC,SAAA,oCAEd,CACED,IAAO,qDACKC,SAAA,oCAEd,CACED,IAAO,qDACKC,SAAA,oCAEd,CACED,IAAO,8BACKC,SAAA,oCAEd,CACED,IAAO,8BACKC,SAAA,oCAEd,CACED,IAAO,8BACKC,SAAA,oCAEd,CACED,IAAO,8BACKC,SAAA,oCAEd,CACED,IAAO,+BACKC,SAAA,oCAEd,CACED,IAAO,+BACKC,SAAA,oCAEd,CACED,IAAO,8BACKC,SAAA,oCAEd,CACED,IAAO,8BACKC,SAAA,oCAEd,CACED,IAAO,gCACKC,SAAA,oCAEd,CACED,IAAO,gCACKC,SAAA,oCAEd,CACED,IAAO,8BACKC,SAAA,oCAEd,CACED,IAAO,8BACKC,SAAA,oCAEd,CACED,IAAO,8BACKC,SAAA,oCAEd,CACED,IAAO,8BACKC,SAAA,oCAEd,CACED,IAAO,8BACKC,SAAA,oCAEd,CACED,IAAO,8BACKC,SAAA,oCAEd,CACED,IAAO,8BACKC,SAAA,oCAEd,CACED,IAAO,8BACKC,SAAA,oCAEd,CACED,IAAO,kCACKC,SAAA,oCAEd,CACED,IAAO,kCACKC,SAAA,oCAEd,CACED,IAAO,iCACKC,SAAA,oCAEd,CACED,IAAO,iCACKC,SAAA,oCAEd,CACED,IAAO,qCACKC,SAAA,oCAEd,CACED,IAAO,qCACKC,SAAA,oCAEd,CACED,IAAO,4BACKC,SAAA,oCAEd,CACED,IAAO,uCACKC,SAAA,oCAEd,CACED,IAAO,uCACKC,SAAA,oCAEd,CACED,IAAO,qCACKC,SAAA,oCAEd,CACED,IAAO,qCACKC,SAAA,oCAEd,CACED,IAAO,qCACKC,SAAA,oCAEd,CACED,IAAO,qCACKC,SAAA,oCAEd,CACED,IAAO,+BACKC,SAAA,oCAEd,CACED,IAAO,+BACKC,SAAA,oCAEd,CACED,IAAO,sCACKC,SAAA,oCAEd,CACED,IAAO,sCACKC,SAAA,oCAEd,CACED,IAAO,gCACKC,SAAA,oCAEd,CACED,IAAO,gCACKC,SAAA,oCAEd,CACED,IAAO,iCACKC,SAAA,oCAEd,CACED,IAAO,iCACKC,SAAA,oCAEd,CACED,IAAO,iCACKC,SAAA,oCAEd,CACED,IAAO,iCACKC,SAAA,oCAEd,CACED,IAAO,kCACKC,SAAA,oCAEd,CACED,IAAO,kCACKC,SAAA,oCAEd,CACED,IAAO,kCACKC,SAAA,oCAEd,CACED,IAAO,kCACKC,SAAA,oCAEd,CACED,IAAO,+CACKC,SAAA,oCAEd,CACED,IAAO,+CACKC,SAAA,oCAEd,CACED,IAAO,8BACKC,SAAA,oCAEd,CACED,IAAO,8BACKC,SAAA,oCAEd,CACED,IAAO,kCACKC,SAAA,oCAEd,CACED,IAAO,8BACKC,SAAA,oCAEd,CACED,IAAO,gCACKC,SAAA,oCAEd,CACED,IAAO,gCACKC,SAAA,oCAEd,CACED,IAAO,uCACKC,SAAA,oCAEd,CACED,IAAO,uCACKC,SAAA,oCAEd,CACED,IAAO,iCACKC,SAAA,oCAEd,CACED,IAAO,iCACKC,SAAA,oCAEd,CACED,IAAO,kCACKC,SAAA,oCAEd,CACED,IAAO,kCACKC,SAAA,oCAEd,CACED,IAAO,sCACKC,SAAA,oCAEd,CACED,IAAO,sCACKC,SAAA,oCAEd,CACED,IAAO,gCACKC,SAAA,oCAEd,CACED,IAAO,gCACKC,SAAA,oCAEd,CACED,IAAO,kCACKC,SAAA,oCAEd,CACED,IAAO,kCACKC,SAAA,oCAEd,CACED,IAAO,wCACKC,SAAA,oCAEd,CACED,IAAO,wCACKC,SAAA,oCAEd,CACED,IAAO,gCACKC,SAAA,oCAEd,CACED,IAAO,gCACKC,SAAA,oCAEd,CACED,IAAO,sCACKC,SAAA,oCAEd,CACED,IAAO,sCACKC,SAAA,oCAEd,CACED,IAAO,+BACKC,SAAA,oCAEd,CACED,IAAO,+BACKC,SAAA,oCAEd,CACED,IAAO,+BACKC,SAAA,oCAEd,CACED,IAAO,8BACKC,SAAA,oCAEd,CACED,IAAO,8BACKC,SAAA,oCAEd,CACED,IAAO,uCACKC,SAAA,oCAEd,CACED,IAAO,uCACKC,SAAA,oCAEd,CACED,IAAO,8BACKC,SAAA,oCAEd,CACED,IAAO,8BACKC,SAAA,oCAEd,CACED,IAAO,mCACKC,SAAA,oCAEd,CACED,IAAO,mCACKC,SAAA,oCAEd,CACED,IAAO,mCACKC,SAAA,oCAEd,CACED,IAAO,mCACKC,SAAA,oCAEd,CACED,IAAO,6BACKC,SAAA,oCAEd,CACED,IAAO,6BACKC,SAAA,oCAEd,CACED,IAAO,6BACKC,SAAA,oCAEd,CACED,IAAO,6BACKC,SAAA,oCAEd,CACED,IAAO,8BACKC,SAAA,oCAEd,CACED,IAAO,8BACKC,SAAA,oCAEd,CACED,IAAO,iCACKC,SAAA,oCAEd,CACED,IAAO,iCACKC,SAAA,oCAEd,CACED,IAAO,4CACKC,SAAA,oCAEd,CACED,IAAO,4CACKC,SAAA,oCAEd,CACED,IAAO,qCACKC,SAAA,oCAEd,CACED,IAAO,qCACKC,SAAA,oCAEd,CACED,IAAO,wCACKC,SAAA,oCAEd,CACED,IAAO,wCACKC,SAAA,oCAEd,CACED,IAAO,8BACKC,SAAA,oCAEd,CACED,IAAO,8BACKC,SAAA,oCAEd,CACED,IAAO,oCACKC,SAAA,oCAEd,CACED,IAAO,8CACKC,SAAA,oCAEd,CACED,IAAO,+BACKC,SAAA,oCAEd,CACED,IAAO,+BACKC,SAAA,oCAEd,CACED,IAAO,gCACKC,SAAA,oCAEd,CACED,IAAO,gCACKC,SAAA,oCAEd,CACED,IAAO,wCACKC,SAAA,oCAEd,CACED,IAAO,wCACKC,SAAA,oCAEd,CACED,IAAO,iCACKC,SAAA,oCAEd,CACED,IAAO,iCACKC,SAAA,oCAEd,CACED,IAAO,iCACKC,SAAA,oCAEd,CACED,IAAO,iCACKC,SAAA,oCAEd,CACED,IAAO,iCACKC,SAAA,oCAEd,CACED,IAAO,iCACKC,SAAA,oCAEd,CACED,IAAO,mCACKC,SAAA,oCAEd,CACED,IAAO,mCACKC,SAAA,oCAEd,CACED,IAAO,kCACKC,SAAA,oCAEd,CACED,IAAO,kCACKC,SAAA,oCAEd,CACED,IAAO,yCACKC,SAAA,oCAEd,CACED,IAAO,yCACKC,SAAA,oCAEd,CACED,IAAO,qCACKC,SAAA,oCAEd,CACED,IAAO,qCACKC,SAAA,oCAEd,CACED,IAAO,wCACKC,SAAA,oCAEd,CACED,IAAO,wCACKC,SAAA,oCAEd,CACED,IAAO,gDACKC,SAAA,oCAEd,CACED,IAAO,gDACKC,SAAA,oCAEd,CACED,IAAO,2CACKC,SAAA,oCAEd,CACED,IAAO,2CACKC,SAAA,oCAEd,CACED,IAAO,gCACKC,SAAA,oCAEd,CACED,IAAO,gCACKC,SAAA,oCAEd,CACED,IAAO,0CACKC,SAAA,oCAEd,CACED,IAAO,0CACKC,SAAA,oCAEd,CACED,IAAO,wCACKC,SAAA,oCAEd,CACED,IAAO,wCACKC,SAAA,oCAEd,CACED,IAAO,iDACKC,SAAA,oCAEd,CACED,IAAO,iDACKC,SAAA,oCAEd,CACED,IAAO,gCACKC,SAAA,oCAEd,CACED,IAAO,gCACKC,SAAA,oCAEd,CACED,IAAO,gCACKC,SAAA,oCAEd,CACED,IAAO,gCACKC,SAAA,oCAEd,CACED,IAAO,gCACKC,SAAA,oCAEd,CACED,IAAO,gCACKC,SAAA,oCAEd,CACED,IAAO,gCACKC,SAAA,oCAEd,CACED,IAAO,sDACKC,SAAA,oCAEd,CACED,IAAO,sDACKC,SAAA,oCAEd,CACED,IAAO,gCACKC,SAAA,oCAEd,CACED,IAAO,wCACKC,SAAA,oCAEd,CACED,IAAO,wCACKC,SAAA,oCAEd,CACED,IAAO,mCACKC,SAAA,oCAEd,CACED,IAAO,mCACKC,SAAA,oCAEd,CACED,IAAO,kDACKC,SAAA,oCAEd,CACED,IAAO,kDACKC,SAAA,oCAEd,CACED,IAAO,mCACKC,SAAA,oCAEd,CACED,IAAO,mCACKC,SAAA,oCAEd,CACED,IAAO,kCACKC,SAAA,oCAEd,CACED,IAAO,kCACKC,SAAA,oCAEd,CACED,IAAO,8BACKC,SAAA,oCAEd,CACED,IAAO,gCACKC,SAAA,oCAEd,CACED,IAAO,gCACKC,SAAA,oCAEd,CACED,IAAO,2BACKC,SAAA,oCAEd,CACED,IAAO,gCACKC,SAAA,oCAEd,CACED,IAAO,gCACKC,SAAA,oCAEd,CACED,IAAO,iCACKC,SAAA,oCAEd,CACED,IAAO,iCACKC,SAAA,oCAEd,CACED,IAAO,qCACKC,SAAA,oCAEd,CACED,IAAO,qCACKC,SAAA,oCAEd,CACED,IAAO,iCACKC,SAAA,oCAEd,CACED,IAAO,iCACKC,SAAA,oCAEd,CACED,IAAO,iCACKC,SAAA,oCAEd,CACED,IAAO,iCACKC,SAAA,oCAEd,CACED,IAAO,4BACKC,SAAA,oCAEd,CACED,IAAO,iCACKC,SAAA,oCAEd,CACED,IAAO,iCACKC,SAAA,oCAEd,CACED,IAAO,kCACKC,SAAA,oCAEd,CACED,IAAO,kCACKC,SAAA,oCAEd,CACED,IAAO,uCACKC,SAAA,oCAEd,CACED,IAAO,uCACKC,SAAA,oCAEd,CACED,IAAO,gCACKC,SAAA,oCAEd,CACED,IAAO,gCACKC,SAAA,oCAEd,CACED,IAAO,qCACKC,SAAA,oCAEd,CACED,IAAO,qCACKC,SAAA,oCAEd,CACED,IAAO,oDACKC,SAAA,oCAEd,CACED,IAAO,oDACKC,SAAA,oCAEd,CACED,IAAO,2DACKC,SAAA,oCAEd,CACED,IAAO,2DACKC,SAAA,oCAEd,CACED,IAAO,kDACKC,SAAA,oCAEd,CACED,IAAO,kDACKC,SAAA,oCAEd,CACED,IAAO,iCACKC,SAAA,oCAEd,CACED,IAAO,iCACKC,SAAA,oCAEd,CACED,IAAO,sCACKC,SAAA,oCAEd,CACED,IAAO,sCACKC,SAAA,oCAEd,CACED,IAAO,oCACKC,SAAA,oCAEd,CACED,IAAO,oCACKC,SAAA,oCAEd,CACED,IAAO,8DACKC,SAAA,oCAEd,CACED,IAAO,8DACKC,SAAA,oCAEd,CACED,IAAO,iCACKC,SAAA,oCAEd,CACED,IAAO,iCACKC,SAAA,oCAEd,CACED,IAAO,sCACKC,SAAA,oCAEd,CACED,IAAO,sCACKC,SAAA,oCAEd,CACED,IAAO,uCACKC,SAAA,oCAEd,CACED,IAAO,uCACKC,SAAA,oCAEd,CACED,IAAO,4CACKC,SAAA,oCAEd,CACED,IAAO,4CACKC,SAAA,oCAEd,CACED,IAAO,mCACKC,SAAA,oCAEd,CACED,IAAO,mCACKC,SAAA,oCAEd,CACED,IAAO,2CACKC,SAAA,oCAEd,CACED,IAAO,2CACKC,SAAA,oCAEd,CACED,IAAO,8BACKC,SAAA,oCAEd,CACED,IAAO,8BACKC,SAAA,oCAEd,CACED,IAAO,mCACKC,SAAA,oCAEd,CACED,IAAO,mCACKC,SAAA,oCAEd,CACED,IAAO,mCACKC,SAAA,oCAEd,CACED,IAAO,mCACKC,SAAA,oCAEd,CACED,IAAO,wCACKC,SAAA,oCAEd,CACED,IAAO,wCACKC,SAAA,oCAEd,CACED,IAAO,kCACKC,SAAA,oCAEd,CACED,IAAO,kCACKC,SAAA,oCAEd,CACED,IAAO,yCACKC,SAAA,oCAEd,CACED,IAAO,yCACKC,SAAA,oCAEd,CACED,IAAO,+BACKC,SAAA,oCAEd,CACED,IAAO,+BACKC,SAAA,oCAEd,CACED,IAAO,mDACKC,SAAA,oCAEd,CACED,IAAO,mDACKC,SAAA,oCAEd,CACED,IAAO,iDACKC,SAAA,oCAEd,CACED,IAAO,iDACKC,SAAA,oCAEd,CACED,IAAO,mEACKC,SAAA,oCAEd,CACED,IAAO,mEACKC,SAAA,oCAEd,CACED,IAAO,yDACKC,SAAA,oCAEd,CACED,IAAO,yDACKC,SAAA,oCAEd,CACED,IAAO,+DACKC,SAAA,oCAEd,CACED,IAAO,+DACKC,SAAA,oCAEd,CACED,IAAO,iDACKC,SAAA,oCAEd,CACED,IAAO,iDACKC,SAAA,oCAEd,CACED,IAAO,uCACKC,SAAA,oCAEd,CACED,IAAO,uCACKC,SAAA,oCAEd,CACED,IAAO,sCACKC,SAAA,oCAEd,CACED,IAAO,sCACKC,SAAA,oCAEd,CACED,IAAO,6CACKC,SAAA,oCAEd,CACED,IAAO,6CACKC,SAAA,oCAEd,CACED,IAAO,0CACKC,SAAA,oCAEd,CACED,IAAO,0CACKC,SAAA,oCAEd,CACED,IAAO,iDACKC,SAAA,oCAEd,CACED,IAAO,iDACKC,SAAA,oCAEd,CACED,IAAO,+BACKC,SAAA,oCAEd,CACED,IAAO,+BACKC,SAAA,oCAEd,CACED,IAAO,mDACKC,SAAA,oCAEd,CACED,IAAO,mDACKC,SAAA,oCAEd,CACED,IAAO,0CACKC,SAAA,oCAEd,CACED,IAAO,0CACKC,SAAA,oCAEd,CACED,IAAO,qCACKC,SAAA,oCAEd,CACED,IAAO,qCACKC,SAAA,oCAEd,CACED,IAAO,gDACKC,SAAA,oCAEd,CACED,IAAO,gDACKC,SAAA,oCAEd,CACED,IAAO,kDACKC,SAAA,oCAEd,CACED,IAAO,kDACKC,SAAA,oCAEd,CACED,IAAO,oCACKC,SAAA,oCAEd,CACED,IAAO,oCACKC,SAAA,oCAEd,CACED,IAAO,wCACKC,SAAA,oCAEd,CACED,IAAO,wCACKC,SAAA,oCAEd,CACED,IAAO,+EACKC,SAAA,oCAEd,CACED,IAAO,+EACKC,SAAA,oCAEd,CACED,IAAO,0CACKC,SAAA,oCAEd,CACED,IAAO,0CACKC,SAAA,oCAEd,CACED,IAAO,kCACKC,SAAA,oCAEd,CACED,IAAO,kCACKC,SAAA,oCAEd,CACED,IAAO,8BACKC,SAAA,oCAEd,CACED,IAAO,WACKC,SAAA,oCAEd,CACED,IAAO,oCACKC,SAAA,oCAEd,CACED,IAAO,qCACKC,SAAA,oCAEd,CACED,IAAO,oCACKC,SAAA,oCAEd,CACED,IAAO,8CACKC,SAAA,oCAEd,CACED,IAAO,6CACKC,SAAA,oCAEd,CACED,IAAO,6CACKC,SAAA,oCAEd,CACED,IAAO,8CACKC,SAAA,oCAEd,CACED,IAAO,+CACKC,SAAA,oCAEd,CACED,IAAO,8CACKC,SAAA,oCAEd,CACED,IAAO,+CACKC,SAAA,oCAEd,CACED,IAAO,gDACKC,SAAA,oCAEd,CACED,IAAO,+CACKC,SAAA,oCAEd,CACED,IAAO,sDACKC,SAAA,oCAEd,CACED,IAAO,qDACKC,SAAA,oCAEd,CACED,IAAO,qDACKC,SAAA,oCAEd,CACED,IAAO,aACKC,SAAA,oCAEd,CACED,IAAO,WACKC,SAAA,oCAEd,CACED,IAAO,iCACKC,SAAA,oCAEd,CACED,IAAO,6BACKC,SAAA,oCAEd,CACED,IAAO,6BACKC,SAAA,oCAEd,CACED,IAAO,kCACKC,SAAA,oCAEd,CACED,IAAO,kCACKC,SAAA,oCAEd,CACED,IAAO,+BACKC,SAAA,oCAEd,CACED,IAAO,oCACKC,SAAA,oCAEd,CACED,IAAO,sCACKC,SAAA,oCAEd,CACED,IAAO,8BACKC,SAAA,oCAEd,CACED,IAAO,WACKC,SAAA,qCAEb,IACHC,EAAAA"} \ No newline at end of file +{"version":3,"file":"service-worker.js","sources":["../../../../../private/var/folders/6b/ysj769_d2gddttlwzw0nmhyc0000gn/T/aa4ec46e6711f38e3cf551e4c1ce3e78/service-worker.js"],"sourcesContent":["import {setCacheNameDetails as workbox_core_setCacheNameDetails} from '/Users/maweiqing/Documents/GitHub/toBeBetterJavaer/node_modules/workbox-core/setCacheNameDetails.mjs';\nimport {clientsClaim as workbox_core_clientsClaim} from '/Users/maweiqing/Documents/GitHub/toBeBetterJavaer/node_modules/workbox-core/clientsClaim.mjs';\nimport {precacheAndRoute as workbox_precaching_precacheAndRoute} from '/Users/maweiqing/Documents/GitHub/toBeBetterJavaer/node_modules/workbox-precaching/precacheAndRoute.mjs';\nimport {cleanupOutdatedCaches as workbox_precaching_cleanupOutdatedCaches} from '/Users/maweiqing/Documents/GitHub/toBeBetterJavaer/node_modules/workbox-precaching/cleanupOutdatedCaches.mjs';/**\n * Welcome to your Workbox-powered service worker!\n *\n * You'll need to register this file in your web app.\n * See https://goo.gl/nhQhGp\n *\n * The rest of the code is auto-generated. Please don't update this file\n * directly; instead, make changes to your Workbox build configuration\n * and re-run your build process.\n * See https://goo.gl/2aRDsh\n */\n\n\n\n\n\nworkbox_core_setCacheNameDetails({prefix: \"Java 程序员进阶之路\"});\n\n\nself.addEventListener('message', (event) => {\n if (event.data && event.data.type === 'SKIP_WAITING') {\n self.skipWaiting();\n }\n});\n\nworkbox_core_clientsClaim();\n\n\n/**\n * The precacheAndRoute() method efficiently caches and responds to\n * requests for URLs in the manifest.\n * See https://goo.gl/S9QRab\n */\nworkbox_precaching_precacheAndRoute([\n {\n \"url\": \"assets/100-budiushi.html.281fc989.js\",\n \"revision\": \"e5349f110a8223b768c7073e1c050248\"\n },\n {\n \"url\": \"assets/100-budiushi.html.c3040dbf.js\",\n \"revision\": \"5e2fdf602f4f9cfe989cd2ecee4c6e1b\"\n },\n {\n \"url\": \"assets/4-debug-skill.html.0c72ed75.js\",\n \"revision\": \"8f688bdfdb736a05c83bbb082378b4b1\"\n },\n {\n \"url\": \"assets/4-debug-skill.html.9bd076fc.js\",\n \"revision\": \"bdd75149e13482f9c53f9ea3e0a36927\"\n },\n {\n \"url\": \"assets/40-interview.html.2cb0fe6c.js\",\n \"revision\": \"b73bdbdbc6bdccce1a2a65eb0e4a34ba\"\n },\n {\n \"url\": \"assets/40-interview.html.e460eeeb.js\",\n \"revision\": \"59d292b1b8fd01e114ec8b92c60aa830\"\n },\n {\n \"url\": \"assets/404.c61acaed.js\",\n \"revision\": \"28aa9123b38d4a0ac28fbf5ff1462d67\"\n },\n {\n \"url\": \"assets/404.html.6cb935de.js\",\n \"revision\": \"12251408caddfaa21efe1731e77d78f4\"\n },\n {\n \"url\": \"assets/404.html.e75684b7.js\",\n \"revision\": \"19f495e79edd1b6a31d59cc9804d8602\"\n },\n {\n \"url\": \"assets/48-keywords.html.c30c9b30.js\",\n \"revision\": \"1018ecb3e0471868b71b0be0edceb6f4\"\n },\n {\n \"url\": \"assets/48-keywords.html.e76832ee.js\",\n \"revision\": \"0f28937c5f2199e1fb19617c0169cc05\"\n },\n {\n \"url\": \"assets/abstract.html.3094fdb5.js\",\n \"revision\": \"3f1e0182c50046175b9a0df0660d37e9\"\n },\n {\n \"url\": \"assets/abstract.html.e17df797.js\",\n \"revision\": \"5d861ea8503b0e335a5e76b1c3e784ff\"\n },\n {\n \"url\": \"assets/algorithm.html.14390f00.js\",\n \"revision\": \"cbe7a405e3cfcc0ad60ef4bffc3765fb\"\n },\n {\n \"url\": \"assets/algorithm.html.8d44122f.js\",\n \"revision\": \"81cb024c205170c12555c527fff76bc4\"\n },\n {\n \"url\": \"assets/ali-executors.html.3e2ae653.js\",\n \"revision\": \"6ee3e51399ba5c81a51cc756465de7d2\"\n },\n {\n \"url\": \"assets/ali-executors.html.988adc8e.js\",\n \"revision\": \"84812d38cd71487938d2a8511d0b7225\"\n },\n {\n \"url\": \"assets/aliyun-shuaiguo-gongchengshi.html.af9a0166.js\",\n \"revision\": \"c9f49241edf377bd52e5f179bdd3ea39\"\n },\n {\n \"url\": \"assets/aliyun-shuaiguo-gongchengshi.html.e4346151.js\",\n \"revision\": \"97ea58e96d96f1afd5bb00e2f3b35fcb\"\n },\n {\n \"url\": \"assets/annotation.html.14064668.js\",\n \"revision\": \"b8c310fbc00430fd403dedfcffd9e496\"\n },\n {\n \"url\": \"assets/annotation.html.3a9fcfe1.js\",\n \"revision\": \"16271f73264a861a848a398ad776a22c\"\n },\n {\n \"url\": \"assets/aop-log.html.390b071a.js\",\n \"revision\": \"4d14cfeb7c0b409467bb60a83463cd8a\"\n },\n {\n \"url\": \"assets/aop-log.html.ec10c829.js\",\n \"revision\": \"d3613c7a4e7a24b84cbf479b4b1662c3\"\n },\n {\n \"url\": \"assets/api-wangguan.html.c2b18262.js\",\n \"revision\": \"82f0406d65453e8eb1a5ad59ca30ecb0\"\n },\n {\n \"url\": \"assets/api-wangguan.html.ec8dd3f1.js\",\n \"revision\": \"7d2ca1dad41875acc0823b5d04c06316\"\n },\n {\n \"url\": \"assets/app.615e41d8.js\",\n \"revision\": \"462a39b9884283fc8e4efdbb3190ca73\"\n },\n {\n \"url\": \"assets/aqs.html.58976faa.js\",\n \"revision\": \"1e899d61bac85c459b062217b1faffcb\"\n },\n {\n \"url\": \"assets/aqs.html.d6a8f5b4.js\",\n \"revision\": \"625d292bc1a70d1e7405da97b6029523\"\n },\n {\n \"url\": \"assets/array.html.19972859.js\",\n \"revision\": \"c7041e95b8141255c15d85bdc25add03\"\n },\n {\n \"url\": \"assets/array.html.77525f56.js\",\n \"revision\": \"c7cc1063f8abb40eb5a6e6bb3a220431\"\n },\n {\n \"url\": \"assets/arraylist.html.0dcdca73.js\",\n \"revision\": \"381a5a48e521e35dda79e367eac116a1\"\n },\n {\n \"url\": \"assets/arraylist.html.f57cbfa7.js\",\n \"revision\": \"20006ece67610ce4fc11f63bb6a06c21\"\n },\n {\n \"url\": \"assets/arrays.html.7944f961.js\",\n \"revision\": \"c15f2d6bcb85818880f6f8383f9dbc61\"\n },\n {\n \"url\": \"assets/arrays.html.ea4b1150.js\",\n \"revision\": \"a68d0b598d5b2f18cd4b2caab0c33ac0\"\n },\n {\n \"url\": \"assets/asm.html.0e0abd8b.js\",\n \"revision\": \"072c730bffd7fc1a8a611ddd1c5da23e\"\n },\n {\n \"url\": \"assets/asm.html.43e7fd57.js\",\n \"revision\": \"fbdf1e03ba81fa6de251a8f57dfbfbbd\"\n },\n {\n \"url\": \"assets/atomic.html.08ec5c1f.js\",\n \"revision\": \"e436e5a1a1d9e7f8b478cc0da7455b8a\"\n },\n {\n \"url\": \"assets/atomic.html.93391f09.js\",\n \"revision\": \"0a81ec041fa27d2b5cff824a647d20a1\"\n },\n {\n \"url\": \"assets/auto-generator.html.341a868e.js\",\n \"revision\": \"ef2dd2da21763df827704142a85df600\"\n },\n {\n \"url\": \"assets/auto-generator.html.7efe2473.js\",\n \"revision\": \"9ebf50d78e0b0c93dd2b94e4e6c93c93\"\n },\n {\n \"url\": \"assets/basic-data-type.html.20d3399e.js\",\n \"revision\": \"30131e0f8a59beb06a01e64bd482ca55\"\n },\n {\n \"url\": \"assets/basic-data-type.html.6be3e7e2.js\",\n \"revision\": \"926a54b4618afc77e58598cb1f53e6ed\"\n },\n {\n \"url\": \"assets/bat-shuati.html.01dded07.js\",\n \"revision\": \"b27249fdf907cce09c7ed8036c1ca2c6\"\n },\n {\n \"url\": \"assets/bat-shuati.html.214e49f5.js\",\n \"revision\": \"230a0084e5f06e7621b3f9ae60c6b782\"\n },\n {\n \"url\": \"assets/beijing.html.78adaacf.js\",\n \"revision\": \"5c6eeabb99c1bae2683df89bcdecf679\"\n },\n {\n \"url\": \"assets/beijing.html.a011f671.js\",\n \"revision\": \"a9bcedf1d92d4670b81886c82152a899\"\n },\n {\n \"url\": \"assets/BIONIOAIO.html.4c184e72.js\",\n \"revision\": \"ab0c38e3b6718606cae3c583575c138f\"\n },\n {\n \"url\": \"assets/BIONIOAIO.html.ea89d11f.js\",\n \"revision\": \"1e4874dbc0370df66e2880da25a688ca\"\n },\n {\n \"url\": \"assets/BlockingQueue.html.76b31f3c.js\",\n \"revision\": \"87a004312a99cb938d30df25abd521a1\"\n },\n {\n \"url\": \"assets/BlockingQueue.html.9ccd9ba0.js\",\n \"revision\": \"ceeda89af92173a6e837c5a077c9d909\"\n },\n {\n \"url\": \"assets/bokeyuan-jianxijavazhongdifangwenquanxiankongzhi.html.5212785d.js\",\n \"revision\": \"3a2e1826d21d67cf8cfe912d952867d8\"\n },\n {\n \"url\": \"assets/bokeyuan-jianxijavazhongdifangwenquanxiankongzhi.html.bc8753e4.js\",\n \"revision\": \"e407e843972f36f357c6600a48c11379\"\n },\n {\n \"url\": \"assets/bokeyuan-ruhegaoxiaodixuexijishu.html.e50696a0.js\",\n \"revision\": \"a0dd1192c35e2a51b30705cce3ba9536\"\n },\n {\n \"url\": \"assets/bokeyuan-ruhegaoxiaodixuexijishu.html.e9d4ca36.js\",\n \"revision\": \"1a48b0e99830900cbfeb4437a51aae72\"\n },\n {\n \"url\": \"assets/BOKEYUANruhegaoxiaodixuexijishu.html.54dd2a4d.js\",\n \"revision\": \"e410b4653746a1f3a29de7315e67451d\"\n },\n {\n \"url\": \"assets/BOKEYUANruhegaoxiaodixuexijishu.html.665a0cbe.js\",\n \"revision\": \"de93c74f41f78e68ddbd04e19033c227\"\n },\n {\n \"url\": \"assets/box.html.03f96a13.js\",\n \"revision\": \"fb5f92bbfef8cfc68c6d988cc8857035\"\n },\n {\n \"url\": \"assets/box.html.54cc70a2.js\",\n \"revision\": \"09778d260a2bd54390c5df81ae5c0a4c\"\n },\n {\n \"url\": \"assets/buy-cloud-server.html.5057ae50.js\",\n \"revision\": \"15698e403fc258d6cd037e628885e4aa\"\n },\n {\n \"url\": \"assets/buy-cloud-server.html.595deaa6.js\",\n \"revision\": \"bea7becb36dcf02d7c5215fc19797c6e\"\n },\n {\n \"url\": \"assets/buy-domain.html.1227af51.js\",\n \"revision\": \"2084929626a6e80923df3997bea07231\"\n },\n {\n \"url\": \"assets/buy-domain.html.e087e5aa.js\",\n \"revision\": \"c00bf58acd8e46e3c6651617563ad248\"\n },\n {\n \"url\": \"assets/bytecode.html.568c5a04.js\",\n \"revision\": \"fff64b976e81c22c8dd0910ea34daa2e\"\n },\n {\n \"url\": \"assets/bytecode.html.ba8f00b6.js\",\n \"revision\": \"c0d1e7ef23332326dc90ce1d81d5d05f\"\n },\n {\n \"url\": \"assets/bzhan-10wan.html.98f8ba37.js\",\n \"revision\": \"d68d1bd3dddf462db72f205b33e3eeb5\"\n },\n {\n \"url\": \"assets/bzhan-10wan.html.e0ad4af0.js\",\n \"revision\": \"e5ad1bf8da307454b5dd5854770ab026\"\n },\n {\n \"url\": \"assets/c.html.5983fe89.js\",\n \"revision\": \"cee3031a57cc138acc6d11755802b30e\"\n },\n {\n \"url\": \"assets/c.html.6387955f.js\",\n \"revision\": \"c4fa4867ea58a30d4f28ba980fd74aec\"\n },\n {\n \"url\": \"assets/cas.html.4534d702.js\",\n \"revision\": \"8bc80781d9d2bdde974c66d01343caf9\"\n },\n {\n \"url\": \"assets/cas.html.68e07dc8.js\",\n \"revision\": \"df931dbc91cb8dbfa0b32f9243e74caa\"\n },\n {\n \"url\": \"assets/ccc.html.51a24970.js\",\n \"revision\": \"e724b888cc455ff547b84535af17a324\"\n },\n {\n \"url\": \"assets/ccc.html.bf391d30.js\",\n \"revision\": \"d75b8ae3f1e9b634c8055ff6d2c2413c\"\n },\n {\n \"url\": \"assets/chadiansanhuo.html.e9cc0b99.js\",\n \"revision\": \"3ae54e43d8b55c9b07f8b96eb885ddfd\"\n },\n {\n \"url\": \"assets/chadiansanhuo.html.fc173db8.js\",\n \"revision\": \"b2d1f3e61ae5215e0dad8546be908155\"\n },\n {\n \"url\": \"assets/chengdu.html.7221dfab.js\",\n \"revision\": \"238d2b06754f63f80055cfd770b492db\"\n },\n {\n \"url\": \"assets/chengdu.html.c9264a1d.js\",\n \"revision\": \"0a8271ba09b166b120fc54b0528a40e7\"\n },\n {\n \"url\": \"assets/chengxuyuannv-chonghui-java.html.01f1b5cf.js\",\n \"revision\": \"1da632940ee5b0e968caa14e10a23da1\"\n },\n {\n \"url\": \"assets/chengxuyuannv-chonghui-java.html.b9de6702.js\",\n \"revision\": \"eae9b017adb086faa22ac24423ebc287\"\n },\n {\n \"url\": \"assets/chiner.html.13c55607.js\",\n \"revision\": \"82785120402bceab024e50887e5714d1\"\n },\n {\n \"url\": \"assets/chiner.html.daf0adff.js\",\n \"revision\": \"637c3a7a711bdb0632f7a8444340e941\"\n },\n {\n \"url\": \"assets/choco.html.2c7d8900.js\",\n \"revision\": \"fa9b65d877ed86d6367a61da0d7c949c\"\n },\n {\n \"url\": \"assets/choco.html.f8923e81.js\",\n \"revision\": \"f1ecf9c1e645995f595ae0192eef1f6c\"\n },\n {\n \"url\": \"assets/Chocolatey-Homebrew.html.5637171d.js\",\n \"revision\": \"353690c435a883fa4f1de692cd3eef52\"\n },\n {\n \"url\": \"assets/Chocolatey-Homebrew.html.ad256880.js\",\n \"revision\": \"f27f5ffe5e873f37caae308cd3f7c800\"\n },\n {\n \"url\": \"assets/class-file-jiegou.html.3aa9524b.js\",\n \"revision\": \"5c367ebfd7097dcace533c9109a06d4e\"\n },\n {\n \"url\": \"assets/class-file-jiegou.html.3dff0326.js\",\n \"revision\": \"96c0ab54ea6bd0c20cc027807b9c0117\"\n },\n {\n \"url\": \"assets/class-load.html.07c5abca.js\",\n \"revision\": \"f25528ca369bd71d97047a371ba891d1\"\n },\n {\n \"url\": \"assets/class-load.html.6a788fca.js\",\n \"revision\": \"1b73773905c7665af8d92be86ff7c93c\"\n },\n {\n \"url\": \"assets/class-object.html.a22a09d8.js\",\n \"revision\": \"4cf232e219ad73ed0249959ef8dab224\"\n },\n {\n \"url\": \"assets/class-object.html.c43412d3.js\",\n \"revision\": \"95d854056dbe7d047f22d73d03c0c4bf\"\n },\n {\n \"url\": \"assets/code-init.html.58676afd.js\",\n \"revision\": \"acc4ac90fdef3e8d9aa4ce8a82ceae3f\"\n },\n {\n \"url\": \"assets/code-init.html.70ef628a.js\",\n \"revision\": \"818831e291e49a1121d4867cbbf34e7b\"\n },\n {\n \"url\": \"assets/collection.html.42c40509.js\",\n \"revision\": \"3e9a280a2708f759c09967d7f84b7b1c\"\n },\n {\n \"url\": \"assets/collection.html.e1c47b4b.js\",\n \"revision\": \"26a8766807c7e70d2a9e2554930f097a\"\n },\n {\n \"url\": \"assets/collections.html.2e6479a3.js\",\n \"revision\": \"2a8ef3d4cdfea297d8e08d2e1767a0f6\"\n },\n {\n \"url\": \"assets/collections.html.37777ec8.js\",\n \"revision\": \"74a0523028638b08bc131be57df3af6a\"\n },\n {\n \"url\": \"assets/comparable-omparator.html.1a3bff07.js\",\n \"revision\": \"f3e803b044d4c357a2173e77dca2dd05\"\n },\n {\n \"url\": \"assets/comparable-omparator.html.397dc2ff.js\",\n \"revision\": \"4fc9d5e6efa5df02a669384c67c775c4\"\n },\n {\n \"url\": \"assets/compile-jdk.html.531caac0.js\",\n \"revision\": \"cfb5cd6a34b5696dec2ff5c2cf32665b\"\n },\n {\n \"url\": \"assets/compile-jdk.html.fddb4940.js\",\n \"revision\": \"929c5f27ada1ab44c0da3cd67c1780d0\"\n },\n {\n \"url\": \"assets/computer-base.html.ca77cdaf.js\",\n \"revision\": \"23ed32d0c469a503e711fcbb51e070de\"\n },\n {\n \"url\": \"assets/computer-base.html.f469b424.js\",\n \"revision\": \"1f6ecd345516bff8d501b14e1594704b\"\n },\n {\n \"url\": \"assets/ConcurrentHashMap.html.77d65cc9.js\",\n \"revision\": \"2a3eb940b8d8b2bac223fb97dbbe09fc\"\n },\n {\n \"url\": \"assets/ConcurrentHashMap.html.e7f83c81.js\",\n \"revision\": \"0d28e48bc1568ebab9dcc835e29ba876\"\n },\n {\n \"url\": \"assets/ConcurrentLinkedQueue.html.da4bfec1.js\",\n \"revision\": \"23433f93339dc43427ba24cee5941137\"\n },\n {\n \"url\": \"assets/ConcurrentLinkedQueue.html.f8564dd9.js\",\n \"revision\": \"e21bcb2150039fb7036df909a85f9e08\"\n },\n {\n \"url\": \"assets/condition.html.4a44859a.js\",\n \"revision\": \"ed0cb025b0f9bce6b82ab7a65dfdb70c\"\n },\n {\n \"url\": \"assets/condition.html.a41bdc76.js\",\n \"revision\": \"d7d34d6a2e7d5506b58e1b72264aad0c\"\n },\n {\n \"url\": \"assets/constant-pool.html.81e697ea.js\",\n \"revision\": \"cd016050bb3a5ede4bb1f78d179e756d\"\n },\n {\n \"url\": \"assets/constant-pool.html.c79f5c21.js\",\n \"revision\": \"61e5fe3195c6360d58f87a081108d8b3\"\n },\n {\n \"url\": \"assets/construct.html.0a38a577.js\",\n \"revision\": \"a389eb8410e37a49fdbffcdf7f197f89\"\n },\n {\n \"url\": \"assets/construct.html.5ae3e6eb.js\",\n \"revision\": \"e6248e5666fb845c81737f955adcee8e\"\n },\n {\n \"url\": \"assets/CopyOnWriteArrayList.html.2fa1badd.js\",\n \"revision\": \"d9bc9b1e089216a91befc69530c20daa\"\n },\n {\n \"url\": \"assets/CopyOnWriteArrayList.html.b8e564c2.js\",\n \"revision\": \"f2f383f2d43d94ceccdbe96b2b1c6440\"\n },\n {\n \"url\": \"assets/cors.html.b1e575b3.js\",\n \"revision\": \"8116ced69938f777925c3268adb9bfe3\"\n },\n {\n \"url\": \"assets/cors.html.b8f51585.js\",\n \"revision\": \"7439fe2677e95d97a601cf2a34e91040\"\n },\n {\n \"url\": \"assets/CountDownLatch.html.79c0b80e.js\",\n \"revision\": \"3619d00b6aee569568a30bbd0a77afa3\"\n },\n {\n \"url\": \"assets/CountDownLatch.html.f036fab2.js\",\n \"revision\": \"26b7d176d09b3669f790cd3526ef5132\"\n },\n {\n \"url\": \"assets/cpu-percent-100.html.30d9234e.js\",\n \"revision\": \"f7f5bf5be6fd4ca92e37b482b539e210\"\n },\n {\n \"url\": \"assets/cpu-percent-100.html.f6bd745b.js\",\n \"revision\": \"ad8a7d92c2d6b25c044333bc25f9537a\"\n },\n {\n \"url\": \"assets/csdn-1000wan.html.22ddf17a.js\",\n \"revision\": \"a6214a6bf8e8aea0073c36c8471d2e6d\"\n },\n {\n \"url\": \"assets/csdn-1000wan.html.438218cb.js\",\n \"revision\": \"259561af8e4bdd5fd3e6a009bb23fb74\"\n },\n {\n \"url\": \"assets/daxue-nuli-jisuanji.html.2b1074e1.js\",\n \"revision\": \"269b99461af7c8e4de2b6672a6db1ed6\"\n },\n {\n \"url\": \"assets/daxue-nuli-jisuanji.html.ad13ab16.js\",\n \"revision\": \"6ba002a8a6c21d267f17cb546aacf1cd\"\n },\n {\n \"url\": \"assets/DBeaver.html.16c02541.js\",\n \"revision\": \"432147c6fb5bea87ca0a3021323d9f1c\"\n },\n {\n \"url\": \"assets/DBeaver.html.75fbe8f6.js\",\n \"revision\": \"d453149ad3ea09402d8efd2ec3cbdb5f\"\n },\n {\n \"url\": \"assets/deep-copy.html.1b203746.js\",\n \"revision\": \"506b9406d44b88b4785ff80460f1007b\"\n },\n {\n \"url\": \"assets/deep-copy.html.b367f078.js\",\n \"revision\": \"e0a2406e1b6499e88721b8e21f44c004\"\n },\n {\n \"url\": \"assets/deletedb-binlog-weiguanjishu.html.0dd5fe85.js\",\n \"revision\": \"79b04df8ceabe08cbafaeb5d04f7d5e2\"\n },\n {\n \"url\": \"assets/deletedb-binlog-weiguanjishu.html.605b28a5.js\",\n \"revision\": \"bd5a5b97f531ad34a84c30fb9af6a895\"\n },\n {\n \"url\": \"assets/electron-information-engineering.html.16bd5754.js\",\n \"revision\": \"8b57afa640a9da11164ff4c4f64a4111\"\n },\n {\n \"url\": \"assets/electron-information-engineering.html.6411b062.js\",\n \"revision\": \"d7730e3aaf3c4a3145c07c1c4aa3eea8\"\n },\n {\n \"url\": \"assets/enum.html.21e74b14.js\",\n \"revision\": \"812d1c9d0547cbd890fb5bc8f3cf78e3\"\n },\n {\n \"url\": \"assets/enum.html.637c7ac9.js\",\n \"revision\": \"448da93dff935241a4cda1c544242570\"\n },\n {\n \"url\": \"assets/equals-hashcode.html.033e729f.js\",\n \"revision\": \"9cf97c1f7a4780b063681534f9b0bcf9\"\n },\n {\n \"url\": \"assets/equals-hashcode.html.cd3210fa.js\",\n \"revision\": \"063e16ab8d211c0c61299a99bf635de1\"\n },\n {\n \"url\": \"assets/equals.html.2fb94b25.js\",\n \"revision\": \"46208de98557b94b1aa23d2d106371fb\"\n },\n {\n \"url\": \"assets/equals.html.f7e52978.js\",\n \"revision\": \"bc945798e26b263c822af465deddd663\"\n },\n {\n \"url\": \"assets/fail-fast.html.4b8a884f.js\",\n \"revision\": \"8f5872231ff04b187d0ad54370d91c4b\"\n },\n {\n \"url\": \"assets/fail-fast.html.dca676b6.js\",\n \"revision\": \"756713d835a37e78076e810cc8f8b031\"\n },\n {\n \"url\": \"assets/fanshe.html.13ada7e7.js\",\n \"revision\": \"7b7c5fe2868eee1782f53b121e74b12f\"\n },\n {\n \"url\": \"assets/fanshe.html.e42ba18d.js\",\n \"revision\": \"76a2dd57cce8c3acbcaa914d94568e0b\"\n },\n {\n \"url\": \"assets/fastjson.html.bf5a0ad8.js\",\n \"revision\": \"3ae1af529161b2dfcf73f5f74975a4eb\"\n },\n {\n \"url\": \"assets/fastjson.html.f97ae6fd.js\",\n \"revision\": \"a8326b550ef22ce4e613c3042cae5cb2\"\n },\n {\n \"url\": \"assets/Filter-Interceptor-Listener.html.3a5897a3.js\",\n \"revision\": \"360c10b180b2ca9a1aabd5ff6f1a581b\"\n },\n {\n \"url\": \"assets/Filter-Interceptor-Listener.html.7803e9df.js\",\n \"revision\": \"8a32f4cfd150818a0bab909ce7444428\"\n },\n {\n \"url\": \"assets/final.html.c83d9074.js\",\n \"revision\": \"c726701bca64c1974ecb054822c85377\"\n },\n {\n \"url\": \"assets/final.html.e625665e.js\",\n \"revision\": \"31c6a883281f40da43c0001f8415b852\"\n },\n {\n \"url\": \"assets/flow-control.html.5046ff0c.js\",\n \"revision\": \"4ada85c9151a658cdeff21a4da64c702\"\n },\n {\n \"url\": \"assets/flow-control.html.f6c60ead.js\",\n \"revision\": \"40ec7db6a6132bc01f51bcdbea3fa717\"\n },\n {\n \"url\": \"assets/forest.html.3141000b.js\",\n \"revision\": \"8f3a7a84b28c79f58b273af0173db459\"\n },\n {\n \"url\": \"assets/forest.html.79a7cfed.js\",\n \"revision\": \"5f057f53de7ba5b74e96f1ec60ffb21e\"\n },\n {\n \"url\": \"assets/fork-join.html.e8674cdb.js\",\n \"revision\": \"f99f20ffed6ba458af53398fb0bc06d1\"\n },\n {\n \"url\": \"assets/fork-join.html.f967d485.js\",\n \"revision\": \"26f31bc4133e61588d3e1ab2966e722b\"\n },\n {\n \"url\": \"assets/fumutuanju.html.577491d1.js\",\n \"revision\": \"d2f0d6831711758976a8c940798c4f4f\"\n },\n {\n \"url\": \"assets/fumutuanju.html.ca0f5d88.js\",\n \"revision\": \"a9f7cd91afeb896a244c8d8b6f3b9089\"\n },\n {\n \"url\": \"assets/gailan.html.0ea3f7da.js\",\n \"revision\": \"ffaad458f1c5db7a1297481a8f8005b6\"\n },\n {\n \"url\": \"assets/gailan.html.50f82bf5.js\",\n \"revision\": \"f2a2eb4ef5b853a6b97912f83a8523ca\"\n },\n {\n \"url\": \"assets/gailan.html.87d77185.js\",\n \"revision\": \"838f7f94a9e88620b46b4e6e7a790e1d\"\n },\n {\n \"url\": \"assets/gailan.html.fee068f9.js\",\n \"revision\": \"656821687243257a5d84494525d3219d\"\n },\n {\n \"url\": \"assets/gc.html.714d0f7b.js\",\n \"revision\": \"1abc61c8701406a5ebb447dcf75a4ec9\"\n },\n {\n \"url\": \"assets/gc.html.cec6db87.js\",\n \"revision\": \"818e2a3e352aea0b7dcfee09455162c7\"\n },\n {\n \"url\": \"assets/generic.html.7ec41e80.js\",\n \"revision\": \"2ff01c60d7d59252cfd4d4d55d0467ff\"\n },\n {\n \"url\": \"assets/generic.html.df9c6eb8.js\",\n \"revision\": \"082c06442ae74b2378b87d1d39de8f4a\"\n },\n {\n \"url\": \"assets/git-qiyuan.html.054515ab.js\",\n \"revision\": \"308020a99661a2530c8989e89c509403\"\n },\n {\n \"url\": \"assets/git-qiyuan.html.085fb4bc.js\",\n \"revision\": \"267a7945ca850f4a441212e1a92552fa\"\n },\n {\n \"url\": \"assets/go.html.528d4a75.js\",\n \"revision\": \"0ce9693e8631b976ca6f1a55edae0f70\"\n },\n {\n \"url\": \"assets/go.html.dbab658a.js\",\n \"revision\": \"278fa7f23a08bf0111b3d608469784e9\"\n },\n {\n \"url\": \"assets/gson.html.a359eddd.js\",\n \"revision\": \"13f1ababdf79fd44dc9d36900c7a0d00\"\n },\n {\n \"url\": \"assets/gson.html.e79a454d.js\",\n \"revision\": \"01fedf3f3911791ead09eedd7e5f410a\"\n },\n {\n \"url\": \"assets/guangzhou.html.58700f92.js\",\n \"revision\": \"07c08132e98a5bb9a589884a132be8e4\"\n },\n {\n \"url\": \"assets/guangzhou.html.c44755f8.js\",\n \"revision\": \"bdf0eff158e2ecc338a17d981cf08252\"\n },\n {\n \"url\": \"assets/guava.html.bbc48258.js\",\n \"revision\": \"f29ee74d7b7b8ce3bd03bc072aabf7e2\"\n },\n {\n \"url\": \"assets/guava.html.e73aaedd.js\",\n \"revision\": \"9d698d9f891d7c22f3ac477808b8f998\"\n },\n {\n \"url\": \"assets/haibukuaiyongmybatisplusshoubashoujiaoni.html.4769ffdb.js\",\n \"revision\": \"8b1f46e7be3e7116c325dc37149193ef\"\n },\n {\n \"url\": \"assets/haibukuaiyongmybatisplusshoubashoujiaoni.html.6feacfb3.js\",\n \"revision\": \"93f1f1d514b136a4d4704e9c12011405\"\n },\n {\n \"url\": \"assets/hangzhou.html.52f2ce43.js\",\n \"revision\": \"7723a4ad6abdd887cc602cdbf230936c\"\n },\n {\n \"url\": \"assets/hangzhou.html.a9b39480.js\",\n \"revision\": \"f43ec1548ed8cd34e82a8b5d8973091e\"\n },\n {\n \"url\": \"assets/hashcode.html.24290486.js\",\n \"revision\": \"343281510b0998fa1d048d3c5bf2b144\"\n },\n {\n \"url\": \"assets/hashcode.html.6a0e81d9.js\",\n \"revision\": \"46a0e2cd2db39ca4ef3ab57aff0fa978\"\n },\n {\n \"url\": \"assets/hashmap-interview.html.307a5634.js\",\n \"revision\": \"fe897032d2207465583c5a2783cc6364\"\n },\n {\n \"url\": \"assets/hashmap-interview.html.36f118fd.js\",\n \"revision\": \"64bad08264419e936a82c84cf2647465\"\n },\n {\n \"url\": \"assets/hashmap.html.e3590cbb.js\",\n \"revision\": \"4f977a72e39a337787a9902fde12b2e6\"\n },\n {\n \"url\": \"assets/hashmap.html.f8e12ca4.js\",\n \"revision\": \"64a8ec255cab16b059484b8930e0338e\"\n },\n {\n \"url\": \"assets/hello-world.html.26946542.js\",\n \"revision\": \"8c51974459c33607c8f425f01d22abf1\"\n },\n {\n \"url\": \"assets/hello-world.html.d0d5adf0.js\",\n \"revision\": \"edf374e50da38d8b82c8dad4c5f2a9c9\"\n },\n {\n \"url\": \"assets/highlight.esm.d982e650.js\",\n \"revision\": \"3457767fb4f7fe757ad6fb071f162a85\"\n },\n {\n \"url\": \"assets/history.html.57bb6aeb.js\",\n \"revision\": \"a6ea2f8cf75bca6abe687f5f12ca30aa\"\n },\n {\n \"url\": \"assets/history.html.6df608e4.js\",\n \"revision\": \"edafea3f3bb61548faac24d804cae17c\"\n },\n {\n \"url\": \"assets/home.html.1fffdb8f.js\",\n \"revision\": \"d809ae5f00c553d32c88021c5c455b59\"\n },\n {\n \"url\": \"assets/home.html.25268b5b.js\",\n \"revision\": \"64d92bd8d652d3552ab2a30f2aef3c1c\"\n },\n {\n \"url\": \"assets/how-jvm-run-zijiema-zhiling.html.400c699c.js\",\n \"revision\": \"a1e65b5f2c56245fb14f3e212611d505\"\n },\n {\n \"url\": \"assets/how-jvm-run-zijiema-zhiling.html.f5dbcd2c.js\",\n \"revision\": \"0b4deaf852f5eb8840789c8b2dfad978\"\n },\n {\n \"url\": \"assets/how-run-java-code.html.1867de4d.js\",\n \"revision\": \"5cf492e41232393c8b14781f521b0932\"\n },\n {\n \"url\": \"assets/how-run-java-code.html.5154cace.js\",\n \"revision\": \"9da78cf0ad75ce8adb3f9db0fea9627f\"\n },\n {\n \"url\": \"assets/hsdb.html.4b8d1063.js\",\n \"revision\": \"0f961228688a0ca619b45f75775f73e6\"\n },\n {\n \"url\": \"assets/hsdb.html.e06d55d6.js\",\n \"revision\": \"ad7a87fc50d8515780225b075b58f367\"\n },\n {\n \"url\": \"assets/https-domain.html.81185a29.js\",\n \"revision\": \"6735adc409780df1d219600baba6102b\"\n },\n {\n \"url\": \"assets/https-domain.html.847eb117.js\",\n \"revision\": \"bf28a27b383cee8995274c7489f6c532\"\n },\n {\n \"url\": \"assets/hutool.html.06e72427.js\",\n \"revision\": \"10ab5d7054f66e38c5a99dbed60d31f9\"\n },\n {\n \"url\": \"assets/hutool.html.5bf70ca7.js\",\n \"revision\": \"c8738259a8043d99dc356643a8af822d\"\n },\n {\n \"url\": \"assets/image-yasuo.html.0e3ff54c.js\",\n \"revision\": \"9f6f881e4bb3b94b7e61a7487e2a86a1\"\n },\n {\n \"url\": \"assets/image-yasuo.html.8853b749.js\",\n \"revision\": \"f81cd85d277b957d04fd25be2cabe9df\"\n },\n {\n \"url\": \"assets/immutable.html.36fadfba.js\",\n \"revision\": \"2c68404981e3db1079eaf013a6d08bb4\"\n },\n {\n \"url\": \"assets/immutable.html.aab5b4ed.js\",\n \"revision\": \"491a901473c08c83dc1020708c930a99\"\n },\n {\n \"url\": \"assets/immutable.html.acff64d4.js\",\n \"revision\": \"c550e285d2b7f1918cccfeb819c856f2\"\n },\n {\n \"url\": \"assets/immutable.html.fdd47709.js\",\n \"revision\": \"55e538731a82b55cc7f6e72e291a0844\"\n },\n {\n \"url\": \"assets/index.html.698aa818.js\",\n \"revision\": \"9c38fccd3fc6dbdfc7314582ff98359c\"\n },\n {\n \"url\": \"assets/index.html.96eac070.js\",\n \"revision\": \"4d01170a8705186df15296e8d463d893\"\n },\n {\n \"url\": \"assets/index.html.9c1a7487.js\",\n \"revision\": \"9c3531c49a986fa241f13ae8a1b8be42\"\n },\n {\n \"url\": \"assets/index.html.9ee0e417.js\",\n \"revision\": \"41aa8c21d4af70e4e12b73e21cc88429\"\n },\n {\n \"url\": \"assets/index.html.a4bb5c6e.js\",\n \"revision\": \"98c0a3ad6498080673df4a2c64bbaf8f\"\n },\n {\n \"url\": \"assets/index.html.b90a750c.js\",\n \"revision\": \"b5446123534ec2f5777814813a362858\"\n },\n {\n \"url\": \"assets/index.html.bc31ce34.js\",\n \"revision\": \"fc2bb694151bf0ac25e94e8c9ceeb51a\"\n },\n {\n \"url\": \"assets/index.html.c95125a9.js\",\n \"revision\": \"be60e47a38ed7dcaedc47b72624cc1ec\"\n },\n {\n \"url\": \"assets/index.html.efbaa943.js\",\n \"revision\": \"396d059ce674449e0e1c8cbab9e4bb99\"\n },\n {\n \"url\": \"assets/index.html.fd879420.js\",\n \"revision\": \"7ffb229fbb962ecfa398ce80c7fe95ec\"\n },\n {\n \"url\": \"assets/initializr.html.47ddf572.js\",\n \"revision\": \"e64adae0afad82ea02bdeb579b8f5be8\"\n },\n {\n \"url\": \"assets/initializr.html.8afcbffb.js\",\n \"revision\": \"269861d3115e13d0c7285a2e42b06557\"\n },\n {\n \"url\": \"assets/inner-class.html.858a9fd0.js\",\n \"revision\": \"d2b65b6c7e88bbba4d596c81172ddd60\"\n },\n {\n \"url\": \"assets/inner-class.html.f2dd62ed.js\",\n \"revision\": \"9e4441914142103b191b8443b65259f1\"\n },\n {\n \"url\": \"assets/install-baota-mianban.html.822010d2.js\",\n \"revision\": \"276bbd9dc29a1fc6767713e49d2876c7\"\n },\n {\n \"url\": \"assets/install-baota-mianban.html.fc940506.js\",\n \"revision\": \"38b991a892897e57b412912a14f56b7e\"\n },\n {\n \"url\": \"assets/instanceof-jvm.html.84099ac1.js\",\n \"revision\": \"13cf64169a7f7570b520f07b075559f1\"\n },\n {\n \"url\": \"assets/instanceof-jvm.html.845ed78f.js\",\n \"revision\": \"943acb44bce021b556febc8afee2fdb3\"\n },\n {\n \"url\": \"assets/instanceof.html.d3be3510.js\",\n \"revision\": \"516855dcbfebdd16e0becfbb9bd85955\"\n },\n {\n \"url\": \"assets/instanceof.html.edc709c7.js\",\n \"revision\": \"5d7a30cdc88e64610cd4f9c54269521b\"\n },\n {\n \"url\": \"assets/int-cache.html.0d30900e.js\",\n \"revision\": \"26b2072adfd383782dd52f78abcee302\"\n },\n {\n \"url\": \"assets/int-cache.html.bb142a51.js\",\n \"revision\": \"5887c3796f479978f812cb144a849eac\"\n },\n {\n \"url\": \"assets/interface.html.7833e904.js\",\n \"revision\": \"0843bf51c814ca573607ae40640f3ab4\"\n },\n {\n \"url\": \"assets/interface.html.de30e51e.js\",\n \"revision\": \"fd250ec4307908c1f18024247099ee84\"\n },\n {\n \"url\": \"assets/intern.html.3d87fa6f.js\",\n \"revision\": \"cdb3dcb855cbe196e3c21a87f9bc130b\"\n },\n {\n \"url\": \"assets/intern.html.cb5b47c3.js\",\n \"revision\": \"b9faaa75ca0de583f7cc91a4b42c134b\"\n },\n {\n \"url\": \"assets/ioc.html.1c4cca00.js\",\n \"revision\": \"1a2ed922af9e8cbbed111c0155a3acb5\"\n },\n {\n \"url\": \"assets/ioc.html.a79e951b.js\",\n \"revision\": \"d89ccf3cefa1919274809c410fce14f4\"\n },\n {\n \"url\": \"assets/iterator-iterable.html.7a5374e3.js\",\n \"revision\": \"986c10bdbaeb487a9879f74a46e8e157\"\n },\n {\n \"url\": \"assets/iterator-iterable.html.967b5cf7.js\",\n \"revision\": \"f1abd8a084a08c39689395506befb003\"\n },\n {\n \"url\": \"assets/jackson.html.ded110ad.js\",\n \"revision\": \"b8bb83b89a37fee5fba205945be76cce\"\n },\n {\n \"url\": \"assets/jackson.html.f4471baf.js\",\n \"revision\": \"57e3411f85b93fd8c531a1ee99106eb1\"\n },\n {\n \"url\": \"assets/java-basic-34.html.70be78f8.js\",\n \"revision\": \"237c8c8244c63138dcdf0c90c93ccf04\"\n },\n {\n \"url\": \"assets/java-basic-34.html.c0108ee7.js\",\n \"revision\": \"232e87ffc59aec91ecb20fec451b3ba8\"\n },\n {\n \"url\": \"assets/java-basic.html.34b72317.js\",\n \"revision\": \"5ecf4a33cf14fcca3610083f86d66063\"\n },\n {\n \"url\": \"assets/java-basic.html.52bd7f06.js\",\n \"revision\": \"c3eddf2b32eebe6b50723c9ac936ea4b\"\n },\n {\n \"url\": \"assets/java-mianshi-zhinan.html.9c0ece4d.js\",\n \"revision\": \"291a4f21a5df7a55040cbb02d7d7f015\"\n },\n {\n \"url\": \"assets/java-mianshi-zhinan.html.f1a349c4.js\",\n \"revision\": \"27ed524714e36e6f747e11622961463d\"\n },\n {\n \"url\": \"assets/java-naming.html.1100d2ca.js\",\n \"revision\": \"0cdbea57df887cd24d70a56e28d43794\"\n },\n {\n \"url\": \"assets/java-naming.html.de2604a0.js\",\n \"revision\": \"d0f0b1a247ac19647b2a902effa60733\"\n },\n {\n \"url\": \"assets/java-thread.html.4a99fb0e.js\",\n \"revision\": \"7bbbed0ab8e420e38b4c2732b0814144\"\n },\n {\n \"url\": \"assets/java-thread.html.87abce4b.js\",\n \"revision\": \"5685a8a8992f08d9ab18de33bf3137ad\"\n },\n {\n \"url\": \"assets/java-unicode.html.9e4e93b1.js\",\n \"revision\": \"bd70784e55f2c80f63364553a992eb8b\"\n },\n {\n \"url\": \"assets/java-unicode.html.c63853a0.js\",\n \"revision\": \"669a79673f1a378cbe0e80d138c1cbca\"\n },\n {\n \"url\": \"assets/java.html.8cfce3ac.js\",\n \"revision\": \"9a9ee538241c31f2c0ac88e0f0907fcf\"\n },\n {\n \"url\": \"assets/java.html.9104a10d.js\",\n \"revision\": \"5d1fbc3f94eb92343d78cde14dc18b92\"\n },\n {\n \"url\": \"assets/javadoc.html.435ee8ec.js\",\n \"revision\": \"7798dde0507b72a78857ac4900b757b6\"\n },\n {\n \"url\": \"assets/javadoc.html.b34e8efb.js\",\n \"revision\": \"c31af3f9ce5f9fd518305e3fcdb225f0\"\n },\n {\n \"url\": \"assets/javase.html.4c6f74ba.js\",\n \"revision\": \"ecfbf2388cf8f4c8cf8dc48daab4fe9d\"\n },\n {\n \"url\": \"assets/javase.html.811355dc.js\",\n \"revision\": \"fef28aa68cd1afd5477935b6b0a650e6\"\n },\n {\n \"url\": \"assets/javathread.html.1bcda474.js\",\n \"revision\": \"7f4f00e58b30cfc68de124c2100571b9\"\n },\n {\n \"url\": \"assets/javathread.html.9fc70ce0.js\",\n \"revision\": \"5711f168b6c19372886c558e4c4575b2\"\n },\n {\n \"url\": \"assets/javaxuexidaoshemechengduokeyizhaodiyifengongzuo.html.3289a228.js\",\n \"revision\": \"12d21d02683e4aa784f8c9e41146d8b5\"\n },\n {\n \"url\": \"assets/javaxuexidaoshemechengduokeyizhaodiyifengongzuo.html.6e4f2abd.js\",\n \"revision\": \"df8453e460b559735b578fbedb1ad93b\"\n },\n {\n \"url\": \"assets/jdk-while-for-wuxian-xunhuan.html.a5707bd9.js\",\n \"revision\": \"76facd70dec52ac3e5881829b2fb6b8a\"\n },\n {\n \"url\": \"assets/jdk-while-for-wuxian-xunhuan.html.e352d875.js\",\n \"revision\": \"cfbb94a92733eeb5dc75e736e4271136\"\n },\n {\n \"url\": \"assets/jdk9-char-byte-string.html.884765a3.js\",\n \"revision\": \"cbfb31f9ba066498adb513f0f7ba45fb\"\n },\n {\n \"url\": \"assets/jdk9-char-byte-string.html.e81be44e.js\",\n \"revision\": \"fc680ffbdb61274f773a8c78c167bfcb\"\n },\n {\n \"url\": \"assets/jiagoushizenyanghuizhijitongjiagoulantu.html.980a677a.js\",\n \"revision\": \"e16ace455638e83fe29e4f986fdb9ed5\"\n },\n {\n \"url\": \"assets/jiagoushizenyanghuizhijitongjiagoulantu.html.aafe265c.js\",\n \"revision\": \"a39a5b308c11200a865fc5e6951abab8\"\n },\n {\n \"url\": \"assets/jianli.html.28361c8b.js\",\n \"revision\": \"b26df3f5afa922b44d528cd7329cff48\"\n },\n {\n \"url\": \"assets/jianli.html.2cde4ea0.js\",\n \"revision\": \"71194a48c1d5367fa3f9ae995975032b\"\n },\n {\n \"url\": \"assets/jibenjieshao.html.6a5f31db.js\",\n \"revision\": \"642688e0cb2bbd4702477951d8fa576c\"\n },\n {\n \"url\": \"assets/jibenjieshao.html.b8a08842.js\",\n \"revision\": \"9a038bd09178c6aa49186884410c43ab\"\n },\n {\n \"url\": \"assets/jielehenduosihuodiganchu.html.0ffa8f43.js\",\n \"revision\": \"38131d5037ed9703e9ef9af66411768f\"\n },\n {\n \"url\": \"assets/jielehenduosihuodiganchu.html.576b64a2.js\",\n \"revision\": \"b527d749b4bd825b17a02275fe7e2c65\"\n },\n {\n \"url\": \"assets/jinan.html.95982728.js\",\n \"revision\": \"8bb545a674ac21a6ee8d105fd64047ca\"\n },\n {\n \"url\": \"assets/jinan.html.d4c22f59.js\",\n \"revision\": \"5a29016c0a21263aac901651eeecd017\"\n },\n {\n \"url\": \"assets/jishuzongjianbeikaichuliao.html.1b7e52c1.js\",\n \"revision\": \"16fba1920863afdcfe7142774cbd4425\"\n },\n {\n \"url\": \"assets/jishuzongjianbeikaichuliao.html.6397e62a.js\",\n \"revision\": \"092f54422ef8fe6a017873fea9a42c7c\"\n },\n {\n \"url\": \"assets/jit.html.a14bdfce.js\",\n \"revision\": \"f6d96dbfd5dcf11323c34d5dcc7335fc\"\n },\n {\n \"url\": \"assets/jit.html.cd04156f.js\",\n \"revision\": \"a5ae31399538df2d6198ae259db11d6f\"\n },\n {\n \"url\": \"assets/jmm.html.2560457a.js\",\n \"revision\": \"a06abfac52e7671ca13674aa36e1ef71\"\n },\n {\n \"url\": \"assets/jmm.html.7be72db5.js\",\n \"revision\": \"f110edd5e2f6a34351d4711a3df6e513\"\n },\n {\n \"url\": \"assets/join.html.50d59b6e.js\",\n \"revision\": \"376c267b3a77d18369021e8e46d436b4\"\n },\n {\n \"url\": \"assets/join.html.bb336f49.js\",\n \"revision\": \"42a931af30f514619d1a1efb40c96591\"\n },\n {\n \"url\": \"assets/jpa.html.c491ef74.js\",\n \"revision\": \"59b8e6a2ea59aafe06aa3c4a7ad30317\"\n },\n {\n \"url\": \"assets/jpa.html.cb4e1f80.js\",\n \"revision\": \"3b773ecba585d413510cd3dd8c716b8d\"\n },\n {\n \"url\": \"assets/junit.html.2436284c.js\",\n \"revision\": \"f3af71d5609908b52eef886f9e995418\"\n },\n {\n \"url\": \"assets/junit.html.9c832cdc.js\",\n \"revision\": \"bebfc226fa864bad8eddf161c6b7815e\"\n },\n {\n \"url\": \"assets/jvm.html.1b4e3107.js\",\n \"revision\": \"8f36d3c8758d9fedb2dcea99714dadcd\"\n },\n {\n \"url\": \"assets/jvm.html.375475cb.js\",\n \"revision\": \"6fe0c7a77105af7ef92d0600e7a09448\"\n },\n {\n \"url\": \"assets/jvm.html.49208e4a.js\",\n \"revision\": \"ae588fea19815644b1c028a676055a4b\"\n },\n {\n \"url\": \"assets/jvm.html.c049e00d.js\",\n \"revision\": \"c0592a53f76f0fce0e437013f36ad79b\"\n },\n {\n \"url\": \"assets/jvm.html.cb0eace1.js\",\n \"revision\": \"bbf53c29a2f7000981aede503a5afccc\"\n },\n {\n \"url\": \"assets/jvm.html.dd68f45e.js\",\n \"revision\": \"5a942829e5fa038171516b43c4953270\"\n },\n {\n \"url\": \"assets/jwt.html.2aed3523.js\",\n \"revision\": \"e76f3a16539733fd1bdd8f1274f4fa60\"\n },\n {\n \"url\": \"assets/jwt.html.b4f208bb.js\",\n \"revision\": \"ccd1e1cf1ba2d50e4abd7ee39cd0ae5f\"\n },\n {\n \"url\": \"assets/knife4j.html.4fbb94b8.js\",\n \"revision\": \"e81295e651e26fce78186ee530efe8a2\"\n },\n {\n \"url\": \"assets/knife4j.html.a18b3a85.js\",\n \"revision\": \"e3995f55e02c655c20900b1e5e63065b\"\n },\n {\n \"url\": \"assets/Lambda.html.997b367a.js\",\n \"revision\": \"52eb395fd4e37f0de01811421653e900\"\n },\n {\n \"url\": \"assets/Lambda.html.bd1566d3.js\",\n \"revision\": \"eea28c312cc307db6b11540fa5473737\"\n },\n {\n \"url\": \"assets/lanqiaobei.html.17699093.js\",\n \"revision\": \"5d54156cabbd398cd05a10f3531bb1f1\"\n },\n {\n \"url\": \"assets/lanqiaobei.html.e24944e8.js\",\n \"revision\": \"105b406a2605e7cfd908e370450eb111\"\n },\n {\n \"url\": \"assets/Layout.2f241dd5.js\",\n \"revision\": \"8304c3e5d083d8c2aea7966c9225096e\"\n },\n {\n \"url\": \"assets/learn-jianyi.html.1b72d4e2.js\",\n \"revision\": \"7d563c363a3d4debd307277bf1a00e67\"\n },\n {\n \"url\": \"assets/learn-jianyi.html.2486d715.js\",\n \"revision\": \"671a0284de2c61a77499c33770aa2f5f\"\n },\n {\n \"url\": \"assets/linkedlist.html.8ede144e.js\",\n \"revision\": \"e2adcd892b90191c375cf979328cb124\"\n },\n {\n \"url\": \"assets/linkedlist.html.e021186b.js\",\n \"revision\": \"3d9c4ed38f5d614623bd2b6225a8497e\"\n },\n {\n \"url\": \"assets/linux-codingmore-run.html.6ac5d933.js\",\n \"revision\": \"8c505e7c59609f7f2fa3abb9102f9f7a\"\n },\n {\n \"url\": \"assets/linux-codingmore-run.html.d96d85b1.js\",\n \"revision\": \"5740c246775c5cdc78359f921d26eedd\"\n },\n {\n \"url\": \"assets/list-war-2.html.4306ceaf.js\",\n \"revision\": \"4614b86ad0b9063c13357295f2728036\"\n },\n {\n \"url\": \"assets/list-war-2.html.b8fa44fb.js\",\n \"revision\": \"cf2ab3c2e799ec10f657d9e2f4dfb65a\"\n },\n {\n \"url\": \"assets/lock.html.5385ecc8.js\",\n \"revision\": \"894e93c8012594ae038f4cd857ff50af\"\n },\n {\n \"url\": \"assets/lock.html.707d5244.js\",\n \"revision\": \"c4ff30cabea577f06cbcc00a6018a134\"\n },\n {\n \"url\": \"assets/LockSupport.html.5ea98b89.js\",\n \"revision\": \"572b7ed89410d5b2483ad25a829d0179\"\n },\n {\n \"url\": \"assets/LockSupport.html.c7d00cfa.js\",\n \"revision\": \"86fdd35f48637ac9a5971fb6e44211d5\"\n },\n {\n \"url\": \"assets/log4j.html.0b4fd542.js\",\n \"revision\": \"b9e30456bef646a1702caff5695777f2\"\n },\n {\n \"url\": \"assets/log4j.html.14af993a.js\",\n \"revision\": \"fa18ccbd6f734f1b12871ec7f9101f6f\"\n },\n {\n \"url\": \"assets/log4j2.html.066d10f7.js\",\n \"revision\": \"46389b220e18124b0d5055c18c74974d\"\n },\n {\n \"url\": \"assets/log4j2.html.9b5a6f13.js\",\n \"revision\": \"74f7162c5d876ef41a09955483435f9e\"\n },\n {\n \"url\": \"assets/log4j2.html.b3fd06a7.js\",\n \"revision\": \"88ff3344444cc2680ddf3e4964c09932\"\n },\n {\n \"url\": \"assets/log4j2.html.d1682823.js\",\n \"revision\": \"392b5f6e36b164ce2f6c315b2089c38c\"\n },\n {\n \"url\": \"assets/logback.html.28ab1df5.js\",\n \"revision\": \"408757b6fbc3d0bbf7246c98de577994\"\n },\n {\n \"url\": \"assets/logback.html.806b8b11.js\",\n \"revision\": \"04c0f7ede5cb1f3a0da739ad154d31b7\"\n },\n {\n \"url\": \"assets/logback.html.a9628274.js\",\n \"revision\": \"5f741c93179b5d8653029776f2026245\"\n },\n {\n \"url\": \"assets/logback.html.ce19f5e4.js\",\n \"revision\": \"b760fa26c3bb5fe9fd6099bdd0dc66a2\"\n },\n {\n \"url\": \"assets/macos-codingmore-run.html.100361aa.js\",\n \"revision\": \"f6780c87ed575010cf5483fa53bedd45\"\n },\n {\n \"url\": \"assets/macos-codingmore-run.html.f9eb5e90.js\",\n \"revision\": \"65ac7cb80f7fc73e7c725acffb01d60a\"\n },\n {\n \"url\": \"assets/map.html.6ee85b94.js\",\n \"revision\": \"837fed237def3e30bb0cd2aef910dd27\"\n },\n {\n \"url\": \"assets/map.html.ae80f8e6.js\",\n \"revision\": \"4caefbc89b1e006c195441565f03be8c\"\n },\n {\n \"url\": \"assets/markdown.esm.832a189d.js\",\n \"revision\": \"4aa467006f9d51cf40293b9b69a0f27a\"\n },\n {\n \"url\": \"assets/math.esm.a3f84b6f.js\",\n \"revision\": \"cbf844f27edbc061c86ae840d70389f6\"\n },\n {\n \"url\": \"assets/maven.html.abe414c5.js\",\n \"revision\": \"076fa6654bcdb82ab1f5d1713ee11a4e\"\n },\n {\n \"url\": \"assets/maven.html.d13a0dbf.js\",\n \"revision\": \"9ce0de892e93f26a9ffea8cef2164c24\"\n },\n {\n \"url\": \"assets/meituan-9-gc.html.7173ffd4.js\",\n \"revision\": \"fe8fa6b143a3dbc5735542403249c11e\"\n },\n {\n \"url\": \"assets/meituan-9-gc.html.f5a5b89a.js\",\n \"revision\": \"244a3f55b6939ca3553511b02032c9dd\"\n },\n {\n \"url\": \"assets/method.html.1f147cbd.js\",\n \"revision\": \"1c99a665cd5628faa625183fba4fcf36\"\n },\n {\n \"url\": \"assets/method.html.4d951864.js\",\n \"revision\": \"561b699c5536ab7660ef94c27166a830\"\n },\n {\n \"url\": \"assets/mybatis.html.41ff93f4.js\",\n \"revision\": \"d9c8df8bd36f2f55b36e8358447306fd\"\n },\n {\n \"url\": \"assets/mybatis.html.7c33d756.js\",\n \"revision\": \"64a1c8c0d21437565c6f4ed7e5b6adff\"\n },\n {\n \"url\": \"assets/mysql-druid.html.1c47eb57.js\",\n \"revision\": \"1a9d22afa107c770c66615a38b97f6ac\"\n },\n {\n \"url\": \"assets/mysql-druid.html.9707dc06.js\",\n \"revision\": \"03e85b61f41594ca8ac3433433f3da81\"\n },\n {\n \"url\": \"assets/mysql.html.1afcd596.js\",\n \"revision\": \"c0ad6261090ab4fd3debd9d30e5e14fb\"\n },\n {\n \"url\": \"assets/mysql.html.99fca397.js\",\n \"revision\": \"f74dbe6f78163ad33b0c9a819ebfc3ca\"\n },\n {\n \"url\": \"assets/nanjing.html.099e9844.js\",\n \"revision\": \"260596f3179d1eed861e1288208be92e\"\n },\n {\n \"url\": \"assets/nanjing.html.44d630fa.js\",\n \"revision\": \"3d25b3c20c05461b274c1cfddecb5d40\"\n },\n {\n \"url\": \"assets/neicun-jiegou.html.f0fca3bb.js\",\n \"revision\": \"6daf0b5605744cbaf3254818812ac171\"\n },\n {\n \"url\": \"assets/neicun-jiegou.html.fee2587a.js\",\n \"revision\": \"cc35a0899ec5029bdecd24422d3a5200\"\n },\n {\n \"url\": \"assets/nginx-setting.html.3934a533.js\",\n \"revision\": \"f98408b462ec69cb20f92d9cdff09464\"\n },\n {\n \"url\": \"assets/nginx-setting.html.68b3250b.js\",\n \"revision\": \"36daa9eff3e0f65428f051701d26f283\"\n },\n {\n \"url\": \"assets/nginx.html.25ed8525.js\",\n \"revision\": \"6db7667d5f4d25d414e14d21a35f76bf\"\n },\n {\n \"url\": \"assets/nginx.html.baa53af7.js\",\n \"revision\": \"cac80db53f25790ef648e13b4e453d30\"\n },\n {\n \"url\": \"assets/nicearticle.html.4730077f.js\",\n \"revision\": \"e334ce4fce0b951d1515dcdffac5640d\"\n },\n {\n \"url\": \"assets/nicearticle.html.b56e678a.js\",\n \"revision\": \"e7e94ff20e83310751fc0c814a6b1e7c\"\n },\n {\n \"url\": \"assets/nixi.html.c022f9fe.js\",\n \"revision\": \"045fae1de49d81b344c5fb968595c21b\"\n },\n {\n \"url\": \"assets/nixi.html.de6f9361.js\",\n \"revision\": \"fb143508dcc92a8f2c24c0f5bd222b45\"\n },\n {\n \"url\": \"assets/notes.esm.3c361cb7.js\",\n \"revision\": \"eda65c99450fe02da90bde90cc614a56\"\n },\n {\n \"url\": \"assets/npe.html.297684ef.js\",\n \"revision\": \"f34420e5e61e95f975372be39e71a808\"\n },\n {\n \"url\": \"assets/npe.html.a94a2b73.js\",\n \"revision\": \"66e85fa3c9bd617e71aef72c2fc50721\"\n },\n {\n \"url\": \"assets/object-class.html.698d849f.js\",\n \"revision\": \"c52eb91b6d96a7d3f8354fd3eae42715\"\n },\n {\n \"url\": \"assets/object-class.html.85420110.js\",\n \"revision\": \"bc2a562c613c3bb7f2f64d53055c00b4\"\n },\n {\n \"url\": \"assets/oom.html.23228526.js\",\n \"revision\": \"0ac9680baff3b41388b27b97b55c779a\"\n },\n {\n \"url\": \"assets/oom.html.cbfa1fb6.js\",\n \"revision\": \"557f65b3ef7e34e159c07edbbf356171\"\n },\n {\n \"url\": \"assets/operator.html.152cf4bc.js\",\n \"revision\": \"034fe53f2cbba60dd6774374cbf7cb55\"\n },\n {\n \"url\": \"assets/operator.html.9431d9fc.js\",\n \"revision\": \"dd2606884797f6115086577981cdf630\"\n },\n {\n \"url\": \"assets/optional.html.23c0a140.js\",\n \"revision\": \"841574f000bebb802ad9b5fb7622fb98\"\n },\n {\n \"url\": \"assets/optional.html.775157f3.js\",\n \"revision\": \"54e19ed9dd841ae5c31dc18f35b22941\"\n },\n {\n \"url\": \"assets/os.html.1d208877.js\",\n \"revision\": \"d6ea19295d438cb210377fd3b8fcebef\"\n },\n {\n \"url\": \"assets/os.html.34768944.js\",\n \"revision\": \"2a3c72e94e5fea9ccc7c3521fd120a18\"\n },\n {\n \"url\": \"assets/os.html.5e6a959a.js\",\n \"revision\": \"0d3240c88a18a8d4ba5ab1f0deb2ed9f\"\n },\n {\n \"url\": \"assets/os.html.781c26b2.js\",\n \"revision\": \"fcf329f5df93c283630362191cf85aeb\"\n },\n {\n \"url\": \"assets/oss.html.8b1ce1ec.js\",\n \"revision\": \"2a579ce6c8ff22b07221e05c326669a0\"\n },\n {\n \"url\": \"assets/oss.html.e3216442.js\",\n \"revision\": \"f478455fa6bb9bd76597cdea808244ea\"\n },\n {\n \"url\": \"assets/others.html.63b5af1f.js\",\n \"revision\": \"7a32a3369509ef63ce3b444ebb411118\"\n },\n {\n \"url\": \"assets/others.html.ed8fcf05.js\",\n \"revision\": \"e6fd1a8c5da4b15d4670159a24ef9506\"\n },\n {\n \"url\": \"assets/override-overload.html.1c9aaf26.js\",\n \"revision\": \"22a791e22c920f9708385a97a173476c\"\n },\n {\n \"url\": \"assets/override-overload.html.f7d74176.js\",\n \"revision\": \"3ee9ca1d6b6aefe5fb57084f0cc15e15\"\n },\n {\n \"url\": \"assets/Overriding.html.14f830f8.js\",\n \"revision\": \"782d5974e1b4f6d2acc30324bd737ad1\"\n },\n {\n \"url\": \"assets/Overriding.html.d8235770.js\",\n \"revision\": \"b9d59dbe8977046d7f3b77b8db8582ad\"\n },\n {\n \"url\": \"assets/pass-by-value.html.cf8023d5.js\",\n \"revision\": \"51748cf216f6de59f32ef703ef641d0d\"\n },\n {\n \"url\": \"assets/pass-by-value.html.e26c3cdc.js\",\n \"revision\": \"3010545820acbe8927e256f4ae13fecd\"\n },\n {\n \"url\": \"assets/pdf.html.79c228f5.js\",\n \"revision\": \"bcb0a579db98a5d402c588741d592d85\"\n },\n {\n \"url\": \"assets/pdf.html.a28195f1.js\",\n \"revision\": \"2878368c7793e0fab9367fd05c73e020\"\n },\n {\n \"url\": \"assets/photoswipe.esm.92018b73.js\",\n \"revision\": \"442a3264b1db7eb84ffc880407e7565d\"\n },\n {\n \"url\": \"assets/plugin-vue_export-helper.21dcd24c.js\",\n \"revision\": \"b29b145139fc88e89a46af507277557d\"\n },\n {\n \"url\": \"assets/pool.html.1918e02b.js\",\n \"revision\": \"837fd39732d9eb3df1e143bd77b9e1cb\"\n },\n {\n \"url\": \"assets/pool.html.7274870a.js\",\n \"revision\": \"744d526c3827d84eb1fedfe20f459576\"\n },\n {\n \"url\": \"assets/print.html.4135561a.js\",\n \"revision\": \"c5f91f379b8e7d36e0c2a19e4f8c1ac5\"\n },\n {\n \"url\": \"assets/print.html.6fe8360d.js\",\n \"revision\": \"7a5cd0b01b2c354dccd58c55ccc7af88\"\n },\n {\n \"url\": \"assets/problem-tools.html.c0e0819e.js\",\n \"revision\": \"acb5a33c88833eadf8cac3018054aaca\"\n },\n {\n \"url\": \"assets/problem-tools.html.fab08888.js\",\n \"revision\": \"8abd2eb80f2525872d9d8f8d2480a0d2\"\n },\n {\n \"url\": \"assets/progit.html.284a6498.js\",\n \"revision\": \"ef6f0f435bc317320968befbe3677cb0\"\n },\n {\n \"url\": \"assets/progit.html.95158ac7.js\",\n \"revision\": \"36b37c641df735698d5e48e97a93e10d\"\n },\n {\n \"url\": \"assets/progit.html.a119468c.js\",\n \"revision\": \"ff8fc203f93f6c67a16915eb0c9b6659\"\n },\n {\n \"url\": \"assets/progit.html.df477a55.js\",\n \"revision\": \"72b64f8670a1b79e9a8c6258c25a644d\"\n },\n {\n \"url\": \"assets/python.html.6ba47e37.js\",\n \"revision\": \"c5282276586042c86148f9cf3caef564\"\n },\n {\n \"url\": \"assets/python.html.a467fb74.js\",\n \"revision\": \"73ccde0eecc64ad7696411f289412dce\"\n },\n {\n \"url\": \"assets/qianduan.html.61a4f111.js\",\n \"revision\": \"80491ad5e938d271d8cd2be59f02e2fb\"\n },\n {\n \"url\": \"assets/qianduan.html.ef57d5d5.js\",\n \"revision\": \"71f054a948e371176c1b0b90159a69a1\"\n },\n {\n \"url\": \"assets/qingdao.html.826f4cb2.js\",\n \"revision\": \"5a4f3a9855d2bc27049e9cd9a16b10bb\"\n },\n {\n \"url\": \"assets/qingdao.html.c4a4c2c4.js\",\n \"revision\": \"e73ea57aaf951c40c0dc06c4adf0cc12\"\n },\n {\n \"url\": \"assets/rabbitmq-rumen.html.1f0066c6.js\",\n \"revision\": \"67e3b3b57c9a055c1f7ddd6a077fd788\"\n },\n {\n \"url\": \"assets/rabbitmq-rumen.html.5bf7bc58.js\",\n \"revision\": \"91b8c4c9ce8a4614f95e26e2e0f17f18\"\n },\n {\n \"url\": \"assets/read-csapp.html.768012b7.js\",\n \"revision\": \"a6363af149e24bc7b4dd9162161e726c\"\n },\n {\n \"url\": \"assets/read-csapp.html.c0e758ea.js\",\n \"revision\": \"b966877b6d1aab734ae853babf191dbf\"\n },\n {\n \"url\": \"assets/record-domain.html.3a82f73e.js\",\n \"revision\": \"937ad5182d910144e272c75aa29177dd\"\n },\n {\n \"url\": \"assets/record-domain.html.667d7982.js\",\n \"revision\": \"e6d8405b67a89e4ab26245a177550252\"\n },\n {\n \"url\": \"assets/redis-shuju-yizhixing.html.0d2d7824.js\",\n \"revision\": \"af7f27a164f234c07500ae1210fe53bf\"\n },\n {\n \"url\": \"assets/redis-shuju-yizhixing.html.480d5fea.js\",\n \"revision\": \"0e298ffaa13403ee710eb1db2d5d5665\"\n },\n {\n \"url\": \"assets/redis-springboot.html.3faa6adc.js\",\n \"revision\": \"2a8a407124af8dcb1bf76ae390ac7706\"\n },\n {\n \"url\": \"assets/redis-springboot.html.44044d02.js\",\n \"revision\": \"cfa6b26eb76aa5b720c5c0c123cab248\"\n },\n {\n \"url\": \"assets/redis.html.b039ba47.js\",\n \"revision\": \"250ee45056172fee92c332e9bb8f2fdf\"\n },\n {\n \"url\": \"assets/redis.html.bcbe4235.js\",\n \"revision\": \"09e244b1960ac2f1463c2481bfc90cf4\"\n },\n {\n \"url\": \"assets/redis12question.html.58f0e7e0.js\",\n \"revision\": \"1ca878de7522dd7bd5f7d4780449386b\"\n },\n {\n \"url\": \"assets/redis12question.html.f0270e84.js\",\n \"revision\": \"600dc76e4c00eda1f2b3e84ad2e2c223\"\n },\n {\n \"url\": \"assets/reentrantLock.html.002f84e4.js\",\n \"revision\": \"475486341b8257def0a182f7945de2b6\"\n },\n {\n \"url\": \"assets/reentrantLock.html.8b519bdc.js\",\n \"revision\": \"e8241c5b308baa417992c4657f61a400\"\n },\n {\n \"url\": \"assets/ReentrantReadWriteLock.html.140f1c3e.js\",\n \"revision\": \"ac3dc90c553309bcb8767717a01b77d6\"\n },\n {\n \"url\": \"assets/ReentrantReadWriteLock.html.d1bd972f.js\",\n \"revision\": \"95da940d4221ddc04eec2e3b5ae8996f\"\n },\n {\n \"url\": \"assets/reveal.esm.b96f05d8.js\",\n \"revision\": \"f78a424fad98faac5d5ca8ebfbebe94b\"\n },\n {\n \"url\": \"assets/rumen.html.27e01d35.js\",\n \"revision\": \"a511f6c5f6172908f99e5000521404bc\"\n },\n {\n \"url\": \"assets/rumen.html.28382740.js\",\n \"revision\": \"bbb73cc8ff60526c113c7b1d16cc8eaf\"\n },\n {\n \"url\": \"assets/rumen.html.3f2b5ec9.js\",\n \"revision\": \"a1e6645af910fa32a8eb130d14e8eddb\"\n },\n {\n \"url\": \"assets/rumen.html.9cc17590.js\",\n \"revision\": \"d296a715b51d7987e19356f118decea2\"\n },\n {\n \"url\": \"assets/rumen.html.e13dbda5.js\",\n \"revision\": \"9f529477271a37fdf0fbaec594e6d279\"\n },\n {\n \"url\": \"assets/rumen.html.ee21a790.js\",\n \"revision\": \"ec7bcc5e5e477600686051e08466b86f\"\n },\n {\n \"url\": \"assets/ScheduledThreadPoolExecutor.html.73744e7a.js\",\n \"revision\": \"f220816aaef20fc0ac9946b6d31af4bf\"\n },\n {\n \"url\": \"assets/ScheduledThreadPoolExecutor.html.8d668046.js\",\n \"revision\": \"b29b0a101162737afa347106c650739f\"\n },\n {\n \"url\": \"assets/search.esm.80da4a02.js\",\n \"revision\": \"690b84c66badd2f8fa69d57bc7cdad19\"\n },\n {\n \"url\": \"assets/shanganaliyun.html.04eee07a.js\",\n \"revision\": \"f74774689b9aa40eb6a262a3cc4e9ae6\"\n },\n {\n \"url\": \"assets/shanganaliyun.html.802605a1.js\",\n \"revision\": \"bf2a7abff579a4b1982b65c3ef81e0c6\"\n },\n {\n \"url\": \"assets/shangtou.html.d25e4bab.js\",\n \"revision\": \"805f1501299b1edd864368e95c7cd7c1\"\n },\n {\n \"url\": \"assets/shangtou.html.dd79a90f.js\",\n \"revision\": \"e491b924cd35190389b7819a21f19b1c\"\n },\n {\n \"url\": \"assets/shengchanzhe-xiaofeizhe.html.0915b865.js\",\n \"revision\": \"ee8bb756f0323bf506becbb4280e574f\"\n },\n {\n \"url\": \"assets/shengchanzhe-xiaofeizhe.html.b76e11fd.js\",\n \"revision\": \"b20f5f14c425c8cd1fb12a8fd5f11d6a\"\n },\n {\n \"url\": \"assets/shenzhen.html.61178979.js\",\n \"revision\": \"2f58532175c0e9944a3da199bee0416b\"\n },\n {\n \"url\": \"assets/shenzhen.html.98e7f6e9.js\",\n \"revision\": \"97da1d26f3b24c007c6e7d9fabc39484\"\n },\n {\n \"url\": \"assets/shijian.html.0924a1ec.js\",\n \"revision\": \"326c95b32e23cf74836881972d518432\"\n },\n {\n \"url\": \"assets/shijian.html.d1dfaaba.js\",\n \"revision\": \"75662f0d9b3a3eb59e65cdb011ac3534\"\n },\n {\n \"url\": \"assets/SkipLink.a2c3a90f.js\",\n \"revision\": \"7c17b4281e8dc33f75ea9e355ed48a3a\"\n },\n {\n \"url\": \"assets/slf4j.html.2fd3dca6.js\",\n \"revision\": \"c2fc64d88ebde1e5685aabe77a9ac3c1\"\n },\n {\n \"url\": \"assets/slf4j.html.f772534d.js\",\n \"revision\": \"d519cb199feeb1661cb0bb7c64c1ae63\"\n },\n {\n \"url\": \"assets/Slide.39e63deb.js\",\n \"revision\": \"7cc031de25acac5f5e36a181475e3a0d\"\n },\n {\n \"url\": \"assets/split.html.0ff2ce60.js\",\n \"revision\": \"782e517f1be73a462dbb3572b55d8b68\"\n },\n {\n \"url\": \"assets/split.html.b69d2cd1.js\",\n \"revision\": \"98d0fdc5ae0f62d9de6a7aaa6838410f\"\n },\n {\n \"url\": \"assets/spring.html.40b7b2ff.js\",\n \"revision\": \"b609dae395c92a166bc41aee4e7b51bb\"\n },\n {\n \"url\": \"assets/spring.html.75b19ea2.js\",\n \"revision\": \"ce83e6c73d54a4eb2d2be0d6b78add4d\"\n },\n {\n \"url\": \"assets/springtask.html.04deb6a0.js\",\n \"revision\": \"79726149afec024f359dc783dc39aa3c\"\n },\n {\n \"url\": \"assets/springtask.html.6f8efcf6.js\",\n \"revision\": \"d6db8b09832b8485e9d63f7c7262706f\"\n },\n {\n \"url\": \"assets/static.html.1a009c06.js\",\n \"revision\": \"3d3bdf938d69191f52064821d34cda66\"\n },\n {\n \"url\": \"assets/static.html.c9732093.js\",\n \"revision\": \"968f3bdfc954039ba6a67d9440ed75ba\"\n },\n {\n \"url\": \"assets/stream.html.02d08777.js\",\n \"revision\": \"bd6b5a8e735b3700733b69640c4a807b\"\n },\n {\n \"url\": \"assets/stream.html.214aab27.js\",\n \"revision\": \"02b20169ec8176d859a10ee4b41683b8\"\n },\n {\n \"url\": \"assets/style.aa7884a9.css\",\n \"revision\": \"b50231da484889a39c0d651cca018162\"\n },\n {\n \"url\": \"assets/suzhou.html.428c3730.js\",\n \"revision\": \"a9ddf78eaac3ba6158593f0abb45799f\"\n },\n {\n \"url\": \"assets/suzhou.html.b2ed5bbc.js\",\n \"revision\": \"ad6b7c2e3bc4ccec8f0df69b0244e82c\"\n },\n {\n \"url\": \"assets/swagger.html.1142f08f.js\",\n \"revision\": \"402a89ba70a79688243b2e02b71f33bc\"\n },\n {\n \"url\": \"assets/swagger.html.e13d1880.js\",\n \"revision\": \"a113ed5764a0ee922db84f0edf6fa01b\"\n },\n {\n \"url\": \"assets/synchronized.html.0249091e.js\",\n \"revision\": \"0efb9296805b3b1f82608783a3bdb980\"\n },\n {\n \"url\": \"assets/synchronized.html.6094d556.js\",\n \"revision\": \"50bb92e6064fb1eeace2b8badcce12ec\"\n },\n {\n \"url\": \"assets/tabby.html.8b43d084.js\",\n \"revision\": \"fede60fdff4466bc0faa5a7c3f40a97e\"\n },\n {\n \"url\": \"assets/tabby.html.c3b44c08.js\",\n \"revision\": \"c81b9570dd8d07ca19fe54488d0c9820\"\n },\n {\n \"url\": \"assets/this-super.html.65fa5da3.js\",\n \"revision\": \"db3b96963f5594951739fe2924632a42\"\n },\n {\n \"url\": \"assets/this-super.html.ff84e809.js\",\n \"revision\": \"d52d1026b3cc4f6b8385b6150fcb859f\"\n },\n {\n \"url\": \"assets/thread-bring-some-problem.html.891141f3.js\",\n \"revision\": \"f6c29adc867ff6055c6389e5cc6f7a2b\"\n },\n {\n \"url\": \"assets/thread-bring-some-problem.html.c8ae3e7a.js\",\n \"revision\": \"d30408042adbdeca4ce50a59c6901032\"\n },\n {\n \"url\": \"assets/thread-group-and-thread-priority.html.777c962b.js\",\n \"revision\": \"aaf93443fed92c2a2c1b33c8f25950cf\"\n },\n {\n \"url\": \"assets/thread-group-and-thread-priority.html.873709ce.js\",\n \"revision\": \"4e54397c857c1341cd41f1cfff69ebb1\"\n },\n {\n \"url\": \"assets/thread-state-and-method.html.70b8e2e8.js\",\n \"revision\": \"99fbdee5498a36cf4161dea3e2aebd57\"\n },\n {\n \"url\": \"assets/thread-state-and-method.html.a816be26.js\",\n \"revision\": \"80d24fe42475ee6ee78ce1986764ea82\"\n },\n {\n \"url\": \"assets/thread.html.34ab4613.js\",\n \"revision\": \"1ed2cba245361944bd4249f6f3efe4fd\"\n },\n {\n \"url\": \"assets/thread.html.4fcef02c.js\",\n \"revision\": \"73676ab811effc7ca8466789ef3325bc\"\n },\n {\n \"url\": \"assets/ThreadLocal.html.2993d4fd.js\",\n \"revision\": \"1d04492707df70770666d10cb1d17b8d\"\n },\n {\n \"url\": \"assets/ThreadLocal.html.f9a6fed8.js\",\n \"revision\": \"e5f398cec6e9663ba5b58fe6a2a1ba63\"\n },\n {\n \"url\": \"assets/thymeleaf.html.943910b5.js\",\n \"revision\": \"a7a28429dce19f8027435507cbc57929\"\n },\n {\n \"url\": \"assets/thymeleaf.html.b2ef505e.js\",\n \"revision\": \"0e388a370a0ad657e60ba4ee5b47aeab\"\n },\n {\n \"url\": \"assets/tobebetterjavaer-wangzhan-shangxian.html.a80895d2.js\",\n \"revision\": \"1023c6d0dadb6420952b89fd749a6adc\"\n },\n {\n \"url\": \"assets/tobebetterjavaer-wangzhan-shangxian.html.eb4a3068.js\",\n \"revision\": \"0dfa3ae0bf98341875631534988ca34b\"\n },\n {\n \"url\": \"assets/tomcat.html.73ec3645.js\",\n \"revision\": \"7a7b107c1633a13d2190549cb6e03310\"\n },\n {\n \"url\": \"assets/tomcat.html.af3e6ee8.js\",\n \"revision\": \"cbda5ecb3fe9d3df6734f1bd0f403b7a\"\n },\n {\n \"url\": \"assets/transaction.html.1d6a1548.js\",\n \"revision\": \"a63bad9390bb54bf489b53e21f4c2dd5\"\n },\n {\n \"url\": \"assets/transaction.html.9982a65f.js\",\n \"revision\": \"a05d82344f35ba095b68c0cb7171933e\"\n },\n {\n \"url\": \"assets/true-generic.html.a683e7b2.js\",\n \"revision\": \"05dc4400bf38521b7ae923ac45277317\"\n },\n {\n \"url\": \"assets/true-generic.html.ce09d792.js\",\n \"revision\": \"7b33c1c5dbde75dd4deedd61ff4ffbb0\"\n },\n {\n \"url\": \"assets/try-with-resouces.html.52a831d4.js\",\n \"revision\": \"424a42ea24d029ae216cb9c41fa74e6f\"\n },\n {\n \"url\": \"assets/try-with-resouces.html.8dcef913.js\",\n \"revision\": \"7803c62919343844326660cb01e85fd9\"\n },\n {\n \"url\": \"assets/tujie-gc.html.3ec6a37b.js\",\n \"revision\": \"413aba6dc2daf9e9bd2013114cb17ed7\"\n },\n {\n \"url\": \"assets/tujie-gc.html.ca2dffab.js\",\n \"revision\": \"a7928789b0d96cef153aaf643807441e\"\n },\n {\n \"url\": \"assets/tupian-zhuanlian.html.7ab13c07.js\",\n \"revision\": \"11bbf9bb17b695c73038945d2d3ff5e3\"\n },\n {\n \"url\": \"assets/tupian-zhuanlian.html.cc248511.js\",\n \"revision\": \"67d582065436fe31c14e0bf91e5ac931\"\n },\n {\n \"url\": \"assets/var.html.6e7f16a9.js\",\n \"revision\": \"fcb3f82378d0cdc042066452ab0572b9\"\n },\n {\n \"url\": \"assets/var.html.7a0cfd0f.js\",\n \"revision\": \"44e56a632667ab8dc6fda19d2e951b8a\"\n },\n {\n \"url\": \"assets/varables.html.3f84ac76.js\",\n \"revision\": \"65b5434110402fac647879544d65adaa\"\n },\n {\n \"url\": \"assets/varables.html.6a80fc0e.js\",\n \"revision\": \"b5d838edc69034b99358140c53b3dacb\"\n },\n {\n \"url\": \"assets/volatile.html.26279f7f.js\",\n \"revision\": \"8b7c26f79da9fab23d11327674fb4d5e\"\n },\n {\n \"url\": \"assets/volatile.html.4f34c8de.js\",\n \"revision\": \"3f2dce960dbb5cfaccdb33226e081581\"\n },\n {\n \"url\": \"assets/waibao-1geyue.html.31a36346.js\",\n \"revision\": \"cee888b3465be2dd6d68694dc6793192\"\n },\n {\n \"url\": \"assets/waibao-1geyue.html.fbddc89c.js\",\n \"revision\": \"e015d6b16e709b6ccb97dce4163bb984\"\n },\n {\n \"url\": \"assets/wangluo.html.b41cb57f.js\",\n \"revision\": \"57732b795849149a6667300feb6a38da\"\n },\n {\n \"url\": \"assets/wangluo.html.bf2e0885.js\",\n \"revision\": \"c538dbc8a3dfeae6b57e2ca2604db68c\"\n },\n {\n \"url\": \"assets/wangzhe-thread.html.752a4836.js\",\n \"revision\": \"076f9ce43e6e8e0f88c214c918ca40f0\"\n },\n {\n \"url\": \"assets/wangzhe-thread.html.dda72253.js\",\n \"revision\": \"a93511501818791c302deaac765b4e15\"\n },\n {\n \"url\": \"assets/warp.html.4380b228.js\",\n \"revision\": \"1c7cd7539426cb69c99eefa6ad943b27\"\n },\n {\n \"url\": \"assets/warp.html.8ae8cc83.js\",\n \"revision\": \"99a539d31ad52d3991e0bb0d24113f7e\"\n },\n {\n \"url\": \"assets/weixin-bagwpdf.html.a32b4b3a.js\",\n \"revision\": \"77ab2bd1cd9b2019c156c83b89a74419\"\n },\n {\n \"url\": \"assets/weixin-bagwpdf.html.e485fe14.js\",\n \"revision\": \"7ed33ecaf7d743517285fb8573acfe11\"\n },\n {\n \"url\": \"assets/weixin-chengxwjdwzhqcgxm.html.18dc866d.js\",\n \"revision\": \"b566da699481353a4ad2423995f7d8eb\"\n },\n {\n \"url\": \"assets/weixin-chengxwjdwzhqcgxm.html.5c788b1b.js\",\n \"revision\": \"612bf1b6a51320c24d60912c479e1be6\"\n },\n {\n \"url\": \"assets/weixin-githubxbkdjavajccjyh.html.11c03a69.js\",\n \"revision\": \"f5f9cb416746799870bafd61c9085196\"\n },\n {\n \"url\": \"assets/weixin-githubxbkdjavajccjyh.html.be4183ae.js\",\n \"revision\": \"fd1c1112078fbc8ef0041114686ce158\"\n },\n {\n \"url\": \"assets/weixin-liaoliaoxianliu.html.624e17ae.js\",\n \"revision\": \"6f5c07a29b2398416dfc5164c9f08d11\"\n },\n {\n \"url\": \"assets/weixin-liaoliaoxianliu.html.fa1a5a6a.js\",\n \"revision\": \"d7adca67a7d381f6981cb817175944c4\"\n },\n {\n \"url\": \"assets/weixin-likbj.html.4138e613.js\",\n \"revision\": \"6395e20d8d24f4bcc933e75894fac268\"\n },\n {\n \"url\": \"assets/weixin-likbj.html.a9767504.js\",\n \"revision\": \"67265416eb31f31606416a0baafd2475\"\n },\n {\n \"url\": \"assets/weixin-mozdsdzfjavableetcodetxxk.html.10059c85.js\",\n \"revision\": \"6473a9bdd950392244f60e71df774de5\"\n },\n {\n \"url\": \"assets/weixin-mozdsdzfjavableetcodetxxk.html.62ab0a25.js\",\n \"revision\": \"0f190ae7e34f0e8ad471ee7809cfe761\"\n },\n {\n \"url\": \"assets/weixin-piaolwzjztqdtskwlzfpdf.html.0792de0c.js\",\n \"revision\": \"f035ffaff7e88d572d2c460ad84db23d\"\n },\n {\n \"url\": \"assets/weixin-piaolwzjztqdtskwlzfpdf.html.ef3235a6.js\",\n \"revision\": \"e3e8e581a5586b56de5c4d2085795f8a\"\n },\n {\n \"url\": \"assets/weixin-quoppomspwml.html.03c9aa24.js\",\n \"revision\": \"c001602f7147046efdac7de37c6de20c\"\n },\n {\n \"url\": \"assets/weixin-quoppomspwml.html.27944449.js\",\n \"revision\": \"1dd56bd3060a835f37fb980c0264913a\"\n },\n {\n \"url\": \"assets/weixin-shejmsnb.html.1f9c172b.js\",\n \"revision\": \"a66e546674efd8231e15dd9ad790ef38\"\n },\n {\n \"url\": \"assets/weixin-shejmsnb.html.5a6a099f.js\",\n \"revision\": \"ef87f2f1d3dd2bdb2068c1618d70f79f\"\n },\n {\n \"url\": \"assets/weixin-shenrjcjavabfbchwjdhl.html.8fda2ac2.js\",\n \"revision\": \"fbf8fe141f102c839715523a885e99d9\"\n },\n {\n \"url\": \"assets/weixin-shenrjcjavabfbchwjdhl.html.ca182283.js\",\n \"revision\": \"941b26ddeff96e2a49395aef68f7a5e2\"\n },\n {\n \"url\": \"assets/weixin-xinllgjszjszzpojozsyjbsjlxyhjfyll.html.8f640dc9.js\",\n \"revision\": \"873bcfb3534b542706c75db73ec1afeb\"\n },\n {\n \"url\": \"assets/weixin-xinllgjszjszzpojozsyjbsjlxyhjfyll.html.b7b8ec57.js\",\n \"revision\": \"854f359a6cb733a4efd07ed379ad7a37\"\n },\n {\n \"url\": \"assets/weixin-zaixsfdnavicatzkkydsjkglgjjmgxk.html.ad8c7107.js\",\n \"revision\": \"dc56c59218a15872112cc8942807b8ea\"\n },\n {\n \"url\": \"assets/weixin-zaixsfdnavicatzkkydsjkglgjjmgxk.html.bcbd11eb.js\",\n \"revision\": \"a70fc393a3bb18ba3eaa747e1fc8fea7\"\n },\n {\n \"url\": \"assets/weixin-zhongxcwbztashjjavahdmj.html.2296ba72.js\",\n \"revision\": \"48b175c2111f71995268f7183440b23d\"\n },\n {\n \"url\": \"assets/weixin-zhongxcwbztashjjavahdmj.html.844aa3a1.js\",\n \"revision\": \"7003350e84221429c44952436b05dd9a\"\n },\n {\n \"url\": \"assets/weixin-zuixinbujiabandigongsimingdan.html.bf87a7d5.js\",\n \"revision\": \"6b31f97d80d9263648f800c7917b6bb4\"\n },\n {\n \"url\": \"assets/weixin-zuixinbujiabandigongsimingdan.html.d0426aa9.js\",\n \"revision\": \"5504be78015703d138372586dace33bd\"\n },\n {\n \"url\": \"assets/what-happen-when-javac.html.a24cf79e.js\",\n \"revision\": \"8d987c500b7bf591d1f295525267a6c3\"\n },\n {\n \"url\": \"assets/what-happen-when-javac.html.ab4282c1.js\",\n \"revision\": \"aec391454b1d49aea2d1ca364b27bbad\"\n },\n {\n \"url\": \"assets/what-is-java.html.b724e432.js\",\n \"revision\": \"ea158f9a6749d586eb5eb1a5fe867369\"\n },\n {\n \"url\": \"assets/what-is-java.html.efbb701f.js\",\n \"revision\": \"e8e1bc913028977370b0593e7598e054\"\n },\n {\n \"url\": \"assets/what-is-jvm.html.3177cd0e.js\",\n \"revision\": \"696737b7be3e43dc6f2a8fc9eb4c5e7b\"\n },\n {\n \"url\": \"assets/what-is-jvm.html.5131a239.js\",\n \"revision\": \"2428430ef6fd17693a8d67d339efdbaf\"\n },\n {\n \"url\": \"assets/whereis-the-object.html.5fa8d65e.js\",\n \"revision\": \"1861acd01f60ab6cd59dcf238a943a84\"\n },\n {\n \"url\": \"assets/whereis-the-object.html.c695df3e.js\",\n \"revision\": \"40f9a605c5d9174441138c22b4df9205\"\n },\n {\n \"url\": \"assets/why-need-thread.html.507a940d.js\",\n \"revision\": \"d4a7d960b4a4125ab55a9d577d1e8360\"\n },\n {\n \"url\": \"assets/why-need-thread.html.8e1db849.js\",\n \"revision\": \"40bfd1d12d1e47eb85f6f578c0c8d4f1\"\n },\n {\n \"url\": \"assets/windows-codingmore-run.html.225f6c56.js\",\n \"revision\": \"135ab97e1dba75841e3f8b9d5be28f80\"\n },\n {\n \"url\": \"assets/windows-codingmore-run.html.6d49b8aa.js\",\n \"revision\": \"cc7b3b5d03ff06b212bd4154eafe2dc7\"\n },\n {\n \"url\": \"assets/xian.html.b0d9fb64.js\",\n \"revision\": \"c3b5f93959ba571c644a777d483db7e6\"\n },\n {\n \"url\": \"assets/xian.html.badb133a.js\",\n \"revision\": \"480724a731e95bf9d96e534d7146a281\"\n },\n {\n \"url\": \"assets/xuebeng-chuantou-jichuan.html.26ef04a3.js\",\n \"revision\": \"c10aab87bc0050f68ba50c3693861364\"\n },\n {\n \"url\": \"assets/xuebeng-chuantou-jichuan.html.ffa86b85.js\",\n \"revision\": \"079052f7ac584ae433e7b88a65a56af2\"\n },\n {\n \"url\": \"assets/yanjiusuo-20wan.html.4b71b495.js\",\n \"revision\": \"ac7087c137f0ec882510a72efd8bcb22\"\n },\n {\n \"url\": \"assets/yanjiusuo-20wan.html.76b660c5.js\",\n \"revision\": \"6cb110df442468ed54c8c39e2aed9685\"\n },\n {\n \"url\": \"assets/yitiaolong.html.0ffd862a.js\",\n \"revision\": \"740513e76f9f97d6e3f30dfbddf7ace9\"\n },\n {\n \"url\": \"assets/yitiaolong.html.277dddb2.js\",\n \"revision\": \"61cd35b123aa09db4ac2cda634ed7036\"\n },\n {\n \"url\": \"assets/yuanyifeng-c-language.html.90250cb3.js\",\n \"revision\": \"0877c195976395eeaca785ebb029c7ab\"\n },\n {\n \"url\": \"assets/yuanyifeng-c-language.html.dbcc3d40.js\",\n \"revision\": \"beb494651a64cdd304ba312be66de182\"\n },\n {\n \"url\": \"assets/yuneban-wangyiyunyinyue.html.275a589e.js\",\n \"revision\": \"02439e9c34e5ddec3bd616d8d036bb42\"\n },\n {\n \"url\": \"assets/yuneban-wangyiyunyinyue.html.83ef1711.js\",\n \"revision\": \"2e422246050a3d4fbe7e14fccfcf7e76\"\n },\n {\n \"url\": \"assets/zhengzhou.html.bee29209.js\",\n \"revision\": \"160ee95c89836a2d601659660d598a31\"\n },\n {\n \"url\": \"assets/zhengzhou.html.c309c263.js\",\n \"revision\": \"c4bf65e9d1458f8065a23c080a3a2ca4\"\n },\n {\n \"url\": \"assets/zhihu-1000wan.html.4bf2b6f4.js\",\n \"revision\": \"677db386556c4a3b1c5368584a949dde\"\n },\n {\n \"url\": \"assets/zhihu-1000wan.html.51362a9b.js\",\n \"revision\": \"fe3ce6427c608033cc2379bb2e7559b4\"\n },\n {\n \"url\": \"assets/zhihu-jisjkyynxzdtjdyj.html.468f166c.js\",\n \"revision\": \"b1ae892dd90147cb90a8a275f1dadbcc\"\n },\n {\n \"url\": \"assets/zhihu-jisjkyynxzdtjdyj.html.8094217b.js\",\n \"revision\": \"d5bb4c3b4257d9d451d8e4a52cfa6ade\"\n },\n {\n \"url\": \"assets/zhihu-weismyrsyxkjgscxyzhdjyxz.html.98987909.js\",\n \"revision\": \"22c49d6f5a97022f58b7b209e5061ad9\"\n },\n {\n \"url\": \"assets/zhihu-weismyrsyxkjgscxyzhdjyxz.html.ec5fcad9.js\",\n \"revision\": \"782767c646a8c40c4526244127448d35\"\n },\n {\n \"url\": \"assets/zhihu-younxzdjsjzyxsjrdgq.html.c66976c6.js\",\n \"revision\": \"e90dad3972a10bc0a21ea85481951f66\"\n },\n {\n \"url\": \"assets/zhihu-younxzdjsjzyxsjrdgq.html.e644f706.js\",\n \"revision\": \"8e28a5bf14351bb13a94e3500f0416a4\"\n },\n {\n \"url\": \"assets/ZHIHUjavaxuexidaoshemechengduokeyizhaodiyifengongzuo.html.e4fead09.js\",\n \"revision\": \"c265404944c7ef4afe301786011a3ab7\"\n },\n {\n \"url\": \"assets/ZHIHUjavaxuexidaoshemechengduokeyizhaodiyifengongzuo.html.ef1e0c27.js\",\n \"revision\": \"6758277cedc73bb0f2d6f20ada4b6a90\"\n },\n {\n \"url\": \"assets/zijiema-zhiling.html.34c655bc.js\",\n \"revision\": \"203ba55ffb1e89f9bb2fe0482a78a416\"\n },\n {\n \"url\": \"assets/zijiema-zhiling.html.60db7eb3.js\",\n \"revision\": \"7f1a8037a4e2922723645d7622235ae1\"\n },\n {\n \"url\": \"assets/zongjie.html.1ee2edb6.js\",\n \"revision\": \"f23bdac3926858be84a5ef0eb4856e0b\"\n },\n {\n \"url\": \"assets/zongjie.html.c9e5e3c3.js\",\n \"revision\": \"bfa15e84daf91ca3742016d07bbb8252\"\n },\n {\n \"url\": \"assets/zoom.esm.8514a202.js\",\n \"revision\": \"8b3ee4f6f71ef2a7c85901cba6d23344\"\n },\n {\n \"url\": \"logo.svg\",\n \"revision\": \"d7efe218a18b0891e803f61130d971ea\"\n },\n {\n \"url\": \"assets/league-gothic.38fcc721.ttf\",\n \"revision\": \"91295fa87df918411b49b7531da5d558\"\n },\n {\n \"url\": \"assets/league-gothic.5eef6df8.woff\",\n \"revision\": \"cd382dc8a9d6317864b5810a320effc5\"\n },\n {\n \"url\": \"assets/league-gothic.8802c66a.eot\",\n \"revision\": \"9900a4643cc63c5d8f969d2196f72572\"\n },\n {\n \"url\": \"assets/source-sans-pro-italic.05d3615f.woff\",\n \"revision\": \"e74f0128884561828ce8c9cf5c284ab8\"\n },\n {\n \"url\": \"assets/source-sans-pro-italic.ad4b0799.eot\",\n \"revision\": \"72217712eb8d28872e7069322f3fda23\"\n },\n {\n \"url\": \"assets/source-sans-pro-italic.d13268af.ttf\",\n \"revision\": \"8256cfd7e4017a7690814879409212cd\"\n },\n {\n \"url\": \"assets/source-sans-pro-regular.c1865d89.ttf\",\n \"revision\": \"2da39ecf9246383937da11b44b7bd9b4\"\n },\n {\n \"url\": \"assets/source-sans-pro-regular.d4eaa48b.woff\",\n \"revision\": \"e7acc589bb558fe58936a853f570193c\"\n },\n {\n \"url\": \"assets/source-sans-pro-regular.dce8869d.eot\",\n \"revision\": \"1d71438462d532b62b05cdd7e6d7197d\"\n },\n {\n \"url\": \"assets/source-sans-pro-semibold.a53e2723.ttf\",\n \"revision\": \"f3565095e6c9158140444970f5a2c5ed\"\n },\n {\n \"url\": \"assets/source-sans-pro-semibold.b0abd273.woff\",\n \"revision\": \"1cb8e94f1185f1131a0c895165998f2b\"\n },\n {\n \"url\": \"assets/source-sans-pro-semibold.ebb8918d.eot\",\n \"revision\": \"0f3da1edf1b5c6a94a6ad948a7664451\"\n },\n {\n \"url\": \"assets/source-sans-pro-semibolditalic.7225cacc.woff\",\n \"revision\": \"6b058fc2634b01d837c3432316c3141f\"\n },\n {\n \"url\": \"assets/source-sans-pro-semibolditalic.dfe0b47a.eot\",\n \"revision\": \"58153ac7194e141d1e73ea88c6b63861\"\n },\n {\n \"url\": \"assets/source-sans-pro-semibolditalic.e8ec22b6.ttf\",\n \"revision\": \"c7e698a4d0956f4a939f42a05685bbf5\"\n },\n {\n \"url\": \"index.html\",\n \"revision\": \"e9cf88a2938b1c751cfa6d8383867883\"\n },\n {\n \"url\": \"404.html\",\n \"revision\": \"52f839eb7af6c3ded982b8d1fb1f0823\"\n },\n {\n \"url\": \"assets/icon/apple-icon-152.png\",\n \"revision\": \"d78854fc622a0bfa2a44a79ec8b6e561\"\n },\n {\n \"url\": \"assets/icon/chrome-192.png\",\n \"revision\": \"eaab382db5bb589c74e2720a777454c3\"\n },\n {\n \"url\": \"assets/icon/chrome-512.png\",\n \"revision\": \"5db9d4a587b378f0b283191e379d85fa\"\n },\n {\n \"url\": \"assets/icon/chrome-mask-192.png\",\n \"revision\": \"eaab382db5bb589c74e2720a777454c3\"\n },\n {\n \"url\": \"assets/icon/chrome-mask-512.png\",\n \"revision\": \"5db9d4a587b378f0b283191e379d85fa\"\n },\n {\n \"url\": \"assets/icon/itwanger-282.png\",\n \"revision\": \"85592fba02d1228f8ca3e842cef07b7c\"\n },\n {\n \"url\": \"assets/icon/itwanger-maskable.png\",\n \"revision\": \"ca6a86caa8171a39adfd0f53f10cdaf2\"\n },\n {\n \"url\": \"assets/icon/itwanger-monochrome.png\",\n \"revision\": \"ca6a86caa8171a39adfd0f53f10cdaf2\"\n },\n {\n \"url\": \"assets/icon/ms-icon-144.png\",\n \"revision\": \"983a00416fc5f5469a79611440389396\"\n },\n {\n \"url\": \"logo.png\",\n \"revision\": \"d30ac8bc232973da730e934321ffeb7f\"\n }\n], {});\nworkbox_precaching_cleanupOutdatedCaches();\n\n\n\n\n\n\n\n"],"names":["workbox_core_setCacheNameDetails","prefix","self","addEventListener","event","data","type","skipWaiting","workbox_core_clientsClaim","workbox_precaching_precacheAndRoute","url","revision","workbox_precaching_cleanupOutdatedCaches"],"mappings":"0nBAmBAA,EAAAA,oBAAiC,CAACC,OAAQ,iBAG1CC,KAAKC,iBAAiB,WAAYC,IAC5BA,EAAMC,MAA4B,iBAApBD,EAAMC,KAAKC,MAC3BJ,KAAKK,iBAITC,EAAAA,eAQAC,EAAAA,iBAAoC,CAClC,CACEC,IAAO,uCACKC,SAAA,oCAEd,CACED,IAAO,uCACKC,SAAA,oCAEd,CACED,IAAO,wCACKC,SAAA,oCAEd,CACED,IAAO,wCACKC,SAAA,oCAEd,CACED,IAAO,uCACKC,SAAA,oCAEd,CACED,IAAO,uCACKC,SAAA,oCAEd,CACED,IAAO,yBACKC,SAAA,oCAEd,CACED,IAAO,8BACKC,SAAA,oCAEd,CACED,IAAO,8BACKC,SAAA,oCAEd,CACED,IAAO,sCACKC,SAAA,oCAEd,CACED,IAAO,sCACKC,SAAA,oCAEd,CACED,IAAO,mCACKC,SAAA,oCAEd,CACED,IAAO,mCACKC,SAAA,oCAEd,CACED,IAAO,oCACKC,SAAA,oCAEd,CACED,IAAO,oCACKC,SAAA,oCAEd,CACED,IAAO,wCACKC,SAAA,oCAEd,CACED,IAAO,wCACKC,SAAA,oCAEd,CACED,IAAO,uDACKC,SAAA,oCAEd,CACED,IAAO,uDACKC,SAAA,oCAEd,CACED,IAAO,qCACKC,SAAA,oCAEd,CACED,IAAO,qCACKC,SAAA,oCAEd,CACED,IAAO,kCACKC,SAAA,oCAEd,CACED,IAAO,kCACKC,SAAA,oCAEd,CACED,IAAO,uCACKC,SAAA,oCAEd,CACED,IAAO,uCACKC,SAAA,oCAEd,CACED,IAAO,yBACKC,SAAA,oCAEd,CACED,IAAO,8BACKC,SAAA,oCAEd,CACED,IAAO,8BACKC,SAAA,oCAEd,CACED,IAAO,gCACKC,SAAA,oCAEd,CACED,IAAO,gCACKC,SAAA,oCAEd,CACED,IAAO,oCACKC,SAAA,oCAEd,CACED,IAAO,oCACKC,SAAA,oCAEd,CACED,IAAO,iCACKC,SAAA,oCAEd,CACED,IAAO,iCACKC,SAAA,oCAEd,CACED,IAAO,8BACKC,SAAA,oCAEd,CACED,IAAO,8BACKC,SAAA,oCAEd,CACED,IAAO,iCACKC,SAAA,oCAEd,CACED,IAAO,iCACKC,SAAA,oCAEd,CACED,IAAO,yCACKC,SAAA,oCAEd,CACED,IAAO,yCACKC,SAAA,oCAEd,CACED,IAAO,0CACKC,SAAA,oCAEd,CACED,IAAO,0CACKC,SAAA,oCAEd,CACED,IAAO,qCACKC,SAAA,oCAEd,CACED,IAAO,qCACKC,SAAA,oCAEd,CACED,IAAO,kCACKC,SAAA,oCAEd,CACED,IAAO,kCACKC,SAAA,oCAEd,CACED,IAAO,oCACKC,SAAA,oCAEd,CACED,IAAO,oCACKC,SAAA,oCAEd,CACED,IAAO,wCACKC,SAAA,oCAEd,CACED,IAAO,wCACKC,SAAA,oCAEd,CACED,IAAO,2EACKC,SAAA,oCAEd,CACED,IAAO,2EACKC,SAAA,oCAEd,CACED,IAAO,2DACKC,SAAA,oCAEd,CACED,IAAO,2DACKC,SAAA,oCAEd,CACED,IAAO,0DACKC,SAAA,oCAEd,CACED,IAAO,0DACKC,SAAA,oCAEd,CACED,IAAO,8BACKC,SAAA,oCAEd,CACED,IAAO,8BACKC,SAAA,oCAEd,CACED,IAAO,2CACKC,SAAA,oCAEd,CACED,IAAO,2CACKC,SAAA,oCAEd,CACED,IAAO,qCACKC,SAAA,oCAEd,CACED,IAAO,qCACKC,SAAA,oCAEd,CACED,IAAO,mCACKC,SAAA,oCAEd,CACED,IAAO,mCACKC,SAAA,oCAEd,CACED,IAAO,sCACKC,SAAA,oCAEd,CACED,IAAO,sCACKC,SAAA,oCAEd,CACED,IAAO,4BACKC,SAAA,oCAEd,CACED,IAAO,4BACKC,SAAA,oCAEd,CACED,IAAO,8BACKC,SAAA,oCAEd,CACED,IAAO,8BACKC,SAAA,oCAEd,CACED,IAAO,8BACKC,SAAA,oCAEd,CACED,IAAO,8BACKC,SAAA,oCAEd,CACED,IAAO,wCACKC,SAAA,oCAEd,CACED,IAAO,wCACKC,SAAA,oCAEd,CACED,IAAO,kCACKC,SAAA,oCAEd,CACED,IAAO,kCACKC,SAAA,oCAEd,CACED,IAAO,sDACKC,SAAA,oCAEd,CACED,IAAO,sDACKC,SAAA,oCAEd,CACED,IAAO,iCACKC,SAAA,oCAEd,CACED,IAAO,iCACKC,SAAA,oCAEd,CACED,IAAO,gCACKC,SAAA,oCAEd,CACED,IAAO,gCACKC,SAAA,oCAEd,CACED,IAAO,8CACKC,SAAA,oCAEd,CACED,IAAO,8CACKC,SAAA,oCAEd,CACED,IAAO,4CACKC,SAAA,oCAEd,CACED,IAAO,4CACKC,SAAA,oCAEd,CACED,IAAO,qCACKC,SAAA,oCAEd,CACED,IAAO,qCACKC,SAAA,oCAEd,CACED,IAAO,uCACKC,SAAA,oCAEd,CACED,IAAO,uCACKC,SAAA,oCAEd,CACED,IAAO,oCACKC,SAAA,oCAEd,CACED,IAAO,oCACKC,SAAA,oCAEd,CACED,IAAO,qCACKC,SAAA,oCAEd,CACED,IAAO,qCACKC,SAAA,oCAEd,CACED,IAAO,sCACKC,SAAA,oCAEd,CACED,IAAO,sCACKC,SAAA,oCAEd,CACED,IAAO,+CACKC,SAAA,oCAEd,CACED,IAAO,+CACKC,SAAA,oCAEd,CACED,IAAO,sCACKC,SAAA,oCAEd,CACED,IAAO,sCACKC,SAAA,oCAEd,CACED,IAAO,wCACKC,SAAA,oCAEd,CACED,IAAO,wCACKC,SAAA,oCAEd,CACED,IAAO,4CACKC,SAAA,oCAEd,CACED,IAAO,4CACKC,SAAA,oCAEd,CACED,IAAO,gDACKC,SAAA,oCAEd,CACED,IAAO,gDACKC,SAAA,oCAEd,CACED,IAAO,oCACKC,SAAA,oCAEd,CACED,IAAO,oCACKC,SAAA,oCAEd,CACED,IAAO,wCACKC,SAAA,oCAEd,CACED,IAAO,wCACKC,SAAA,oCAEd,CACED,IAAO,oCACKC,SAAA,oCAEd,CACED,IAAO,oCACKC,SAAA,oCAEd,CACED,IAAO,+CACKC,SAAA,oCAEd,CACED,IAAO,+CACKC,SAAA,oCAEd,CACED,IAAO,+BACKC,SAAA,oCAEd,CACED,IAAO,+BACKC,SAAA,oCAEd,CACED,IAAO,yCACKC,SAAA,oCAEd,CACED,IAAO,yCACKC,SAAA,oCAEd,CACED,IAAO,0CACKC,SAAA,oCAEd,CACED,IAAO,0CACKC,SAAA,oCAEd,CACED,IAAO,uCACKC,SAAA,oCAEd,CACED,IAAO,uCACKC,SAAA,oCAEd,CACED,IAAO,8CACKC,SAAA,oCAEd,CACED,IAAO,8CACKC,SAAA,oCAEd,CACED,IAAO,kCACKC,SAAA,oCAEd,CACED,IAAO,kCACKC,SAAA,oCAEd,CACED,IAAO,oCACKC,SAAA,oCAEd,CACED,IAAO,oCACKC,SAAA,oCAEd,CACED,IAAO,uDACKC,SAAA,oCAEd,CACED,IAAO,uDACKC,SAAA,oCAEd,CACED,IAAO,2DACKC,SAAA,oCAEd,CACED,IAAO,2DACKC,SAAA,oCAEd,CACED,IAAO,+BACKC,SAAA,oCAEd,CACED,IAAO,+BACKC,SAAA,oCAEd,CACED,IAAO,0CACKC,SAAA,oCAEd,CACED,IAAO,0CACKC,SAAA,oCAEd,CACED,IAAO,iCACKC,SAAA,oCAEd,CACED,IAAO,iCACKC,SAAA,oCAEd,CACED,IAAO,oCACKC,SAAA,oCAEd,CACED,IAAO,oCACKC,SAAA,oCAEd,CACED,IAAO,iCACKC,SAAA,oCAEd,CACED,IAAO,iCACKC,SAAA,oCAEd,CACED,IAAO,mCACKC,SAAA,oCAEd,CACED,IAAO,mCACKC,SAAA,oCAEd,CACED,IAAO,sDACKC,SAAA,oCAEd,CACED,IAAO,sDACKC,SAAA,oCAEd,CACED,IAAO,gCACKC,SAAA,oCAEd,CACED,IAAO,gCACKC,SAAA,oCAEd,CACED,IAAO,uCACKC,SAAA,oCAEd,CACED,IAAO,uCACKC,SAAA,oCAEd,CACED,IAAO,iCACKC,SAAA,oCAEd,CACED,IAAO,iCACKC,SAAA,oCAEd,CACED,IAAO,oCACKC,SAAA,oCAEd,CACED,IAAO,oCACKC,SAAA,oCAEd,CACED,IAAO,qCACKC,SAAA,oCAEd,CACED,IAAO,qCACKC,SAAA,oCAEd,CACED,IAAO,iCACKC,SAAA,oCAEd,CACED,IAAO,iCACKC,SAAA,oCAEd,CACED,IAAO,iCACKC,SAAA,oCAEd,CACED,IAAO,iCACKC,SAAA,oCAEd,CACED,IAAO,6BACKC,SAAA,oCAEd,CACED,IAAO,6BACKC,SAAA,oCAEd,CACED,IAAO,kCACKC,SAAA,oCAEd,CACED,IAAO,kCACKC,SAAA,oCAEd,CACED,IAAO,qCACKC,SAAA,oCAEd,CACED,IAAO,qCACKC,SAAA,oCAEd,CACED,IAAO,6BACKC,SAAA,oCAEd,CACED,IAAO,6BACKC,SAAA,oCAEd,CACED,IAAO,+BACKC,SAAA,oCAEd,CACED,IAAO,+BACKC,SAAA,oCAEd,CACED,IAAO,oCACKC,SAAA,oCAEd,CACED,IAAO,oCACKC,SAAA,oCAEd,CACED,IAAO,gCACKC,SAAA,oCAEd,CACED,IAAO,gCACKC,SAAA,oCAEd,CACED,IAAO,mEACKC,SAAA,oCAEd,CACED,IAAO,mEACKC,SAAA,oCAEd,CACED,IAAO,mCACKC,SAAA,oCAEd,CACED,IAAO,mCACKC,SAAA,oCAEd,CACED,IAAO,mCACKC,SAAA,oCAEd,CACED,IAAO,mCACKC,SAAA,oCAEd,CACED,IAAO,4CACKC,SAAA,oCAEd,CACED,IAAO,4CACKC,SAAA,oCAEd,CACED,IAAO,kCACKC,SAAA,oCAEd,CACED,IAAO,kCACKC,SAAA,oCAEd,CACED,IAAO,sCACKC,SAAA,oCAEd,CACED,IAAO,sCACKC,SAAA,oCAEd,CACED,IAAO,mCACKC,SAAA,oCAEd,CACED,IAAO,kCACKC,SAAA,oCAEd,CACED,IAAO,kCACKC,SAAA,oCAEd,CACED,IAAO,+BACKC,SAAA,oCAEd,CACED,IAAO,+BACKC,SAAA,oCAEd,CACED,IAAO,sDACKC,SAAA,oCAEd,CACED,IAAO,sDACKC,SAAA,oCAEd,CACED,IAAO,4CACKC,SAAA,oCAEd,CACED,IAAO,4CACKC,SAAA,oCAEd,CACED,IAAO,+BACKC,SAAA,oCAEd,CACED,IAAO,+BACKC,SAAA,oCAEd,CACED,IAAO,uCACKC,SAAA,oCAEd,CACED,IAAO,uCACKC,SAAA,oCAEd,CACED,IAAO,iCACKC,SAAA,oCAEd,CACED,IAAO,iCACKC,SAAA,oCAEd,CACED,IAAO,sCACKC,SAAA,oCAEd,CACED,IAAO,sCACKC,SAAA,oCAEd,CACED,IAAO,oCACKC,SAAA,oCAEd,CACED,IAAO,oCACKC,SAAA,oCAEd,CACED,IAAO,oCACKC,SAAA,oCAEd,CACED,IAAO,oCACKC,SAAA,oCAEd,CACED,IAAO,gCACKC,SAAA,oCAEd,CACED,IAAO,gCACKC,SAAA,oCAEd,CACED,IAAO,gCACKC,SAAA,oCAEd,CACED,IAAO,gCACKC,SAAA,oCAEd,CACED,IAAO,gCACKC,SAAA,oCAEd,CACED,IAAO,gCACKC,SAAA,oCAEd,CACED,IAAO,gCACKC,SAAA,oCAEd,CACED,IAAO,gCACKC,SAAA,oCAEd,CACED,IAAO,gCACKC,SAAA,oCAEd,CACED,IAAO,gCACKC,SAAA,oCAEd,CACED,IAAO,qCACKC,SAAA,oCAEd,CACED,IAAO,qCACKC,SAAA,oCAEd,CACED,IAAO,sCACKC,SAAA,oCAEd,CACED,IAAO,sCACKC,SAAA,oCAEd,CACED,IAAO,gDACKC,SAAA,oCAEd,CACED,IAAO,gDACKC,SAAA,oCAEd,CACED,IAAO,yCACKC,SAAA,oCAEd,CACED,IAAO,yCACKC,SAAA,oCAEd,CACED,IAAO,qCACKC,SAAA,oCAEd,CACED,IAAO,qCACKC,SAAA,oCAEd,CACED,IAAO,oCACKC,SAAA,oCAEd,CACED,IAAO,oCACKC,SAAA,oCAEd,CACED,IAAO,oCACKC,SAAA,oCAEd,CACED,IAAO,oCACKC,SAAA,oCAEd,CACED,IAAO,iCACKC,SAAA,oCAEd,CACED,IAAO,iCACKC,SAAA,oCAEd,CACED,IAAO,8BACKC,SAAA,oCAEd,CACED,IAAO,8BACKC,SAAA,oCAEd,CACED,IAAO,4CACKC,SAAA,oCAEd,CACED,IAAO,4CACKC,SAAA,oCAEd,CACED,IAAO,kCACKC,SAAA,oCAEd,CACED,IAAO,kCACKC,SAAA,oCAEd,CACED,IAAO,wCACKC,SAAA,oCAEd,CACED,IAAO,wCACKC,SAAA,oCAEd,CACED,IAAO,qCACKC,SAAA,oCAEd,CACED,IAAO,qCACKC,SAAA,oCAEd,CACED,IAAO,8CACKC,SAAA,oCAEd,CACED,IAAO,8CACKC,SAAA,oCAEd,CACED,IAAO,sCACKC,SAAA,oCAEd,CACED,IAAO,sCACKC,SAAA,oCAEd,CACED,IAAO,sCACKC,SAAA,oCAEd,CACED,IAAO,sCACKC,SAAA,oCAEd,CACED,IAAO,uCACKC,SAAA,oCAEd,CACED,IAAO,uCACKC,SAAA,oCAEd,CACED,IAAO,+BACKC,SAAA,oCAEd,CACED,IAAO,+BACKC,SAAA,oCAEd,CACED,IAAO,kCACKC,SAAA,oCAEd,CACED,IAAO,kCACKC,SAAA,oCAEd,CACED,IAAO,iCACKC,SAAA,oCAEd,CACED,IAAO,iCACKC,SAAA,oCAEd,CACED,IAAO,qCACKC,SAAA,oCAEd,CACED,IAAO,qCACKC,SAAA,oCAEd,CACED,IAAO,0EACKC,SAAA,oCAEd,CACED,IAAO,0EACKC,SAAA,oCAEd,CACED,IAAO,uDACKC,SAAA,oCAEd,CACED,IAAO,uDACKC,SAAA,oCAEd,CACED,IAAO,gDACKC,SAAA,oCAEd,CACED,IAAO,gDACKC,SAAA,oCAEd,CACED,IAAO,kEACKC,SAAA,oCAEd,CACED,IAAO,kEACKC,SAAA,oCAEd,CACED,IAAO,iCACKC,SAAA,oCAEd,CACED,IAAO,iCACKC,SAAA,oCAEd,CACED,IAAO,uCACKC,SAAA,oCAEd,CACED,IAAO,uCACKC,SAAA,oCAEd,CACED,IAAO,mDACKC,SAAA,oCAEd,CACED,IAAO,mDACKC,SAAA,oCAEd,CACED,IAAO,gCACKC,SAAA,oCAEd,CACED,IAAO,gCACKC,SAAA,oCAEd,CACED,IAAO,qDACKC,SAAA,oCAEd,CACED,IAAO,qDACKC,SAAA,oCAEd,CACED,IAAO,8BACKC,SAAA,oCAEd,CACED,IAAO,8BACKC,SAAA,oCAEd,CACED,IAAO,8BACKC,SAAA,oCAEd,CACED,IAAO,8BACKC,SAAA,oCAEd,CACED,IAAO,+BACKC,SAAA,oCAEd,CACED,IAAO,+BACKC,SAAA,oCAEd,CACED,IAAO,8BACKC,SAAA,oCAEd,CACED,IAAO,8BACKC,SAAA,oCAEd,CACED,IAAO,gCACKC,SAAA,oCAEd,CACED,IAAO,gCACKC,SAAA,oCAEd,CACED,IAAO,8BACKC,SAAA,oCAEd,CACED,IAAO,8BACKC,SAAA,oCAEd,CACED,IAAO,8BACKC,SAAA,oCAEd,CACED,IAAO,8BACKC,SAAA,oCAEd,CACED,IAAO,8BACKC,SAAA,oCAEd,CACED,IAAO,8BACKC,SAAA,oCAEd,CACED,IAAO,8BACKC,SAAA,oCAEd,CACED,IAAO,8BACKC,SAAA,oCAEd,CACED,IAAO,kCACKC,SAAA,oCAEd,CACED,IAAO,kCACKC,SAAA,oCAEd,CACED,IAAO,iCACKC,SAAA,oCAEd,CACED,IAAO,iCACKC,SAAA,oCAEd,CACED,IAAO,qCACKC,SAAA,oCAEd,CACED,IAAO,qCACKC,SAAA,oCAEd,CACED,IAAO,4BACKC,SAAA,oCAEd,CACED,IAAO,uCACKC,SAAA,oCAEd,CACED,IAAO,uCACKC,SAAA,oCAEd,CACED,IAAO,qCACKC,SAAA,oCAEd,CACED,IAAO,qCACKC,SAAA,oCAEd,CACED,IAAO,+CACKC,SAAA,oCAEd,CACED,IAAO,+CACKC,SAAA,oCAEd,CACED,IAAO,qCACKC,SAAA,oCAEd,CACED,IAAO,qCACKC,SAAA,oCAEd,CACED,IAAO,+BACKC,SAAA,oCAEd,CACED,IAAO,+BACKC,SAAA,oCAEd,CACED,IAAO,sCACKC,SAAA,oCAEd,CACED,IAAO,sCACKC,SAAA,oCAEd,CACED,IAAO,gCACKC,SAAA,oCAEd,CACED,IAAO,gCACKC,SAAA,oCAEd,CACED,IAAO,iCACKC,SAAA,oCAEd,CACED,IAAO,iCACKC,SAAA,oCAEd,CACED,IAAO,iCACKC,SAAA,oCAEd,CACED,IAAO,iCACKC,SAAA,oCAEd,CACED,IAAO,kCACKC,SAAA,oCAEd,CACED,IAAO,kCACKC,SAAA,oCAEd,CACED,IAAO,kCACKC,SAAA,oCAEd,CACED,IAAO,kCACKC,SAAA,oCAEd,CACED,IAAO,+CACKC,SAAA,oCAEd,CACED,IAAO,+CACKC,SAAA,oCAEd,CACED,IAAO,8BACKC,SAAA,oCAEd,CACED,IAAO,8BACKC,SAAA,oCAEd,CACED,IAAO,kCACKC,SAAA,oCAEd,CACED,IAAO,8BACKC,SAAA,oCAEd,CACED,IAAO,gCACKC,SAAA,oCAEd,CACED,IAAO,gCACKC,SAAA,oCAEd,CACED,IAAO,uCACKC,SAAA,oCAEd,CACED,IAAO,uCACKC,SAAA,oCAEd,CACED,IAAO,iCACKC,SAAA,oCAEd,CACED,IAAO,iCACKC,SAAA,oCAEd,CACED,IAAO,kCACKC,SAAA,oCAEd,CACED,IAAO,kCACKC,SAAA,oCAEd,CACED,IAAO,sCACKC,SAAA,oCAEd,CACED,IAAO,sCACKC,SAAA,oCAEd,CACED,IAAO,gCACKC,SAAA,oCAEd,CACED,IAAO,gCACKC,SAAA,oCAEd,CACED,IAAO,kCACKC,SAAA,oCAEd,CACED,IAAO,kCACKC,SAAA,oCAEd,CACED,IAAO,wCACKC,SAAA,oCAEd,CACED,IAAO,wCACKC,SAAA,oCAEd,CACED,IAAO,wCACKC,SAAA,oCAEd,CACED,IAAO,wCACKC,SAAA,oCAEd,CACED,IAAO,gCACKC,SAAA,oCAEd,CACED,IAAO,gCACKC,SAAA,oCAEd,CACED,IAAO,sCACKC,SAAA,oCAEd,CACED,IAAO,sCACKC,SAAA,oCAEd,CACED,IAAO,+BACKC,SAAA,oCAEd,CACED,IAAO,+BACKC,SAAA,oCAEd,CACED,IAAO,+BACKC,SAAA,oCAEd,CACED,IAAO,8BACKC,SAAA,oCAEd,CACED,IAAO,8BACKC,SAAA,oCAEd,CACED,IAAO,uCACKC,SAAA,oCAEd,CACED,IAAO,uCACKC,SAAA,oCAEd,CACED,IAAO,8BACKC,SAAA,oCAEd,CACED,IAAO,8BACKC,SAAA,oCAEd,CACED,IAAO,mCACKC,SAAA,oCAEd,CACED,IAAO,mCACKC,SAAA,oCAEd,CACED,IAAO,mCACKC,SAAA,oCAEd,CACED,IAAO,mCACKC,SAAA,oCAEd,CACED,IAAO,6BACKC,SAAA,oCAEd,CACED,IAAO,6BACKC,SAAA,oCAEd,CACED,IAAO,6BACKC,SAAA,oCAEd,CACED,IAAO,6BACKC,SAAA,oCAEd,CACED,IAAO,8BACKC,SAAA,oCAEd,CACED,IAAO,8BACKC,SAAA,oCAEd,CACED,IAAO,iCACKC,SAAA,oCAEd,CACED,IAAO,iCACKC,SAAA,oCAEd,CACED,IAAO,4CACKC,SAAA,oCAEd,CACED,IAAO,4CACKC,SAAA,oCAEd,CACED,IAAO,qCACKC,SAAA,oCAEd,CACED,IAAO,qCACKC,SAAA,oCAEd,CACED,IAAO,wCACKC,SAAA,oCAEd,CACED,IAAO,wCACKC,SAAA,oCAEd,CACED,IAAO,8BACKC,SAAA,oCAEd,CACED,IAAO,8BACKC,SAAA,oCAEd,CACED,IAAO,oCACKC,SAAA,oCAEd,CACED,IAAO,8CACKC,SAAA,oCAEd,CACED,IAAO,+BACKC,SAAA,oCAEd,CACED,IAAO,+BACKC,SAAA,oCAEd,CACED,IAAO,gCACKC,SAAA,oCAEd,CACED,IAAO,gCACKC,SAAA,oCAEd,CACED,IAAO,wCACKC,SAAA,oCAEd,CACED,IAAO,wCACKC,SAAA,oCAEd,CACED,IAAO,iCACKC,SAAA,oCAEd,CACED,IAAO,iCACKC,SAAA,oCAEd,CACED,IAAO,iCACKC,SAAA,oCAEd,CACED,IAAO,iCACKC,SAAA,oCAEd,CACED,IAAO,iCACKC,SAAA,oCAEd,CACED,IAAO,iCACKC,SAAA,oCAEd,CACED,IAAO,mCACKC,SAAA,oCAEd,CACED,IAAO,mCACKC,SAAA,oCAEd,CACED,IAAO,kCACKC,SAAA,oCAEd,CACED,IAAO,kCACKC,SAAA,oCAEd,CACED,IAAO,yCACKC,SAAA,oCAEd,CACED,IAAO,yCACKC,SAAA,oCAEd,CACED,IAAO,qCACKC,SAAA,oCAEd,CACED,IAAO,qCACKC,SAAA,oCAEd,CACED,IAAO,wCACKC,SAAA,oCAEd,CACED,IAAO,wCACKC,SAAA,oCAEd,CACED,IAAO,gDACKC,SAAA,oCAEd,CACED,IAAO,gDACKC,SAAA,oCAEd,CACED,IAAO,2CACKC,SAAA,oCAEd,CACED,IAAO,2CACKC,SAAA,oCAEd,CACED,IAAO,gCACKC,SAAA,oCAEd,CACED,IAAO,gCACKC,SAAA,oCAEd,CACED,IAAO,0CACKC,SAAA,oCAEd,CACED,IAAO,0CACKC,SAAA,oCAEd,CACED,IAAO,wCACKC,SAAA,oCAEd,CACED,IAAO,wCACKC,SAAA,oCAEd,CACED,IAAO,iDACKC,SAAA,oCAEd,CACED,IAAO,iDACKC,SAAA,oCAEd,CACED,IAAO,gCACKC,SAAA,oCAEd,CACED,IAAO,gCACKC,SAAA,oCAEd,CACED,IAAO,gCACKC,SAAA,oCAEd,CACED,IAAO,gCACKC,SAAA,oCAEd,CACED,IAAO,gCACKC,SAAA,oCAEd,CACED,IAAO,gCACKC,SAAA,oCAEd,CACED,IAAO,gCACKC,SAAA,oCAEd,CACED,IAAO,sDACKC,SAAA,oCAEd,CACED,IAAO,sDACKC,SAAA,oCAEd,CACED,IAAO,gCACKC,SAAA,oCAEd,CACED,IAAO,wCACKC,SAAA,oCAEd,CACED,IAAO,wCACKC,SAAA,oCAEd,CACED,IAAO,mCACKC,SAAA,oCAEd,CACED,IAAO,mCACKC,SAAA,oCAEd,CACED,IAAO,kDACKC,SAAA,oCAEd,CACED,IAAO,kDACKC,SAAA,oCAEd,CACED,IAAO,mCACKC,SAAA,oCAEd,CACED,IAAO,mCACKC,SAAA,oCAEd,CACED,IAAO,kCACKC,SAAA,oCAEd,CACED,IAAO,kCACKC,SAAA,oCAEd,CACED,IAAO,8BACKC,SAAA,oCAEd,CACED,IAAO,gCACKC,SAAA,oCAEd,CACED,IAAO,gCACKC,SAAA,oCAEd,CACED,IAAO,2BACKC,SAAA,oCAEd,CACED,IAAO,gCACKC,SAAA,oCAEd,CACED,IAAO,gCACKC,SAAA,oCAEd,CACED,IAAO,iCACKC,SAAA,oCAEd,CACED,IAAO,iCACKC,SAAA,oCAEd,CACED,IAAO,qCACKC,SAAA,oCAEd,CACED,IAAO,qCACKC,SAAA,oCAEd,CACED,IAAO,iCACKC,SAAA,oCAEd,CACED,IAAO,iCACKC,SAAA,oCAEd,CACED,IAAO,iCACKC,SAAA,oCAEd,CACED,IAAO,iCACKC,SAAA,oCAEd,CACED,IAAO,4BACKC,SAAA,oCAEd,CACED,IAAO,iCACKC,SAAA,oCAEd,CACED,IAAO,iCACKC,SAAA,oCAEd,CACED,IAAO,kCACKC,SAAA,oCAEd,CACED,IAAO,kCACKC,SAAA,oCAEd,CACED,IAAO,uCACKC,SAAA,oCAEd,CACED,IAAO,uCACKC,SAAA,oCAEd,CACED,IAAO,gCACKC,SAAA,oCAEd,CACED,IAAO,gCACKC,SAAA,oCAEd,CACED,IAAO,qCACKC,SAAA,oCAEd,CACED,IAAO,qCACKC,SAAA,oCAEd,CACED,IAAO,oDACKC,SAAA,oCAEd,CACED,IAAO,oDACKC,SAAA,oCAEd,CACED,IAAO,2DACKC,SAAA,oCAEd,CACED,IAAO,2DACKC,SAAA,oCAEd,CACED,IAAO,kDACKC,SAAA,oCAEd,CACED,IAAO,kDACKC,SAAA,oCAEd,CACED,IAAO,iCACKC,SAAA,oCAEd,CACED,IAAO,iCACKC,SAAA,oCAEd,CACED,IAAO,sCACKC,SAAA,oCAEd,CACED,IAAO,sCACKC,SAAA,oCAEd,CACED,IAAO,oCACKC,SAAA,oCAEd,CACED,IAAO,oCACKC,SAAA,oCAEd,CACED,IAAO,8DACKC,SAAA,oCAEd,CACED,IAAO,8DACKC,SAAA,oCAEd,CACED,IAAO,iCACKC,SAAA,oCAEd,CACED,IAAO,iCACKC,SAAA,oCAEd,CACED,IAAO,sCACKC,SAAA,oCAEd,CACED,IAAO,sCACKC,SAAA,oCAEd,CACED,IAAO,uCACKC,SAAA,oCAEd,CACED,IAAO,uCACKC,SAAA,oCAEd,CACED,IAAO,4CACKC,SAAA,oCAEd,CACED,IAAO,4CACKC,SAAA,oCAEd,CACED,IAAO,mCACKC,SAAA,oCAEd,CACED,IAAO,mCACKC,SAAA,oCAEd,CACED,IAAO,2CACKC,SAAA,oCAEd,CACED,IAAO,2CACKC,SAAA,oCAEd,CACED,IAAO,8BACKC,SAAA,oCAEd,CACED,IAAO,8BACKC,SAAA,oCAEd,CACED,IAAO,mCACKC,SAAA,oCAEd,CACED,IAAO,mCACKC,SAAA,oCAEd,CACED,IAAO,mCACKC,SAAA,oCAEd,CACED,IAAO,mCACKC,SAAA,oCAEd,CACED,IAAO,wCACKC,SAAA,oCAEd,CACED,IAAO,wCACKC,SAAA,oCAEd,CACED,IAAO,kCACKC,SAAA,oCAEd,CACED,IAAO,kCACKC,SAAA,oCAEd,CACED,IAAO,yCACKC,SAAA,oCAEd,CACED,IAAO,yCACKC,SAAA,oCAEd,CACED,IAAO,+BACKC,SAAA,oCAEd,CACED,IAAO,+BACKC,SAAA,oCAEd,CACED,IAAO,yCACKC,SAAA,oCAEd,CACED,IAAO,yCACKC,SAAA,oCAEd,CACED,IAAO,mDACKC,SAAA,oCAEd,CACED,IAAO,mDACKC,SAAA,oCAEd,CACED,IAAO,sDACKC,SAAA,oCAEd,CACED,IAAO,sDACKC,SAAA,oCAEd,CACED,IAAO,iDACKC,SAAA,oCAEd,CACED,IAAO,iDACKC,SAAA,oCAEd,CACED,IAAO,uCACKC,SAAA,oCAEd,CACED,IAAO,uCACKC,SAAA,oCAEd,CACED,IAAO,2DACKC,SAAA,oCAEd,CACED,IAAO,2DACKC,SAAA,oCAEd,CACED,IAAO,wDACKC,SAAA,oCAEd,CACED,IAAO,wDACKC,SAAA,oCAEd,CACED,IAAO,8CACKC,SAAA,oCAEd,CACED,IAAO,8CACKC,SAAA,oCAEd,CACED,IAAO,0CACKC,SAAA,oCAEd,CACED,IAAO,0CACKC,SAAA,oCAEd,CACED,IAAO,uDACKC,SAAA,oCAEd,CACED,IAAO,uDACKC,SAAA,oCAEd,CACED,IAAO,mEACKC,SAAA,oCAEd,CACED,IAAO,mEACKC,SAAA,oCAEd,CACED,IAAO,iEACKC,SAAA,oCAEd,CACED,IAAO,iEACKC,SAAA,oCAEd,CACED,IAAO,yDACKC,SAAA,oCAEd,CACED,IAAO,yDACKC,SAAA,oCAEd,CACED,IAAO,+DACKC,SAAA,oCAEd,CACED,IAAO,+DACKC,SAAA,oCAEd,CACED,IAAO,iDACKC,SAAA,oCAEd,CACED,IAAO,iDACKC,SAAA,oCAEd,CACED,IAAO,uCACKC,SAAA,oCAEd,CACED,IAAO,uCACKC,SAAA,oCAEd,CACED,IAAO,sCACKC,SAAA,oCAEd,CACED,IAAO,sCACKC,SAAA,oCAEd,CACED,IAAO,6CACKC,SAAA,oCAEd,CACED,IAAO,6CACKC,SAAA,oCAEd,CACED,IAAO,0CACKC,SAAA,oCAEd,CACED,IAAO,0CACKC,SAAA,oCAEd,CACED,IAAO,iDACKC,SAAA,oCAEd,CACED,IAAO,iDACKC,SAAA,oCAEd,CACED,IAAO,+BACKC,SAAA,oCAEd,CACED,IAAO,+BACKC,SAAA,oCAEd,CACED,IAAO,mDACKC,SAAA,oCAEd,CACED,IAAO,mDACKC,SAAA,oCAEd,CACED,IAAO,0CACKC,SAAA,oCAEd,CACED,IAAO,0CACKC,SAAA,oCAEd,CACED,IAAO,qCACKC,SAAA,oCAEd,CACED,IAAO,qCACKC,SAAA,oCAEd,CACED,IAAO,gDACKC,SAAA,oCAEd,CACED,IAAO,gDACKC,SAAA,oCAEd,CACED,IAAO,kDACKC,SAAA,oCAEd,CACED,IAAO,kDACKC,SAAA,oCAEd,CACED,IAAO,oCACKC,SAAA,oCAEd,CACED,IAAO,oCACKC,SAAA,oCAEd,CACED,IAAO,wCACKC,SAAA,oCAEd,CACED,IAAO,wCACKC,SAAA,oCAEd,CACED,IAAO,iDACKC,SAAA,oCAEd,CACED,IAAO,iDACKC,SAAA,oCAEd,CACED,IAAO,yDACKC,SAAA,oCAEd,CACED,IAAO,yDACKC,SAAA,oCAEd,CACED,IAAO,oDACKC,SAAA,oCAEd,CACED,IAAO,oDACKC,SAAA,oCAEd,CACED,IAAO,+EACKC,SAAA,oCAEd,CACED,IAAO,+EACKC,SAAA,oCAEd,CACED,IAAO,0CACKC,SAAA,oCAEd,CACED,IAAO,0CACKC,SAAA,oCAEd,CACED,IAAO,kCACKC,SAAA,oCAEd,CACED,IAAO,kCACKC,SAAA,oCAEd,CACED,IAAO,8BACKC,SAAA,oCAEd,CACED,IAAO,WACKC,SAAA,oCAEd,CACED,IAAO,oCACKC,SAAA,oCAEd,CACED,IAAO,qCACKC,SAAA,oCAEd,CACED,IAAO,oCACKC,SAAA,oCAEd,CACED,IAAO,8CACKC,SAAA,oCAEd,CACED,IAAO,6CACKC,SAAA,oCAEd,CACED,IAAO,6CACKC,SAAA,oCAEd,CACED,IAAO,8CACKC,SAAA,oCAEd,CACED,IAAO,+CACKC,SAAA,oCAEd,CACED,IAAO,8CACKC,SAAA,oCAEd,CACED,IAAO,+CACKC,SAAA,oCAEd,CACED,IAAO,gDACKC,SAAA,oCAEd,CACED,IAAO,+CACKC,SAAA,oCAEd,CACED,IAAO,sDACKC,SAAA,oCAEd,CACED,IAAO,qDACKC,SAAA,oCAEd,CACED,IAAO,qDACKC,SAAA,oCAEd,CACED,IAAO,aACKC,SAAA,oCAEd,CACED,IAAO,WACKC,SAAA,oCAEd,CACED,IAAO,iCACKC,SAAA,oCAEd,CACED,IAAO,6BACKC,SAAA,oCAEd,CACED,IAAO,6BACKC,SAAA,oCAEd,CACED,IAAO,kCACKC,SAAA,oCAEd,CACED,IAAO,kCACKC,SAAA,oCAEd,CACED,IAAO,+BACKC,SAAA,oCAEd,CACED,IAAO,oCACKC,SAAA,oCAEd,CACED,IAAO,sCACKC,SAAA,oCAEd,CACED,IAAO,8BACKC,SAAA,oCAEd,CACED,IAAO,WACKC,SAAA,qCAEb,IACHC,EAAAA"} \ No newline at end of file diff --git a/dist/shigu/image-yasuo.html b/dist/shigu/image-yasuo.html index ccb4a7c7..8040c2be 100644 --- a/dist/shigu/image-yasuo.html +++ b/dist/shigu/image-yasuo.html @@ -39,10 +39,10 @@ } - + -

    沉默王二2022年3月8日大约 8 分钟

    坦白从宽吧,我就是那个花了两天两夜把 1M 图片优化到 100kb 的家伙——王小二!

    自从因为一篇报道登上热搜后,我差点抑郁,每天要靠 50 片安眠药才能入睡。

    网络上曝光的那些关于一码通的消息,有真有假,我这里就不再澄清了。就说说我是怎么把图片从 1M 优化到 100kb 的故事吧。

    是的,由于系统群体规模和访问规模的特殊性,每一行代码、每一张图片、每一个技术文档都反复核准,优化再优化,精益求精。为确保系统运行得更高效,我们将一张图片从1MB压缩到500KB,再从500KB优化到100KB。

    这样的工作在外人看起来,简单到就好像悄悄给学妹塞一张情书就能让她做我女朋友一样简单。

    但殊不知,这其中蕴含着极高的技术含量!

    不信,我给你们普及下。

    一、图像压缩

    图像压缩是数据压缩技术在数字图像上的应用,目的是减少图像数据中的冗余信息,从而用更加高效的格式存储和传输数据。

    图像压缩可以是有损数据压缩,也可以是无损数据压缩。

    怎么样?

    是不是感觉图像压缩技术没有想象中那么简单了?

    更多关于图像压缩的资料可参考以下链接。

    机器之心:https://www.jiqizhixin.com/graph/technologies/08b2b25e-21a0-48e1-9de8-f91d424adfe1

    二、Java数字图像处理

    作为这次“20 多万外包项目”的“主力开发人员”,我这里就给大家介绍下 Java 数字图像处理技术吧,一开始我就是用它来处理图片的。

    数字图像处理(Digital Image Processing)是通过计算机对图像进行去除噪声、增强、复原、分割、提取特征等处理的方法和技术。

    输入的是图像信号,然后经过 DIP 进行有效的算法处理后,输出为数字信号。

    为了压缩图像,我们需要读取图像并将其转换成 BufferedImage 对象,BufferedImage 是 Image 类的一个子类,描述了一个具有可访问的图像数据缓冲区,由 ColorModel 和 Raster 的图像数据组成。

    废话我就不多说了,直接进入实战吧!

    三、图像压缩实战

    刚好我本地有一张之前用过的封面图,离 1M 只差 236 KB,可以拿来作为测试用。

    这其中要用到 ImageIO 类,这是一个静态类,提供了一系列方法用来读和写图像,同时还可以对图像进行简单的编码和解码。

    比如说通过 ImageIO.read() 可以将图像读取到 BufferedImage 对象:

    File input = new File("ceshi.jpg");
    +    

    沉默王二2022年3月8日大约 8 分钟

    坦白从宽吧,我就是那个花了两天两夜把 1M 图片优化到 100kb 的家伙——王小二!

    自从因为一篇报道登上热搜后,我差点抑郁,每天要靠 50 片安眠药才能入睡。

    网络上曝光的那些关于一码通的消息,有真有假,我这里就不再澄清了。就说说我是怎么把图片从 1M 优化到 100kb 的故事吧。

    是的,由于系统群体规模和访问规模的特殊性,每一行代码、每一张图片、每一个技术文档都反复核准,优化再优化,精益求精。为确保系统运行得更高效,我们将一张图片从1MB压缩到500KB,再从500KB优化到100KB。

    这样的工作在外人看起来,简单到就好像悄悄给学妹塞一张情书就能让她做我女朋友一样简单。

    但殊不知,这其中蕴含着极高的技术含量!

    不信,我给你们普及下。

    一、图像压缩

    图像压缩是数据压缩技术在数字图像上的应用,目的是减少图像数据中的冗余信息,从而用更加高效的格式存储和传输数据。

    图像压缩可以是有损数据压缩,也可以是无损数据压缩。

    怎么样?

    是不是感觉图像压缩技术没有想象中那么简单了?

    更多关于图像压缩的资料可参考以下链接。

    机器之心:https://www.jiqizhixin.com/graph/technologies/08b2b25e-21a0-48e1-9de8-f91d424adfe1

    二、Java数字图像处理

    作为这次“20 多万外包项目”的“主力开发人员”,我这里就给大家介绍下 Java 数字图像处理技术吧,一开始我就是用它来处理图片的。

    数字图像处理(Digital Image Processing)是通过计算机对图像进行去除噪声、增强、复原、分割、提取特征等处理的方法和技术。

    输入的是图像信号,然后经过 DIP 进行有效的算法处理后,输出为数字信号。

    为了压缩图像,我们需要读取图像并将其转换成 BufferedImage 对象,BufferedImage 是 Image 类的一个子类,描述了一个具有可访问的图像数据缓冲区,由 ColorModel 和 Raster 的图像数据组成。

    废话我就不多说了,直接进入实战吧!

    三、图像压缩实战

    刚好我本地有一张之前用过的封面图,离 1M 只差 236 KB,可以拿来作为测试用。

    这其中要用到 ImageIO 类,这是一个静态类,提供了一系列方法用来读和写图像,同时还可以对图像进行简单的编码和解码。

    比如说通过 ImageIO.read() 可以将图像读取到 BufferedImage 对象:

    File input = new File("ceshi.jpg");
     BufferedImage image = ImageIO.read(input);
     

    比如说通过 ImageIO.getImageWritersByFormatName() 可以返回一个Iterator,其中包含了通过命名格式对图像进行编码的 ImageWriter。

    Iterator<ImageWriter> writers =  ImageIO.getImageWritersByFormatName("jpg");
     ImageWriter writer = (ImageWriter) writers.next();
    @@ -99,6 +99,6 @@ param.setCom
     

    MatOfInt 的构造参数是一个可变参数,第一个参数 IMWRITE_JPEG_QUALITY 表示对图片的质量进行改变,第二个是质量因子,1-100,值越大表示质量越高。

    执行代码后得到的图片如下所示:

    借这个机会,来对比下 OpenCV 和 JDK 原生 API 在压缩图像时所使用的时间。

    这是我本机的配置情况,早年买的顶配 iMac,也是我的主力机。一开始只有 16 G 内存,后来加了一个 16 G 内存条,不过最近半年电脑突然死机重启的频率明显提高了,不知道是不是 Big Sur 这个操作系统的问题还是电脑硬件老了。

    结果如下所示:

    opencvCompress压缩完成,所花时间:1070
     jdkCompress压缩完成,所花时间:322
     

    压缩后的图片大小差不多,都是 19 KB,并且质量因子都是最低值。

    四、一点点心声

    经过上面的技术分析后,相信你们都明白了,把1M图片优化到100kb实在是一件“不太容易”的事情。。。。

    100KB 很小了吧?只有原来的 1/10。

    要知道,我可是连续加班了两天两夜,不眠不休。

    累到最后,我趴在电脑上都睡着了。

    没想到哈喇子直接给电脑整短路了,我这才算是从梦里面吓醒来了!

    😔,生活不易,且行且珍惜吧~


    本篇已收录至 GitHub 上星标 1.6k+ star 的开源专栏《Java 程序员进阶之路》,据说每一个优秀的 Java 程序员都喜欢她,风趣幽默、通俗易懂。内容包括 Java 基础、Java 并发编程、Java 虚拟机、Java 企业级开发、Java 面试等核心知识点。学 Java,就认准 Java 程序员进阶之路😄。

    https://github.com/itwanger/toBeBetterJavaeropen in new window

    star 了这个仓库就等于你拥有了成为了一名优秀 Java 工程师的潜力。也可以戳下面的链接跳转到《Java 程序员进阶之路》的官网网址,开始愉快的学习之旅吧。

    https://tobebetterjavaer.com/open in new window

    image

    没有什么使我停留——除了目的,纵然岸旁有玫瑰、有绿荫、有宁静的港湾,我是不系之舟

    - + diff --git a/dist/shigu/log4j2.html b/dist/shigu/log4j2.html index b4717fdf..bc4689f5 100644 --- a/dist/shigu/log4j2.html +++ b/dist/shigu/log4j2.html @@ -39,10 +39,10 @@ } - + -

    沉默王二2021年12月23日大约 3 分钟

    长话短说吧。

    相信大家已经被 Log4j2 的重大漏洞刷屏了,估计有不少小伙伴此时此刻已经累趴下了。很不幸,我的小老弟小二的 Spring Boot 项目中恰好用的就是 Log4j2,版本特喵的还是 2.14.1,在这次漏洞波及的版本范围之内。

    第一时间从网上得知这个漏洞的消息后,小二吓尿了。赶紧跑过来问老王怎么解决。

    老王先是给小二提供了一些临时性的建议,比如说:

    JVM 参数添加 -Dlog4j2.formatMsgNoLookups=true
    +    

    沉默王二2021年12月23日大约 3 分钟

    长话短说吧。

    相信大家已经被 Log4j2 的重大漏洞刷屏了,估计有不少小伙伴此时此刻已经累趴下了。很不幸,我的小老弟小二的 Spring Boot 项目中恰好用的就是 Log4j2,版本特喵的还是 2.14.1,在这次漏洞波及的版本范围之内。

    第一时间从网上得知这个漏洞的消息后,小二吓尿了。赶紧跑过来问老王怎么解决。

    老王先是给小二提供了一些临时性的建议,比如说:

    JVM 参数添加 -Dlog4j2.formatMsgNoLookups=true
     log4j2.formatMsgNoLookups=True
     FORMAT_MESSAGES_PATTERN_DISABLE_LOOKUPS 设置为true
     

    并且老王也在时刻的关注着 Log4j2 的官网和 Spring Boot GitHub 仓库的最新消息。

    Java 后端开发的小伙伴应该都知道,Log4j、SLF4J、Logback 这 3 个日志组件是一个爹——Ceki Gulcu,但 Log4j 2 却是例外,它是 Apache 基金会的产品。

    所以这波超级高危漏洞的锅必须得由 Apache 来背。并且波及范围非常广,已知受影响的应用程序和组件有:

    • Spring-boot-strater-log4j2
    • Apache Solr
    • Apache Flink
    • Apache Druid

    并且只要是在 Log4j 2.x <= 2.14.1 之间的版本,都将受到影响——注定被载入史册的一波 bug 啊。

    目前,Log4j2 的官网已经发布了 Log4j2 2.15.0 正式版,来解决此次漏洞。

    那随着 Log4j2 2.15.0 正式版的发布,Spring Boot 的 GitHub 仓库提的这些关于 Log4j2 的 issue 都已经处于关闭状态了。

    看到这些消息后,老王紧张的情绪一下子就缓解了下来,就像吃了一颗定心丸,赶紧去通知小二不用再提心吊胆了,直接一行代码搞定。

    <properties>
    @@ -70,6 +70,6 @@ FORMAT_MESSAGES_PATTERN_DISABLE_LOOKUPS 设置为true
         }
     }
     

    具体的攻击手段可以参考这里:

    https://github.com/apache/pulsar/issues/13232

    下图是程序猿阿朗画的简单的攻击链路步骤图。

    感兴趣的小伙伴可以在本地复现一下,但千万不要不当利用哦!

    再次提醒大家一下,排查自己的项目是否引入了 Apache log4j-core Jar 包。

    如果存在依赖引入,且在受影响版本范围内,请升级到 Apache Log4j2 2.15.0 版本,目前已经 release。

    - + diff --git a/dist/sidebar/computer-base.html b/dist/sidebar/computer-base.html index 19c01066..252c52b9 100644 --- a/dist/sidebar/computer-base.html +++ b/dist/sidebar/computer-base.html @@ -39,10 +39,10 @@ } - + - - +

    计算机基础

    沉默王二2022年3月9日小于 1 分钟

    + diff --git a/dist/sidebar/herongwei/mysql.html b/dist/sidebar/herongwei/mysql.html index 65c00d93..1bca133b 100644 --- a/dist/sidebar/herongwei/mysql.html +++ b/dist/sidebar/herongwei/mysql.html @@ -39,10 +39,10 @@ } - + -

    精选数据库60道面试题必看👍

    沉默王二2022年3月9日
    • 数据库
    • MySQL
    大约 37 分钟

    精选数据库60道面试题必看👍

    图文详解 60 道 MySQL 面试高频题,这次吊打面试官,我觉得稳了(手动 dog)。整理:沉默王二,戳转载链接open in new window,里面有局详细的思维导图;作者:herongwei,戳原文链接open in new window

    基础

    1、关系型和非关系型数据库的区别?

    关系型数据库的优点

    • 容易理解,因为它采用了关系模型来组织数据。
    • 可以保持数据的一致性。
    • 数据更新的开销比较小。
    • 支持复杂查询(带 where 子句的查询)

    非关系型数据库(NOSQL)的优点

    • 无需经过 SQL 层的解析,读写效率高。
    • 基于键值对,读写性能很高,易于扩展
    • 可以支持多种类型数据的存储,如图片,文档等等。
    • 扩展(可分为内存性数据库以及文档型数据库,比如 Redis,MongoDB,HBase 等,适合场景:数据量大高可用的日志系统/地理位置存储系统)。

    2、详细说一下一条 MySQL 语句执行的步骤

    Server 层按顺序执行 SQL 的步骤为:

    • 客户端请求 -> 连接器(验证用户身份,给予权限)
    • 查询缓存(存在缓存则直接返回,不存在则执行后续操作)
    • 分析器(对 SQL 进行词法分析和语法分析操作)
    • 优化器(主要对执行的 SQL 优化选择最优的执行方案方法)
    • 执行器(执行时会先看用户是否有执行权限,有才去使用这个引擎提供的接口)-> 去引擎层获取数据返回(如果开启查询缓存则会缓存查询结果)

    索引相关

    3、MySQL 使用索引的原因?

    根本原因

    • 索引的出现,就是为了提高数据查询的效率,就像书的目录一样。
    • 对于数据库的表而言,索引其实就是它的“目录”。

    扩展

    • 创建唯一性索引,可以保证数据库表中每一行数据的唯一性。
    • 帮助引擎层避免排序和临时表
    • 将随机 IO 变为顺序 IO,加速表和表之间的连接。

    4、索引的三种常见底层数据结构以及优缺点

    三种常见的索引底层数据结构:分别是哈希表、有序数组和搜索树。

    • 哈希表这种适用于等值查询的场景,比如 memcached 以及其它一些 NoSQL 引擎,不适合范围查询。
    • 有序数组索引只适用于静态存储引擎,等值和范围查询性能好,但更新数据成本高。
    • N 叉树由于读写上的性能优点以及适配磁盘访问模式以及广泛应用在数据库引擎中。
    • 扩展(以 InnoDB 的一个整数字段索引为例,这个 N 差不多是 1200。棵树高是 4 的时候,就可以存 1200 的 3 次方个值,这已经 17 亿了。考虑到树根的数据块总是在内存中的,一个 10 亿行的表上一个整数字段的索引,查找一个值最多只需要访问 3 次磁盘。其实,树的第二层也有很大概率在内存中,那么访问磁盘的平均次数就更少了。)

    5、索引的常见类型以及它是如何发挥作用的?

    根据叶子节点的内容,索引类型分为主键索引和非主键索引。

    • 主键索引的叶子节点存的整行数据,在InnoDB里也被称为聚簇索引。
    • 非主键索引叶子节点存的主键的值,在InnoDB里也被称为二级索引。

    6、MyISAM 和 InnoDB 实现 B 树索引方式的区别是什么?

    • InnoDB 存储引擎:B+ 树索引的叶子节点保存数据本身,其数据文件本身就是索引文件。
    • MyISAM 存储引擎:B+ 树索引的叶子节点保存数据的物理地址,叶节点的 data 域存放的是数据记录的地址,索引文件和数据文件是分离的。

    7、InnoDB 为什么设计 B+ 树索引?

    两个考虑因素:

    • InnoDB 需要执行的场景和功能需要在特定查询上拥有较强的性能。
    • CPU 将磁盘上的数据加载到内存中需要花费大量时间。

    为什么选择 B+ 树:

    • 哈希索引虽然能提供O(1)复杂度查询,但对范围查询和排序却无法很好的支持,最终会导致全表扫描。

    • B 树能够在非叶子节点存储数据,但会导致在查询连续数据可能带来更多的随机 IO。

    • 而 B+ 树的所有叶节点可以通过指针来相互连接,减少顺序遍历带来的随机 IO。

    • 普通索引还是唯一索引?

      由于唯一索引用不上 change buffer 的优化机制,因此如果业务可以接受,从性能角度出发建议你优先考虑非唯一索引。

    8、什么是覆盖索引和索引下推?

    覆盖索引:

    • 在某个查询里面,索引 k 已经“覆盖了”我们的查询需求,称为覆盖索引。

    • 覆盖索引可以减少树的搜索次数,显著提升查询性能,所以使用覆盖索引是一个常用的性能优化手段。

    索引下推:

    • MySQL 5.6 引入的索引下推优化(index condition pushdown), 可以在索引遍历过程中,对索引中包含的字段先做判断,直接过滤掉不满足条件的记录,减少回表次数。

    9、哪些操作会导致索引失效?

    • 对索引使用左或者左右模糊匹配,也就是 like %xx 或者 like %xx% 这两种方式都会造成索引失效。原因在于查询的结果可能是多个,不知道从哪个索引值开始比较,于是就只能通过全表扫描的方式来查询。
    • 对索引进行函数/对索引进行表达式计算,因为索引保持的是索引字段的原始值,而不是经过函数计算的值,自然就没办法走索引。
    • 对索引进行隐式转换相当于使用了新函数。
    • WHERE 子句中的 OR语句,只要有条件列不是索引列,就会进行全表扫描。

    10、字符串加索引

    • 直接创建完整索引,这样可能会比较占用空间。
    • 创建前缀索引,节省空间,但会增加查询扫描次数,并且不能使用覆盖索引。
    • 倒序存储,再创建前缀索引,用于绕过字符串本身前缀的区分度不够的问题。
    • 创建 hash 字段索引,查询性能稳定,有额外的存储和计算消耗,跟第三种方式一样,都不支持范围扫描。

    日志相关

    11、MySQL 的 change buffer 是什么?

    • 当需要更新一个数据页时,如果数据页在内存中就直接更新;而如果这个数据页还没有在内存中的话,在不影响数据一致性的前提下,InnoDB 会将这些更新操作缓存在 change buffer 中。
    • 这样就不需要从磁盘中读入这个数据页了,在下次查询需要访问这个数据页的时候,将数据页读入内存,然后执行 change buffer 中与这个页有关的操作。通过这种方式就能保证这个数据逻辑的正确性。
    • 注意唯一索引的更新就不能使用 change buffer,实际上也只有普通索引可以使用。
    • 适用场景:
      • 对于写多读少的业务来说,页面在写完以后马上被访问到的概率比较小,此时 change buffer 的使用效果最好。这种业务模型常见的就是账单类、日志类的系统。
      • 反过来,假设一个业务的更新模式是写入之后马上会做查询,那么即使满足了条件,将更新先记录在 change buffer,但之后由于马上要访问这个数据页,会立即触发 merge 过程。这样随机访问 IO 的次数不会减少,反而增加了 change buffer 的维护代价。

    12、MySQL 是如何判断一行扫描数的?

    • MySQL 在真正开始执行语句之前,并不能精确地知道满足这个条件的记录有多少条。
    • 而只能根据统计信息来估算记录数。这个统计信息就是索引的“区分度。

    13、MySQL 的 redo log 和 binlog 区别?

    14、为什么需要 redo log?

    • redo log 主要用于 MySQL 异常重启后的一种数据恢复手段,确保了数据的一致性。
    • 其实是为了配合 MySQL 的 WAL 机制。因为 MySQL 进行更新操作,为了能够快速响应,所以采用了异步写回磁盘的技术,写入内存后就返回。但是这样,会存在 crash后 内存数据丢失的隐患,而 redo log 具备 crash safe 的能力。

    15、为什么 redo log 具有 crash-safe 的能力,是 binlog 无法替代的?

    第一点:redo log 可确保 innoDB 判断哪些数据已经刷盘,哪些数据还没有

    • redo log 和 binlog 有一个很大的区别就是,一个是循环写,一个是追加写。也就是说 redo log 只会记录未刷盘的日志,已经刷入磁盘的数据都会从 redo log 这个有限大小的日志文件里删除。binlog 是追加日志,保存的是全量的日志。

    • 当数据库 crash 后,想要恢复未刷盘但已经写入 redo log 和 binlog 的数据到内存时,binlog 是无法恢复的。虽然 binlog 拥有全量的日志,但没有一个标志让 innoDB 判断哪些数据已经刷盘,哪些数据还没有。

    • 但 redo log 不一样,只要刷入磁盘的数据,都会从 redo log 中抹掉,因为是循环写!数据库重启后,直接把 redo log 中的数据都恢复至内存就可以了。

    第二点:如果 redo log 写入失败,说明此次操作失败,事务也不可能提交

    • redo log 每次更新操作完成后,就一定会写入日志,如果写入失败,说明此次操作失败,事务也不可能提交。
    • redo log 内部结构是基于页的,记录了这个页的字段值变化,只要crash后读取redo log进行重放,就可以恢复数据。
    • 这就是为什么 redo log 具有 crash-safe 的能力,而 binlog 不具备。

    16、当数据库 crash 后,如何恢复未刷盘的数据到内存中?

    根据 redo log 和 binlog 的两阶段提交,未持久化的数据分为几种情况:

    • change buffer 写入,redo log 虽然做了 fsync 但未 commit,binlog 未 fsync 到磁盘,这部分数据丢失。

    • change buffer 写入,redo log fsync 未 commit,binlog 已经 fsync 到磁盘,先从 binlog 恢复 redo log,再从 redo log 恢复 change buffer。

    • change buffer 写入,redo log 和 binlog 都已经 fsync,直接从 redo log 里恢复。

    17、redo log 写入方式?

    redo log包括两部分内容,分别是内存中的日志缓冲(redo log buffer)和磁盘上的日志文件(redo log file)。

    MySQL 每执行一条 DML 语句,会先把记录写入 redo log buffer(用户空间) ,再保存到内核空间的缓冲区 OS-buffer 中,后续某个时间点再一次性将多个操作记录写到 redo log file(刷盘) 。这种先写日志,再写磁盘的技术,就是WAL

    可以发现,redo log buffer写入到redo log file,是经过OS buffer中转的。其实可以通过参数innodb_flush_log_at_trx_commit进行配置,参数值含义如下:

    • 0:称为延迟写,事务提交时不会将redo log buffer中日志写入到OS buffer,而是每秒写入OS buffer并调用写入到redo log file中。
    • 1:称为实时写,实时刷”,事务每次提交都会将redo log buffer中的日志写入OS buffer并保存到redo log file中。
    • 2: 称为实时写,延迟刷。每次事务提交写入到OS buffer,然后是每秒将日志写入到redo log file。

    18、redo log 的执行流程?

    我们来看下Redo log的执行流程,假设执行的 SQL 如下:

    update T set a =1 where id =666
    +    

    精选数据库60道面试题必看👍

    沉默王二2022年3月9日
    • 数据库
    • MySQL
    大约 37 分钟

    精选数据库60道面试题必看👍

    图文详解 60 道 MySQL 面试高频题,这次吊打面试官,我觉得稳了(手动 dog)。整理:沉默王二,戳转载链接open in new window,里面有局详细的思维导图;作者:herongwei,戳原文链接open in new window

    基础

    1、关系型和非关系型数据库的区别?

    关系型数据库的优点

    • 容易理解,因为它采用了关系模型来组织数据。
    • 可以保持数据的一致性。
    • 数据更新的开销比较小。
    • 支持复杂查询(带 where 子句的查询)

    非关系型数据库(NOSQL)的优点

    • 无需经过 SQL 层的解析,读写效率高。
    • 基于键值对,读写性能很高,易于扩展
    • 可以支持多种类型数据的存储,如图片,文档等等。
    • 扩展(可分为内存性数据库以及文档型数据库,比如 Redis,MongoDB,HBase 等,适合场景:数据量大高可用的日志系统/地理位置存储系统)。

    2、详细说一下一条 MySQL 语句执行的步骤

    Server 层按顺序执行 SQL 的步骤为:

    • 客户端请求 -> 连接器(验证用户身份,给予权限)
    • 查询缓存(存在缓存则直接返回,不存在则执行后续操作)
    • 分析器(对 SQL 进行词法分析和语法分析操作)
    • 优化器(主要对执行的 SQL 优化选择最优的执行方案方法)
    • 执行器(执行时会先看用户是否有执行权限,有才去使用这个引擎提供的接口)-> 去引擎层获取数据返回(如果开启查询缓存则会缓存查询结果)

    索引相关

    3、MySQL 使用索引的原因?

    根本原因

    • 索引的出现,就是为了提高数据查询的效率,就像书的目录一样。
    • 对于数据库的表而言,索引其实就是它的“目录”。

    扩展

    • 创建唯一性索引,可以保证数据库表中每一行数据的唯一性。
    • 帮助引擎层避免排序和临时表
    • 将随机 IO 变为顺序 IO,加速表和表之间的连接。

    4、索引的三种常见底层数据结构以及优缺点

    三种常见的索引底层数据结构:分别是哈希表、有序数组和搜索树。

    • 哈希表这种适用于等值查询的场景,比如 memcached 以及其它一些 NoSQL 引擎,不适合范围查询。
    • 有序数组索引只适用于静态存储引擎,等值和范围查询性能好,但更新数据成本高。
    • N 叉树由于读写上的性能优点以及适配磁盘访问模式以及广泛应用在数据库引擎中。
    • 扩展(以 InnoDB 的一个整数字段索引为例,这个 N 差不多是 1200。棵树高是 4 的时候,就可以存 1200 的 3 次方个值,这已经 17 亿了。考虑到树根的数据块总是在内存中的,一个 10 亿行的表上一个整数字段的索引,查找一个值最多只需要访问 3 次磁盘。其实,树的第二层也有很大概率在内存中,那么访问磁盘的平均次数就更少了。)

    5、索引的常见类型以及它是如何发挥作用的?

    根据叶子节点的内容,索引类型分为主键索引和非主键索引。

    • 主键索引的叶子节点存的整行数据,在InnoDB里也被称为聚簇索引。
    • 非主键索引叶子节点存的主键的值,在InnoDB里也被称为二级索引。

    6、MyISAM 和 InnoDB 实现 B 树索引方式的区别是什么?

    • InnoDB 存储引擎:B+ 树索引的叶子节点保存数据本身,其数据文件本身就是索引文件。
    • MyISAM 存储引擎:B+ 树索引的叶子节点保存数据的物理地址,叶节点的 data 域存放的是数据记录的地址,索引文件和数据文件是分离的。

    7、InnoDB 为什么设计 B+ 树索引?

    两个考虑因素:

    • InnoDB 需要执行的场景和功能需要在特定查询上拥有较强的性能。
    • CPU 将磁盘上的数据加载到内存中需要花费大量时间。

    为什么选择 B+ 树:

    • 哈希索引虽然能提供O(1)复杂度查询,但对范围查询和排序却无法很好的支持,最终会导致全表扫描。

    • B 树能够在非叶子节点存储数据,但会导致在查询连续数据可能带来更多的随机 IO。

    • 而 B+ 树的所有叶节点可以通过指针来相互连接,减少顺序遍历带来的随机 IO。

    • 普通索引还是唯一索引?

      由于唯一索引用不上 change buffer 的优化机制,因此如果业务可以接受,从性能角度出发建议你优先考虑非唯一索引。

    8、什么是覆盖索引和索引下推?

    覆盖索引:

    • 在某个查询里面,索引 k 已经“覆盖了”我们的查询需求,称为覆盖索引。

    • 覆盖索引可以减少树的搜索次数,显著提升查询性能,所以使用覆盖索引是一个常用的性能优化手段。

    索引下推:

    • MySQL 5.6 引入的索引下推优化(index condition pushdown), 可以在索引遍历过程中,对索引中包含的字段先做判断,直接过滤掉不满足条件的记录,减少回表次数。

    9、哪些操作会导致索引失效?

    • 对索引使用左或者左右模糊匹配,也就是 like %xx 或者 like %xx% 这两种方式都会造成索引失效。原因在于查询的结果可能是多个,不知道从哪个索引值开始比较,于是就只能通过全表扫描的方式来查询。
    • 对索引进行函数/对索引进行表达式计算,因为索引保持的是索引字段的原始值,而不是经过函数计算的值,自然就没办法走索引。
    • 对索引进行隐式转换相当于使用了新函数。
    • WHERE 子句中的 OR语句,只要有条件列不是索引列,就会进行全表扫描。

    10、字符串加索引

    • 直接创建完整索引,这样可能会比较占用空间。
    • 创建前缀索引,节省空间,但会增加查询扫描次数,并且不能使用覆盖索引。
    • 倒序存储,再创建前缀索引,用于绕过字符串本身前缀的区分度不够的问题。
    • 创建 hash 字段索引,查询性能稳定,有额外的存储和计算消耗,跟第三种方式一样,都不支持范围扫描。

    日志相关

    11、MySQL 的 change buffer 是什么?

    • 当需要更新一个数据页时,如果数据页在内存中就直接更新;而如果这个数据页还没有在内存中的话,在不影响数据一致性的前提下,InnoDB 会将这些更新操作缓存在 change buffer 中。
    • 这样就不需要从磁盘中读入这个数据页了,在下次查询需要访问这个数据页的时候,将数据页读入内存,然后执行 change buffer 中与这个页有关的操作。通过这种方式就能保证这个数据逻辑的正确性。
    • 注意唯一索引的更新就不能使用 change buffer,实际上也只有普通索引可以使用。
    • 适用场景:
      • 对于写多读少的业务来说,页面在写完以后马上被访问到的概率比较小,此时 change buffer 的使用效果最好。这种业务模型常见的就是账单类、日志类的系统。
      • 反过来,假设一个业务的更新模式是写入之后马上会做查询,那么即使满足了条件,将更新先记录在 change buffer,但之后由于马上要访问这个数据页,会立即触发 merge 过程。这样随机访问 IO 的次数不会减少,反而增加了 change buffer 的维护代价。

    12、MySQL 是如何判断一行扫描数的?

    • MySQL 在真正开始执行语句之前,并不能精确地知道满足这个条件的记录有多少条。
    • 而只能根据统计信息来估算记录数。这个统计信息就是索引的“区分度。

    13、MySQL 的 redo log 和 binlog 区别?

    14、为什么需要 redo log?

    • redo log 主要用于 MySQL 异常重启后的一种数据恢复手段,确保了数据的一致性。
    • 其实是为了配合 MySQL 的 WAL 机制。因为 MySQL 进行更新操作,为了能够快速响应,所以采用了异步写回磁盘的技术,写入内存后就返回。但是这样,会存在 crash后 内存数据丢失的隐患,而 redo log 具备 crash safe 的能力。

    15、为什么 redo log 具有 crash-safe 的能力,是 binlog 无法替代的?

    第一点:redo log 可确保 innoDB 判断哪些数据已经刷盘,哪些数据还没有

    • redo log 和 binlog 有一个很大的区别就是,一个是循环写,一个是追加写。也就是说 redo log 只会记录未刷盘的日志,已经刷入磁盘的数据都会从 redo log 这个有限大小的日志文件里删除。binlog 是追加日志,保存的是全量的日志。

    • 当数据库 crash 后,想要恢复未刷盘但已经写入 redo log 和 binlog 的数据到内存时,binlog 是无法恢复的。虽然 binlog 拥有全量的日志,但没有一个标志让 innoDB 判断哪些数据已经刷盘,哪些数据还没有。

    • 但 redo log 不一样,只要刷入磁盘的数据,都会从 redo log 中抹掉,因为是循环写!数据库重启后,直接把 redo log 中的数据都恢复至内存就可以了。

    第二点:如果 redo log 写入失败,说明此次操作失败,事务也不可能提交

    • redo log 每次更新操作完成后,就一定会写入日志,如果写入失败,说明此次操作失败,事务也不可能提交。
    • redo log 内部结构是基于页的,记录了这个页的字段值变化,只要crash后读取redo log进行重放,就可以恢复数据。
    • 这就是为什么 redo log 具有 crash-safe 的能力,而 binlog 不具备。

    16、当数据库 crash 后,如何恢复未刷盘的数据到内存中?

    根据 redo log 和 binlog 的两阶段提交,未持久化的数据分为几种情况:

    • change buffer 写入,redo log 虽然做了 fsync 但未 commit,binlog 未 fsync 到磁盘,这部分数据丢失。

    • change buffer 写入,redo log fsync 未 commit,binlog 已经 fsync 到磁盘,先从 binlog 恢复 redo log,再从 redo log 恢复 change buffer。

    • change buffer 写入,redo log 和 binlog 都已经 fsync,直接从 redo log 里恢复。

    17、redo log 写入方式?

    redo log包括两部分内容,分别是内存中的日志缓冲(redo log buffer)和磁盘上的日志文件(redo log file)。

    MySQL 每执行一条 DML 语句,会先把记录写入 redo log buffer(用户空间) ,再保存到内核空间的缓冲区 OS-buffer 中,后续某个时间点再一次性将多个操作记录写到 redo log file(刷盘) 。这种先写日志,再写磁盘的技术,就是WAL

    可以发现,redo log buffer写入到redo log file,是经过OS buffer中转的。其实可以通过参数innodb_flush_log_at_trx_commit进行配置,参数值含义如下:

    • 0:称为延迟写,事务提交时不会将redo log buffer中日志写入到OS buffer,而是每秒写入OS buffer并调用写入到redo log file中。
    • 1:称为实时写,实时刷”,事务每次提交都会将redo log buffer中的日志写入OS buffer并保存到redo log file中。
    • 2: 称为实时写,延迟刷。每次事务提交写入到OS buffer,然后是每秒将日志写入到redo log file。

    18、redo log 的执行流程?

    我们来看下Redo log的执行流程,假设执行的 SQL 如下:

    update T set a =1 where id =666
     

    1. MySQL 客户端将请求语句 update T set a =1 where id =666,发往 MySQL Server 层。
    2. MySQL Server 层接收到 SQL 请求后,对其进行分析、优化、执行等处理工作,将生成的 SQL 执行计划发到 InnoDB 存储引擎层执行。
    3. InnoDB 存储引擎层将a修改为1的这个操作记录到内存中。
    4. 记录到内存以后会修改 redo log 的记录,会在添加一行记录,其内容是需要在哪个数据页上做什么修改
    5. 此后,将事务的状态设置为 prepare ,说明已经准备好提交事务了。
    6. 等到 MySQL Server 层处理完事务以后,会将事务的状态设置为 commit,也就是提交该事务。
    7. 在收到事务提交的请求以后,redo log 会把刚才写入内存中的操作记录写入到磁盘中,从而完成整个日志的记录过程。

    19、binlog 的概念是什么,起到什么作用, 可以保证 crash-safe 吗?

    • binlog 是归档日志,属于 MySQL Server 层的日志。可以实现主从复制数据恢复两个作用。
    • 当需要恢复数据时,可以取出某个时间范围内的 binlog 进行重放恢复。
    • 但是 binlog 不可以做 crash safe,因为 crash 之前,binlog 可能没有写入完全 MySQL 就挂了。所以需要配合 redo log 才可以进行 crash safe。

    20、什么是两阶段提交?

    MySQL 将 redo log 的写入拆成了两个步骤:prepare 和 commit,中间再穿插写入binlog,这就是"两阶段提交"。

    而两阶段提交就是让这两个状态保持逻辑上的一致。redolog 用于恢复主机故障时的未更新的物理数据,binlog 用于备份操作。两者本身就是两个独立的个体,要想保持一致,就必须使用分布式事务的解决方案来处理。

    为什么需要两阶段提交呢?

    • 如果不用两阶段提交的话,可能会出现这样情况
    • 先写 redo log,crash 后 bin log 备份恢复时少了一次更新,与当前数据不一致。
    • 先写 bin log,crash 后,由于 redo log 没写入,事务无效,所以后续 bin log 备份恢复时,数据不一致。
    • 两阶段提交就是为了保证 redo log 和 binlog 数据的安全一致性。只有在这两个日志文件逻辑上高度一致了才能放心的使用。

    在恢复数据时,redolog 状态为 commit 则说明 binlog 也成功,直接恢复数据;如果 redolog 是 prepare,则需要查询对应的 binlog事务是否成功,决定是回滚还是执行。

    21、MySQL 怎么知道 binlog 是完整的?

    一个事务的 binlog 是有完整格式的:

    • statement 格式的 binlog,最后会有 COMMIT;
    • row 格式的 binlog,最后会有一个 XID event。

    22、什么是 WAL 技术,有什么优点?

    WAL,中文全称是 Write-Ahead Logging,它的关键点就是日志先写内存,再写磁盘。MySQL 执行更新操作后,在真正把数据写入到磁盘前,先记录日志

    好处是不用每一次操作都实时把数据写盘,就算 crash 后也可以通过redo log 恢复,所以能够实现快速响应 SQL 语句。

    23、binlog 日志的三种格式

    binlog 日志有三种格式

    • Statement:基于SQL语句的复制((statement-based replication,SBR))
    • Row:基于行的复制。(row-based replication,RBR)
    • Mixed:混合模式复制。(mixed-based replication,MBR)

    Statement格式

    每一条会修改数据的 SQL 都会记录在 binlog 中

    • 优点:不需要记录每一行的变化,减少了binlog日志量,节约了IO,提高性能。
    • 缺点:由于记录的只是执行语句,为了这些语句能在备库上正确运行,还必须记录每条语句在执行的时候的一些相关信息,以保证所有语句能在备库得到和在主库端执行时候相同的结果。

    Row格式

    不记录 SQL 语句上下文相关信息,仅保存哪条记录被修改。

    • 优点:binlog 中可以不记录执行的 SQL 语句的上下文相关的信息,仅需要记录那一条记录被修改成什么了。所以rowlevel的日志内容会非常清楚的记录下每一行数据修改的细节。不会出现某些特定情况下的存储过程、或 function、或trigger的调用和触发无法被正确复制的问题。
    • 缺点:可能会产生大量的日志内容。

    Mixed格式

    实际上就是 Statement 与 Row 的结合。一般的语句修改使用 statment 格式保存 binlog,如一些函数,statement 无法完成主从复制的操作,则采用 row 格式保存 binlog,MySQL 会根据执行的每一条具体的 SQL 语句来区分对待记录的日志形式。

    24、redo log日志格式

    redo log buffer (内存中)是由首尾相连的四个文件组成的,它们分别是:ib_logfile_1、ib_logfile_2、ib_logfile_3、ib_logfile_4。

    • write pos 是当前记录的位置,一边写一边后移,写到第 3 号文件末尾后就回到 0 号文件开头。
    • checkpoint 是当前要擦除的位置,也是往后推移并且循环的,擦除记录前要把记录更新到数据文件。
    • write pos 和 checkpoint 之间的是“粉板”上还空着的部分,可以用来记录新的操作。
    • 如果 write pos 追上 checkpoint,表示“粉板”满了,这时候不能再执行新的更新,得停下来先擦掉一些记录,把 checkpoint 推进一下。
    • 有了 redo log,当数据库发生宕机重启后,可通过 redo log将未落盘的数据(check point之后的数据)恢复,保证已经提交的事务记录不会丢失,这种能力称为crash-safe

    25、原本可以执行得很快的 SQL 语句,执行速度却比预期的慢很多,原因是什么?如何解决?

    原因:从大到小可分为四种情况

    • MySQL 数据库本身被堵住了,比如:系统或网络资源不够。
    • SQL 语句被堵住了,比如:表锁,行锁等,导致存储引擎不执行对应的 SQL 语句。
    • 确实是索引使用不当,没有走索引。
    • 表中数据的特点导致的,走了索引,但回表次数庞大。

    解决:

    • 考虑采用 force index 强行选择一个索引
    • 考虑修改语句,引导 MySQL 使用我们期望的索引。比如把“order by b limit 1” 改成 “order by b,a limit 1” ,语义的逻辑是相同的。
    • 第三种方法是,在有些场景下,可以新建一个更合适的索引,来提供给优化器做选择,或删掉误用的索引。
    • 如果确定是索引根本没必要,可以考虑删除索引。

    26、InnoDB 数据页结构

    一个数据页大致划分七个部分

    • File Header:表示页的一些通用信息,占固定的38字节。
    • page Header:表示数据页专有信息,占固定的56字节。
    • inimum+Supermum:两个虚拟的伪记录,分别表示页中的最小记录和最大记录,占固定的26字节。
    • User Records:真正存储我们插入的数据,大小不固定。
    • Free Space:页中尚未使用的部分,大小不固定。
    • Page Directory:页中某些记录的相对位置,也就是各个槽对应的记录在页面中的地址偏移量。
    • File Trailer:用于检验页是否完整,占固定大小 8 字节。

    数据相关

    27、MySQL 是如何保证数据不丢失的?

    • 只要redolog 和 binlog 保证持久化磁盘就能确保MySQL异常重启后回复数据
    • 在恢复数据时,redolog 状态为 commit 则说明 binlog 也成功,直接恢复数据;如果 redolog 是 prepare,则需要查询对应的 binlog事务是否成功,决定是回滚还是执行。

    28、误删数据怎么办?

    DBA 的最核心的工作就是保证数据的完整性,先要做好预防,预防的话大概是通过这几个点:

    • 权限控制与分配(数据库和服务器权限)
    • 制作操作规范
    • 定期给开发进行培训
    • 搭建延迟备库
    • 做好 SQL 审计,只要是对线上数据有更改操作的语句(DML和DDL)都需要进行审核
    • 做好备份。备份的话又分为两个点 (1)如果数据量比较大,用物理备份 xtrabackup。定期对数据库进行全量备份,也可以做增量备份。 (2)如果数据量较少,用 mysqldump 或者 mysqldumper。再利用 binlog 来恢复或者搭建主从的方式来恢复数据。 定期备份binlog 文件也是很有必要的
    • 如果发生了数据删除的操作,又可以从以下几个点来恢复:
    • DML 误操作语句造成数据不完整或者丢失。可以通过 flashback,美团的 myflash,也是一个不错的工具,本质都差不多,都是先解析 binlog event,然后在进行反转。把 delete 反转为insert,insert 反转为 delete,update前后 image 对调。所以必须设置binlog_format=row 和 binlog_row_image=full,切记恢复数据的时候,应该先恢复到临时的实例,然后在恢复回主库上。
    • DDL语句误操作(truncate和drop),由于DDL语句不管 binlog_format 是 row 还是 statement ,在 binlog 里都只记录语句,不记录 image 所以恢复起来相对要麻烦得多。只能通过全量备份+应用 binlog 的方式来恢复数据。一旦数据量比较大,那么恢复时间就特别长
    • rm 删除:使用备份跨机房,或者最好是跨城市保存。

    29、drop、truncate 和 delete 的区别

    • DELETE 语句执行删除的过程是每次从表中删除一行,并且同时将该行的删除操作作为事务记录在日志中保存以便进行进行回滚操作。
    • TRUNCATE TABLE 则一次性地从表中删除所有的数据并不把单独的删除操作记录记入日志保存,删除行是不能恢复的。并且在删除的过程中不会激活与表有关的删除触发器。执行速度快。
    • drop语句将表所占用的空间全释放掉。
    • 在速度上,一般来说,drop> truncate > delete。
    • 如果想删除部分数据用 delete,注意带上 where 子句,回滚段要足够大;
    • 如果想删除表,当然用 drop; 如果想保留表而将所有数据删除,如果和事务无关,用 truncate 即可;
    • 如果和事务有关,或者想触发 trigger,还是用 delete; 如果是整理表内部的碎片,可以用 truncate 跟上 reuse stroage,再重新导入/插入数据。

    30、在 MySQL 中有两个 kill 命令

    • 一个是 kill query + 线程 id,表示终止这个线程中正在执行的语句
    • 一个是 kill connection + 线程 id,这里 connection 可缺省,表示断开这个线程的连接

    kill 不掉的原因

    • kill命令被堵了,还没到位
    • kill命令到位了,但是没被立刻触发
    • kill命令被触发了,但执行完也需要时间

    31、如何理解 MySQL 的边读边发

    • 如果客户端接受慢,会导致 MySQL 服务端由于结果发不出去,这个事务的执行时间会很长。
    • 服务端并不需要保存一个完整的结果集,取数据和发数据的流程都是通过一个 next_buffer 来操作的。
    • 内存的数据页都是在 Buffer_Pool中操作的。
    • InnoDB 管理 Buffer_Pool 使用的是改进的 LRU 算法,使用链表实现,实现上,按照 5:3 的比例把整个 LRU 链表分成了 young 区域和 old 区域。

    32、MySQL 的大表查询为什么不会爆内存?

    • 由于 MySQL 是边读变发,因此对于数据量很大的查询结果来说,不会再 server 端保存完整的结果集,所以,如果客户端读结果不及时,会堵住 MySQL 的查询过程,但是不会把内存打爆。
    • InnoDB 引擎内部,由于有淘汰策略,InnoDB 管理 Buffer_Pool 使用的是改进的 LRU 算法,使用链表实现,实现上,按照 5:3 的比例把整个 LRU 链表分成了 young 区域和 old 区域。对冷数据的全扫描,影响也能做到可控制。

    33、MySQL 临时表的用法和特性

    • 只对当前session可见。
    • 可以与普通表重名。
    • 增删改查用的是临时表。
    • show tables 不显示普通表。
    • 在实际应用中,临时表一般用于处理比较复杂的计算逻辑。
    • 由于临时表是每个线程自己可见的,所以不需要考虑多个线程执行同一个处理时临时表的重名问题,在线程退出的时候,临时表会自动删除。

    34、MySQL 存储引擎介绍(InnoDB、MyISAM、MEMORY)

    • InnoDB 是事务型数据库的首选引擎,支持事务安全表 (ACID),支持行锁定和外键。MySQL5.5.5 之后,InnoDB 作为默认存储引擎
    • MyISAM 基于 ISAM 的存储引擎,并对其进行扩展。它是在 Web、数据存储和其他应用环境下最常用的存储引擎之一。MyISAM 拥有较高的插入、查询速度,但不支持事务。在 MySQL5.5.5 之前的版本中,MyISAM 是默认存储引擎
    • MEMORY 存储引擎将表中的数据存储到内存中,为查询和引用其他表数据提供快速访问。

    35、都说 InnoDB 好,那还要不要使用 MEMORY 引擎?

    • 内存表就是使用 memory 引擎创建的表
    • 为什么我不建议你在生产环境上使用内存表。这里的原因主要包括两个方面:锁粒度问题;数据持久化问题。
    • 由于重启会丢数据,如果一个备库重启,会导致主备同步线程停止;如果主库跟这个备库是双 M 架构,还可能导致主库的内存表数据被删掉。

    36、如果数据库误操作, 如何执行数据恢复?

    数据库在某个时候误操作,就可以找到距离误操作最近的时间节点的bin log,重放到临时数据库里,然后选择误删的数据节点,恢复到线上数据库。

    主从备份相关

    37、MySQL 是如何保证主备同步?

    主备关系的建立:

    • 一开始创建主备关系的时候,是由备库指定的,比如基于位点的主备关系,备库说“我要从binlog文件A的位置P”开始同步,主库就从这个指定的位置开始往后发。
    • 而主备关系搭建之后,是主库决定要发给数据给备库的,所以主库有新的日志也会发给备库。

    MySQL 主备切换流程:

    • 客户端读写都是直接访问A,而节点B是备库,只要将A的更新都同步过来,到本地执行就可以保证数据是相同的。
    • 当需要切换的时候就把节点换一下,A的节点B的备库

    一个事务完整的同步过程:

    • 备库B和主库A建立来了长链接,主库A内部专门线程用于维护了这个长链接。

    • 在备库B上通过changemaster命令设置主库A的IP端口用户名密码以及从哪个位置开始请求binlog包括文件名和日志偏移量

    • 在备库B上执行start-slave命令备库会启动两个线程:io_thread和sql_thread分别负责建立连接和读取中转日志进行解析执行

    • 备库读取主库传过来的binlog文件备库收到文件写到本地成为中转日志

    • 后来由于多线程复制方案的引入,sql_thread演化成了多个线程。

    38、什么是主备延迟

    主库和备库在执行同一个事务的时候出现时间差的问题,主要原因有:

    • 有些部署条件下,备库所在机器的性能要比主库性能差。
    • 备库的压力较大。
    • 大事务,一个主库上语句执行10分钟,那么这个事务可能会导致从库延迟10分钟。

    39、为什么要有多线程复制策略?

    • 因为单线程复制的能力全面低于多线程复制,对于更新压力较大的主库,备库可能是一直追不上主库的,带来的现象就是备库上seconds_behind_master值越来越大。
    • 在实际应用中,建议使用可靠性优先策略,减少主备延迟,提升系统可用性,尽量减少大事务操作,把大事务拆分小事务。

    40、MySQL 的并行策略有哪些?

    • 按表分发策略:如果两个事务更新不同的表,它们就可以并行。因为数据是存储在表里的,所以按表分发,可以保证两个 worker 不会更新同一行。缺点:如果碰到热点表,比如所有的更新事务都会涉及到某一个表的时候,所有事务都会被分配到同一个 worker 中,就变成单线程复制了。
    • 按行分发策略:如果两个事务没有更新相同的行,它们在备库上可以并行。如果两个事务没有更新相同的行,它们在备库上可以并行执行。显然,这个模式要求 binlog 格式必须是 row。缺点:相比于按表并行分发策略,按行并行策略在决定线程分发的时候,需要消耗更多的计算资源。

    41、MySQL的一主一备和一主多从有什么区别?

    在一主一备的双 M 架构里,主备切换只需要把客户端流量切到备库;而在一主多从架构里,主备切换除了要把客户端流量切到备库外,还需要把从库接到新主库上。

    42、主库出问题如何解决?

    • 基于位点的主备切换:存在找同步位点这个问题
    • MySQL 5.6 版本引入了 GTID,彻底解决了这个困难。那么,GTID 到底是什么意思,又是如何解决找同步位点这个问题呢?
    • GTID:全局事务 ID,是一个事务在提交的时候生成的,是这个事务的唯一标识;它由两部分组成,格式是:GTID=server_uuid:gno
    • 每个 MySQL 实例都维护了一个 GTID 集合,用来对应“这个实例执行过的所有事务”。
    • 在基于 GTID 的主备关系里,系统认为只要建立主备关系,就必须保证主库发给备库的日志是完整的。因此,如果实例 B 需要的日志已经不存在,A’就拒绝把日志发给 B。

    43、MySQL 读写分离涉及到过期读问题的几种解决方案?

    • 强制走主库方案
    • sleep 方案
    • 判断主备无延迟方案
    • 配合 semi-sync 方案
    • 等主库位点方案
    • GTID 方案。
    • 实际生产中,先客户端对请求做分类,区分哪些请求可以接受过期读,而哪些请求完全不能接受过期读;然后,对于不能接受过期读的语句,再使用等 GTID 或等位点的方案。

    44、MySQL的并发链接和并发查询有什么区别?

    • 在执行show processlist的结果里,看到了几千个连接,指的是并发连接。而"当前正在执行"的语句,才是并发查询。
    • 并发连接数多影响的是内存,并发查询太高对CPU不利。一个机器的CPU核数有限,线程全冲进来,上下文切换的成本就会太高。
    • 所以需要设置参数:innodb_thread_concurrency 用来限制线程数,当线程数达到该参数,InnoDB就会认为线程数用完了,会阻止其他语句进入引擎执行。

    性能相关

    45、短时间提高 MySQL 性能的方法

    • 第一种方法:先处理掉那些占着连接但是不工作的线程。或者再考虑断开事务内空闲太久的连接。 kill connection + id
    • 第二种方法:减少连接过程的消耗:慢查询性能问题在 MySQL 中,会引发性能问题的慢查询,大体有以下三种可能:索引没有设计好;SQL 语句没写好;MySQL 选错了索引(force index)。

    46、为什么 MySQL 自增主键 ID 不连续?

    • 唯一键冲突

    • 事务回滚

    • 自增主键的批量申请

    • 深层次原因是:MySQL 不判断自增主键是否存在,从而减少加锁的时间范围和粒度,这样能保持更高的性能,确保自增主键不能回退,所以才有自增主键不连续。

    • 自增主键怎么做到唯一性?自增值加1来通过自增锁控制并发

    47、InnoDB 为什么要用自增 ID 作为主键?

    • 自增主键的插入模式,符合递增插入,每次都是追加操作,不涉及挪动记录,也不会触发叶子节点的分裂。

    • 每次插入新的记录就会顺序添加到当前索引节点的后续位置,当一页写满,就会自动开辟一个新的页。

    • 而有业务逻辑的字段做主键,不容易保证有序插入,由于每次插入主键的值近似于随机

    • 因此每次新纪录都要被插到现有索引页得中间某个位置, 频繁的移动、分页操作造成了大量的碎片,得到了不够紧凑的索引结构,写数据成本较高。

    48、如何最快的复制一张表?

    • 为了避免对源表加读锁,更稳妥的方案是先将数据写到外部文本文件,然后再写回目标表
    • 一种方法是,使用 mysqldump 命令将数据导出成一组 INSERT 语句
    • 另一种方法是直接将结果导出成.csv 文件。MySQL 提供语法,用来将查询结果导出到服务端本地目录:select * from db1.t where a>900 into outfile '/server_tmp/t.csv';得到.csv 导出文件后,你就可以用下面的 load data 命令将数据导入到目标表 db2.t 中:load data infile '/server_tmp/t.csv' into table db2.t;
    • 物理拷贝:在 MySQL 5.6 版本引入了可传输表空间(transportable tablespace) 的方法,可以通过导出 + 导入表空间的方式,实现物理拷贝表的功能。

    49、grant 和 flush privileges语句

    • grant语句会同时修改数据表和内存,判断权限的时候使用的内存数据,因此,规范使用是不需要加上 flush privileges 语句。
    • flush privileges 语句本身会用数据表的数据重建一份内存权限数据,所以在权限数据可能存在不一致的情况下再使用。

    50、要不要使用分区表?

    • 分区并不是越细越好。实际上,单表或者单分区的数据一千万行,只要没有特别大的索引,对于现在的硬件能力来说都已经是小表了。
    • 分区也不要提前预留太多,在使用之前预先创建即可。比如,如果是按月分区,每年年底时再把下一年度的 12 个新分区创建上即可。对于没有数据的历史分区,要及时的 drop 掉。

    51、join 用法

    • 使用 left join 左边的表不一定是驱动表
    • 如果需要 left join 的语义,就不能把被驱动表的字段放在 where 条件里面做等值判断或不等值判断,必须都写在 on 里面
    • 标准的 group by 语句,是需要在 select 部分加一个聚合函数,比如select a,count(*) from t group by a order by null;

    52、MySQL 有哪些自增ID?各自场景是什么?

    • 表的自增 ID 达到上限之后,在申请值不会变化,进而导致联系插入数据的时候报主键冲突错误。

    • row_id 达到上限之后,归 0 在重新递增,如果出现相同的 row_id 后写的数据会覆盖之前的数据。

    • Xid 只需要不在同一个 binlog 文件出现重复值即可,理论上会出现重复值,但概率极小可忽略不计。

    • InnoDB 的 max_trx_id 递增值每次 MySQL 重启会保存起来。

    • Xid 是由 server 层维护的。InnoDB 内部使用 Xid,就是为了能够在 InnoDB 事务和 server 之间做关联。但是,InnoDB 自己的 trx_id,是另外维护的。

    • thread_id 是我们使用中最常见的,而且也是处理得最好的一个自增 id 逻辑了。使用了insert_unique算法

    53、Xid 在 MySQL 内部是怎么生成的呢?

    MySQL 内部维护了一个全局变量 global_query_id,每次执行语句(包括select语句)的时候将它赋值给 Query_id,然后给这个变量加 1。如果当前语句是这个事务执行的第一条语句,那么 MySQL 还会同时把 Query_id 赋值给这个事务的 Xid。

    而 global_query_id 是一个纯内存变量,重启之后就清零了。所以你就知道了,在同一个数据库实例中,不同事务的 Xid 也是有可能相同的。但是 MySQL 重启之后会重新生成新的 binlog 文件,这就保证了,同一个 binlog 文件里,Xid 一定是惟一的。

    锁相关

    54、说一下 MySQL 的锁

    • MySQL 在 server 层 和 存储引擎层 都运用了大量的锁
    • MySQL server 层需要讲两种锁,第一种是MDL(metadata lock) 元数据锁,第二种则 Table Lock 表锁。
    • MDL 又名元数据锁,那么什么是元数据呢,任何描述数据库的内容就是元数据,比如我们的表结构、库结构等都是元数据。那为什么需要 MDL 呢?
    • 主要解决两个问题:事务隔离问题;数据复制问题
    • InnoDB 有五种表级锁:IS(意向读锁);IX(意向写锁);S(读);X(写);AUTO-INC
    • 在对表进行select/insert/delete/update语句时候不会加表级锁
    • IS和IX的作用是为了判断表中是否有已经被加锁的记录
    • 自增主键的保障就是有 AUTO-INC 锁,是语句级别的:为表的某个列添加 AUTO_INCREMENT 属性,之后在插⼊记录时,可以不指定该列的值,系统会⾃动为它赋上单调递增的值。
    • InnoDB 4 种行级锁
    • RecordLock:记录锁
    • GapLock:间隙锁解决幻读;前一次查询不存在的东西在下一次查询出现了,其实就是事务A中的两次查询之间事务B执行插入操作被事务A感知了
    • Next-KeyLock:锁住某条记录又想阻止其它事务在改记录前面的间隙插入新纪录
    • InsertIntentionLock:插入意向锁;如果插入到同一行间隙中的多个事务未插入到间隙内的同一位置则无须等待
    • 行锁和表锁的抉择
      • 全表扫描用行级锁

    55、什么是幻读?

    值在同一个事务中,存在前后两次查询同一个范围的数据,第二次看到了第一次没有查询到的数据。

    幻读出现的场景:

    • 事务的隔离级别是可重复读,且是当前读。
    • 幻读指新插入的行。

    幻读带来的问题:

    • 对行锁语义的破坏
    • 破坏了数据一致性

    解决:

    • 加间隙锁,锁住行与行之间的间隙,阻塞新插入的操作。
    • 带来的问题:降低并发度,可能导致死锁。

    其它为什么系列

    56、为什么 MySQL 会抖一下?

    • 脏页会被后台线程自动 flush,也会由于数据页淘汰而触发 flush,而刷脏页的过程由于会占用资源,可能会让你的更新和查询语句的响应时间长一些。

    57、为什么删除了表,表文件的大小还是没变?

    • 数据项删除之后 InnoDB 某个页 page A 会被标记为可复用。
    • delete 命令把整个表的数据删除,结果就是,所有的数据页都会被标记为可复用。但是磁盘上,文件不会变小。
    • 经过大量增删改的表,都是可能是存在空洞的。这些空洞也占空间所以,如果能够把这些空洞去掉,就能达到收缩表空间的目的。
    • 重建表,就可以达到这样的目的。可以使用 alter table A engine=InnoDB 命令来重建表。

    58、count(*)实现方式以及各种 count 对比

    • 对于 count(主键 id) 来说,InnoDB 引擎会遍历整张表,把每一行的 id 值都取出来,返回给 server 层。server 层拿到 id 后,判断是不可能为空的,就按行累加。
    • 对于 count(1) 来说,InnoDB 引擎遍历整张表,但不取值。server 层对于返回的每一行,放一个数字“1”进去,判断是不可能为空的,按行累加。 单看这两个用法的差别的话,你能对比出来,count(1) 执行得要比 count(主键 id) 快。因为从引擎返回 id 会涉及到解析数据行,以及拷贝字段值的操作。
    • 对于 count(字段) 来说:如果这个“字段”是定义为 not null 的话,一行行地从记录里面读出这个字段,判断不能为 null,按行累加;如果这个“字段”定义允许为 null,那么执行的时候,判断到有可能是 null,还要把值取出来再判断一下,不是 null 才累加。也就是前面的第一条原则,server 层要什么字段,InnoDB 就返回什么字段。
    • 但是 count * 是例外,并不会把全部字段取出来,而是专门做了优化,不取值。count(*)肯定不是 null,按行累加。
    • 所以结论是:按照效率排序的话,count(字段)<count(主键 id)<count(1)≈count(※),所以建议尽量使用 count(*)

    59、orderby 排序内部原理

    • MySQL 会为每个线程分配一个内存(sort-buffer)用于排序该内存大小为 sort_buffer_size;

    • 如果排序的数据量小于 sort_buffer_size,排序就会在内存中完成;

      内部排序分为两种

    • 全字段排序:到索引树上找到满足条件的主键ID根据主键ID去取出数据放到sort_buffer然后进行快速排序

    • rowid排序:通过控制排序的行数据的长度来让sort_buffer中尽可能多的存放数据

    • 如果数据量很大,内存中无法存下这么多,就会使用磁盘临时文件来辅助排序,称为外部排序;

    • 外部排序,MySQL会分为好几份单独的临时文件来存放排序后的数据,一般是磁盘文件中进行归并,然后将这些文件合并成一个大文件;

    60、如何高效的使用 MySQL 显式随机消息

    • 随机取出 Y1,Y2,Y3之后,算出Ymax,Ymin

    • 得到id集后算出Y1、Y2、Y3对应的三个id 最后 select * from t where id in (id1, id2, id3) 这样扫描的行数应该是C+Ymax+3

      mysql> select count(*) into @C from t;
       set @Y1 = floor(@C * rand());
       set @Y2 = floor(@C * rand());
    @@ -51,6 +51,6 @@
       Ymin = min(Y1,Y2,Y3)
       select id from t limit Ymin,(Ymax - Ymin)
     

    图文详解 60 道 MySQL 面试高频题,这次吊打面试官,我觉得稳了(手动 dog)。整理:沉默王二,戳转载链接open in new window,里面有局详细的思维导图;作者:herongwei,戳原文链接open in new window

    - + diff --git a/dist/sidebar/sanfene/collection.html b/dist/sidebar/sanfene/collection.html index 66ce72d5..241de922 100644 --- a/dist/sidebar/sanfene/collection.html +++ b/dist/sidebar/sanfene/collection.html @@ -39,10 +39,10 @@ } - + -

    面渣逆袭(Java 集合框架篇)必看👍

    沉默王二2022年3月9日
    • 面渣逆袭
    • Java
    大约 27 分钟

    面渣逆袭(Java 集合框架篇)必看👍

    图文详解 30 道Java集合框架面试高频题,这次吊打面试官,我觉得稳了(手动 dog)。整理:沉默王二,戳转载链接open in new window,作者:三分恶,戳原文链接open in new window

    引言

    1.说说有哪些常见集合?

    集合相关类和接口都在java.util中,主要分为3种:List(列表)、Map(映射)、Set(集)。

    Java集合主要关系

    其中Collection是集合ListSet的父接口,它主要有两个子接口:

    • List:存储的元素有序,可重复。
    • Set:存储的元素不无序,不可重复。

    Map是另外的接口,是键值对映射结构的集合。

    List

    List,也没啥好问的,但不排除面试官剑走偏锋,比如面试官也看了我这篇文章。

    2.ArrayList和LinkedList有什么区别?

    **(1)**数据结构不同

    • ArrayList基于数组实现
    • LinkedList基于双向链表实现

    ArrayList和LinkedList的数据结构

    (2) 多数情况下,ArrayList更利于查找,LinkedList更利于增删

    • ArrayList基于数组实现,get(int index)可以直接通过数组下标获取,时间复杂度是O(1);LinkedList基于链表实现,get(int index)需要遍历链表,时间复杂度是O(n);当然,get(E element)这种查找,两种集合都需要遍历,时间复杂度都是O(n)。

    • ArrayList增删如果是数组末尾的位置,直接插入或者删除就可以了,但是如果插入中间的位置,就需要把插入位置后的元素都向前或者向后移动,甚至还有可能触发扩容;双向链表的插入和删除只需要改变前驱节点、后继节点和插入节点的指向就行了,不需要移动元素。

    ArrayList和LinkedList中间插入

    ArrayList和LinkedList中间删除

    注意,这个地方可能会出陷阱,LinkedList更利于增删更多是体现在平均步长上,不是体现在时间复杂度上,二者增删的时间复杂度都是O(n)

    **(3)**是否支持随机访问

    • ArrayList基于数组,所以它可以根据下标查找,支持随机访问,当然,它也实现了RandmoAccess 接口,这个接口只是用来标识是否支持随机访问。
    • LinkedList基于链表,所以它没法根据序号直接获取元素,它没有实现RandmoAccess 接口,标记不支持随机访问。

    **(4)**内存占用,ArrayList基于数组,是一块连续的内存空间,LinkedList基于链表,内存空间不连续,它们在空间占用上都有一些额外的消耗:

    • ArrayList是预先定义好的数组,可能会有空的内存空间,存在一定空间浪费
    • LinkedList每个节点,需要存储前驱和后继,所以每个节点会占用更多的空间

    3.ArrayList的扩容机制了解吗?

    ArrayList是基于数组的集合,数组的容量是在定义的时候确定的,如果数组满了,再插入,就会数组溢出。所以在插入时候,会先检查是否需要扩容,如果当前容量+1超过数组长度,就会进行扩容。

    ArrayList的扩容是创建一个1.5倍的新数组,然后把原数组的值拷贝过去。

    ArrayList扩容

    4.ArrayList怎么序列化的知道吗? 为什么用transient修饰数组?

    ArrayList的序列化不太一样,它使用transient修饰存储元素的elementData的数组,transient关键字的作用是让被修饰的成员属性不被序列化。

    为什么最ArrayList不直接序列化元素数组呢?

    出于效率的考虑,数组可能长度100,但实际只用了50,剩下的50不用其实不用序列化,这样可以提高序列化和反序列化的效率,还可以节省内存空间。

    那ArrayList怎么序列化呢?

    ArrayList通过两个方法readObject、writeObject自定义序列化和反序列化策略,实际直接使用两个流ObjectOutputStreamObjectInputStream来进行序列化和反序列化。

    ArrayList自定义序列化

    5.快速失败(fail-fast)和安全失败(fail-safe)了解吗?

    快速失败(fail—fast):快速失败是Java集合的一种错误检测机制

    • 在用迭代器遍历一个集合对象时,如果线程A遍历过程中,线程B对集合对象的内容进行了修改(增加、删除、修改),则会抛出Concurrent Modification Exception。
    • 原理:迭代器在遍历时直接访问集合中的内容,并且在遍历过程中使用一个 modCount 变量。集合在被遍历期间如果内容发生变化,就会改变modCount的值。每当迭代器使用hashNext()/next()遍历下一个元素之前,都会检测modCount变量是否为expectedmodCount值,是的话就返回遍历;否则抛出异常,终止遍历。
    • 注意:这里异常的抛出条件是检测到 modCount!=expectedmodCount 这个条件。如果集合发生变化时修改modCount值刚好又设置为了expectedmodCount值,则异常不会抛出。因此,不能依赖于这个异常是否抛出而进行并发操作的编程,这个异常只建议用于检测并发修改的bug。
    • 场景:java.util包下的集合类都是快速失败的,不能在多线程下发生并发修改(迭代过程中被修改),比如ArrayList 类。

    安全失败(fail—safe)

    • 采用安全失败机制的集合容器,在遍历时不是直接在集合内容上访问的,而是先复制原有集合内容,在拷贝的集合上进行遍历。
    • 原理:由于迭代时是对原集合的拷贝进行遍历,所以在遍历过程中对原集合所作的修改并不能被迭代器检测到,所以不会触发Concurrent Modification Exception。
    • 缺点:基于拷贝内容的优点是避免了Concurrent Modification Exception,但同样地,迭代器并不能访问到修改后的内容,即:迭代器遍历的是开始遍历那一刻拿到的集合拷贝,在遍历期间原集合发生的修改迭代器是不知道的。
    • 场景:java.util.concurrent包下的容器都是安全失败,可以在多线程下并发使用,并发修改,比如CopyOnWriteArrayList类。

    6.有哪几种实现ArrayList线程安全的方法?

    fail-fast是一种可能触发的机制,实际上,ArrayList的线程安全仍然没有保证,一般,保证ArrayList的线程安全可以通过这些方案:

    • 使用 Vector 代替 ArrayList。(不推荐,Vector是一个历史遗留类)
    • 使用 Collections.synchronizedList 包装 ArrayList,然后操作包装后的 list。
    • 使用 CopyOnWriteArrayList 代替 ArrayList。
    • 在使用 ArrayList 时,应用程序通过同步机制去控制 ArrayList 的读写。

    7.CopyOnWriteArrayList了解多少?

    CopyOnWriteArrayList就是线程安全版本的ArrayList。

    它的名字叫CopyOnWrite——写时复制,已经明示了它的原理。

    CopyOnWriteArrayList采用了一种读写分离的并发策略。CopyOnWriteArrayList容器允许并发读,读操作是无锁的,性能较高。至于写操作,比如向容器中添加一个元素,则首先将当前容器复制一份,然后在新副本上执行写操作,结束之后再将原容器的引用指向新容器。

    CopyOnWriteArrayList原理

    Map

    Map中,毫无疑问,最重要的就是HashMap,面试基本被盘出包浆了,各种问法,一定要好好准备。

    8.能说一下HashMap的数据结构吗?

    JDK1.7的数据结构是数组+链表,JDK1.7还有人在用?不会吧……

    说一下JDK1.8的数据结构吧:

    JDK1.8的数据结构是数组+链表+红黑树

    数据结构示意图如下:

    jdk1.8 hashmap数据结构示意图

    其中,桶数组是用来存储数据元素,链表是用来解决冲突,红黑树是为了提高查询的效率。

    • 数据元素通过映射关系,也就是散列函数,映射到桶数组对应索引的位置
    • 如果发生冲突,从冲突的位置拉一个链表,插入冲突的元素
    • 如果链表长度>8&数组大小>=64,链表转为红黑树
    • 如果红黑树节点个数<6 ,转为链表

    9.你对红黑树了解多少?为什么不用二叉树/平衡树呢?

    红黑树本质上是一种二叉查找树,为了保持平衡,它又在二叉查找树的基础上增加了一些规则:

    1. 每个节点要么是红色,要么是黑色;
    2. 根节点永远是黑色的;
    3. 所有的叶子节点都是是黑色的(注意这里说叶子节点其实是图中的 NULL 节点);
    4. 每个红色节点的两个子节点一定都是黑色;
    5. 从任一节点到其子树中每个叶子节点的路径都包含相同数量的黑色节点;

    红黑树

    之所以不用二叉树:

    红黑树是一种平衡的二叉树,插入、删除、查找的最坏时间复杂度都为 O(logn),避免了二叉树最坏情况下的O(n)时间复杂度。

    之所以不用平衡二叉树:

    平衡二叉树是比红黑树更严格的平衡树,为了保持保持平衡,需要旋转的次数更多,也就是说平衡二叉树保持平衡的效率更低,所以平衡二叉树插入和删除的效率比红黑树要低。

    10.红黑树怎么保持平衡的知道吗?

    红黑树有两种方式保持平衡:旋转染色

    • 旋转:旋转分为两种,左旋和右旋

    左旋

    右旋

    • 染⾊:

    染色

    11.HashMap的put流程知道吗?

    先上个流程图吧:

    HashMap插入数据流程图

    1. 首先进行哈希值的扰动,获取一个新的哈希值。(key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);

    2. 判断tab是否位空或者长度为0,如果是则进行扩容操作。

      if ((tab = table) == null || (n = tab.length) == 0)
      +    

      面渣逆袭(Java 集合框架篇)必看👍

      沉默王二2022年3月9日
      • 面渣逆袭
      • Java
      大约 27 分钟

      面渣逆袭(Java 集合框架篇)必看👍

      图文详解 30 道Java集合框架面试高频题,这次吊打面试官,我觉得稳了(手动 dog)。整理:沉默王二,戳转载链接open in new window,作者:三分恶,戳原文链接open in new window

      引言

      1.说说有哪些常见集合?

      集合相关类和接口都在java.util中,主要分为3种:List(列表)、Map(映射)、Set(集)。

      Java集合主要关系

      其中Collection是集合ListSet的父接口,它主要有两个子接口:

      • List:存储的元素有序,可重复。
      • Set:存储的元素不无序,不可重复。

      Map是另外的接口,是键值对映射结构的集合。

      List

      List,也没啥好问的,但不排除面试官剑走偏锋,比如面试官也看了我这篇文章。

      2.ArrayList和LinkedList有什么区别?

      **(1)**数据结构不同

      • ArrayList基于数组实现
      • LinkedList基于双向链表实现

      ArrayList和LinkedList的数据结构

      (2) 多数情况下,ArrayList更利于查找,LinkedList更利于增删

      • ArrayList基于数组实现,get(int index)可以直接通过数组下标获取,时间复杂度是O(1);LinkedList基于链表实现,get(int index)需要遍历链表,时间复杂度是O(n);当然,get(E element)这种查找,两种集合都需要遍历,时间复杂度都是O(n)。

      • ArrayList增删如果是数组末尾的位置,直接插入或者删除就可以了,但是如果插入中间的位置,就需要把插入位置后的元素都向前或者向后移动,甚至还有可能触发扩容;双向链表的插入和删除只需要改变前驱节点、后继节点和插入节点的指向就行了,不需要移动元素。

      ArrayList和LinkedList中间插入

      ArrayList和LinkedList中间删除

      注意,这个地方可能会出陷阱,LinkedList更利于增删更多是体现在平均步长上,不是体现在时间复杂度上,二者增删的时间复杂度都是O(n)

      **(3)**是否支持随机访问

      • ArrayList基于数组,所以它可以根据下标查找,支持随机访问,当然,它也实现了RandmoAccess 接口,这个接口只是用来标识是否支持随机访问。
      • LinkedList基于链表,所以它没法根据序号直接获取元素,它没有实现RandmoAccess 接口,标记不支持随机访问。

      **(4)**内存占用,ArrayList基于数组,是一块连续的内存空间,LinkedList基于链表,内存空间不连续,它们在空间占用上都有一些额外的消耗:

      • ArrayList是预先定义好的数组,可能会有空的内存空间,存在一定空间浪费
      • LinkedList每个节点,需要存储前驱和后继,所以每个节点会占用更多的空间

      3.ArrayList的扩容机制了解吗?

      ArrayList是基于数组的集合,数组的容量是在定义的时候确定的,如果数组满了,再插入,就会数组溢出。所以在插入时候,会先检查是否需要扩容,如果当前容量+1超过数组长度,就会进行扩容。

      ArrayList的扩容是创建一个1.5倍的新数组,然后把原数组的值拷贝过去。

      ArrayList扩容

      4.ArrayList怎么序列化的知道吗? 为什么用transient修饰数组?

      ArrayList的序列化不太一样,它使用transient修饰存储元素的elementData的数组,transient关键字的作用是让被修饰的成员属性不被序列化。

      为什么最ArrayList不直接序列化元素数组呢?

      出于效率的考虑,数组可能长度100,但实际只用了50,剩下的50不用其实不用序列化,这样可以提高序列化和反序列化的效率,还可以节省内存空间。

      那ArrayList怎么序列化呢?

      ArrayList通过两个方法readObject、writeObject自定义序列化和反序列化策略,实际直接使用两个流ObjectOutputStreamObjectInputStream来进行序列化和反序列化。

      ArrayList自定义序列化

      5.快速失败(fail-fast)和安全失败(fail-safe)了解吗?

      快速失败(fail—fast):快速失败是Java集合的一种错误检测机制

      • 在用迭代器遍历一个集合对象时,如果线程A遍历过程中,线程B对集合对象的内容进行了修改(增加、删除、修改),则会抛出Concurrent Modification Exception。
      • 原理:迭代器在遍历时直接访问集合中的内容,并且在遍历过程中使用一个 modCount 变量。集合在被遍历期间如果内容发生变化,就会改变modCount的值。每当迭代器使用hashNext()/next()遍历下一个元素之前,都会检测modCount变量是否为expectedmodCount值,是的话就返回遍历;否则抛出异常,终止遍历。
      • 注意:这里异常的抛出条件是检测到 modCount!=expectedmodCount 这个条件。如果集合发生变化时修改modCount值刚好又设置为了expectedmodCount值,则异常不会抛出。因此,不能依赖于这个异常是否抛出而进行并发操作的编程,这个异常只建议用于检测并发修改的bug。
      • 场景:java.util包下的集合类都是快速失败的,不能在多线程下发生并发修改(迭代过程中被修改),比如ArrayList 类。

      安全失败(fail—safe)

      • 采用安全失败机制的集合容器,在遍历时不是直接在集合内容上访问的,而是先复制原有集合内容,在拷贝的集合上进行遍历。
      • 原理:由于迭代时是对原集合的拷贝进行遍历,所以在遍历过程中对原集合所作的修改并不能被迭代器检测到,所以不会触发Concurrent Modification Exception。
      • 缺点:基于拷贝内容的优点是避免了Concurrent Modification Exception,但同样地,迭代器并不能访问到修改后的内容,即:迭代器遍历的是开始遍历那一刻拿到的集合拷贝,在遍历期间原集合发生的修改迭代器是不知道的。
      • 场景:java.util.concurrent包下的容器都是安全失败,可以在多线程下并发使用,并发修改,比如CopyOnWriteArrayList类。

      6.有哪几种实现ArrayList线程安全的方法?

      fail-fast是一种可能触发的机制,实际上,ArrayList的线程安全仍然没有保证,一般,保证ArrayList的线程安全可以通过这些方案:

      • 使用 Vector 代替 ArrayList。(不推荐,Vector是一个历史遗留类)
      • 使用 Collections.synchronizedList 包装 ArrayList,然后操作包装后的 list。
      • 使用 CopyOnWriteArrayList 代替 ArrayList。
      • 在使用 ArrayList 时,应用程序通过同步机制去控制 ArrayList 的读写。

      7.CopyOnWriteArrayList了解多少?

      CopyOnWriteArrayList就是线程安全版本的ArrayList。

      它的名字叫CopyOnWrite——写时复制,已经明示了它的原理。

      CopyOnWriteArrayList采用了一种读写分离的并发策略。CopyOnWriteArrayList容器允许并发读,读操作是无锁的,性能较高。至于写操作,比如向容器中添加一个元素,则首先将当前容器复制一份,然后在新副本上执行写操作,结束之后再将原容器的引用指向新容器。

      CopyOnWriteArrayList原理

      Map

      Map中,毫无疑问,最重要的就是HashMap,面试基本被盘出包浆了,各种问法,一定要好好准备。

      8.能说一下HashMap的数据结构吗?

      JDK1.7的数据结构是数组+链表,JDK1.7还有人在用?不会吧……

      说一下JDK1.8的数据结构吧:

      JDK1.8的数据结构是数组+链表+红黑树

      数据结构示意图如下:

      jdk1.8 hashmap数据结构示意图

      其中,桶数组是用来存储数据元素,链表是用来解决冲突,红黑树是为了提高查询的效率。

      • 数据元素通过映射关系,也就是散列函数,映射到桶数组对应索引的位置
      • 如果发生冲突,从冲突的位置拉一个链表,插入冲突的元素
      • 如果链表长度>8&数组大小>=64,链表转为红黑树
      • 如果红黑树节点个数<6 ,转为链表

      9.你对红黑树了解多少?为什么不用二叉树/平衡树呢?

      红黑树本质上是一种二叉查找树,为了保持平衡,它又在二叉查找树的基础上增加了一些规则:

      1. 每个节点要么是红色,要么是黑色;
      2. 根节点永远是黑色的;
      3. 所有的叶子节点都是是黑色的(注意这里说叶子节点其实是图中的 NULL 节点);
      4. 每个红色节点的两个子节点一定都是黑色;
      5. 从任一节点到其子树中每个叶子节点的路径都包含相同数量的黑色节点;

      红黑树

      之所以不用二叉树:

      红黑树是一种平衡的二叉树,插入、删除、查找的最坏时间复杂度都为 O(logn),避免了二叉树最坏情况下的O(n)时间复杂度。

      之所以不用平衡二叉树:

      平衡二叉树是比红黑树更严格的平衡树,为了保持保持平衡,需要旋转的次数更多,也就是说平衡二叉树保持平衡的效率更低,所以平衡二叉树插入和删除的效率比红黑树要低。

      10.红黑树怎么保持平衡的知道吗?

      红黑树有两种方式保持平衡:旋转染色

      • 旋转:旋转分为两种,左旋和右旋

      左旋

      右旋

      • 染⾊:

      染色

      11.HashMap的put流程知道吗?

      先上个流程图吧:

      HashMap插入数据流程图

      1. 首先进行哈希值的扰动,获取一个新的哈希值。(key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);

      2. 判断tab是否位空或者长度为0,如果是则进行扩容操作。

        if ((tab = table) == null || (n = tab.length) == 0)
             n = (tab = resize()).length;
         
      3. 根据哈希值计算下标,如果对应小标正好没有存放数据,则直接插入即可否则需要覆盖。tab[i = (n - 1) & hash])

      4. 判断tab[i]是否为树节点,否则向链表中插入数据,是则向树中插入节点。

      5. 如果链表中插入节点的时候,链表长度大于等于8,则需要把链表转换为红黑树。treeifyBin(tab, hash);

      6. 最后所有元素处理完成后,判断是否超过阈值;threshold,超过则扩容。

      12.HashMap怎么查找元素的呢?

      先看流程图:

      HashMap查找流程图

      HashMap的查找就简单很多:

      1. 使用扰动函数,获取新的哈希值
      2. 计算数组下标,获取节点
      3. 当前节点和key匹配,直接返回
      4. 否则,当前节点是否为树节点,查找红黑树
      5. 否则,遍历链表查找

      13.HashMap的哈希/扰动函数是怎么设计的?

      HashMap的哈希函数是先拿到 key 的hashcode,是一个32位的int类型的数值,然后让hashcode的高16位和低16位进行异或操作。

          static final int hash(Object key) {
               int h;
      @@ -131,6 +131,6 @@
           return oldValue;
       }
       

      图文详解 30 道Java集合框架面试高频题,这次吊打面试官,我觉得稳了(手动 dog)。整理:沉默王二,戳转载链接open in new window,作者:三分恶,戳原文链接open in new window

      - + diff --git a/dist/sidebar/sanfene/javase.html b/dist/sidebar/sanfene/javase.html index f97db031..31f7832e 100644 --- a/dist/sidebar/sanfene/javase.html +++ b/dist/sidebar/sanfene/javase.html @@ -39,10 +39,10 @@ } - + -

      面渣逆袭(Java 基础篇)必看👍

      沉默王二2022年3月9日
      • 面渣逆袭
      • Java
      大约 48 分钟

      面渣逆袭(Java 基础篇)必看👍

      图文详解 53 道Java基础面试高频题,这次吊打面试官,我觉得稳了(手动 dog)。整理:沉默王二,戳转载链接open in new window,作者:三分恶,戳原文链接open in new window

      Java 概述

      1.什么是 Java?

      下辈子还学Java

      PS:碎怂 Java,有啥好介绍的。哦,面试啊。

      Java 是一门面向对象的编程语言,不仅吸收了 C++语言的各种优点,还摒弃了 C++里难以理解的多继承、指针等概念,因此 Java 语言具有功能强大和简单易用两个特征。Java 语言作为静态面向对象编程语言的优秀代表,极好地实现了面向对象理论,允许程序员以优雅的思维方式进行复杂的编程 。

      2.Java 语言有哪些特点?

      Java 语言有很多优秀(可吹)的特点,以下几个是比较突出的:

      Java语言特点

      • 面向对象(封装,继承,多态);
      • 平台无关性,平台无关性的具体表现在于,Java 是“一次编写,到处运行(Write Once,Run any Where)”的语言,因此采用 Java 语言编写的程序具有很好的可移植性,而保证这一点的正是 Java 的虚拟机机制。在引入虚拟机之后,Java 语言在不同的平台上运行不需要重新编译。
      • 支持多线程。C++ 语言没有内置的多线程机制,因此必须调用操作系统的多线程功能来进行多线程程序设计,而 Java 语言却提供了多线程支持;
      • 编译与解释并存;

      3.JVM、JDK 和 JRE 有什么区别?

      JVM:Java Virtual Machine,Java 虚拟机,Java 程序运行在 Java 虚拟机上。针对不同系统的实现(Windows,Linux,macOS)不同的 JVM,因此 Java 语言可以实现跨平台。

      JRE: Java 运⾏时环境。它是运⾏已编译 Java 程序所需的所有内容的集合,包括 Java 虚拟机(JVM),Java 类库,Java 命令和其他的⼀些基础构件。但是,它不能⽤于创建新程序。

      JDK: Java Development Kit,它是功能⻬全的 Java SDK。它拥有 JRE 所拥有的⼀切,还有编译器(javac)和⼯具(如 javadoc 和 jdb)。它能够创建和编译程序。

      简单来说,JDK 包含 JRE,JRE 包含 JVM。

      JDK、JRE、JVM关系

      4.说说什么是跨平台性?原理是什么

      所谓跨平台性,是指 Java 语言编写的程序,一次编译后,可以在多个系统平台上运行。

      实现原理:Java 程序是通过 Java 虚拟机在系统平台上运行的,只要该系统可以安装相应的 Java 虚拟机,该系统就可以运行 java 程序。

      5.什么是字节码?采用字节码的好处是什么?

      所谓的字节码,就是 Java 程序经过编译之类产生的.class 文件,字节码能够被虚拟机识别,从而实现 Java 程序的跨平台性。

      Java 程序从源代码到运行主要有三步:

      • 编译:将我们的代码(.java)编译成虚拟机可以识别理解的字节码(.class)
      • 解释:虚拟机执行 Java 字节码,将字节码翻译成机器能识别的机器码
      • 执行:对应的机器执行二进制机器码

      Java程序执行过程

      只需要把 Java 程序编译成 Java 虚拟机能识别的 Java 字节码,不同的平台安装对应的 Java 虚拟机,这样就可以可以实现 Java 语言的平台无关性。

      6.为什么说 Java 语言“编译与解释并存”?

      高级编程语言按照程序的执行方式分为编译型解释型两种。

      简单来说,编译型语言是指编译器针对特定的操作系统将源代码一次性翻译成可被该平台执行的机器码;解释型语言是指解释器对源程序逐行解释成特定平台的机器码并立即执行。

      比如,你想读一本外国的小说,你可以找一个翻译人员帮助你翻译,有两种选择方式,你可以先等翻译人员将全本的小说(也就是源码)都翻译成汉语,再去阅读,也可以让翻译人员翻译一段,你在旁边阅读一段,慢慢把书读完。

      Java 语言既具有编译型语言的特征,也具有解释型语言的特征,因为 Java 程序要经过先编译,后解释两个步骤,由 Java 编写的程序需要先经过编译步骤,生成字节码(\*.class 文件),这种字节码必须再经过 JVM,解释成操作系统能识别的机器码,在由操作系统执行。因此,我们可以认为 Java 语言编译解释并存。

      编译与解释

      基础语法

      7.Java 有哪些数据类型?

      定义:Java 语言是强类型语言,对于每一种数据都定义了明确的具体的数据类型,在内存中分配了不同大小的内存空间。

      Java 语言数据类型分为两种:基本数据类型引用数据类型

      Java数据类型

      基本数据类型:

      • 数值型
        • 整数类型(byte、short、int、long)
        • 浮点类型(float、double)
      • 字符型(char)
      • 布尔型(boolean)

      Java 基本数据类型范围和默认值:

      基本类型位数字节默认值
      int3240
      short1620
      long6480L
      byte810
      char162'u0000'
      float3240f
      double6480d
      boolean1false

      引用数据类型:

      • 类(class)
      • 接口(interface)
      • 数组([])

      8.自动类型转换、强制类型转换?看看这几行代码?

      Java 所有的数值型变量可以相互转换,当把一个表数范围小的数值或变量直接赋给另一个表数范围大的变量时,可以进行自动类型转换;反之,需要强制转换。

      Java自动类型转换方向

      这就好像,小杯里的水倒进大杯没问题,但大杯的水倒进小杯就不行了,可能会溢出。

      float f=3.4,对吗?

      不正确。3.4 是单精度数,将双精度型(double)赋值给浮点型(float)属于下转型(down-casting,也称为窄化)会造成精度损失,因此需要强制类型转换float f =(float)3.4;或者写成float f =3.4F

      short s1 = 1; s1 = s1 + 1;对吗?short s1 = 1; s1 += 1;对吗?

      对于 short s1 = 1; s1 = s1 + 1;编译出错,由于 1 是 int 类型,因此 s1+1 运算结果也是 int 型,需要强制转换类型才能赋值给 short 型。

      而 short s1 = 1; s1 += 1;可以正确编译,因为 s1+= 1;相当于 s1 = (short(s1 + 1);其中有隐含的强制类型转换。

      9.什么是自动拆箱/封箱?

      • 装箱:将基本类型用它们对应的引用类型包装起来;
      • 拆箱:将包装类型转换为基本数据类型;

      Java 可以自动对基本数据类型和它们的包装类进行装箱和拆箱。

      装箱和拆箱

      举例:

      Integer i = 10;  //装箱
      +    

      面渣逆袭(Java 基础篇)必看👍

      沉默王二2022年3月9日
      • 面渣逆袭
      • Java
      大约 48 分钟

      面渣逆袭(Java 基础篇)必看👍

      图文详解 53 道Java基础面试高频题,这次吊打面试官,我觉得稳了(手动 dog)。整理:沉默王二,戳转载链接open in new window,作者:三分恶,戳原文链接open in new window

      Java 概述

      1.什么是 Java?

      下辈子还学Java

      PS:碎怂 Java,有啥好介绍的。哦,面试啊。

      Java 是一门面向对象的编程语言,不仅吸收了 C++语言的各种优点,还摒弃了 C++里难以理解的多继承、指针等概念,因此 Java 语言具有功能强大和简单易用两个特征。Java 语言作为静态面向对象编程语言的优秀代表,极好地实现了面向对象理论,允许程序员以优雅的思维方式进行复杂的编程 。

      2.Java 语言有哪些特点?

      Java 语言有很多优秀(可吹)的特点,以下几个是比较突出的:

      Java语言特点

      • 面向对象(封装,继承,多态);
      • 平台无关性,平台无关性的具体表现在于,Java 是“一次编写,到处运行(Write Once,Run any Where)”的语言,因此采用 Java 语言编写的程序具有很好的可移植性,而保证这一点的正是 Java 的虚拟机机制。在引入虚拟机之后,Java 语言在不同的平台上运行不需要重新编译。
      • 支持多线程。C++ 语言没有内置的多线程机制,因此必须调用操作系统的多线程功能来进行多线程程序设计,而 Java 语言却提供了多线程支持;
      • 编译与解释并存;

      3.JVM、JDK 和 JRE 有什么区别?

      JVM:Java Virtual Machine,Java 虚拟机,Java 程序运行在 Java 虚拟机上。针对不同系统的实现(Windows,Linux,macOS)不同的 JVM,因此 Java 语言可以实现跨平台。

      JRE: Java 运⾏时环境。它是运⾏已编译 Java 程序所需的所有内容的集合,包括 Java 虚拟机(JVM),Java 类库,Java 命令和其他的⼀些基础构件。但是,它不能⽤于创建新程序。

      JDK: Java Development Kit,它是功能⻬全的 Java SDK。它拥有 JRE 所拥有的⼀切,还有编译器(javac)和⼯具(如 javadoc 和 jdb)。它能够创建和编译程序。

      简单来说,JDK 包含 JRE,JRE 包含 JVM。

      JDK、JRE、JVM关系

      4.说说什么是跨平台性?原理是什么

      所谓跨平台性,是指 Java 语言编写的程序,一次编译后,可以在多个系统平台上运行。

      实现原理:Java 程序是通过 Java 虚拟机在系统平台上运行的,只要该系统可以安装相应的 Java 虚拟机,该系统就可以运行 java 程序。

      5.什么是字节码?采用字节码的好处是什么?

      所谓的字节码,就是 Java 程序经过编译之类产生的.class 文件,字节码能够被虚拟机识别,从而实现 Java 程序的跨平台性。

      Java 程序从源代码到运行主要有三步:

      • 编译:将我们的代码(.java)编译成虚拟机可以识别理解的字节码(.class)
      • 解释:虚拟机执行 Java 字节码,将字节码翻译成机器能识别的机器码
      • 执行:对应的机器执行二进制机器码

      Java程序执行过程

      只需要把 Java 程序编译成 Java 虚拟机能识别的 Java 字节码,不同的平台安装对应的 Java 虚拟机,这样就可以可以实现 Java 语言的平台无关性。

      6.为什么说 Java 语言“编译与解释并存”?

      高级编程语言按照程序的执行方式分为编译型解释型两种。

      简单来说,编译型语言是指编译器针对特定的操作系统将源代码一次性翻译成可被该平台执行的机器码;解释型语言是指解释器对源程序逐行解释成特定平台的机器码并立即执行。

      比如,你想读一本外国的小说,你可以找一个翻译人员帮助你翻译,有两种选择方式,你可以先等翻译人员将全本的小说(也就是源码)都翻译成汉语,再去阅读,也可以让翻译人员翻译一段,你在旁边阅读一段,慢慢把书读完。

      Java 语言既具有编译型语言的特征,也具有解释型语言的特征,因为 Java 程序要经过先编译,后解释两个步骤,由 Java 编写的程序需要先经过编译步骤,生成字节码(\*.class 文件),这种字节码必须再经过 JVM,解释成操作系统能识别的机器码,在由操作系统执行。因此,我们可以认为 Java 语言编译解释并存。

      编译与解释

      基础语法

      7.Java 有哪些数据类型?

      定义:Java 语言是强类型语言,对于每一种数据都定义了明确的具体的数据类型,在内存中分配了不同大小的内存空间。

      Java 语言数据类型分为两种:基本数据类型引用数据类型

      Java数据类型

      基本数据类型:

      • 数值型
        • 整数类型(byte、short、int、long)
        • 浮点类型(float、double)
      • 字符型(char)
      • 布尔型(boolean)

      Java 基本数据类型范围和默认值:

      基本类型位数字节默认值
      int3240
      short1620
      long6480L
      byte810
      char162'u0000'
      float3240f
      double6480d
      boolean1false

      引用数据类型:

      • 类(class)
      • 接口(interface)
      • 数组([])

      8.自动类型转换、强制类型转换?看看这几行代码?

      Java 所有的数值型变量可以相互转换,当把一个表数范围小的数值或变量直接赋给另一个表数范围大的变量时,可以进行自动类型转换;反之,需要强制转换。

      Java自动类型转换方向

      这就好像,小杯里的水倒进大杯没问题,但大杯的水倒进小杯就不行了,可能会溢出。

      float f=3.4,对吗?

      不正确。3.4 是单精度数,将双精度型(double)赋值给浮点型(float)属于下转型(down-casting,也称为窄化)会造成精度损失,因此需要强制类型转换float f =(float)3.4;或者写成float f =3.4F

      short s1 = 1; s1 = s1 + 1;对吗?short s1 = 1; s1 += 1;对吗?

      对于 short s1 = 1; s1 = s1 + 1;编译出错,由于 1 是 int 类型,因此 s1+1 运算结果也是 int 型,需要强制转换类型才能赋值给 short 型。

      而 short s1 = 1; s1 += 1;可以正确编译,因为 s1+= 1;相当于 s1 = (short(s1 + 1);其中有隐含的强制类型转换。

      9.什么是自动拆箱/封箱?

      • 装箱:将基本类型用它们对应的引用类型包装起来;
      • 拆箱:将包装类型转换为基本数据类型;

      Java 可以自动对基本数据类型和它们的包装类进行装箱和拆箱。

      装箱和拆箱

      举例:

      Integer i = 10;  //装箱
       int n = i;   //拆箱
       

      10.&和&&有什么区别?

      &运算符有两种用法:短路与逻辑与

      &&运算符是短路与运算。逻辑与跟短路与的差别是非常巨大的,虽然二者都要求运算符左右两端的布尔值都是 true 整个表达式的值才是 true。

      &&之所以称为短路运算是因为,如果&&左边的表达式的值是 false,右边的表达式会被直接短路掉,不会进行运算。很多时候我们可能都需要用&&而不是&。

      例如在验证用户登录时判定用户名不是 null 而且不是空字符串,应当写为username != null &&!username.equals(""),二者的顺序不能交换,更不能用&运算符,因为第一个条件如果不成立,根本不能进行字符串的 equals 比较,否则会产生 NullPointerException 异常。

      注意:逻辑或运算符(|)和短路或运算符(||)的差别也是如此。

      11.switch 是否能作用在 byte/long/String 上?

      Java5 以前 switch(expr)中,expr 只能是 byte、short、char、int。

      从 Java 5 开始,Java 中引入了枚举类型, expr 也可以是 enum 类型。

      从 Java 7 开始,expr 还可以是字符串(String),但是长整型(long)在目前所有的版本中都是不可以的。

      12.break ,continue ,return 的区别及作用?

      • break 跳出整个循环,不再执行循环(结束当前的循环体)
      • continue 跳出本次循环,继续执行下次循环(结束正在执行的循环 进入下一个循环条件)
      • return 程序返回,不再执行下面的代码(结束当前的方法 直接返回)

      break 、continue 、return

      13.用最有效率的方法计算 2 乘以 8?

      2 << 3。位运算,数字的二进制位左移三位相当于乘以 2 的三次方。

      14.说说自增自减运算?看下这几个代码运行结果?

      在写代码的过程中,常见的一种情况是需要某个整数类型变量增加 1 或减少 1,Java 提供了一种特殊的运算符,用于这种表达式,叫做自增运算符(++)和自减运算符(--)。

      ++和--运算符可以放在变量之前,也可以放在变量之后。

      当运算符放在变量之前时(前缀),先自增/减,再赋值;当运算符放在变量之后时(后缀),先赋值,再自增/减。

      例如,当 b = ++a 时,先自增(自己增加 1),再赋值(赋值给 b);当 b = a++ 时,先赋值(赋值给 b),再自增(自己增加 1)。也就是,++a 输出的是 a+1 的值,a++输出的是 a 值。

      用一句口诀就是:“符号在前就先加/减,符号在后就后加/减”。

      看一下这段代码运行结果?

      int i  = 1;
       i = i++;
      @@ -354,6 +354,6 @@ stringCollection..ifPresent(System.out::println);
       // "aaa1#aaa2#bbb1#bbb2#bbb3#ccc#ddd1#ddd2"
       

      以上是常见的几种流式操作,还有其它的一些流式操作,可以帮助我们更便捷地处理集合数据。

      Java Stream流

      图文详解 53 道Java基础面试高频题,这次吊打面试官,我觉得稳了(手动 dog)。整理:沉默王二,戳转载链接open in new window,作者:三分恶,戳原文链接open in new window

      - + diff --git a/dist/sidebar/sanfene/javathread.html b/dist/sidebar/sanfene/javathread.html index b8a854d4..ae446198 100644 --- a/dist/sidebar/sanfene/javathread.html +++ b/dist/sidebar/sanfene/javathread.html @@ -39,10 +39,10 @@ } - + -

      面渣逆袭(Java 并发编程篇)必看👍

      沉默王二2022年3月9日
      • 面渣逆袭
      • Java
      大约 79 分钟

      面渣逆袭(Java 并发编程篇)必看👍

      图文详解 60 道Java并发面试高频题,这次面试,一定吊打面试官,整理:沉默王二,戳转载链接open in new window,作者:三分恶,戳原文链接open in new window

      基础

      1.并行跟并发有什么区别?

      从操作系统的角度来看,线程是CPU分配的最小单位。

      • 并行就是同一时刻,两个线程都在执行。这就要求有两个CPU去分别执行两个线程。
      • 并发就是同一时刻,只有一个执行,但是一个时间段内,两个线程都执行了。并发的实现依赖于CPU切换线程,因为切换的时间特别短,所以基本对于用户是无感知的。

      并行和并发

      就好像我们去食堂打饭,并行就是我们在多个窗口排队,几个阿姨同时打菜;并发就是我们挤在一个窗口,阿姨给这个打一勺,又手忙脚乱地给那个打一勺。

      并行并发和食堂打饭

      2.说说什么是进程和线程?

      要说线程,必须得先说说进程。

      • 进程:进程是代码在数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位。
      • 线程:线程是进程的一个执行路径,一个进程中至少有一个线程,进程中的多个线程共享进程的资源。

      操作系统在分配资源时是把资源分配给进程的, 但是 CPU 资源比较特殊,它是被分配到线程的,因为真正要占用CPU运行的是线程,所以也说线程是 CPU分配的基本单位。

      比如在Java中,当我们启动 main 函数其实就启动了一个JVM进程,而 main 函数在的线程就是这个进程中的一个线程,也称主线程。

      程序进程线程关系

      一个进程中有多个线程,多个线程共用进程的堆和方法区资源,但是每个线程有自己的程序计数器和栈。

      3.说说线程有几种创建方式?

      Java中创建线程主要有三种方式,分别为继承Thread类、实现Runnable接口、实现Callable接口。

      线程创建三种方式

      • 继承Thread类,重写run()方法,调用start()方法启动线程
      public class ThreadTest {
      +    

      面渣逆袭(Java 并发编程篇)必看👍

      沉默王二2022年3月9日
      • 面渣逆袭
      • Java
      大约 79 分钟

      面渣逆袭(Java 并发编程篇)必看👍

      图文详解 60 道Java并发面试高频题,这次面试,一定吊打面试官,整理:沉默王二,戳转载链接open in new window,作者:三分恶,戳原文链接open in new window

      基础

      1.并行跟并发有什么区别?

      从操作系统的角度来看,线程是CPU分配的最小单位。

      • 并行就是同一时刻,两个线程都在执行。这就要求有两个CPU去分别执行两个线程。
      • 并发就是同一时刻,只有一个执行,但是一个时间段内,两个线程都执行了。并发的实现依赖于CPU切换线程,因为切换的时间特别短,所以基本对于用户是无感知的。

      并行和并发

      就好像我们去食堂打饭,并行就是我们在多个窗口排队,几个阿姨同时打菜;并发就是我们挤在一个窗口,阿姨给这个打一勺,又手忙脚乱地给那个打一勺。

      并行并发和食堂打饭

      2.说说什么是进程和线程?

      要说线程,必须得先说说进程。

      • 进程:进程是代码在数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位。
      • 线程:线程是进程的一个执行路径,一个进程中至少有一个线程,进程中的多个线程共享进程的资源。

      操作系统在分配资源时是把资源分配给进程的, 但是 CPU 资源比较特殊,它是被分配到线程的,因为真正要占用CPU运行的是线程,所以也说线程是 CPU分配的基本单位。

      比如在Java中,当我们启动 main 函数其实就启动了一个JVM进程,而 main 函数在的线程就是这个进程中的一个线程,也称主线程。

      程序进程线程关系

      一个进程中有多个线程,多个线程共用进程的堆和方法区资源,但是每个线程有自己的程序计数器和栈。

      3.说说线程有几种创建方式?

      Java中创建线程主要有三种方式,分别为继承Thread类、实现Runnable接口、实现Callable接口。

      线程创建三种方式

      • 继承Thread类,重写run()方法,调用start()方法启动线程
      public class ThreadTest {
       
           /**
            * 继承Thread类
      @@ -442,6 +442,6 @@ lock.lock}
       

      ForkJoinTask与一般Task的主要区别在于它需要实现compute方法,在这个方法里,首先需要判断任务是否足够小,如果足够小就直接执行任务。如果比较大,就必须分割成两个子任务,每个子任务在调用fork方法时,又会进compute方法,看看当前子任务是否需要继续分割成子任务,如果不需要继续分割,则执行当前子任务并返回结果。使用join方法会等待子任务执行完并得到其结果。

      图文详解 60 道Java并发面试高频题,这次面试,一定吊打面试官,整理:沉默王二,戳转载链接open in new window,作者:三分恶,戳原文链接open in new window

      - + diff --git a/dist/sidebar/sanfene/jvm.html b/dist/sidebar/sanfene/jvm.html index d2e2e484..e26f032a 100644 --- a/dist/sidebar/sanfene/jvm.html +++ b/dist/sidebar/sanfene/jvm.html @@ -39,10 +39,10 @@ } - + -

      面渣逆袭(Java 虚拟机篇)必看👍

      沉默王二2022年3月9日
      • 面渣逆袭
      • Java
      大约 54 分钟

      面渣逆袭(Java 虚拟机篇)必看👍

      图文详解 50 道Java虚拟机高频面试题,这次面试,一定吊打面试官,整理:沉默王二,戳转载链接open in new window,作者:三分恶,戳原文链接open in new window

      一、引言

      1.什么是 JVM?

      JVM——Java 虚拟机,它是 Java 实现平台无关性的基石。

      Java 程序运行的时候,编译器将 Java 文件编译成平台无关的 Java 字节码文件(.class),接下来对应平台 JVM 对字节码文件进行解释,翻译成对应平台匹配的机器指令并运行。

      Java语言编译运行

      同时 JVM 也是一个跨语言的平台,和语言无关,只和 class 的文件格式关联,任何语言,只要能翻译成符合规范的字节码文件,都能被 JVM 运行。

      JVM跨语言

      二、内存管理

      2.能说一下 JVM 的内存区域吗?

      JVM 内存区域最粗略的划分可以分为,当然,按照虚拟机规范,可以划分为以下几个区域:

      Java虚拟机运行时数据区

      JVM 内存分为线程私有区和线程共享区,其中方法区是线程共享区,虚拟机栈本地方法栈程序计数器是线程隔离的数据区。

      1)程序计数器

      程序计数器(Program Counter Register)也被称为 PC 寄存器,是一块较小的内存空间。

      它可以看作是当前线程所执行的字节码的行号指示器。

      2)Java 虚拟机栈

      Java 虚拟机栈(Java Virtual Machine Stack)也是线程私有的,它的生命周期与线程相同。

      Java 虚拟机栈描述的是 Java 方法执行的线程内存模型:方法执行时,JVM 会同步创建一个栈帧,用来存储局部变量表、操作数栈、动态连接等。

      Java虚拟机栈

      3)本地方法栈

      本地方法栈(Native Method Stacks)与虚拟机栈所发挥的作用是非常相似的,其区别只是虚拟机栈为虚拟机执行 Java 方法(也就是字节码)服务,而本地方法栈则是为虚拟机使用到的本地(Native)方法服务。

      Java 虚拟机规范允许本地方法栈被实现成固定大小的或者是根据计算动态扩展和收缩的。

      4)Java 堆

      对于 Java 应用程序来说,Java 堆(Java Heap)是虚拟机所管理的内存中最大的一块。Java 堆是被所有线程共享的一块内存区域,在虚拟机启动时创建。此内存区域的唯一目的就是存放对象实例,Java 里“几乎”所有的对象实例都在这里分配内存。

      Java 堆是垃圾收集器管理的内存区域,因此一些资料中它也被称作“GC 堆”(Garbage Collected Heap,)。从回收内存的角度看,由于现代垃圾收集器大部分都是基于分代收集理论设计的,所以 Java 堆中经常会出现新生代老年代Eden空间From Survivor空间To Survivor空间等名词,需要注意的是这种划分只是根据垃圾回收机制来进行的划分,不是 Java 虚拟机规范本身制定的。

      Java 堆内存结构

      5)方法区

      方法区是比较特别的一块区域,和堆类似,它也是各个线程共享的内存区域,用于存储已被虚拟机加载的类型信息、常量、静态变量、即时编译器编译后的代码缓存等数据。

      它特别在 Java 虚拟机规范对它的约束非常宽松,所以方法区的具体实现历经了许多变迁,例如 jdk1.7 之前使用永久代作为方法区的实现。

      3.说一下 JDK1.6、1.7、1.8 内存区域的变化?

      JDK1.6、1.7/1.8 内存区域发生了变化,主要体现在方法区的实现:

      • JDK1.6 使用永久代实现方法区:

      JDK 1.6内存区域

      • JDK1.7 时发生了一些变化,将字符串常量池、静态变量,存放在堆上

      JDK 1.7内存区域

      • 在 JDK1.8 时彻底干掉了永久代,而在直接内存中划出一块区域作为元空间,运行时常量池、类常量池都移动到元空间。

      JDK 1.8内存区域

      4.为什么使用元空间替代永久代作为方法区的实现?

      Java 虚拟机规范规定的方法区只是换种方式实现。有客观和主观两个原因。

      • 客观上使用永久代来实现方法区的决定的设计导致了 Java 应用更容易遇到内存溢出的问题(永久代有-XX:MaxPermSize 的上限,即使不设置也有默认大小,而 J9 和 JRockit 只要没有触碰到进程可用内存的上限,例如 32 位系统中的 4GB 限制,就不会出问题),而且有极少数方法 (例如 String::intern())会因永久代的原因而导致不同虚拟机下有不同的表现。

      • 主观上当 Oracle 收购 BEA 获得了 JRockit 的所有权后,准备把 JRockit 中的优秀功能,譬如 Java Mission Control 管理工具,移植到 HotSpot 虚拟机时,但因为两者对方法区实现的差异而面临诸多困难。考虑到 HotSpot 未来的发展,在 JDK 6 的 时候 HotSpot 开发团队就有放弃永久代,逐步改为采用本地内存(Native Memory)来实现方法区的计划了,到了 JDK 7 的 HotSpot,已经把原本放在永久代的字符串常量池、静态变量等移出,而到了 JDK 8,终于完全废弃了永久代的概念,改用与 JRockit、J9 一样在本地内存中实现的元空间(Meta-space)来代替,把 JDK 7 中永久代还剩余的内容(主要是类型信息)全部移到元空间中。

      5.对象创建的过程了解吗?

      在 JVM 中对象的创建,我们从一个 new 指令开始:

      • 首先检查这个指令的参数是否能在常量池中定位到一个类的符号引用

      • 检查这个符号引用代表的类是否已被加载、解析和初始化过。如果没有,就先执行相应的类加载过程

      • 类加载检查通过后,接下来虚拟机将为新生对象分配内存。

      • 内存分配完成之后,虚拟机将分配到的内存空间(但不包括对象头)都初始化为零值。

      • 接下来设置对象头,请求头里包含了对象是哪个类的实例、如何才能找到类的元数据信息、对象的哈希码、对象的 GC 分代年龄等信息。

      这个过程大概图示如下:

      对象创建过程

      6.什么是指针碰撞?什么是空闲列表?

      内存分配有两种方式,指针碰撞(Bump The Pointer)、空闲列表(Free List)。

      指针碰撞和空闲列表

      • 指针碰撞:假设 Java 堆中内存是绝对规整的,所有被使用过的内存都被放在一边,空闲的内存被放在另一边,中间放着一个指针作为分界点的指示器,那所分配内存就仅仅是把那个指针向空闲空间方向挪动一段与对象大小相等的距离,这种分配方式称为“指针碰撞”。
      • 空闲列表:如果 Java 堆中的内存并不是规整的,已被使用的内存和空闲的内存相互交错在一起,那就没有办法简单地进行指针碰撞了,虚拟机就必须维护一个列表,记录上哪些内存块是可用的,在分配的时候从列表中找到一块足够大的空间划分给对象实例,并更新列表上的记录,这种分配方式称为“空闲列表”。
      • 两种方式的选择由 Java 堆是否规整决定,Java 堆是否规整是由选择的垃圾收集器是否具有压缩整理能力决定的。

      7.JVM 里 new 对象时,堆会发生抢占吗?JVM 是怎么设计来保证线程安全的?

      会,假设 JVM 虚拟机上,每一次 new 对象时,指针就会向右移动一个对象 size 的距离,一个线程正在给 A 对象分配内存,指针还没有来的及修改,另一个为 B 对象分配内存的线程,又引用了这个指针来分配内存,这就发生了抢占。

      有两种可选方案来解决这个问题:

      堆抢占和解决方案

      • 采用 CAS 分配重试的方式来保证更新操作的原子性

      • 每个线程在 Java 堆中预先分配一小块内存,也就是本地线程分配缓冲(Thread Local Allocation

        Buffer,TLAB),要分配内存的线程,先在本地缓冲区中分配,只有本地缓冲区用完了,分配新的缓存区时才需要同步锁定。

      8.能说一下对象的内存布局吗?

      在 HotSpot 虚拟机里,对象在堆内存中的存储布局可以划分为三个部分:对象头(Header)、实例数据(Instance Data)和对齐填充(Padding)。

      对象的存储布局

      对象头主要由两部分组成:

      • 第一部分存储对象自身的运行时数据:哈希码、GC 分代年龄、锁状态标志、线程持有的锁、偏向线程 ID、偏向时间戳等,官方称它为 Mark Word,它是个动态的结构,随着对象状态变化。
      • 第二部分是类型指针,指向对象的类元数据类型(即对象代表哪个类)。
      • 此外,如果对象是一个 Java 数组,那还应该有一块用于记录数组长度的数据

      实例数据用来存储对象真正的有效信息,也就是我们在程序代码里所定义的各种类型的字段内容,无论是从父类继承的,还是自己定义的。

      对齐填充不是必须的,没有特别含义,仅仅起着占位符的作用。

      9.对象怎么访问定位?

      Java 程序会通过栈上的 reference 数据来操作堆上的具体对象。由于 reference 类型在《Java 虚拟机规范》里面只规定了它是一个指向对象的引用,并没有定义这个引用应该通过什么方式去定位、访问到堆中对象的具体位置,所以对象访问方式也是由虚拟机实现而定的,主流的访问方式主要有使用句柄和直接指针两种:

      • 如果使用句柄访问的话,Java 堆中将可能会划分出一块内存来作为句柄池,reference 中存储的就是对象的句柄地址,而句柄中包含了对象实例数据与类型数据各自具体的地址信息,其结构如图所示:

      通过句柄访问对象

      • 如果使用直接指针访问的话,Java 堆中对象的内存布局就必须考虑如何放置访问类型数据的相关信息,reference 中存储的直接就是对象地址,如果只是访问对象本身的话,就不需要多一次间接访问的开销,如图所示:

      通过直接指针访问对象

      这两种对象访问方式各有优势,使用句柄来访问的最大好处就是 reference 中存储的是稳定句柄地址,在对象被移动(垃圾收集时移动对象是非常普遍的行为)时只会改变句柄中的实例数据指针,而 reference 本身不需要被修改。

      使用直接指针来访问最大的好处就是速度更快,它节省了一次指针定位的时间开销,由于对象访问在 Java 中非常频繁,因此这类开销积少成多也是一项极为可观的执行成本。

      HotSpot 虚拟机主要使用直接指针来进行对象访问。

      10.内存溢出和内存泄漏是什么意思?

      内存泄露就是申请的内存空间没有被正确释放,导致内存被白白占用。

      内存溢出就是申请的内存超过了可用内存,内存不够了。

      两者关系:内存泄露可能会导致内存溢出。

      用一个有味道的比喻,内存溢出就是排队去蹲坑,发现没坑位了,内存泄漏,就是有人占着茅坑不拉屎,占着茅坑不拉屎的多了可能会导致坑位不够用。

      内存泄漏、内存溢出

      11.能手写内存溢出的例子吗?

      在 JVM 的几个内存区域中,除了程序计数器外,其他几个运行时区域都有发生内存溢出(OOM)异常的可能,重点关注堆和栈。

      • Java 堆溢出

      Java 堆用于储存对象实例,只要不断创建不可被回收的对象,比如静态对象,那么随着对象数量的增加,总容量触及最大堆的容量限制后就会产生内存溢出异常(OutOfMemoryError)。

      这就相当于一个房子里,不断堆积不能被收走的杂物,那么房子很快就会被堆满了。

      /**
      +    

      面渣逆袭(Java 虚拟机篇)必看👍

      沉默王二2022年3月9日
      • 面渣逆袭
      • Java
      大约 54 分钟

      面渣逆袭(Java 虚拟机篇)必看👍

      图文详解 50 道Java虚拟机高频面试题,这次面试,一定吊打面试官,整理:沉默王二,戳转载链接open in new window,作者:三分恶,戳原文链接open in new window

      一、引言

      1.什么是 JVM?

      JVM——Java 虚拟机,它是 Java 实现平台无关性的基石。

      Java 程序运行的时候,编译器将 Java 文件编译成平台无关的 Java 字节码文件(.class),接下来对应平台 JVM 对字节码文件进行解释,翻译成对应平台匹配的机器指令并运行。

      Java语言编译运行

      同时 JVM 也是一个跨语言的平台,和语言无关,只和 class 的文件格式关联,任何语言,只要能翻译成符合规范的字节码文件,都能被 JVM 运行。

      JVM跨语言

      二、内存管理

      2.能说一下 JVM 的内存区域吗?

      JVM 内存区域最粗略的划分可以分为,当然,按照虚拟机规范,可以划分为以下几个区域:

      Java虚拟机运行时数据区

      JVM 内存分为线程私有区和线程共享区,其中方法区是线程共享区,虚拟机栈本地方法栈程序计数器是线程隔离的数据区。

      1)程序计数器

      程序计数器(Program Counter Register)也被称为 PC 寄存器,是一块较小的内存空间。

      它可以看作是当前线程所执行的字节码的行号指示器。

      2)Java 虚拟机栈

      Java 虚拟机栈(Java Virtual Machine Stack)也是线程私有的,它的生命周期与线程相同。

      Java 虚拟机栈描述的是 Java 方法执行的线程内存模型:方法执行时,JVM 会同步创建一个栈帧,用来存储局部变量表、操作数栈、动态连接等。

      Java虚拟机栈

      3)本地方法栈

      本地方法栈(Native Method Stacks)与虚拟机栈所发挥的作用是非常相似的,其区别只是虚拟机栈为虚拟机执行 Java 方法(也就是字节码)服务,而本地方法栈则是为虚拟机使用到的本地(Native)方法服务。

      Java 虚拟机规范允许本地方法栈被实现成固定大小的或者是根据计算动态扩展和收缩的。

      4)Java 堆

      对于 Java 应用程序来说,Java 堆(Java Heap)是虚拟机所管理的内存中最大的一块。Java 堆是被所有线程共享的一块内存区域,在虚拟机启动时创建。此内存区域的唯一目的就是存放对象实例,Java 里“几乎”所有的对象实例都在这里分配内存。

      Java 堆是垃圾收集器管理的内存区域,因此一些资料中它也被称作“GC 堆”(Garbage Collected Heap,)。从回收内存的角度看,由于现代垃圾收集器大部分都是基于分代收集理论设计的,所以 Java 堆中经常会出现新生代老年代Eden空间From Survivor空间To Survivor空间等名词,需要注意的是这种划分只是根据垃圾回收机制来进行的划分,不是 Java 虚拟机规范本身制定的。

      Java 堆内存结构

      5)方法区

      方法区是比较特别的一块区域,和堆类似,它也是各个线程共享的内存区域,用于存储已被虚拟机加载的类型信息、常量、静态变量、即时编译器编译后的代码缓存等数据。

      它特别在 Java 虚拟机规范对它的约束非常宽松,所以方法区的具体实现历经了许多变迁,例如 jdk1.7 之前使用永久代作为方法区的实现。

      3.说一下 JDK1.6、1.7、1.8 内存区域的变化?

      JDK1.6、1.7/1.8 内存区域发生了变化,主要体现在方法区的实现:

      • JDK1.6 使用永久代实现方法区:

      JDK 1.6内存区域

      • JDK1.7 时发生了一些变化,将字符串常量池、静态变量,存放在堆上

      JDK 1.7内存区域

      • 在 JDK1.8 时彻底干掉了永久代,而在直接内存中划出一块区域作为元空间,运行时常量池、类常量池都移动到元空间。

      JDK 1.8内存区域

      4.为什么使用元空间替代永久代作为方法区的实现?

      Java 虚拟机规范规定的方法区只是换种方式实现。有客观和主观两个原因。

      • 客观上使用永久代来实现方法区的决定的设计导致了 Java 应用更容易遇到内存溢出的问题(永久代有-XX:MaxPermSize 的上限,即使不设置也有默认大小,而 J9 和 JRockit 只要没有触碰到进程可用内存的上限,例如 32 位系统中的 4GB 限制,就不会出问题),而且有极少数方法 (例如 String::intern())会因永久代的原因而导致不同虚拟机下有不同的表现。

      • 主观上当 Oracle 收购 BEA 获得了 JRockit 的所有权后,准备把 JRockit 中的优秀功能,譬如 Java Mission Control 管理工具,移植到 HotSpot 虚拟机时,但因为两者对方法区实现的差异而面临诸多困难。考虑到 HotSpot 未来的发展,在 JDK 6 的 时候 HotSpot 开发团队就有放弃永久代,逐步改为采用本地内存(Native Memory)来实现方法区的计划了,到了 JDK 7 的 HotSpot,已经把原本放在永久代的字符串常量池、静态变量等移出,而到了 JDK 8,终于完全废弃了永久代的概念,改用与 JRockit、J9 一样在本地内存中实现的元空间(Meta-space)来代替,把 JDK 7 中永久代还剩余的内容(主要是类型信息)全部移到元空间中。

      5.对象创建的过程了解吗?

      在 JVM 中对象的创建,我们从一个 new 指令开始:

      • 首先检查这个指令的参数是否能在常量池中定位到一个类的符号引用

      • 检查这个符号引用代表的类是否已被加载、解析和初始化过。如果没有,就先执行相应的类加载过程

      • 类加载检查通过后,接下来虚拟机将为新生对象分配内存。

      • 内存分配完成之后,虚拟机将分配到的内存空间(但不包括对象头)都初始化为零值。

      • 接下来设置对象头,请求头里包含了对象是哪个类的实例、如何才能找到类的元数据信息、对象的哈希码、对象的 GC 分代年龄等信息。

      这个过程大概图示如下:

      对象创建过程

      6.什么是指针碰撞?什么是空闲列表?

      内存分配有两种方式,指针碰撞(Bump The Pointer)、空闲列表(Free List)。

      指针碰撞和空闲列表

      • 指针碰撞:假设 Java 堆中内存是绝对规整的,所有被使用过的内存都被放在一边,空闲的内存被放在另一边,中间放着一个指针作为分界点的指示器,那所分配内存就仅仅是把那个指针向空闲空间方向挪动一段与对象大小相等的距离,这种分配方式称为“指针碰撞”。
      • 空闲列表:如果 Java 堆中的内存并不是规整的,已被使用的内存和空闲的内存相互交错在一起,那就没有办法简单地进行指针碰撞了,虚拟机就必须维护一个列表,记录上哪些内存块是可用的,在分配的时候从列表中找到一块足够大的空间划分给对象实例,并更新列表上的记录,这种分配方式称为“空闲列表”。
      • 两种方式的选择由 Java 堆是否规整决定,Java 堆是否规整是由选择的垃圾收集器是否具有压缩整理能力决定的。

      7.JVM 里 new 对象时,堆会发生抢占吗?JVM 是怎么设计来保证线程安全的?

      会,假设 JVM 虚拟机上,每一次 new 对象时,指针就会向右移动一个对象 size 的距离,一个线程正在给 A 对象分配内存,指针还没有来的及修改,另一个为 B 对象分配内存的线程,又引用了这个指针来分配内存,这就发生了抢占。

      有两种可选方案来解决这个问题:

      堆抢占和解决方案

      • 采用 CAS 分配重试的方式来保证更新操作的原子性

      • 每个线程在 Java 堆中预先分配一小块内存,也就是本地线程分配缓冲(Thread Local Allocation

        Buffer,TLAB),要分配内存的线程,先在本地缓冲区中分配,只有本地缓冲区用完了,分配新的缓存区时才需要同步锁定。

      8.能说一下对象的内存布局吗?

      在 HotSpot 虚拟机里,对象在堆内存中的存储布局可以划分为三个部分:对象头(Header)、实例数据(Instance Data)和对齐填充(Padding)。

      对象的存储布局

      对象头主要由两部分组成:

      • 第一部分存储对象自身的运行时数据:哈希码、GC 分代年龄、锁状态标志、线程持有的锁、偏向线程 ID、偏向时间戳等,官方称它为 Mark Word,它是个动态的结构,随着对象状态变化。
      • 第二部分是类型指针,指向对象的类元数据类型(即对象代表哪个类)。
      • 此外,如果对象是一个 Java 数组,那还应该有一块用于记录数组长度的数据

      实例数据用来存储对象真正的有效信息,也就是我们在程序代码里所定义的各种类型的字段内容,无论是从父类继承的,还是自己定义的。

      对齐填充不是必须的,没有特别含义,仅仅起着占位符的作用。

      9.对象怎么访问定位?

      Java 程序会通过栈上的 reference 数据来操作堆上的具体对象。由于 reference 类型在《Java 虚拟机规范》里面只规定了它是一个指向对象的引用,并没有定义这个引用应该通过什么方式去定位、访问到堆中对象的具体位置,所以对象访问方式也是由虚拟机实现而定的,主流的访问方式主要有使用句柄和直接指针两种:

      • 如果使用句柄访问的话,Java 堆中将可能会划分出一块内存来作为句柄池,reference 中存储的就是对象的句柄地址,而句柄中包含了对象实例数据与类型数据各自具体的地址信息,其结构如图所示:

      通过句柄访问对象

      • 如果使用直接指针访问的话,Java 堆中对象的内存布局就必须考虑如何放置访问类型数据的相关信息,reference 中存储的直接就是对象地址,如果只是访问对象本身的话,就不需要多一次间接访问的开销,如图所示:

      通过直接指针访问对象

      这两种对象访问方式各有优势,使用句柄来访问的最大好处就是 reference 中存储的是稳定句柄地址,在对象被移动(垃圾收集时移动对象是非常普遍的行为)时只会改变句柄中的实例数据指针,而 reference 本身不需要被修改。

      使用直接指针来访问最大的好处就是速度更快,它节省了一次指针定位的时间开销,由于对象访问在 Java 中非常频繁,因此这类开销积少成多也是一项极为可观的执行成本。

      HotSpot 虚拟机主要使用直接指针来进行对象访问。

      10.内存溢出和内存泄漏是什么意思?

      内存泄露就是申请的内存空间没有被正确释放,导致内存被白白占用。

      内存溢出就是申请的内存超过了可用内存,内存不够了。

      两者关系:内存泄露可能会导致内存溢出。

      用一个有味道的比喻,内存溢出就是排队去蹲坑,发现没坑位了,内存泄漏,就是有人占着茅坑不拉屎,占着茅坑不拉屎的多了可能会导致坑位不够用。

      内存泄漏、内存溢出

      11.能手写内存溢出的例子吗?

      在 JVM 的几个内存区域中,除了程序计数器外,其他几个运行时区域都有发生内存溢出(OOM)异常的可能,重点关注堆和栈。

      • Java 堆溢出

      Java 堆用于储存对象实例,只要不断创建不可被回收的对象,比如静态对象,那么随着对象数量的增加,总容量触及最大堆的容量限制后就会产生内存溢出异常(OutOfMemoryError)。

      这就相当于一个房子里,不断堆积不能被收走的杂物,那么房子很快就会被堆满了。

      /**
        * VM参数: -Xms20m -Xmx20m -XX:+HeapDumpOnOutOfMemoryError
        */
       public class HeapOOM {
      @@ -146,6 +146,6 @@ jmap -dump:format=b,fileDumping heap to /root/dump ...
       Heap dump file created
       

      10)dump 文件分析

      可以使用 jhat 命令分析:jhat -port 8000 29471.dump,浏览器访问 jhat 服务,端口是 8000。

      通常使用图形化工具分析,如 JDK 自带的 jvisualvm,从菜单 > 文件 > 装入 dump 文件。

      或使用第三方式具分析的,如 JProfiler 也是个图形化工具,GCViewer 工具。Eclipse 或以使用 MAT 工具查看。或使用在线分析平台 GCEasy

      注意:如果 dump 文件较大的话,分析会占比较大的内存。

      11)在 dump 文析结果中查找存在大量的对象,再查对其的引用。

      基本上就可以定位到代码层的逻辑了。

      41.有没有处理过内存溢出问题?

      内存泄漏和内存溢出二者关系非常密切,内存溢出可能会有很多原因导致,内存泄漏最可能的罪魁祸首之一。

      排查过程和排查内存泄漏过程类似。

      四、虚拟机执行

      42.能说一下类的生命周期吗?

      一个类从被加载到虚拟机内存中开始,到从内存中卸载,整个生命周期需要经过七个阶段:加载 (Loading)、验证(Verification)、准备(Preparation)、解析(Resolution)、初始化 (Initialization)、使用(Using)和卸载(Unloading),其中验证、准备、解析三个部分统称为连接(Linking)。

      类的生命周期

      43.类加载的过程知道吗?

      加载是 JVM 加载的起点,具体什么时候开始加载,《Java 虚拟机规范》中并没有进行强制约束,可以交给虚拟机的具体实现来自由把握。

      在加载过程,JVM 要做三件事情:

      加载

      • 1)通过一个类的全限定名来获取定义此类的二进制字节流。

      • 2)将这个字节流所代表的静态存储结构转化为方法区的运行时数据结构。

      • 3)在内存中生成一个代表这个类的 java.lang.Class 对象,作为方法区这个类的各种数据的访问入口。

      加载阶段结束后,Java 虚拟机外部的二进制字节流就按照虚拟机所设定的格式存储在方法区之中了,方法区中的数据存储格式完全由虚拟机实现自行定义,《Java 虚拟机规范》未规定此区域的具体数据结构。

      类型数据妥善安置在方法区之后,会在 Java 堆内存中实例化一个 java.lang.Class 类的对象, 这个对象将作为程序访问方法区中的类型数据的外部接口。

      44.类加载器有哪些?

      主要有四种类加载器:

      • 启动类加载器(Bootstrap ClassLoader)用来加载 java 核心类库,无法被 java 程序直接引用。

      • 扩展类加载器(extensions class loader):它用来加载 Java 的扩展库。Java 虚拟机的实现会提供一个扩展库目录。该类加载器在此目录里面查找并加载 Java 类。

      • 系统类加载器(system class loader):它根据 Java 应用的类路径(CLASSPATH)来加载 Java 类。一般来说,Java 应用的类都是由它来完成加载的。可以通过 ClassLoader.getSystemClassLoader()来获取它。

      • 用户自定义类加载器 (user class loader),用户通过继承 java.lang.ClassLoader 类的方式自行实现的类加载器。

      45.什么是双亲委派机制?

      双亲委派模型

      双亲委派模型的工作过程:如果一个类加载器收到了类加载的请求,它首先不会自己去尝试加载这个类,而是把这个请求委派给父类加载器去完成,每一个层次的类加载器都是如此,因此所有的加载请求最终都应该传送到最顶层的启动类加载器中,只有当父加载器反馈自己无法完成这个加载请求时,子加载器才会尝试自己去完成加载。

      46.为什么要用双亲委派机制?

      答案是为了保证应用程序的稳定有序。

      例如类 java.lang.Object,它存放在 rt.jar 之中,通过双亲委派机制,保证最终都是委派给处于模型最顶端的启动类加载器进行加载,保证 Object 的一致。反之,都由各个类加载器自行去加载的话,如果用户自己也编写了一个名为 java.lang.Object 的类,并放在程序的 ClassPath 中,那系统中就会出现多个不同的 Object 类。

      47.如何破坏双亲委派机制?

      如果不想打破双亲委派模型,就重写 ClassLoader 类中的 fifindClass()方法即可,无法被父类加载器加载的类最终会通过这个方法被加载。而如果想打破双亲委派模型则需要重写 loadClass()方法。

      48.历史上有哪几次双亲委派机制的破坏?

      双亲委派机制在历史上主要有三次破坏:

      双亲委派模型的三次破坏

      第一次破坏

      双亲委派模型的第一次“被破坏”其实发生在双亲委派模型出现之前——即 JDK 1.2 面世以前的“远古”时代。

      由于双亲委派模型在 JDK 1.2 之后才被引入,但是类加载器的概念和抽象类 java.lang.ClassLoader 则在 Java 的第一个版本中就已经存在,为了向下兼容旧代码,所以无法以技术手段避免 loadClass()被子类覆盖的可能性,只能在 JDK 1.2 之后的 java.lang.ClassLoader 中添加一个新的 protected 方法 findClass(),并引导用户编写的类加载逻辑时尽可能去重写这个方法,而不是在 loadClass()中编写代码。

      第二次破坏

      双亲委派模型的第二次“被破坏”是由这个模型自身的缺陷导致的,如果有基础类型又要调用回用户的代码,那该怎么办呢?

      例如我们比较熟悉的 JDBC:

      各个厂商各有不同的 JDBC 的实现,Java 在核心包\lib里定义了对应的 SPI,那么这个就毫无疑问由启动类加载器加载器加载。

      但是各个厂商的实现,是没办法放在核心包里的,只能放在classpath里,只能被应用类加载器加载。那么,问题来了,启动类加载器它就加载不到厂商提供的 SPI 服务代码。

      为了解决这个问题,引入了一个不太优雅的设计:线程上下文类加载器 (Thread Context ClassLoader)。这个类加载器可以通过 java.lang.Thread 类的 setContext-ClassLoader()方法进行设置,如果创建线程时还未设置,它将会从父线程中继承一个,如果在应用程序的全局范围内都没有设置过的话,那这个类加载器默认就是应用程序类加载器。

      JNDI 服务使用这个线程上下文类加载器去加载所需的 SPI 服务代码,这是一种父类加载器去请求子类加载器完成类加载的行为。

      第三次破坏

      双亲委派模型的第三次“被破坏”是由于用户对程序动态性的追求而导致的,例如代码热替换(Hot Swap)、模块热部署(Hot Deployment)等。

      OSGi 实现模块化热部署的关键是它自定义的类加载器机制的实现,每一个程序模块(OSGi 中称为 Bundle)都有一个自己的类加载器,当需要更换一个 Bundle 时,就把 Bundle 连同类加载器一起换掉以实现代码的热替换。在 OSGi 环境下,类加载器不再双亲委派模型推荐的树状结构,而是进一步发展为更加复杂的网状结构。

      49.你觉得应该怎么实现一个热部署功能?

      我们已经知道了 Java 类的加载过程。一个 Java 类文件到虚拟机里的对象,要经过如下过程:首先通过 Java 编译器,将 Java 文件编译成 class 字节码,类加载器读取 class 字节码,再将类转化为实例,对实例 newInstance 就可以生成对象。

      类加载器 ClassLoader 功能,也就是将 class 字节码转换到类的实例。在 Java 应用中,所有的实例都是由类加载器,加载而来。

      一般在系统中,类的加载都是由系统自带的类加载器完成,而且对于同一个全限定名的 java 类(如 com.csiar.soc.HelloWorld),只能被加载一次,而且无法被卸载。

      这个时候问题就来了,如果我们希望将 java 类卸载,并且替换更新版本的 java 类,该怎么做呢?

      既然在类加载器中,Java 类只能被加载一次,并且无法卸载。那么我们是不是可以直接把 Java 类加载器干掉呢?答案是可以的,我们可以自定义类加载器,并重写 ClassLoader 的 findClass 方法。

      想要实现热部署可以分以下三个步骤:

      • 1)销毁原来的自定义 ClassLoader
      • 2)更新 class 类文件
      • 3)创建新的 ClassLoader 去加载更新后的 class 类文件。

      到此,一个热部署的功能就这样实现了。

      50.Tomcat 的类加载机制了解吗?

      Tomcat 是主流的 Java Web 服务器之一,为了实现一些特殊的功能需求,自定义了一些类加载器。

      Tomcat 类加载器如下:

      Tomcat类加载器

      Tomcat 实际上也是破坏了双亲委派模型的。

      Tomact 是 web 容器,可能需要部署多个应用程序。不同的应用程序可能会依赖同一个第三方类库的不同版本,但是不同版本的类库中某一个类的全路径名可能是一样的。如多个应用都要依赖 hollis.jar,但是 A 应用需要依赖 1.0.0 版本,但是 B 应用需要依赖 1.0.1 版本。这两个版本中都有一个类是 com.hollis.Test.class。如果采用默认的双亲委派类加载机制,那么无法加载多个相同的类。

      所以,Tomcat 破坏了双亲委派原则,提供隔离的机制,为每个 web 容器单独提供一个 WebAppClassLoader 加载器。每一个 WebAppClassLoader 负责加载本身的目录下的 class 文件,加载不到时再交 CommonClassLoader 加载,这和双亲委派刚好相反。

      图文详解 50 道Java虚拟机高频面试题,这次面试,一定吊打面试官,整理:沉默王二,戳转载链接open in new window,作者:三分恶,戳原文链接open in new window

      - + diff --git a/dist/sidebar/sanfene/mybatis.html b/dist/sidebar/sanfene/mybatis.html index f35b046e..e6983777 100644 --- a/dist/sidebar/sanfene/mybatis.html +++ b/dist/sidebar/sanfene/mybatis.html @@ -39,10 +39,10 @@ } - + -

      面渣逆袭(MyBatis)必看

      沉默王二2022年6月6日
      • 面渣逆袭
      • MyBatis
      大约 26 分钟

      图文详解 20 道MyBatis面试高频题,这次吊打面试官,我觉得稳了(手动 dog)。整理:沉默王二,戳转载链接open in new window,作者:三分恶,戳原文链接open in new window

      大家好,我是二哥呀,面渣逆袭系列继续,这节我们的主角是MyBatis,作为当前国内最流行的ORM框架,是我们这些crud选手最趁手的工具,赶紧来看看面试都会问哪些问题吧。

      基础

      1. 说说什么是MyBatis?

      MyBatis logo

      先吹一下

      • Mybatis 是一个半 ORM(对象关系映射)框架,它内部封装了 JDBC,开发时只需要关注 SQL 语句本身,不需要花费精力去处理加载驱动、创建连接、创建statement 等繁杂的过程。程序员直接编写原生态 sql,可以严格控制 sql 执行性能,灵活度高。
      • MyBatis 可以使用 XML 或注解来配置和映射原生信息,将 POJO 映射成数据库中的记录,避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。

      再说一下缺点

      • SQL语句的编写工作量较大,尤其当字段多、关联表多时,对开发人员编写SQL语句的功底有一定要求
      • SQL语句依赖于数据库,导致数据库移植性差,不能随意更换数据库

      ORM是什么?

      ORM简单示意图

      • ORM(Object Relational Mapping),对象关系映射,是一种为了解决关系型数据库数据与简单Java对象(POJO)的映射关系的技术。简单来说,ORM是通过使用描述对象和数据库之间映射的元数据,将程序中的对象自动持久化到关系型数据库中。

      为什么说Mybatis是半自动ORM映射工具?它与全自动的区别在哪里?

      • Hibernate属于全自动ORM映射工具,使用Hibernate查询关联对象或者关联集合对象时,可以根据对象关系模型直接获取,所以它是全自动的。
      • 而Mybatis在查询关联对象或关联集合对象时,需要手动编写SQL来完成,所以,被称之为半自动ORM映射工具。

      JDBC编程有哪些不足之处,MyBatis是如何解决的?

      JDBC编程的不足

      • 1、数据连接创建、释放频繁造成系统资源浪费从而影响系统性能,在mybatis-config.xml中配置数据链接池,使用连接池统一管理数据库连接。
      • 2、sql语句写在代码中造成代码不易维护,将sql语句配置在XXXXmapper.xml文件中与java代码分离。
      • 3、向sql语句传参数麻烦,因为sql语句的where条件不一定,可能多也可能少,占位符需要和参数一一对应。Mybatis自动将java对象映射至sql语句。
      • 4、对结果集解析麻烦,sql变化导致解析代码变化,且解析前需要遍历,如果能将数据库记录封装成pojo对象解析比较方便。Mybatis自动将sql执行结果映射至java对象。

      2. Hibernate 和 MyBatis 有什么区别?

      相同点

      • 都是对jdbc的封装,都是应用于持久层的框架。

      这还用说?

      不同点

      1)映射关系

      • MyBatis 是一个半自动映射的框架,配置Java对象与sql语句执行结果的对应关系,多表关联关系配置简单
      • Hibernate 是一个全表映射的框架,配置Java对象与数据库表的对应关系,多表关联关系配置复杂

      2)SQL优化和移植性

      • Hibernate 对SQL语句封装,提供了日志、缓存、级联(级联比 MyBatis 强大)等特性,此外还提供 HQL(Hibernate Query Language)操作数据库,数据库无关性支持好,但会多消耗性能。如果项目需要支持多种数据库,代码开发量少,但SQL语句优化困难。
      • MyBatis 需要手动编写 SQL,支持动态 SQL、处理列表、动态生成表名、支持存储过程。开发工作量相对大些。直接使用SQL语句操作数据库,不支持数据库无关性,但sql语句优化容易。

      3)MyBatis和Hibernate的适用场景不同

      Mybatis vs Hibernate

      • Hibernate 是标准的ORM框架,SQL编写量较少,但不够灵活,适合于需求相对稳定,中小型的软件项目,比如:办公自动化系统
      • MyBatis 是半ORM框架,需要编写较多SQL,但是比较灵活,适合于需求变化频繁,快速迭代的项目,比如:电商网站

      3. MyBatis使用过程?生命周期?

      MyBatis基本使用的过程大概可以分为这么几步:

      Mybatis基本使用步骤

      • 1)创建SqlSessionFactory

      可以从配置或者直接编码来创建SqlSessionFactory

      String resource = "org/mybatis/example/mybatis-config.xml";
      +    

      面渣逆袭(MyBatis)必看

      沉默王二2022年6月6日
      • 面渣逆袭
      • MyBatis
      大约 26 分钟

      图文详解 20 道MyBatis面试高频题,这次吊打面试官,我觉得稳了(手动 dog)。整理:沉默王二,戳转载链接open in new window,作者:三分恶,戳原文链接open in new window

      大家好,我是二哥呀,面渣逆袭系列继续,这节我们的主角是MyBatis,作为当前国内最流行的ORM框架,是我们这些crud选手最趁手的工具,赶紧来看看面试都会问哪些问题吧。

      基础

      1. 说说什么是MyBatis?

      MyBatis logo

      先吹一下

      • Mybatis 是一个半 ORM(对象关系映射)框架,它内部封装了 JDBC,开发时只需要关注 SQL 语句本身,不需要花费精力去处理加载驱动、创建连接、创建statement 等繁杂的过程。程序员直接编写原生态 sql,可以严格控制 sql 执行性能,灵活度高。
      • MyBatis 可以使用 XML 或注解来配置和映射原生信息,将 POJO 映射成数据库中的记录,避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。

      再说一下缺点

      • SQL语句的编写工作量较大,尤其当字段多、关联表多时,对开发人员编写SQL语句的功底有一定要求
      • SQL语句依赖于数据库,导致数据库移植性差,不能随意更换数据库

      ORM是什么?

      ORM简单示意图

      • ORM(Object Relational Mapping),对象关系映射,是一种为了解决关系型数据库数据与简单Java对象(POJO)的映射关系的技术。简单来说,ORM是通过使用描述对象和数据库之间映射的元数据,将程序中的对象自动持久化到关系型数据库中。

      为什么说Mybatis是半自动ORM映射工具?它与全自动的区别在哪里?

      • Hibernate属于全自动ORM映射工具,使用Hibernate查询关联对象或者关联集合对象时,可以根据对象关系模型直接获取,所以它是全自动的。
      • 而Mybatis在查询关联对象或关联集合对象时,需要手动编写SQL来完成,所以,被称之为半自动ORM映射工具。

      JDBC编程有哪些不足之处,MyBatis是如何解决的?

      JDBC编程的不足

      • 1、数据连接创建、释放频繁造成系统资源浪费从而影响系统性能,在mybatis-config.xml中配置数据链接池,使用连接池统一管理数据库连接。
      • 2、sql语句写在代码中造成代码不易维护,将sql语句配置在XXXXmapper.xml文件中与java代码分离。
      • 3、向sql语句传参数麻烦,因为sql语句的where条件不一定,可能多也可能少,占位符需要和参数一一对应。Mybatis自动将java对象映射至sql语句。
      • 4、对结果集解析麻烦,sql变化导致解析代码变化,且解析前需要遍历,如果能将数据库记录封装成pojo对象解析比较方便。Mybatis自动将sql执行结果映射至java对象。

      2. Hibernate 和 MyBatis 有什么区别?

      相同点

      • 都是对jdbc的封装,都是应用于持久层的框架。

      这还用说?

      不同点

      1)映射关系

      • MyBatis 是一个半自动映射的框架,配置Java对象与sql语句执行结果的对应关系,多表关联关系配置简单
      • Hibernate 是一个全表映射的框架,配置Java对象与数据库表的对应关系,多表关联关系配置复杂

      2)SQL优化和移植性

      • Hibernate 对SQL语句封装,提供了日志、缓存、级联(级联比 MyBatis 强大)等特性,此外还提供 HQL(Hibernate Query Language)操作数据库,数据库无关性支持好,但会多消耗性能。如果项目需要支持多种数据库,代码开发量少,但SQL语句优化困难。
      • MyBatis 需要手动编写 SQL,支持动态 SQL、处理列表、动态生成表名、支持存储过程。开发工作量相对大些。直接使用SQL语句操作数据库,不支持数据库无关性,但sql语句优化容易。

      3)MyBatis和Hibernate的适用场景不同

      Mybatis vs Hibernate

      • Hibernate 是标准的ORM框架,SQL编写量较少,但不够灵活,适合于需求相对稳定,中小型的软件项目,比如:办公自动化系统
      • MyBatis 是半ORM框架,需要编写较多SQL,但是比较灵活,适合于需求变化频繁,快速迭代的项目,比如:电商网站

      3. MyBatis使用过程?生命周期?

      MyBatis基本使用的过程大概可以分为这么几步:

      Mybatis基本使用步骤

      • 1)创建SqlSessionFactory

      可以从配置或者直接编码来创建SqlSessionFactory

      String resource = "org/mybatis/example/mybatis-config.xml";
       InputStream inputStream = Resources.getResourceAsStream(resource);
       SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
       
      • 2)通过SqlSessionFactory创建SqlSession

      SqlSession(会话)可以理解为程序和数据库之间的桥梁

      SqlSession session = sqlSessionFactory.openSession();
      @@ -405,6 +405,6 @@ var8 = new</plugin>
       </plugins>    
       

      20. MyBatis是如何进行分页的?分页插件的原理是什么?

      MyBatis是如何分页的?

      MyBatis使用RowBounds对象进行分页,它是针对ResultSet结果集执行的内存分页,而非物理分页。可以在sql内直接书写带有物理分页的参数来完成物理分页功能,也可以使用分页插件来完成物理分页。

      分页插件的原理是什么?

      • 分页插件的基本原理是使用Mybatis提供的插件接口,实现自定义插件,拦截Executor的query方法
      • 在执行查询的时候,拦截待执行的sql,然后重写sql,根据dialect方言,添加对应的物理分页语句和物理分页参数。
      • 举例:select * from student,拦截sql后重写为:select t.* from (select * from student) t limit 0, 10

      可以看一下一个大概的MyBatis通用分页拦截器:

      Mybatis-通用分页拦截器


      图文详解 20 道MyBatis面试高频题,这次吊打面试官,我觉得稳了(手动 dog)。整理:沉默王二,戳转载链接open in new window,作者:三分恶,戳原文链接open in new window

      - + diff --git a/dist/sidebar/sanfene/nixi.html b/dist/sidebar/sanfene/nixi.html index 36b0f698..604367af 100644 --- a/dist/sidebar/sanfene/nixi.html +++ b/dist/sidebar/sanfene/nixi.html @@ -39,10 +39,10 @@ } - + - - + + diff --git a/dist/sidebar/sanfene/redis.html b/dist/sidebar/sanfene/redis.html index 434702d5..faa15523 100644 --- a/dist/sidebar/sanfene/redis.html +++ b/dist/sidebar/sanfene/redis.html @@ -39,10 +39,10 @@ } - + -

      面渣逆袭(Redis)必看👍

      沉默王二2022年5月9日
      • 面渣逆袭
      • Redis
      大约 71 分钟

      面渣逆袭(Redis)必看👍

      图文详解 53 道Redis面试高频题,这次吊打面试官,我觉得稳了(手动 dog)。整理:沉默王二,戳转载链接open in new window,作者:三分恶,戳原文链接open in new window

      基础

      1.说说什么是Redis?

      Redis图标

      Redis是一种基于键值对(key-value)的NoSQL数据库。

      比一般键值对数据库强大的地方,Redis中的value支持string(字符串)、hash(哈希)、 list(列表)、set(集合)、zset(有序集合)、Bitmaps(位图)、 HyperLogLog、GEO(地理信息定位)等多种数据结构,因此 Redis可以满足很多的应用场景。

      而且因为Redis会将所有数据都存放在内存中,所以它的读写性能非常出色。

      不仅如此,Redis还可以将内存的数据利用快照和日志的形式保存到硬盘上,这样在发生类似断电或者机器故障的时候,内存中的数据不会“丢失”。

      除了上述功能以外,Redis还提供了键过期、发布订阅、事务、流水线、Lua脚本等附加功能。

      总之,Redis是一款强大的性能利器。

      2.Redis可以用来干什么?

      Redis

      1. 缓存

        这是Redis应用最广泛地方,基本所有的Web应用都会使用Redis作为缓存,来降低数据源压力,提高响应速度。 Redis缓存

      2. 计数器 Redis天然支持计数功能,而且计数性能非常好,可以用来记录浏览量、点赞量等等。

      3. 排行榜 Redis提供了列表和有序集合数据结构,合理地使用这些数据结构可以很方便地构建各种排行榜系统。

      4. 社交网络 赞/踩、粉丝、共同好友/喜好、推送、下拉刷新。

      5. 消息队列 Redis提供了发布订阅功能和阻塞队列的功能,可以满足一般消息队列功能。

      6. 分布式锁 分布式环境下,利用Redis实现分布式锁,也是Redis常见的应用。

      Redis的应用一般会结合项目去问,以一个电商项目的用户服务为例:

      • Token存储:用户登录成功之后,使用Redis存储Token
      • 登录失败次数计数:使用Redis计数,登录失败超过一定次数,锁定账号
      • 地址缓存:对省市区数据的缓存
      • 分布式锁:分布式环境下登录、注册等操作加分布式锁
      • ……

      3.Redis 有哪些数据结构?

      Redis基本数据结构 Redis有五种基本数据结构。

      string

      字符串最基础的数据结构。字符串类型的值实际可以是字符串(简单的字符串、复杂的字符串(例如JSON、XML))、数字 (整数、浮点数),甚至是二进制(图片、音频、视频),但是值最大不能超过512MB。

      字符串主要有以下几个典型使用场景:

      • 缓存功能
      • 计数
      • 共享Session
      • 限速

      hash

      哈希类型是指键值本身又是一个键值对结构。

      哈希主要有以下典型应用场景:

      • 缓存用户信息
      • 缓存对象

      list

      列表(list)类型是用来存储多个有序的字符串。列表是一种比较灵活的数据结构,它可以充当栈和队列的角色

      列表主要有以下几种使用场景:

      • 消息队列
      • 文章列表

      set

      集合(set)类型也是用来保存多个的字符串元素,但和列表类型不一 样的是,集合中不允许有重复元素,并且集合中的元素是无序的。

      集合主要有如下使用场景:

      • 标签(tag)
      • 共同关注

      sorted set

      有序集合中的元素可以排序。但是它和列表使用索引下标作为排序依据不同的是,它给每个元素设置一个权重(score)作为排序的依据。

      有序集合主要应用场景:

      • 用户点赞统计
      • 用户排序

      4.Redis为什么快呢?

      Redis的速度⾮常的快,单机的Redis就可以⽀撑每秒十几万的并发,相对于MySQL来说,性能是MySQL的⼏⼗倍。速度快的原因主要有⼏点:

      1. 完全基于内存操作
      2. 使⽤单线程,避免了线程切换和竞态产生的消耗
      3. 基于⾮阻塞的IO多路复⽤机制
      4. C语⾔实现,优化过的数据结构,基于⼏种基础的数据结构,redis做了⼤量的优化,性能极⾼ Redis使用IO多路复用和自身事件模型

      5.能说一下I/O多路复用吗?

      引用知乎上一个高赞的回答来解释什么是I/O多路复用。假设你是一个老师,让30个学生解答一道题目,然后检查学生做的是否正确,你有下面几个选择:

      • 第一种选择:按顺序逐个检查,先检查A,然后是B,之后是C、D。。。这中间如果有一个学生卡住,全班都会被耽误。这种模式就好比,你用循环挨个处理socket,根本不具有并发能力。

      • 第二种选择:你创建30个分身,每个分身检查一个学生的答案是否正确。 这种类似于为每一个用户创建一个进程或者- 线程处理连接。

      • 第三种选择,你站在讲台上等,谁解答完谁举手。这时C、D举手,表示他们解答问题完毕,你下去依次检查C、D的答案,然后继续回到讲台上等。此时E、A又举手,然后去处理E和A。

      第一种就是阻塞IO模型,第三种就是I/O复用模型。

      多路复用模型

      Linux系统有三种方式实现IO多路复用:select、poll和epoll。

      例如epoll方式是将用户socket对应的fd注册进epoll,然后epoll帮你监听哪些socket上有消息到达,这样就避免了大量的无用操作。此时的socket应该采用非阻塞模式。

      这样,整个过程只在进行select、poll、epoll这些调用的时候才会阻塞,收发客户消息是不会阻塞的,整个进程或者线程就被充分利用起来,这就是事件驱动,所谓的reactor模式。

      6. Redis为什么早期选择单线程?

      官方解释:https://redis.io/topics/faq

      官方单线程解释 官方FAQ表示,因为Redis是基于内存的操作,CPU成为Redis的瓶颈的情况很少见,Redis的瓶颈最有可能是内存的大小或者网络限制。

      如果想要最大程度利用CPU,可以在一台机器上启动多个Redis实例。

      PS:网上有这样的回答,吐槽官方的解释有些敷衍,其实就是历史原因,开发者嫌多线程麻烦,后来这个CPU的利用问题就被抛给了使用者。

      同时FAQ里还提到了, Redis 4.0 之后开始变成多线程,除了主线程外,它也有后台线程在处理一些较为缓慢的操作,例如清理脏数据、无用连接的释放、大 Key 的删除等等。

      7.Redis6.0使用多线程是怎么回事?

      Redis不是说用单线程的吗?怎么6.0成了多线程的?

      Redis6.0的多线程是用多线程来处理数据的读写和协议解析,但是Redis执行命令还是单线程的。

      Redis6.0多线程 这样做的⽬的是因为Redis的性能瓶颈在于⽹络IO⽽⾮CPU,使⽤多线程能提升IO读写的效率,从⽽整体提⾼Redis的性能。

      持久化

      8.Redis持久化⽅式有哪些?有什么区别?

      Redis持久化⽅案分为RDB和AOF两种。 Redis持久化两种方式

      RDB

      RDB持久化是把当前进程数据生成快照保存到硬盘的过程,触发RDB持久化过程分为手动触发和自动触发。

      RDB⽂件是⼀个压缩的⼆进制⽂件,通过它可以还原某个时刻数据库的状态。由于RDB⽂件是保存在硬盘上的,所以即使Redis崩溃或者退出,只要RDB⽂件存在,就可以⽤它来恢复还原数据库的状态。

      手动触发分别对应save和bgsave命令: save和bgsave

      • save命令:阻塞当前Redis服务器,直到RDB过程完成为止,对于内存比较大的实例会造成长时间阻塞,线上环境不建议使用。

      • bgsave命令:Redis进程执行fork操作创建子进程,RDB持久化过程由子进程负责,完成后自动结束。阻塞只发生在fork阶段,一般时间很短。

      以下场景会自动触发RDB持久化:

      • 使用save相关配置,如“save m n”。表示m秒内数据集存在n次修改时,自动触发bgsave。
      • 如果从节点执行全量复制操作,主节点自动执行bgsave生成RDB文件并发送给从节点
      • 执行debug reload命令重新加载Redis时,也会自动触发save操作
      • 默认情况下执行shutdown命令时,如果没有开启AOF持久化功能则自动执行bgsave。

      AOF

      AOF(append only file)持久化:以独立日志的方式记录每次写命令, 重启时再重新执行AOF文件中的命令达到恢复数据的目的。AOF的主要作用是解决了数据持久化的实时性,目前已经是Redis持久化的主流方式。

      AOF的工作流程操作:命令写入 (append)、文件同步(sync)、文件重写(rewrite)、重启加载 (load) AOF工作流程流程如下:

      1)所有的写入命令会追加到aof_buf(缓冲区)中。

      2)AOF缓冲区根据对应的策略向硬盘做同步操作。

      3)随着AOF文件越来越大,需要定期对AOF文件进行重写,达到压缩 的目的。

      4)当Redis服务器重启时,可以加载AOF文件进行数据恢复。

      9.RDB 和 AOF 各自有什么优缺点?

      RDB | 优点

      1. 只有一个紧凑的二进制文件 dump.rdb,非常适合备份、全量复制的场景。
      2. 容灾性好,可以把RDB文件拷贝道远程机器或者文件系统张,用于容灾恢复。
      3. 恢复速度快,RDB恢复数据的速度远远快于AOF的方式

      RDB | 缺点

      1. 实时性低,RDB 是间隔一段时间进行持久化,没法做到实时持久化/秒级持久化。如果在这一间隔事件发生故障,数据会丢失。
      2. 存在兼容问题,Redis演进过程存在多个格式的RDB版本,存在老版本Redis无法兼容新版本RDB的问题。

      AOF | 优点

      1. 实时性好,aof 持久化可以配置 appendfsync 属性,有 always,每进行一次命令操作就记录到 aof 文件中一次。
      2. 通过 append 模式写文件,即使中途服务器宕机,可以通过 redis-check-aof 工具解决数据一致性问题。

      AOF | 缺点

      1. AOF 文件比 RDB 文件大,且 恢复速度慢
      2. 数据集大 的时候,比 RDB 启动效率低

      10.RDB和AOF如何选择?

      • 一般来说, 如果想达到足以媲美数据库的 数据安全性,应该 同时使用两种持久化功能。在这种情况下,当 Redis 重启的时候会优先载入 AOF 文件来恢复原始的数据,因为在通常情况下 AOF 文件保存的数据集要比 RDB 文件保存的数据集要完整。
      • 如果 可以接受数分钟以内的数据丢失,那么可以 只使用 RDB 持久化
      • 有很多用户都只使用 AOF 持久化,但并不推荐这种方式,因为定时生成 RDB 快照(snapshot)非常便于进行数据备份, 并且 RDB 恢复数据集的速度也要比 AOF 恢复的速度要快,除此之外,使用 RDB 还可以避免 AOF 程序的 bug。
      • 如果只需要数据在服务器运行的时候存在,也可以不使用任何持久化方式。

      11.Redis的数据恢复?

      当Redis发生了故障,可以从RDB或者AOF中恢复数据。

      恢复的过程也很简单,把RDB或者AOF文件拷贝到Redis的数据目录下,如果使用AOF恢复,配置文件开启AOF,然后启动redis-server即可。 Redis启动加载数据

      Redis 启动时加载数据的流程:

      1. AOF持久化开启且存在AOF文件时,优先加载AOF文件。
      2. AOF关闭或者AOF文件不存在时,加载RDB文件。
      3. 加载AOF/RDB文件成功后,Redis启动成功。
      4. AOF/RDB文件存在错误时,Redis启动失败并打印错误信息。

      12.Redis 4.0 的混合持久化了解吗?

      重启 Redis 时,我们很少使用 RDB 来恢复内存状态,因为会丢失大量数据。我们通常使用 AOF 日志重放,但是重放 AOF 日志性能相对 RDB 来说要慢很多,这样在 Redis 实例很大的情况下,启动需要花费很长的时间。

      Redis 4.0 为了解决这个问题,带来了一个新的持久化选项——混合持久化。将 rdb 文件的内容和增量的 AOF 日志文件存在一起。这里的 AOF 日志不再是全量的日志,而是 自持久化开始到持久化结束 的这段时间发生的增量 AOF 日志,通常这部分 AOF 日志很小: 混合持久化

      于是在 Redis 重启的时候,可以先加载 rdb 的内容,然后再重放增量 AOF 日志就可以完全替代之前的 AOF 全量文件重放,重启效率因此大幅得到提升。

      高可用

      Redis保证高可用主要有三种方式:主从、哨兵、集群。

      13.主从复制了解吗?

      Redis主从复制简图

      主从复制,是指将一台 Redis 服务器的数据,复制到其他的 Redis 服务器。前者称为 主节点(master),后者称为 从节点(slave)。且数据的复制是 单向 的,只能由主节点到从节点。Redis 主从复制支持 主从同步从从同步 两种,后者是 Redis 后续版本新增的功能,以减轻主节点的同步负担。

      主从复制主要的作用?

      • 数据冗余: 主从复制实现了数据的热备份,是持久化之外的一种数据冗余方式。
      • 故障恢复: 当主节点出现问题时,可以由从节点提供服务,实现快速的故障恢复 (实际上是一种服务的冗余)
      • 负载均衡: 在主从复制的基础上,配合读写分离,可以由主节点提供写服务,由从节点提供读服务 (即写 Redis 数据时应用连接主节点,读 Redis 数据时应用连接从节点),分担服务器负载。尤其是在写少读多的场景下,通过多个从节点分担读负载,可以大大提高 Redis 服务器的并发量。
      • 高可用基石: 除了上述作用以外,主从复制还是哨兵和集群能够实施的 基础,因此说主从复制是 Redis 高可用的基础。

      14.Redis主从有几种常见的拓扑结构?

      Redis的复制拓扑结构可以支持单层或多层复制关系,根据拓扑复杂性可以分为以下三种:一主一从、一主多从、树状主从结构。

      1.一主一从结构

      一主一从结构是最简单的复制拓扑结构,用于主节点出现宕机时从节点提供故障转移支持。 一主一从结构 2.一主多从结构

      一主多从结构(又称为星形拓扑结构)使得应用端可以利用多个从节点实现读写分离(见图6-5)。对于读占比较大的场景,可以把读命令发送到从节点来分担主节点压力。 一主多从结构 3.树状主从结构

      树状主从结构(又称为树状拓扑结构)使得从节点不但可以复制主节点数据,同时可以作为其他从节点的主节点继续向下层复制。通过引入复制中间层,可以有效降低主节点负载和需要传送给从节点的数据量。 树状主从结构

      15.Redis的主从复制原理了解吗?

      Redis主从复制的工作流程大概可以分为如下几步: Redis主从复制工作流程

      1. 保存主节点(master)信息 这一步只是保存主节点信息,保存主节点的ip和port。
      2. 主从建立连接 从节点(slave)发现新的主节点后,会尝试和主节点建立网络连接。
      3. 发送ping命令 连接建立成功后从节点发送ping请求进行首次通信,主要是检测主从之间网络套接字是否可用、主节点当前是否可接受处理命令。
      4. 权限验证 如果主节点要求密码验证,从节点必须正确的密码才能通过验证。
      5. 同步数据集 主从复制连接正常通信后,主节点会把持有的数据全部发送给从节点。
      6. 命令持续复制 接下来主节点会持续地把写命令发送给从节点,保证主从数据一致性。

      16.说说主从数据同步的方式?

      Redis在2.8及以上版本使用psync命令完成主从数据同步,同步过程分为:全量复制和部分复制。

      主从数据同步方式

      全量复制 一般用于初次复制场景,Redis早期支持的复制功能只有全量复制,它会把主节点全部数据一次性发送给从节点,当数据量较大时,会对主从节点和网络造成很大的开销。

      全量复制的完整运行流程如下: 全量复制

      1. 发送psync命令进行数据同步,由于是第一次进行复制,从节点没有复制偏移量和主节点的运行ID,所以发送psync-1。
      2. 主节点根据psync-1解析出当前为全量复制,回复+FULLRESYNC响应。
      3. 从节点接收主节点的响应数据保存运行ID和偏移量offset
      4. 主节点执行bgsave保存RDB文件到本地
      5. 主节点发送RDB文件给从节点,从节点把接收的RDB文件保存在本地并直接作为从节点的数据文件
      6. 对于从节点开始接收RDB快照到接收完成期间,主节点仍然响应读写命令,因此主节点会把这期间写命令数据保存在复制客户端缓冲区内,当从节点加载完RDB文件后,主节点再把缓冲区内的数据发送给从节点,保证主从之间数据一致性。
      7. 从节点接收完主节点传送来的全部数据后会清空自身旧数据
      8. 从节点清空数据后开始加载RDB文件
      9. 从节点成功加载完RDB后,如果当前节点开启了AOF持久化功能, 它会立刻做bgrewriteaof操作,为了保证全量复制后AOF持久化文件立刻可用。

      部分复制 部分复制主要是Redis针对全量复制的过高开销做出的一种优化措施, 使用psync{runId}{offset}命令实现。当从节点(slave)正在复制主节点 (master)时,如果出现网络闪断或者命令丢失等异常情况时,从节点会向 主节点要求补发丢失的命令数据,如果主节点的复制积压缓冲区内存在这部分数据则直接发送给从节点,这样就可以保持主从节点复制的一致性。 部分复制

      1. 当主从节点之间网络出现中断时,如果超过repl-timeout时间,主节点会认为从节点故障并中断复制连接
      2. 主从连接中断期间主节点依然响应命令,但因复制连接中断命令无法发送给从节点,不过主节点内部存在的复制积压缓冲区,依然可以保存最近一段时间的写命令数据,默认最大缓存1MB。
      3. 当主从节点网络恢复后,从节点会再次连上主节点
      4. 当主从连接恢复后,由于从节点之前保存了自身已复制的偏移量和主节点的运行ID。因此会把它们当作psync参数发送给主节点,要求进行部分复制操作。
      5. 主节点接到psync命令后首先核对参数runId是否与自身一致,如果一 致,说明之前复制的是当前主节点;之后根据参数offset在自身复制积压缓冲区查找,如果偏移量之后的数据存在缓冲区中,则对从节点发送+CONTINUE响应,表示可以进行部分复制。
      6. 主节点根据偏移量把复制积压缓冲区里的数据发送给从节点,保证主从复制进入正常状态。

      17.主从复制存在哪些问题呢?

      主从复制虽好,但也存在一些问题:

      • 一旦主节点出现故障,需要手动将一个从节点晋升为主节点,同时需要修改应用方的主节点地址,还需要命令其他从节点去复制新的主节点,整个过程都需要人工干预。
      • 主节点的写能力受到单机的限制。
      • 主节点的存储能力受到单机的限制。

      第一个问题是Redis的高可用问题,第二、三个问题属于Redis的分布式问题。

      18.Redis Sentinel(哨兵)了解吗?

      主从复制存在一个问题,没法完成自动故障转移。所以我们需要一个方案来完成自动故障转移,它就是Redis Sentinel(哨兵)。

      Redis Sentinel

      Redis Sentinel ,它由两部分组成,哨兵节点和数据节点:

      • 哨兵节点: 哨兵系统由一个或多个哨兵节点组成,哨兵节点是特殊的 Redis 节点,不存储数据,对数据节点进行监控。
      • 数据节点: 主节点和从节点都是数据节点;

      在复制的基础上,哨兵实现了 自动化的故障恢复 功能,下面是官方对于哨兵功能的描述:

      • 监控(Monitoring): 哨兵会不断地检查主节点和从节点是否运作正常。
      • 自动故障转移(Automatic failover):主节点 不能正常工作时,哨兵会开始 自动故障转移操作,它会将失效主节点的其中一个 从节点升级为新的主节点,并让其他从节点改为复制新的主节点。
      • 配置提供者(Configuration provider): 客户端在初始化时,通过连接哨兵来获得当前 Redis 服务的主节点地址。
      • 通知(Notification): 哨兵可以将故障转移的结果发送给客户端。

      其中,监控和自动故障转移功能,使得哨兵可以及时发现主节点故障并完成转移。而配置提供者和通知功能,则需要在与客户端的交互中才能体现。

      19.Redis Sentinel(哨兵)实现原理知道吗?

      哨兵模式是通过哨兵节点完成对数据节点的监控、下线、故障转移。 Redis Sentinel工作流程

      • 定时监控三个定时任务Redis Sentinel通过三个定时监控任务完成对各个节点发现和监控:
        1. 每隔10秒,每个Sentinel节点会向主节点和从节点发送info命令获取最新的拓扑结构
        2. 每隔2秒,每个Sentinel节点会向Redis数据节点的__sentinel__:hello 频道上发送该Sentinel节点对于主节点的判断以及当前Sentinel节点的信息
        3. 每隔1秒,每个Sentinel节点会向主节点、从节点、其余Sentinel节点发送一条ping命令做一次心跳检测,来确认这些节点当前是否可达
      • 主观下线和客观下线 主观下线就是哨兵节点认为某个节点有问题,客观下线就是超过一定数量的哨兵节点认为主节点有问题。 主观下线和客观下线
      1. 主观下线 每个Sentinel节点会每隔1秒对主节点、从节点、其他Sentinel节点发送ping命令做心跳检测,当这些节点超过 down-after-milliseconds没有进行有效回复,Sentinel节点就会对该节点做失败判定,这个行为叫做主观下线。

      2. 客观下线 当Sentinel主观下线的节点是主节点时,该Sentinel节点会通过sentinel is- master-down-by-addr命令向其他Sentinel节点询问对主节点的判断,当超过 <quorum>个数,Sentinel节点认为主节点确实有问题,这时该Sentinel节点会做出客观下线的决定

      • 领导者Sentinel节点选举 Sentinel节点之间会做一个领导者选举的工作,选出一个Sentinel节点作为领导者进行故障转移的工作。Redis使用了Raft算法实现领导者选举。

      • 故障转移

        领导者选举出的Sentinel节点负责故障转移,过程如下: 故障转移

        1. 在从节点列表中选出一个节点作为新的主节点,这一步是相对复杂一些的一步
        2. Sentinel领导者节点会对第一步选出来的从节点执行slaveof no one命令让其成为主节点
        3. Sentinel领导者节点会向剩余的从节点发送命令,让它们成为新主节点的从节点
        4. Sentinel节点集合会将原来的主节点更新为从节点,并保持着对其关注,当其恢复后命令它去复制新的主节点

      20.领导者Sentinel节点选举了解吗?

      Redis使用了Raft算法实 现领导者选举,大致流程如下: 领导者Sentinel节点选举

      1. 每个在线的Sentinel节点都有资格成为领导者,当它确认主节点主观 下线时候,会向其他Sentinel节点发送sentinel is-master-down-by-addr命令, 要求将自己设置为领导者。
      2. 收到命令的Sentinel节点,如果没有同意过其他Sentinel节点的sentinel is-master-down-by-addr命令,将同意该请求,否则拒绝。
      3. 如果该Sentinel节点发现自己的票数已经大于等于max(quorum, num(sentinels)/2+1),那么它将成为领导者。
      4. 如果此过程没有选举出领导者,将进入下一次选举。

      21.新的主节点是怎样被挑选出来的?

      选出新的主节点,大概分为这么几步: 新的主节点

      1. 过滤:“不健康”(主观下线、断线)、5秒内没有回复过Sentinel节 点ping响应、与主节点失联超过down-after-milliseconds*10秒。
      2. 选择slave-priority(从节点优先级)最高的从节点列表,如果存在则返回,不存在则继续。
      3. 选择复制偏移量最大的从节点(复制的最完整),如果存在则返 回,不存在则继续。
      4. 选择runid最小的从节点。

      22.Redis 集群了解吗?

      前面说到了主从存在高可用和分布式的问题,哨兵解决了高可用的问题,而集群就是终极方案,一举解决高可用和分布式问题。 Redis 集群示意图

      1. 数据分区: 数据分区 (或称数据分片) 是集群最核心的功能。集群将数据分散到多个节点,一方面 突破了 Redis 单机内存大小的限制,存储容量大大增加另一方面 每个主节点都可以对外提供读服务和写服务,大大提高了集群的响应能力

      2. 高可用: 集群支持主从复制和主节点的 自动故障转移 (与哨兵类似),当任一节点发生故障时,集群仍然可以对外提供服务。

      23.集群中数据如何分区?

      分布式的存储中,要把数据集按照分区规则映射到多个节点,常见的数据分区规则三种: 分布式数据分区

      方案一:节点取余分区

      节点取余分区,非常好理解,使用特定的数据,比如Redis的键,或者用户ID之类,对响应的hash值取余:hash(key)%N,来确定数据映射到哪一个节点上。

      不过该方案最大的问题是,当节点数量变化时,如扩容或收缩节点,数据节点映射关 系需要重新计算,会导致数据的重新迁移。

      节点取余分区

      方案二:一致性哈希分区

      将整个 Hash 值空间组织成一个虚拟的圆环,然后将缓存节点的 IP 地址或者主机名做 Hash 取值后,放置在这个圆环上。当我们需要确定某一个 Key 需 要存取到哪个节点上的时候,先对这个 Key 做同样的 Hash 取值,确定在环上的位置,然后按照顺时针方向在环上“行走”,遇到的第一个缓存节点就是要访问的节点。

      比如说下面 这张图里面,Key 1 和 Key 2 会落入到 Node 1 中,Key 3、Key 4 会落入到 Node 2 中,Key 5 落入到 Node 3 中,Key 6 落入到 Node 4 中。 一致性哈希分区

      这种方式相比节点取余最大的好处在于加入和删除节点只影响哈希环中 相邻的节点,对其他节点无影响。

      但它还是存在问题:

      • 缓存节点在圆环上分布不平均,会造成部分缓存节点的压力较大
      • 当某个节点故障时,这个节点所要承担的所有访问都会被顺移到另一个节点上,会对后面这个节点造成力。
      方案三:虚拟槽分区

      这个方案 一致性哈希分区的基础上,引入了 虚拟节点 的概念。Redis 集群使用的便是该方案,其中的虚拟节点称为 槽(slot)。槽是介于数据和实际节点之间的虚拟概念,每个实际节点包含一定数量的槽,每个槽包含哈希值在一定范围内的数据。 虚拟槽分配

      在使用了槽的一致性哈希分区中,槽是数据管理和迁移的基本单位。槽解耦了数据和实际节点 之间的关系,增加或删除节点对系统的影响很小。仍以上图为例,系统中有 4 个实际节点,假设为其分配 16 个槽(0-15);

      • 槽 0-3 位于 node1;4-7 位于 node2;以此类推....

      如果此时删除 node2,只需要将槽 4-7 重新分配即可,例如槽 4-5 分配给 node1,槽 6 分配给 node3,槽 7 分配给 node4,数据在其他节点的分布仍然较为均衡。

      24.能说说Redis集群的原理吗?

      Redis集群通过数据分区来实现数据的分布式存储,通过自动故障转移实现高可用。

      集群创建

      数据分区是在集群创建的时候完成的。 集群创建

      设置节点 Redis集群一般由多个节点组成,节点数量至少为6个才能保证组成完整高可用的集群。每个节点需要开启配置cluster-enabled yes,让Redis运行在集群模式下。 节点和握手节点握手 节点握手是指一批运行在集群模式下的节点通过Gossip协议彼此通信, 达到感知对方的过程。节点握手是集群彼此通信的第一步,由客户端发起命 令:cluster meet{ip}{port}。完成节点握手之后,一个个的Redis节点就组成了一个多节点的集群。

      分配槽(slot) Redis集群把所有的数据映射到16384个槽中。每个节点对应若干个槽,只有当节点分配了槽,才能响应和这些槽关联的键命令。通过 cluster addslots命令为节点分配槽。

      分配槽

      故障转移

      Redis集群的故障转移和哨兵的故障转移类似,但是Redis集群中所有的节点都要承担状态维护的任务。

      故障发现 Redis集群内节点通过ping/pong消息实现节点通信,集群中每个节点都会定期向其他节点发送ping消息,接收节点回复pong 消息作为响应。如果在cluster-node-timeout时间内通信一直失败,则发送节 点会认为接收节点存在故障,把接收节点标记为主观下线(pfail)状态。 主观下线 当某个节点判断另一个节点主观下线后,相应的节点状态会跟随消息在集群内传播。通过Gossip消息传播,集群内节点不断收集到故障节点的下线报告。当 半数以上持有槽的主节点都标记某个节点是主观下线时。触发客观下线流程。 主观下线和客观下线

      故障恢复

      故障节点变为客观下线后,如果下线节点是持有槽的主节点则需要在它 的从节点中选出一个替换它,从而保证集群的高可用。

      故障恢复流程

      1. 资格检查 每个从节点都要检查最后与主节点断线时间,判断是否有资格替换故障 的主节点。
      2. 准备选举时间 当从节点符合故障转移资格后,更新触发故障选举的时间,只有到达该 时间后才能执行后续流程。
      3. 发起选举 当从节点定时任务检测到达故障选举时间(failover_auth_time)到达后,发起选举流程。
      4. 选举投票 持有槽的主节点处理故障选举消息。投票过程其实是一个领导者选举的过程,如集群内有N个持有槽的主节 点代表有N张选票。由于在每个配置纪元内持有槽的主节点只能投票给一个 从节点,因此只能有一个从节点获得N/2+1的选票,保证能够找出唯一的从节点。 选举投票
      5. 替换主节点 当从节点收集到足够的选票之后,触发替换主节点操作。

      部署Redis集群至少需要几个物理节点?

      在投票选举的环节,故障主节点也算在投票数内,假设集群内节点规模是3主3从,其中有2 个主节点部署在一台机器上,当这台机器宕机时,由于从节点无法收集到 3/2+1个主节点选票将导致故障转移失败。这个问题也适用于故障发现环节。因此部署集群时所有主节点最少需要部署在3台物理机上才能避免单点问题。

      25.说说集群的伸缩?

      Redis集群提供了灵活的节点扩容和收缩方案,可以在不影响集群对外服务的情况下,为集群添加节点进行扩容也可以下线部分节点进行缩容。 集群的伸缩其实,集群扩容和缩容的关键点,就在于槽和节点的对应关系,扩容和缩容就是将一部分数据迁移给新节点。

      例如下面一个集群,每个节点对应若干个槽,每个槽对应一定的数据,如果希望加入1个节点希望实现集群扩容时,需要通过相关命令把一部分槽和内容迁移给新节点。 扩容实例缩容也是类似,先把槽和数据迁移到其它节点,再把对应的节点下线。

      缓存设计

      26.什么是缓存击穿、缓存穿透、缓存雪崩?

      PS:这是多年黄历的老八股了,一定要理解清楚。

      缓存击穿

      一个并发访问量比较大的key在某个时间过期,导致所有的请求直接打在DB上。

      缓存击穿 解决⽅案:

      1. 加锁更新,⽐如请求查询A,发现缓存中没有,对A这个key加锁,同时去数据库查询数据,写⼊缓存,再返回给⽤户,这样后⾯的请求就可以从缓存中拿到数据了。 加锁更新

      2. 将过期时间组合写在value中,通过异步的⽅式不断的刷新过期时间,防⽌此类现象。

      缓存穿透

      缓存穿透指的查询缓存和数据库中都不存在的数据,这样每次请求直接打到数据库,就好像缓存不存在一样。

      缓存穿透 缓存穿透将导致不存在的数据每次请求都要到存储层去查询,失去了缓存保护后端存储的意义。

      缓存穿透可能会使后端存储负载加大,如果发现大量存储层空命中,可能就是出现了缓存穿透问题。

      缓存穿透可能有两种原因:

      1. 自身业务代码问题
      2. 恶意攻击,爬虫造成空命中

      它主要有两种解决办法:

      • 缓存空值/默认值

      一种方式是在数据库不命中之后,把一个空对象或者默认值保存到缓存,之后再访问这个数据,就会从缓存中获取,这样就保护了数据库。

      缓存空值/默认值

      缓存空值有两大问题:

      1. 空值做了缓存,意味着缓存层中存了更多的键,需要更多的内存空间(如果是攻击,问题更严重),比较有效的方法是针对这类数据设置一个较短的过期时间,让其自动剔除。

      2. 缓存层和存储层的数据会有一段时间窗口的不一致,可能会对业务有一定影响。 例如过期时间设置为5分钟,如果此时存储层添加了这个数据,那此段时间就会出现缓存层和存储层数据的不一致。 这时候可以利用消息队列或者其它异步方式清理缓存中的空对象。

      • 布隆过滤器 除了缓存空对象,我们还可以在存储和缓存之前,加一个布隆过滤器,做一层过滤。

      布隆过滤器里会保存数据是否存在,如果判断数据不不能再,就不会访问存储。 布隆过滤器 两种解决方案的对比: 缓存空对象核布隆过滤器方案对比

      缓存雪崩

      某⼀时刻发⽣⼤规模的缓存失效的情况,例如缓存服务宕机、大量key在同一时间过期,这样的后果就是⼤量的请求进来直接打到DB上,可能导致整个系统的崩溃,称为雪崩。

      缓存雪崩 缓存雪崩是三大缓存问题里最严重的一种,我们来看看怎么预防和处理。

      • 提高缓存可用性
      1. 集群部署:通过集群来提升缓存的可用性,可以利用Redis本身的Redis Cluster或者第三方集群方案如Codis等。
      2. 多级缓存:设置多级缓存,第一级缓存失效的基础上,访问二级缓存,每一级缓存的失效时间都不同。
      • 过期时间
      1. 均匀过期:为了避免大量的缓存在同一时间过期,可以把不同的 key 过期时间随机生成,避免过期时间太过集中。
      2. 热点数据永不过期。
      • 熔断降级
      1. 服务熔断:当缓存服务器宕机或超时响应时,为了防止整个系统出现雪崩,暂时停止业务服务访问缓存系统。
      2. 服务降级:当出现大量缓存失效,而且处在高并发高负荷的情况下,在业务系统内部暂时舍弃对一些非核心的接口和数据的请求,而直接返回一个提前准备好的 fallback(退路)错误处理信息。

      27.能说说布隆过滤器吗?

      布隆过滤器,它是一个连续的数据结构,每个存储位存储都是一个bit,即0或者1, 来标识数据是否存在。

      存储数据的时时候,使用K个不同的哈希函数将这个变量映射为bit列表的的K个点,把它们置为1。

      布隆过滤器我们判断缓存key是否存在,同样,K个哈希函数,映射到bit列表上的K个点,判断是不是1:

      • 如果全不是1,那么key不存在;
      • 如果都是1,也只是表示key可能存在。

      布隆过滤器也有一些缺点:

      1. 它在判断元素是否在集合中时是有一定错误几率,因为哈希算法有一定的碰撞的概率。
      2. 不支持删除元素。

      28.如何保证缓存和数据库数据的⼀致性?

      根据CAP理论,在保证可用性和分区容错性的前提下,无法保证一致性,所以缓存和数据库的绝对一致是不可能实现的,只能尽可能保存缓存和数据库的最终一致性。

      选择合适的缓存更新策略

      1. 删除缓存而不是更新缓存

      当一个线程对缓存的key进行写操作的时候,如果其它线程进来读数据库的时候,读到的就是脏数据,产生了数据不一致问题。

      相比较而言,删除缓存的速度比更新缓存的速度快很多,所用时间相对也少很多,读脏数据的概率也小很多。 删除缓存和更新缓存

      1. 先更数据,后删缓存 先更数据库还是先删缓存?这是一个问题。

      更新数据,耗时可能在删除缓存的百倍以上。在缓存中不存在对应的key,数据库又没有完成更新的时候,如果有线程进来读取数据,并写入到缓存,那么在更新成功之后,这个key就是一个脏数据。

      毫无疑问,先删缓存,再更数据库,缓存中key不存在的时间的时间更长,有更大的概率会产生脏数据。

      先更数据库还是先删缓存目前最流行的缓存读写策略cache-aside-pattern就是采用先更数据库,再删缓存的方式。

      缓存不一致处理

      如果不是并发特别高,对缓存依赖性很强,其实一定程序的不一致是可以接受的。

      但是如果对一致性要求比较高,那就得想办法保证缓存和数据库中数据一致。

      缓存和数据库数据不一致常见的两种原因:

      • 缓存key删除失败
      • 并发导致写入了脏数据

      缓存一致性

      消息队列保证key被删除 可以引入消息队列,把要删除的key或者删除失败的key丢尽消息队列,利用消息队列的重试机制,重试删除对应的key。

      消息队列保证key被删除这种方案看起来不错,缺点是对业务代码有一定的侵入性。

      数据库订阅+消息队列保证key被删除 可以用一个服务(比如阿里的 canal)去监听数据库的binlog,获取需要操作的数据。

      然后用一个公共的服务获取订阅程序传来的信息,进行缓存删除操作。 数据库订阅+消息队列保证key被删除 这种方式降低了对业务的侵入,但其实整个系统的复杂度是提升的,适合基建完善的大厂。

      延时双删防止脏数据 还有一种情况,是在缓存不存在的时候,写入了脏数据,这种情况在先删缓存,再更数据库的缓存更新策略下发生的比较多,解决方案是延时双删。

      简单说,就是在第一次删除缓存之后,过了一段时间之后,再次删除缓存。

      延时双删

      这种方式的延时时间设置需要仔细考量和测试。

      设置缓存过期时间兜底

      这是一个朴素但是有用的办法,给缓存设置一个合理的过期时间,即使发生了缓存数据不一致的问题,它也不会永远不一致下去,缓存过期的时候,自然又会恢复一致。

      29.如何保证本地缓存和分布式缓存的一致?

      PS:这道题面试很少问,但实际工作中很常见。

      在日常的开发中,我们常常采用两级缓存:本地缓存+分布式缓存。

      所谓本地缓存,就是对应服务器的内存缓存,比如Caffeine,分布式缓存基本就是采用Redis。

      那么问题来了,本地缓存和分布式缓存怎么保持数据一致? 延时双删 Redis缓存,数据库发生更新,直接删除缓存的key即可,因为对于应用系统而言,它是一种中心化的缓存。

      但是本地缓存,它是非中心化的,散落在分布式服务的各个节点上,没法通过客户端的请求删除本地缓存的key,所以得想办法通知集群所有节点,删除对应的本地缓存key。 本地缓存/分布式缓存保持一致

      可以采用消息队列的方式:

      1. 采用Redis本身的Pub/Sub机制,分布式集群的所有节点订阅删除本地缓存频道,删除Redis缓存的节点,同事发布删除本地缓存消息,订阅者们订阅到消息后,删除对应的本地key。 但是Redis的发布订阅不是可靠的,不能保证一定删除成功。
      2. 引入专业的消息队列,比如RocketMQ,保证消息的可靠性,但是增加了系统的复杂度。
      3. 设置适当的过期时间兜底,本地缓存可以设置相对短一些的过期时间。

      30.怎么处理热key?

      什么是热Key? 所谓的热key,就是访问频率比较的key。

      比如,热门新闻事件或商品,这类key通常有大流量的访问,对存储这类信息的 Redis来说,是不小的压力。

      假如Redis集群部署,热key可能会造成整体流量的不均衡,个别节点出现OPS过大的情况,极端情况下热点key甚至会超过 Redis本身能够承受的OPS。

      怎么处理热key?

      热key处理 对热key的处理,最关键的是对热点key的监控,可以从这些端来监控热点key:

      1. 客户端 客户端其实是距离key“最近”的地方,因为Redis命令就是从客户端发出的,例如在客户端设置全局字典(key和调用次数),每次调用Redis命令时,使用这个字典进行记录。

      2. 代理端 像Twemproxy、Codis这些基于代理的Redis分布式架构,所有客户端的请求都是通过代理端完成的,可以在代理端进行收集统计。

      3. Redis服务端 使用monitor命令统计热点key是很多开发和运维人员首先想到,monitor命令可以监控到Redis执行的所有命令。

      只要监控到了热key,对热key的处理就简单了:

      1. 把热key打散到不同的服务器,降低压⼒

      2. 加⼊⼆级缓存,提前加载热key数据到内存中,如果redis宕机,⾛内存查询

      31.缓存预热怎么做呢?

      所谓缓存预热,就是提前把数据库里的数据刷到缓存里,通常有这些方法:

      1、直接写个缓存刷新页面或者接口,上线时手动操作

      2、数据量不大,可以在项目启动的时候自动进行加载

      3、定时任务刷新缓存.

      32.热点key重建?问题?解决?

      开发的时候一般使用“缓存+过期时间”的策略,既可以加速数据读写,又保证数据的定期更新,这种模式基本能够满足绝大部分需求。

      但是有两个问题如果同时出现,可能就会出现比较大的问题:

      • 当前key是一个热点key(例如一个热门的娱乐新闻),并发量非常大。

      • 重建缓存不能在短时间完成,可能是一个复杂计算,例如复杂的 SQL、多次IO、多个依赖等。 在缓存失效的瞬间,有大量线程来重建缓存,造成后端负载加大,甚至可能会让应用崩溃。

      怎么处理呢?

      要解决这个问题也不是很复杂,解决问题的要点在于:

      • 减少重建缓存的次数。
      • 数据尽可能一致。
      • 较少的潜在危险。

      所以一般采用如下方式:

      1. 互斥锁(mutex key) 这种方法只允许一个线程重建缓存,其他线程等待重建缓存的线程执行完,重新从缓存获取数据即可。
      2. 永远不过期 “永远不过期”包含两层意思:
      • 从缓存层面来看,确实没有设置过期时间,所以不会出现热点key过期后产生的问题,也就是“物理”不过期。
      • 从功能层面来看,为每个value设置一个逻辑过期时间,当发现超过逻辑过期时间后,会使用单独的线程去构建缓存。

      33.无底洞问题吗?如何解决?

      什么是无底洞问题?

      2010年,Facebook的Memcache节点已经达到了3000个,承载着TB级别的缓存数据。但开发和运维人员发现了一个问题,为了满足业务要求添加了大量新Memcache节点,但是发现性能不但没有好转反而下降了,当时将这 种现象称为缓存的“无底洞”现象。

      那么为什么会产生这种现象呢?

      通常来说添加节点使得Memcache集群 性能应该更强了,但事实并非如此。键值数据库由于通常采用哈希函数将 key映射到各个节点上,造成key的分布与业务无关,但是由于数据量和访问量的持续增长,造成需要添加大量节点做水平扩容,导致键值分布到更多的 节点上,所以无论是Memcache还是Redis的分布式,批量操作通常需要从不同节点上获取,相比于单机批量操作只涉及一次网络操作,分布式批量操作会涉及多次网络时间。

      无底洞问题如何优化呢?

      先分析一下无底洞问题:

      • 客户端一次批量操作会涉及多次网络操作,也就意味着批量操作会随着节点的增多,耗时会不断增大。

      • 网络连接数变多,对节点的性能也有一定影响。

      常见的优化思路如下:

      • 命令本身的优化,例如优化操作语句等。

      • 减少网络通信次数。

      • 降低接入成本,例如客户端使用长连/连接池、NIO等。

      Redis运维

      34.Redis报内存不足怎么处理?

      Redis 内存不足有这么几种处理方式:

      • 修改配置文件 redis.conf 的 maxmemory 参数,增加 Redis 可用内存
      • 也可以通过命令set maxmemory动态设置内存上限
      • 修改内存淘汰策略,及时释放内存空间
      • 使用 Redis 集群模式,进行横向扩容。

      35.Redis的过期数据回收策略有哪些?

      Redis主要有2种过期数据回收策略: 在这里插入图片描述

      惰性删除

      惰性删除指的是当我们查询key的时候才对key进⾏检测,如果已经达到过期时间,则删除。显然,他有⼀个缺点就是如果这些过期的key没有被访问,那么他就⼀直⽆法被删除,⽽且⼀直占⽤内存。

      定期删除

      定期删除指的是Redis每隔⼀段时间对数据库做⼀次检查,删除⾥⾯的过期key。由于不可能对所有key去做轮询来删除,所以Redis会每次随机取⼀些key去做检查和删除。

      36.Redis有哪些内存溢出控制/内存淘汰策略?

      Redis所用内存达到maxmemory上限时会触发相应的溢出控制策略,Redis支持六种策略: Redis六种内存溢出控制策略

      1. noeviction:默认策略,不会删除任何数据,拒绝所有写入操作并返 回客户端错误信息,此 时Redis只响应读操作。
      2. volatile-lru:根据LRU算法删除设置了超时属性(expire)的键,直 到腾出足够空间为止。如果没有可删除的键对象,回退到noeviction策略。
      3. allkeys-lru:根据LRU算法删除键,不管数据有没有设置超时属性, 直到腾出足够空间为止。
      4. allkeys-random:随机删除所有键,直到腾出足够空间为止。
      5. volatile-random:随机删除过期键,直到腾出足够空间为止。
      6. volatile-ttl:根据键值对象的ttl属性,删除最近将要过期数据。如果 没有,回退到noeviction策略。

      37.Redis阻塞?怎么解决?

      Redis发生阻塞,可以从以下几个方面排查: Redis阻塞排查

      • API或数据结构使用不合理

        通常Redis执行命令速度非常快,但是不合理地使用命令,可能会导致执行速度很慢,导致阻塞,对于高并发的场景,应该尽量避免在大对象上执行算法复杂 度超过O(n)的命令。

        对慢查询的处理分为两步:

        1. 发现慢查询: slowlog get{n}命令可以获取最近 的n条慢查询命令;
        2. 发现慢查询后,可以从两个方向去优化慢查询: 1)修改为低算法复杂度的命令,如hgetall改为hmget等,禁用keys、sort等命 令 2)调整大对象:缩减大对象数据或把大对象拆分为多个小对象,防止一次命令操作过多的数据。
      • CPU饱和的问题

        单线程的Redis处理命令时只能使用一个CPU。而CPU饱和是指Redis单核CPU使用率跑到接近100%。

        针对这种情况,处理步骤一般如下:

        1. 判断当前Redis并发量是否已经达到极限,可以使用统计命令redis-cli-h{ip}-p{port}--stat获取当前 Redis使用情况
        2. 如果Redis的请求几万+,那么大概就是Redis的OPS已经到了极限,应该做集群化水品扩展来分摊OPS压力
        3. 如果只有几百几千,那么就得排查命令和内存的使用
      • 持久化相关的阻塞

        对于开启了持久化功能的Redis节点,需要排查是否是持久化导致的阻塞。

        1. fork阻塞 fork操作发生在RDB和AOF重写时,Redis主线程调用fork操作产生共享 内存的子进程,由子进程完成持久化文件重写工作。如果fork操作本身耗时过长,必然会导致主线程的阻塞。
        2. AOF刷盘阻塞 当我们开启AOF持久化功能时,文件刷盘的方式一般采用每秒一次,后台线程每秒对AOF文件做fsync操作。当硬盘压力过大时,fsync操作需要等 待,直到写入完成。如果主线程发现距离上一次的fsync成功超过2秒,为了 数据安全性它会阻塞直到后台线程执行fsync操作完成。
        3. HugePage写操作阻塞 对于开启Transparent HugePages的 操作系统,每次写命令引起的复制内存页单位由4K变为2MB,放大了512 倍,会拖慢写操作的执行时间,导致大量写操作慢查询。

      38.大key问题了解吗?

      Redis使用过程中,有时候会出现大key的情况, 比如:

      • 单个简单的key存储的value很大,size超过10KB
      • hash, set,zset,list 中存储过多的元素(以万为单位)

      大key会造成什么问题呢?

      • 客户端耗时增加,甚至超时
      • 对大key进行IO操作时,会严重占用带宽和CPU
      • 造成Redis集群中数据倾斜
      • 主动删除、被动删等,可能会导致阻塞

      如何找到大key?

      • bigkeys命令:使用bigkeys命令以遍历的方式分析Redis实例中的所有Key,并返回整体统计信息与每个数据类型中Top1的大Key
      • redis-rdb-tools:redis-rdb-tools是由Python写的用来分析Redis的rdb快照文件用的工具,它可以把rdb快照文件生成json文件或者生成报表用来分析Redis的使用详情。

      如何处理大key?

      大key处理

      • 删除大key

        • 当Redis版本大于4.0时,可使用UNLINK命令安全地删除大Key,该命令能够以非阻塞的方式,逐步地清理传入的Key。
        • 当Redis版本小于4.0时,避免使用阻塞式命令KEYS,而是建议通过SCAN命令执行增量迭代扫描key,然后判断进行删除。
      • 压缩和拆分key

        • 当vaule是string时,比较难拆分,则使用序列化、压缩算法将key的大小控制在合理范围内,但是序列化和反序列化都会带来更多时间上的消耗。
        • 当value是string,压缩之后仍然是大key,则需要进行拆分,一个大key分为不同的部分,记录每个部分的key,使用multiget等操作实现事务读取。
        • 当value是list/set等集合类型时,根据预估的数据规模来进行分片,不同的元素计算后分到不同的片。

      39.Redis常见性能问题和解决方案?

      1. Master 最好不要做任何持久化工作,包括内存快照和 AOF 日志文件,特别是不要启用内存快照做持久化。
      2. 如果数据比较关键,某个 Slave 开启 AOF 备份数据,策略为每秒同步一次。
      3. 为了主从复制的速度和连接的稳定性,Slave 和 Master 最好在同一个局域网内。
      4. 尽量避免在压力较大的主库上增加从库。
      5. Master 调用 BGREWRITEAOF 重写 AOF 文件,AOF 在重写的时候会占大量的 CPU 和内存资源,导致服务 load 过高,出现短暂服务暂停现象。
      6. 为了 Master 的稳定性,主从复制不要用图状结构,用单向链表结构更稳定,即主从关为:Master<–Slave1<–Slave2<–Slave3…,这样的结构也方便解决单点故障问题,实现 Slave 对 Master 的替换,也即,如果 Master 挂了,可以立马启用 Slave1 做 Master,其他不变。

      Redis应用

      40.使用Redis 如何实现异步队列?

      我们知道redis支持很多种结构的数据,那么如何使用redis作为异步队列使用呢? 一般有以下几种方式:

      • 使用list作为队列,lpush生产消息,rpop消费消息

      这种方式,消费者死循环rpop从队列中消费消息。但是这样,即使队列里没有消息,也会进行rpop,会导致Redis CPU的消耗。 list作为队列 可以通过让消费者休眠的方式的方式来处理,但是这样又会又消息的延迟问题。

      -使用list作为队列,lpush生产消息,brpop消费消息

      brpop是rpop的阻塞版本,list为空的时候,它会一直阻塞,直到list中有值或者超时。 list作为队列,brpop

      这种方式只能实现一对一的消息队列。

      • 使用Redis的pub/sub来进行消息的发布/订阅

      发布/订阅模式可以1:N的消息发布/订阅。发布者将消息发布到指定的频道频道(channel),订阅相应频道的客户端都能收到消息。

      pub/sub 但是这种方式不是可靠的,它不保证订阅者一定能收到消息,也不进行消息的存储。

      所以,一般的异步队列的实现还是交给专业的消息队列。

      41.Redis 如何实现延时队列?

      • 使用zset,利用排序实现

      可以使用 zset这个结构,用设置好的时间戳作为score进行排序,使用 zadd score1 value1 ....命令就可以一直往内存中生产消息。再利用 zrangebysocre 查询符合条件的所有待处理的任务,通过循环执行队列任务即可。 zset实现延时队列

      42.Redis 支持事务吗?

      Redis提供了简单的事务,但它对事务ACID的支持并不完备。

      multi命令代表事务开始,exec命令代表事务结束,它们之间的命令是原子顺序执行的:

      127.0.0.1:6379> multi 
      +    

      面渣逆袭(Redis)必看👍

      沉默王二2022年5月9日
      • 面渣逆袭
      • Redis
      大约 71 分钟

      面渣逆袭(Redis)必看👍

      图文详解 53 道Redis面试高频题,这次吊打面试官,我觉得稳了(手动 dog)。整理:沉默王二,戳转载链接open in new window,作者:三分恶,戳原文链接open in new window

      基础

      1.说说什么是Redis?

      Redis图标

      Redis是一种基于键值对(key-value)的NoSQL数据库。

      比一般键值对数据库强大的地方,Redis中的value支持string(字符串)、hash(哈希)、 list(列表)、set(集合)、zset(有序集合)、Bitmaps(位图)、 HyperLogLog、GEO(地理信息定位)等多种数据结构,因此 Redis可以满足很多的应用场景。

      而且因为Redis会将所有数据都存放在内存中,所以它的读写性能非常出色。

      不仅如此,Redis还可以将内存的数据利用快照和日志的形式保存到硬盘上,这样在发生类似断电或者机器故障的时候,内存中的数据不会“丢失”。

      除了上述功能以外,Redis还提供了键过期、发布订阅、事务、流水线、Lua脚本等附加功能。

      总之,Redis是一款强大的性能利器。

      2.Redis可以用来干什么?

      Redis

      1. 缓存

        这是Redis应用最广泛地方,基本所有的Web应用都会使用Redis作为缓存,来降低数据源压力,提高响应速度。 Redis缓存

      2. 计数器 Redis天然支持计数功能,而且计数性能非常好,可以用来记录浏览量、点赞量等等。

      3. 排行榜 Redis提供了列表和有序集合数据结构,合理地使用这些数据结构可以很方便地构建各种排行榜系统。

      4. 社交网络 赞/踩、粉丝、共同好友/喜好、推送、下拉刷新。

      5. 消息队列 Redis提供了发布订阅功能和阻塞队列的功能,可以满足一般消息队列功能。

      6. 分布式锁 分布式环境下,利用Redis实现分布式锁,也是Redis常见的应用。

      Redis的应用一般会结合项目去问,以一个电商项目的用户服务为例:

      • Token存储:用户登录成功之后,使用Redis存储Token
      • 登录失败次数计数:使用Redis计数,登录失败超过一定次数,锁定账号
      • 地址缓存:对省市区数据的缓存
      • 分布式锁:分布式环境下登录、注册等操作加分布式锁
      • ……

      3.Redis 有哪些数据结构?

      Redis基本数据结构 Redis有五种基本数据结构。

      string

      字符串最基础的数据结构。字符串类型的值实际可以是字符串(简单的字符串、复杂的字符串(例如JSON、XML))、数字 (整数、浮点数),甚至是二进制(图片、音频、视频),但是值最大不能超过512MB。

      字符串主要有以下几个典型使用场景:

      • 缓存功能
      • 计数
      • 共享Session
      • 限速

      hash

      哈希类型是指键值本身又是一个键值对结构。

      哈希主要有以下典型应用场景:

      • 缓存用户信息
      • 缓存对象

      list

      列表(list)类型是用来存储多个有序的字符串。列表是一种比较灵活的数据结构,它可以充当栈和队列的角色

      列表主要有以下几种使用场景:

      • 消息队列
      • 文章列表

      set

      集合(set)类型也是用来保存多个的字符串元素,但和列表类型不一 样的是,集合中不允许有重复元素,并且集合中的元素是无序的。

      集合主要有如下使用场景:

      • 标签(tag)
      • 共同关注

      sorted set

      有序集合中的元素可以排序。但是它和列表使用索引下标作为排序依据不同的是,它给每个元素设置一个权重(score)作为排序的依据。

      有序集合主要应用场景:

      • 用户点赞统计
      • 用户排序

      4.Redis为什么快呢?

      Redis的速度⾮常的快,单机的Redis就可以⽀撑每秒十几万的并发,相对于MySQL来说,性能是MySQL的⼏⼗倍。速度快的原因主要有⼏点:

      1. 完全基于内存操作
      2. 使⽤单线程,避免了线程切换和竞态产生的消耗
      3. 基于⾮阻塞的IO多路复⽤机制
      4. C语⾔实现,优化过的数据结构,基于⼏种基础的数据结构,redis做了⼤量的优化,性能极⾼ Redis使用IO多路复用和自身事件模型

      5.能说一下I/O多路复用吗?

      引用知乎上一个高赞的回答来解释什么是I/O多路复用。假设你是一个老师,让30个学生解答一道题目,然后检查学生做的是否正确,你有下面几个选择:

      • 第一种选择:按顺序逐个检查,先检查A,然后是B,之后是C、D。。。这中间如果有一个学生卡住,全班都会被耽误。这种模式就好比,你用循环挨个处理socket,根本不具有并发能力。

      • 第二种选择:你创建30个分身,每个分身检查一个学生的答案是否正确。 这种类似于为每一个用户创建一个进程或者- 线程处理连接。

      • 第三种选择,你站在讲台上等,谁解答完谁举手。这时C、D举手,表示他们解答问题完毕,你下去依次检查C、D的答案,然后继续回到讲台上等。此时E、A又举手,然后去处理E和A。

      第一种就是阻塞IO模型,第三种就是I/O复用模型。

      多路复用模型

      Linux系统有三种方式实现IO多路复用:select、poll和epoll。

      例如epoll方式是将用户socket对应的fd注册进epoll,然后epoll帮你监听哪些socket上有消息到达,这样就避免了大量的无用操作。此时的socket应该采用非阻塞模式。

      这样,整个过程只在进行select、poll、epoll这些调用的时候才会阻塞,收发客户消息是不会阻塞的,整个进程或者线程就被充分利用起来,这就是事件驱动,所谓的reactor模式。

      6. Redis为什么早期选择单线程?

      官方解释:https://redis.io/topics/faq

      官方单线程解释 官方FAQ表示,因为Redis是基于内存的操作,CPU成为Redis的瓶颈的情况很少见,Redis的瓶颈最有可能是内存的大小或者网络限制。

      如果想要最大程度利用CPU,可以在一台机器上启动多个Redis实例。

      PS:网上有这样的回答,吐槽官方的解释有些敷衍,其实就是历史原因,开发者嫌多线程麻烦,后来这个CPU的利用问题就被抛给了使用者。

      同时FAQ里还提到了, Redis 4.0 之后开始变成多线程,除了主线程外,它也有后台线程在处理一些较为缓慢的操作,例如清理脏数据、无用连接的释放、大 Key 的删除等等。

      7.Redis6.0使用多线程是怎么回事?

      Redis不是说用单线程的吗?怎么6.0成了多线程的?

      Redis6.0的多线程是用多线程来处理数据的读写和协议解析,但是Redis执行命令还是单线程的。

      Redis6.0多线程 这样做的⽬的是因为Redis的性能瓶颈在于⽹络IO⽽⾮CPU,使⽤多线程能提升IO读写的效率,从⽽整体提⾼Redis的性能。

      持久化

      8.Redis持久化⽅式有哪些?有什么区别?

      Redis持久化⽅案分为RDB和AOF两种。 Redis持久化两种方式

      RDB

      RDB持久化是把当前进程数据生成快照保存到硬盘的过程,触发RDB持久化过程分为手动触发和自动触发。

      RDB⽂件是⼀个压缩的⼆进制⽂件,通过它可以还原某个时刻数据库的状态。由于RDB⽂件是保存在硬盘上的,所以即使Redis崩溃或者退出,只要RDB⽂件存在,就可以⽤它来恢复还原数据库的状态。

      手动触发分别对应save和bgsave命令: save和bgsave

      • save命令:阻塞当前Redis服务器,直到RDB过程完成为止,对于内存比较大的实例会造成长时间阻塞,线上环境不建议使用。

      • bgsave命令:Redis进程执行fork操作创建子进程,RDB持久化过程由子进程负责,完成后自动结束。阻塞只发生在fork阶段,一般时间很短。

      以下场景会自动触发RDB持久化:

      • 使用save相关配置,如“save m n”。表示m秒内数据集存在n次修改时,自动触发bgsave。
      • 如果从节点执行全量复制操作,主节点自动执行bgsave生成RDB文件并发送给从节点
      • 执行debug reload命令重新加载Redis时,也会自动触发save操作
      • 默认情况下执行shutdown命令时,如果没有开启AOF持久化功能则自动执行bgsave。

      AOF

      AOF(append only file)持久化:以独立日志的方式记录每次写命令, 重启时再重新执行AOF文件中的命令达到恢复数据的目的。AOF的主要作用是解决了数据持久化的实时性,目前已经是Redis持久化的主流方式。

      AOF的工作流程操作:命令写入 (append)、文件同步(sync)、文件重写(rewrite)、重启加载 (load) AOF工作流程流程如下:

      1)所有的写入命令会追加到aof_buf(缓冲区)中。

      2)AOF缓冲区根据对应的策略向硬盘做同步操作。

      3)随着AOF文件越来越大,需要定期对AOF文件进行重写,达到压缩 的目的。

      4)当Redis服务器重启时,可以加载AOF文件进行数据恢复。

      9.RDB 和 AOF 各自有什么优缺点?

      RDB | 优点

      1. 只有一个紧凑的二进制文件 dump.rdb,非常适合备份、全量复制的场景。
      2. 容灾性好,可以把RDB文件拷贝道远程机器或者文件系统张,用于容灾恢复。
      3. 恢复速度快,RDB恢复数据的速度远远快于AOF的方式

      RDB | 缺点

      1. 实时性低,RDB 是间隔一段时间进行持久化,没法做到实时持久化/秒级持久化。如果在这一间隔事件发生故障,数据会丢失。
      2. 存在兼容问题,Redis演进过程存在多个格式的RDB版本,存在老版本Redis无法兼容新版本RDB的问题。

      AOF | 优点

      1. 实时性好,aof 持久化可以配置 appendfsync 属性,有 always,每进行一次命令操作就记录到 aof 文件中一次。
      2. 通过 append 模式写文件,即使中途服务器宕机,可以通过 redis-check-aof 工具解决数据一致性问题。

      AOF | 缺点

      1. AOF 文件比 RDB 文件大,且 恢复速度慢
      2. 数据集大 的时候,比 RDB 启动效率低

      10.RDB和AOF如何选择?

      • 一般来说, 如果想达到足以媲美数据库的 数据安全性,应该 同时使用两种持久化功能。在这种情况下,当 Redis 重启的时候会优先载入 AOF 文件来恢复原始的数据,因为在通常情况下 AOF 文件保存的数据集要比 RDB 文件保存的数据集要完整。
      • 如果 可以接受数分钟以内的数据丢失,那么可以 只使用 RDB 持久化
      • 有很多用户都只使用 AOF 持久化,但并不推荐这种方式,因为定时生成 RDB 快照(snapshot)非常便于进行数据备份, 并且 RDB 恢复数据集的速度也要比 AOF 恢复的速度要快,除此之外,使用 RDB 还可以避免 AOF 程序的 bug。
      • 如果只需要数据在服务器运行的时候存在,也可以不使用任何持久化方式。

      11.Redis的数据恢复?

      当Redis发生了故障,可以从RDB或者AOF中恢复数据。

      恢复的过程也很简单,把RDB或者AOF文件拷贝到Redis的数据目录下,如果使用AOF恢复,配置文件开启AOF,然后启动redis-server即可。 Redis启动加载数据

      Redis 启动时加载数据的流程:

      1. AOF持久化开启且存在AOF文件时,优先加载AOF文件。
      2. AOF关闭或者AOF文件不存在时,加载RDB文件。
      3. 加载AOF/RDB文件成功后,Redis启动成功。
      4. AOF/RDB文件存在错误时,Redis启动失败并打印错误信息。

      12.Redis 4.0 的混合持久化了解吗?

      重启 Redis 时,我们很少使用 RDB 来恢复内存状态,因为会丢失大量数据。我们通常使用 AOF 日志重放,但是重放 AOF 日志性能相对 RDB 来说要慢很多,这样在 Redis 实例很大的情况下,启动需要花费很长的时间。

      Redis 4.0 为了解决这个问题,带来了一个新的持久化选项——混合持久化。将 rdb 文件的内容和增量的 AOF 日志文件存在一起。这里的 AOF 日志不再是全量的日志,而是 自持久化开始到持久化结束 的这段时间发生的增量 AOF 日志,通常这部分 AOF 日志很小: 混合持久化

      于是在 Redis 重启的时候,可以先加载 rdb 的内容,然后再重放增量 AOF 日志就可以完全替代之前的 AOF 全量文件重放,重启效率因此大幅得到提升。

      高可用

      Redis保证高可用主要有三种方式:主从、哨兵、集群。

      13.主从复制了解吗?

      Redis主从复制简图

      主从复制,是指将一台 Redis 服务器的数据,复制到其他的 Redis 服务器。前者称为 主节点(master),后者称为 从节点(slave)。且数据的复制是 单向 的,只能由主节点到从节点。Redis 主从复制支持 主从同步从从同步 两种,后者是 Redis 后续版本新增的功能,以减轻主节点的同步负担。

      主从复制主要的作用?

      • 数据冗余: 主从复制实现了数据的热备份,是持久化之外的一种数据冗余方式。
      • 故障恢复: 当主节点出现问题时,可以由从节点提供服务,实现快速的故障恢复 (实际上是一种服务的冗余)
      • 负载均衡: 在主从复制的基础上,配合读写分离,可以由主节点提供写服务,由从节点提供读服务 (即写 Redis 数据时应用连接主节点,读 Redis 数据时应用连接从节点),分担服务器负载。尤其是在写少读多的场景下,通过多个从节点分担读负载,可以大大提高 Redis 服务器的并发量。
      • 高可用基石: 除了上述作用以外,主从复制还是哨兵和集群能够实施的 基础,因此说主从复制是 Redis 高可用的基础。

      14.Redis主从有几种常见的拓扑结构?

      Redis的复制拓扑结构可以支持单层或多层复制关系,根据拓扑复杂性可以分为以下三种:一主一从、一主多从、树状主从结构。

      1.一主一从结构

      一主一从结构是最简单的复制拓扑结构,用于主节点出现宕机时从节点提供故障转移支持。 一主一从结构 2.一主多从结构

      一主多从结构(又称为星形拓扑结构)使得应用端可以利用多个从节点实现读写分离(见图6-5)。对于读占比较大的场景,可以把读命令发送到从节点来分担主节点压力。 一主多从结构 3.树状主从结构

      树状主从结构(又称为树状拓扑结构)使得从节点不但可以复制主节点数据,同时可以作为其他从节点的主节点继续向下层复制。通过引入复制中间层,可以有效降低主节点负载和需要传送给从节点的数据量。 树状主从结构

      15.Redis的主从复制原理了解吗?

      Redis主从复制的工作流程大概可以分为如下几步: Redis主从复制工作流程

      1. 保存主节点(master)信息 这一步只是保存主节点信息,保存主节点的ip和port。
      2. 主从建立连接 从节点(slave)发现新的主节点后,会尝试和主节点建立网络连接。
      3. 发送ping命令 连接建立成功后从节点发送ping请求进行首次通信,主要是检测主从之间网络套接字是否可用、主节点当前是否可接受处理命令。
      4. 权限验证 如果主节点要求密码验证,从节点必须正确的密码才能通过验证。
      5. 同步数据集 主从复制连接正常通信后,主节点会把持有的数据全部发送给从节点。
      6. 命令持续复制 接下来主节点会持续地把写命令发送给从节点,保证主从数据一致性。

      16.说说主从数据同步的方式?

      Redis在2.8及以上版本使用psync命令完成主从数据同步,同步过程分为:全量复制和部分复制。

      主从数据同步方式

      全量复制 一般用于初次复制场景,Redis早期支持的复制功能只有全量复制,它会把主节点全部数据一次性发送给从节点,当数据量较大时,会对主从节点和网络造成很大的开销。

      全量复制的完整运行流程如下: 全量复制

      1. 发送psync命令进行数据同步,由于是第一次进行复制,从节点没有复制偏移量和主节点的运行ID,所以发送psync-1。
      2. 主节点根据psync-1解析出当前为全量复制,回复+FULLRESYNC响应。
      3. 从节点接收主节点的响应数据保存运行ID和偏移量offset
      4. 主节点执行bgsave保存RDB文件到本地
      5. 主节点发送RDB文件给从节点,从节点把接收的RDB文件保存在本地并直接作为从节点的数据文件
      6. 对于从节点开始接收RDB快照到接收完成期间,主节点仍然响应读写命令,因此主节点会把这期间写命令数据保存在复制客户端缓冲区内,当从节点加载完RDB文件后,主节点再把缓冲区内的数据发送给从节点,保证主从之间数据一致性。
      7. 从节点接收完主节点传送来的全部数据后会清空自身旧数据
      8. 从节点清空数据后开始加载RDB文件
      9. 从节点成功加载完RDB后,如果当前节点开启了AOF持久化功能, 它会立刻做bgrewriteaof操作,为了保证全量复制后AOF持久化文件立刻可用。

      部分复制 部分复制主要是Redis针对全量复制的过高开销做出的一种优化措施, 使用psync{runId}{offset}命令实现。当从节点(slave)正在复制主节点 (master)时,如果出现网络闪断或者命令丢失等异常情况时,从节点会向 主节点要求补发丢失的命令数据,如果主节点的复制积压缓冲区内存在这部分数据则直接发送给从节点,这样就可以保持主从节点复制的一致性。 部分复制

      1. 当主从节点之间网络出现中断时,如果超过repl-timeout时间,主节点会认为从节点故障并中断复制连接
      2. 主从连接中断期间主节点依然响应命令,但因复制连接中断命令无法发送给从节点,不过主节点内部存在的复制积压缓冲区,依然可以保存最近一段时间的写命令数据,默认最大缓存1MB。
      3. 当主从节点网络恢复后,从节点会再次连上主节点
      4. 当主从连接恢复后,由于从节点之前保存了自身已复制的偏移量和主节点的运行ID。因此会把它们当作psync参数发送给主节点,要求进行部分复制操作。
      5. 主节点接到psync命令后首先核对参数runId是否与自身一致,如果一 致,说明之前复制的是当前主节点;之后根据参数offset在自身复制积压缓冲区查找,如果偏移量之后的数据存在缓冲区中,则对从节点发送+CONTINUE响应,表示可以进行部分复制。
      6. 主节点根据偏移量把复制积压缓冲区里的数据发送给从节点,保证主从复制进入正常状态。

      17.主从复制存在哪些问题呢?

      主从复制虽好,但也存在一些问题:

      • 一旦主节点出现故障,需要手动将一个从节点晋升为主节点,同时需要修改应用方的主节点地址,还需要命令其他从节点去复制新的主节点,整个过程都需要人工干预。
      • 主节点的写能力受到单机的限制。
      • 主节点的存储能力受到单机的限制。

      第一个问题是Redis的高可用问题,第二、三个问题属于Redis的分布式问题。

      18.Redis Sentinel(哨兵)了解吗?

      主从复制存在一个问题,没法完成自动故障转移。所以我们需要一个方案来完成自动故障转移,它就是Redis Sentinel(哨兵)。

      Redis Sentinel

      Redis Sentinel ,它由两部分组成,哨兵节点和数据节点:

      • 哨兵节点: 哨兵系统由一个或多个哨兵节点组成,哨兵节点是特殊的 Redis 节点,不存储数据,对数据节点进行监控。
      • 数据节点: 主节点和从节点都是数据节点;

      在复制的基础上,哨兵实现了 自动化的故障恢复 功能,下面是官方对于哨兵功能的描述:

      • 监控(Monitoring): 哨兵会不断地检查主节点和从节点是否运作正常。
      • 自动故障转移(Automatic failover):主节点 不能正常工作时,哨兵会开始 自动故障转移操作,它会将失效主节点的其中一个 从节点升级为新的主节点,并让其他从节点改为复制新的主节点。
      • 配置提供者(Configuration provider): 客户端在初始化时,通过连接哨兵来获得当前 Redis 服务的主节点地址。
      • 通知(Notification): 哨兵可以将故障转移的结果发送给客户端。

      其中,监控和自动故障转移功能,使得哨兵可以及时发现主节点故障并完成转移。而配置提供者和通知功能,则需要在与客户端的交互中才能体现。

      19.Redis Sentinel(哨兵)实现原理知道吗?

      哨兵模式是通过哨兵节点完成对数据节点的监控、下线、故障转移。 Redis Sentinel工作流程

      • 定时监控三个定时任务Redis Sentinel通过三个定时监控任务完成对各个节点发现和监控:
        1. 每隔10秒,每个Sentinel节点会向主节点和从节点发送info命令获取最新的拓扑结构
        2. 每隔2秒,每个Sentinel节点会向Redis数据节点的__sentinel__:hello 频道上发送该Sentinel节点对于主节点的判断以及当前Sentinel节点的信息
        3. 每隔1秒,每个Sentinel节点会向主节点、从节点、其余Sentinel节点发送一条ping命令做一次心跳检测,来确认这些节点当前是否可达
      • 主观下线和客观下线 主观下线就是哨兵节点认为某个节点有问题,客观下线就是超过一定数量的哨兵节点认为主节点有问题。 主观下线和客观下线
      1. 主观下线 每个Sentinel节点会每隔1秒对主节点、从节点、其他Sentinel节点发送ping命令做心跳检测,当这些节点超过 down-after-milliseconds没有进行有效回复,Sentinel节点就会对该节点做失败判定,这个行为叫做主观下线。

      2. 客观下线 当Sentinel主观下线的节点是主节点时,该Sentinel节点会通过sentinel is- master-down-by-addr命令向其他Sentinel节点询问对主节点的判断,当超过 <quorum>个数,Sentinel节点认为主节点确实有问题,这时该Sentinel节点会做出客观下线的决定

      • 领导者Sentinel节点选举 Sentinel节点之间会做一个领导者选举的工作,选出一个Sentinel节点作为领导者进行故障转移的工作。Redis使用了Raft算法实现领导者选举。

      • 故障转移

        领导者选举出的Sentinel节点负责故障转移,过程如下: 故障转移

        1. 在从节点列表中选出一个节点作为新的主节点,这一步是相对复杂一些的一步
        2. Sentinel领导者节点会对第一步选出来的从节点执行slaveof no one命令让其成为主节点
        3. Sentinel领导者节点会向剩余的从节点发送命令,让它们成为新主节点的从节点
        4. Sentinel节点集合会将原来的主节点更新为从节点,并保持着对其关注,当其恢复后命令它去复制新的主节点

      20.领导者Sentinel节点选举了解吗?

      Redis使用了Raft算法实 现领导者选举,大致流程如下: 领导者Sentinel节点选举

      1. 每个在线的Sentinel节点都有资格成为领导者,当它确认主节点主观 下线时候,会向其他Sentinel节点发送sentinel is-master-down-by-addr命令, 要求将自己设置为领导者。
      2. 收到命令的Sentinel节点,如果没有同意过其他Sentinel节点的sentinel is-master-down-by-addr命令,将同意该请求,否则拒绝。
      3. 如果该Sentinel节点发现自己的票数已经大于等于max(quorum, num(sentinels)/2+1),那么它将成为领导者。
      4. 如果此过程没有选举出领导者,将进入下一次选举。

      21.新的主节点是怎样被挑选出来的?

      选出新的主节点,大概分为这么几步: 新的主节点

      1. 过滤:“不健康”(主观下线、断线)、5秒内没有回复过Sentinel节 点ping响应、与主节点失联超过down-after-milliseconds*10秒。
      2. 选择slave-priority(从节点优先级)最高的从节点列表,如果存在则返回,不存在则继续。
      3. 选择复制偏移量最大的从节点(复制的最完整),如果存在则返 回,不存在则继续。
      4. 选择runid最小的从节点。

      22.Redis 集群了解吗?

      前面说到了主从存在高可用和分布式的问题,哨兵解决了高可用的问题,而集群就是终极方案,一举解决高可用和分布式问题。 Redis 集群示意图

      1. 数据分区: 数据分区 (或称数据分片) 是集群最核心的功能。集群将数据分散到多个节点,一方面 突破了 Redis 单机内存大小的限制,存储容量大大增加另一方面 每个主节点都可以对外提供读服务和写服务,大大提高了集群的响应能力

      2. 高可用: 集群支持主从复制和主节点的 自动故障转移 (与哨兵类似),当任一节点发生故障时,集群仍然可以对外提供服务。

      23.集群中数据如何分区?

      分布式的存储中,要把数据集按照分区规则映射到多个节点,常见的数据分区规则三种: 分布式数据分区

      方案一:节点取余分区

      节点取余分区,非常好理解,使用特定的数据,比如Redis的键,或者用户ID之类,对响应的hash值取余:hash(key)%N,来确定数据映射到哪一个节点上。

      不过该方案最大的问题是,当节点数量变化时,如扩容或收缩节点,数据节点映射关 系需要重新计算,会导致数据的重新迁移。

      节点取余分区

      方案二:一致性哈希分区

      将整个 Hash 值空间组织成一个虚拟的圆环,然后将缓存节点的 IP 地址或者主机名做 Hash 取值后,放置在这个圆环上。当我们需要确定某一个 Key 需 要存取到哪个节点上的时候,先对这个 Key 做同样的 Hash 取值,确定在环上的位置,然后按照顺时针方向在环上“行走”,遇到的第一个缓存节点就是要访问的节点。

      比如说下面 这张图里面,Key 1 和 Key 2 会落入到 Node 1 中,Key 3、Key 4 会落入到 Node 2 中,Key 5 落入到 Node 3 中,Key 6 落入到 Node 4 中。 一致性哈希分区

      这种方式相比节点取余最大的好处在于加入和删除节点只影响哈希环中 相邻的节点,对其他节点无影响。

      但它还是存在问题:

      • 缓存节点在圆环上分布不平均,会造成部分缓存节点的压力较大
      • 当某个节点故障时,这个节点所要承担的所有访问都会被顺移到另一个节点上,会对后面这个节点造成力。
      方案三:虚拟槽分区

      这个方案 一致性哈希分区的基础上,引入了 虚拟节点 的概念。Redis 集群使用的便是该方案,其中的虚拟节点称为 槽(slot)。槽是介于数据和实际节点之间的虚拟概念,每个实际节点包含一定数量的槽,每个槽包含哈希值在一定范围内的数据。 虚拟槽分配

      在使用了槽的一致性哈希分区中,槽是数据管理和迁移的基本单位。槽解耦了数据和实际节点 之间的关系,增加或删除节点对系统的影响很小。仍以上图为例,系统中有 4 个实际节点,假设为其分配 16 个槽(0-15);

      • 槽 0-3 位于 node1;4-7 位于 node2;以此类推....

      如果此时删除 node2,只需要将槽 4-7 重新分配即可,例如槽 4-5 分配给 node1,槽 6 分配给 node3,槽 7 分配给 node4,数据在其他节点的分布仍然较为均衡。

      24.能说说Redis集群的原理吗?

      Redis集群通过数据分区来实现数据的分布式存储,通过自动故障转移实现高可用。

      集群创建

      数据分区是在集群创建的时候完成的。 集群创建

      设置节点 Redis集群一般由多个节点组成,节点数量至少为6个才能保证组成完整高可用的集群。每个节点需要开启配置cluster-enabled yes,让Redis运行在集群模式下。 节点和握手节点握手 节点握手是指一批运行在集群模式下的节点通过Gossip协议彼此通信, 达到感知对方的过程。节点握手是集群彼此通信的第一步,由客户端发起命 令:cluster meet{ip}{port}。完成节点握手之后,一个个的Redis节点就组成了一个多节点的集群。

      分配槽(slot) Redis集群把所有的数据映射到16384个槽中。每个节点对应若干个槽,只有当节点分配了槽,才能响应和这些槽关联的键命令。通过 cluster addslots命令为节点分配槽。

      分配槽

      故障转移

      Redis集群的故障转移和哨兵的故障转移类似,但是Redis集群中所有的节点都要承担状态维护的任务。

      故障发现 Redis集群内节点通过ping/pong消息实现节点通信,集群中每个节点都会定期向其他节点发送ping消息,接收节点回复pong 消息作为响应。如果在cluster-node-timeout时间内通信一直失败,则发送节 点会认为接收节点存在故障,把接收节点标记为主观下线(pfail)状态。 主观下线 当某个节点判断另一个节点主观下线后,相应的节点状态会跟随消息在集群内传播。通过Gossip消息传播,集群内节点不断收集到故障节点的下线报告。当 半数以上持有槽的主节点都标记某个节点是主观下线时。触发客观下线流程。 主观下线和客观下线

      故障恢复

      故障节点变为客观下线后,如果下线节点是持有槽的主节点则需要在它 的从节点中选出一个替换它,从而保证集群的高可用。

      故障恢复流程

      1. 资格检查 每个从节点都要检查最后与主节点断线时间,判断是否有资格替换故障 的主节点。
      2. 准备选举时间 当从节点符合故障转移资格后,更新触发故障选举的时间,只有到达该 时间后才能执行后续流程。
      3. 发起选举 当从节点定时任务检测到达故障选举时间(failover_auth_time)到达后,发起选举流程。
      4. 选举投票 持有槽的主节点处理故障选举消息。投票过程其实是一个领导者选举的过程,如集群内有N个持有槽的主节 点代表有N张选票。由于在每个配置纪元内持有槽的主节点只能投票给一个 从节点,因此只能有一个从节点获得N/2+1的选票,保证能够找出唯一的从节点。 选举投票
      5. 替换主节点 当从节点收集到足够的选票之后,触发替换主节点操作。

      部署Redis集群至少需要几个物理节点?

      在投票选举的环节,故障主节点也算在投票数内,假设集群内节点规模是3主3从,其中有2 个主节点部署在一台机器上,当这台机器宕机时,由于从节点无法收集到 3/2+1个主节点选票将导致故障转移失败。这个问题也适用于故障发现环节。因此部署集群时所有主节点最少需要部署在3台物理机上才能避免单点问题。

      25.说说集群的伸缩?

      Redis集群提供了灵活的节点扩容和收缩方案,可以在不影响集群对外服务的情况下,为集群添加节点进行扩容也可以下线部分节点进行缩容。 集群的伸缩其实,集群扩容和缩容的关键点,就在于槽和节点的对应关系,扩容和缩容就是将一部分数据迁移给新节点。

      例如下面一个集群,每个节点对应若干个槽,每个槽对应一定的数据,如果希望加入1个节点希望实现集群扩容时,需要通过相关命令把一部分槽和内容迁移给新节点。 扩容实例缩容也是类似,先把槽和数据迁移到其它节点,再把对应的节点下线。

      缓存设计

      26.什么是缓存击穿、缓存穿透、缓存雪崩?

      PS:这是多年黄历的老八股了,一定要理解清楚。

      缓存击穿

      一个并发访问量比较大的key在某个时间过期,导致所有的请求直接打在DB上。

      缓存击穿 解决⽅案:

      1. 加锁更新,⽐如请求查询A,发现缓存中没有,对A这个key加锁,同时去数据库查询数据,写⼊缓存,再返回给⽤户,这样后⾯的请求就可以从缓存中拿到数据了。 加锁更新

      2. 将过期时间组合写在value中,通过异步的⽅式不断的刷新过期时间,防⽌此类现象。

      缓存穿透

      缓存穿透指的查询缓存和数据库中都不存在的数据,这样每次请求直接打到数据库,就好像缓存不存在一样。

      缓存穿透 缓存穿透将导致不存在的数据每次请求都要到存储层去查询,失去了缓存保护后端存储的意义。

      缓存穿透可能会使后端存储负载加大,如果发现大量存储层空命中,可能就是出现了缓存穿透问题。

      缓存穿透可能有两种原因:

      1. 自身业务代码问题
      2. 恶意攻击,爬虫造成空命中

      它主要有两种解决办法:

      • 缓存空值/默认值

      一种方式是在数据库不命中之后,把一个空对象或者默认值保存到缓存,之后再访问这个数据,就会从缓存中获取,这样就保护了数据库。

      缓存空值/默认值

      缓存空值有两大问题:

      1. 空值做了缓存,意味着缓存层中存了更多的键,需要更多的内存空间(如果是攻击,问题更严重),比较有效的方法是针对这类数据设置一个较短的过期时间,让其自动剔除。

      2. 缓存层和存储层的数据会有一段时间窗口的不一致,可能会对业务有一定影响。 例如过期时间设置为5分钟,如果此时存储层添加了这个数据,那此段时间就会出现缓存层和存储层数据的不一致。 这时候可以利用消息队列或者其它异步方式清理缓存中的空对象。

      • 布隆过滤器 除了缓存空对象,我们还可以在存储和缓存之前,加一个布隆过滤器,做一层过滤。

      布隆过滤器里会保存数据是否存在,如果判断数据不不能再,就不会访问存储。 布隆过滤器 两种解决方案的对比: 缓存空对象核布隆过滤器方案对比

      缓存雪崩

      某⼀时刻发⽣⼤规模的缓存失效的情况,例如缓存服务宕机、大量key在同一时间过期,这样的后果就是⼤量的请求进来直接打到DB上,可能导致整个系统的崩溃,称为雪崩。

      缓存雪崩 缓存雪崩是三大缓存问题里最严重的一种,我们来看看怎么预防和处理。

      • 提高缓存可用性
      1. 集群部署:通过集群来提升缓存的可用性,可以利用Redis本身的Redis Cluster或者第三方集群方案如Codis等。
      2. 多级缓存:设置多级缓存,第一级缓存失效的基础上,访问二级缓存,每一级缓存的失效时间都不同。
      • 过期时间
      1. 均匀过期:为了避免大量的缓存在同一时间过期,可以把不同的 key 过期时间随机生成,避免过期时间太过集中。
      2. 热点数据永不过期。
      • 熔断降级
      1. 服务熔断:当缓存服务器宕机或超时响应时,为了防止整个系统出现雪崩,暂时停止业务服务访问缓存系统。
      2. 服务降级:当出现大量缓存失效,而且处在高并发高负荷的情况下,在业务系统内部暂时舍弃对一些非核心的接口和数据的请求,而直接返回一个提前准备好的 fallback(退路)错误处理信息。

      27.能说说布隆过滤器吗?

      布隆过滤器,它是一个连续的数据结构,每个存储位存储都是一个bit,即0或者1, 来标识数据是否存在。

      存储数据的时时候,使用K个不同的哈希函数将这个变量映射为bit列表的的K个点,把它们置为1。

      布隆过滤器我们判断缓存key是否存在,同样,K个哈希函数,映射到bit列表上的K个点,判断是不是1:

      • 如果全不是1,那么key不存在;
      • 如果都是1,也只是表示key可能存在。

      布隆过滤器也有一些缺点:

      1. 它在判断元素是否在集合中时是有一定错误几率,因为哈希算法有一定的碰撞的概率。
      2. 不支持删除元素。

      28.如何保证缓存和数据库数据的⼀致性?

      根据CAP理论,在保证可用性和分区容错性的前提下,无法保证一致性,所以缓存和数据库的绝对一致是不可能实现的,只能尽可能保存缓存和数据库的最终一致性。

      选择合适的缓存更新策略

      1. 删除缓存而不是更新缓存

      当一个线程对缓存的key进行写操作的时候,如果其它线程进来读数据库的时候,读到的就是脏数据,产生了数据不一致问题。

      相比较而言,删除缓存的速度比更新缓存的速度快很多,所用时间相对也少很多,读脏数据的概率也小很多。 删除缓存和更新缓存

      1. 先更数据,后删缓存 先更数据库还是先删缓存?这是一个问题。

      更新数据,耗时可能在删除缓存的百倍以上。在缓存中不存在对应的key,数据库又没有完成更新的时候,如果有线程进来读取数据,并写入到缓存,那么在更新成功之后,这个key就是一个脏数据。

      毫无疑问,先删缓存,再更数据库,缓存中key不存在的时间的时间更长,有更大的概率会产生脏数据。

      先更数据库还是先删缓存目前最流行的缓存读写策略cache-aside-pattern就是采用先更数据库,再删缓存的方式。

      缓存不一致处理

      如果不是并发特别高,对缓存依赖性很强,其实一定程序的不一致是可以接受的。

      但是如果对一致性要求比较高,那就得想办法保证缓存和数据库中数据一致。

      缓存和数据库数据不一致常见的两种原因:

      • 缓存key删除失败
      • 并发导致写入了脏数据

      缓存一致性

      消息队列保证key被删除 可以引入消息队列,把要删除的key或者删除失败的key丢尽消息队列,利用消息队列的重试机制,重试删除对应的key。

      消息队列保证key被删除这种方案看起来不错,缺点是对业务代码有一定的侵入性。

      数据库订阅+消息队列保证key被删除 可以用一个服务(比如阿里的 canal)去监听数据库的binlog,获取需要操作的数据。

      然后用一个公共的服务获取订阅程序传来的信息,进行缓存删除操作。 数据库订阅+消息队列保证key被删除 这种方式降低了对业务的侵入,但其实整个系统的复杂度是提升的,适合基建完善的大厂。

      延时双删防止脏数据 还有一种情况,是在缓存不存在的时候,写入了脏数据,这种情况在先删缓存,再更数据库的缓存更新策略下发生的比较多,解决方案是延时双删。

      简单说,就是在第一次删除缓存之后,过了一段时间之后,再次删除缓存。

      延时双删

      这种方式的延时时间设置需要仔细考量和测试。

      设置缓存过期时间兜底

      这是一个朴素但是有用的办法,给缓存设置一个合理的过期时间,即使发生了缓存数据不一致的问题,它也不会永远不一致下去,缓存过期的时候,自然又会恢复一致。

      29.如何保证本地缓存和分布式缓存的一致?

      PS:这道题面试很少问,但实际工作中很常见。

      在日常的开发中,我们常常采用两级缓存:本地缓存+分布式缓存。

      所谓本地缓存,就是对应服务器的内存缓存,比如Caffeine,分布式缓存基本就是采用Redis。

      那么问题来了,本地缓存和分布式缓存怎么保持数据一致? 延时双删 Redis缓存,数据库发生更新,直接删除缓存的key即可,因为对于应用系统而言,它是一种中心化的缓存。

      但是本地缓存,它是非中心化的,散落在分布式服务的各个节点上,没法通过客户端的请求删除本地缓存的key,所以得想办法通知集群所有节点,删除对应的本地缓存key。 本地缓存/分布式缓存保持一致

      可以采用消息队列的方式:

      1. 采用Redis本身的Pub/Sub机制,分布式集群的所有节点订阅删除本地缓存频道,删除Redis缓存的节点,同事发布删除本地缓存消息,订阅者们订阅到消息后,删除对应的本地key。 但是Redis的发布订阅不是可靠的,不能保证一定删除成功。
      2. 引入专业的消息队列,比如RocketMQ,保证消息的可靠性,但是增加了系统的复杂度。
      3. 设置适当的过期时间兜底,本地缓存可以设置相对短一些的过期时间。

      30.怎么处理热key?

      什么是热Key? 所谓的热key,就是访问频率比较的key。

      比如,热门新闻事件或商品,这类key通常有大流量的访问,对存储这类信息的 Redis来说,是不小的压力。

      假如Redis集群部署,热key可能会造成整体流量的不均衡,个别节点出现OPS过大的情况,极端情况下热点key甚至会超过 Redis本身能够承受的OPS。

      怎么处理热key?

      热key处理 对热key的处理,最关键的是对热点key的监控,可以从这些端来监控热点key:

      1. 客户端 客户端其实是距离key“最近”的地方,因为Redis命令就是从客户端发出的,例如在客户端设置全局字典(key和调用次数),每次调用Redis命令时,使用这个字典进行记录。

      2. 代理端 像Twemproxy、Codis这些基于代理的Redis分布式架构,所有客户端的请求都是通过代理端完成的,可以在代理端进行收集统计。

      3. Redis服务端 使用monitor命令统计热点key是很多开发和运维人员首先想到,monitor命令可以监控到Redis执行的所有命令。

      只要监控到了热key,对热key的处理就简单了:

      1. 把热key打散到不同的服务器,降低压⼒

      2. 加⼊⼆级缓存,提前加载热key数据到内存中,如果redis宕机,⾛内存查询

      31.缓存预热怎么做呢?

      所谓缓存预热,就是提前把数据库里的数据刷到缓存里,通常有这些方法:

      1、直接写个缓存刷新页面或者接口,上线时手动操作

      2、数据量不大,可以在项目启动的时候自动进行加载

      3、定时任务刷新缓存.

      32.热点key重建?问题?解决?

      开发的时候一般使用“缓存+过期时间”的策略,既可以加速数据读写,又保证数据的定期更新,这种模式基本能够满足绝大部分需求。

      但是有两个问题如果同时出现,可能就会出现比较大的问题:

      • 当前key是一个热点key(例如一个热门的娱乐新闻),并发量非常大。

      • 重建缓存不能在短时间完成,可能是一个复杂计算,例如复杂的 SQL、多次IO、多个依赖等。 在缓存失效的瞬间,有大量线程来重建缓存,造成后端负载加大,甚至可能会让应用崩溃。

      怎么处理呢?

      要解决这个问题也不是很复杂,解决问题的要点在于:

      • 减少重建缓存的次数。
      • 数据尽可能一致。
      • 较少的潜在危险。

      所以一般采用如下方式:

      1. 互斥锁(mutex key) 这种方法只允许一个线程重建缓存,其他线程等待重建缓存的线程执行完,重新从缓存获取数据即可。
      2. 永远不过期 “永远不过期”包含两层意思:
      • 从缓存层面来看,确实没有设置过期时间,所以不会出现热点key过期后产生的问题,也就是“物理”不过期。
      • 从功能层面来看,为每个value设置一个逻辑过期时间,当发现超过逻辑过期时间后,会使用单独的线程去构建缓存。

      33.无底洞问题吗?如何解决?

      什么是无底洞问题?

      2010年,Facebook的Memcache节点已经达到了3000个,承载着TB级别的缓存数据。但开发和运维人员发现了一个问题,为了满足业务要求添加了大量新Memcache节点,但是发现性能不但没有好转反而下降了,当时将这 种现象称为缓存的“无底洞”现象。

      那么为什么会产生这种现象呢?

      通常来说添加节点使得Memcache集群 性能应该更强了,但事实并非如此。键值数据库由于通常采用哈希函数将 key映射到各个节点上,造成key的分布与业务无关,但是由于数据量和访问量的持续增长,造成需要添加大量节点做水平扩容,导致键值分布到更多的 节点上,所以无论是Memcache还是Redis的分布式,批量操作通常需要从不同节点上获取,相比于单机批量操作只涉及一次网络操作,分布式批量操作会涉及多次网络时间。

      无底洞问题如何优化呢?

      先分析一下无底洞问题:

      • 客户端一次批量操作会涉及多次网络操作,也就意味着批量操作会随着节点的增多,耗时会不断增大。

      • 网络连接数变多,对节点的性能也有一定影响。

      常见的优化思路如下:

      • 命令本身的优化,例如优化操作语句等。

      • 减少网络通信次数。

      • 降低接入成本,例如客户端使用长连/连接池、NIO等。

      Redis运维

      34.Redis报内存不足怎么处理?

      Redis 内存不足有这么几种处理方式:

      • 修改配置文件 redis.conf 的 maxmemory 参数,增加 Redis 可用内存
      • 也可以通过命令set maxmemory动态设置内存上限
      • 修改内存淘汰策略,及时释放内存空间
      • 使用 Redis 集群模式,进行横向扩容。

      35.Redis的过期数据回收策略有哪些?

      Redis主要有2种过期数据回收策略: 在这里插入图片描述

      惰性删除

      惰性删除指的是当我们查询key的时候才对key进⾏检测,如果已经达到过期时间,则删除。显然,他有⼀个缺点就是如果这些过期的key没有被访问,那么他就⼀直⽆法被删除,⽽且⼀直占⽤内存。

      定期删除

      定期删除指的是Redis每隔⼀段时间对数据库做⼀次检查,删除⾥⾯的过期key。由于不可能对所有key去做轮询来删除,所以Redis会每次随机取⼀些key去做检查和删除。

      36.Redis有哪些内存溢出控制/内存淘汰策略?

      Redis所用内存达到maxmemory上限时会触发相应的溢出控制策略,Redis支持六种策略: Redis六种内存溢出控制策略

      1. noeviction:默认策略,不会删除任何数据,拒绝所有写入操作并返 回客户端错误信息,此 时Redis只响应读操作。
      2. volatile-lru:根据LRU算法删除设置了超时属性(expire)的键,直 到腾出足够空间为止。如果没有可删除的键对象,回退到noeviction策略。
      3. allkeys-lru:根据LRU算法删除键,不管数据有没有设置超时属性, 直到腾出足够空间为止。
      4. allkeys-random:随机删除所有键,直到腾出足够空间为止。
      5. volatile-random:随机删除过期键,直到腾出足够空间为止。
      6. volatile-ttl:根据键值对象的ttl属性,删除最近将要过期数据。如果 没有,回退到noeviction策略。

      37.Redis阻塞?怎么解决?

      Redis发生阻塞,可以从以下几个方面排查: Redis阻塞排查

      • API或数据结构使用不合理

        通常Redis执行命令速度非常快,但是不合理地使用命令,可能会导致执行速度很慢,导致阻塞,对于高并发的场景,应该尽量避免在大对象上执行算法复杂 度超过O(n)的命令。

        对慢查询的处理分为两步:

        1. 发现慢查询: slowlog get{n}命令可以获取最近 的n条慢查询命令;
        2. 发现慢查询后,可以从两个方向去优化慢查询: 1)修改为低算法复杂度的命令,如hgetall改为hmget等,禁用keys、sort等命 令 2)调整大对象:缩减大对象数据或把大对象拆分为多个小对象,防止一次命令操作过多的数据。
      • CPU饱和的问题

        单线程的Redis处理命令时只能使用一个CPU。而CPU饱和是指Redis单核CPU使用率跑到接近100%。

        针对这种情况,处理步骤一般如下:

        1. 判断当前Redis并发量是否已经达到极限,可以使用统计命令redis-cli-h{ip}-p{port}--stat获取当前 Redis使用情况
        2. 如果Redis的请求几万+,那么大概就是Redis的OPS已经到了极限,应该做集群化水品扩展来分摊OPS压力
        3. 如果只有几百几千,那么就得排查命令和内存的使用
      • 持久化相关的阻塞

        对于开启了持久化功能的Redis节点,需要排查是否是持久化导致的阻塞。

        1. fork阻塞 fork操作发生在RDB和AOF重写时,Redis主线程调用fork操作产生共享 内存的子进程,由子进程完成持久化文件重写工作。如果fork操作本身耗时过长,必然会导致主线程的阻塞。
        2. AOF刷盘阻塞 当我们开启AOF持久化功能时,文件刷盘的方式一般采用每秒一次,后台线程每秒对AOF文件做fsync操作。当硬盘压力过大时,fsync操作需要等 待,直到写入完成。如果主线程发现距离上一次的fsync成功超过2秒,为了 数据安全性它会阻塞直到后台线程执行fsync操作完成。
        3. HugePage写操作阻塞 对于开启Transparent HugePages的 操作系统,每次写命令引起的复制内存页单位由4K变为2MB,放大了512 倍,会拖慢写操作的执行时间,导致大量写操作慢查询。

      38.大key问题了解吗?

      Redis使用过程中,有时候会出现大key的情况, 比如:

      • 单个简单的key存储的value很大,size超过10KB
      • hash, set,zset,list 中存储过多的元素(以万为单位)

      大key会造成什么问题呢?

      • 客户端耗时增加,甚至超时
      • 对大key进行IO操作时,会严重占用带宽和CPU
      • 造成Redis集群中数据倾斜
      • 主动删除、被动删等,可能会导致阻塞

      如何找到大key?

      • bigkeys命令:使用bigkeys命令以遍历的方式分析Redis实例中的所有Key,并返回整体统计信息与每个数据类型中Top1的大Key
      • redis-rdb-tools:redis-rdb-tools是由Python写的用来分析Redis的rdb快照文件用的工具,它可以把rdb快照文件生成json文件或者生成报表用来分析Redis的使用详情。

      如何处理大key?

      大key处理

      • 删除大key

        • 当Redis版本大于4.0时,可使用UNLINK命令安全地删除大Key,该命令能够以非阻塞的方式,逐步地清理传入的Key。
        • 当Redis版本小于4.0时,避免使用阻塞式命令KEYS,而是建议通过SCAN命令执行增量迭代扫描key,然后判断进行删除。
      • 压缩和拆分key

        • 当vaule是string时,比较难拆分,则使用序列化、压缩算法将key的大小控制在合理范围内,但是序列化和反序列化都会带来更多时间上的消耗。
        • 当value是string,压缩之后仍然是大key,则需要进行拆分,一个大key分为不同的部分,记录每个部分的key,使用multiget等操作实现事务读取。
        • 当value是list/set等集合类型时,根据预估的数据规模来进行分片,不同的元素计算后分到不同的片。

      39.Redis常见性能问题和解决方案?

      1. Master 最好不要做任何持久化工作,包括内存快照和 AOF 日志文件,特别是不要启用内存快照做持久化。
      2. 如果数据比较关键,某个 Slave 开启 AOF 备份数据,策略为每秒同步一次。
      3. 为了主从复制的速度和连接的稳定性,Slave 和 Master 最好在同一个局域网内。
      4. 尽量避免在压力较大的主库上增加从库。
      5. Master 调用 BGREWRITEAOF 重写 AOF 文件,AOF 在重写的时候会占大量的 CPU 和内存资源,导致服务 load 过高,出现短暂服务暂停现象。
      6. 为了 Master 的稳定性,主从复制不要用图状结构,用单向链表结构更稳定,即主从关为:Master<–Slave1<–Slave2<–Slave3…,这样的结构也方便解决单点故障问题,实现 Slave 对 Master 的替换,也即,如果 Master 挂了,可以立马启用 Slave1 做 Master,其他不变。

      Redis应用

      40.使用Redis 如何实现异步队列?

      我们知道redis支持很多种结构的数据,那么如何使用redis作为异步队列使用呢? 一般有以下几种方式:

      • 使用list作为队列,lpush生产消息,rpop消费消息

      这种方式,消费者死循环rpop从队列中消费消息。但是这样,即使队列里没有消息,也会进行rpop,会导致Redis CPU的消耗。 list作为队列 可以通过让消费者休眠的方式的方式来处理,但是这样又会又消息的延迟问题。

      -使用list作为队列,lpush生产消息,brpop消费消息

      brpop是rpop的阻塞版本,list为空的时候,它会一直阻塞,直到list中有值或者超时。 list作为队列,brpop

      这种方式只能实现一对一的消息队列。

      • 使用Redis的pub/sub来进行消息的发布/订阅

      发布/订阅模式可以1:N的消息发布/订阅。发布者将消息发布到指定的频道频道(channel),订阅相应频道的客户端都能收到消息。

      pub/sub 但是这种方式不是可靠的,它不保证订阅者一定能收到消息,也不进行消息的存储。

      所以,一般的异步队列的实现还是交给专业的消息队列。

      41.Redis 如何实现延时队列?

      • 使用zset,利用排序实现

      可以使用 zset这个结构,用设置好的时间戳作为score进行排序,使用 zadd score1 value1 ....命令就可以一直往内存中生产消息。再利用 zrangebysocre 查询符合条件的所有待处理的任务,通过循环执行队列任务即可。 zset实现延时队列

      42.Redis 支持事务吗?

      Redis提供了简单的事务,但它对事务ACID的支持并不完备。

      multi命令代表事务开始,exec命令代表事务结束,它们之间的命令是原子顺序执行的:

      127.0.0.1:6379> multi 
       OK
       127.0.0.1:6379> sadd user:a:follow user:b 
       QUEUED 
      @@ -87,6 +87,6 @@ OK
       (integer) 1
       

      但是以上逻辑还有问题。如果在 setnx 和 expire 之间服务器进程突然挂掉了,可能是因为机器掉电或者是被人为杀掉的,就会导致 expire 得不到执行,也会造成死锁。

      这种问题的根源就在于 setnx 和 expire 是两条指令而不是原子指令。如果这两条指令可以一起执行就不会出现问题。

      • V3:set指令

      这个问题在Redis 2.8 版本中得到了解决,这个版本加入了 set 指令的扩展参数,使得 setnx 和expire 指令可以一起执行。 set原子指令

      set lock:fighter3 true ex 5 nx OK ... do something critical ... > del lock:codehole
       

      上面这个指令就是 setnx 和 expire 组合在一起的原子指令,这个就算是比较完善的分布式锁了。

      当然实际的开发,没人会去自己写分布式锁的命令,因为有专业的轮子——Redisson

      底层结构

      这一部分就比较深了,如果不是简历上写了精通Redis,应该不会怎么问。

      46.说说Redis底层数据结构?

      Redis有动态字符串(sds)链表(list)字典(ht)跳跃表(skiplist)整数集合(intset)压缩列表(ziplist) 等底层数据结构。

      Redis并没有使用这些数据结构来直接实现键值对数据库,而是基于这些数据结构创建了一个对象系统,来表示所有的key-value。

      redisObject对应的映射 我们常用的数据类型和编码对应的映射关系:

      类型-编码-结构 简单看一下底层数据结构,如果对数据结构掌握不错的话,理解这些结构应该不是特别难:

      1. 字符串:redis没有直接使⽤C语⾔传统的字符串表示,⽽是⾃⼰实现的叫做简单动态字符串SDS的抽象类型。

        C语⾔的字符串不记录⾃身的⻓度信息,⽽SDS则保存了⻓度信息,这样将获取字符串⻓度的时间由O(N)降低到了O(1),同时可以避免缓冲区溢出和减少修改字符串⻓度时所需的内存重分配次数。

      SDS

      1. 链表linkedlist:redis链表是⼀个双向⽆环链表结构,很多发布订阅、慢查询、监视器功能都是使⽤到了链表来实现,每个链表的节点由⼀个listNode结构来表示,每个节点都有指向前置节点和后置节点的指针,同时表头节点的前置和后置节点都指向NULL。

      链表linkedlist

      1. 字典dict:⽤于保存键值对的抽象数据结构。Redis使⽤hash表作为底层实现,一个哈希表里可以有多个哈希表节点,而每个哈希表节点就保存了字典里中的一个键值对。 每个字典带有两个hash表,供平时使⽤和rehash时使⽤,hash表使⽤链地址法来解决键冲突,被分配到同⼀个索引位置的多个键值对会形成⼀个单向链表,在对hash表进⾏扩容或者缩容的时候,为了服务的可⽤性,rehash的过程不是⼀次性完成的,⽽是渐进式的。 字典

      2. 跳跃表skiplist:跳跃表是有序集合的底层实现之⼀,Redis中在实现有序集合键和集群节点的内部结构中都是⽤到了跳跃表。Redis跳跃表由zskiplist和zskiplistNode组成,zskiplist⽤于保存跳跃表信息(表头、表尾节点、⻓度等),zskiplistNode⽤于表示表跳跃节点,每个跳跃表节点的层⾼都是1-32的随机数,在同⼀个跳跃表中,多个节点可以包含相同的分值,但是每个节点的成员对象必须是唯⼀的,节点按照分值⼤⼩排序,如果分值相同,则按照成员对象的⼤⼩排序。 跳跃表

      3. 整数集合intset:⽤于保存整数值的集合抽象数据结构,不会出现重复元素,底层实现为数组。 整数集合intset

      4. 压缩列表ziplist:压缩列表是为节约内存⽽开发的顺序性数据结构,它可以包含任意多个节点,每个节点可以保存⼀个字节数组或者整数值。

      压缩列表组成

      47.Redis 的 SDS 和 C 中字符串相比有什么优势?

      C 语言使用了一个长度为 N+1 的字符数组来表示长度为 N 的字符串,并且字符数组最后一个元素总是 \0,这种简单的字符串表示方式 不符合 Redis 对字符串在安全性、效率以及功能方面的要求。

      C语言的字符串

      C语言的字符串可能有什么问题?

      这样简单的数据结构可能会造成以下一些问题:

      • 获取字符串长度复杂度高 :因为 C 不保存数组的长度,每次都需要遍历一遍整个数组,时间复杂度为O(n);
      • 不能杜绝 缓冲区溢出/内存泄漏 的问题 : C字符串不记录自身长度带来的另外一个问题是容易造成缓存区溢出(buffer overflow),例如在字符串拼接的时候,新的
      • C 字符串 只能保存文本数据 → 因为 C 语言中的字符串必须符合某种编码(比如 ASCII),例如中间出现的 '\0' 可能会被判定为提前结束的字符串而识别不了;

      Redis如何解决?优势?

      Redis sds

      简单来说一下 Redis 如何解决的:

      1. 多增加 len 表示当前字符串的长度:这样就可以直接获取长度了,复杂度 O(1);
      2. 自动扩展空间:当 SDS 需要对字符串进行修改时,首先借助于 lenalloc 检查空间是否满足修改所需的要求,如果空间不够的话,SDS 会自动扩展空间,避免了像 C 字符串操作中的溢出情况;
      3. 有效降低内存分配次数:C 字符串在涉及增加或者清除操作时会改变底层数组的大小造成重新分配,SDS 使用了 空间预分配惰性空间释放 机制,简单理解就是每次在扩展时是成倍的多分配的,在缩容是也是先留着并不正式归还给 OS;
      4. 二进制安全:C 语言字符串只能保存 ascii 码,对于图片、音频等信息无法保存,SDS 是二进制安全的,写入什么读取就是什么,不做任何过滤和限制;

      48.字典是如何实现的?Rehash 了解吗?

      字典是 Redis 服务器中出现最为频繁的复合型数据结构。除了 hash 结构的数据会用到字典外,整个 Redis 数据库的所有 keyvalue 也组成了一个 全局字典,还有带过期时间的 key 也是一个字典。(存储在 RedisDb 数据结构中)

      字典结构是什么样的呢?

      Redis 中的字典相当于 Java 中的 HashMap,内部实现也差不多类似,采用哈希与运算计算下标位置;通过 "数组 + 链表" 链地址法 来解决哈希冲突,同时这样的结构也吸收了两种不同数据结构的优点。 Redis字典结构

      字典是怎么扩容的?

      字典结构内部包含 两个 hashtable,通常情况下只有一个哈希表 ht[0] 有值,在扩容的时候,把ht[0]里的值rehash到ht[1],然后进行 渐进式rehash ——所谓渐进式rehash,指的是这个rehash的动作并不是一次性、集中式地完成的,而是分多次、渐进式地完成的。

      待搬迁结束后,h[1]就取代h[0]存储字典的元素。

      49.跳跃表是如何实现的?原理?

      PS:跳跃表是比较常问的一种结构。

      跳跃表(skiplist)是一种有序数据结构,它通过在每个节点中维持多个指向其它节点的指针,从而达到快速访问节点的目的。 跳跃表

      为什么使用跳跃表?

      首先,因为 zset 要支持随机的插入和删除,所以它 不宜使用数组来实现,关于排序问题,我们也很容易就想到 红黑树/ 平衡树 这样的树形结构,为什么 Redis 不使用这样一些结构呢?

      1. 性能考虑: 在高并发的情况下,树形结构需要执行一些类似于 rebalance 这样的可能涉及整棵树的操作,相对来说跳跃表的变化只涉及局部;
      2. 实现考虑: 在复杂度与红黑树相同的情况下,跳跃表实现起来更简单,看起来也更加直观;

      基于以上的一些考虑,Redis 基于 William Pugh 的论文做出一些改进后采用了 跳跃表 这样的结构。

      本质是解决查找问题。

      跳跃表是怎么实现的?

      跳跃表的节点里有这些元素:

      • 跳跃表节点的level数组可以包含多个元素,每个元素都包含一个指向其它节点的指针,程序可以通过这些层来加快访问其它节点的速度,一般来说,层的数量月多,访问其它节点的速度就越快。

        每次创建一个新的跳跃表节点的时候,程序都根据幂次定律,随机生成一个介于1和32之间的值作为level数组的大小,这个大小就是层的“高度”

      • 前进指针 每个层都有一个指向表尾的前进指针(level[i].forward属性),用于从表头向表尾方向访问节点。

        我们看一下跳跃表从表头到表尾,遍历所有节点的路径: 通过前进指针遍历

      • 跨度 层的跨度用于记录两个节点之间的距离。跨度是用来计算排位(rank)的:在查找某个节点的过程中,将沿途访问过的所有层的跨度累计起来,得到的结果就是目标节点在跳跃表中的排位。

        例如查找,分值为3.0、成员对象为o3的节点时,沿途经历的层:查找的过程只经过了一个层,并且层的跨度为3,所以目标节点在跳跃表中的排位为3。 计算节点的排位

      • 分值和成员 节点的分值(score属性)是一个double类型的浮点数,跳跃表中所有的节点都按分值从小到大来排序。

        节点的成员对象(obj属性)是一个指针,它指向一个字符串对象,而字符串对象则保存这一个SDS值。

      50.压缩列表了解吗?

      压缩列表是 Redis 为了节约内存 而使用的一种数据结构,是由一系列特殊编码的连续内存快组成的顺序型数据结构。

      一个压缩列表可以包含任意多个节点(entry),每个节点可以保存一个字节数组或者一个整数值。

      压缩列表组成部分压缩列表由这么几部分组成:

      • zlbyttes:记录整个压缩列表占用的内存字节数
      • zltail:记录压缩列表表尾节点距离压缩列表的起始地址有多少字节
      • zllen:记录压缩列表包含的节点数量
      • entryX:列表节点
      • zlend:用于标记压缩列表的末端

      压缩列表示例

      51.快速列表 quicklist 了解吗?

      Redis 早期版本存储 list 列表数据结构使用的是压缩列表 ziplist 和普通的双向链表 linkedlist,也就是说当元素少时使用 ziplist,当元素多时用 linkedlist。

      但考虑到链表的附加空间相对较高,prevnext 指针就要占去 16 个字节(64 位操作系统占用 8 个字节),另外每个节点的内存都是单独分配,会家具内存的碎片化,影响内存管理效率。

      后来 Redis 新版本(3.2)对列表数据结构进行了改造,使用 quicklist 代替了 ziplistlinkedlist,quicklist是综合考虑了时间效率与空间效率引入的新型数据结构。

      quicklist由list和ziplist结合而成,它是一个由ziplist充当节点的双向链表。 quicklist

      其他问题

      52.假如Redis里面有1亿个key,其中有10w个key是以某个固定的已知的前缀开头的,如何将它们全部找出来?

      使用 keys 指令可以扫出指定模式的 key 列表。但是要注意 keys 指令会导致线程阻塞一段时间,线上服务会停顿,直到指令执行完毕,服务才能恢复。这个时候可以使用 scan 指令,scan 指令可以无阻塞的提取出指定模式的 key 列表,但是会有一定的重复概率,在客户端做一次去重就可以了,但是整体所花费的时间会比直接用 keys 指令长。


      图文详解 53 道Redis面试高频题,这次吊打面试官,我觉得稳了(手动 dog)。整理:沉默王二,戳转载链接open in new window,作者:三分恶,戳原文链接open in new window

      - + diff --git a/dist/sidebar/sanfene/spring.html b/dist/sidebar/sanfene/spring.html index 3fd8fd87..3acbe7fe 100644 --- a/dist/sidebar/sanfene/spring.html +++ b/dist/sidebar/sanfene/spring.html @@ -39,10 +39,10 @@ } - + -

      面渣逆袭(Spring)必看👍

      沉默王二2022年4月21日
      • 面渣逆袭
      • Spring
      大约 54 分钟

      面渣逆袭(Spring)必看👍

      图文详解 35 道Spring面试高频题,这次吊打面试官,我觉得稳了(手动 dog)。整理:沉默王二,戳转载链接open in new window,作者:三分恶,戳原文链接open in new window

      基础

      1.Spring 是什么?特性?有哪些模块?

      Spring Logo

      一句话概括:Spring 是一个轻量级、非入侵式的控制反转 (IoC) 和面向切面 (AOP) 的框架。

      2003 年,一个音乐家 Rod Johnson 决定发展一个轻量级的 Java 开发框架,Spring作为 Java 战场的龙骑兵渐渐崛起,并淘汰了EJB这个传统的重装骑兵。

      Spring重要版本

      到了现在,企业级开发的标配基本就是 Spring5 + Spring Boot 2 + JDK 8

      Spring 有哪些特性呢?

      Spring 有很多优点:

      Spring特性

      1. IOCDI 的支持

      Spring 的核心就是一个大的工厂容器,可以维护所有对象的创建和依赖关系,Spring 工厂用于生成 Bean,并且管理 Bean 的生命周期,实现高内聚低耦合的设计理念。

      1. AOP 编程的支持

      Spring 提供了面向切面编程,可以方便的实现对程序进行权限拦截、运行监控等切面功能。

      1. 声明式事务的支持

      支持通过配置就来完成对事务的管理,而不需要通过硬编码的方式,以前重复的一些事务提交、回滚的 JDBC 代码,都可以不用自己写了。

      1. 快捷测试的支持

      Spring 对 Junit 提供支持,可以通过注解快捷地测试 Spring 程序。

      1. 快速集成功能

      方便集成各种优秀框架,Spring 不排斥各种优秀的开源框架,其内部提供了对各种优秀框架(如:Struts、Hibernate、MyBatis、Quartz 等)的直接支持。

      1. 复杂 API 模板封装

      Spring 对 JavaEE 开发中非常难用的一些 API(JDBC、JavaMail、远程调用等)都提供了模板化的封装,这些封装 API 的提供使得应用难度大大降低。

      2.Spring 有哪些模块呢?

      Spring 框架是分模块存在,除了最核心的Spring Core Container是必要模块之外,其他模块都是可选,大约有 20 多个模块。

      Spring模块划分

      最主要的七大模块:

      1. Spring Core:Spring 核心,它是框架最基础的部分,提供 IOC 和依赖注入 DI 特性。
      2. Spring Context:Spring 上下文容器,它是 BeanFactory 功能加强的一个子接口。
      3. Spring Web:它提供 Web 应用开发的支持。
      4. Spring MVC:它针对 Web 应用中 MVC 思想的实现。
      5. Spring DAO:提供对 JDBC 抽象层,简化了 JDBC 编码,同时,编码更具有健壮性。
      6. Spring ORM:它支持用于流行的 ORM 框架的整合,比如:Spring + Hibernate、Spring + iBatis、Spring + JDO 的整合等。
      7. Spring AOP:即面向切面编程,它提供了与 AOP 联盟兼容的编程实现。

      3.Spring 有哪些常用注解呢?

      Spring 有很多模块,甚至广义的 SpringBoot、SpringCloud 也算是 Spring 的一部分,我们来分模块,按功能来看一下一些常用的注解:

      Spring常用注解

      Web:

      • @Controller:组合注解(组合了@Component 注解),应用在 MVC 层(控制层)。
      • @RestController:该注解为一个组合注解,相当于@Controller 和@ResponseBody 的组合,注解在类上,意味着,该 Controller 的所有方法都默认加上了@ResponseBody。
      • @RequestMapping:用于映射 Web 请求,包括访问路径和参数。如果是 Restful 风格接口,还可以根据请求类型使用不同的注解:
        • @GetMapping
        • @PostMapping
        • @PutMapping
        • @DeleteMapping
      • @ResponseBody:支持将返回值放在 response 内,而不是一个页面,通常用户返回 json 数据。
      • @RequestBody:允许 request 的参数在 request 体中,而不是在直接连接在地址后面。
      • @PathVariable:用于接收路径参数,比如 @RequestMapping(“/hello/{name}”)申明的路径,将注解放在参数中前,即可获取该值,通常作为 Restful 的接口实现方法。
      • @RestController:该注解为一个组合注解,相当于@Controller 和@ResponseBody 的组合,注解在类上,意味着,该 Controller 的所有方法都默认加上了@ResponseBody。

      容器:

      • @Component:表示一个带注释的类是一个“组件”,成为 Spring 管理的 Bean。当使用基于注解的配置和类路径扫描时,这些类被视为自动检测的候选对象。同时@Component 还是一个元注解。
      • @Service:组合注解(组合了@Component 注解),应用在 service 层(业务逻辑层)。
      • @Repository:组合注解(组合了@Component 注解),应用在 dao 层(数据访问层)。
      • @Autowired:Spring 提供的工具(由 Spring 的依赖注入工具(BeanPostProcessor、BeanFactoryPostProcessor)自动注入)。
      • @Qualifier:该注解通常跟 @Autowired 一起使用,当想对注入的过程做更多的控制,@Qualifier 可帮助配置,比如两个以上相同类型的 Bean 时 Spring 无法抉择,用到此注解
      • @Configuration:声明当前类是一个配置类(相当于一个 Spring 配置的 xml 文件)
      • @Value:可用在字段,构造器参数跟方法参数,指定一个默认值,支持 #{} 跟 \${} 两个方式。一般将 SpringbBoot 中的 application.properties 配置的属性值赋值给变量。
      • @Bean:注解在方法上,声明当前方法的返回值为一个 Bean。返回的 Bean 对应的类中可以定义 init()方法和 destroy()方法,然后在@Bean(initMethod=”init”,destroyMethod=”destroy”)定义,在构造之后执行 init,在销毁之前执行 destroy。
      • @Scope:定义我们采用什么模式去创建 Bean(方法上,得有@Bean) 其设置类型包括:Singleton 、Prototype、Request 、 Session、GlobalSession。

      AOP:

      • @Aspect:声明一个切面(类上) 使用@After、@Before、@Around 定义建言(advice),可直接将拦截规则(切点)作为参数。
        • @After :在方法执行之后执行(方法上)。
        • @Before: 在方法执行之前执行(方法上)。
        • @Around: 在方法执行之前与之后执行(方法上)。
        • @PointCut: 声明切点 在 java 配置类中使用@EnableAspectJAutoProxy 注解开启 Spring 对 AspectJ 代理的支持(类上)。

      事务:

      • @Transactional:在要开启事务的方法上使用@Transactional 注解,即可声明式开启事务。

      4.Spring 中应用了哪些设计模式呢?

      Spring 框架中广泛使用了不同类型的设计模式,下面我们来看看到底有哪些设计模式?

      Spring中用到的设计模式

      1. 工厂模式 : Spring 容器本质是一个大工厂,使用工厂模式通过 BeanFactory、ApplicationContext 创建 bean 对象。
      2. 代理模式 : Spring AOP 功能功能就是通过代理模式来实现的,分为动态代理和静态代理。
      3. 单例模式 : Spring 中的 Bean 默认都是单例的,这样有利于容器对 Bean 的管理。
      4. 模板模式 : Spring 中 JdbcTemplate、RestTemplate 等以 Template 结尾的对数据库、网络等等进行操作的模板类,就使用到了模板模式。
      5. 观察者模式: Spring 事件驱动模型就是观察者模式很经典的一个应用。
      6. 适配器模式 :Spring AOP 的增强或通知 (Advice) 使用到了适配器模式、Spring MVC 中也是用到了适配器模式适配 Controller。
      7. 策略模式:Spring 中有一个 Resource 接口,它的不同实现类,会根据不同的策略去访问资源。

      IOC

      5.说一说什么是 IOC?什么是 DI?

      Java 是面向对象的编程语言,一个个实例对象相互合作组成了业务逻辑,原来,我们都是在代码里创建对象和对象的依赖。

      所谓的IOC(控制反转):就是由容器来负责控制对象的生命周期和对象间的关系。以前是我们想要什么,就自己创建什么,现在是我们需要什么,容器就给我们送来什么。

      引入IOC之前和引入IOC之后

      也就是说,控制对象生命周期的不再是引用它的对象,而是容器。对具体对象,以前是它控制其它对象,现在所有对象都被容器控制,所以这就叫控制反转

      控制反转示意图

      DI(依赖注入):指的是容器在实例化对象的时候把它依赖的类注入给它。有的说法 IOC 和 DI 是一回事,有的说法是 IOC 是思想,DI 是 IOC 的实现。

      为什么要使用 IOC 呢?

      最主要的是两个字解耦,硬编码会造成对象间的过度耦合,使用 IOC 之后,我们可以不用关心对象间的依赖,专心开发应用就行。

      6.能简单说一下 Spring IOC 的实现机制吗?

      PS:这道题老三在面试中被问到过,问法是“你有自己实现过简单的 Spring 吗?

      Spring 的 IOC 本质就是一个大工厂,我们想想一个工厂是怎么运行的呢?

      工厂运行

      • 生产产品:一个工厂最核心的功能就是生产产品。在 Spring 里,不用 Bean 自己来实例化,而是交给 Spring,应该怎么实现呢?——答案毫无疑问,反射

        那么这个厂子的生产管理是怎么做的?你应该也知道——工厂模式

      • 库存产品:工厂一般都是有库房的,用来库存产品,毕竟生产的产品不能立马就拉走。Spring 我们都知道是一个容器,这个容器里存的就是对象,不能每次来取对象,都得现场来反射创建对象,得把创建出的对象存起来。

      • 订单处理:还有最重要的一点,工厂根据什么来提供产品呢?订单。这些订单可能五花八门,有线上签签的、有到工厂签的、还有工厂销售上门签的……最后经过处理,指导工厂的出货。

        在 Spring 里,也有这样的订单,它就是我们 bean 的定义和依赖关系,可以是 xml 形式,也可以是我们最熟悉的注解形式。

      我们简单地实现一个 mini 版的 Spring IOC:

      mini版本Spring IOC

      Bean 定义:

      Bean 通过一个配置文件定义,把它解析成一个类型。

    • 运行结果

    运行结果

    至此,随手写的一个自定义 SpringBoot-Starter 就完成了,虽然比较简单,但是完成了主要的自动装配的能力。

    34.Springboot 启动原理?

    SpringApplication 这个类主要做了以下四件事情:

    1. 推断应用的类型是普通的项目还是 Web 项目
    2. 查找并加载所有可用初始化器 , 设置到 initializers 属性中
    3. 找出所有的应用程序监听器,设置到 listeners 属性中
    4. 推断并设置 main 方法的定义类,找到运行的主类

    SpringBoot 启动大致流程如下 :

    SpringBoot 启动大致流程-图片来源网络

    Spring Cloud

    35.对 SpringCloud 了解多少?

    SpringCloud 是 Spring 官方推出的微服务治理框架。

    Spring Cloud Netfilx核心组件-来源参考[2]

    什么是微服务?

    1. 2014 年 Martin Fowler 提出的一种新的架构形式。微服务架构是一种架构模式,提倡将单一应用程序划分成一组小的服务,服务之间相互协调,互相配合,为用户提供最终价值。每个服务运行在其独立的进程中,服务与服务之间采用轻量级的通信机制(如 HTTP 或 Dubbo)互相协作,每个服务都围绕着具体的业务进行构建,并且能够被独立的部署到生产环境中,另外,应尽量避免统一的,集中式的服务管理机制,对具体的一个服务而言,应根据业务上下文,选择合适的语言、工具(如 Maven)对其进行构建。
    2. 微服务化的核心就是将传统的一站式应用,根据业务拆分成一个一个的服务,彻底地去耦合,每一个微服务提供单个业务功能的服务,一个服务做一件事情,从技术角度看就是一种小而独立的处理过程,类似进程的概念,能够自行单独启动或销毁,拥有自己独立的数据库。

    微服务架构主要要解决哪些问题?

    1. 服务很多,客户端怎么访问,如何提供对外网关?
    2. 这么多服务,服务之间如何通信? HTTP 还是 RPC?
    3. 这么多服务,如何治理? 服务的注册和发现。
    4. 服务挂了怎么办?熔断机制。

    有哪些主流微服务框架?

    1. Spring Cloud Netflix
    2. Spring Cloud Alibaba
    3. SpringBoot + Dubbo + ZooKeeper

    SpringCloud 有哪些核心组件?

    SpringCloud

    PS:微服务后面有机会再扩展,其实面试一般都是结合项目去问。

    图文详解 35 道Spring面试高频题,这次吊打面试官,我觉得稳了(手动 dog)。整理:沉默王二,戳转载链接open in new window,作者:三分恶,戳原文链接open in new window

    - + diff --git a/dist/sitemap.xml b/dist/sitemap.xml index d8305bd8..19e3a80c 100644 --- a/dist/sitemap.xml +++ b/dist/sitemap.xml @@ -1 +1 @@ -https://tobebetterjavaer.com/2022-06-07T12:38:47.000Zhttps://tobebetterjavaer.com/home.html2022-06-08T06:51:04.000Zhttps://tobebetterjavaer.com/array/array.html2022-03-29T01:56:53.000Zhttps://tobebetterjavaer.com/array/print.html2022-05-13T23:14:28.000Zhttps://tobebetterjavaer.com/about-the-author/bzhan-10wan.html2022-05-12T08:24:21.000Zhttps://tobebetterjavaer.com/about-the-author/csdn-1000wan.html2022-05-12T08:24:21.000Zhttps://tobebetterjavaer.com/about-the-author/2022-05-12T08:24:21.000Zhttps://tobebetterjavaer.com/about-the-author/zhihu-1000wan.html2022-05-12T08:24:21.000Zhttps://tobebetterjavaer.com/baguwen/java-basic-34.html2022-05-12T08:24:21.000Zhttps://tobebetterjavaer.com/baguwen/java-basic.html2022-05-13T23:14:28.000Zhttps://tobebetterjavaer.com/baguwen/java-thread.html2022-05-13T23:14:28.000Zhttps://tobebetterjavaer.com/baguwen/jvm.html2022-05-13T23:14:28.000Zhttps://tobebetterjavaer.com/basic-grammar/basic-data-type.html2022-05-13T23:14:28.000Zhttps://tobebetterjavaer.com/basic-grammar/flow-control.html2022-05-13T23:14:28.000Zhttps://tobebetterjavaer.com/basic-grammar/javadoc.html2022-05-13T23:14:28.000Zhttps://tobebetterjavaer.com/basic-grammar/operator.html2022-05-13T23:14:28.000Zhttps://tobebetterjavaer.com/cityselect/beijing.html2022-05-13T23:14:28.000Zhttps://tobebetterjavaer.com/cityselect/chengdu.html2022-05-13T23:14:28.000Zhttps://tobebetterjavaer.com/cityselect/guangzhou.html2022-05-13T23:14:28.000Zhttps://tobebetterjavaer.com/cityselect/hangzhou.html2022-05-13T23:14:28.000Zhttps://tobebetterjavaer.com/cityselect/nanjing.html2022-05-13T23:14:28.000Zhttps://tobebetterjavaer.com/cityselect/qingdao.html2022-05-13T23:14:28.000Zhttps://tobebetterjavaer.com/cityselect/shenzhen.html2022-05-13T23:14:28.000Zhttps://tobebetterjavaer.com/cityselect/suzhou.html2022-05-13T23:14:28.000Zhttps://tobebetterjavaer.com/cityselect/xian.html2022-05-13T23:14:28.000Zhttps://tobebetterjavaer.com/cityselect/zhengzhou.html2022-05-13T23:14:28.000Zhttps://tobebetterjavaer.com/collection/arraylist.html2022-05-13T23:14:28.000Zhttps://tobebetterjavaer.com/collection/fail-fast.html2022-05-13T23:14:28.000Zhttps://tobebetterjavaer.com/collection/gailan.html2022-05-13T23:14:28.000Zhttps://tobebetterjavaer.com/collection/hashmap-interview.html2022-05-13T23:14:28.000Zhttps://tobebetterjavaer.com/collection/hashmap.html2022-06-06T15:31:27.000Zhttps://tobebetterjavaer.com/collection/iterator-iterable.html2022-05-13T23:14:28.000Zhttps://tobebetterjavaer.com/collection/linkedlist.html2022-05-13T23:14:28.000Zhttps://tobebetterjavaer.com/collection/list-war-2.html2022-05-13T23:14:28.000Zhttps://tobebetterjavaer.com/basic-extra-meal/48-keywords.html2022-04-13T08:53:39.000Zhttps://tobebetterjavaer.com/basic-extra-meal/Overriding.html2022-05-13T23:14:28.000Zhttps://tobebetterjavaer.com/basic-extra-meal/annotation.html2022-05-13T23:14:28.000Zhttps://tobebetterjavaer.com/basic-extra-meal/box.html2022-05-13T23:14:28.000Zhttps://tobebetterjavaer.com/basic-extra-meal/class-object.html2022-05-12T08:24:21.000Zhttps://tobebetterjavaer.com/basic-extra-meal/comparable-omparator.html2022-05-13T23:14:28.000Zhttps://tobebetterjavaer.com/basic-extra-meal/deep-copy.html2022-05-31T09:56:13.000Zhttps://tobebetterjavaer.com/basic-extra-meal/enum.html2022-05-13T23:14:28.000Zhttps://tobebetterjavaer.com/basic-extra-meal/equals-hashcode.html2022-05-13T23:14:28.000Zhttps://tobebetterjavaer.com/basic-extra-meal/fanshe.html2022-05-13T23:14:28.000Zhttps://tobebetterjavaer.com/basic-extra-meal/generic.html2022-05-13T23:14:28.000Zhttps://tobebetterjavaer.com/basic-extra-meal/hashcode.html2022-05-13T23:14:28.000Zhttps://tobebetterjavaer.com/basic-extra-meal/immutable.html2022-06-06T15:31:27.000Zhttps://tobebetterjavaer.com/basic-extra-meal/instanceof-jvm.html2022-05-12T08:24:21.000Zhttps://tobebetterjavaer.com/basic-extra-meal/int-cache.html2022-05-13T23:14:28.000Zhttps://tobebetterjavaer.com/basic-extra-meal/java-naming.html2022-05-13T23:14:28.000Zhttps://tobebetterjavaer.com/basic-extra-meal/java-unicode.html2022-05-13T23:14:28.000Zhttps://tobebetterjavaer.com/basic-extra-meal/jdk-while-for-wuxian-xunhuan.html2022-05-13T23:14:28.000Zhttps://tobebetterjavaer.com/basic-extra-meal/jdk9-char-byte-string.html2022-05-13T23:14:28.000Zhttps://tobebetterjavaer.com/basic-extra-meal/override-overload.html2022-05-13T23:14:28.000Zhttps://tobebetterjavaer.com/basic-extra-meal/pass-by-value.html2022-05-13T23:14:28.000Zhttps://tobebetterjavaer.com/basic-extra-meal/true-generic.html2022-05-13T23:14:28.000Zhttps://tobebetterjavaer.com/basic-extra-meal/varables.html2022-05-13T23:14:28.000Zhttps://tobebetterjavaer.com/common-tool/arrays.html2022-05-13T23:14:28.000Zhttps://tobebetterjavaer.com/common-tool/collections.html2022-05-13T23:14:28.000Zhttps://tobebetterjavaer.com/common-tool/guava.html2022-05-13T23:14:28.000Zhttps://tobebetterjavaer.com/common-tool/hutool.html2022-05-12T08:24:21.000Zhttps://tobebetterjavaer.com/cs/os.html2022-05-29T01:05:54.000Zhttps://tobebetterjavaer.com/cs/wangluo.html2022-05-12T08:24:21.000Zhttps://tobebetterjavaer.com/download/bat-shuati.html2022-03-18T02:19:22.000Zhttps://tobebetterjavaer.com/download/history.html2022-06-07T02:26:02.000Zhttps://tobebetterjavaer.com/download/java.html2022-05-12T08:24:21.000Zhttps://tobebetterjavaer.com/download/jianli.html2022-05-12T08:24:21.000Zhttps://tobebetterjavaer.com/download/learn-jianyi.html2022-04-21T12:29:07.000Zhttps://tobebetterjavaer.com/download/nicearticle.html2022-04-19T04:15:34.000Zhttps://tobebetterjavaer.com/download/pdf.html2022-04-20T00:59:56.000Zhttps://tobebetterjavaer.com/download/progit.html2022-05-12T08:24:21.000Zhttps://tobebetterjavaer.com/download/yuanyifeng-c-language.html2022-03-18T02:19:22.000Zhttps://tobebetterjavaer.com/elasticsearch/rumen.html2022-05-13T23:14:28.000Zhttps://tobebetterjavaer.com/exception/gailan.html2022-05-12T08:24:21.000Zhttps://tobebetterjavaer.com/exception/npe.html2022-05-13T23:14:28.000Zhttps://tobebetterjavaer.com/exception/shijian.html2022-05-13T23:14:28.000Zhttps://tobebetterjavaer.com/exception/try-with-resouces.html2022-05-13T23:14:28.000Zhttps://tobebetterjavaer.com/git/git-qiyuan.html2022-06-08T06:51:04.000Zhttps://tobebetterjavaer.com/git/progit.html2022-05-12T08:24:21.000Zhttps://tobebetterjavaer.com/gongju/Chocolatey-Homebrew.html2022-05-09T06:49:16.000Zhttps://tobebetterjavaer.com/gongju/DBeaver.html2022-05-24T09:00:49.000Zhttps://tobebetterjavaer.com/gongju/chiner.html2022-05-24T09:00:49.000Zhttps://tobebetterjavaer.com/gongju/choco.html2022-05-24T09:00:49.000Zhttps://tobebetterjavaer.com/gongju/fastjson.html2022-05-24T09:00:49.000Zhttps://tobebetterjavaer.com/gongju/forest.html2022-05-24T09:00:49.000Zhttps://tobebetterjavaer.com/gongju/gson.html2022-05-24T09:00:49.000Zhttps://tobebetterjavaer.com/gongju/jackson.html2022-05-24T09:00:49.000Zhttps://tobebetterjavaer.com/gongju/junit.html2022-05-24T09:00:49.000Zhttps://tobebetterjavaer.com/gongju/knife4j.html2022-05-21T16:06:08.000Zhttps://tobebetterjavaer.com/gongju/log4j.html2022-05-24T09:00:49.000Zhttps://tobebetterjavaer.com/gongju/log4j2.html2022-05-24T09:00:49.000Zhttps://tobebetterjavaer.com/gongju/logback.html2022-05-24T09:00:49.000Zhttps://tobebetterjavaer.com/gongju/others.html2022-03-18T02:19:22.000Zhttps://tobebetterjavaer.com/gongju/slf4j.html2022-05-24T09:00:49.000Zhttps://tobebetterjavaer.com/gongju/tabby.html2022-06-07T04:06:44.000Zhttps://tobebetterjavaer.com/gongju/warp.html2022-05-24T09:00:49.000Zhttps://tobebetterjavaer.com/ide/4-debug-skill.html2022-05-12T08:24:21.000Zhttps://tobebetterjavaer.com/io/BIONIOAIO.html2022-05-12T08:24:21.000Zhttps://tobebetterjavaer.com/io/shangtou.html2022-05-13T23:14:28.000Zhttps://tobebetterjavaer.com/java8/Lambda.html2022-05-13T23:14:28.000Zhttps://tobebetterjavaer.com/java8/optional.html2022-05-13T23:14:28.000Zhttps://tobebetterjavaer.com/java8/stream.html2022-05-13T23:14:28.000Zhttps://tobebetterjavaer.com/jvm/asm.html2022-05-13T23:14:28.000Zhttps://tobebetterjavaer.com/jvm/bytecode.html2022-05-13T23:14:28.000Zhttps://tobebetterjavaer.com/jvm/class-file-jiegou.html2022-05-13T23:14:28.000Zhttps://tobebetterjavaer.com/jvm/class-load.html2022-05-13T23:14:28.000Zhttps://tobebetterjavaer.com/jvm/compile-jdk.html2022-05-13T23:14:28.000Zhttps://tobebetterjavaer.com/jvm/cpu-percent-100.html2022-05-12T08:24:21.000Zhttps://tobebetterjavaer.com/jvm/gc.html2022-05-13T23:14:28.000Zhttps://tobebetterjavaer.com/jvm/how-jvm-run-zijiema-zhiling.html2022-05-13T23:14:28.000Zhttps://tobebetterjavaer.com/jvm/how-run-java-code.html2022-05-12T08:24:21.000Zhttps://tobebetterjavaer.com/jvm/hsdb.html2022-05-13T23:14:28.000Zhttps://tobebetterjavaer.com/jvm/jit.html2022-05-13T23:14:28.000Zhttps://tobebetterjavaer.com/jvm/meituan-9-gc.html2022-05-13T23:14:28.000Zhttps://tobebetterjavaer.com/jvm/neicun-jiegou.html2022-05-12T08:24:21.000Zhttps://tobebetterjavaer.com/jvm/oom.html2022-05-12T08:24:21.000Zhttps://tobebetterjavaer.com/jvm/problem-tools.html2022-05-12T08:24:21.000Zhttps://tobebetterjavaer.com/jvm/tujie-gc.html2022-05-12T08:24:21.000Zhttps://tobebetterjavaer.com/jvm/what-happen-when-javac.html2022-05-13T23:14:28.000Zhttps://tobebetterjavaer.com/jvm/what-is-jvm.html2022-05-13T23:14:28.000Zhttps://tobebetterjavaer.com/jvm/whereis-the-object.html2022-05-13T23:14:28.000Zhttps://tobebetterjavaer.com/jvm/zijiema-zhiling.html2022-05-13T23:14:28.000Zhttps://tobebetterjavaer.com/jvm/zongjie.html2022-05-12T08:24:21.000Zhttps://tobebetterjavaer.com/kaiyuan/auto-generator.html2022-05-21T16:06:08.000Zhttps://tobebetterjavaer.com/kaiyuan/2022-03-18T02:19:22.000Zhttps://tobebetterjavaer.com/kaiyuan/yuneban-wangyiyunyinyue.html2022-05-12T08:24:21.000Zhttps://tobebetterjavaer.com/manongshenghuo/waibao-1geyue.html2022-03-03T01:51:15.000Zhttps://tobebetterjavaer.com/manongshenghuo/yanjiusuo-20wan.html2022-05-12T08:24:21.000Zhttps://tobebetterjavaer.com/maven/maven.html2022-06-08T06:51:04.000Zhttps://tobebetterjavaer.com/mianjing/redis12question.html2022-05-13T23:14:28.000Zhttps://tobebetterjavaer.com/mianjing/shanganaliyun.html2022-05-13T23:14:28.000Zhttps://tobebetterjavaer.com/microservice/api-wangguan.html2022-05-21T00:14:16.000Zhttps://tobebetterjavaer.com/mongodb/rumen.html2022-05-13T23:14:28.000Zhttps://tobebetterjavaer.com/mq/100-budiushi.html2022-05-13T23:14:28.000Zhttps://tobebetterjavaer.com/mq/rabbitmq-rumen.html2022-05-13T23:14:28.000Zhttps://tobebetterjavaer.com/mysql/deletedb-binlog-weiguanjishu.html2022-05-12T08:24:21.000Zhttps://tobebetterjavaer.com/mysql/redis-shuju-yizhixing.html2022-05-21T00:14:16.000Zhttps://tobebetterjavaer.com/nginx/40-interview.html2022-05-12T08:24:21.000Zhttps://tobebetterjavaer.com/nginx/nginx.html2022-06-08T06:51:04.000Zhttps://tobebetterjavaer.com/nice-article/BOKEYUANruhegaoxiaodixuexijishu.html2022-05-30T05:41:40.000Zhttps://tobebetterjavaer.com/nice-article/ZHIHUjavaxuexidaoshemechengduokeyizhaodiyifengongzuo.html2022-05-30T05:41:40.000Zhttps://tobebetterjavaer.com/nice-article/bokeyuan-jianxijavazhongdifangwenquanxiankongzhi.html2022-05-31T11:11:41.000Zhttps://tobebetterjavaer.com/nice-article/bokeyuan-ruhegaoxiaodixuexijishu.html2022-05-31T05:30:50.000Zhttps://tobebetterjavaer.com/nice-article/haibukuaiyongmybatisplusshoubashoujiaoni.html2022-05-29T01:05:54.000Zhttps://tobebetterjavaer.com/nice-article/javaxuexidaoshemechengduokeyizhaodiyifengongzuo.html2022-05-30T13:19:41.000Zhttps://tobebetterjavaer.com/nice-article/jiagoushizenyanghuizhijitongjiagoulantu.html2022-05-29T01:05:54.000Zhttps://tobebetterjavaer.com/nice-article/jielehenduosihuodiganchu.html2022-05-29T01:05:54.000Zhttps://tobebetterjavaer.com/nice-article/jishuzongjianbeikaichuliao.html2022-05-29T01:05:54.000Zhttps://tobebetterjavaer.com/nice-article/weixin-chengxwjdwzhqcgxm.html2022-06-08T02:10:51.000Zhttps://tobebetterjavaer.com/nice-article/weixin-liaoliaoxianliu.html2022-06-01T23:41:54.000Zhttps://tobebetterjavaer.com/nice-article/weixin-xinllgjszjszzpojozsyjbsjlxyhjfyll.html2022-06-05T23:36:38.000Zhttps://tobebetterjavaer.com/nice-article/weixin-zhongxcwbztashjjavahdmj.html2022-06-08T02:10:51.000Zhttps://tobebetterjavaer.com/nice-article/weixin-zuixinbujiabandigongsimingdan.html2022-05-30T14:29:10.000Zhttps://tobebetterjavaer.com/oo/abstract.html2022-05-13T23:14:28.000Zhttps://tobebetterjavaer.com/oo/code-init.html2022-05-13T23:14:28.000Zhttps://tobebetterjavaer.com/oo/construct.html2022-05-13T23:14:28.000Zhttps://tobebetterjavaer.com/oo/final.html2022-05-12T08:24:21.000Zhttps://tobebetterjavaer.com/oo/inner-class.html2022-05-17T23:32:53.000Zhttps://tobebetterjavaer.com/oo/instanceof.html2022-05-13T23:14:28.000Zhttps://tobebetterjavaer.com/oo/interface.html2022-05-13T23:14:28.000Zhttps://tobebetterjavaer.com/oo/method.html2022-05-13T23:14:28.000Zhttps://tobebetterjavaer.com/oo/object-class.html2022-05-12T08:24:21.000Zhttps://tobebetterjavaer.com/oo/static.html2022-05-13T23:14:28.000Zhttps://tobebetterjavaer.com/oo/this-super.html2022-05-13T23:14:28.000Zhttps://tobebetterjavaer.com/oo/var.html2022-05-13T23:14:28.000Zhttps://tobebetterjavaer.com/overview/hello-world.html2022-05-13T23:14:28.000Zhttps://tobebetterjavaer.com/overview/what-is-java.html2022-05-13T23:14:28.000Zhttps://tobebetterjavaer.com/redis/redis-springboot.html2022-05-21T16:06:08.000Zhttps://tobebetterjavaer.com/redis/rumen.html2022-05-12T08:24:21.000Zhttps://tobebetterjavaer.com/redis/xuebeng-chuantou-jichuan.html2022-03-31T02:38:06.000Zhttps://tobebetterjavaer.com/shigu/image-yasuo.html2022-05-12T08:24:21.000Zhttps://tobebetterjavaer.com/shigu/log4j2.html2022-05-12T08:24:21.000Zhttps://tobebetterjavaer.com/sidebar/computer-base.html2022-03-09T01:11:11.000Zhttps://tobebetterjavaer.com/springboot/Filter-Interceptor-Listener.html2022-05-21T16:06:08.000Zhttps://tobebetterjavaer.com/springboot/aop-log.html2022-05-12T08:24:21.000Zhttps://tobebetterjavaer.com/springboot/cors.html2022-05-12T08:24:21.000Zhttps://tobebetterjavaer.com/springboot/initializr.html2022-05-21T16:06:08.000Zhttps://tobebetterjavaer.com/springboot/ioc.html2022-05-12T08:24:21.000Zhttps://tobebetterjavaer.com/springboot/jpa.html2022-05-21T16:06:08.000Zhttps://tobebetterjavaer.com/springboot/jwt.html2022-05-12T08:24:21.000Zhttps://tobebetterjavaer.com/springboot/logback.html2022-05-21T16:06:08.000Zhttps://tobebetterjavaer.com/springboot/macos-codingmore-run.html2022-06-08T06:51:04.000Zhttps://tobebetterjavaer.com/springboot/mysql-druid.html2022-05-21T16:06:08.000Zhttps://tobebetterjavaer.com/springboot/oss.html2022-03-22T07:30:06.000Zhttps://tobebetterjavaer.com/springboot/springtask.html2022-05-25T01:33:28.000Zhttps://tobebetterjavaer.com/springboot/swagger.html2022-05-21T16:06:08.000Zhttps://tobebetterjavaer.com/springboot/thymeleaf.html2022-05-21T16:06:08.000Zhttps://tobebetterjavaer.com/springboot/tomcat.html2022-05-12T08:24:21.000Zhttps://tobebetterjavaer.com/springboot/transaction.html2022-05-21T16:06:08.000Zhttps://tobebetterjavaer.com/springboot/windows-codingmore-run.html2022-06-08T06:51:04.000Zhttps://tobebetterjavaer.com/string/constant-pool.html2022-05-12T08:24:21.000Zhttps://tobebetterjavaer.com/string/equals.html2022-05-12T08:24:21.000Zhttps://tobebetterjavaer.com/string/immutable.html2022-03-27T08:36:50.000Zhttps://tobebetterjavaer.com/string/intern.html2022-05-12T08:24:21.000Zhttps://tobebetterjavaer.com/string/join.html2022-03-27T08:36:50.000Zhttps://tobebetterjavaer.com/string/split.html2022-05-12T08:24:21.000Zhttps://tobebetterjavaer.com/szjy/buy-cloud-server.html2022-06-08T06:51:04.000Zhttps://tobebetterjavaer.com/szjy/buy-domain.html2022-06-08T06:51:04.000Zhttps://tobebetterjavaer.com/szjy/https-domain.html2022-06-08T06:51:04.000Zhttps://tobebetterjavaer.com/szjy/install-baota-mianban.html2022-06-08T06:51:04.000Zhttps://tobebetterjavaer.com/szjy/record-domain.html2022-06-08T06:51:04.000Zhttps://tobebetterjavaer.com/szjy/tobebetterjavaer-wangzhan-shangxian.html2022-05-12T08:24:21.000Zhttps://tobebetterjavaer.com/szjy/tupian-zhuanlian.html2022-05-12T08:24:21.000Zhttps://tobebetterjavaer.com/thread/BlockingQueue.html2022-05-12T08:24:21.000Zhttps://tobebetterjavaer.com/thread/ConcurrentHashMap.html2022-05-12T08:24:21.000Zhttps://tobebetterjavaer.com/thread/ConcurrentLinkedQueue.html2022-05-12T08:24:21.000Zhttps://tobebetterjavaer.com/thread/CopyOnWriteArrayList.html2022-05-12T08:24:21.000Zhttps://tobebetterjavaer.com/thread/CountDownLatch.html2022-03-27T08:36:50.000Zhttps://tobebetterjavaer.com/thread/LockSupport.html2022-04-21T12:29:07.000Zhttps://tobebetterjavaer.com/thread/ReentrantReadWriteLock.html2022-05-12T08:24:21.000Zhttps://tobebetterjavaer.com/thread/ScheduledThreadPoolExecutor.html2022-05-12T08:24:21.000Zhttps://tobebetterjavaer.com/thread/ThreadLocal.html2022-05-12T08:24:21.000Zhttps://tobebetterjavaer.com/thread/ali-executors.html2022-05-12T08:24:21.000Zhttps://tobebetterjavaer.com/thread/aqs.html2022-05-06T14:42:52.000Zhttps://tobebetterjavaer.com/thread/atomic.html2022-03-27T08:36:50.000Zhttps://tobebetterjavaer.com/thread/cas.html2022-05-12T08:24:21.000Zhttps://tobebetterjavaer.com/thread/condition.html2022-05-12T08:24:21.000Zhttps://tobebetterjavaer.com/thread/fork-join.html2022-05-12T08:24:21.000Zhttps://tobebetterjavaer.com/thread/jmm.html2022-05-12T08:24:21.000Zhttps://tobebetterjavaer.com/thread/lock.html2022-03-27T08:36:50.000Zhttps://tobebetterjavaer.com/thread/map.html2022-05-12T08:24:21.000Zhttps://tobebetterjavaer.com/thread/pool.html2022-05-12T08:24:21.000Zhttps://tobebetterjavaer.com/thread/reentrantLock.html2022-03-27T08:36:50.000Zhttps://tobebetterjavaer.com/thread/shengchanzhe-xiaofeizhe.html2022-03-27T08:36:50.000Zhttps://tobebetterjavaer.com/thread/synchronized.html2022-05-12T08:24:21.000Zhttps://tobebetterjavaer.com/thread/thread-bring-some-problem.html2022-05-12T08:24:21.000Zhttps://tobebetterjavaer.com/thread/thread-group-and-thread-priority.html2022-03-27T08:36:50.000Zhttps://tobebetterjavaer.com/thread/thread-state-and-method.html2022-05-12T08:24:21.000Zhttps://tobebetterjavaer.com/thread/volatile.html2022-05-12T08:24:21.000Zhttps://tobebetterjavaer.com/thread/wangzhe-thread.html2022-05-12T08:24:21.000Zhttps://tobebetterjavaer.com/thread/why-need-thread.html2022-03-27T08:36:50.000Zhttps://tobebetterjavaer.com/xianliaolaoke/aliyun-shuaiguo-gongchengshi.html2022-05-12T08:24:21.000Zhttps://tobebetterjavaer.com/xianliaolaoke/chadiansanhuo.html2022-05-12T08:24:21.000Zhttps://tobebetterjavaer.com/xianliaolaoke/chengxuyuannv-chonghui-java.html2022-05-12T08:24:21.000Zhttps://tobebetterjavaer.com/xianliaolaoke/daxue-nuli-jisuanji.html2022-05-12T08:24:21.000Zhttps://tobebetterjavaer.com/xianliaolaoke/fumutuanju.html2022-05-12T08:24:21.000Zhttps://tobebetterjavaer.com/xuexijianyi/electron-information-engineering.html2022-05-12T08:24:21.000Zhttps://tobebetterjavaer.com/xuexijianyi/read-csapp.html2022-05-12T08:24:21.000Zhttps://tobebetterjavaer.com/xuexiluxian/algorithm.html2022-06-06T15:31:27.000Zhttps://tobebetterjavaer.com/xuexiluxian/c.html2022-06-06T15:31:27.000Zhttps://tobebetterjavaer.com/xuexiluxian/ccc.html2022-06-06T15:31:27.000Zhttps://tobebetterjavaer.com/xuexiluxian/go.html2022-06-06T15:31:27.000Zhttps://tobebetterjavaer.com/xuexiluxian/lanqiaobei.html2022-06-06T15:31:27.000Zhttps://tobebetterjavaer.com/xuexiluxian/os.html2022-06-06T15:31:27.000Zhttps://tobebetterjavaer.com/xuexiluxian/python.html2022-06-06T15:31:27.000Zhttps://tobebetterjavaer.com/xuexiluxian/qianduan.html2022-06-06T15:31:27.000Zhttps://tobebetterjavaer.com/xuexiluxian/2022-06-06T15:31:27.000Zhttps://tobebetterjavaer.com/zhishixingqiu/java-mianshi-zhinan.html2022-05-12T08:24:21.000Zhttps://tobebetterjavaer.com/zhishixingqiu/2022-05-13T03:20:56.000Zhttps://tobebetterjavaer.com/zookeeper/jibenjieshao.html2022-05-12T08:24:21.000Zhttps://tobebetterjavaer.com/sidebar/herongwei/mysql.html2022-05-13T23:14:28.000Zhttps://tobebetterjavaer.com/sidebar/sanfene/collection.html2022-05-13T23:14:28.000Zhttps://tobebetterjavaer.com/sidebar/sanfene/javase.html2022-06-06T15:31:27.000Zhttps://tobebetterjavaer.com/sidebar/sanfene/javathread.html2022-05-20T03:14:08.000Zhttps://tobebetterjavaer.com/sidebar/sanfene/jvm.html2022-05-13T23:14:28.000Zhttps://tobebetterjavaer.com/sidebar/sanfene/mybatis.html2022-06-06T15:31:27.000Zhttps://tobebetterjavaer.com/sidebar/sanfene/nixi.html2022-06-06T15:31:27.000Zhttps://tobebetterjavaer.com/sidebar/sanfene/redis.html2022-05-09T06:49:16.000Zhttps://tobebetterjavaer.com/sidebar/sanfene/spring.html2022-05-12T08:24:21.000Zhttps://tobebetterjavaer.com/xuexiluxian/java/jvm.html2022-06-06T15:31:27.000Zhttps://tobebetterjavaer.com/xuexiluxian/java/thread.html2022-06-06T15:31:27.000Zhttps://tobebetterjavaer.com/xuexiluxian/java/yitiaolong.html2022-06-06T15:31:27.000Z \ No newline at end of file +https://tobebetterjavaer.com/2022-06-11T12:15:48.000Zhttps://tobebetterjavaer.com/home.html2022-06-11T12:19:18.000Zhttps://tobebetterjavaer.com/about-the-author/bzhan-10wan.html2022-05-12T08:24:21.000Zhttps://tobebetterjavaer.com/about-the-author/csdn-1000wan.html2022-05-12T08:24:21.000Zhttps://tobebetterjavaer.com/about-the-author/2022-05-12T08:24:21.000Zhttps://tobebetterjavaer.com/about-the-author/zhihu-1000wan.html2022-05-12T08:24:21.000Zhttps://tobebetterjavaer.com/array/array.html2022-03-29T01:56:53.000Zhttps://tobebetterjavaer.com/array/print.html2022-05-13T23:14:28.000Zhttps://tobebetterjavaer.com/basic-grammar/basic-data-type.html2022-05-13T23:14:28.000Zhttps://tobebetterjavaer.com/basic-grammar/flow-control.html2022-05-13T23:14:28.000Zhttps://tobebetterjavaer.com/basic-grammar/javadoc.html2022-05-13T23:14:28.000Zhttps://tobebetterjavaer.com/basic-grammar/operator.html2022-05-13T23:14:28.000Zhttps://tobebetterjavaer.com/baguwen/java-basic-34.html2022-05-12T08:24:21.000Zhttps://tobebetterjavaer.com/baguwen/java-basic.html2022-05-13T23:14:28.000Zhttps://tobebetterjavaer.com/baguwen/java-thread.html2022-05-13T23:14:28.000Zhttps://tobebetterjavaer.com/baguwen/jvm.html2022-05-13T23:14:28.000Zhttps://tobebetterjavaer.com/basic-extra-meal/48-keywords.html2022-04-13T08:53:39.000Zhttps://tobebetterjavaer.com/basic-extra-meal/Overriding.html2022-05-13T23:14:28.000Zhttps://tobebetterjavaer.com/basic-extra-meal/annotation.html2022-05-13T23:14:28.000Zhttps://tobebetterjavaer.com/basic-extra-meal/box.html2022-05-13T23:14:28.000Zhttps://tobebetterjavaer.com/basic-extra-meal/class-object.html2022-05-12T08:24:21.000Zhttps://tobebetterjavaer.com/basic-extra-meal/comparable-omparator.html2022-05-13T23:14:28.000Zhttps://tobebetterjavaer.com/basic-extra-meal/deep-copy.html2022-05-31T09:56:13.000Zhttps://tobebetterjavaer.com/basic-extra-meal/enum.html2022-05-13T23:14:28.000Zhttps://tobebetterjavaer.com/basic-extra-meal/equals-hashcode.html2022-05-13T23:14:28.000Zhttps://tobebetterjavaer.com/basic-extra-meal/fanshe.html2022-05-13T23:14:28.000Zhttps://tobebetterjavaer.com/basic-extra-meal/generic.html2022-05-13T23:14:28.000Zhttps://tobebetterjavaer.com/basic-extra-meal/hashcode.html2022-05-13T23:14:28.000Zhttps://tobebetterjavaer.com/basic-extra-meal/immutable.html2022-06-06T15:31:27.000Zhttps://tobebetterjavaer.com/basic-extra-meal/instanceof-jvm.html2022-05-12T08:24:21.000Zhttps://tobebetterjavaer.com/basic-extra-meal/int-cache.html2022-05-13T23:14:28.000Zhttps://tobebetterjavaer.com/basic-extra-meal/java-naming.html2022-05-13T23:14:28.000Zhttps://tobebetterjavaer.com/basic-extra-meal/java-unicode.html2022-05-13T23:14:28.000Zhttps://tobebetterjavaer.com/basic-extra-meal/jdk-while-for-wuxian-xunhuan.html2022-05-13T23:14:28.000Zhttps://tobebetterjavaer.com/basic-extra-meal/jdk9-char-byte-string.html2022-05-13T23:14:28.000Zhttps://tobebetterjavaer.com/basic-extra-meal/override-overload.html2022-05-13T23:14:28.000Zhttps://tobebetterjavaer.com/basic-extra-meal/pass-by-value.html2022-05-13T23:14:28.000Zhttps://tobebetterjavaer.com/basic-extra-meal/true-generic.html2022-05-13T23:14:28.000Zhttps://tobebetterjavaer.com/basic-extra-meal/varables.html2022-05-13T23:14:28.000Zhttps://tobebetterjavaer.com/cityselect/beijing.html2022-06-11T12:15:48.000Zhttps://tobebetterjavaer.com/cityselect/chengdu.html2022-06-11T12:15:48.000Zhttps://tobebetterjavaer.com/cityselect/guangzhou.html2022-06-11T12:15:48.000Zhttps://tobebetterjavaer.com/cityselect/hangzhou.html2022-06-11T12:15:48.000Zhttps://tobebetterjavaer.com/cityselect/jinan.html2022-06-11T12:15:48.000Zhttps://tobebetterjavaer.com/cityselect/nanjing.html2022-06-11T12:15:48.000Zhttps://tobebetterjavaer.com/cityselect/qingdao.html2022-06-11T12:15:48.000Zhttps://tobebetterjavaer.com/cityselect/shenzhen.html2022-06-11T12:15:48.000Zhttps://tobebetterjavaer.com/cityselect/suzhou.html2022-06-11T12:15:48.000Zhttps://tobebetterjavaer.com/cityselect/xian.html2022-06-11T12:15:48.000Zhttps://tobebetterjavaer.com/cityselect/zhengzhou.html2022-06-11T12:15:48.000Zhttps://tobebetterjavaer.com/collection/arraylist.html2022-05-13T23:14:28.000Zhttps://tobebetterjavaer.com/collection/fail-fast.html2022-05-13T23:14:28.000Zhttps://tobebetterjavaer.com/collection/gailan.html2022-05-13T23:14:28.000Zhttps://tobebetterjavaer.com/collection/hashmap-interview.html2022-05-13T23:14:28.000Zhttps://tobebetterjavaer.com/collection/hashmap.html2022-06-06T15:31:27.000Zhttps://tobebetterjavaer.com/collection/iterator-iterable.html2022-05-13T23:14:28.000Zhttps://tobebetterjavaer.com/collection/linkedlist.html2022-05-13T23:14:28.000Zhttps://tobebetterjavaer.com/collection/list-war-2.html2022-05-13T23:14:28.000Zhttps://tobebetterjavaer.com/common-tool/arrays.html2022-05-13T23:14:28.000Zhttps://tobebetterjavaer.com/common-tool/collections.html2022-05-13T23:14:28.000Zhttps://tobebetterjavaer.com/common-tool/guava.html2022-05-13T23:14:28.000Zhttps://tobebetterjavaer.com/common-tool/hutool.html2022-05-12T08:24:21.000Zhttps://tobebetterjavaer.com/cs/os.html2022-05-29T01:05:54.000Zhttps://tobebetterjavaer.com/cs/wangluo.html2022-05-12T08:24:21.000Zhttps://tobebetterjavaer.com/download/bat-shuati.html2022-06-11T12:15:48.000Zhttps://tobebetterjavaer.com/download/history.html2022-06-07T02:26:02.000Zhttps://tobebetterjavaer.com/download/java.html2022-06-11T12:15:48.000Zhttps://tobebetterjavaer.com/download/jianli.html2022-06-11T12:15:48.000Zhttps://tobebetterjavaer.com/download/learn-jianyi.html2022-04-21T12:29:07.000Zhttps://tobebetterjavaer.com/download/nicearticle.html2022-04-19T04:15:34.000Zhttps://tobebetterjavaer.com/download/pdf.html2022-04-20T00:59:56.000Zhttps://tobebetterjavaer.com/download/progit.html2022-06-11T12:15:48.000Zhttps://tobebetterjavaer.com/download/yuanyifeng-c-language.html2022-06-11T12:15:48.000Zhttps://tobebetterjavaer.com/elasticsearch/rumen.html2022-05-13T23:14:28.000Zhttps://tobebetterjavaer.com/exception/gailan.html2022-05-12T08:24:21.000Zhttps://tobebetterjavaer.com/exception/npe.html2022-05-13T23:14:28.000Zhttps://tobebetterjavaer.com/exception/shijian.html2022-05-13T23:14:28.000Zhttps://tobebetterjavaer.com/exception/try-with-resouces.html2022-05-13T23:14:28.000Zhttps://tobebetterjavaer.com/git/git-qiyuan.html2022-06-08T06:51:04.000Zhttps://tobebetterjavaer.com/git/progit.html2022-05-12T08:24:21.000Zhttps://tobebetterjavaer.com/gongju/Chocolatey-Homebrew.html2022-05-09T06:49:16.000Zhttps://tobebetterjavaer.com/gongju/DBeaver.html2022-05-24T09:00:49.000Zhttps://tobebetterjavaer.com/gongju/chiner.html2022-05-24T09:00:49.000Zhttps://tobebetterjavaer.com/gongju/choco.html2022-05-24T09:00:49.000Zhttps://tobebetterjavaer.com/gongju/fastjson.html2022-05-24T09:00:49.000Zhttps://tobebetterjavaer.com/gongju/forest.html2022-05-24T09:00:49.000Zhttps://tobebetterjavaer.com/gongju/gson.html2022-05-24T09:00:49.000Zhttps://tobebetterjavaer.com/gongju/jackson.html2022-05-24T09:00:49.000Zhttps://tobebetterjavaer.com/gongju/junit.html2022-05-24T09:00:49.000Zhttps://tobebetterjavaer.com/gongju/knife4j.html2022-06-10T11:28:25.000Zhttps://tobebetterjavaer.com/gongju/log4j.html2022-05-24T09:00:49.000Zhttps://tobebetterjavaer.com/gongju/log4j2.html2022-05-24T09:00:49.000Zhttps://tobebetterjavaer.com/gongju/logback.html2022-05-24T09:00:49.000Zhttps://tobebetterjavaer.com/gongju/others.html2022-03-18T02:19:22.000Zhttps://tobebetterjavaer.com/gongju/slf4j.html2022-05-24T09:00:49.000Zhttps://tobebetterjavaer.com/gongju/tabby.html2022-06-07T04:06:44.000Zhttps://tobebetterjavaer.com/gongju/warp.html2022-05-24T09:00:49.000Zhttps://tobebetterjavaer.com/ide/4-debug-skill.html2022-05-12T08:24:21.000Zhttps://tobebetterjavaer.com/io/BIONIOAIO.html2022-05-12T08:24:21.000Zhttps://tobebetterjavaer.com/io/shangtou.html2022-05-13T23:14:28.000Zhttps://tobebetterjavaer.com/java8/Lambda.html2022-05-13T23:14:28.000Zhttps://tobebetterjavaer.com/java8/optional.html2022-05-13T23:14:28.000Zhttps://tobebetterjavaer.com/java8/stream.html2022-05-13T23:14:28.000Zhttps://tobebetterjavaer.com/jvm/asm.html2022-05-13T23:14:28.000Zhttps://tobebetterjavaer.com/jvm/bytecode.html2022-05-13T23:14:28.000Zhttps://tobebetterjavaer.com/jvm/class-file-jiegou.html2022-05-13T23:14:28.000Zhttps://tobebetterjavaer.com/jvm/class-load.html2022-05-13T23:14:28.000Zhttps://tobebetterjavaer.com/jvm/compile-jdk.html2022-05-13T23:14:28.000Zhttps://tobebetterjavaer.com/jvm/cpu-percent-100.html2022-05-12T08:24:21.000Zhttps://tobebetterjavaer.com/jvm/gc.html2022-05-13T23:14:28.000Zhttps://tobebetterjavaer.com/jvm/how-jvm-run-zijiema-zhiling.html2022-05-13T23:14:28.000Zhttps://tobebetterjavaer.com/jvm/how-run-java-code.html2022-05-12T08:24:21.000Zhttps://tobebetterjavaer.com/jvm/hsdb.html2022-05-13T23:14:28.000Zhttps://tobebetterjavaer.com/jvm/jit.html2022-05-13T23:14:28.000Zhttps://tobebetterjavaer.com/jvm/meituan-9-gc.html2022-05-13T23:14:28.000Zhttps://tobebetterjavaer.com/jvm/neicun-jiegou.html2022-05-12T08:24:21.000Zhttps://tobebetterjavaer.com/jvm/oom.html2022-05-12T08:24:21.000Zhttps://tobebetterjavaer.com/jvm/problem-tools.html2022-05-12T08:24:21.000Zhttps://tobebetterjavaer.com/jvm/tujie-gc.html2022-05-12T08:24:21.000Zhttps://tobebetterjavaer.com/jvm/what-happen-when-javac.html2022-05-13T23:14:28.000Zhttps://tobebetterjavaer.com/jvm/what-is-jvm.html2022-05-13T23:14:28.000Zhttps://tobebetterjavaer.com/jvm/whereis-the-object.html2022-05-13T23:14:28.000Zhttps://tobebetterjavaer.com/jvm/zijiema-zhiling.html2022-05-13T23:14:28.000Zhttps://tobebetterjavaer.com/jvm/zongjie.html2022-05-12T08:24:21.000Zhttps://tobebetterjavaer.com/kaiyuan/auto-generator.html2022-06-10T11:28:25.000Zhttps://tobebetterjavaer.com/kaiyuan/2022-03-18T02:19:22.000Zhttps://tobebetterjavaer.com/kaiyuan/yuneban-wangyiyunyinyue.html2022-05-12T08:24:21.000Zhttps://tobebetterjavaer.com/manongshenghuo/waibao-1geyue.html2022-03-03T01:51:15.000Zhttps://tobebetterjavaer.com/manongshenghuo/yanjiusuo-20wan.html2022-05-12T08:24:21.000Zhttps://tobebetterjavaer.com/maven/maven.html2022-06-08T06:51:04.000Zhttps://tobebetterjavaer.com/mianjing/redis12question.html2022-05-13T23:14:28.000Zhttps://tobebetterjavaer.com/mianjing/shanganaliyun.html2022-05-13T23:14:28.000Zhttps://tobebetterjavaer.com/microservice/api-wangguan.html2022-05-21T00:14:16.000Zhttps://tobebetterjavaer.com/mongodb/rumen.html2022-05-13T23:14:28.000Zhttps://tobebetterjavaer.com/mq/100-budiushi.html2022-05-13T23:14:28.000Zhttps://tobebetterjavaer.com/mq/rabbitmq-rumen.html2022-05-13T23:14:28.000Zhttps://tobebetterjavaer.com/mysql/deletedb-binlog-weiguanjishu.html2022-05-12T08:24:21.000Zhttps://tobebetterjavaer.com/mysql/redis-shuju-yizhixing.html2022-05-21T00:14:16.000Zhttps://tobebetterjavaer.com/nginx/40-interview.html2022-05-12T08:24:21.000Zhttps://tobebetterjavaer.com/nginx/nginx.html2022-06-08T06:51:04.000Zhttps://tobebetterjavaer.com/nice-article/BOKEYUANruhegaoxiaodixuexijishu.html2022-05-30T05:41:40.000Zhttps://tobebetterjavaer.com/nice-article/ZHIHUjavaxuexidaoshemechengduokeyizhaodiyifengongzuo.html2022-05-30T05:41:40.000Zhttps://tobebetterjavaer.com/nice-article/bokeyuan-jianxijavazhongdifangwenquanxiankongzhi.html2022-05-31T11:11:41.000Zhttps://tobebetterjavaer.com/nice-article/bokeyuan-ruhegaoxiaodixuexijishu.html2022-05-31T05:30:50.000Zhttps://tobebetterjavaer.com/nice-article/haibukuaiyongmybatisplusshoubashoujiaoni.html2022-05-29T01:05:54.000Zhttps://tobebetterjavaer.com/nice-article/javaxuexidaoshemechengduokeyizhaodiyifengongzuo.html2022-05-30T13:19:41.000Zhttps://tobebetterjavaer.com/nice-article/jiagoushizenyanghuizhijitongjiagoulantu.html2022-05-29T01:05:54.000Zhttps://tobebetterjavaer.com/nice-article/jielehenduosihuodiganchu.html2022-05-29T01:05:54.000Zhttps://tobebetterjavaer.com/nice-article/jishuzongjianbeikaichuliao.html2022-05-29T01:05:54.000Zhttps://tobebetterjavaer.com/nice-article/nginx-setting.html2022-06-10T09:58:21.000Zhttps://tobebetterjavaer.com/nice-article/weixin-bagwpdf.html2022-06-11T12:15:48.000Zhttps://tobebetterjavaer.com/nice-article/weixin-chengxwjdwzhqcgxm.html2022-06-08T02:10:51.000Zhttps://tobebetterjavaer.com/nice-article/weixin-githubxbkdjavajccjyh.html2022-06-11T12:15:48.000Zhttps://tobebetterjavaer.com/nice-article/weixin-liaoliaoxianliu.html2022-06-01T23:41:54.000Zhttps://tobebetterjavaer.com/nice-article/weixin-likbj.html2022-06-09T00:46:28.000Zhttps://tobebetterjavaer.com/nice-article/weixin-mozdsdzfjavableetcodetxxk.html2022-06-11T12:15:48.000Zhttps://tobebetterjavaer.com/nice-article/weixin-piaolwzjztqdtskwlzfpdf.html2022-06-11T12:15:48.000Zhttps://tobebetterjavaer.com/nice-article/weixin-quoppomspwml.html2022-06-10T09:58:21.000Zhttps://tobebetterjavaer.com/nice-article/weixin-shejmsnb.html2022-06-11T12:15:48.000Zhttps://tobebetterjavaer.com/nice-article/weixin-shenrjcjavabfbchwjdhl.html2022-06-11T12:15:48.000Zhttps://tobebetterjavaer.com/nice-article/weixin-xinllgjszjszzpojozsyjbsjlxyhjfyll.html2022-06-05T23:36:38.000Zhttps://tobebetterjavaer.com/nice-article/weixin-zaixsfdnavicatzkkydsjkglgjjmgxk.html2022-06-10T09:58:21.000Zhttps://tobebetterjavaer.com/nice-article/weixin-zhongxcwbztashjjavahdmj.html2022-06-08T02:10:51.000Zhttps://tobebetterjavaer.com/nice-article/weixin-zuixinbujiabandigongsimingdan.html2022-05-30T14:29:10.000Zhttps://tobebetterjavaer.com/nice-article/zhihu-jisjkyynxzdtjdyj.html2022-06-11T12:15:48.000Zhttps://tobebetterjavaer.com/nice-article/zhihu-weismyrsyxkjgscxyzhdjyxz.html2022-06-11T12:15:48.000Zhttps://tobebetterjavaer.com/nice-article/zhihu-younxzdjsjzyxsjrdgq.html2022-06-11T12:15:48.000Zhttps://tobebetterjavaer.com/oo/abstract.html2022-05-13T23:14:28.000Zhttps://tobebetterjavaer.com/oo/code-init.html2022-05-13T23:14:28.000Zhttps://tobebetterjavaer.com/oo/construct.html2022-05-13T23:14:28.000Zhttps://tobebetterjavaer.com/oo/final.html2022-05-12T08:24:21.000Zhttps://tobebetterjavaer.com/oo/inner-class.html2022-05-17T23:32:53.000Zhttps://tobebetterjavaer.com/oo/instanceof.html2022-05-13T23:14:28.000Zhttps://tobebetterjavaer.com/oo/interface.html2022-05-13T23:14:28.000Zhttps://tobebetterjavaer.com/oo/method.html2022-05-13T23:14:28.000Zhttps://tobebetterjavaer.com/oo/object-class.html2022-05-12T08:24:21.000Zhttps://tobebetterjavaer.com/oo/static.html2022-05-13T23:14:28.000Zhttps://tobebetterjavaer.com/oo/this-super.html2022-05-13T23:14:28.000Zhttps://tobebetterjavaer.com/oo/var.html2022-05-13T23:14:28.000Zhttps://tobebetterjavaer.com/overview/hello-world.html2022-05-13T23:14:28.000Zhttps://tobebetterjavaer.com/overview/what-is-java.html2022-05-13T23:14:28.000Zhttps://tobebetterjavaer.com/redis/redis-springboot.html2022-06-10T11:28:25.000Zhttps://tobebetterjavaer.com/redis/rumen.html2022-05-12T08:24:21.000Zhttps://tobebetterjavaer.com/redis/xuebeng-chuantou-jichuan.html2022-03-31T02:38:06.000Zhttps://tobebetterjavaer.com/shigu/image-yasuo.html2022-05-12T08:24:21.000Zhttps://tobebetterjavaer.com/shigu/log4j2.html2022-05-12T08:24:21.000Zhttps://tobebetterjavaer.com/sidebar/computer-base.html2022-03-09T01:11:11.000Zhttps://tobebetterjavaer.com/springboot/Filter-Interceptor-Listener.html2022-06-10T11:28:25.000Zhttps://tobebetterjavaer.com/springboot/aop-log.html2022-05-12T08:24:21.000Zhttps://tobebetterjavaer.com/springboot/cors.html2022-05-12T08:24:21.000Zhttps://tobebetterjavaer.com/springboot/initializr.html2022-06-10T11:28:25.000Zhttps://tobebetterjavaer.com/springboot/ioc.html2022-05-12T08:24:21.000Zhttps://tobebetterjavaer.com/springboot/jpa.html2022-06-10T11:28:25.000Zhttps://tobebetterjavaer.com/springboot/jwt.html2022-05-12T08:24:21.000Zhttps://tobebetterjavaer.com/springboot/linux-codingmore-run.html2022-06-10T11:28:25.000Zhttps://tobebetterjavaer.com/springboot/logback.html2022-06-10T11:28:25.000Zhttps://tobebetterjavaer.com/springboot/macos-codingmore-run.html2022-06-08T06:51:04.000Zhttps://tobebetterjavaer.com/springboot/mysql-druid.html2022-06-10T11:28:25.000Zhttps://tobebetterjavaer.com/springboot/oss.html2022-06-10T11:28:25.000Zhttps://tobebetterjavaer.com/springboot/springtask.html2022-06-10T11:28:25.000Zhttps://tobebetterjavaer.com/springboot/swagger.html2022-06-10T11:28:25.000Zhttps://tobebetterjavaer.com/springboot/thymeleaf.html2022-06-10T11:28:25.000Zhttps://tobebetterjavaer.com/springboot/tomcat.html2022-05-12T08:24:21.000Zhttps://tobebetterjavaer.com/springboot/transaction.html2022-06-10T11:28:25.000Zhttps://tobebetterjavaer.com/springboot/windows-codingmore-run.html2022-06-10T11:28:25.000Zhttps://tobebetterjavaer.com/string/constant-pool.html2022-05-12T08:24:21.000Zhttps://tobebetterjavaer.com/string/equals.html2022-05-12T08:24:21.000Zhttps://tobebetterjavaer.com/string/immutable.html2022-03-27T08:36:50.000Zhttps://tobebetterjavaer.com/string/intern.html2022-05-12T08:24:21.000Zhttps://tobebetterjavaer.com/string/join.html2022-03-27T08:36:50.000Zhttps://tobebetterjavaer.com/string/split.html2022-05-12T08:24:21.000Zhttps://tobebetterjavaer.com/szjy/buy-cloud-server.html2022-06-08T06:51:04.000Zhttps://tobebetterjavaer.com/szjy/buy-domain.html2022-06-08T06:51:04.000Zhttps://tobebetterjavaer.com/szjy/https-domain.html2022-06-08T06:51:04.000Zhttps://tobebetterjavaer.com/szjy/install-baota-mianban.html2022-06-08T06:51:04.000Zhttps://tobebetterjavaer.com/szjy/record-domain.html2022-06-08T06:55:00.000Zhttps://tobebetterjavaer.com/szjy/tobebetterjavaer-wangzhan-shangxian.html2022-05-12T08:24:21.000Zhttps://tobebetterjavaer.com/szjy/tupian-zhuanlian.html2022-05-12T08:24:21.000Zhttps://tobebetterjavaer.com/thread/BlockingQueue.html2022-05-12T08:24:21.000Zhttps://tobebetterjavaer.com/thread/ConcurrentHashMap.html2022-05-12T08:24:21.000Zhttps://tobebetterjavaer.com/thread/ConcurrentLinkedQueue.html2022-05-12T08:24:21.000Zhttps://tobebetterjavaer.com/thread/CopyOnWriteArrayList.html2022-05-12T08:24:21.000Zhttps://tobebetterjavaer.com/thread/CountDownLatch.html2022-03-27T08:36:50.000Zhttps://tobebetterjavaer.com/thread/LockSupport.html2022-04-21T12:29:07.000Zhttps://tobebetterjavaer.com/thread/ReentrantReadWriteLock.html2022-05-12T08:24:21.000Zhttps://tobebetterjavaer.com/thread/ScheduledThreadPoolExecutor.html2022-05-12T08:24:21.000Zhttps://tobebetterjavaer.com/thread/ThreadLocal.html2022-05-12T08:24:21.000Zhttps://tobebetterjavaer.com/thread/ali-executors.html2022-05-12T08:24:21.000Zhttps://tobebetterjavaer.com/thread/aqs.html2022-05-06T14:42:52.000Zhttps://tobebetterjavaer.com/thread/atomic.html2022-03-27T08:36:50.000Zhttps://tobebetterjavaer.com/thread/cas.html2022-05-12T08:24:21.000Zhttps://tobebetterjavaer.com/thread/condition.html2022-05-12T08:24:21.000Zhttps://tobebetterjavaer.com/thread/fork-join.html2022-05-12T08:24:21.000Zhttps://tobebetterjavaer.com/thread/jmm.html2022-05-12T08:24:21.000Zhttps://tobebetterjavaer.com/thread/lock.html2022-03-27T08:36:50.000Zhttps://tobebetterjavaer.com/thread/map.html2022-05-12T08:24:21.000Zhttps://tobebetterjavaer.com/thread/pool.html2022-05-12T08:24:21.000Zhttps://tobebetterjavaer.com/thread/reentrantLock.html2022-03-27T08:36:50.000Zhttps://tobebetterjavaer.com/thread/shengchanzhe-xiaofeizhe.html2022-03-27T08:36:50.000Zhttps://tobebetterjavaer.com/thread/synchronized.html2022-05-12T08:24:21.000Zhttps://tobebetterjavaer.com/thread/thread-bring-some-problem.html2022-05-12T08:24:21.000Zhttps://tobebetterjavaer.com/thread/thread-group-and-thread-priority.html2022-03-27T08:36:50.000Zhttps://tobebetterjavaer.com/thread/thread-state-and-method.html2022-05-12T08:24:21.000Zhttps://tobebetterjavaer.com/thread/volatile.html2022-05-12T08:24:21.000Zhttps://tobebetterjavaer.com/thread/wangzhe-thread.html2022-05-12T08:24:21.000Zhttps://tobebetterjavaer.com/thread/why-need-thread.html2022-03-27T08:36:50.000Zhttps://tobebetterjavaer.com/xianliaolaoke/aliyun-shuaiguo-gongchengshi.html2022-05-12T08:24:21.000Zhttps://tobebetterjavaer.com/xianliaolaoke/chadiansanhuo.html2022-05-12T08:24:21.000Zhttps://tobebetterjavaer.com/xianliaolaoke/chengxuyuannv-chonghui-java.html2022-05-12T08:24:21.000Zhttps://tobebetterjavaer.com/xianliaolaoke/daxue-nuli-jisuanji.html2022-05-12T08:24:21.000Zhttps://tobebetterjavaer.com/xianliaolaoke/fumutuanju.html2022-05-12T08:24:21.000Zhttps://tobebetterjavaer.com/xuexijianyi/electron-information-engineering.html2022-06-11T12:19:18.000Zhttps://tobebetterjavaer.com/xuexijianyi/read-csapp.html2022-06-11T12:19:18.000Zhttps://tobebetterjavaer.com/xuexiluxian/algorithm.html2022-06-06T15:31:27.000Zhttps://tobebetterjavaer.com/xuexiluxian/c.html2022-06-06T15:31:27.000Zhttps://tobebetterjavaer.com/xuexiluxian/ccc.html2022-06-06T15:31:27.000Zhttps://tobebetterjavaer.com/xuexiluxian/go.html2022-06-06T15:31:27.000Zhttps://tobebetterjavaer.com/xuexiluxian/lanqiaobei.html2022-06-06T15:31:27.000Zhttps://tobebetterjavaer.com/xuexiluxian/os.html2022-06-06T15:31:27.000Zhttps://tobebetterjavaer.com/xuexiluxian/python.html2022-06-06T15:31:27.000Zhttps://tobebetterjavaer.com/xuexiluxian/qianduan.html2022-06-06T15:31:27.000Zhttps://tobebetterjavaer.com/xuexiluxian/2022-06-06T15:31:27.000Zhttps://tobebetterjavaer.com/zhishixingqiu/java-mianshi-zhinan.html2022-05-12T08:24:21.000Zhttps://tobebetterjavaer.com/zhishixingqiu/2022-06-10T09:58:21.000Zhttps://tobebetterjavaer.com/zookeeper/jibenjieshao.html2022-05-12T08:24:21.000Zhttps://tobebetterjavaer.com/sidebar/herongwei/mysql.html2022-05-13T23:14:28.000Zhttps://tobebetterjavaer.com/sidebar/sanfene/collection.html2022-05-13T23:14:28.000Zhttps://tobebetterjavaer.com/sidebar/sanfene/javase.html2022-06-06T15:31:27.000Zhttps://tobebetterjavaer.com/sidebar/sanfene/javathread.html2022-05-20T03:14:08.000Zhttps://tobebetterjavaer.com/sidebar/sanfene/jvm.html2022-05-13T23:14:28.000Zhttps://tobebetterjavaer.com/sidebar/sanfene/mybatis.html2022-06-06T15:31:27.000Zhttps://tobebetterjavaer.com/sidebar/sanfene/nixi.html2022-06-06T15:31:27.000Zhttps://tobebetterjavaer.com/sidebar/sanfene/redis.html2022-05-09T06:49:16.000Zhttps://tobebetterjavaer.com/sidebar/sanfene/spring.html2022-05-12T08:24:21.000Zhttps://tobebetterjavaer.com/xuexiluxian/java/jvm.html2022-06-06T15:31:27.000Zhttps://tobebetterjavaer.com/xuexiluxian/java/thread.html2022-06-06T15:31:27.000Zhttps://tobebetterjavaer.com/xuexiluxian/java/yitiaolong.html2022-06-06T15:31:27.000Z \ No newline at end of file diff --git a/dist/springboot/Filter-Interceptor-Listener.html b/dist/springboot/Filter-Interceptor-Listener.html index 6594d8c2..d93a8dda 100644 --- a/dist/springboot/Filter-Interceptor-Listener.html +++ b/dist/springboot/Filter-Interceptor-Listener.html @@ -5,7 +5,7 @@ - Spring Boot 整合 Thymeleaf 模板引擎 | Java 程序员进阶之路 + 过滤器、拦截器、监听器 | Java 程序员进阶之路 + + + + + +

    编程喵🐱实战项目如何在云服务器上跑起来?

    沉默王二2022年6月10日
    • Java企业级开发
    • Spring Boot
    • Vue
    大约 9 分钟

    云服务器

    我们需要一台云服务器,我之前白嫖过一台丐版的,1 核1G 内存,并且已经安装了宝塔面板(安装教程戳链接🔗open in new window)。

    这是从宝塔面板首页看到的服务器配置详情。

    马上 618 了,阿里云服务器也开始整活了,需要白嫖的小伙伴可以先加群。

    MySQL

    登录宝塔面板,点击「数据库」→「添加数据库」,填写数据库名,宝塔面板会自动帮我们创建一个和数据库同名的账号,注意访问权限选择「本地服务器」。

    在 codingmore 栏目中点击「导入」「从本地上传」编程喵的数据库文件。上传完成后点击导入。

    DB 文件放在 coding-more/doc 目录下。

    建议先做一次备份,点击「无备份」「备份」就可以将我们的数据库文件备份下来了,如果后面想恢复的话,直接点击「恢复」就可以了。

    记住用户名,并复制密码,然后在数据库条目中点击「管理」

    填写用户名和密码后,点击执行。

    就可以看到编程喵的数据库文件了。

    Nginx

    Nginxopen in new window 是一个高性能的 HTTP 和反向代理 Web 服务器,基本上就变成了一个服务器必须安装的前置条件之一。

    宝塔面板中安装 Nginx 比较简单,直接在软件商店中搜「Nginx」就可以点击安装了。

    Redis

    宝塔面板中安装 Redis 也比较简单,直接在软件商店中搜「Redis」就可以点击安装了。

    项目打包

    1)codingmore-admin

    编程喵的管理后端,注意修改生产环境下的 MySQL 用户名和密码,在 application-prod.yml 文件中。

    然后把 application.yml 文件中的 active 修改为 prod 生产环境。

    替换 OSS 配置。

    2)codingmore-web

    编程喵的 Web 前端(网站门户、文章展示/文章详情等),注意修改生产环境下的 MySQL 用户名和密码,在 application-prod.yml 文件中。

    然后把 application.yml 文件中的 active 修改为 prod 生产环境。

    然后就可以双击 Maven 的 package 打包了。

    3)codingmore-admin-web

    admin 管理端的前端界面。在 Visual Studio Code 中,现在终端中执行 yarn install 安装项目的依赖插件。

    再执行 yarn run build 就可以构建 codingmore-admin-web 的静态页面了。

    会在项目的根目录中生成一个 dist 目录,里面就是打包好的管理端静态页面。

    打包的时候有两个要点要补充下,在 config 目录下有三个配置文件,dev.env.js 是开发环境下的一些配置,index.js 是主配置,prod.env.js 是生产环境下的配置。

    为了提高网站的性能,我们需要关闭 source map,设置 productionSourceMap: false,同时开启 js 和 css 的文件压缩功能。

    这样打包后的文件大小就会小很多,放到服务器上也能减少网络请求的响应时间。

    可以看得出,最大的一个 js 文件为 3.7M,压缩版只有 662kb,体积缩小了五倍。

    将打包好的文件上传到服务器

    在宝塔面板中点击「FTP」「添加 FTP」。

    点击「根目录」

    跳转到文件页。

    点击上传,在 target 目录下选择上传的两个 jar 包,admin 和 web。

    点击「开始上传」

    还有 codingmore-admin-web 的静态文件。

    一键部署

    在软件商店里搜「Java」关键字,可以看到一个「Java 项目一键部署 3.5」的插件,安装它。

    进入「Java 项目一键部署」面板。

    可以在「容器管理」面板中选择 Tomcat 8 安装下,如果没有安装 JDK,在安装 Tomcat 8 的时候会默认安装一个 JDK 1.8。

    进入 Spring Boot 面板,点击「添加项目」,点击「项目路径」右侧的文件夹图标,就可以上传部署我们的 Spring Boot 项目了。

    codingmore-web(网站前端)

    先选择 codingmore-web。

    填写域名(编程喵的域名为 codingmore.top),修改端口号为 8081,application.yml 文件中定义的。

    点击确定。

    可以看到服务已经在启动了,点「日志」看一下。

    没问题。

    也可以在这个路径下使用终端工具看日志。

    在安全面板里确认一下 8081 端口是否放开。

    确认放开后,打开 Chrome 浏览器的无痕模式,输入 IP+端口号。

    通过域名+端口号的形式也可以访问到。

    codingmore-admin(网站管理端)

    再次进入 「Java 项目一键部署」Spring Boot 面板中,添加 codingmore-admin 项目。

    稍等片刻,来看一下日志。

    启动没问题。

    codingmore-admin 只是一个后端服务,界面是用 vue 完成的,所以我们此时可以通过 Swagger 来确认一下接口是否可以正常访问。

    先放行 9002 端口。

    在浏览器地址栏里输入 http://www.codingmore.top:9002/doc.html,可以看到我们用 Knife4j+Swagger 生成的 API 文档接口。

    OK,这样就可以验证我们的 admin 端服务也正确运行了。

    随后,为了减少服务器被攻击的可能性,我们关掉 9002 的端口。

    Nginx 配置

    codingmore-web

    域名+端口号虽然可以访问,但不够优雅,我们想直接访问域名 codingmore.top,该怎么办呢?

    可以使用 Nginxopen in new window 进行端口转发。

    Nginx 的实现原理是,用 Nginx 监听 80 端口,当有 HTTP 请求到来时,将 HTTP 请求的 HOST 等信息与配置文件进行匹配并转发给对应的端口。

    比如说,当用户访问 codingmore.top 时,Nginx 从配置文件中得知这是一个 HTTP 请求,于是将此请求转发给 8081 端口的应用处理。

    upstream codingmore_web_pool{
    +    server 127.0.0.1:8081;
    +}
    +
    +server {
    +    listen       80;
    +    server_name  codingmore.top;
    +    access_log logs/codingmore_web.log;
    +    error_log logs/codingmore_web.error;
    +    
    +    #将所有请求转发给pool池的应用处理
    +    location / {
    +        proxy_set_header Host $host;
    +        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    +        proxy_pass http://codingmore_web_pool;
    +    }
    +}
    +

    这就是所谓的端口转发,由软件统一监听某个域名上的某个端口(一般是80端口),当访问服务器的域名和端口符合要求时,就按照配置转发给指定的 Tomcat 服务器处理。我们常用的 Nginx 也有端口转发功能。

    OK,原理了解完后,我们把这段配置复制到宝塔面板中的 Nginx 配置中。

    点击「保存」。

    再在浏览器中访问 codingmore.topopen in new window 就可以请求到内容了。

    既然如此,我们顺带把 8081 端口给关掉,减少一个服务器被攻击的可能性。

    OK,这样我们就完成了 codingmore-web 也就是编程喵🐱前端的服务部署了。

    codingmore-admin-web

    codingmore-admin-web 打包后的文件是静态的,所以我们只需要在 Nginx 里添加 admin 的配置路径就 OK 了。

    upstream codingmore_web_pool{
    +    server 127.0.0.1:8081;
    +}
    +
    +server {
    +    listen       80;
    +    server_name  codingmore.top;
    +    access_log /home/www/codingmore_web.log;
    +    error_log /home/www/codingmore_web.error;
    +
    +    location /admin {
    +        alias /www/wwwroot/itwanger/dist/; # 根目录
    +        index index.html;
    +    }
    +    
    +    #将所有请求转发给pool池的应用处理
    +    location / {
    +        proxy_set_header Host $host;
    +        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    +        proxy_pass http://codingmore_web_pool;
    +    }
    +}
    +

    我们在 server 中增加了一个 admin 的 location,也就是说,当我们访问 codingmore.top/adminopen in new window 的时候,就去请求 /www/wwwroot/itwanger/dist/ 目录下的静态文件。

    这里讲一下 root 和 alias 的区别:

    • root:实际访问的地址前缀是 root + 请求的 path路径,即 admin => /www/wwwroot/itwanger/dist/admin
    • alias: 实际访问的就是 /www/wwwroot/itwanger/dist

    注意两者的区别。我们来访问下codingmore.top/adminopen in new window

    OK。

    编程喵🐱是一个前后端分离项目,前端的请求如何访问后端的 API 接口呢?简单聊一下。

    打开 codingmore-admin-web/config/prod.env.js 文件,里面有一个 VUE_APP_BASE_API 属性,它的值为 /api,也就意味着前端的请求会发送到 /api 这个前缀路径下。

    'use strict'
    +module.exports = {
    +  NODE_ENV: '"production"',
    +  VUE_APP_BASE_API: '"/api"'
    +}
    +

    那我们的 codingmore-admin 后端服务是跑在 9002 端口下的,这就意味着,我们需要在 Nginx 中增加一个路径,将 api 前缀的请求转发到 9002 下。

    OK,来看一下完整的配置内容。

    upstream codingmore_web_pool{
    +    server 127.0.0.1:8081;
    +}
    +
    +upstream codingmore_admin_pool{
    +    server 127.0.0.1:9002/;
    +}
    +
    +server {
    +    listen       80;
    +    server_name  codingmore.top;
    +    access_log /home/www/codingmore_web.log;
    +    error_log /home/www/codingmore_web.error;
    +
    +    location /admin {
    +        alias /www/wwwroot/itwanger/dist/; # 根目录
    +        index index.html;
    +    }
    +
    +    location /api/ {
    +        proxy_set_header Host $host;
    +        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    +        proxy_pass http://codingmore_admin_pool;
    +    }
    +    
    +    #将所有请求转发给pool池的应用处理
    +    location / {
    +        proxy_set_header Host $host;
    +        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    +        proxy_pass http://codingmore_web_pool;
    +    }
    +}
    +

    ok,登录 admin 端,可以看到我们的文章管理页面了。

    网站域名

    + + + diff --git a/dist/springboot/logback.html b/dist/springboot/logback.html index ddd7db3c..d4bb8d6f 100644 --- a/dist/springboot/logback.html +++ b/dist/springboot/logback.html @@ -5,7 +5,7 @@ - - + -

    Spring Boot 整合 Logback 定制日志框架

    沉默王二2022年5月21日
    • Java企业级开发
    • Spring Boot
    • Redis
    大约 8 分钟

    关于 Logback

    日志系统是一个线上项目必备的素质之一,代表性的日志框架 Log4j、SLF4J、Logback 这哥仨竟然是亲兄弟,他们有一个亲爹,那就是巨佬 Ceki Gulcu。

    由于 Spring Boot 的默认日志框架选用的 Logback,再加上 Log4j2 之前爆过严重的漏洞,所以我们这次就只关注 Logback。

    1)Logback 非常自然地实现了 SLF4J,不需要像 Log4j 和 JUL 那样加一个适配层。

    2)Spring Boot 的默认日志框架使用的是 Logback,启动编程喵项目的时候就可以看到 Logback 记录的日志了。

    怎么看出来是 logback 呢?

    说实话,看不出来,哈哈哈,不过可以从 Spring Boot 官网找到证据。

    还有,通过源码也可以窥见一二。

    3)logback 分为三个模块:

    • logback-core,核心模块,提供了关键的通用机制;
    • logback-classic,可以看作是 log4j 的改进版,实现了简单的日志门面 SLF4J;
    • logback-access,主要用来和 Servlet 容器交互,比如说 Tomcat,提供了一些 HTTP 访问的功能。

    如果想研究 logback 源码的话,可以按照这三个模块去研究。

    直接上手

    不废话,直接新建一个空的 Spring Boot 项目,在测试类中加上两行代码。

    @SpringBootTest
    +    

    Spring Boot 整合 Logback 定制日志框架

    沉默王二2022年5月21日
    • Java企业级开发
    • Spring Boot
    • Redis
    大约 8 分钟

    关于 Logback

    日志系统是一个线上项目必备的素质之一,代表性的日志框架 Log4j、SLF4J、Logback 这哥仨竟然是亲兄弟,他们有一个亲爹,那就是巨佬 Ceki Gulcu。

    由于 Spring Boot 的默认日志框架选用的 Logback,再加上 Log4j2 之前爆过严重的漏洞,所以我们这次就只关注 Logback。

    1)Logback 非常自然地实现了 SLF4J,不需要像 Log4j 和 JUL 那样加一个适配层。

    2)Spring Boot 的默认日志框架使用的是 Logback,启动编程喵项目的时候就可以看到 Logback 记录的日志了。

    怎么看出来是 logback 呢?

    说实话,看不出来,哈哈哈,不过可以从 Spring Boot 官网找到证据。

    还有,通过源码也可以窥见一二。

    3)logback 分为三个模块:

    • logback-core,核心模块,提供了关键的通用机制;
    • logback-classic,可以看作是 log4j 的改进版,实现了简单的日志门面 SLF4J;
    • logback-access,主要用来和 Servlet 容器交互,比如说 Tomcat,提供了一些 HTTP 访问的功能。

    如果想研究 logback 源码的话,可以按照这三个模块去研究。

    直接上手

    不废话,直接新建一个空的 Spring Boot 项目,在测试类中加上两行代码。

    @SpringBootTest
     class CodingmoreLogbackApplicationTests {
       static Logger logger = LoggerFactory.getLogger(CodingmoreLogbackApplicationTests.class);
       @Test
    @@ -53,7 +53,7 @@
     

    Logger 和 LoggerFactory 都来自 SLF4J,所以如果项目是从 Log4j + SLF4J 切换到 Logback 的话,此时的代码是零改动的。

    其他什么也不用做,运行后就可以看到 logback 已经正常工作了。

    在没有配置文件的情况下,一切都是默认的,Logback 的日志信息会输出到控制台。可以通过 StatusPrinter 来打印 Logback 的内部信息:

    LoggerContext lc = (LoggerContext)LoggerFactory.getILoggerFactory();
     StatusPrinter.print(lc);
     

    再次运行测试类,可以在控制台看到以下信息:

    也就是说,Logback 会在 classpath 路径下先寻找 logback-test.xml 文件,没有找到的话,寻找 logback.xml 文件,都找不到的话,就输出到控制台。

    并且,Logger 的默认日志级别是 INFO 级别的,这就意味着如果尝试下面的代码:

    logger.debug("沉默王二是傻 X");
    -

    控制台是看不到这行日志输出的。Logback 的日志级别是这样的:

    TRACE < DEBUG < INFO < WARN < ERROR

    也就是说小于 INFO 级别的日志都不会记录,只有大于等于 INFO 级别的日志才会被记录。

    编程喵实战项目的日志案例分析

    尽管默认配置很有用,但它很可能不能满足我们的实际开发需求,于是我们需要找到一种更优雅的解决方案。

    src/main/resources 目录下有以下名称之一的配置文件时,Spring Boot 将自动加载它来作为 Logback 的配置项:

    • logback-spring.xml
    • logback.xml
    • logback-spring.groovy
    • logback.groovy

    Spring Boot 建议我们使用 -spring 结尾的配置文件,这样可以使用 Spring Boot 的 Profile 功能(针对不同的环境(开发环境、测试环境、正式环境)提供不同的配置项)。

    编程喵用的是 logback-spring.xml(在 codingmore-admin 项目下可以找得到):

    <!--
    +

    控制台是看不到这行日志输出的。Logback 的日志级别是这样的:

    TRACE < DEBUG < INFO < WARN < ERROR

    也就是说小于 INFO 级别的日志都不会记录,只有大于等于 INFO 级别的日志才会被记录。

    编程喵实战项目的日志案例分析

    尽管默认配置很有用,但它很可能不能满足我们的实际开发需求,于是我们需要找到一种更优雅的解决方案。

    src/main/resources 目录下有以下名称之一的配置文件时,Spring Boot 将自动加载它来作为 Logback 的配置项:

    • logback-spring.xml
    • logback.xml
    • logback-spring.groovy
    • logback.groovy

    Spring Boot 建议我们使用 -spring 结尾的配置文件,这样可以使用 Spring Boot 的 Profile 功能(针对不同的环境(开发环境、测试环境、正式环境)提供不同的配置项)。

    编程喵用的是 logback-spring.xml(在 codingmore-admin 项目下可以找得到):

    <!--
     configuration 有三个属性:
     scan:当此属性设置为true时,配置文件如果发生改变,将会被重新加载,默认值为true。
     scanPeriod:设置监测配置文件是否有修改的时间间隔,如果没有给出时间单位,默认单位是毫秒当scan为true时,此属性生效。默认的时间间隔为1分钟。
    @@ -163,7 +163,7 @@ debug:当此属性设置为true时,将打印出logback内部日志信息,
             <appender-ref ref="APPLICATION" />
         </root>
     </configuration>
    -

    只说几个不同的点。

    FILE_LOG_PATTERNCONSOLE_LOG_PATTERN 是在 Spring Boot 中默认定义的。

    https://github.com/spring-projects/spring-boot/blob/main/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/logging/logback/DefaultLogbackConfiguration.javaopen in new window

    SizeAndTimeBasedRollingPolicy 比 TimeBasedRollingPolicy 多了一个日志文件大小设定的属性:maxFileSize,其他完全一样。

    totalSizeCap,所有日志文件的大小(可选项)。超出这个大小时,旧的日志文件将会被异步删除。需要配合 maxHistory 属性一起使用,并且是第二条件。

    在Intellij IDEA 中启动项目,我们来查看一下配置后的日志效果(控制台中)。

    由于我们加了颜色配置,所以控制台日志看起来对眼睛更友好了一些。

    那配置的日志文件在哪里呢?在 user.home 下,如果不确定具体值是什么的话,可以通过 System.getProperty("user.home") 获取到。

    顺着这个路径就可以找到生成的日志文件了,并且日志的生成策略也是符合我们的预期的。

    使用 lombok 进行日志记录

    在上面的例子中,我们必须在类中声明一个静态的 Logger 对象才能在需要记录日志的地方使用它。

    static Logger logger = LoggerFactory.getLogger(CodingmoreLogbackApplicationTests.class);
    +

    只说几个不同的点。

    FILE_LOG_PATTERNCONSOLE_LOG_PATTERN 是在 Spring Boot 中默认定义的。

    https://github.com/spring-projects/spring-boot/blob/main/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/logging/logback/DefaultLogbackConfiguration.javaopen in new window

    SizeAndTimeBasedRollingPolicy 比 TimeBasedRollingPolicy 多了一个日志文件大小设定的属性:maxFileSize,其他完全一样。

    totalSizeCap,所有日志文件的大小(可选项)。超出这个大小时,旧的日志文件将会被异步删除。需要配合 maxHistory 属性一起使用,并且是第二条件。

    在Intellij IDEA 中启动项目,我们来查看一下配置后的日志效果(控制台中)。

    由于我们加了颜色配置,所以控制台日志看起来对眼睛更友好了一些。

    那配置的日志文件在哪里呢?在 user.home 下,如果不确定具体值是什么的话,可以通过 System.getProperty("user.home") 获取到。

    顺着这个路径就可以找到生成的日志文件了,并且日志的生成策略也是符合我们的预期的。

    使用 lombok 进行日志记录

    在上面的例子中,我们必须在类中声明一个静态的 Logger 对象才能在需要记录日志的地方使用它。

    static Logger logger = LoggerFactory.getLogger(CodingmoreLogbackApplicationTests.class);
     

    这样的样板代码令人生厌!

    我们可以通过 lombok 的方式来解决这个问题,在 pom.xml 文件中加入依赖。

    <dependency>
       <groupId>org.projectlombok</groupId>
       <artifactId>lombok</artifactId>
    @@ -177,7 +177,7 @@ class CodingmoreLogbackApplicationTests {
         log.info("沉默王二是个大煞笔");
       }
     }
    -

    更多内容,只针对《Java 程序员进阶之路》星球用户开放,需要的小伙伴可以戳链接🔗加入我们的星球,一起学习,一起卷。。编程喵🐱是一个 Spring Boot+Vue 的前后端分离项目,融合了市面上绝大多数流行的技术要点。通过学习实战项目,你可以将所学的知识通过实践进行检验、你可以拓宽自己的技术边界,你可以掌握一个真正的实战项目是如何从 0 到 1 的。


    源码路径

    - +

    更多内容,只针对《Java 程序员进阶之路》星球用户开放,需要的小伙伴可以戳链接🔗open in new window加入我们的星球,一起学习,一起卷。。编程喵🐱是一个 Spring Boot+Vue 的前后端分离项目,融合了市面上绝大多数流行的技术要点。通过学习实战项目,你可以将所学的知识通过实践进行检验、你可以拓宽自己的技术边界,你可以掌握一个真正的实战项目是如何从 0 到 1 的。


    源码路径

    + diff --git a/dist/springboot/macos-codingmore-run.html b/dist/springboot/macos-codingmore-run.html index bf31a8cb..137f4e80 100644 --- a/dist/springboot/macos-codingmore-run.html +++ b/dist/springboot/macos-codingmore-run.html @@ -39,16 +39,16 @@ } - + -

    如何在本地(macOS环境)跑起来编程喵(Spring Boot+Vue)项目源码?

    沉默王二2022年6月6日
    • Java企业级开发
    • Spring Boot
    • Vue
    大约 8 分钟

    前置环境的准备

    • 一台可以开机的电脑
    • JDK 8
    • Maven
    • Intellij IDEA(非必须,可用 Eclipse)
    • Visual Studio Code(非必须,可用 hbuilderx)
    • MySQL
    • Redis(非必须,会报错,但不影响跑)
    • OSS(非必须,上传图片时报错,但不影响跑)

    对,编程喵 🐱(Spring Boot+Vue 的前后端分离项目)要想在本地跑起来,需要这 8 个前置环境。

    第一个条件,一台可以开机的电脑,显然我相信大家都是有的。不然怎么学编程是吧?瞧我这废话真多。

    这篇先以 macOS 为例,Windows 的话,我另开一篇。下图是我的主力机 iMac 的配置。

    第二个条件,JDK 8,可以通过 homebrewopen in new window(macOS 软件包管理器)安装,非常方面,然后用 jenvopen in new window 来管理 Java 版本。

    执行 brew -v 可以查看 homebrew 版本

    执行 brew install java 可以安装最新版 JDK。

    执行 brew install adoptopenjdk/openjdk/adoptopenjdk8 --cask 可以安装最 JDK 8。

    执行 ls /Library/Java/JavaVirtualMachines/ 可以查看本机所有安装过的 JDK 包。

    通过 jenv add adoptopenjdk-8.jdk/Contents/Home/ 可以将安装过的 JDK 加入到 jenv 版本库中。

    执行 jenv global openjdk64-1.8.0.292 可以指定当前的 JDK 版本。再执行 jenv versions 可以查看默认使用的 JDK 版本(带*的)

    执行 java -version 可以查看当前 JDK 版本

    第三个条件,Maven,可以直接通过 brew install maven 来完成安装。通过 mvn -v 来查看版本。

    为了加快项目依赖包的下载速度,我们需要配置 Maven 的国内镜像源。

    找到 Maven Home(/Users/yourpath/save/apache-maven-3.8.3),复制一份 settings.xml。

    /Users/you/.m2 路径下。

    在 mirrors 节点下添加阿里云镜像地址,并保存。

    <mirror>
    +    

    如何在本地(macOS环境)跑起来编程喵(Spring Boot+Vue)项目源码?

    沉默王二2022年6月6日
    • Java企业级开发
    • Spring Boot
    • Vue
    大约 8 分钟

    前置环境的准备

    • 一台可以开机的电脑
    • JDK 8
    • Maven
    • Intellij IDEA(非必须,可用 Eclipse)
    • Visual Studio Code(非必须,可用 hbuilderx)
    • MySQL
    • Redis(非必须,会报错,但不影响跑)
    • OSS(非必须,上传图片时报错,但不影响跑)

    对,编程喵 🐱(Spring Boot+Vue 的前后端分离项目)要想在本地跑起来,需要这 8 个前置环境。

    第一个条件,一台可以开机的电脑,显然我相信大家都是有的。不然怎么学编程是吧?瞧我这废话真多。

    这篇先以 macOS 为例,Windows 的话,我另开一篇。下图是我的主力机 iMac 的配置。

    第二个条件,JDK 8,可以通过 homebrewopen in new window(macOS 软件包管理器)安装,非常方面,然后用 jenvopen in new window 来管理 Java 版本。

    执行 brew -v 可以查看 homebrew 版本

    执行 brew install java 可以安装最新版 JDK。

    执行 brew install adoptopenjdk/openjdk/adoptopenjdk8 --cask 可以安装最 JDK 8。

    执行 ls /Library/Java/JavaVirtualMachines/ 可以查看本机所有安装过的 JDK 包。

    通过 jenv add adoptopenjdk-8.jdk/Contents/Home/ 可以将安装过的 JDK 加入到 jenv 版本库中。

    执行 jenv global openjdk64-1.8.0.292 可以指定当前的 JDK 版本。再执行 jenv versions 可以查看默认使用的 JDK 版本(带*的)

    执行 java -version 可以查看当前 JDK 版本

    第三个条件,Maven,可以直接通过 brew install maven 来完成安装。通过 mvn -v 来查看版本。

    为了加快项目依赖包的下载速度,我们需要配置 Maven 的国内镜像源。

    找到 Maven Home(/Users/yourpath/save/apache-maven-3.8.3),复制一份 settings.xml。

    /Users/you/.m2 路径下。

    在 mirrors 节点下添加阿里云镜像地址,并保存。

    <mirror>
       <id>alimaven</id>
       <name>aliyun maven</name>
     <url>http://maven.aliyun.com/nexus/content/groups/public/</url>
       <mirrorOf>central</mirrorOf>
     </mirror>
     

    第四个条件,Intellij IDEA,Java 后端开发必备神器,可以安装社区版,也可以安装旗舰版。

    https://www.jetbrains.com/zh-cn/idea/download/#section=macopen in new window

    第五个条件,Visual Studio Code,在编写前端代码(vue、JavaScript、css 等)时,比 Intellij IDEA 更值得信赖。

    https://code.visualstudio.com/open in new window

    第六个条件,MySQL,可以通过 MySQL 官网open in new window下载安装包。

    安装完成后,可以通过设置面板看到 MySQL 服务(记住用户名和密码)。

    点进去可以查看 MySQL 运行状态。

    第七个条件,Redis,可以直接通过 brew install redis 来完成安装。

    执行 redis-server 就可以启动 Redis 服务了。

    第八个条件,OSS,主要用来保存图片,可以通过阿里云官方去购买服务,并且创建 Bucket。

    然后配置 AccessKey。

    针对星球用户open in new window,我会开放自己的 accessKeyId 和 accessKeySecret,请勿外泄,免得被恶意攻击。

    下载编程喵(codingmore)源码

    编程喵一共有三个仓库,分别是:

    编程喵 🐱 是一个非常纯粹的前后端分离项目,后端用到的技术包括:

    • Spring Boot 容器+MVC 框架
    • SpringSecurity 认证和授权框架
    • MyBatis ORM 框架
    • MyBatis-Plus MyBatis 增强工具
    • Nginx 静态资源服务器
    • Druid 数据库连接池
    • OSS 对象存储
    • Redis 缓存中间件
    • MySQL 关系型数据库
    • Swagger-UI 文档生成工具
    • Knife4j Swagger 美化增强工具
    • Hibernator-Validator 验证框架
    • Logback 日志框架
    • Lombok 简化对象封装工具
    • Hutool Java 工具类库

    前端用到的技术包括:

    • Vue 前端框架
    • Vue-router 路由框架
    • Vuex 全局状态管理框架
    • Element 前端 UI 框架
    • Axios 前端 HTTP 框架
    • Js-cookie cookie 管理工具
    • nprogress 进度条控件

    第一步,下载 coding-more 源码,戳链接 🔗open in new window进入到该页面。

    第二步,如果安装有 GitHub 桌面版的话,可以点击「open with GitHub desktop」,如果没有安装的话,可以点击「download zip」

    点击「show in finder」就可以看到编程喵的源码了。

    第三步,通过 Intellij IDEA 导入就可以了。

    第一次打开的话,需要稍等片刻,等待 Maven 去下载依赖包。Maven 下载完毕后,项目的结构图如下图所示。

    第四步,下载 codingmore-admin-web 源码,戳链接 🔗open in new window进入到该页面。

    源码下载完毕后,建议通过 VS Code 导入项目,VS Code 对前端项目比 Intellij IDEA 更加友好。

    部署编程喵(codingmore)源码

    01、MySQL

    第一步,安装 Navicat,这是一个图形化界面的数据库管理工具。

    安装完毕后,输入 MySQL 数据库的用户名和密码,建立本地连接。

    第二步,打开链接,新建数据库 codingmore,导入编程喵的 DB 文件。

    DB 文件放在 coding-more/doc 目录下。

    导入成功后,可以看到目前 codingmore 所用到的 27 个数据库文件,其中 qrtz 开头的是定时任务的持久化表,剩余是编程喵的数据库表文件。

    然后,修改 codingmore-admin/src/main/resources/application-dev.yml 文件中的 spring.datasource.username、password、url 等,该为你本地的用户名、密码和数据库链接地址(Web 管理端)。

    修改 codingmore-web/src/main/resources/application-dev.yml 文件中的 spring.datasource.username、password、url 等,该为你本地的用户名、密码和数据库链接地址(Web 前端)。

    02、Redis

    执行 redis-server 启动 Redis 服务即可,不需要额外配置。

    记住 PID,如果想关闭的话,使用 kill -9 PID 大法就可以了。

    然后,修改 codingmore-admin/src/main/resources/application-dev.yml 文件中的 spring.redis.host、database、port、password、timeout 等,该为你本地的 Redis 链接信息,一般默认就好(Web 管理端)。

    修改 codingmore-web/src/main/resources/application-dev.yml 文件中的 spring.redis.host、database、port、password、timeout 等,该为你本地的 Redis 链接信息,一般默认就好(Web 前端)。

    03、OSS

    星球用户open in new window需要自己购买阿里云的 OSS 服务和 CDN 服务。星球用户open in new window可以直接私信我获取 accessKeyId 和 accessKeySecret。

    然后修改 codingmore-admin/src/main/resources/application-dev.yml 文件中的 aliyun.cdn、oss 等。

    04、codingmore-admin

    在 Intellij IDEA 中运行 CodingmoreAdminBootstrap 主类,启动管理端后台服务。

    如果启动失败,可以尝试在 Maven 面板中选择 codingmore-admin 双击运行 clean 清除缓存。

    05、codingmore-web

    在 Intellij IDEA 中运行 CodingmoreAdminBootstrap 主类,启动管理端后台服务。

    如果启动失败,可以尝试在 Maven 面板中选择 codingmore-web 双击运行 clean 清除缓存。

    启动后,可以直接在浏览器地址栏输入 http://localhost:8081 访问 Web 前端。

    06、codingmore-admin-web

    打开终端,执行 yarn install 添加项目依赖(yarn 是 Facebook 为 node.js 运行时环境开发软件打包工具,是 npm 软件包管理器的替代品)。

    之后执行 yarn run dev 编译 admin 前端。

    在浏览器地址栏输入 http://localhost:8080 就可以访问到了。

    可以点击「获取体验账号」的方式获取登录用户名和密码。当然了,你也可以直接在 users 表上暴力破解密码。

    星球用户open in new window可以直接私信我获取超级管理员的密码。登录后就可以看到文章列表啦。

    这是文章编辑页,是不是非常清爽?

    好了,Mac 版如何下载编程喵源码,如何在本地跑起来编程喵的服务就告一段落辣,我们回头见!

    - + diff --git a/dist/springboot/mysql-druid.html b/dist/springboot/mysql-druid.html index d8973ec8..30d93be1 100644 --- a/dist/springboot/mysql-druid.html +++ b/dist/springboot/mysql-druid.html @@ -5,7 +5,7 @@ - - + -

    Spring Boot 整合 MySQL 和 Druid

    沉默王二2022年5月5日
    • Java企业级开发
    • Spring Boot
    大约 7 分钟

    MySQL 简介

    MySQL 是目前项目中运用最广泛的关系型数据库,无论是互联网大厂,还是中小型公司,几乎都在用。

    MySQL 体积小、速度快、源码开放,所以广受开发者喜爱。

    MySQL 的安装非常简单,针对不同的操作系统,MySQL 都提供了安装包的下载。

    MySQL 目前主推的版本是 8.0,参考手册的地址如下所示:

    https://dev.mysql.com/doc/refman/8.0/en/open in new window

    如何安装 MySQL

    如果有云服务器的话,建议安装在云服务器上,这样就可以长时间运行 MySQL 而不用担心服务重启的问题。按照步骤参照下面的文档。

    https://dev.mysql.com/doc/refman/8.0/en/linux-installation.htmlopen in new window

    也可以直接通过宝塔面板的形式来安装,这样更省事省力省心。

    宝塔面板安装脚本地址:https://www.bt.cn/new/download.htmlopen in new window

    安装完成后,就可以在数据库管理页面添加数据库并且进行管理了。

    如果是 Windows 用户的话,安装步骤参照下面的文档。

    https://dev.mysql.com/doc/refman/8.0/en/windows-installation.htmlopen in new window

    如果是 macOS 用户的话,安装步骤参照下面的文档。

    https://dev.mysql.com/doc/refman/8.0/en/macos-installation-pkg.htmlopen in new window

    Windows 和 macOS 的安装都非常的简单,主要就是下载对应操作系统的 MySQL 包安装管理器。

    然后按照包安装向导的提示一步步傻瓜式安装即可。

    Spring Boot 整合 MySQL 数据库

    Spring Boot 整合 MySQL 数据库非常简单,只需要添加 MySQL 依赖并在配置文件中添加数据库配置即可。我们可以不用编写原始的访问数据库的代码,也不用调用 JDBC 或者连接池就可以访问 MySQL。

    1)使用 Intellij IDEA 新建一个 Spring Boot 项目,使用 Java 8 版本「社区版没有此功能,需要到 (Spring initializr)[https://start.spring.io/])生成项目后导入,推荐使用旗舰版,功能更加强大」。

    添加 MySQL 的 Java连接驱动依赖和 JDBC Starter。

    对应pom.xml文件中的代码:

    <dependency>
    +    

    Spring Boot 整合 MySQL 和 Druid

    沉默王二2022年5月5日
    • Java企业级开发
    • Spring Boot
    大约 7 分钟

    MySQL 简介

    MySQL 是目前项目中运用最广泛的关系型数据库,无论是互联网大厂,还是中小型公司,几乎都在用。

    MySQL 体积小、速度快、源码开放,所以广受开发者喜爱。

    MySQL 的安装非常简单,针对不同的操作系统,MySQL 都提供了安装包的下载。

    MySQL 目前主推的版本是 8.0,参考手册的地址如下所示:

    https://dev.mysql.com/doc/refman/8.0/en/open in new window

    如何安装 MySQL

    如果有云服务器的话,建议安装在云服务器上,这样就可以长时间运行 MySQL 而不用担心服务重启的问题。按照步骤参照下面的文档。

    https://dev.mysql.com/doc/refman/8.0/en/linux-installation.htmlopen in new window

    也可以直接通过宝塔面板的形式来安装,这样更省事省力省心。

    宝塔面板安装脚本地址:https://www.bt.cn/new/download.htmlopen in new window

    安装完成后,就可以在数据库管理页面添加数据库并且进行管理了。

    如果是 Windows 用户的话,安装步骤参照下面的文档。

    https://dev.mysql.com/doc/refman/8.0/en/windows-installation.htmlopen in new window

    如果是 macOS 用户的话,安装步骤参照下面的文档。

    https://dev.mysql.com/doc/refman/8.0/en/macos-installation-pkg.htmlopen in new window

    Windows 和 macOS 的安装都非常的简单,主要就是下载对应操作系统的 MySQL 包安装管理器。

    然后按照包安装向导的提示一步步傻瓜式安装即可。

    Spring Boot 整合 MySQL 数据库

    Spring Boot 整合 MySQL 数据库非常简单,只需要添加 MySQL 依赖并在配置文件中添加数据库配置即可。我们可以不用编写原始的访问数据库的代码,也不用调用 JDBC 或者连接池就可以访问 MySQL。

    1)使用 Intellij IDEA 新建一个 Spring Boot 项目,使用 Java 8 版本「社区版没有此功能,需要到 (Spring initializr)[https://start.spring.io/])生成项目后导入,推荐使用旗舰版,功能更加强大」。

    添加 MySQL 的 Java连接驱动依赖和 JDBC Starter。

    对应pom.xml文件中的代码:

    <dependency>
         <groupId>mysql</groupId>
         <artifactId>mysql-connector-java</artifactId>
         <scope>runtime</scope>
    @@ -110,12 +110,12 @@ COMMIT;
             log.info("用户{}",users);
         }
     }
    -

    Spring Boot 的测试类主要放置在 src/test/java 目录下面,项目创建成功后,Spring Boot 会根据项目名称自动为我们生成测试类。

    比如说本次项目名为 codingmore-mysql,那么测试类名为 CodingmoreMysqlApplicationTests。

    @SpringBootTest 注解能够测试我们的项目主类,该项目为 CodingmoreMysqlApplication。

    @Test 注解是 junit 单元测试的注解,表示该方法为测试方法。

    JdbcTemplate 一个通过 JDBC 连接数据库的工具类,spring-boot-starter-jdbc 依赖中包含了该类。

    @Resource 注解会帮我们在 Spring Boot 启动的时候注入一个 JdbcTemplate 的对象。

    jdbcTemplate.query() 方法通过 SQL 语句和匿名内部类参数的形式,执行 SQL 并查询结果集。

    RowMapper 就是查询到的每一行数据对象,我们可以通过重写 mapRow 方法将数据结果集封装到 User 对象上。

    右键菜单运行 testMysql 方法就可以在日志中看到 SQL 执行的结果。

    如何通过 Navicat 连接 MySQL

    Navicat 是一个从我参加工作到现在一直都在用的 MySQL 客户端工具,通过 Navicat 可以轻松连接数据库,并执行增删改查操作。

    连接数据库也非常的简单,只需要填写主机 IP 地址、端口、用户名和密码即可。

    如何通过 Intellij IDEA 连接 MySQL

    除了 Navicat,还可以使用 Intellij IDEA 直连 MySQL。

    点击「database」面板,在左上角选择 + 号,选择 DataSource,再选择 MySQL。

    在弹出面板中填写连接信息。

    如果是第一次连接 MySQL 的话,记得点击「download」下载 MySQL 驱动,之后点击「test connection」测试是否链接成功,如果出现以下界面,则表示 OK。

    选择右侧的数据库表,双击,就可以查看到数据了。

    在「console」SQL 查询面板里可以编写 SQL 语句来执行增删改查操作。

    Spring Boot 整合 Druid

    Druid 是阿里巴巴开源的一款数据库连接池,结合了C3P0、DBCP 等 DB 池的优点,同时还加入了日志监控。

    Druid 在 GitHub 上已经收获了 25.4k 的 star,可以说非常的知名,从简介上也能看得出,Druid 就是为了监控而生的。

    https://github.com/alibaba/druid/open in new window

    Druid 包含了三个重要的组成部分:

    • DruidDriver,能够提供基于 Filter-Chain 模式的插件体系;
    • DruidDataSource,高效可管理的数据库连接池;
    • SQLParser,支持所有 JDBC 兼容的数据库,包括 Oracle、MySQL 等。

    Spring Boot2.0 以上默认使用的是 Hikari 连接池,我们从之前的日志信息里就可以看得到。

    那如果我们想使用 Druid 的话,该怎么整合呢?

    这次我们直接在编程喵项目后端项目 codingmore-admin 上进行修改。

    第一步,在 pom.xml 文件中添加 Druid 的依赖,官方已经提供了 starter,我们直接使用。

    <dependency>
    +

    Spring Boot 的测试类主要放置在 src/test/java 目录下面,项目创建成功后,Spring Boot 会根据项目名称自动为我们生成测试类。

    比如说本次项目名为 codingmore-mysql,那么测试类名为 CodingmoreMysqlApplicationTests。

    @SpringBootTest 注解能够测试我们的项目主类,该项目为 CodingmoreMysqlApplication。

    @Test 注解是 junit 单元测试的注解,表示该方法为测试方法。

    JdbcTemplate 一个通过 JDBC 连接数据库的工具类,spring-boot-starter-jdbc 依赖中包含了该类。

    @Resource 注解会帮我们在 Spring Boot 启动的时候注入一个 JdbcTemplate 的对象。

    jdbcTemplate.query() 方法通过 SQL 语句和匿名内部类参数的形式,执行 SQL 并查询结果集。

    RowMapper 就是查询到的每一行数据对象,我们可以通过重写 mapRow 方法将数据结果集封装到 User 对象上。

    右键菜单运行 testMysql 方法就可以在日志中看到 SQL 执行的结果。

    如何通过 Navicat 连接 MySQL

    Navicat 是一个从我参加工作到现在一直都在用的 MySQL 客户端工具,通过 Navicat 可以轻松连接数据库,并执行增删改查操作。

    连接数据库也非常的简单,只需要填写主机 IP 地址、端口、用户名和密码即可。

    如何通过 Intellij IDEA 连接 MySQL

    除了 Navicat,还可以使用 Intellij IDEA 直连 MySQL。

    点击「database」面板,在左上角选择 + 号,选择 DataSource,再选择 MySQL。

    在弹出面板中填写连接信息。

    如果是第一次连接 MySQL 的话,记得点击「download」下载 MySQL 驱动,之后点击「test connection」测试是否链接成功,如果出现以下界面,则表示 OK。

    选择右侧的数据库表,双击,就可以查看到数据了。

    在「console」SQL 查询面板里可以编写 SQL 语句来执行增删改查操作。

    Spring Boot 整合 Druid

    Druid 是阿里巴巴开源的一款数据库连接池,结合了C3P0、DBCP 等 DB 池的优点,同时还加入了日志监控。

    Druid 在 GitHub 上已经收获了 25.4k 的 star,可以说非常的知名,从简介上也能看得出,Druid 就是为了监控而生的。

    https://github.com/alibaba/druid/open in new window

    Druid 包含了三个重要的组成部分:

    • DruidDriver,能够提供基于 Filter-Chain 模式的插件体系;
    • DruidDataSource,高效可管理的数据库连接池;
    • SQLParser,支持所有 JDBC 兼容的数据库,包括 Oracle、MySQL 等。

    Spring Boot2.0 以上默认使用的是 Hikari 连接池,我们从之前的日志信息里就可以看得到。

    那如果我们想使用 Druid 的话,该怎么整合呢?

    这次我们直接在编程喵项目后端项目 codingmore-admin 上进行修改。

    第一步,在 pom.xml 文件中添加 Druid 的依赖,官方已经提供了 starter,我们直接使用。

    <dependency>
         <groupId>com.alibaba</groupId>
         <artifactId>druid-spring-boot-starter</artifactId>
         <version>1.1.23</version>
     </dependency>
    -

    第二步,在 application.yml 文件中添加 Druid 配置。


    更多内容,只针对《Java 程序员进阶之路》星球用户开放,需要的小伙伴可以戳链接🔗加入我们的星球,一起学习,一起卷。。编程喵🐱是一个 Spring Boot+Vue 的前后端分离项目,融合了市面上绝大多数流行的技术要点。通过学习实战项目,你可以将所学的知识通过实践进行检验、你可以拓宽自己的技术边界,你可以掌握一个真正的实战项目是如何从 0 到 1 的。


    源码地址


    - +

    第二步,在 application.yml 文件中添加 Druid 配置。


    更多内容,只针对《Java 程序员进阶之路》星球用户开放,需要的小伙伴可以戳链接🔗open in new window加入我们的星球,一起学习,一起卷。。编程喵🐱是一个 Spring Boot+Vue 的前后端分离项目,融合了市面上绝大多数流行的技术要点。通过学习实战项目,你可以将所学的知识通过实践进行检验、你可以拓宽自己的技术边界,你可以掌握一个真正的实战项目是如何从 0 到 1 的。


    源码地址


    + diff --git a/dist/springboot/oss.html b/dist/springboot/oss.html index 2f550971..52055dbf 100644 --- a/dist/springboot/oss.html +++ b/dist/springboot/oss.html @@ -5,7 +5,7 @@ - - + -

    崩溃!我带的实习生竟然把图片直接存到了服务器上!

    沉默王二2022年3月22日
    • Java企业级开发
    • Spring Boot
    大约 5 分钟

    崩溃!我带的实习生竟然把图片直接存到了服务器上!

    小二是新来的实习生,作为技术 leader,我给他安排了一个非常简单的练手任务,把前端 markdown 编辑器里上传的图片保存到服务器端,结果他真的就把图片直接保存到了服务器上,这下可把我气坏了,就不能搞个对象存储服务,比如说 OSS、MinIO?

    他理直气壮地反驳道:“谁让你不讲清楚,我去找老板把你开掉!”我瞬间就怂了,说,“来来来,我手把手教你怎么把图片保存到 OSS 上,好不好?”

    “不用了,还是我来教你吧。”小二非常自信,下面是他在 Spring Boot 应用中整合 OSS 做的记录。

    特此声明:阿里云 OSS 的产品负责人看到后请自觉过来结算下推广费用(狗头)。真心讲:Spring Boot+OSS 在实际开发中挺常见的。

    一、开通 OSS

    OSS 也就是 Object Storage Service,是阿里云提供的一套对象存储服务,国内的竞品还有七牛云的 Kodo和腾讯云的COS。

    第一步,登录阿里云官网,搜索“OSS”关键字,进入 OSS 产品页。

    第二步,如果是 OSS 新用户的话,可以享受 6 个月的新人专享优惠价,不过续费的时候还是会肉疼。

    第三步,进入 OSS 管理控制台,点击「Bucket 列表」,点击「创建 Bucket」。

    Bucket 的词面意思是桶,这里指存储空间,就是用于存储对象的容器。注意读写权限为“公共读”,也就是允许互联网用户访问云空间上的图片。

    第四步,点击「确定」就算是开通成功了。

    二、整合 OSS

    第一步,在 pom.xml 文件中添加 OSS 的依赖。

    <!-- 阿里云 OSS -->
    +    

    崩溃!我带的实习生竟然把图片直接存到了服务器上!

    沉默王二2022年3月22日
    • Java企业级开发
    • Spring Boot
    大约 5 分钟

    崩溃!我带的实习生竟然把图片直接存到了服务器上!

    小二是新来的实习生,作为技术 leader,我给他安排了一个非常简单的练手任务,把前端 markdown 编辑器里上传的图片保存到服务器端,结果他真的就把图片直接保存到了服务器上,这下可把我气坏了,就不能搞个对象存储服务,比如说 OSS、MinIO?

    他理直气壮地反驳道:“谁让你不讲清楚,我去找老板把你开掉!”我瞬间就怂了,说,“来来来,我手把手教你怎么把图片保存到 OSS 上,好不好?”

    “不用了,还是我来教你吧。”小二非常自信,下面是他在 Spring Boot 应用中整合 OSS 做的记录。

    特此声明:阿里云 OSS 的产品负责人看到后请自觉过来结算下推广费用(狗头)。真心讲:Spring Boot+OSS 在实际开发中挺常见的。

    一、开通 OSS

    OSS 也就是 Object Storage Service,是阿里云提供的一套对象存储服务,国内的竞品还有七牛云的 Kodo和腾讯云的COS。

    第一步,登录阿里云官网,搜索“OSS”关键字,进入 OSS 产品页。

    第二步,如果是 OSS 新用户的话,可以享受 6 个月的新人专享优惠价,不过续费的时候还是会肉疼。

    第三步,进入 OSS 管理控制台,点击「Bucket 列表」,点击「创建 Bucket」。

    Bucket 的词面意思是桶,这里指存储空间,就是用于存储对象的容器。注意读写权限为“公共读”,也就是允许互联网用户访问云空间上的图片。

    第四步,点击「确定」就算是开通成功了。

    二、整合 OSS

    第一步,在 pom.xml 文件中添加 OSS 的依赖。

    <!-- 阿里云 OSS -->
     <dependency>
         <groupId>com.aliyun.oss</groupId>
         <artifactId>aliyun-sdk-oss</artifactId>
    @@ -190,7 +190,7 @@
         }
         return formatOSSPath(objectName);
     }
    -

    第三步,通过 Web 管理端来测试外链是否转链成功。先找两张外链的图片,可以看到 markdown 在预览的时候就不显示。

    然后我们点击发布,可以看到两张图片都正常显示了,因为转成了 OSS 的图片访问地址。

    五、小结

    综上来看,实习生小二在 Spring Boot 中整合 OSS 的代码还是挺靠谱的。也许 OSS+CDN 才是图床的最好解决方案,不过阿里云的 HTTPS CDN 在 GitHub 上无法回源open in new window导致图片不显示的问题仍然没有得到有效的解决。

    需要源码的小伙伴可以直接到编程喵🐱源码路径拉取:

    https://github.com/itwanger/coding-moreopen in new window


    - +

    第三步,通过 Web 管理端来测试外链是否转链成功。先找两张外链的图片,可以看到 markdown 在预览的时候就不显示。

    然后我们点击发布,可以看到两张图片都正常显示了,因为转成了 OSS 的图片访问地址。

    五、小结

    综上来看,实习生小二在 Spring Boot 中整合 OSS 的代码还是挺靠谱的。也许 OSS+CDN 才是图床的最好解决方案,不过阿里云的 HTTPS CDN 在 GitHub 上无法回源open in new window导致图片不显示的问题仍然没有得到有效的解决。

    需要源码的小伙伴可以直接到编程喵🐱源码路径拉取:

    https://github.com/itwanger/coding-moreopen in new window


    + diff --git a/dist/springboot/springtask.html b/dist/springboot/springtask.html index b3d90ba0..67512478 100644 --- a/dist/springboot/springtask.html +++ b/dist/springboot/springtask.html @@ -5,7 +5,7 @@ - - + -

    Spring Boot 整合 Spring Task 实现定时任务

    沉默王二2022年5月20日
    • Java企业级开发
    • Spring Boot
    大约 8 分钟

    定时任务的应用场景其实蛮常见的:

    • 数据备份
    • 订单未支付则自动取消
    • 定时爬取数据
    • 定时推送信息
    • 定时发布文章
    • 定时生成报表
    • 等等(想不到其他场景了,就只能等等来凑,等等也算是一种定时的场景吧!)

    Timer

    JDK 1.3 就开始支持的一种定时任务的实现方式。内部通过 TaskQueue 的类来存放定时任务,用起来比较简单,但缺陷比较多,比如说一个 Timer 就会起一个线程,任务多了性能就非常差,再比如说如果执行任务期间某个 TimerTask 耗时比较久,就会影响其他任务的调度。

    @Slf4j
    +    

    Spring Boot 整合 Spring Task 实现定时任务

    沉默王二2022年5月20日
    • Java企业级开发
    • Spring Boot
    大约 8 分钟

    定时任务的应用场景其实蛮常见的:

    • 数据备份
    • 订单未支付则自动取消
    • 定时爬取数据
    • 定时推送信息
    • 定时发布文章
    • 定时生成报表
    • 等等(想不到其他场景了,就只能等等来凑,等等也算是一种定时的场景吧!)

    Timer

    JDK 1.3 就开始支持的一种定时任务的实现方式。内部通过 TaskQueue 的类来存放定时任务,用起来比较简单,但缺陷比较多,比如说一个 Timer 就会起一个线程,任务多了性能就非常差,再比如说如果执行任务期间某个 TimerTask 耗时比较久,就会影响其他任务的调度。

    @Slf4j
     public class TimerDemo {
         public static void main(String[] args) {
             TimerTask task = new TimerTask() {
    @@ -157,7 +157,7 @@
     2022-04-27 15:33:07.390  INFO 4421 --- [led-task-pool-1] c.codingmore.component.PublishPostTask   : Fixed Rate Task : The time is now 2022-04-27 15:33:07
     2022-04-27 15:33:09.391  INFO 4421 --- [led-task-pool-1] c.codingmore.component.PublishPostTask   : Fixed Rate Task : The time is now 2022-04-27 15:33:09
     2022-04-27 15:33:13.295  INFO 4421 --- [led-task-pool-1] c.codingmore.component.PublishPostTask   : Fixed Rate Task : The time is now 2022-04-27 15:33:13
    -

    关于 Cron 表达式

    这里顺带普及一下 Cron 表达式,在定时任务中会经常会遇到。Cron 这个词来源于希腊语 chronos,原意也就是时间。

    Cron 表达式是一个含有时间意义的字符串,以 5 个空格隔开,分成 6 个时间元素。举几个例子就一目了然了。

    示例说明
    0 15 10 ? * *每天上午10:15执行任务
    0 0 10,14,16 * * ?每天10 点、14 点、16 点执行任务
    0 0 12 ? * 3每个星期三中午 12 点执行任务
    0 15 10 15 * ?每月 15 日上午 10 点 15 执行任务

    Cron 的语法格式可以总结为:

    Seconds Minutes Hours DayofMonth Month DayofWeek

    每个时间元素的取值范围,以及可出现的特殊字符如下所示。

    时间元素取值范围可出现的特殊字符
    [0,59]*,-/
    分钟[0,59]*,-/
    小时[0,59]*,-/
    日期[0,31]*,-/?LW
    月份[1,12]*,-/
    星期[1,7]*,-/?L#

    特殊字符的含义和示例如下所示。

    特殊字符含义示例
    *所有可能的值很好理解,月域中为每个月,星期域中每个星期几
    ,枚举的值很好理解,小时域中 10,14,16,就表示这几个小时可选
    -范围很好理解,分钟域中 10-19,就表示 10-19 分钟每隔一分钟执行一次
    /指定数值的增量很好理解,分钟域中 0/15,就表示每隔 15 分钟执行一次
    ?不指定值很好理解,日期域指定了星期域就不能指定值,反之亦然,因为日期域和星期域属于冲突关系
    L单词 Last 的首字母很好理解,日期域和星期域支持,表示月的最后一天或者星期的最后一天
    W除周末以外的工作日很好理解,仅日期域支持
    #每个月的第几个星期几很好理解,仅星期域支持,4#2表示某月的第二个星期四

    小结

    Spring Task 虽然用起来很方便,但用法过去简单,很多复杂的业务逻辑是没有办法实现的,比如说编程喵的定时发布文章功能,只用 Spring Task 是没办法的。


    更多内容,只针对《Java 程序员进阶之路》星球用户开放,需要的小伙伴可以戳链接🔗加入我们的星球,一起学习,一起卷。。编程喵🐱是一个 Spring Boot+Vue 的前后端分离项目,融合了市面上绝大多数流行的技术要点。通过学习实战项目,你可以将所学的知识通过实践进行检验、你可以拓宽自己的技术边界,你可以掌握一个真正的实战项目是如何从 0 到 1 的。


    源码路径

    - +

    关于 Cron 表达式

    这里顺带普及一下 Cron 表达式,在定时任务中会经常会遇到。Cron 这个词来源于希腊语 chronos,原意也就是时间。

    Cron 表达式是一个含有时间意义的字符串,以 5 个空格隔开,分成 6 个时间元素。举几个例子就一目了然了。

    示例说明
    0 15 10 ? * *每天上午10:15执行任务
    0 0 10,14,16 * * ?每天10 点、14 点、16 点执行任务
    0 0 12 ? * 3每个星期三中午 12 点执行任务
    0 15 10 15 * ?每月 15 日上午 10 点 15 执行任务

    Cron 的语法格式可以总结为:

    Seconds Minutes Hours DayofMonth Month DayofWeek

    每个时间元素的取值范围,以及可出现的特殊字符如下所示。

    时间元素取值范围可出现的特殊字符
    [0,59]*,-/
    分钟[0,59]*,-/
    小时[0,59]*,-/
    日期[0,31]*,-/?LW
    月份[1,12]*,-/
    星期[1,7]*,-/?L#

    特殊字符的含义和示例如下所示。

    特殊字符含义示例
    *所有可能的值很好理解,月域中为每个月,星期域中每个星期几
    ,枚举的值很好理解,小时域中 10,14,16,就表示这几个小时可选
    -范围很好理解,分钟域中 10-19,就表示 10-19 分钟每隔一分钟执行一次
    /指定数值的增量很好理解,分钟域中 0/15,就表示每隔 15 分钟执行一次
    ?不指定值很好理解,日期域指定了星期域就不能指定值,反之亦然,因为日期域和星期域属于冲突关系
    L单词 Last 的首字母很好理解,日期域和星期域支持,表示月的最后一天或者星期的最后一天
    W除周末以外的工作日很好理解,仅日期域支持
    #每个月的第几个星期几很好理解,仅星期域支持,4#2表示某月的第二个星期四

    小结

    Spring Task 虽然用起来很方便,但用法过去简单,很多复杂的业务逻辑是没有办法实现的,比如说编程喵的定时发布文章功能,只用 Spring Task 是没办法的。


    更多内容,只针对《Java 程序员进阶之路》星球用户开放,需要的小伙伴可以戳链接🔗open in new window加入我们的星球,一起学习,一起卷。。编程喵🐱是一个 Spring Boot+Vue 的前后端分离项目,融合了市面上绝大多数流行的技术要点。通过学习实战项目,你可以将所学的知识通过实践进行检验、你可以拓宽自己的技术边界,你可以掌握一个真正的实战项目是如何从 0 到 1 的。


    源码路径

    + diff --git a/dist/springboot/swagger.html b/dist/springboot/swagger.html index 491aa242..383b493f 100644 --- a/dist/springboot/swagger.html +++ b/dist/springboot/swagger.html @@ -5,7 +5,7 @@ - - + -

    Spring Boot整合Swagger-UI实现在线API文档

    沉默王二2022年5月18日
    • Java企业级开发
    • Spring Boot
    大约 8 分钟

    关于 Swagger

    Swagger 是一个用于生成、描述和调用 RESTful 接口的 Web 服务。

    想要理解RESTful架构的话,可以戳链接查看阮一峰老师的博客:https://www.ruanyifeng.com/blog/2011/09/restful.htmlopen in new window

    换句话说,Swagger 就是将项目中想要暴露的接口展示在页面上,开发者可以直接进行接口调用和测试,能在很大程度上提升开发的效率。

    比如说,一个后端程序员写了一个登录接口,想要测试自己写的接口是否符合预期的话,就得先模拟用户登录的行为,包括正常的行为(输入正确的用户名和密码)和异常的行为(输入错误的用户名和密码),这就要命了。

    但有了 Swagger 后,可以通过简单的配置生成接口的展示页面,把接口的请求参数、返回结果通过可视化的形式展示出来,并且提供了便捷的测试服务。

    • 前端程序员可以通过接口展示页面查看需要传递的请求参数和返回的数据格式,不需要后端程序员再编写接口文档了;
    • 后端程序员可以通过接口展示页面测试验证自己的接口是否符合预期,降低了开发阶段的调试成本。

    前后端分离就可以很完美的落地了,有没有?

    Swagger 官网地址:https://swagger.io/open in new window

    那在 Swagger 出现之前,局面就比较糟糕。前端经常抱怨后端给的接口文档与实际情况不一致。后端又觉得编写及维护接口文档会耗费不少精力,经常来不及更新。

    大家都被无情地折磨,痛不堪言。。。

    Swagger 定义了一套规范,你只需要按照它的规范去定义接口及接口相关的信息,然后通过 Swagger 衍生出来的一系列工具,就可以生成各种格式的接口文档,甚至还可以生成多种语言的客户端和服务端代码,以及在线接口调试页面等等。

    那只要及时更新 Swagger 的描述文件,就可以自动生成接口文档了,做到调用端代码、服务端代码以及接口文档的一致性。

    整合 Swagger-UI

    Swagger-UI 是一套 HTML/CSS/JS 框架,用于渲染 Swagger 文档,以便提供美观的 API 文档界面。

    也就是说,Swagger-UI 是 Swagger 提供的一套可视化渲染组件,支持在线导入描述文件和本地部署UI项目。

    第一步,在 pom.xml 文件中添加 Swagger 的 starter。

    <dependency>
    +    

    Spring Boot整合Swagger-UI实现在线API文档

    沉默王二2022年5月18日
    • Java企业级开发
    • Spring Boot
    大约 8 分钟

    关于 Swagger

    Swagger 是一个用于生成、描述和调用 RESTful 接口的 Web 服务。

    想要理解RESTful架构的话,可以戳链接查看阮一峰老师的博客:https://www.ruanyifeng.com/blog/2011/09/restful.htmlopen in new window

    换句话说,Swagger 就是将项目中想要暴露的接口展示在页面上,开发者可以直接进行接口调用和测试,能在很大程度上提升开发的效率。

    比如说,一个后端程序员写了一个登录接口,想要测试自己写的接口是否符合预期的话,就得先模拟用户登录的行为,包括正常的行为(输入正确的用户名和密码)和异常的行为(输入错误的用户名和密码),这就要命了。

    但有了 Swagger 后,可以通过简单的配置生成接口的展示页面,把接口的请求参数、返回结果通过可视化的形式展示出来,并且提供了便捷的测试服务。

    • 前端程序员可以通过接口展示页面查看需要传递的请求参数和返回的数据格式,不需要后端程序员再编写接口文档了;
    • 后端程序员可以通过接口展示页面测试验证自己的接口是否符合预期,降低了开发阶段的调试成本。

    前后端分离就可以很完美的落地了,有没有?

    Swagger 官网地址:https://swagger.io/open in new window

    那在 Swagger 出现之前,局面就比较糟糕。前端经常抱怨后端给的接口文档与实际情况不一致。后端又觉得编写及维护接口文档会耗费不少精力,经常来不及更新。

    大家都被无情地折磨,痛不堪言。。。

    Swagger 定义了一套规范,你只需要按照它的规范去定义接口及接口相关的信息,然后通过 Swagger 衍生出来的一系列工具,就可以生成各种格式的接口文档,甚至还可以生成多种语言的客户端和服务端代码,以及在线接口调试页面等等。

    那只要及时更新 Swagger 的描述文件,就可以自动生成接口文档了,做到调用端代码、服务端代码以及接口文档的一致性。

    整合 Swagger-UI

    Swagger-UI 是一套 HTML/CSS/JS 框架,用于渲染 Swagger 文档,以便提供美观的 API 文档界面。

    也就是说,Swagger-UI 是 Swagger 提供的一套可视化渲染组件,支持在线导入描述文件和本地部署UI项目。

    第一步,在 pom.xml 文件中添加 Swagger 的 starter。

    <dependency>
         <groupId>io.springfox</groupId>
         <artifactId>springfox-boot-starter</artifactId>
         <version>3.0.0</version>
    @@ -87,7 +87,7 @@
             return "沉默王二又帅又丑";
         }
     }
    -

    1)@Api注解,用在类上,该注解将控制器标注为一个 Swagger 资源。该注解有 3 个属性:

    • tags,具有相同标签的 API 会被归在一组内展示
    • value,如果 tags 没有定义,value 将作为 API 的 tags 使用。
    • description,已废弃

    2)@ApiOperation 注解,用在方法上,描述这个方法是做什么用的。该注解有 4 个属性:

    • value 操作的简单说明,长度为120个字母,60个汉字。
    • notes 对操作的详细说明。
    • httpMethod HTTP请求的动作名,可选值有:"GET", "HEAD", "POST", "PUT", "DELETE", "OPTIONS" and "PATCH"。
    • code 默认为200,有效值必须符合标准的HTTP Status Code Definitions。

    3)@RestController 注解,用在类上,是@ResponseBody和@Controller的组合注解,如果方法要返回 JSON 的话,可省去 @ResponseBody 注解。

    4)@RequestMapping 注解,可用在类(父路径)和方法(子路径)上,主要用来定义 API 的请求路径和请求类型。该注解有 6 个属性:

    • value,指定请求的实际地址
    • method,指定请求的method类型, GET、POST、PUT、DELETE等
    • consumes,指定处理请求的提交内容类型(Content-Type),例如 application/json, text/html
    • produces,指定返回的内容类型,仅当request请求头中的(Accept)类型中包含该指定类型才返回
    • params,指定request中必须包含某些参数值
    • headers,指定request中必须包含某些指定的header值

    第四步,启动服务,在浏览器中输入 http://localhost:8080/swagger-ui/ 就可以访问 Swagger 生成的 API 文档了。

    点开 get 请求的面板,点击「try it out」再点击「excute」可以查看接口返回的数据。

    版本不兼容

    在 Spring Boot 整合 Swagger 的过程中,我发现一个大 bug,Spring Boot 2.6.7 版本和 springfox 3.0.0 版本不兼容,启动的时候直接就报错了。

    Caused by: java.lang.NullPointerException: Cannot invoke "org.springframework.web.servlet.mvc.condition.PatternsRequestCondition.getPatterns()" because "this.condition" is null

    一路跟踪下来,发现 GitHub 上确认有人在 Spring Boot 仓库下提到了这个 bug。

    https://github.com/spring-projects/spring-boot/issues/28794open in new window

    Spring Boot 说这是 springfox 的 bug。

    追踪过来一看,确实。

    有人提到的解决方案是切换到 SpringDoc。

    这样就需要切换注解 @Api → @Tag@ApiOperation(value = "foo", notes = "bar") → @Operation(summary = "foo", description = "bar"),对旧项目不是很友好,如果是新项目的话,倒是可以直接尝试 SpringDoc。

    还有人提出的解决方案是:

    • 先将匹配策略调整为 ant-path-matcher(application.yml)。
    spring:
    +

    1)@Api注解,用在类上,该注解将控制器标注为一个 Swagger 资源。该注解有 3 个属性:

    • tags,具有相同标签的 API 会被归在一组内展示
    • value,如果 tags 没有定义,value 将作为 API 的 tags 使用。
    • description,已废弃

    2)@ApiOperation 注解,用在方法上,描述这个方法是做什么用的。该注解有 4 个属性:

    • value 操作的简单说明,长度为120个字母,60个汉字。
    • notes 对操作的详细说明。
    • httpMethod HTTP请求的动作名,可选值有:"GET", "HEAD", "POST", "PUT", "DELETE", "OPTIONS" and "PATCH"。
    • code 默认为200,有效值必须符合标准的HTTP Status Code Definitions。

    3)@RestController 注解,用在类上,是@ResponseBody和@Controller的组合注解,如果方法要返回 JSON 的话,可省去 @ResponseBody 注解。

    4)@RequestMapping 注解,可用在类(父路径)和方法(子路径)上,主要用来定义 API 的请求路径和请求类型。该注解有 6 个属性:

    • value,指定请求的实际地址
    • method,指定请求的method类型, GET、POST、PUT、DELETE等
    • consumes,指定处理请求的提交内容类型(Content-Type),例如 application/json, text/html
    • produces,指定返回的内容类型,仅当request请求头中的(Accept)类型中包含该指定类型才返回
    • params,指定request中必须包含某些参数值
    • headers,指定request中必须包含某些指定的header值

    第四步,启动服务,在浏览器中输入 http://localhost:8080/swagger-ui/ 就可以访问 Swagger 生成的 API 文档了。

    点开 get 请求的面板,点击「try it out」再点击「excute」可以查看接口返回的数据。

    版本不兼容

    在 Spring Boot 整合 Swagger 的过程中,我发现一个大 bug,Spring Boot 2.6.7 版本和 springfox 3.0.0 版本不兼容,启动的时候直接就报错了。

    Caused by: java.lang.NullPointerException: Cannot invoke "org.springframework.web.servlet.mvc.condition.PatternsRequestCondition.getPatterns()" because "this.condition" is null

    一路跟踪下来,发现 GitHub 上确认有人在 Spring Boot 仓库下提到了这个 bug。

    https://github.com/spring-projects/spring-boot/issues/28794open in new window

    Spring Boot 说这是 springfox 的 bug。

    追踪过来一看,确实。

    有人提到的解决方案是切换到 SpringDoc。

    这样就需要切换注解 @Api → @Tag@ApiOperation(value = "foo", notes = "bar") → @Operation(summary = "foo", description = "bar"),对旧项目不是很友好,如果是新项目的话,倒是可以直接尝试 SpringDoc。

    还有人提出的解决方案是:

    • 先将匹配策略调整为 ant-path-matcher(application.yml)。
    spring:
       mvc:
         path match:
           matching-strategy: ANT_PATH_MATCHER
    @@ -123,7 +123,7 @@ public static BeanPostProcessor springfoxHandlerProviderBeanPostProcessor() {
             }
         };
     }
    -

    解决方案地址:https://github.com/springfox/springfox/issues/3462open in new window

    重新编译项目,就会发现错误消失了,我只能说GitHub 仓库的 issue 区都是大神!

    查看 Swagger 接口文档,发现一切正常。

    我只能再强调一次,GitHub 仓库的 issue 区都是大神!大家遇到问题的时候,一定要多到 issue 区看看。

    至于为什么要这样做,问题的解决者给出了自己的答案。

    大致的意思就是 springfox 和 Spring 在 pathPatternsCondition 上产生了分歧,这两个步骤就是用来消除这个分歧的。

    除此之外,还有另外一种保守的做法,直接将 Spring Boot 的版本回退到更低的版本,比如说 2.4.5。

    小结

    Swagger 虽然解决了调用端代码、服务端代码以及接口文档的不一致的问题,但有一说一,Swagger-UI 实在是太丑了。


    更多内容,只针对《Java 程序员进阶之路》星球用户开放,需要的小伙伴可以戳链接🔗加入我们的星球,一起学习,一起卷。。编程喵🐱是一个 Spring Boot+Vue 的前后端分离项目,融合了市面上绝大多数流行的技术要点。通过学习实战项目,你可以将所学的知识通过实践进行检验、你可以拓宽自己的技术边界,你可以掌握一个真正的实战项目是如何从 0 到 1 的。


    源码路径

    - +

    解决方案地址:https://github.com/springfox/springfox/issues/3462open in new window

    重新编译项目,就会发现错误消失了,我只能说GitHub 仓库的 issue 区都是大神!

    查看 Swagger 接口文档,发现一切正常。

    我只能再强调一次,GitHub 仓库的 issue 区都是大神!大家遇到问题的时候,一定要多到 issue 区看看。

    至于为什么要这样做,问题的解决者给出了自己的答案。

    大致的意思就是 springfox 和 Spring 在 pathPatternsCondition 上产生了分歧,这两个步骤就是用来消除这个分歧的。

    除此之外,还有另外一种保守的做法,直接将 Spring Boot 的版本回退到更低的版本,比如说 2.4.5。

    小结

    Swagger 虽然解决了调用端代码、服务端代码以及接口文档的不一致的问题,但有一说一,Swagger-UI 实在是太丑了。


    更多内容,只针对《Java 程序员进阶之路》星球用户开放,需要的小伙伴可以戳链接🔗open in new window加入我们的星球,一起学习,一起卷。。编程喵🐱是一个 Spring Boot+Vue 的前后端分离项目,融合了市面上绝大多数流行的技术要点。通过学习实战项目,你可以将所学的知识通过实践进行检验、你可以拓宽自己的技术边界,你可以掌握一个真正的实战项目是如何从 0 到 1 的。


    源码路径

    + diff --git a/dist/springboot/thymeleaf.html b/dist/springboot/thymeleaf.html index 301c2bd9..9be15aae 100644 --- a/dist/springboot/thymeleaf.html +++ b/dist/springboot/thymeleaf.html @@ -5,7 +5,7 @@ - - + -

    Spring Boot 整合 Thymeleaf 模板引擎

    沉默王二2022年5月21日
    • Java企业级开发
    • Spring Boot
    大约 3 分钟

    关于 Thymeleaf

    Thymeleaf 是一个优秀的、面向 Java 的 HTML 页面模板,具有丰富的标签语言和函数。在 JSP 被淘汰之后,Thymeleaf 取而代之成为了 Spring Boot 推荐的模板引擎。

    Thymeleaf 在有网和没网的环境下都可以正常工作,既能让美工在浏览器中查看页面的静态效果,也能让程序员在服务器查看带数据的动态页面效果。

    这是因为 Thymeleaf 支持 HTML 原型,在 HTML 标签里增加额外的属性来达到模板+数据的展示方式。

    浏览器在解释 HTML 的时候会忽略未定义的标签属性,所以 Thymeleaf 可以静态地运行;当有数据返回页面时,Thymeleaf 标签会动态地替换静态内容。

    下面列举一些 Thymeleaf 常用的表达式、标签和函数。

    1)常用表达式

    • ${...}变量表达式
    • *{...}选择表达式
    • #{...}文字表达式
    • @{...}URL 表达式
    • #maps 对象表达式

    2)常用标签

    • th:action 定义服务器端控制器路径。
    • th:each 循环语句
    • th:field 表单字段
    • th:href URL 链接
    • th:id div 标签中的 ID
    • th:if 条件判断
    • th:include 引入文件
    • th:fragment 定义代码片段
    • th:object 替换对象
    • th:src 图片地址
    • th:text 文本
    • th:value 属性值

    3)常用函数

    • #dates 日期函数
    • #lists 列表函数
    • #arrays 数组函数
    • #strings 字符串函数
    • #numbers 数字函数
    • #calendars 日历函数
    • #objects 对象函数
    • #bools 布尔函数

    想要查看更多 Thymeleaf 表达式、标签、函数等内容,可以到 Thymeleaf 官网:

    https://www.thymeleaf.org/open in new window

    整合 Thymeleaf

    第一步,在 pom.xml 文件中添加 Thymeleaf 的 stater

    <dependency>
    +    

    Spring Boot 整合 Thymeleaf 模板引擎

    沉默王二2022年5月21日
    • Java企业级开发
    • Spring Boot
    大约 3 分钟

    关于 Thymeleaf

    Thymeleaf 是一个优秀的、面向 Java 的 HTML 页面模板,具有丰富的标签语言和函数。在 JSP 被淘汰之后,Thymeleaf 取而代之成为了 Spring Boot 推荐的模板引擎。

    Thymeleaf 在有网和没网的环境下都可以正常工作,既能让美工在浏览器中查看页面的静态效果,也能让程序员在服务器查看带数据的动态页面效果。

    这是因为 Thymeleaf 支持 HTML 原型,在 HTML 标签里增加额外的属性来达到模板+数据的展示方式。

    浏览器在解释 HTML 的时候会忽略未定义的标签属性,所以 Thymeleaf 可以静态地运行;当有数据返回页面时,Thymeleaf 标签会动态地替换静态内容。

    下面列举一些 Thymeleaf 常用的表达式、标签和函数。

    1)常用表达式

    • ${...}变量表达式
    • *{...}选择表达式
    • #{...}文字表达式
    • @{...}URL 表达式
    • #maps 对象表达式

    2)常用标签

    • th:action 定义服务器端控制器路径。
    • th:each 循环语句
    • th:field 表单字段
    • th:href URL 链接
    • th:id div 标签中的 ID
    • th:if 条件判断
    • th:include 引入文件
    • th:fragment 定义代码片段
    • th:object 替换对象
    • th:src 图片地址
    • th:text 文本
    • th:value 属性值

    3)常用函数

    • #dates 日期函数
    • #lists 列表函数
    • #arrays 数组函数
    • #strings 字符串函数
    • #numbers 数字函数
    • #calendars 日历函数
    • #objects 对象函数
    • #bools 布尔函数

    想要查看更多 Thymeleaf 表达式、标签、函数等内容,可以到 Thymeleaf 官网:

    https://www.thymeleaf.org/open in new window

    整合 Thymeleaf

    第一步,在 pom.xml 文件中添加 Thymeleaf 的 stater

    <dependency>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter-thymeleaf</artifactId>
     </dependency>
    @@ -80,7 +80,7 @@
         </table>
     </body>
     </html>
    -

    <html lang="zh" xmlns:th="http://www.thymeleaf.org"> 为 Thymeleaf 的命名空间,通过引入命名空间就可以在 HTML 文件中使用 Thymeleaf 标签语言,用关键字 “th”来标注。

    第五步,启动主类,如果看到以下信息表示启动成功。

    第六步,在浏览器地址栏里输入 http://localhost:8080/user/all 访问接口。

    HTTP Client


    更多内容,只针对《Java 程序员进阶之路》星球用户开放,需要的小伙伴可以戳链接🔗加入我们的星球,一起学习,一起卷。。编程喵🐱是一个 Spring Boot+Vue 的前后端分离项目,融合了市面上绝大多数流行的技术要点。通过学习实战项目,你可以将所学的知识通过实践进行检验、你可以拓宽自己的技术边界,你可以掌握一个真正的实战项目是如何从 0 到 1 的。


    源码地址

    - +

    <html lang="zh" xmlns:th="http://www.thymeleaf.org"> 为 Thymeleaf 的命名空间,通过引入命名空间就可以在 HTML 文件中使用 Thymeleaf 标签语言,用关键字 “th”来标注。

    第五步,启动主类,如果看到以下信息表示启动成功。

    第六步,在浏览器地址栏里输入 http://localhost:8080/user/all 访问接口。

    HTTP Client


    更多内容,只针对《Java 程序员进阶之路》星球用户开放,需要的小伙伴可以戳链接🔗open in new window加入我们的星球,一起学习,一起卷。。编程喵🐱是一个 Spring Boot+Vue 的前后端分离项目,融合了市面上绝大多数流行的技术要点。通过学习实战项目,你可以将所学的知识通过实践进行检验、你可以拓宽自己的技术边界,你可以掌握一个真正的实战项目是如何从 0 到 1 的。


    源码地址

    + diff --git a/dist/springboot/tomcat.html b/dist/springboot/tomcat.html index f1d6566f..0a223183 100644 --- a/dist/springboot/tomcat.html +++ b/dist/springboot/tomcat.html @@ -39,10 +39,10 @@ } - + -

    Spring Boot为什么不需要额外安装Tomcat?

    沉默王二2022年1月1日
    • Java企业级开发
    • Spring Boot
    大约 4 分钟

    Spring Boot为什么不需要额外安装Tomcat?

    首次接触 Spring Boot 的时候,绝大多数小伙伴应该和我一样好奇:

    为什么 Spring Boot 不需要额外安装 Tomcat 啊?

    到底为什么呢?让我们带着好奇心开始今天的旅程吧。

    打开上一节open in new window我们搭建好的 tobebetterjavaer 项目,找到 pom.xml 文件,可以在里面看到一个 parent 属性,代码如下:

    <parent>
    +    

    Spring Boot为什么不需要额外安装Tomcat?

    沉默王二2022年1月1日
    • Java企业级开发
    • Spring Boot
    大约 4 分钟

    Spring Boot为什么不需要额外安装Tomcat?

    首次接触 Spring Boot 的时候,绝大多数小伙伴应该和我一样好奇:

    为什么 Spring Boot 不需要额外安装 Tomcat 啊?

    到底为什么呢?让我们带着好奇心开始今天的旅程吧。

    打开上一节open in new window我们搭建好的 tobebetterjavaer 项目,找到 pom.xml 文件,可以在里面看到一个 parent 属性,代码如下:

    <parent>
     	<groupId>org.springframework.boot</groupId>
     	<artifactId>spring-boot-starter-parent</artifactId>
     	<version>2.6.1</version>
    @@ -126,6 +126,6 @@
       </dependencies>
     </project>
     

    从这里可以看出来SpringBoot默认的启动容器是Tomcat,Tomcat 的组成核心 jakarta.annotation、tomcat-embed-core、tomcat-annotations-api、org.apache.tomcat.embed 全部都通过 Maven 引入过来了。

    core 的版本是 9.0.55,Tomcat 官网上最新的 9.0.x 版本是 9.0.56,高了一个版本。

    不过无所谓,直接下载 9.0.56 的 src,对比看一下,是否大致相同。

    对比之下可以看得出,Spring Boot 引入的 Tomcat 更精简一点,大体上都是相同的,这也就是为什么Spring Boot 不需要额外安装 Tomcat 的根本原因了

    Spring Boot 的 starter 已经帮我们搞定过了。这也是Spring Boot 大行其道的重要原因,省去了开发人员配置的时间,更专注于业务逻辑的实现、性能的优化,至于那些繁杂的配置嘛,交给 Spring Boot 这个大管家就可以了,他约定好的东西,只要没问题,不需要特殊化定制,用就对了。

    - + diff --git a/dist/springboot/transaction.html b/dist/springboot/transaction.html index 35eed699..6429e9d6 100644 --- a/dist/springboot/transaction.html +++ b/dist/springboot/transaction.html @@ -5,7 +5,7 @@ - - + -

    Spring Boot 如何开启事务支持?

    沉默王二2022年5月21日
    • Java企业级开发
    • Spring Boot
    大约 14 分钟

    关于事务

    事务在逻辑上是一组操作,要么执行,要不都不执行。主要是针对数据库而言的,比如说 MySQL。

    只要记住这一点,理解事务就很容易了。在 Java 中,我们通常要在业务里面处理多个事件,比如说我们有一个保存文章的方法,它除了要保存文章本身之外,还要保存文章对应的标签,标签和文章不在同一个表里,但会通过在文章表里(posts)保存标签主键(tag_id)来关联标签表(tags):

    public void savePosts(PostsParam postsParam) {
    +    

    Spring Boot 如何开启事务支持?

    沉默王二2022年5月21日
    • Java企业级开发
    • Spring Boot
    大约 14 分钟

    关于事务

    事务在逻辑上是一组操作,要么执行,要不都不执行。主要是针对数据库而言的,比如说 MySQL。

    只要记住这一点,理解事务就很容易了。在 Java 中,我们通常要在业务里面处理多个事件,比如说我们有一个保存文章的方法,它除了要保存文章本身之外,还要保存文章对应的标签,标签和文章不在同一个表里,但会通过在文章表里(posts)保存标签主键(tag_id)来关联标签表(tags):

    public void savePosts(PostsParam postsParam) {
       // 保存文章
       save(posts);
       // 处理标签
       insertOrUpdateTag(postsParam, posts);
     }
    -

    那么此时就需要开启事务,保证文章表和标签表中的数据保持同步,要么都执行,要么都不执行。

    否则就有可能造成,文章保存成功了,但标签保存失败了,或者文章保存失败了,标签保存成功了——这些场景都不符合我们的预期。

    为了保证事务是正确可靠的,在数据库进行写入或者更新操作时,就必须得表现出 ACID 的 4 个重要特性:

    • 原子性(Atomicity):一个事务中的所有操作,要么全部完成,要么全部不完成,不会结束在中间某个环节。事务在执行过程中发生错误,会被回滚(Rollback)到事务开始前的状态,就像这个事务从来没有执行过一样。
    • 一致性(Consistency):在事务开始之前和事务结束以后,数据库的完整性没有被破坏。
    • 事务隔离(Isolation):数据库允许多个并发事务同时对其数据进行读写和修改,隔离性可以防止多个事务并发执行时由于交叉执行而导致数据的不一致。
    • 持久性(Durability):事务处理结束后,对数据的修改就是永久的,即便系统故障也不会丢失。

    其中,事务隔离又分为 4 种不同的级别,包括:

    • 未提交读(Read uncommitted),最低的隔离级别,允许“脏读”(dirty reads),事务可以看到其他事务“尚未提交”的修改。如果另一个事务回滚,那么当前事务读到的数据就是脏数据。
    • 提交读(read committed),一个事务可能会遇到不可重复读(Non Repeatable Read)的问题。不可重复读是指,在一个事务内,多次读同一数据,在这个事务还没有结束时,如果另一个事务恰好修改了这个数据,那么,在第一个事务中,两次读取的数据就可能不一致。
    • 可重复读(repeatable read),一个事务可能会遇到幻读(Phantom Read)的问题。幻读是指,在一个事务中,第一次查询某条记录,发现没有,但是,当试图更新这条不存在的记录时,竟然能成功,并且,再次读取同一条记录,它就神奇地出现了。
    • 串行化(Serializable),最严格的隔离级别,所有事务按照次序依次执行,因此,脏读、不可重复读、幻读都不会出现。虽然 Serializable 隔离级别下的事务具有最高的安全性,但是,由于事务是串行执行,所以效率会大大下降,应用程序的性能会急剧降低。如果没有特别重要的情景,一般都不会使用 Serializable 隔离级别。

    需要格外注意的是:事务能否生效,取决于数据库引擎是否支持事务,MySQL 的 InnoDB 引擎是支持事务的,但 MyISAM 就不支持

    关于 Spring 对事务的支持

    Spring 支持两种事务方式,分别是编程式事务和声明式事务,后者最常见,通常情况下只需要一个 @Transactional 就搞定了(代码侵入性降到了最低),就像这样:

    @Transactional
    +

    那么此时就需要开启事务,保证文章表和标签表中的数据保持同步,要么都执行,要么都不执行。

    否则就有可能造成,文章保存成功了,但标签保存失败了,或者文章保存失败了,标签保存成功了——这些场景都不符合我们的预期。

    为了保证事务是正确可靠的,在数据库进行写入或者更新操作时,就必须得表现出 ACID 的 4 个重要特性:

    • 原子性(Atomicity):一个事务中的所有操作,要么全部完成,要么全部不完成,不会结束在中间某个环节。事务在执行过程中发生错误,会被回滚(Rollback)到事务开始前的状态,就像这个事务从来没有执行过一样。
    • 一致性(Consistency):在事务开始之前和事务结束以后,数据库的完整性没有被破坏。
    • 事务隔离(Isolation):数据库允许多个并发事务同时对其数据进行读写和修改,隔离性可以防止多个事务并发执行时由于交叉执行而导致数据的不一致。
    • 持久性(Durability):事务处理结束后,对数据的修改就是永久的,即便系统故障也不会丢失。

    其中,事务隔离又分为 4 种不同的级别,包括:

    • 未提交读(Read uncommitted),最低的隔离级别,允许“脏读”(dirty reads),事务可以看到其他事务“尚未提交”的修改。如果另一个事务回滚,那么当前事务读到的数据就是脏数据。
    • 提交读(read committed),一个事务可能会遇到不可重复读(Non Repeatable Read)的问题。不可重复读是指,在一个事务内,多次读同一数据,在这个事务还没有结束时,如果另一个事务恰好修改了这个数据,那么,在第一个事务中,两次读取的数据就可能不一致。
    • 可重复读(repeatable read),一个事务可能会遇到幻读(Phantom Read)的问题。幻读是指,在一个事务中,第一次查询某条记录,发现没有,但是,当试图更新这条不存在的记录时,竟然能成功,并且,再次读取同一条记录,它就神奇地出现了。
    • 串行化(Serializable),最严格的隔离级别,所有事务按照次序依次执行,因此,脏读、不可重复读、幻读都不会出现。虽然 Serializable 隔离级别下的事务具有最高的安全性,但是,由于事务是串行执行,所以效率会大大下降,应用程序的性能会急剧降低。如果没有特别重要的情景,一般都不会使用 Serializable 隔离级别。

    需要格外注意的是:事务能否生效,取决于数据库引擎是否支持事务,MySQL 的 InnoDB 引擎是支持事务的,但 MyISAM 就不支持

    关于 Spring 对事务的支持

    Spring 支持两种事务方式,分别是编程式事务和声明式事务,后者最常见,通常情况下只需要一个 @Transactional 就搞定了(代码侵入性降到了最低),就像这样:

    @Transactional
     public void savePosts(PostsParam postsParam) {
       // 保存文章
       save(posts);
    @@ -87,7 +87,7 @@
                   transactionManager.rollback(status);
               }
     }
    -

    就编程式事务管理而言,Spring 更推荐使用 TransactionTemplate。

    在编程式事务中,必须在每个业务操作中包含额外的事务管理代码,就导致代码看起来非常的臃肿,但对理解 Spring 的事务管理模型非常有帮助。

    2)声明式事务

    声明式事务将事务管理代码从业务方法中抽离了出来,以声明式的方式来实现事务管理,对于开发者来说,声明式事务显然比编程式事务更易用、更好用。

    当然了,要想实现事务管理和业务代码的抽离,就必须得用到 Spring 当中最关键最核心的技术之一,AOPopen in new window,其本质是对方法前后进行拦截,然后在目标方法开始之前创建或者加入一个事务,执行完目标方法之后根据执行的情况提交或者回滚。

    声明式事务虽然优于编程式事务,但也有不足,声明式事务管理的粒度是方法级别,而编程式事务是可以精确到代码块级别的

    事务管理模型

    Spring 将事务管理的核心抽象为一个事务管理器(TransactionManager),它的源码只有一个简单的接口定义,属于一个标记接口:

    public interface TransactionManager {
    +

    就编程式事务管理而言,Spring 更推荐使用 TransactionTemplate。

    在编程式事务中,必须在每个业务操作中包含额外的事务管理代码,就导致代码看起来非常的臃肿,但对理解 Spring 的事务管理模型非常有帮助。

    2)声明式事务

    声明式事务将事务管理代码从业务方法中抽离了出来,以声明式的方式来实现事务管理,对于开发者来说,声明式事务显然比编程式事务更易用、更好用。

    当然了,要想实现事务管理和业务代码的抽离,就必须得用到 Spring 当中最关键最核心的技术之一,AOPopen in new window,其本质是对方法前后进行拦截,然后在目标方法开始之前创建或者加入一个事务,执行完目标方法之后根据执行的情况提交或者回滚。

    声明式事务虽然优于编程式事务,但也有不足,声明式事务管理的粒度是方法级别,而编程式事务是可以精确到代码块级别的

    事务管理模型

    Spring 将事务管理的核心抽象为一个事务管理器(TransactionManager),它的源码只有一个简单的接口定义,属于一个标记接口:

    public interface TransactionManager {
     
     }
     

    该接口有两个子接口,分别是编程式事务接口 ReactiveTransactionManager 和声明式事务接口 PlatformTransactionManager。我们来重点说说 PlatformTransactionManager,该接口定义了 3 个接口方法:

    interface PlatformTransactionManager extends TransactionManager{
    @@ -135,7 +135,7 @@
       boolean readOnly() default false;
     
     }
    -
    • @Transactional 注解中的 propagation 对应 TransactionDefinition 中的 getPropagationBehavior,默认值为 Propagation.REQUIRED(TransactionDefinition.PROPAGATION_REQUIRED)
    • @Transactional 注解中的 isolation 对应 TransactionDefinition 中的 getIsolationLevel,默认值为 DEFAULT(TransactionDefinition.ISOLATION_DEFAULT)
    • @Transactional 注解中的 timeout 对应 TransactionDefinition 中的 getTimeout,默认值为TransactionDefinition.TIMEOUT_DEFAULT。
    • @Transactional 注解中的 readOnly 对应 TransactionDefinition 中的 isReadOnly,默认值为 false。

    说到这,我们来详细地说明一下 Spring 事务的传播行为、事务的隔离级别、事务的超时时间、事务的只读属性,以及事务的回滚规则。

    事务传播行为

    当事务方法被另外一个事务方法调用时,必须指定事务应该如何传播,例如,方法可能继续在当前事务中执行,也可以开启一个新的事务,在自己的事务中执行。

    声明式事务的传播行为可以通过 @Transactional 注解中的 propagation 属性来定义,比如说:

    @Transactional(propagation = Propagation.REQUIRED)
    +
    • @Transactional 注解中的 propagation 对应 TransactionDefinition 中的 getPropagationBehavior,默认值为 Propagation.REQUIRED(TransactionDefinition.PROPAGATION_REQUIRED)
    • @Transactional 注解中的 isolation 对应 TransactionDefinition 中的 getIsolationLevel,默认值为 DEFAULT(TransactionDefinition.ISOLATION_DEFAULT)
    • @Transactional 注解中的 timeout 对应 TransactionDefinition 中的 getTimeout,默认值为TransactionDefinition.TIMEOUT_DEFAULT。
    • @Transactional 注解中的 readOnly 对应 TransactionDefinition 中的 isReadOnly,默认值为 false。

    说到这,我们来详细地说明一下 Spring 事务的传播行为、事务的隔离级别、事务的超时时间、事务的只读属性,以及事务的回滚规则。

    事务传播行为

    当事务方法被另外一个事务方法调用时,必须指定事务应该如何传播,例如,方法可能继续在当前事务中执行,也可以开启一个新的事务,在自己的事务中执行。

    声明式事务的传播行为可以通过 @Transactional 注解中的 propagation 属性来定义,比如说:

    @Transactional(propagation = Propagation.REQUIRED)
     public void savePosts(PostsParam postsParam) {
     }
     

    TransactionDefinition 一共定义了 7 种事务传播行为:

    01、PROPAGATION_REQUIRED

    这也是 @Transactional 默认的事务传播行为,指的是如果当前存在事务,则加入该事务;如果当前没有事务,则创建一个新的事务。更确切地意思是:

    • 如果外部方法没有开启事务的话,Propagation.REQUIRED 修饰的内部方法会开启自己的事务,且开启的事务相互独立,互不干扰。
    • 如果外部方法开启事务并且是 Propagation.REQUIRED 的话,所有 Propagation.REQUIRED 修饰的内部方法和外部方法均属于同一事务 ,只要一个方法回滚,整个事务都需要回滚。
    Class A {
    @@ -168,8 +168,8 @@
            //do something
         }
     }
    -

    如果 aMethod()发生异常回滚,bMethod()不会跟着回滚,因为 bMethod()开启了独立的事务。但是,如果 bMethod()抛出了未被捕获的异常并且这个异常满足事务回滚规则的话,aMethod()同样也会回滚。

    03、PROPAGATION_NESTED

    如果当前存在事务,就在当前事务内执行;否则,就执行与 PROPAGATION_REQUIRED 类似的操作。

    04、PROPAGATION_MANDATORY

    如果当前存在事务,则加入该事务;如果当前没有事务,则抛出异常。

    05、PROPAGATION_SUPPORTS

    如果当前存在事务,则加入该事务;如果当前没有事务,则以非事务的方式继续运行。

    06、PROPAGATION_NOT_SUPPORTED

    以非事务方式运行,如果当前存在事务,则把当前事务挂起。

    07、PROPAGATION_NEVER

    以非事务方式运行,如果当前存在事务,则抛出异常。

    3、4、5、6、7 这 5 种事务传播方式不常用,了解即可。

    事务隔离级别

    前面我们已经了解了数据库的事务隔离级别,再来理解 Spring 的事务隔离级别就容易多了。

    TransactionDefinition 中一共定义了 5 种事务隔离级别:

    • ISOLATION_DEFAULT,使用数据库默认的隔离级别,MySql 默认采用的是 REPEATABLE_READ,也就是可重复读。
    • ISOLATION_READ_UNCOMMITTED,最低的隔离级别,可能会出现脏读、幻读或者不可重复读。
    • ISOLATION_READ_COMMITTED,允许读取并发事务提交的数据,可以防止脏读,但幻读和不可重复读仍然有可能发生。
    • ISOLATION_REPEATABLE_READ,对同一字段的多次读取结果都是一致的,除非数据是被自身事务所修改的,可以阻止脏读和不可重复读,但幻读仍有可能发生。
    • ISOLATION_SERIALIZABLE,最高的隔离级别,虽然可以阻止脏读、幻读和不可重复读,但会严重影响程序性能。

    通常情况下,我们采用默认的隔离级别 ISOLATION_DEFAULT 就可以了,也就是交给数据库来决定,可以通过 SELECT @@transaction_isolation; 命令来查看 MySql 的默认隔离级别,结果为 REPEATABLE-READ,也就是可重复读。

    事务的超时时间

    事务超时,也就是指一个事务所允许执行的最长时间,如果在超时时间内还没有完成的话,就自动回滚。

    假如事务的执行时间格外的长,由于事务涉及到对数据库的锁定,就会导致长时间运行的事务占用数据库资源。

    事务的只读属性

    如果一个事务只是对数据库执行读操作,那么该数据库就可以利用事务的只读属性,采取优化措施,适用于多条数据库查询操作中。

    为什么一个查询操作还要启用事务支持呢?

    这是因为 MySql(innodb)默认对每一个连接都启用了 autocommit 模式,在该模式下,每一个发送到 MySql 服务器的 SQL 语句都会在一个单独的事务中进行处理,执行结束后会自动提交事务。

    那如果我们给方法加上了 @Transactional 注解,那这个方法中所有的 SQL 都会放在一个事务里。否则,每条 SQL 都会单独开启一个事务,中间被其他事务修改了数据,都会实时读取到。

    有些情况下,当一次执行多条查询语句时,需要保证数据一致性时,就需要启用事务支持。否则上一条 SQL 查询后,被其他用户改变了数据,那么下一个 SQL 查询可能就会出现不一致的状态。

    事务的回滚策略

    默认情况下,事务只在出现运行时异常(Runtime Exception)时回滚,以及 Error,出现检查异常(checked exception,需要主动捕获处理或者向上抛出)时不回滚。

    checked和unchecked异常open in new window

    如果你想要回滚特定的异常类型的话,可以这样设置:

    @Transactional(rollbackFor= MyException.class)
    -

    关于 Spring Boot 对事务的支持

    以前,我们需要通过 XML 配置 Spring 来托管事务,有了 Spring Boot 之后,一切就变得更加简单了,只需要在业务层添加事务注解(@Transactional)就可以快速开启事务。

    也就是说,我们只需要把焦点放在 @Transactional 注解上就可以了。

    @Transactional 的作用范围

    • 类上,表明类中所有 public 方法都启用事务
    • 方法上,最常用的一种
    • 接口上,不推荐使用

    @Transactional 的常用配置参数

    虽然 @Transactional 注解源码中定义了很多属性,但大多数时候,我都是采用默认配置,当然了,如果需要自定义的话,前面也都说明过了。

    @Transactional 的使用注意事项总结

    1)要在 public 方法上使用,在AbstractFallbackTransactionAttributeSource类的computeTransactionAttribute方法中有个判断,如果目标方法不是public,则TransactionAttribute返回null,即不支持事务。

    protected TransactionAttribute computeTransactionAttribute(Method method, @Nullable Class<?> targetClass) {
    +

    如果 aMethod()发生异常回滚,bMethod()不会跟着回滚,因为 bMethod()开启了独立的事务。但是,如果 bMethod()抛出了未被捕获的异常并且这个异常满足事务回滚规则的话,aMethod()同样也会回滚。

    03、PROPAGATION_NESTED

    如果当前存在事务,就在当前事务内执行;否则,就执行与 PROPAGATION_REQUIRED 类似的操作。

    04、PROPAGATION_MANDATORY

    如果当前存在事务,则加入该事务;如果当前没有事务,则抛出异常。

    05、PROPAGATION_SUPPORTS

    如果当前存在事务,则加入该事务;如果当前没有事务,则以非事务的方式继续运行。

    06、PROPAGATION_NOT_SUPPORTED

    以非事务方式运行,如果当前存在事务,则把当前事务挂起。

    07、PROPAGATION_NEVER

    以非事务方式运行,如果当前存在事务,则抛出异常。

    3、4、5、6、7 这 5 种事务传播方式不常用,了解即可。

    事务隔离级别

    前面我们已经了解了数据库的事务隔离级别,再来理解 Spring 的事务隔离级别就容易多了。

    TransactionDefinition 中一共定义了 5 种事务隔离级别:

    • ISOLATION_DEFAULT,使用数据库默认的隔离级别,MySql 默认采用的是 REPEATABLE_READ,也就是可重复读。
    • ISOLATION_READ_UNCOMMITTED,最低的隔离级别,可能会出现脏读、幻读或者不可重复读。
    • ISOLATION_READ_COMMITTED,允许读取并发事务提交的数据,可以防止脏读,但幻读和不可重复读仍然有可能发生。
    • ISOLATION_REPEATABLE_READ,对同一字段的多次读取结果都是一致的,除非数据是被自身事务所修改的,可以阻止脏读和不可重复读,但幻读仍有可能发生。
    • ISOLATION_SERIALIZABLE,最高的隔离级别,虽然可以阻止脏读、幻读和不可重复读,但会严重影响程序性能。

    通常情况下,我们采用默认的隔离级别 ISOLATION_DEFAULT 就可以了,也就是交给数据库来决定,可以通过 SELECT @@transaction_isolation; 命令来查看 MySql 的默认隔离级别,结果为 REPEATABLE-READ,也就是可重复读。

    事务的超时时间

    事务超时,也就是指一个事务所允许执行的最长时间,如果在超时时间内还没有完成的话,就自动回滚。

    假如事务的执行时间格外的长,由于事务涉及到对数据库的锁定,就会导致长时间运行的事务占用数据库资源。

    事务的只读属性

    如果一个事务只是对数据库执行读操作,那么该数据库就可以利用事务的只读属性,采取优化措施,适用于多条数据库查询操作中。

    为什么一个查询操作还要启用事务支持呢?

    这是因为 MySql(innodb)默认对每一个连接都启用了 autocommit 模式,在该模式下,每一个发送到 MySql 服务器的 SQL 语句都会在一个单独的事务中进行处理,执行结束后会自动提交事务。

    那如果我们给方法加上了 @Transactional 注解,那这个方法中所有的 SQL 都会放在一个事务里。否则,每条 SQL 都会单独开启一个事务,中间被其他事务修改了数据,都会实时读取到。

    有些情况下,当一次执行多条查询语句时,需要保证数据一致性时,就需要启用事务支持。否则上一条 SQL 查询后,被其他用户改变了数据,那么下一个 SQL 查询可能就会出现不一致的状态。

    事务的回滚策略

    默认情况下,事务只在出现运行时异常(Runtime Exception)时回滚,以及 Error,出现检查异常(checked exception,需要主动捕获处理或者向上抛出)时不回滚。

    checked和unchecked异常open in new window

    如果你想要回滚特定的异常类型的话,可以这样设置:

    @Transactional(rollbackFor= MyException.class)
    +

    关于 Spring Boot 对事务的支持

    以前,我们需要通过 XML 配置 Spring 来托管事务,有了 Spring Boot 之后,一切就变得更加简单了,只需要在业务层添加事务注解(@Transactional)就可以快速开启事务。

    也就是说,我们只需要把焦点放在 @Transactional 注解上就可以了。

    @Transactional 的作用范围

    • 类上,表明类中所有 public 方法都启用事务
    • 方法上,最常用的一种
    • 接口上,不推荐使用

    @Transactional 的常用配置参数

    虽然 @Transactional 注解源码中定义了很多属性,但大多数时候,我都是采用默认配置,当然了,如果需要自定义的话,前面也都说明过了。

    @Transactional 的使用注意事项总结

    1)要在 public 方法上使用,在AbstractFallbackTransactionAttributeSource类的computeTransactionAttribute方法中有个判断,如果目标方法不是public,则TransactionAttribute返回null,即不支持事务。

    protected TransactionAttribute computeTransactionAttribute(Method method, @Nullable Class<?> targetClass) {
         // Don't allow no-public methods as required.
         if (allowPublicMethodsOnly() && !Modifier.isPublic(method.getModifiers())) {
           return null;
    @@ -205,13 +205,13 @@
         }
         return null;
       }
    -

    2)避免同一个类中调用 @Transactional 注解的方法,这样会导致事务失效。

    更多事务失效的场景可以参考:

    https://mp.weixin.qq.com/s/qoWlR4ohVMfZf8IlhdSQDQopen in new window

    测试事务是否起效

    在测试之前,我们先把 Spring Boot 默认的日志级别 info 调整为 debug,在 application.yml 文件中 修改:

    logging:
    +

    2)避免同一个类中调用 @Transactional 注解的方法,这样会导致事务失效。

    更多事务失效的场景可以参考:

    https://mp.weixin.qq.com/s/qoWlR4ohVMfZf8IlhdSQDQopen in new window

    测试事务是否起效

    在测试之前,我们先把 Spring Boot 默认的日志级别 info 调整为 debug,在 application.yml 文件中 修改:

    logging:
       level:
         org:
           hibernate: debug
           springframework:
             web: debug
    -

    然后,来看修改之前查到的数据:

    开搞。在控制器中添加一个 update 接口,准备修改数据,打算把沉默王二的狗腿子修改为沉默王二的狗腿:


    更多内容,只针对《Java 程序员进阶之路》星球用户开放,需要的小伙伴可以戳链接🔗加入我们的星球,一起学习,一起卷。。编程喵🐱是一个 Spring Boot+Vue 的前后端分离项目,融合了市面上绝大多数流行的技术要点。通过学习实战项目,你可以将所学的知识通过实践进行检验、你可以拓宽自己的技术边界,你可以掌握一个真正的实战项目是如何从 0 到 1 的。


    - +

    然后,来看修改之前查到的数据:

    开搞。在控制器中添加一个 update 接口,准备修改数据,打算把沉默王二的狗腿子修改为沉默王二的狗腿:


    更多内容,只针对《Java 程序员进阶之路》星球用户开放,需要的小伙伴可以戳链接🔗open in new window加入我们的星球,一起学习,一起卷。。编程喵🐱是一个 Spring Boot+Vue 的前后端分离项目,融合了市面上绝大多数流行的技术要点。通过学习实战项目,你可以将所学的知识通过实践进行检验、你可以拓宽自己的技术边界,你可以掌握一个真正的实战项目是如何从 0 到 1 的。


    + diff --git a/dist/springboot/windows-codingmore-run.html b/dist/springboot/windows-codingmore-run.html index a89a3e2d..6d0e2d12 100644 --- a/dist/springboot/windows-codingmore-run.html +++ b/dist/springboot/windows-codingmore-run.html @@ -5,7 +5,7 @@ - - + -

    如何在本地(Windows环境)跑起来编程喵(Spring Boot+Vue)项目源码?

    沉默王二2022年6月7日
    • Java企业级开发
    • Spring Boot
    • Vue
    大约 10 分钟

    前置环境的准备

    • 一台可以开机的电脑
    • JDK 8
    • Maven
    • Intellij IDEA(非必须,可用 Eclipse)
    • Visual Studio Code(非必须,可用 hbuilderx)
    • MySQL
    • Redis(非必须,会报错,但不影响跑)
    • OSS(非必须,上传图片时报错,但不影响跑)

    对,编程喵 🐱(Spring Boot+Vue 的前后端分离项目)要想在本地跑起来,需要这 8 个前置环境。

    第一个条件,一台可以开机的电脑,显然我相信大家都是有的。不然怎么学编程是吧?瞧我这废话真多。

    这篇先以 Windows 为例,macOS系统open in new window戳这个链接。下图是我的备用机小米笔记本的配置。

    第二个条件,JDK 8,可以通过 Chocolateyopen in new window(Windows 软件包管理器)安装,非常方便(前提条件是你得科学上网,否则速度会非常慢,如果不能科学上网我也会提供另外一种常规的方式)。

    执行 choco -v 可以查看 Chocolatey 版本。记得一定要以管理员身份运行,否则可以拿不到安装权限。

    执行 choco install jdk8 可以安装 JDK 8 了。

    执行 java -version 可以查看当前 JDK 版本

    使用 Chocolatey 安装 JDK 的好处就是不需要再配置环境变量。

    如果没有安装 chocolatey 的话(或者没有外网权限的话),可以戳 Downloads - Java SE 8 (oracle.com)open in new window 下载 JDK 8。

    之后一步步安装完成后,再配置一下环境变量就OK了。

    第三个条件,Maven,可以直接通过 choco install maven 来完成安装。

    也可以戳 Maven – Download Apache Mavenopen in new window 下载免安装版。

    之后配置到环境变量中。

    通过 mvn -v 来查看版本。

    为了加快项目依赖包的下载速度,我们需要配置 Maven 的国内镜像源。

    找到 Maven Home(D:\download\apache-maven-3.8.5-bin\apache-maven-3.8.5),复制一份 settings.xml。

    C:\Users\yours\.m2 路径下。

    打开 settings.xml 文件在 mirrors 节点下添加阿里云镜像地址,并保存。

    <mirror>
    +    

    如何在本地(Windows环境)跑起来编程喵(Spring Boot+Vue)项目源码?

    沉默王二2022年6月7日
    • Java企业级开发
    • Spring Boot
    • Vue
    大约 10 分钟

    前置环境的准备

    • 一台可以开机的电脑
    • JDK 8
    • Maven
    • Intellij IDEA(非必须,可用 Eclipse)
    • Visual Studio Code(非必须,可用 hbuilderx)
    • MySQL
    • Redis(非必须,会报错,但不影响跑)
    • OSS(非必须,上传图片时报错,但不影响跑)

    对,编程喵 🐱(Spring Boot+Vue 的前后端分离项目)要想在本地跑起来,需要这 8 个前置环境。

    第一个条件,一台可以开机的电脑,显然我相信大家都是有的。不然怎么学编程是吧?瞧我这废话真多。

    这篇先以 Windows 为例,macOS系统open in new window戳这个链接。下图是我的备用机小米笔记本的配置。

    第二个条件,JDK 8,可以通过 Chocolateyopen in new window(Windows 软件包管理器)安装,非常方便(前提条件是你得科学上网,否则速度会非常慢,如果不能科学上网我也会提供另外一种常规的方式)。

    执行 choco -v 可以查看 Chocolatey 版本。记得一定要以管理员身份运行,否则可以拿不到安装权限。

    执行 choco install jdk8 可以安装 JDK 8 了。

    执行 java -version 可以查看当前 JDK 版本

    使用 Chocolatey 安装 JDK 的好处就是不需要再配置环境变量。

    如果没有安装 chocolatey 的话(或者没有外网权限的话),可以戳 Downloads - Java SE 8 (oracle.com)open in new window 下载 JDK 8。

    之后一步步安装完成后,再配置一下环境变量就OK了。

    第三个条件,Maven,可以直接通过 choco install maven 来完成安装。

    也可以戳 Maven – Download Apache Mavenopen in new window 下载免安装版。

    之后配置到环境变量中。

    通过 mvn -v 来查看版本。

    为了加快项目依赖包的下载速度,我们需要配置 Maven 的国内镜像源。

    找到 Maven Home(D:\download\apache-maven-3.8.5-bin\apache-maven-3.8.5),复制一份 settings.xml。

    C:\Users\yours\.m2 路径下。

    打开 settings.xml 文件在 mirrors 节点下添加阿里云镜像地址,并保存。

    <mirror>
       <id>alimaven</id>
       <name>aliyun maven</name>
     <url>http://maven.aliyun.com/nexus/content/groups/public/</url>
       <mirrorOf>central</mirrorOf>
     </mirror>
    -

    第四个条件,Intellij IDEA,Java 后端开发必备神器,可以安装社区版,也可以安装旗舰版。

    https://www.jetbrains.com/zh-cn/idea/download/#section=macopen in new window

    第五个条件,Visual Studio Code,在编写前端代码(vue、JavaScript、css 等)时,比 Intellij IDEA 更值得信赖。

    https://code.visualstudio.com/open in new window

    第六个条件,MySQL,可以通过执行 choco install mysql.installer 在本机上安装 MySql 的工具箱。

    也可以戳 MySQL :: Download MySQL Installeropen in new window 直接下载 MySql的工具箱。

    之后通过 MySql工具箱来安装 MySQL。

    如果觉得这个过程比较麻烦的话,也可以直接执行 choco install mysql 来安装MySQL。

    也可以戳 MySQL :: Download MySQL Community Serveropen in new window 下载MySQL安装包。

    安装(记住MySQL的用户名和密码)完成后,可以在计算机管理面板里找到 MySQL 服务。

    第七个条件,Redis,可以直接通过 choco install redis 来完成安装。

    也可以戳 Releases · microsoftarchive/redis · GitHubopen in new window 下载 Redis。

    下载完直接安装。

    安装完成后,可以在计算机管理面板里找到Redis服务。

    如果下载的是绿色版免安装版,只需要把 zip 包解压就可以了。

    在解压目录下,你会发现一份叫 Windows Service Documentation.docx 的文件,里面详细地说明了 Redis 服务的注册/卸载方式,以及启动/停止方式。

    复制对应命令在 CMD 命令行下执行就OK了。

    第八个条件,OSS,主要用来保存图片,可以通过阿里云官方去购买服务,并且创建 Bucket。

    然后配置 AccessKey。

    针对星球用户open in new window,我会开放自己的 accessKeyId 和 accessKeySecret,请勿外泄,免得被恶意攻击。

    下载编程喵(codingmore)源码

    编程喵一共有三个仓库,分别是:

    编程喵 🐱 是一个非常纯粹的前后端分离项目,后端用到的技术包括:

    • Spring Boot 容器+MVC 框架
    • SpringSecurity 认证和授权框架
    • MyBatis ORM 框架
    • MyBatis-Plus MyBatis 增强工具
    • Nginx 静态资源服务器
    • Druid 数据库连接池
    • OSS 对象存储
    • Redis 缓存中间件
    • MySQL 关系型数据库
    • Swagger-UI 文档生成工具
    • Knife4j Swagger 美化增强工具
    • Hibernator-Validator 验证框架
    • Logback 日志框架
    • Lombok 简化对象封装工具
    • Hutool Java 工具类库

    前端用到的技术包括:

    • Vue 前端框架
    • Vue-router 路由框架
    • Vuex 全局状态管理框架
    • Element 前端 UI 框架
    • Axios 前端 HTTP 框架
    • Js-cookie cookie 管理工具
    • nprogress 进度条控件

    第一步,下载 coding-more 源码,戳链接 🔗open in new window进入到该页面。

    第二步,如果安装有 GitHub 桌面版的话,可以点击「open with GitHub desktop」,也可以在这一步下载安装GitHub 桌面版。

    也可以点击「download zip」。

    第三步,通过 Intellij IDEA 导入新项目就可以了,第一次导入的话,需要等待Maven下载依赖包。

    第四步,下载 codingmore-admin-web 源码,戳链接 🔗open in new window进入到该页面。

    源码下载完毕后,建议通过 VS Code 导入项目,VS Code 对前端项目比 Intellij IDEA 更加友好。

    部署编程喵(codingmore)源码

    01、MySQL

    第一步,安装 Navicat,这是一个图形化界面的数据库管理工具。

    安装完毕后,输入 MySQL 数据库的用户名和密码,建立本地连接。

    第二步,打开链接,新建数据库 codingmore,导入编程喵的 DB 文件。DB 文件放在 coding-more/doc 目录下。

    导入成功后,可以看到目前 codingmore 所用到的 27 个数据库文件,其中 qrtz 开头的是定时任务的持久化表,剩余是编程喵的数据库表文件。

    然后,修改 codingmore-admin/src/main/resources/application-dev.yml 文件中的 spring.datasource.username、password、url 等,该为你本地的用户名、密码和数据库链接地址(Web 管理端)。

    修改 codingmore-web/src/main/resources/application-dev.yml 文件中的 spring.datasource.username、password、url 等,该为你本地的用户名、密码和数据库链接地址(Web 前端)。

    02、Redis

    在计算机管理面板里启动Redis服务。

    然后,修改 codingmore-admin/src/main/resources/application-dev.yml 文件中的 spring.redis.host、database、port、password、timeout 等,该为你本地的 Redis 链接信息,一般默认就好(Web 管理端)。

    修改 codingmore-web/src/main/resources/application-dev.yml 文件中的 spring.redis.host、database、port、password、timeout 等,该为你本地的 Redis 链接信息,一般默认就好(Web 前端)。

    04、OSS

    星球用户open in new window需要自己购买阿里云的 OSS 服务和 CDN 服务。星球用户open in new window可以直接私信我获取 accessKeyId 和 accessKeySecret。

    然后修改 codingmore-admin/src/main/resources/application-dev.yml 文件中的 aliyun.cdn、oss 等。

    05、codingmore-admin

    在 Intellij IDEA 中运行 CodingmoreAdminBootstrap 主类,启动管理端后台服务。

    如果编译失败,注意调整 JDK 版本为 Java 8。

    06、codingmore-web

    在 Intellij IDEA 中运行 CodingmoreAdminBootstrap 主类,启动管理端后台服务。

    启动后,可以直接在浏览器地址栏输入 http://localhost:8081 访问 Web 前端。

    07、codingmore-admin-web

    在 vscode 中打开终端,执行 yarn install 添加项目依赖(yarn 是 Facebook 为 node.js 运行时环境开发软件打包工具,是 npm 软件包管理器的替代品)。

    如果没有安装 yarn 的话,会出现以下错误。

    可以直接以管理员模式执行 choco install yarn 来安装 yarn 包。

    如果没有安装 chocolatey 的话,需要戳 Download | Node.js (nodejs.org)open in new window 先安装node.js:

    强烈推荐大家安装 chocolatey,安装 node.js 的时候也会出现 chocolatey的影子。

    再执行 npm install -g yarn 来安装 yarn。安装成功后,重新打开 vscode,执行 yarn -v 就可以查看 yarn 的版本了。

    再次执行 yarn install 安装前端环境。之后执行 yarn run dev 编译 admin 前端。

    在浏览器地址栏输入 http://localhost:8080 就可以访问到了。

    可以点击「获取体验账号」的方式获取登录用户名和密码。当然了,你也可以直接在 users 表上暴力破解密码。

    星球用户open in new window可以直接私信我获取超级管理员的密码。登录后就可以看到文章列表啦。

    这是文章编辑页,是不是非常清爽?

    好了,MacOS 版open in new window和Windows版如何下载编程喵源码,如何在本地跑起来的整个演示过程就告一段落辣,我们回头见!

    - +

    第四个条件,Intellij IDEA,Java 后端开发必备神器,可以安装社区版,也可以安装旗舰版。

    https://www.jetbrains.com/zh-cn/idea/download/#section=macopen in new window

    第五个条件,Visual Studio Code,在编写前端代码(vue、JavaScript、css 等)时,比 Intellij IDEA 更值得信赖。

    https://code.visualstudio.com/open in new window

    第六个条件,MySQL,可以通过执行 choco install mysql.installer 在本机上安装 MySql 的工具箱。

    也可以戳 MySQL :: Download MySQL Installeropen in new window 直接下载 MySql的工具箱。

    之后通过 MySql工具箱来安装 MySQL。

    如果觉得这个过程比较麻烦的话,也可以直接执行 choco install mysql 来安装MySQL。

    也可以戳 MySQL :: Download MySQL Community Serveropen in new window 下载MySQL安装包。

    安装(记住MySQL的用户名和密码)完成后,可以在计算机管理面板里找到 MySQL 服务。

    第七个条件,Redis,可以直接通过 choco install redis 来完成安装。

    也可以戳 Releases · microsoftarchive/redis · GitHubopen in new window 下载 Redis。

    下载完直接安装。

    安装完成后,可以在计算机管理面板里找到Redis服务。

    如果下载的是绿色版免安装版,只需要把 zip 包解压就可以了。

    在解压目录下,你会发现一份叫 Windows Service Documentation.docx 的文件,里面详细地说明了 Redis 服务的注册/卸载方式,以及启动/停止方式。

    复制对应命令在 CMD 命令行下执行就OK了。

    第八个条件,OSS,主要用来保存图片,可以通过阿里云官方去购买服务,并且创建 Bucket。

    然后配置 AccessKey。

    针对星球用户open in new window,我会开放自己的 accessKeyId 和 accessKeySecret,请勿外泄,免得被恶意攻击。

    下载编程喵(codingmore)源码

    编程喵一共有三个仓库,分别是:

    编程喵 🐱 是一个非常纯粹的前后端分离项目,后端用到的技术包括:

    • Spring Boot 容器+MVC 框架
    • SpringSecurity 认证和授权框架
    • MyBatis ORM 框架
    • MyBatis-Plus MyBatis 增强工具
    • Nginx 静态资源服务器
    • Druid 数据库连接池
    • OSS 对象存储
    • Redis 缓存中间件
    • MySQL 关系型数据库
    • Swagger-UI 文档生成工具
    • Knife4j Swagger 美化增强工具
    • Hibernator-Validator 验证框架
    • Logback 日志框架
    • Lombok 简化对象封装工具
    • Hutool Java 工具类库

    前端用到的技术包括:

    • Vue 前端框架
    • Vue-router 路由框架
    • Vuex 全局状态管理框架
    • Element 前端 UI 框架
    • Axios 前端 HTTP 框架
    • Js-cookie cookie 管理工具
    • nprogress 进度条控件

    第一步,下载 coding-more 源码,戳链接 🔗open in new window进入到该页面。

    第二步,如果安装有 GitHub 桌面版的话,可以点击「open with GitHub desktop」,也可以在这一步下载安装GitHub 桌面版。

    也可以点击「download zip」。

    第三步,通过 Intellij IDEA 导入新项目就可以了,第一次导入的话,需要等待Maven下载依赖包。

    第四步,下载 codingmore-admin-web 源码,戳链接 🔗open in new window进入到该页面。

    源码下载完毕后,建议通过 VS Code 导入项目,VS Code 对前端项目比 Intellij IDEA 更加友好。

    部署编程喵(codingmore)源码

    01、MySQL

    第一步,安装 Navicat,这是一个图形化界面的数据库管理工具。

    安装完毕后,输入 MySQL 数据库的用户名和密码,建立本地连接。

    第二步,打开链接,新建数据库 codingmore,导入编程喵的 DB 文件。DB 文件放在 coding-more/doc 目录下。

    导入成功后,可以看到目前 codingmore 所用到的 27 个数据库文件,其中 qrtz 开头的是定时任务的持久化表,剩余是编程喵的数据库表文件。

    然后,修改 codingmore-admin/src/main/resources/application-dev.yml 文件中的 spring.datasource.username、password、url 等,该为你本地的用户名、密码和数据库链接地址(Web 管理端)。

    修改 codingmore-web/src/main/resources/application-dev.yml 文件中的 spring.datasource.username、password、url 等,该为你本地的用户名、密码和数据库链接地址(Web 前端)。

    02、Redis

    在计算机管理面板里启动Redis服务。

    然后,修改 codingmore-admin/src/main/resources/application-dev.yml 文件中的 spring.redis.host、database、port、password、timeout 等,该为你本地的 Redis 链接信息,一般默认就好(Web 管理端)。

    修改 codingmore-web/src/main/resources/application-dev.yml 文件中的 spring.redis.host、database、port、password、timeout 等,该为你本地的 Redis 链接信息,一般默认就好(Web 前端)。

    04、OSS

    星球用户open in new window需要自己购买阿里云的 OSS 服务和 CDN 服务。星球用户open in new window可以直接私信我获取 accessKeyId 和 accessKeySecret。

    然后修改 codingmore-admin/src/main/resources/application-dev.yml 文件中的 aliyun.cdn、oss 等。

    05、codingmore-admin

    在 Intellij IDEA 中运行 CodingmoreAdminBootstrap 主类,启动管理端后台服务。

    如果编译失败,注意调整 JDK 版本为 Java 8。

    06、codingmore-web

    在 Intellij IDEA 中运行 CodingmoreAdminBootstrap 主类,启动管理端后台服务。

    启动后,可以直接在浏览器地址栏输入 http://localhost:8081 访问 Web 前端。

    07、codingmore-admin-web

    在 vscode 中打开终端,执行 yarn install 添加项目依赖(yarn 是 Facebook 为 node.js 运行时环境开发软件打包工具,是 npm 软件包管理器的替代品)。

    如果没有安装 yarn 的话,会出现以下错误。

    可以直接以管理员模式执行 choco install yarn 来安装 yarn 包。

    如果没有安装 chocolatey 的话,需要戳 Download | Node.js (nodejs.org)open in new window 先安装node.js:

    强烈推荐大家安装 chocolatey,安装 node.js 的时候也会出现 chocolatey的影子。

    再执行 npm install -g yarn 来安装 yarn。安装成功后,重新打开 vscode,执行 yarn -v 就可以查看 yarn 的版本了。

    再次执行 yarn install 安装前端环境。之后执行 yarn run dev 编译 admin 前端。

    在浏览器地址栏输入 http://localhost:8080 就可以访问到了。

    可以点击「获取体验账号」的方式获取登录用户名和密码。当然了,你也可以直接在 users 表上暴力破解密码。

    星球用户open in new window可以直接私信我获取超级管理员的密码。登录后就可以看到文章列表啦。

    这是文章编辑页,是不是非常清爽?

    好了,MacOS 版open in new window和Windows版如何下载编程喵源码,如何在本地跑起来的整个演示过程就告一段落辣,我们回头见!

    + diff --git a/dist/string/constant-pool.html b/dist/string/constant-pool.html index 61548117..183ff2eb 100644 --- a/dist/string/constant-pool.html +++ b/dist/string/constant-pool.html @@ -39,16 +39,16 @@ } - + -

    深入了解Java字符串常量池

    沉默王二2021年6月5日
    • Java核心
    • Java
    大约 4 分钟

    深入了解Java字符串常量池

    “三妹,今天我们来学习一下字符串常量池吧,这是字符串中非常关键的一个知识点。”我话音未落,青岛路小学那边传来了嘹亮的歌声就钻进了我的耳朵,“唱 ~ 山 ~ 歌 ~”

    三妹说,“好呀,开始吧,哥。”

    “先从这道面试题开始吧!”

    String s = new String("二哥");
    +    

    深入了解Java字符串常量池

    沉默王二2021年6月5日
    • Java核心
    • Java
    大约 4 分钟

    深入了解Java字符串常量池

    “三妹,今天我们来学习一下字符串常量池吧,这是字符串中非常关键的一个知识点。”我话音未落,青岛路小学那边传来了嘹亮的歌声就钻进了我的耳朵,“唱 ~ 山 ~ 歌 ~”

    三妹说,“好呀,开始吧,哥。”

    “先从这道面试题开始吧!”

    String s = new String("二哥");
     

    “这行代码创建了几个对象?”

    “不就一个吗?”三妹不假思索地回答。

    “不,两个!”我直接否定了三妹的答案,“使用 new 关键字创建一个字符串对象时,Java 虚拟机会先在字符串常量池中查找有没有‘二哥’这个字符串对象,如果有,就不会在字符串常量池中创建‘二哥’这个对象了,直接在堆中创建一个‘二哥’的字符串对象,然后将堆中这个‘二哥’的对象地址返回赋值给变量 s。”

    “如果没有,先在字符串常量池中创建一个‘二哥’的字符串对象,然后再在堆中创建一个‘二哥’的字符串对象,然后将堆中这个‘二哥’的字符串对象地址返回赋值给变量 s。”

    “为什么要先在字符串常量池中创建对象,然后再在堆上创建呢?这样不就多此一举了?”三妹敏锐地发现了问题。

    我回答,“由于字符串的使用频率实在是太高了,所以 Java 虚拟机为了提高性能和减少内存开销,在创建字符串对象的时候进行了一些优化,特意为字符串开辟了一个字符串常量池。”

    通常情况下,我们会采用双引号的方式来创建字符串对象,而不是通过 new 关键字的方式:

    String s = "三妹";
     

    当执行 String s = "三妹" 时,Java 虚拟机会先在字符串常量池中查找有没有“三妹”这个字符串对象,如果有,则不创建任何对象,直接将字符串常量池中这个“三妹”的对象地址返回,赋给变量 s;如果没有,在字符串常量池中创建“三妹”这个对象,然后将其地址返回,赋给变量 s。

    “哦,我明白了,哥。”三妹突然插话到,“有了字符串常量池,就可以通过双引号的方式直接创建字符串对象,不用再通过 new 的方式在堆中创建对象了,对吧?”

    “是滴。new 的方式始终会创建一个对象,不管字符串的内容是否已经存在,而双引号的方式会重复利用字符串常量池中已经存在的对象。”我说。

    来看下面这个例子:

    String s = new String("二哥");
     String s1 = new String("二哥");
     

    按照我们之前的分析,这两行代码会创建三个对象,字符串常量池中一个,堆上两个。

    再来看下面这个例子:

    String s = "三妹";
     String s1 = "三妹";
     

    这两行代码只会创建一个对象,就是字符串常量池中的那个。这样的话,性能肯定就提高了!

    “那哥,字符串常量池在内存中的什么位置呢?”三妹问。

    我说,“三妹,你这个问题问得好呀!”

    在 Java 8 之前,字符串常量池在永久代中。

    Java 8 之后,移除了永久代,字符串常量池就移到了堆中。

    “哥,能再简单给我解释一下方法区,永久代和元空间的概念吗?有点模糊。”三妹说。

    我说,“可以呀。”

    • 方法区是 Java 虚拟机规范中的一个概念,就像是一个接口吧;
    • 永久代是 HotSpot 虚拟机中对方法的一个实现,就像是接口的实现类;
    • Java 8 的时候,移除了永久代,取而代之的是元空间,是方法区的另外一个实现。

    永久代是放在运行时数据区中的,所以它的大小受到 Java 虚拟机本身大小的限制,所以 Java 8 之前,会经常遇到 java.lang.OutOfMemoryError: PremGen Space 的异常,PremGen Space 就是方法区的意思;而元空间是直接放在内存中的,所以只受本机可用内存的限制,虽然也会发生内存溢出,但出现的几率相对之前就小了很多。

    “明白了吧,三妹?”我问。

    “嗯嗯。”三妹回答。

    “那关于字符串常量池,就先说这么多吧,是不是还挺有意思的。”我说。

    “是的,我现在是彻底搞懂了字符串常量池,哥,你真棒!”三妹说。

    - + diff --git a/dist/string/equals.html b/dist/string/equals.html index 6f6db8bd..6d180193 100644 --- a/dist/string/equals.html +++ b/dist/string/equals.html @@ -39,10 +39,10 @@ } - + -

    Java判断两个字符串是否相等?

    沉默王二2021年7月13日
    • Java核心
    • Java
    大约 6 分钟

    Java判断两个字符串是否相等?

    “哥,如何比较两个字符串相等啊?”三妹问。

    “这个问题看似简单,却在 Stack Overflow 上有超过 370 万的访问量。”我说,“这个问题也可以引申为 .equals() 和 ‘==’ 操作符有什么区别。”

    • “==”操作符用于比较两个对象的地址是否相等。
    • .equals() 方法用于比较两个对象的内容是否相等。

    “不是很理解。”三妹感到很困惑。

    “我来举个不恰当又很恰当的例子,一看你就明白了,三妹。”

    有一对双胞胎,姐姐叫阿丽塔,妹妹叫洛丽塔。我们普通人可能完全无法分辨谁是姐姐谁是妹妹,可她们的妈妈却可以轻而易举地辨认出。

    .equals() 就好像我们普通人,看见阿丽塔以为是洛丽塔,看见洛丽塔以为是阿丽塔,看起来一样就觉得她们是同一个人;“==”操作符就好像她们的妈妈,要求更严格,观察更细致,一眼就能分辨出谁是姐姐谁是妹妹。

    String alita = new String("小萝莉");
    +    

    Java判断两个字符串是否相等?

    沉默王二2021年7月13日
    • Java核心
    • Java
    大约 6 分钟

    Java判断两个字符串是否相等?

    “哥,如何比较两个字符串相等啊?”三妹问。

    “这个问题看似简单,却在 Stack Overflow 上有超过 370 万的访问量。”我说,“这个问题也可以引申为 .equals() 和 ‘==’ 操作符有什么区别。”

    • “==”操作符用于比较两个对象的地址是否相等。
    • .equals() 方法用于比较两个对象的内容是否相等。

    “不是很理解。”三妹感到很困惑。

    “我来举个不恰当又很恰当的例子,一看你就明白了,三妹。”

    有一对双胞胎,姐姐叫阿丽塔,妹妹叫洛丽塔。我们普通人可能完全无法分辨谁是姐姐谁是妹妹,可她们的妈妈却可以轻而易举地辨认出。

    .equals() 就好像我们普通人,看见阿丽塔以为是洛丽塔,看见洛丽塔以为是阿丽塔,看起来一样就觉得她们是同一个人;“==”操作符就好像她们的妈妈,要求更严格,观察更细致,一眼就能分辨出谁是姐姐谁是妹妹。

    String alita = new String("小萝莉");
     String luolita = new String("小萝莉");
     
     System.out.println(alita.equals(luolita)); // true
    @@ -125,6 +125,6 @@ a.equalsreturn true;
     }
     

    从源码上可以看得出,如果 cs 是 StringBuffer,该方法还会进行同步,非常的智能化;如果是 String 的话,其实调用的还是 equals() 方法。当然了,这也就意味着使用该方法进行比较的时候,多出来了很多步骤,性能上有些损失。

    “是的,总体上感觉还是 Objects.equals() 比较舒服。”三妹的眼睛是雪亮的,发现了这个方法的优点。

    - + diff --git a/dist/string/immutable.html b/dist/string/immutable.html index f6326b41..b86e6dfa 100644 --- a/dist/string/immutable.html +++ b/dist/string/immutable.html @@ -39,10 +39,10 @@ } - + -

    为什么String是不可变的?

    沉默王二2021年10月22日
    • Java核心
    • Java
    大约 5 分钟

    为什么String是不可变的?

    我正坐在沙发上津津有味地读刘欣大佬的《码农翻身》——Java 帝国这一章,门铃响了。起身打开门一看,是三妹,她从学校回来了。

    “三妹,你回来的真及时,今天我们打算讲 Java 中的字符串呢。”等三妹换鞋的时候我说。

    “哦,可以呀,哥。听说字符串的细节特别多,什么字符串常量池了、字符串不可变性了、字符串拼接了、字符串长度限制了等等,你最好慢慢讲,否则我可能一时半会消化不了。”三妹的态度显得很诚恳。

    “嗯,我已经想好了,今天就只带你大概认识一下字符串,具体的细节咱们后面再慢慢讲,保证你能及时消化。”

    “好,那就开始吧。”三妹已经准备好坐在了电脑桌的边上。

    我应了一声后走到电脑桌前坐下来,顺手打开 Intellij IDEA,并找到了 String 的源码。

    public final class String
    +    

    为什么String是不可变的?

    沉默王二2021年10月22日
    • Java核心
    • Java
    大约 5 分钟

    为什么String是不可变的?

    我正坐在沙发上津津有味地读刘欣大佬的《码农翻身》——Java 帝国这一章,门铃响了。起身打开门一看,是三妹,她从学校回来了。

    “三妹,你回来的真及时,今天我们打算讲 Java 中的字符串呢。”等三妹换鞋的时候我说。

    “哦,可以呀,哥。听说字符串的细节特别多,什么字符串常量池了、字符串不可变性了、字符串拼接了、字符串长度限制了等等,你最好慢慢讲,否则我可能一时半会消化不了。”三妹的态度显得很诚恳。

    “嗯,我已经想好了,今天就只带你大概认识一下字符串,具体的细节咱们后面再慢慢讲,保证你能及时消化。”

    “好,那就开始吧。”三妹已经准备好坐在了电脑桌的边上。

    我应了一声后走到电脑桌前坐下来,顺手打开 Intellij IDEA,并找到了 String 的源码。

    public final class String
         implements java.io.Serializable, Comparable<String>, CharSequence {
         @Stable
         private final byte[] value;
    @@ -101,6 +101,6 @@
         return new String(buf, UTF16);
     }
     

    concat() 方法用于拼接字符串,不管编码是否一致,最终也返回的是新的字符串对象。

    replace() 替换方法其实也一样,三妹,你可以自己一会看一下源码,也是返回新的字符串对象。”

    “这就意味着,不管是截取、拼接,还是替换,都不是在原有的字符串上进行的,而是重新生成了新的字符串对象。也就是说,这些操作执行过后,原来的字符串对象并没有发生改变。”

    “三妹,你记住,String 对象一旦被创建后就固定不变了,对 String 对象的任何修改都不会影响到原来的字符串对象,都会生成新的字符串对象。”

    “嗯嗯,记住了,哥。”三妹很乖。

    “那今天就先讲到这吧,后面我们再对每一个细分领域深入地展开一下。你可以找一些资料先预习下,我出去散会心。。。。。”

    - + diff --git a/dist/string/intern.html b/dist/string/intern.html index 1eb49cf1..902ab008 100644 --- a/dist/string/intern.html +++ b/dist/string/intern.html @@ -39,10 +39,10 @@ } - + -

    深入解析 String#intern

    沉默王二2021年6月5日
    • Java核心
    • Java
    大约 5 分钟

    深入解析 String#intern

    “哥,你发给我的那篇文章我看了,结果直接把我给看得不想学 Java 了!”三妹气冲冲地说。

    “哪一篇啊?”看着三妹面色沉重,我关心地问到。

    “就是美团技术团队深入解析 String.intern() 那篇啊!”三妹回答。

    https://tech.meituan.com/2014/03/06/in-depth-understanding-string-intern.html

    “哦,我想起来了,不挺好一篇文章嘛,深入浅出,精品中的精品,看完后你应该对 String 的 intern 彻底理解了才对呀。”

    “好是好,但我就是看不懂!”三妹委屈地说,“哥,还是你亲自给我讲讲吧?”

    “好吧,上次学的字符串常量池open in new window你都搞清楚了吧?”

    “嗯。”三妹微微的点了点头。

    要理解美团技术团队的这篇文章,你只需要记住这几点内容:

    第一,使用双引号声明的字符串对象会保存在字符串常量池中。

    第二,使用 new 关键字创建的字符串对象会先从字符串常量池中找,如果没找到就创建一个,然后再在堆中创建字符串对象;如果找到了,就直接在堆中创建字符串对象。

    第三,针对没有使用双引号声明的字符串对象来说,就像下面代码中的 s1 那样:

    String s1 = new String("二哥") + new String("三妹");
    +    

    深入解析 String#intern

    沉默王二2021年6月5日
    • Java核心
    • Java
    大约 5 分钟

    深入解析 String#intern

    “哥,你发给我的那篇文章我看了,结果直接把我给看得不想学 Java 了!”三妹气冲冲地说。

    “哪一篇啊?”看着三妹面色沉重,我关心地问到。

    “就是美团技术团队深入解析 String.intern() 那篇啊!”三妹回答。

    https://tech.meituan.com/2014/03/06/in-depth-understanding-string-intern.html

    “哦,我想起来了,不挺好一篇文章嘛,深入浅出,精品中的精品,看完后你应该对 String 的 intern 彻底理解了才对呀。”

    “好是好,但我就是看不懂!”三妹委屈地说,“哥,还是你亲自给我讲讲吧?”

    “好吧,上次学的字符串常量池open in new window你都搞清楚了吧?”

    “嗯。”三妹微微的点了点头。

    要理解美团技术团队的这篇文章,你只需要记住这几点内容:

    第一,使用双引号声明的字符串对象会保存在字符串常量池中。

    第二,使用 new 关键字创建的字符串对象会先从字符串常量池中找,如果没找到就创建一个,然后再在堆中创建字符串对象;如果找到了,就直接在堆中创建字符串对象。

    第三,针对没有使用双引号声明的字符串对象来说,就像下面代码中的 s1 那样:

    String s1 = new String("二哥") + new String("三妹");
     

    如果想把 s1 的内容也放入字符串常量池的话,可以调用 intern() 方法来完成。

    不过,需要注意的是,Java 7 的时候,字符串常量池从永久代中移动到了堆中,虽然此时永久代还没有完全被移除。Java 8 的时候,永久代被彻底移除。

    这个变化也直接影响了 String.intern() 方法在执行时的策略,Java 7 之前,执行 String.intern() 方法的时候,不管对象在堆中是否已经创建,字符串常量池中仍然会创建一个内容完全相同的新对象; Java 7 之后呢,由于字符串常量池放在了堆中,执行 String.intern() 方法的时候,如果对象在堆中已经创建了,字符串常量池中就不需要再创建新的对象了,而是直接保存堆中对象的引用,也就节省了一部分的内存空间。

    “三妹,来猜猜这段代码输出的结果吧。”我说。

    String s1 = new String("二哥三妹");
     String s2 = s1.intern();
     System.out.println(s1 == s2);
    @@ -52,6 +52,6 @@
     System.out.println(s1 == s2);
     

    “难道也输出 false ?”三妹有点不确定。

    “不,这段代码会输出 true。”我否定了三妹的猜测。

    “为啥呀?”三妹迫切地想要知道答案。

    第一行代码,会在字符串常量池中创建两个对象,一个是“二哥”,一个是“三妹”,然后在堆中会创建两个匿名对象“二哥”和“三妹”(可以暂时忽略),最后还有一个“二哥三妹”的对象,s1 引用的是堆中“二哥三妹”这个对象。

    第二行代码,对 s1 执行 intern() 方法,该方法会从字符串常量池中查找“二哥三妹”这个对象是否存在,此时不存在的,但堆中已经存在了,所以字符串常量池中保存的是堆中这个“二哥三妹”对象的引用,也就是说,s2 和 s1 的引用地址是相同的,所以输出的结果为 true。

    “来看一下运行结果。”我胸有成竹地说。

    true
     

    “我再来画幅图,帮助你理解下。”

    “哇,我明白了!”三妹长舒一口气,大有感慨 intern 也没什么难理解的意味。

    不过需要注意的是,尽管 intern 可以确保所有具有相同内容的字符串共享相同的内存空间,但也不要烂用 intern,因为任何的缓存池都是有大小限制的,不能无缘无故就占用了相对稀缺的缓存空间,导致其他字符串没有坑位可占。

    另外,字符串常量池本质上是一个固定大小的 StringTable,如果放进去的字符串过多,就会造成严重的哈希冲突,从而导致链表变长,链表变长也就意味着字符串常量池的性能会大幅下降,因为要一个一个找是需要花费时间的。

    “好了,三妹,关于 String 的 intern 就讲到这吧,这次理解了吧?”我问。

    “哥,你真棒!”

    看到三妹一点一滴的进步,我也感到由衷的开心。

    - + diff --git a/dist/string/join.html b/dist/string/join.html index 0727de6e..023ac204 100644 --- a/dist/string/join.html +++ b/dist/string/join.html @@ -39,10 +39,10 @@ } - + -

    Java字符串拼接的几种方式

    沉默王二2021年7月13日
    • Java核心
    • Java
    大约 8 分钟

    Java字符串拼接的几种方式

    “哥,你让我看的《Java 开发手册》上有这么一段内容:循环体内,拼接字符串最好使用 StringBuilder 的 append() 方法,而不是 + 号操作符。这是为什么呀?”三妹疑惑地问。

    “好的,三妹,哥来慢慢给你讲。”我回答。

    三妹能在学习的过程中不断地发现问题,让我感到非常的开心。其实很多时候,我们不应该只是把知识点记在心里,还应该问一问自己,到底是为什么,只有迈出去这一步,才能真正的成长起来。

    “+ 号操作符其实被 Java 在编译的时候重新解释了,换一种说法就是,+ 号操作符是一种语法糖,让字符串的拼接变得更简便了。”一边给三妹解释,我一边在 Intellij IDEA 中敲出了下面这段代码。

    class Demo {
    +    

    Java字符串拼接的几种方式

    沉默王二2021年7月13日
    • Java核心
    • Java
    大约 8 分钟

    Java字符串拼接的几种方式

    “哥,你让我看的《Java 开发手册》上有这么一段内容:循环体内,拼接字符串最好使用 StringBuilder 的 append() 方法,而不是 + 号操作符。这是为什么呀?”三妹疑惑地问。

    “好的,三妹,哥来慢慢给你讲。”我回答。

    三妹能在学习的过程中不断地发现问题,让我感到非常的开心。其实很多时候,我们不应该只是把知识点记在心里,还应该问一问自己,到底是为什么,只有迈出去这一步,才能真正的成长起来。

    “+ 号操作符其实被 Java 在编译的时候重新解释了,换一种说法就是,+ 号操作符是一种语法糖,让字符串的拼接变得更简便了。”一边给三妹解释,我一边在 Intellij IDEA 中敲出了下面这段代码。

    class Demo {
         public static void main(String[] args) {
             String chenmo = "沉默";
             String wanger = "王二";
    @@ -229,6 +229,6 @@ public class com.itwanger.thirtyseven.Demo {
         return buf.toString();
     }
     

    内部使用的仍然是 StringBuilder。

    “好了,三妹,关于字符串拼接的知识点我们就讲到这吧。注意 Java 9 以后,对 + 号操作符的解释和之前发生了变化,字节码指令已经不同了,等后面你学了字节码指令后我们再详细地讲一次。”我说。

    “嗯,哥,你休息吧,我把这些例子再重新跑一遍。”三妹说。

    - + diff --git a/dist/string/split.html b/dist/string/split.html index 58af4729..f8a55a93 100644 --- a/dist/string/split.html +++ b/dist/string/split.html @@ -39,10 +39,10 @@ } - + -

    如何在Java中优雅地分割String字符串?

    沉默王二2021年7月13日
    • Java核心
    • Java
    大约 6 分钟

    如何在Java中优雅地分割String字符串?

    “哥,我感觉字符串拆分没什么可讲的呀,直接上 String 类的 split() 方法不就可以了!”三妹毫不客气地说。

    “假如你真的这么觉得,那可要注意了,事情远没这么简单。”我微笑着说。

    假如现在有这样一串字符序列“沉默王二,一枚有趣的程序员”,需要按照中文逗号“,”进行拆分,这意味着第一串字符序列为逗号前面的“沉默王二”,第二串字符序列为逗号后面的“一枚有趣的程序员”。

    “这不等于没说吗?哥!”还没等我说,三妹就打断了我。

    “别着急嘛,等哥说完。”我依然保持着微笑继续说,“在拆分之前,要先进行检查,判断一下这串字符是否包含逗号,否则应该抛出异常。”

    public class Test {
    +    

    如何在Java中优雅地分割String字符串?

    沉默王二2021年7月13日
    • Java核心
    • Java
    大约 6 分钟

    如何在Java中优雅地分割String字符串?

    “哥,我感觉字符串拆分没什么可讲的呀,直接上 String 类的 split() 方法不就可以了!”三妹毫不客气地说。

    “假如你真的这么觉得,那可要注意了,事情远没这么简单。”我微笑着说。

    假如现在有这样一串字符序列“沉默王二,一枚有趣的程序员”,需要按照中文逗号“,”进行拆分,这意味着第一串字符序列为逗号前面的“沉默王二”,第二串字符序列为逗号后面的“一枚有趣的程序员”。

    “这不等于没说吗?哥!”还没等我说,三妹就打断了我。

    “别着急嘛,等哥说完。”我依然保持着微笑继续说,“在拆分之前,要先进行检查,判断一下这串字符是否包含逗号,否则应该抛出异常。”

    public class Test {
         public static void main(String[] args) {
             String cmower = "沉默王二,一枚有趣的程序员";
             if (cmower.contains(",")) {
    @@ -108,6 +108,6 @@
     }
     

    进入 debug 模式的话,可以看到以下内容:

    也就是说,传递 2 个参数的时候,会直接调用 substring() 进行截取,第二个分隔符后的就不再拆分了。

    来看一下程序输出的结果:

    第一部分:沉默王二 第二部分:一枚有趣的程序员,宠爱他
     

    “没想到啊,这个字符串拆分还挺讲究的呀!”三妹感慨地说。

    “是的,其实字符串拆分在实际的工作当中还是挺经常用的。前端经常会按照规则传递一长串字符序列到后端,后端就需要按照规则把字符串拆分再做处理。”我说。

    “嗯,我把今天的内容温习下,二哥,你休息会。”三妹说。

    - + diff --git a/dist/szjy/buy-cloud-server.html b/dist/szjy/buy-cloud-server.html index 4b4f7518..c0f4bdb8 100644 --- a/dist/szjy/buy-cloud-server.html +++ b/dist/szjy/buy-cloud-server.html @@ -39,10 +39,10 @@ } - + -

    购买云服务器

    沉默王二2022年6月8日
    • 知识库搭建
    • 知识库搭建
    大约 1 分钟

    马上 618/1111 了,各大云服务器厂家应该已经准备好活动方案了,不管如何,新用户应该是最香的,反正不管什么时候,我们都只负责白飘——备份迁移,绝不续费!

    谁让这些云服务器厂家在续费上贵的一笔呢?需要云服务器的小伙伴可以直接扫码进群(需要确保是新用户,之前没购买过阿里云产品的,购过买的切记用亲朋好友的账号顶上),反正白嫖就是香。

    总之一句话,“老客不如狗,新客是真香”~

    有些买过服务器的小伙伴,已经把个人博客整起来了,这里推荐三个给大家欣赏一下(可以直接复制图片下的链接到浏览器地址栏),真的惊艳~

    http://zhuoke.xyz/

    打开这个网站的时候要小心,小心差点鼻血流出来~~~~

    https://laifeng.xyz/about_me/

    https://www.zm211314.top/

    不得不说,都是二哥的铁粉,个人博客还不忘夸二哥一番。

    😜

    之前买阿里云服务器的时候,很多小伙伴就强烈要求二哥出一些教程把饭喂到嘴里,因为是第一次——玩服务器~

    我出过一期视频,讲了程序员拥有一台云服务器能做哪些很酷的事情?

    视频地址戳这里:https://www.bilibili.com/video/BV1nb4y187rU/open in new window

    - +

    购买云服务器

    沉默王二2022年6月8日
    • 知识库搭建
    • 知识库搭建
    大约 1 分钟

    马上 618/1111 了,各大云服务器厂家应该已经准备好活动方案了,不管如何,新用户应该是最香的,反正不管什么时候,我们都只负责白飘——备份迁移,绝不续费!

    谁让这些云服务器厂家在续费上贵的一笔呢?需要云服务器的小伙伴可以直接扫码进群(需要确保是新用户,之前没购买过阿里云产品的,购过买的切记用亲朋好友的账号顶上),反正白嫖就是香。

    总之一句话,“老客不如狗,新客是真香”~

    有些买过服务器的小伙伴,已经把个人博客整起来了,这里推荐三个给大家欣赏一下(可以直接复制图片下的链接到浏览器地址栏),真的惊艳~

    http://zhuoke.xyz/

    打开这个网站的时候要小心,小心差点鼻血流出来~~~~

    https://laifeng.xyz/about_me/

    https://www.zm211314.top/

    不得不说,都是二哥的铁粉,个人博客还不忘夸二哥一番。

    😜

    之前买阿里云服务器的时候,很多小伙伴就强烈要求二哥出一些教程把饭喂到嘴里,因为是第一次——玩服务器~

    我出过一期视频,讲了程序员拥有一台云服务器能做哪些很酷的事情?

    视频地址戳这里:https://www.bilibili.com/video/BV1nb4y187rU/open in new window

    + diff --git a/dist/szjy/buy-domain.html b/dist/szjy/buy-domain.html index d33f2ec4..9ea78a08 100644 --- a/dist/szjy/buy-domain.html +++ b/dist/szjy/buy-domain.html @@ -39,10 +39,10 @@ } - + -

    购买域名&域名解析

    沉默王二2022年6月8日
    • 知识库搭建
    • 知识库搭建
    大约 2 分钟

    购买域名可以通过多个服务商,比如说阿里云、百度云、腾讯云。

    我这里以阿里云为例,购入一个 tobebetterjavaer.comopen in new window 的域名(寓意 Java 程序员进阶之路)。

    在此之前呢,我已经购买了一台阿里云的服务器,2核4G内存的轻量级云服务器。就是上次带大家白票的那波open in new window,我自己也购入了一台。

    这台服务器上目前已经安装了宝塔面板open in new windowNginxopen in new window,并且可以通过 IP 地址成功访问 80 端口。

    我想做什么呢?

    我希望可以通过域名直接访问而不是 IP

    直接在浏览器地址栏里输入域名访问肯定是不行的。

    那该怎么办呢?

    进行域名解析。当我们购买了一台云服务器后,系统会默认给这台服务器分配一个已经绑定的 IP 地址。但由于 IP 地址是由数组组成的,不方便记忆,所以就使用域名来代替。

    域名解析就是把域名指向网站的 IP 地址,让用户通过域名就可以访问到网站的一种服务。

    阿里云是通过云解析 DNS 提供域名解析服务的。DNS,全称 Domain Name System,也就是域名系统,是一个将域名和IP地址相互映射的分布式数据库,以便用户访问互联网。

    云解析 DNS 支持 A、AAAA 、CNAME 等记录类型。

    进入域名控制台,选择要解析的域名,点击「解析」会跳转到解析设置页面。

    直接点击「新手指导」按钮,填写服务器的 IP 地址。

    该方法可以同时添加 www 和 @ 记录,成功后,可以通过带 www 和不带 www 的方式访问网站。

    TTL 为缓存时间,数值越小,表示修改记录生效的时间越快,默认为10分钟。

    记得对域名进行实名认证,认证通过后(否则域名会处于锁定状态 serverhold),再次刷新页面,就可以访问成功了!

    nice!

    - +

    购买域名&域名解析

    沉默王二2022年6月8日
    • 知识库搭建
    • 知识库搭建
    大约 2 分钟

    购买域名可以通过多个服务商,比如说阿里云、百度云、腾讯云。

    我这里以阿里云为例,购入一个 tobebetterjavaer.comopen in new window 的域名(寓意 Java 程序员进阶之路)。

    在此之前呢,我已经购买了一台阿里云的服务器,2核4G内存的轻量级云服务器。就是上次带大家白票的那波open in new window,我自己也购入了一台。

    这台服务器上目前已经安装了宝塔面板open in new windowNginxopen in new window,并且可以通过 IP 地址成功访问 80 端口。

    我想做什么呢?

    我希望可以通过域名直接访问而不是 IP

    直接在浏览器地址栏里输入域名访问肯定是不行的。

    那该怎么办呢?

    进行域名解析。当我们购买了一台云服务器后,系统会默认给这台服务器分配一个已经绑定的 IP 地址。但由于 IP 地址是由数组组成的,不方便记忆,所以就使用域名来代替。

    域名解析就是把域名指向网站的 IP 地址,让用户通过域名就可以访问到网站的一种服务。

    阿里云是通过云解析 DNS 提供域名解析服务的。DNS,全称 Domain Name System,也就是域名系统,是一个将域名和IP地址相互映射的分布式数据库,以便用户访问互联网。

    云解析 DNS 支持 A、AAAA 、CNAME 等记录类型。

    进入域名控制台,选择要解析的域名,点击「解析」会跳转到解析设置页面。

    直接点击「新手指导」按钮,填写服务器的 IP 地址。

    该方法可以同时添加 www 和 @ 记录,成功后,可以通过带 www 和不带 www 的方式访问网站。

    TTL 为缓存时间,数值越小,表示修改记录生效的时间越快,默认为10分钟。

    记得对域名进行实名认证,认证通过后(否则域名会处于锁定状态 serverhold),再次刷新页面,就可以访问成功了!

    nice!

    + diff --git a/dist/szjy/https-domain.html b/dist/szjy/https-domain.html index cbda6091..4d57cb2c 100644 --- a/dist/szjy/https-domain.html +++ b/dist/szjy/https-domain.html @@ -39,10 +39,10 @@ } - + -

    给域名配置HTTPS证书

    沉默王二2022年6月8日
    • 知识库搭建
    • 知识库搭建
    大约 4 分钟

    上一次,我们完成域名解析open in new window后,发现浏览器地址栏里的域名被提示为不安全,就是因为它还是个宝宝,没有从 HTTP 升级为 HTTPS。

    那怎么升级为 HTTPS 证书呢?可以直接通过阿里云购买 SSL 证书,但特么巨贵!

    本来想尝试一下 AWS 的免费 SSL 证书,但卡到验证码这一步就是收不到信息。

    索性就还用 FreeSSL 吧。

    FreeSSL.cn 是一个提供免费HTTPS证书申请的网站,网址如下:

    https://freessl.cnopen in new window

    输入域名 tobebetterjavaer.com 选择 trustAsia 品牌证书,点击「创建」,这次我选择的是三年期自动化(刚好我的服务器申请的是三年,域名也是三年),9.9 元,还是非常良心的。

    微信/支付宝支付完成后会跳到证书的订单列表。

    选择「更多操作」里的订单详情,会跳转到 CertCloud 页的管理订单。

    点击「提交 CSR」后点击「提交」。

    接下来就到了域名验证环节,点击「获取验证信息」。

    切换到域名解析设置页,准备添加记录。

    按照 CertCloud 提供的域名验证信息,添加记录。

    添加完成后切换到 CertCloud,点击「域名验证」。

    如果不确定上一步的记录是否添加成功,可以点击「诊断」按钮进行测试,如果没有问题会提示匹配成功的信息。

    之后,点击「我已完成配置,检测一下」,如果没有问题,会先提示等待 CA 颁发证书,之后再次检测会提示「证书已签发,请刷新页面查看」。

    好的,直接刷新页面,可以看到订单状态已经变成「已签发」的状态。

    点击证书操作中的「下载证书」,选择适用于 Nginx 的 PEM 格式证书,点击下载。

    使用 Tabby 终端open in new window的「SFTP」将证书上传到网站的云服务器。

    打开宝塔面板open in new window,准备配置 Nginx 的 SSL 证书。将以下信息复制到 Nginx 的配置文件中,保存后重新加载配置。

    # HTTPS server
    +    

    给域名配置HTTPS证书

    沉默王二2022年6月8日
    • 知识库搭建
    • 知识库搭建
    大约 4 分钟

    上一次,我们完成域名解析open in new window后,发现浏览器地址栏里的域名被提示为不安全,就是因为它还是个宝宝,没有从 HTTP 升级为 HTTPS。

    那怎么升级为 HTTPS 证书呢?可以直接通过阿里云购买 SSL 证书,但特么巨贵!

    本来想尝试一下 AWS 的免费 SSL 证书,但卡到验证码这一步就是收不到信息。

    索性就还用 FreeSSL 吧。

    FreeSSL.cn 是一个提供免费HTTPS证书申请的网站,网址如下:

    https://freessl.cnopen in new window

    输入域名 tobebetterjavaer.com 选择 trustAsia 品牌证书,点击「创建」,这次我选择的是三年期自动化(刚好我的服务器申请的是三年,域名也是三年),9.9 元,还是非常良心的。

    微信/支付宝支付完成后会跳到证书的订单列表。

    选择「更多操作」里的订单详情,会跳转到 CertCloud 页的管理订单。

    点击「提交 CSR」后点击「提交」。

    接下来就到了域名验证环节,点击「获取验证信息」。

    切换到域名解析设置页,准备添加记录。

    按照 CertCloud 提供的域名验证信息,添加记录。

    添加完成后切换到 CertCloud,点击「域名验证」。

    如果不确定上一步的记录是否添加成功,可以点击「诊断」按钮进行测试,如果没有问题会提示匹配成功的信息。

    之后,点击「我已完成配置,检测一下」,如果没有问题,会先提示等待 CA 颁发证书,之后再次检测会提示「证书已签发,请刷新页面查看」。

    好的,直接刷新页面,可以看到订单状态已经变成「已签发」的状态。

    点击证书操作中的「下载证书」,选择适用于 Nginx 的 PEM 格式证书,点击下载。

    使用 Tabby 终端open in new window的「SFTP」将证书上传到网站的云服务器。

    打开宝塔面板open in new window,准备配置 Nginx 的 SSL 证书。将以下信息复制到 Nginx 的配置文件中,保存后重新加载配置。

    # HTTPS server
     
     server {
         listen       443 ssl;
    @@ -67,7 +67,7 @@ server {
         server_name  tobebetterjavaer.com www.tobebetterjavaer.com;
         return 301 https://$server_name$request_uri;
     }
    -

    注释掉原来的 80 端口监听,改为 return 跳转。

    再次刷新原来的 HTTP 访问链接,可以看到已经跳转到 HTTPS 了,如果你查看地址栏的话,也会看到地址变成了 [https://tobebetterjavaer.com](https://tobebetterjavaer.com。

    希望这个小破站能自力更生地活下去。目前已有的花费有:

    • 阿里云服务器:3 年 204 元
    • 域名:3 年 273 元
    • SSL 证书:3 年 9.9 元

    希望能给学习 Java 的小伙伴提供一点点帮助,二哥就感觉值了!

    到此为止,《Java 程序员进阶之路》网站的硬件设施就全部完善了,她已经是个成熟的宝宝了。

    希望百度和谷歌等搜索引擎尽快收录,后面也会去学习一些 SEO 方面的知识,提高一下网站的排名,让网站获得更多的流量,从而提升品牌的影响力。

    恭喜!

    - +

    注释掉原来的 80 端口监听,改为 return 跳转。

    再次刷新原来的 HTTP 访问链接,可以看到已经跳转到 HTTPS 了,如果你查看地址栏的话,也会看到地址变成了 [https://tobebetterjavaer.com](https://tobebetterjavaer.com。

    希望这个小破站能自力更生地活下去。目前已有的花费有:

    • 阿里云服务器:3 年 204 元
    • 域名:3 年 273 元
    • SSL 证书:3 年 9.9 元

    希望能给学习 Java 的小伙伴提供一点点帮助,二哥就感觉值了!

    到此为止,《Java 程序员进阶之路》网站的硬件设施就全部完善了,她已经是个成熟的宝宝了。

    希望百度和谷歌等搜索引擎尽快收录,后面也会去学习一些 SEO 方面的知识,提高一下网站的排名,让网站获得更多的流量,从而提升品牌的影响力。

    恭喜!

    + diff --git a/dist/szjy/install-baota-mianban.html b/dist/szjy/install-baota-mianban.html index 4fefb1da..27f13ad3 100644 --- a/dist/szjy/install-baota-mianban.html +++ b/dist/szjy/install-baota-mianban.html @@ -39,11 +39,11 @@ } - + -

    安装宝塔面板

    沉默王二2022年6月8日
    • 知识库搭建
    • 知识库搭建
    大约 4 分钟

    今天来给大家推荐一款玩转云服务器的神器——宝塔面板,有了这玩意,服务器能玩一整年,甚至余生!

    https://www.bt.cn/

    --------开始保姆级演示如何安装宝塔面板-------

    为了给大家呈现出保姆级的教程,我自己新下单了一款轻量应用服务器。登录阿里云服务器后台,可以看到这台服务器正在运行当中。

    点击「远程链接」的小图标,第一次需要手机验证码,之后进入到在线版的终端窗口。

    可以按照提示输入 sudo su root 命令切换到 root 账户。

    切换到宝塔Linux 面板页,可以看到对应的安装命令,如下图所示:

    我的云服务器镜像选择的是 CentOS,所以可以直接复制 yum 命令

    yum install -y wget && wget -O install.sh http://download.bt.cn/install/install_6.0.sh && sh install.sh
    +    

    安装宝塔面板

    沉默王二2022年6月8日
    • 知识库搭建
    • 知识库搭建
    大约 4 分钟

    今天来给大家推荐一款玩转云服务器的神器——宝塔面板,有了这玩意,服务器能玩一整年,甚至余生!

    https://www.bt.cn/

    --------开始保姆级演示如何安装宝塔面板-------

    为了给大家呈现出保姆级的教程,我自己新下单了一款轻量应用服务器。登录阿里云服务器后台,可以看到这台服务器正在运行当中。

    点击「远程链接」的小图标,第一次需要手机验证码,之后进入到在线版的终端窗口。

    可以按照提示输入 sudo su root 命令切换到 root 账户。

    切换到宝塔Linux 面板页,可以看到对应的安装命令,如下图所示:

    我的云服务器镜像选择的是 CentOS,所以可以直接复制 yum 命令

    yum install -y wget && wget -O install.sh http://download.bt.cn/install/install_6.0.sh && sh install.sh
     

    到云服务器的「终端」下进行在线安装。

    yum 命令是 CentOS 的优势,可以在线安装和升级软件。当出现上图提示的内容(外网面板地址、用户名和密码)后就表示宝塔面板安装成功了!

    前后大概 2 分钟左右的时间,还是比较快的。记住外网面板地址、用户名和密码,就可以通过宝塔面板访问云服务器了。

    如果无法访问,表示服务器没有开放 8888 端口。选择我的轻量服务器,选择防火墙,选择「添加规则」。

    能看到目前服务器只开放了 HTTP、HTTPS 和 SSH 的端口,8888 端口还没有放行。

    再次访问外网面板地址,就可以看到登录页面了。

    登录成功后(让浏览器帮你记住账号和密码),如果之前有宝塔官方账号,可以选择绑定,如果没有的话,注册一个。之后就可以看到宝塔面板推荐我们安装的服务器软件了。

    通常来说,直接安装 LNMP 组合包就可以了,包括可以一键安装到 Linux 环境的 Nginx、MySQL、PHP 等成员。

    LNMP 一键安装包能为不会 Linux 的新手提供一个可以使用 Linux 生产的基础环境,无需一个一个的输入命令,无需值守,无需为软件之间的依赖而烦恼。

    https://lnmp.orgopen in new window

    LAMP 和 LNMP 的差别就在于前者提供的是 Apache 的 Web 服务器,后来是 Nginx。Nginx 由 Igor Sysoev 为俄罗斯访问量第二的 Rambler.ru 站点开发的 Web服务器软件,国内外的门户网站、行业网站也都在使用Nginx,相当的稳定。

    MySQL 基本上是中小型服务器必备的关系型数据库软件;PHP 虽然没落了,但仍然是很多服务器软件的前置环境,比如说最受欢迎的服务器建站工具 WordPress。

    点击「一键安装」,宝塔面板就会帮我们自动安排上了。

    到此为止,宝塔面板的基础环境就准备完成了。可以在上面按照左侧的菜单项目对服务器进行操作了,比如说:

    • 网站
    • FTP
    • 数据库
    • 监控
    • 安全
    • 防火墙
    • 文件
    • 终端
    • 计划任务
    • 软件商店
    • 等等

    这里先说一下终端,第一次进来的时候需要进行 SSH 账号验证。

    密码从哪里来的呢?

    在「服务器运维」中选择「远程链接」页面下。有 3 种方式,第一种可以直接使用浏览器,第二种使用密钥,第三种使用账户和密码。

    为了方便演示,这里选择选择「设置密码」。

    设置完成后,重启服务器生效。之后在宝塔面板的「终端」面板下填写密码就可以链接了。不过在浏览器的终端里敲命令总感觉有点不太方便,我们最好选择 iterm2、putty、xshell 这样的客户端。

    再说一下软件商店,有付费的有免费的,不过对于我们个人服务器来说,免费版的都足够用了。需要什么安装什么就好了。

    上传下载文件也非常方便。

    ---再再割一下------

    讲真,有了宝塔面板后,操作服务器是真特么的方便啊!装了以后可以:

    • 创建管理网站
    • 带颜色的终端命令行
    • 数据库可视化管理
    • 文件可视化管理
    • 服务器软件可视化管理
    • 一键安装 Nginx 反向代理软件
    • 申请部署网站 SSL 证书
    • 代理云服务器端口
    • 更多强大功能,等待大家去解锁

    - + diff --git a/dist/szjy/record-domain.html b/dist/szjy/record-domain.html index 32b6236a..2ef7a031 100644 --- a/dist/szjy/record-domain.html +++ b/dist/szjy/record-domain.html @@ -5,7 +5,7 @@ - 购买域名&域名解析 | Java 程序员进阶之路 + 备案域名 | Java 程序员进阶之路