{"@attributes":{"version":"2.0"},"channel":{"title":"hello world","link":"https:\/\/sunpe.github.io\/","description":"Recent content on hello world","generator":"Hugo -- gohugo.io","language":"en","copyright":"Copyright &copy; 2022 - sunpeng","lastBuildDate":"Sat, 02 Dec 2023 22:00:00 +0800","item":[{"title":"MySql \u95f4\u9699\u9501\u6574\u7406","link":"https:\/\/sunpe.github.io\/posts\/2023-12-02-mysql-gap-locks\/","pubDate":"Sat, 02 Dec 2023 22:00:00 +0800","guid":"https:\/\/sunpe.github.io\/posts\/2023-12-02-mysql-gap-locks\/","description":"<p>MySql InnoDB \u4e8b\u52a1\u9694\u79bb\u7ea7\u522b\u662f RR \u7684\u60c5\u51b5\u4e0b\uff0c\u95f4\u9699\u9501\u4f1a\u5c01\u9501\u8be5\u6761\u8bb0\u5f55\u76f8\u90bb\u4e24\u4e2a\u952e\u4e4b\u95f4\u7684\u7a7a\u767d\u533a\u57df\uff0c\u9632\u6b62\u5176\u5b83\u4e8b\u52a1\u5728\u8fd9\u4e2a\u533a\u57df\u5185\u63d2\u5165\u3001\u4fee\u6539\u3001\u5220\u9664\u6570\u636e\uff0c\u4ee5\u9632\u6b62\u51fa\u73b0\u5e7b\u8bfb\u73b0\u8c61\u3002<\/p><p>MySql InnoDb \u9ed8\u8ba4\u5f00\u542f\u95f4\u9699\u9501\uff0c\u67e5\u770b\u662f\u95f4\u9699\u9501\u5f00\u542f\u72b6\u6001\uff1a<\/p><pre tabindex=\"0\"><code>show variables like &#39;innodb_locks_unsafe_for_binlog&#39;;<\/code><\/pre><p>\u95f4\u9699\u9501\u4ea7\u751f\u6761\u4ef6\u53ef\u4ee5\u5206\u4e3a\u4ee5\u4e0b\u4e09\u79cd\u60c5\u51b5\uff1a<\/p><ul><li>\u4f7f\u7528\u666e\u901a\u7d22\u5f15\u9501\u5b9a<\/li><li>\u4f7f\u7528\u591a\u5217\u552f\u4e00\u7d22\u5f15 \uff08\u4f7f\u7528\u4e00\u5217\u552f\u4e00\u7d22\u5f15\u9501\u5b9a\u4e0d\u4ea7\u751f\u95f4\u9699\u9501\uff09<\/li><li>\u4f7f\u7528\u552f\u4e00\u7d22\u5f15\u9501\u5b9a\u591a\u884c\u8bb0\u5f55<\/li><\/ul><h1 id=\"\u552f\u4e00\u7d22\u5f15\u7684\u95f4\u9699\u9501\">\u552f\u4e00\u7d22\u5f15\u7684\u95f4\u9699\u9501<\/h1><p>\u5047\u5982\u6709\u5982\u4e0b\u6570\u636e\u8868\uff1a<\/p><pre tabindex=\"0\"><code>CREATE TABLE `test` ( `id` int(1) NOT NULL AUTO_INCREMENT, `name` varchar(8) DEFAULT NULL, PRIMARY KEY (`id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;<\/code><\/pre><h2 id=\"\u6267\u884c-insert-\u64cd\u4f5c\">\u6267\u884c insert \u64cd\u4f5c<\/h2><p>\u6267\u884c\u63d2\u5165\u8bed\u53e5\uff1a<\/p><pre tabindex=\"0\"><code>INSERT INTO `test` VALUES (&#39;1&#39;, &#39;\u5c0f\u7f57&#39;);INSERT INTO `test` VALUES (&#39;5&#39;, &#39;\u5c0f\u9ec4&#39;);INSERT INTO `test` VALUES (&#39;7&#39;, &#39;\u5c0f\u660e&#39;);INSERT INTO `test` VALUES (&#39;11&#39;, &#39;\u5c0f\u7ea2&#39;);<\/code><\/pre><p>\u4ee5\u4e0b\u533a\u95f4\u4f1a\u88ab\u9501\u4f4f\uff1a<\/p><ul><li>(-infinity, 1]<\/li><li>(1, 5]<\/li><li>(5, 7]<\/li><li>(7, 11]<\/li><li>(11, +infinity]<\/li><\/ul><h2 id=\"\u4f7f\u7528\u552f\u4e00\u7d22\u5f15\u9501\u5b9a\u4e00\u884c\">\u4f7f\u7528\u552f\u4e00\u7d22\u5f15\u9501\u5b9a\u4e00\u884c<\/h2><p>\u5982\u679c\u53ea\u6839\u636e\u4e3b\u952e\u6216\u552f\u4e00\u7d22\u5f15\u9501\u5b9a\u4e00\u884c\uff0c\u4e0d\u4f1a\u4ea7\u751f\u95f4\u9699\u9501\uff0c\u6bd4\u5982\u5982\u4e0b\u64cd\u4f5c\uff0c\u53ea\u5bf9 <code>id=5<\/code> \u8fd9\u4e00\u884c\u52a0\u9501\uff0c\u5219\u4e0d\u4f1a\u4ea7\u751f\u95f4\u9699\u9501\uff0c\u4e5f\u4e0d\u4f1a\u963b\u585e\u4e4b\u540e\u7684\u5199\u5165\u3002<\/p><pre tabindex=\"0\"><code>\/* \u5f00\u542f\u4e8b\u52a11 *\/BEGIN;\/* \u67e5\u8be2 id = 5 \u7684\u6570\u636e\u5e76\u52a0\u8bb0\u5f55\u9501 *\/SELECT * FROM `test` WHERE `id` = 5 FOR UPDATE;\/* \u5ef6\u8fdf30\u79d2\u6267\u884c\uff0c\u9632\u6b62\u9501\u91ca\u653e *\/SELECT SLEEP(30);# \u6ce8\u610f\uff1a\u4ee5\u4e0b\u7684\u8bed\u53e5\u4e0d\u662f\u653e\u5728\u4e00\u4e2a\u4e8b\u52a1\u4e2d\u6267\u884c\uff0c\u800c\u662f\u5206\u5f00\u591a\u6b21\u6267\u884c\uff0c\u6bcf\u6b21\u4e8b\u52a1\u4e2d\u53ea\u6709\u4e00\u6761\u6dfb\u52a0\u8bed\u53e5\/* \u4e8b\u52a12\u63d2\u5165\u4e00\u6761 name = &#39;\u5c0f\u5f20&#39; \u7684\u6570\u636e *\/INSERT INTO `test` (`id`, `name`) VALUES (4, &#39;\u5c0f\u5f20&#39;); # \u6b63\u5e38\u6267\u884c\/* \u4e8b\u52a13\u63d2\u5165\u4e00\u6761 name = &#39;\u5c0f\u5f20&#39; \u7684\u6570\u636e *\/INSERT INTO `test` (`id`, `name`) VALUES (8, &#39;\u5c0f\u4e1c&#39;); # \u6b63\u5e38\u6267\u884c\/* \u63d0\u4ea4\u4e8b\u52a11\uff0c\u91ca\u653e\u4e8b\u52a11\u7684\u9501 *\/COMMIT;<\/code><\/pre><h2 id=\"\u4f7f\u7528\u552f\u4e00\u7d22\u5f15\u6216\u4e3b\u952e\u7d22\u5f15\u9501\u5b9a\u591a\u884c\">\u4f7f\u7528\u552f\u4e00\u7d22\u5f15\u6216\u4e3b\u952e\u7d22\u5f15\u9501\u5b9a\u591a\u884c<\/h2><p>\u4f7f\u7528\u552f\u4e00\u7d22\u5f15\u6216\u4e3b\u952e\u7d22\u5f15\u9501\u5b9a\u591a\u884c\uff0c\u4f1a\u4ea7\u751f\u95f4\u9699\u9501\uff0c\u4f8b\u5982\u5982\u4e0b\u64cd\u4f5c\u9501\u5b9a <code>[5, 7]<\/code>\uff0c\u5219\u4f1a\u4ea7\u751f\u95f4\u9699\u9501\uff0c<code>(5, 7]<\/code>\u3001<code>(7, 11]<\/code> \u8fd9\u4e24\u4e2a\u533a\u95f4\uff0c\u90fd\u4e0d\u53ef\u63d2\u5165\u6570\u636e\uff0c\u5176\u4ed6\u533a\u95f4\u53ef\u4ee5\u6b63\u5e38\u63d2\u5165\u6570\u636e\u3002<\/p><pre tabindex=\"0\"><code>\/* \u5f00\u542f\u4e8b\u52a11 *\/BEGIN;\/* \u67e5\u8be2 id \u5728 7 - 11 \u8303\u56f4\u7684\u6570\u636e\u5e76\u52a0\u8bb0\u5f55\u9501 *\/SELECT * FROM `test` WHERE `id` &gt;= 5 AND `id` &lt;= 7 FOR UPDATE;\/* \u5ef6\u8fdf30\u79d2\u6267\u884c\uff0c\u9632\u6b62\u9501\u91ca\u653e *\/SELECT SLEEP(30);# \u6ce8\u610f\uff1a\u4ee5\u4e0b\u7684\u8bed\u53e5\u4e0d\u662f\u653e\u5728\u4e00\u4e2a\u4e8b\u52a1\u4e2d\u6267\u884c\uff0c\u800c\u662f\u5206\u5f00\u591a\u6b21\u6267\u884c\uff0c\u6bcf\u6b21\u4e8b\u52a1\u4e2d\u53ea\u6709\u4e00\u6761\u6dfb\u52a0\u8bed\u53e5\/* \u4e8b\u52a12\u63d2\u5165\u4e00\u6761 id = 3\uff0cname = &#39;\u5c0f\u5f201&#39; \u7684\u6570\u636e *\/INSERT INTO `test` (`id`, `name`) VALUES (3, &#39;\u5c0f\u5f201&#39;); # \u6b63\u5e38\u6267\u884c\/* \u4e8b\u52a13\u63d2\u5165\u4e00\u6761 id = 4\uff0cname = &#39;\u5c0f\u767d&#39; \u7684\u6570\u636e *\/INSERT INTO `test` (`id`, `name`) VALUES (4, &#39;\u5c0f\u767d&#39;); # \u6b63\u5e38\u6267\u884c\/* \u4e8b\u52a14\u63d2\u5165\u4e00\u6761 id = 6\uff0cname = &#39;\u5c0f\u4e1c&#39; \u7684\u6570\u636e *\/INSERT INTO `test` (`id`, `name`) VALUES (6, &#39;\u5c0f\u4e1c&#39;); # \u963b\u585e\/* \u4e8b\u52a15\u63d2\u5165\u4e00\u6761 id = 8\uff0c name = &#39;\u5927\u7f57&#39; \u7684\u6570\u636e *\/INSERT INTO `test` (`id`, `name`) VALUES (8, &#39;\u5927\u7f57&#39;); # \u963b\u585e\/* \u4e8b\u52a16\u63d2\u5165\u4e00\u6761 id = 9\uff0c name = &#39;\u5927\u4e1c&#39; \u7684\u6570\u636e *\/INSERT INTO `test` (`id`, `name`) VALUES (9, &#39;\u5927\u4e1c&#39;); # \u963b\u585e\/* \u4e8b\u52a17\u63d2\u5165\u4e00\u6761 id = 11\uff0c name = &#39;\u674e\u897f&#39; \u7684\u6570\u636e *\/INSERT INTO `test` (`id`, `name`) VALUES (11, &#39;\u674e\u897f&#39;); # \u963b\u585e\/* \u4e8b\u52a18\u63d2\u5165\u4e00\u6761 id = 12\uff0c name = &#39;\u5f20\u4e09&#39; \u7684\u6570\u636e *\/INSERT INTO `test` (`id`, `name`) VALUES (12, &#39;\u5f20\u4e09&#39;); # \u6b63\u5e38\u6267\u884c\/* \u63d0\u4ea4\u4e8b\u52a11\uff0c\u91ca\u653e\u4e8b\u52a11\u7684\u9501 *\/COMMIT;<\/code><\/pre><h2 id=\"\u9501\u4f4f\u7684\u6570\u636e\u4e0d\u5b58\u5728\u7684\u60c5\u51b5\">\u9501\u4f4f\u7684\u6570\u636e\u4e0d\u5b58\u5728\u7684\u60c5\u51b5<\/h2><p>\u9501\u4f4f\u7684\u6570\u636e\u4e0d\u5b58\u5728\u7684\u60c5\u51b5\uff0c\u4f1a\u4ea7\u751f\u95f4\u9699\u9501\uff0c\u5982\u4e0b\u64cd\u4f5c\u9501\u4f4f\u4e00\u6761\u4e0d\u5b58\u5728\u7684\u6570\u636e\uff0c\u4ea7\u751f\u4e86\u95f4\u9699\u9501<\/p><pre tabindex=\"0\"><code>\/* \u5f00\u542f\u4e8b\u52a11 *\/BEGIN;\/* \u67e5\u8be2 id = 3 \u8fd9\u4e00\u6761\u4e0d\u5b58\u5728\u7684\u6570\u636e\u5e76\u52a0\u8bb0\u5f55\u9501 *\/SELECT * FROM `test` WHERE `id` = 3 FOR UPDATE;\/* \u5ef6\u8fdf30\u79d2\u6267\u884c\uff0c\u9632\u6b62\u9501\u91ca\u653e *\/SELECT SLEEP(30);# \u6ce8\u610f\uff1a\u4ee5\u4e0b\u7684\u8bed\u53e5\u4e0d\u662f\u653e\u5728\u4e00\u4e2a\u4e8b\u52a1\u4e2d\u6267\u884c\uff0c\u800c\u662f\u5206\u5f00\u591a\u6b21\u6267\u884c\uff0c\u6bcf\u6b21\u4e8b\u52a1\u4e2d\u53ea\u6709\u4e00\u6761\u6dfb\u52a0\u8bed\u53e5\/* \u4e8b\u52a12\u63d2\u5165\u4e00\u6761 id = 3\uff0cname = &#39;\u5c0f\u5f201&#39; \u7684\u6570\u636e *\/INSERT INTO `test` (`id`, `name`) VALUES (2, &#39;\u5c0f\u5f201&#39;); # \u963b\u585e\/* \u4e8b\u52a13\u63d2\u5165\u4e00\u6761 id = 4\uff0cname = &#39;\u5c0f\u767d&#39; \u7684\u6570\u636e *\/INSERT INTO `test` (`id`, `name`) VALUES (4, &#39;\u5c0f\u767d&#39;); # \u963b\u585e\/* \u4e8b\u52a14\u63d2\u5165\u4e00\u6761 id = 6\uff0cname = &#39;\u5c0f\u4e1c&#39; \u7684\u6570\u636e *\/INSERT INTO `test` (`id`, `name`) VALUES (6, &#39;\u5c0f\u4e1c&#39;); # \u6b63\u5e38\u6267\u884c\/* \u4e8b\u52a15\u63d2\u5165\u4e00\u6761 id = 8\uff0c name = &#39;\u5927\u7f57&#39; \u7684\u6570\u636e *\/INSERT INTO `test` (`id`, `name`) VALUES (8, &#39;\u5927\u7f57&#39;); # \u6b63\u5e38\u6267\u884c\/* \u63d0\u4ea4\u4e8b\u52a11\uff0c\u91ca\u653e\u4e8b\u52a11\u7684\u9501 *\/COMMIT;<\/code><\/pre><h2 id=\"\u5c0f\u7ed3\">\u5c0f\u7ed3<\/h2><ul><li>\u6839\u636e\u4e3b\u952e\u6216\u552f\u4e00\u7d22\u5f15\u5bf9\u67d0\u4e00\u6761\u8bb0\u5f55\u52a0\u9501\uff0c\u5982\u679c\u8bb0\u5f55\u4e0d\u5b58\u5728\u4f1a\u4ea7\u751f\u884c\u9501\u548c\u95f4\u9699\u9501\uff0c\u5982\u679c\u8bb0\u5f55\u5b58\u5728\uff0c\u53ea\u4f1a\u4ea7\u751f\u884c\u9501\u3002<\/li><li>\u8303\u56f4\u67e5\u8be2\u52a0\u9501\uff0c\u4f1a\u4ea7\u751f\u95f4\u9699\u9501<\/li><\/ul><h1 id=\"\u666e\u901a\u7d22\u5f15\u7684\u95f4\u9699\u9501\">\u666e\u901a\u7d22\u5f15\u7684\u95f4\u9699\u9501<\/h1><p>\u5047\u5982\u6709\u5982\u4e0b\u6570\u636e\u8868<\/p><pre tabindex=\"0\"><code>CREATE TABLE `test1` ( `id` int(1) NOT NULL AUTO_INCREMENT, `number` int(1) NOT NULL COMMENT &#39;\u6570\u5b57&#39;, # number \u4e0d\u662f\u552f\u4e00\u503c PRIMARY KEY (`id`), KEY `number` (`number`) USING BTREE) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;<\/code><\/pre><h2 id=\"\u6570\u636e\u5199\u5165\">\u6570\u636e\u5199\u5165<\/h2><p>\u6267\u884c\u5982\u4e0b insert \u64cd\u4f5c<\/p><pre tabindex=\"0\"><code>INSERT INTO `test1` VALUES (1, 1);INSERT INTO `test1` VALUES (5, 3);INSERT INTO `test1` VALUES (7, 8);INSERT INTO `test1` VALUES (11, 12);<\/code><\/pre><p>\u4ee5\u4e0b\u533a\u95f4\u4f1a\u88ab\u9501\u4f4f\uff1a<\/p><ol><li>(-infinity, 1]<\/li><li>(1, 3]<\/li><li>(3, 8]<\/li><li>(8, 12]<\/li><li>(12, +infinity]<\/li><\/ol><h2 id=\"\u4f7f\u7528\u666e\u901a\u7d22\u5f15\">\u4f7f\u7528\u666e\u901a\u7d22\u5f15<\/h2><p>\u6267\u884c\u5982\u4e0b\u64cd\u4f5c\uff0c\u5bf9 <code>number=3<\/code> \u6570\u636e\u52a0\u9501\uff0c\u5bfc\u81f4\u533a\u95f4 <code>[1,8)<\/code> \u88ab\u9501\u4f4f\u3002<\/p><pre tabindex=\"0\"><code>\/* \u5f00\u542f\u4e8b\u52a11 *\/BEGIN;\/* \u67e5\u8be2 number = 3 \u7684\u6570\u636e\u5e76\u52a0\u884c\u9501 *\/SELECT * FROM `test1` WHERE `number` = 3 FOR UPDATE;\/* \u5ef6\u8fdf30\u79d2\u6267\u884c\uff0c\u9632\u6b62\u9501\u91ca\u653e *\/SELECT SLEEP(30);# \u6ce8\u610f\uff1a\u4ee5\u4e0b\u7684\u8bed\u53e5\u4e0d\u662f\u653e\u5728\u4e00\u4e2a\u4e8b\u52a1\u4e2d\u6267\u884c\uff0c\u800c\u662f\u5206\u5f00\u591a\u6b21\u6267\u884c\uff0c\u6bcf\u6b21\u4e8b\u52a1\u4e2d\u53ea\u6709\u4e00\u6761\u6dfb\u52a0\u8bed\u53e5\/* \u4e8b\u52a12\u63d2\u5165\u4e00\u6761 number = 0 \u7684\u6570\u636e *\/INSERT INTO `test1` (`number`) VALUES (0); # \u6b63\u5e38\u6267\u884c\/* \u4e8b\u52a13\u63d2\u5165\u4e00\u6761 number = 1 \u7684\u6570\u636e *\/INSERT INTO `test1` (`number`) VALUES (1); # \u88ab\u963b\u585e\/* \u4e8b\u52a14\u63d2\u5165\u4e00\u6761 number = 2 \u7684\u6570\u636e *\/INSERT INTO `test1` (`number`) VALUES (2); # \u88ab\u963b\u585e\/* \u4e8b\u52a15\u63d2\u5165\u4e00\u6761 number = 4 \u7684\u6570\u636e *\/INSERT INTO `test1` (`number`) VALUES (4); # \u88ab\u963b\u585e\/* \u4e8b\u52a16\u63d2\u5165\u4e00\u6761 number = 8 \u7684\u6570\u636e *\/INSERT INTO `test1` (`number`) VALUES (8); # \u6b63\u5e38\u6267\u884c\/* \u4e8b\u52a17\u63d2\u5165\u4e00\u6761 number = 9 \u7684\u6570\u636e *\/INSERT INTO `test1` (`number`) VALUES (9); # \u6b63\u5e38\u6267\u884c\/* \u4e8b\u52a18\u63d2\u5165\u4e00\u6761 number = 10 \u7684\u6570\u636e *\/INSERT INTO `test1` (`number`) VALUES (10); # \u6b63\u5e38\u6267\u884c\/* \u63d0\u4ea4\u4e8b\u52a11 *\/COMMIT;<\/code><\/pre><h2 id=\"\u4f7f\u7528\u666e\u901a\u7d22\u5f15\u9501\u4f4f\u4e0d\u5b58\u5728\u7684\u6570\u636e\">\u4f7f\u7528\u666e\u901a\u7d22\u5f15\u9501\u4f4f\u4e0d\u5b58\u5728\u7684\u6570\u636e<\/h2><p>\u6267\u884c\u5982\u4e0b\u64cd\u4f5c\uff0c\u9501\u4f4f\u4e00\u6761\u4e0d\u5b58\u5728\u7684\u6570\u636e <code>number=5<\/code>\uff0c<code>(1,3)<\/code>\u3001<code>(3,8)<\/code>\u3001<code>(8,12)<\/code>\u3001<code>(12,+infinity)<\/code> \u533a\u95f4\u88ab\u963b\u585e<\/p><pre tabindex=\"0\"><code>\/* \u5f00\u542f\u4e8b\u52a11 *\/BEGIN;\/* \u67e5\u8be2 number = 5 \u7684\u6570\u636e\u5e76\u52a0\u8bb0\u5f55\u9501 *\/SELECT * FROM `test1` WHERE `number` = 5 FOR UPDATE;\/* \u5ef6\u8fdf30\u79d2\u6267\u884c\uff0c\u9632\u6b62\u9501\u91ca\u653e *\/SELECT SLEEP(30);\/* \u4e8b\u52a11\u63d2\u5165\u4e00\u6761 id = 2\uff0c number = 1 \u7684\u6570\u636e *\/INSERT INTO `test1` (`id`, `number`) VALUES (2, 1); # \u963b\u585e\/* \u4e8b\u52a12\u63d2\u5165\u4e00\u6761 id = 3\uff0c number = 2 \u7684\u6570\u636e *\/INSERT INTO `test1` (`id`, `number`) VALUES (3, 2); # \u963b\u585e\/* \u4e8b\u52a13\u63d2\u5165\u4e00\u6761 id = 6\uff0c number = 8 \u7684\u6570\u636e *\/INSERT INTO `test1` (`id`, `number`) VALUES (6, 8); # \u963b\u585e\/* \u4e8b\u52a14\u63d2\u5165\u4e00\u6761 id = 8\uff0c number = 8 \u7684\u6570\u636e *\/INSERT INTO `test1` (`id`, `number`) VALUES (8, 8); # \u6b63\u5e38\u6267\u884c\/* \u4e8b\u52a15\u63d2\u5165\u4e00\u6761 id = 9\uff0c number = 9 \u7684\u6570\u636e *\/INSERT INTO `test1` (`id`, `number`) VALUES (9, 9); # \u6b63\u5e38\u6267\u884c\/* \u4e8b\u52a16\u63d2\u5165\u4e00\u6761 id = 10\uff0c number = 12 \u7684\u6570\u636e *\/INSERT INTO `test1` (`id`, `number`) VALUES (10, 12); # \u6b63\u5e38\u6267\u884c\/* \u4e8b\u52a17\u4fee\u6539 id = 11\uff0c number = 12 \u7684\u6570\u636e *\/UPDATE `test1` SET `number` = 5 WHERE `id` = 11 AND `number` = 12; # \u963b\u585e\/* \u63d0\u4ea4\u4e8b\u52a11 *\/COMMIT;<\/code><\/pre><h2 id=\"\u5c0f\u7ed3-1\">\u5c0f\u7ed3<\/h2><ul><li>\u5728\u666e\u901a\u7d22\u5f15\u5217\u4e0a\uff0c\u4e0d\u7ba1\u662f\u4f55\u79cd\u67e5\u8be2\uff0c\u53ea\u8981\u52a0\u9501\uff0c\u90fd\u4f1a\u4ea7\u751f\u95f4\u9699\u9501<\/li><li>\u5728\u666e\u901a\u7d22\u5f15\u8ddf\u552f\u4e00\u7d22\u5f15\u4e2d\uff0c\u6570\u636e\u95f4\u9699\u7684\u5206\u6790\uff0c\u6570\u636e\u884c\u662f\u4f18\u5148\u6839\u636e\u666e\u901a\u7d22\u5f15\u6392\u5e8f\uff0c\u518d\u6839\u636e\u552f\u4e00\u7d22\u5f15\u6392\u5e8f<\/li><\/ul><h1 id=\"\u603b\u7ed3\">\u603b\u7ed3<\/h1><ul><li>\u552f\u4e00\u7d22\u5f15\u53ea\u6709\u9501\u4f4f\u591a\u6761\u8bb0\u5f55\u6216\u8005\u4e00\u6761\u4e0d\u5b58\u5728\u7684\u8bb0\u5f55\u7684\u65f6\u5019\uff0c\u624d\u4f1a\u4ea7\u751f\u95f4\u9699\u9501<\/li><li>\u666e\u901a\u7d22\u5f15\u4e0d\u7ba1\u662f\u9501\u4f4f\u5355\u6761\uff0c\u8fd8\u662f\u591a\u6761\u8bb0\u5f55\uff0c\u90fd\u4f1a\u4ea7\u751f\u95f4\u9699\u9501<\/li><\/ul><pre tabindex=\"0\"><code>CREATE TABLE test ( `id` int(1) NOT NULL AUTO_INCREMENT, `age` int(1) NOT NULL , `name` varchar(8) DEFAULT NULL, PRIMARY KEY (`id`), key `idx_age` (`age`)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;INSERT INTO `test` VALUES (1, 10, &#39;\u8d75&#39;);INSERT INTO `test` VALUES (5, 15, &#39;\u94b1&#39;);INSERT INTO `test` VALUES (10, 20, &#39;\u5b59&#39;);INSERT INTO `test` VALUES (15, 25, &#39;\u674e&#39;);# \u4e3b\u952e\/\u552f\u4e00\u7d22\u5f15 \u9501\u5b9a\u5355\u6761\u8bb0\u5f55 \u4e0d\u4ea7\u751f\u95f4\u9699\u9501 \u5bf9\u95f4\u9699\u8bb0\u5f55\u4fee\u6539\u4e0d\u963b\u585ebegin;select * from `test` where id=5 for update ;select sleep(30);# insert into `test`.`test` values (4, 14, &#39;\u5468&#39;); # \u4e0d\u963b\u585e# insert into `test`.`test` values (6, 16, &#39;\u5434&#39;); # \u4e0d\u963b\u585e# \u4e3b\u952e\/\u552f\u4e00\u7d22\u5f15 \u9501\u5b9a\u591a\u6761\u8bb0\u5f55 \u4ea7\u751f\u95f4\u9699\u9501 \u5bf9\u95f4\u9699\u8bb0\u5f55\u4fee\u6539\u963b\u585ebegin;select * from `test` where id&gt;=5 and id&lt;=10 for update ;select sleep(30);# insert into `test`.`test` values (3, 13, &#39;\u90d1&#39;); # \u4e0d\u963b\u585e# insert into `test`.`test` values (7, 17, &#39;\u738b&#39;); # \u963b\u585e# \u4e3b\u952e\/\u552f\u4e00\u7d22\u5f15 \u9501\u4f4f\u4e0d\u5b58\u5728\u7684\u6570\u636e\u65f6 \u4ea7\u751f\u95f4\u9699\u9501 \u5bf9\u95f4\u9699\u8bb0\u5f55\u4fee\u6539\u963b\u585ebegin;select * from `test` where id =7 for update ;select sleep(30);# insert into `test`.`test` values (2, 12, &#39;\u90d1&#39;); # \u4e0d\u963b\u585e# insert into `test`.`test` values (8, 18, &#39;\u738b&#39;); # \u963b\u585e# \u666e\u901a\u7d22\u5f15 \u9501\u4f4f\u5355\u884cdelete from test.test where id in (2, 3, 4, 6, 7, 8);begin;select * from `test` where age = 15 for update ;select sleep(30);commit;# insert into `test`.`test` values (4, 13, &#39;\u5468&#39;); # \u963b\u585e# insert into `test`.`test` values (6, 18, &#39;\u5434&#39;); # \u963b\u585e# insert into `test`.`test` values (12, 22, &#39;\u90d1&#39;); # \u4e0d\u963b\u585e<\/code><\/pre>"},{"title":"golang \u8e29\u5751\u603b\u7ed3","link":"https:\/\/sunpe.github.io\/posts\/2023-05-10-experience-in-golang\/","pubDate":"Wed, 10 May 2023 22:00:00 +0800","guid":"https:\/\/sunpe.github.io\/posts\/2023-05-10-experience-in-golang\/","description":"<h1 id=\"groutine-\u6cc4\u6f0f\">groutine \u6cc4\u6f0f<\/h1><p>goroutine \u662f\u7528\u6237\u6001\u7684\u8f7b\u91cf\u7ea7\u534f\u7a0b\uff0c\u5728 golang \u4e2d\u5f00\u542f groutine \u5f00\u9500\u5f88\u5c0f\uff0c\u80fd\u8f7b\u677e\u5f00\u542f\u6210\u5343\u4e0a\u4e07\u7684 goroutine\u3002\u4f46\u662f\u5982\u679c\u5f00\u542f\u7684 groutine \u957f\u9a7b\u5185\u5b58\uff0c\u5e76\u4e14\u8fd8\u4e0d\u65ad\u7684\u5f00\u542f\u65b0\u7684 goroutine\uff0c\u90a3\u4e48\u53ef\u80fd\u4f1a\u5bfc\u81f4\u5185\u5b58\u6cc4\u6f0f\u95ee\u9898\u3002<\/p><p>\u7a0b\u5e8f 1 \u5c55\u793a\u4e86\u4e00\u79cd\u5e38\u89c1\u7684 goroutine \u6cc4\u6f0f\u7684 case\u3002<code>leak<\/code> \u51fd\u6570\u4e2d\uff0c\u521b\u5efa\u4e00\u4e2a channel\uff0c\u5e76\u542f\u52a8\u4e00\u4e2a goroutine \u6765\u6d88\u8d39\u8fd9\u4e2a channel\u3002\u8fd9\u4e2a goroutine \u7ed3\u675f\u7684\u552f\u4e00\u6761\u4ef6\u662f\u5173\u95ed ch\u3002\u4f46\u662f leak \u51fd\u6570\u8fd4\u56de\u4e4b\u540e\uff0cch \u6ca1\u6709\u88ab\u5173\u95ed\uff0c\u8fd9\u6837 goroutine \u4f1a\u4e00\u76f4\u5728\u5185\u5b58\u4e2d\uff0c\u968f\u7740 leak \u51fd\u6570\u8c03\u7528\u6b21\u6570\u7684\u589e\u591a\uff0c\u5360\u7528\u5185\u5b58\u4e5f\u968f\u7740\u589e\u957f\uff0c\u6700\u7ec8\u5bfc\u81f4\u5185\u5b58\u6cc4\u6f0f\u3002<\/p><div class=\"highlight\"><pre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"><code class=\"language-go\" data-lang=\"go\"><span style=\"display:flex;\"><span><span style=\"color:#75715e\">\/\/ \u7a0b\u5e8f 1 <\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span><span style=\"color:#66d9ef\">func<\/span> <span style=\"color:#a6e22e\">leak<\/span>() {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">ch<\/span> <span style=\"color:#f92672\">:=<\/span> make(<span style=\"color:#66d9ef\">chan<\/span> <span style=\"color:#66d9ef\">int<\/span>)<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">go<\/span> <span style=\"color:#66d9ef\">func<\/span>() {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">for<\/span> <span style=\"color:#66d9ef\">range<\/span> <span style=\"color:#a6e22e\">ch<\/span> { }<\/span><\/span><span style=\"display:flex;\"><span> }() <\/span><\/span><span style=\"display:flex;\"><span>}<\/span><\/span><\/code><\/pre><\/div><p>\u5f00\u542f goroutine \u4e4b\u524d\uff0c\u5fc5\u987b\u8981\u6e05\u695a goroutine \u7684\u9000\u51fa\u6761\u4ef6\u3002<\/p><h1 id=\"\u5728\u5faa\u73af\u4e2d-goroutine-func-\u76f4\u63a5\u4f7f\u7528\u5b57\u9762\u91cf\">\u5728\u5faa\u73af\u4e2d goroutine func \u76f4\u63a5\u4f7f\u7528\u5b57\u9762\u91cf<\/h1><p>\u8fd9\u662f\u521a\u5f00\u59cb\u5199 goroutine \u65f6\u7279\u522b\u5bb9\u6613\u72af\u7684\u4e00\u4e2a\u95ee\u9898\uff0c\u5728\u5faa\u73af\u4e2d goroutine func \u76f4\u63a5\u4f7f\u7528\u5b57\u9762\u91cf\uff0c\u53ef\u80fd\u4f1a\u5bfc\u81f4\u4e00\u4e9b\u4e0d\u53ef\u9884\u671f\u7684\u884c\u4e3a\u3002\u7b80\u5355\u770b\u4e00\u4e2a demo\u3002\u7a0b\u5e8f 2 \u4e2d\uff0c\u539f\u60f3\u8f93\u51fa <code>array<\/code> \u4e2d\u7684\u503c\uff0c\u4f46\u6700\u7ec8\u8f93\u51fa\u7684\u53ef\u80fd\u4e0d\u786e\u5b9a\uff0c\u5728\u6211\u7684\u673a\u5668\u4e0a\u662f <code>55555<\/code>\u3002\u8fd9\u6bb5\u4ee3\u7801\u5728 IDE \u4e2d\u4f1a\u6709 <code>Loop variables captured by 'func' literals in 'go' statements might have unexpected values <\/code> \u8b66\u544a\uff0c\u4ea7\u751f\u8fd9\u95ee\u9898\u7684\u539f\u56e0\u662f goroutine \u4e2d\u7684\u533f\u540d\u51fd\u6570\u6267\u884c\u7684\u65f6\u673a\u65f6\u4e0d\u786e\u5b9a\u7684\uff0c\u6267\u884c\u533f\u540d\u51fd\u6570\u65f6\uff0ca \u7684\u503c\u53ef\u80fd\u5df2\u7ecf\u6539\u53d8\u4e86\u3002<\/p><div class=\"highlight\"><pre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"><code class=\"language-go\" data-lang=\"go\"><span style=\"display:flex;\"><span><span style=\"color:#75715e\">\/\/ \u7a0b\u5e8f 2 <\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span><span style=\"color:#66d9ef\">func<\/span> <span style=\"color:#a6e22e\">main<\/span>() {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">array<\/span> <span style=\"color:#f92672\">:=<\/span> []<span style=\"color:#66d9ef\">int<\/span>{<span style=\"color:#ae81ff\">1<\/span>, <span style=\"color:#ae81ff\">2<\/span>, <span style=\"color:#ae81ff\">3<\/span>, <span style=\"color:#ae81ff\">4<\/span>, <span style=\"color:#ae81ff\">5<\/span>}<\/span><\/span><span style=\"display:flex;\"><span><\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">for<\/span> <span style=\"color:#a6e22e\">_<\/span>, <span style=\"color:#a6e22e\">a<\/span> <span style=\"color:#f92672\">:=<\/span> <span style=\"color:#66d9ef\">range<\/span> <span style=\"color:#a6e22e\">array<\/span> {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">go<\/span> <span style=\"color:#66d9ef\">func<\/span>() {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">fmt<\/span>.<span style=\"color:#a6e22e\">Print<\/span>(<span style=\"color:#a6e22e\">a<\/span>)<\/span><\/span><span style=\"display:flex;\"><span> }()<\/span><\/span><span style=\"display:flex;\"><span> }<\/span><\/span><span style=\"display:flex;\"><span><\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">time<\/span>.<span style=\"color:#a6e22e\">Sleep<\/span>(<span style=\"color:#a6e22e\">time<\/span>.<span style=\"color:#a6e22e\">Second<\/span>)<\/span><\/span><span style=\"display:flex;\"><span>}<\/span><\/span><\/code><\/pre><\/div><p>\u4fee\u6539\u65b9\u5f0f\u6709\u5f88\u591a\uff0c\u53ef\u4ee5\u5c06 <code>a<\/code> \u8d4b\u503c\u53e6\u4e00\u4e2a\u53d8\u91cf\uff0c\u5982 \u7a0b\u5e8f 3 \u6240\u793a\uff0c\u7528 <code>i<\/code> \u6682\u5b58 <code>a<\/code> \u7684\u503c\uff0c\u8fd9\u6837\u5c31\u53ef\u4ee5\u8f93\u51fa\u9884\u671f\u7684\u7ed3\u679c\u3002<\/p><div class=\"highlight\"><pre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"><code class=\"language-go\" data-lang=\"go\"><span style=\"display:flex;\"><span><span style=\"color:#75715e\">\/\/ \u7a0b\u5e8f 3 <\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span><span style=\"color:#66d9ef\">func<\/span> <span style=\"color:#a6e22e\">main<\/span>() {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">array<\/span> <span style=\"color:#f92672\">:=<\/span> []<span style=\"color:#66d9ef\">int<\/span>{<span style=\"color:#ae81ff\">1<\/span>, <span style=\"color:#ae81ff\">2<\/span>, <span style=\"color:#ae81ff\">3<\/span>, <span style=\"color:#ae81ff\">4<\/span>, <span style=\"color:#ae81ff\">5<\/span>}<\/span><\/span><span style=\"display:flex;\"><span><\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">for<\/span> <span style=\"color:#a6e22e\">_<\/span>, <span style=\"color:#a6e22e\">a<\/span> <span style=\"color:#f92672\">:=<\/span> <span style=\"color:#66d9ef\">range<\/span> <span style=\"color:#a6e22e\">array<\/span> {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">i<\/span> <span style=\"color:#f92672\">:=<\/span> <span style=\"color:#a6e22e\">a<\/span><\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">go<\/span> <span style=\"color:#66d9ef\">func<\/span>() {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">fmt<\/span>.<span style=\"color:#a6e22e\">Println<\/span>(<span style=\"color:#a6e22e\">i<\/span>)<\/span><\/span><span style=\"display:flex;\"><span> }()<\/span><\/span><span style=\"display:flex;\"><span> }<\/span><\/span><span style=\"display:flex;\"><span><\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">time<\/span>.<span style=\"color:#a6e22e\">Sleep<\/span>(<span style=\"color:#a6e22e\">time<\/span>.<span style=\"color:#a6e22e\">Second<\/span>)<\/span><\/span><span style=\"display:flex;\"><span>}<\/span><\/span><\/code><\/pre><\/div><p>\u6216\u8005\u5c06 <code>a<\/code> \u4f5c\u4e3a\u53c2\u6570\u4f20\u9012\u7ed9 goroutine \u7684\u533f\u540d\u51fd\u6570\uff0c\u5982\u7a0b\u5e8f 4 \u6240\u793a\u3002<\/p><div class=\"highlight\"><pre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"><code class=\"language-go\" data-lang=\"go\"><span style=\"display:flex;\"><span><span style=\"color:#75715e\">\/\/ \u7a0b\u5e8f 4 <\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span><span style=\"color:#66d9ef\">func<\/span> <span style=\"color:#a6e22e\">main<\/span>() {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">array<\/span> <span style=\"color:#f92672\">:=<\/span> []<span style=\"color:#66d9ef\">int<\/span>{<span style=\"color:#ae81ff\">1<\/span>, <span style=\"color:#ae81ff\">2<\/span>, <span style=\"color:#ae81ff\">3<\/span>, <span style=\"color:#ae81ff\">4<\/span>, <span style=\"color:#ae81ff\">5<\/span>}<\/span><\/span><span style=\"display:flex;\"><span><\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">for<\/span> <span style=\"color:#a6e22e\">_<\/span>, <span style=\"color:#a6e22e\">a<\/span> <span style=\"color:#f92672\">:=<\/span> <span style=\"color:#66d9ef\">range<\/span> <span style=\"color:#a6e22e\">array<\/span> {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">go<\/span> <span style=\"color:#66d9ef\">func<\/span>(<span style=\"color:#a6e22e\">i<\/span> <span style=\"color:#66d9ef\">int<\/span>) {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">fmt<\/span>.<span style=\"color:#a6e22e\">Println<\/span>(<span style=\"color:#a6e22e\">i<\/span>)<\/span><\/span><span style=\"display:flex;\"><span> }(<span style=\"color:#a6e22e\">a<\/span>)<\/span><\/span><span style=\"display:flex;\"><span> }<\/span><\/span><span style=\"display:flex;\"><span><\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">time<\/span>.<span style=\"color:#a6e22e\">Sleep<\/span>(<span style=\"color:#a6e22e\">time<\/span>.<span style=\"color:#a6e22e\">Second<\/span>)<\/span><\/span><span style=\"display:flex;\"><span>}<\/span><\/span><\/code><\/pre><\/div><h1 id=\"close-a-closed-channel\">close a closed channel<\/h1><p>golang \u4e2d channel \u4e0d\u80fd\u91cd\u590d close\uff0c\u8fd9\u5e94\u8be5\u662f\u5927\u5bb6\u90fd\u77e5\u9053\u7684\u95ee\u9898\u3002\u8fd9\u91cc\u5c31\u4e0d\u518d\u8d58\u8ff0\u3002golang \u4e2d channel \u53ef\u4ee5\u4e0d\u5173\u95ed\uff0c\u5982\u679c channel \u4e0d\u518d\u88ab\u4f7f\u7528\uff0c\u5373\u4f7f\u4e0d\u5173\u95ed\u4e5f\u4f1a\u88ab\u56de\u6536\u3002\u901a\u5e38 close channel \u4f1a\u4f5c\u4e3a channel \u4e0d\u4f1a\u518d\u6709\u6570\u636e\u7684\u63a7\u5236\u4fe1\u53f7\uff0c\u5982\u679c\u63a5\u6536\u65b9\u4e0d\u5173\u5fc3 channel \u4e2d\u662f\u5426\u8fd8\u4f1a\u6709\u6570\u636e\uff0c\u90a3\u4e48\u6ca1\u5fc5\u8981\u4e3b\u52a8\u5173\u95ed channel\u3002\u5982\u679c\u8981\u5173\u95ed channel\uff0c\u5219\u6700\u597d\u662f\u7531\u53d1\u9001\u65b9\u6765\u5173\u95ed\u3002<\/p><blockquote><p>Note that it is only necessary to close a channel if the receiver is looking for a close. Closing the channel is a control signal on the channel indicating that no more data follows.<\/p><\/blockquote><p>\u5173\u4e8e channel \u8fd8\u6709\u4ee5\u4e0b\u51e0\u4e2a\u70b9\u9700\u8981\u6ce8\u610f\uff1a<\/p><ul><li>channel \u7684\u96f6\u503c\u662f <code>nil<\/code>\uff0c\u4f7f\u7528\u524d\u9700\u8981\u5148\u521d\u59cb\u5316<\/li><li>\u5411\u672a\u521d\u59cb\u5316\u7684 channel \u53d1\u9001\u6570\u636e\u4f1a block<\/li><li>\u4ece\u672a\u521d\u59cb\u5316\u7684 channel \u8bfb\u6570\u636e\u4f1a block<\/li><li>\u5411\u5df2\u7ecf closed \u7684 channel \u53d1\u6570\u636e\u4f1a panic<\/li><li>\u4ece\u5df2\u7ecf closed \u7684 channel \u8bfb\u6570\u636e\u4e0d\u4f1a panic\uff0c\u4f1a\u8bfb\u5230 channel \u4e2d\u672a\u88ab\u8bfb\u53d6\u7684\u6570\u636e\u6216\u9ed8\u8ba4\u503c<\/li><\/ul><h1 id=\"make-\u7684\u4e09\u79cd\u6570\u636e\u7c7b\u578b\">make \u7684\u4e09\u79cd\u6570\u636e\u7c7b\u578b<\/h1><p>make \u51fd\u6570\u53ef\u4ee5\u7528\u4e8e\u521b\u5efa channel\u3001slice\u3001map\u3002\u5176\u4e2d channel \u5fc5\u987b\u5148\u521d\u59cb\u5316\uff1b\u800c map \u5219\u53ef\u4ee5\u53ea\u505a\u58f0\u660e\uff1b\u800c\u5982\u679c\u8981\u7528 index \u64cd\u4f5c slice\uff0c\u5219 slice \u4e5f\u5fc5\u987b\u521d\u59cb\u5316\uff0c\u800c\u4f7f\u7528 append \u5219\u53ef\u4ee5\u4e0d\u7528\u521d\u59cb\u5316\u3002<\/p><p>\u5904\u4e8e\u5bf9\u6027\u80fd\u7684\u8003\u8651\uff0c\u4f7f\u7528 map \u6216 slice \u65f6\uff0c\u5982\u679c\u80fd\u63d0\u524d\u9884\u4f30\u5bb9\u91cf\uff0c\u5219\u63a8\u8350\u5148\u521d\u59cb\u5316\u518d\u4f7f\u7528\uff0c\u5e76\u4e14\u5728\u521d\u59cb\u5316\u7684\u65f6\u5019\u6307\u5b9a\u5bb9\u91cf\u3002<\/p><h1 id=\"\u6df1-copy-or-\u6d45-copy\">\u6df1 copy or \u6d45 copy<\/h1><p>\u6df1 copy \u4f1a\u91cd\u65b0\u5f00\u8f9f\u5185\u5b58\u7a7a\u95f4\u5e76\u521b\u5efa\u4e00\u4e2a\u4e00\u6837\u7684\u5bf9\u8c61\uff0c\u65b0\u5bf9\u8c61\u548c\u539f\u6765\u7684\u5bf9\u8c61\u4e0d\u4f1a\u5171\u4eab\u5185\u5b58\u7a7a\u95f4\u3002\u6d45 copy \u53ea\u4f1a copy \u6570\u636e\u7684\u5730\u5740\uff0c\u65b0\u5bf9\u8c61\u548c\u539f\u6765\u7684\u5bf9\u8c61\u6307\u5411\u540c\u4e00\u5757\u5185\u5b58\u7a7a\u95f4\u3002<\/p><p>\u5148\u8bf4\u7ed3\u8bba\uff0c\u503c\u7c7b\u578b\u9ed8\u8ba4\u6df1 copy\uff0c\u6bd4\u5982 int\u3001 string\u3001\u6570\u7ec4\u3001\u7ed3\u6784\u4f53\u7b49\uff1b\u5f15\u7528\u7c7b\u578b\u9ed8\u8ba4\u6d45 copy\uff0c\u6bd4\u5982 slice\u3001map\u7b49\u3002<\/p><p>\u518d\u6765\u770b\u51e0\u4e2a\u793a\u4f8b\u3002<\/p><p>\u7a0b\u5e8f 5 \u5c55\u793a\u4e86\u6570\u7ec4\u7c7b\u578b\u6df1\u62f7\u8d1d\u7684\u793a\u4f8b\uff0c\u867d\u7136\u5c06 a \u8d4b\u503c\u7ed9 b\uff0c\u4f46 a \u548c b \u662f\u4e0d\u540c\u7684\u6570\u7ec4\uff0c\u4fee\u6539 b \u5e76\u4e0d\u4f1a\u5f71\u54cd a\u3002<\/p><pre tabindex=\"0\"><code>\/\/ \u7a0b\u5e8f 5func main() { a := [3]int{1, 2, 3} b := a fmt.Printf(&#34;a: %+v, %p \\n&#34;, a, &amp;a) \/\/ a: [1 2 3], 0xc00001c0a8 fmt.Printf(&#34;b: %+v, %p \\n&#34;, b, &amp;b) \/\/ b: [1 2 3], 0xc00001c0c0 b[0] = 0 fmt.Printf(&#34;a: %+v, %p \\n&#34;, a, &amp;a) \/\/ a: [1 2 3], 0xc00001c0a8 fmt.Printf(&#34;b: %+v, %p \\n&#34;, b, &amp;b) \/\/ b: [0 2 3], 0xc00001c0c0}<\/code><\/pre><p>\u7a0b\u5e8f 6 \u5c55\u793a\u4e86 slice \u7c7b\u578b\u6d45\u62f7\u8d1d\u7684\u793a\u4f8b\uff0ca \u548c b \u6307\u5411\u540c\u4e00\u4e2a\u5730\u5740\uff0c\u5982\u679c\u4fee\u6539\u4e86 b \uff0c\u90a3\u4e48 a \u4e5f\u4f1a\u968f\u7740\u53d8\u3002<\/p><pre tabindex=\"0\"><code>\/\/ \u7a0b\u5e8f 6func main() { a := []int{1, 2, 3} b := a fmt.Printf(&#34;a: %+v, %p \\n&#34;, a, a) \/\/ a: [1 2 3], 0xc0000b4018 fmt.Printf(&#34;b: %+v, %p \\n&#34;, b, b) \/\/ b: [1 2 3], 0xc0000b4018 b[0] = 0 fmt.Printf(&#34;a: %+v, %p \\n&#34;, a, a) \/\/ a: [0 2 3], 0xc0000b4018 fmt.Printf(&#34;b: %+v, %p \\n&#34;, b, b) \/\/ b: [0 2 3], 0xc0000b4018}<\/code><\/pre><h1 id=\"slice-\u4f5c\u4e3a-\u53c2\u6570\">slice \u4f5c\u4e3a \u53c2\u6570<\/h1><p>slice \u4e2d\u7684 array \u662f\u6307\u9488\u7c7b\u578b\uff0c\u4f5c\u4e3a\u53c2\u6570\u4f20\u9012\u7684\u662f\u6307\u9488\u7684\u503c\uff0c\u4f46\u662f slice \u662f\u4e00\u4e2a\u7ed3\u6784\u4f53\uff0c\u5e76\u4e0d\u5b8c\u5168\u662f\u4e00\u4e2a\u6307\u9488\uff0cslice \u7684\u7ed3\u6784\u5982\u7a0b\u5e8f 7 \u6240\u793a\u3002<\/p><pre tabindex=\"0\"><code>\/\/ \u7a0b\u5e8f 7type slice struct { array unsafe.Pointer len int cap int}<\/code><\/pre><p>\u770b\u4e0b\u9762\u8fd9\u4e2a\u793a\u4f8b\uff0c\u60f3\u5728 <code>appendSlice<\/code> \u51fd\u6570\u4e2d\u5c06\u5143\u7d20 append \u5230 a\uff0c\u4f46\u6700\u7ec8\u8f93\u51fa\u7684\u7ed3\u679c\u4e3a <code>[1, 2, 3]<\/code>\uff0c\u800c\u5e76\u4e0d\u662f\u6211\u4eec\u671f\u671b\u7684\u7ed3\u679c\u3002\u518d\u56de\u8fc7\u6765\u770b slice \u7684\u7ed3\u6784\uff0c\u5176\u4e2d\u7684 array \u662f\u6307\u9488\uff0c\u800c len \u548c cap \u5219\u662f\u666e\u901a\u7684 int \u503c\uff0c\u6240\u4ee5 slice \u4f5c\u4e3a\u51fd\u6570\u53c2\u6570\u65f6\uff0c\u4fee\u6539\u5176\u957f\u5ea6\uff0c\u53ef\u80fd\u4f1a\u5f97\u5230\u975e\u9884\u671f\u7684\u7ed3\u679c\u3002<\/p><pre tabindex=\"0\"><code>\/\/ \u7a0b\u5e8f 8func main() { a := []int{1, 2, 3} appendSlice(a, 4) fmt.Println(a) \/\/ [1, 2, 3]}func appendSlice(s []int, a int) { s = append(s, a)}<\/code><\/pre><h1 id=\"intuint-\u7684\u957f\u5ea6\u4e0d\u662f\u56fa\u5b9a\u7684\">int\/uint \u7684\u957f\u5ea6\u4e0d\u662f\u56fa\u5b9a\u7684<\/h1><p>int \u6570\u636e\u7c7b\u578b\u7684\u957f\u5ea6\u4e0d\u662f\u56fa\u5b9a\u7684\uff0c\u957f\u5ea6\u548c\u5e73\u53f0\u6709\u5173\uff0c\u53ef\u80fd\u662f 32 \u4f4d\uff0c\u4e5f\u53ef\u80fd\u662f 64 \u4f4d\u3002<\/p><h1 id=\"\u4e2d\u6587\u5b57\u7b26\u4e32\u957f\u5ea6\u95ee\u9898\">\u4e2d\u6587\u5b57\u7b26\u4e32\u957f\u5ea6\u95ee\u9898<\/h1><p>\u8ba1\u7b97\u4e2d\u6587\u5b57\u7b26\u4e32\u957f\u5ea6\u7684\u65f6\uff0c\u4e0d\u80fd\u7b80\u5355\u7684\u7528 <code>len()<\/code> \u51fd\u6570\uff0c\u800c\u5e94\u8be5\u4f7f\u7528 <code>utf8.RuneCountInString()<\/code>\uff0c\u6216\u8005\u5148\u8f6c\u6362\u4e3a <code>rune<\/code> \u6570\u7ec4\uff0c\u7136\u540e\u8ba1\u7b97\u6570\u7ec4\u957f\u5ea6\u3002golang \u4e2d\u5b57\u7b26\u4e32\u662f\u5b57\u8282\u6570\u7ec4\uff0c<code>len()<\/code> \u51fd\u6570\u7528\u4e8e\u8ba1\u7b97\u5b57\u7b26\u4e32\u5b57\u8282\u957f\u5ea6\uff0c<code>utf8.RuneCountInString()<\/code> \u4f1a\u8ba1\u7b97\u5b57\u7b26\u957f\u5ea6\u3002<\/p><pre tabindex=\"0\"><code>s1 := &#34;Hello, World!&#34;fmt.Println(len(s1)) \/\/13s2 := &#34;\u4f60\u597d\uff0c\u4e16\u754c\uff01&#34;fmt.Println(len(s2)) \/\/ 18fmt.Println(utf8.RuneCountInString(s2)) \/\/ 6rs := []rune(s2)fmt.Println(len(rs)) \/\/ 6<\/code><\/pre><p><strong>\u672a\u5b8c\u5f85\u7eed&hellip;&hellip;<\/strong><\/p>"},{"title":"grafana plugin \u67e5\u8be2\u7ed3\u679c\u5217\u540d bug \u6392\u67e5","link":"https:\/\/sunpe.github.io\/posts\/2022-11-21-grafana-datasource-plugin-column-name-bug\/","pubDate":"Mon, 21 Nov 2022 22:00:00 +0800","guid":"https:\/\/sunpe.github.io\/posts\/2022-11-21-grafana-datasource-plugin-column-name-bug\/","description":"<h2 id=\"\u95ee\u9898\u63cf\u8ff0\">\u95ee\u9898\u63cf\u8ff0<\/h2><p>\u6709\u7528\u6237\u53cd\u9988\uff0c\u4f7f\u7528 grafanaplugin \uff0c\u5728 alerting \u9875\u9762\u6570\u636e\u67e5\u8be2\u65f6\uff0c\u5c55\u793a\u7684\u5217\u540d\u4e0d\u5bf9\u3002<\/p><p><img src=\"https:\/\/sunpe.github.io\/images\/grafana_plugin_column_name_bug\/1.png\" alt=\"\"><\/p><p>\u67e5\u770b\u9875\u9762\u7684\u8fd4\u56de\u6570\u636e\uff0c\u7b2c\u4e8c\u5217\u7684\u5217\u540d\u7684\u786e\u6709\u95ee\u9898\u3002<\/p><p><img src=\"https:\/\/sunpe.github.io\/images\/grafana_plugin_column_name_bug\/2.jpeg\" alt=\"\"><\/p><h2 id=\"\u95ee\u9898\u6392\u67e5\">\u95ee\u9898\u6392\u67e5<\/h2><p>\u9996\u5148\u6000\u7591\u662f\u63d2\u4ef6\u4ee3\u7801\u7684bug\uff0c\u6dfb\u52a0\u65e5\u5fd7\u6392\u67e5\u63d2\u4ef6 <code>QueryData<\/code> \u65b9\u6cd5\u8f93\u51fa\uff0c\u53d1\u73b0\u8f93\u51fa\u7684\u6570\u636e\u6ca1\u95ee\u9898\u3002<\/p><p><img src=\"https:\/\/sunpe.github.io\/images\/grafana_plugin_column_name_bug\/3.jpeg\" alt=\"\"><\/p><p>\u7531\u6b64\u6000\u7591\u53ef\u80fd\u662f grafana \u5185\u90e8\u7684\u8f6c\u6362\u903b\u8f91\u5f15\u8d77\u7684\u3002<\/p><p>\u4e0b\u8f7d grafana \u6e90\u7801\uff0c\u770b\u5230\u6709 ngalert \u5305\uff0c\u5e94\u8be5\u662f 8.0 \u4e4b\u540e\u52a0\u7684 unified alert \u4ee3\u7801\u5b9e\u73b0\uff0c\u76f8\u5173\u4ee3\u7801\u5e94\u8be5\u662f\u5728\u8fd9\u91cc\u3002grafana \u65e5\u5fd7\u7ea7\u522b\u6539\u6210 debug\uff0c\u5e0c\u671b\u80fd\u6253\u51fa\u6765\u90e8\u5206\u6709\u7528\u7684\u65e5\u5fd7\uff0c\u6700\u7ec8\u627e\u5230\u4e86\u63d2\u4ef6\u8fd4\u56de\u4e4b\u540e\u5c31\u6253\u5370\u8fd9\u884c\u65e5\u5fd7\u3002<\/p><pre tabindex=\"0\"><code>DBUG [11-22|16:43:12] expression datasource query (seriesSet) logger=expr query=A<\/code><\/pre><p>\u5168\u5c40\u641c\u7d22\uff0c\u8fd9\u884c\u65e5\u5fd7\u5728 expr \u5305\u4e0b\u9762\uff0c\u987a\u7740\u8c03\u7528\u5173\u7cfb\u5f80\u4e0a\u627e\uff0c\u53ef\u4ee5\u627e\u5230 ngalert\/eval\/eval.go\uff0c\u73b0\u5728 unified alert \u7684\u8c03\u7528\u5173\u7cfb\u5e94\u8be5\u5c31\u6bd4\u8f83\u6e05\u6670\u4e86\u3002<\/p><p>nglaert \u7684\u8c03\u5ea6\u5668\u9876\u5c42\u63a5\u53e3\u662f <a href=\"https:\/\/github.com\/grafana\/grafana\/blob\/main\/pkg\/services\/ngalert\/schedule\/schedule.go#L32\">ScheduleService<\/a>\uff0c\u8c03\u5ea6\u5668\u4f1a\u4e00\u5c42\u4e00\u5c42\u7684\u8c03\u7528 <a href=\"https:\/\/github.com\/grafana\/grafana\/blob\/main\/pkg\/services\/ngalert\/eval\/eval.go#L40\">ConditionEvaluator<\/a> \u63a5\u53e3\u7684 Execute \u65b9\u6cd5\uff0c\u8be5\u65b9\u6cd5\u4f1a\u8c03\u7528\u63d2\u4ef6\u7684 gRPC \u63a5\u53e3\u67e5\u8be2\u6570\u636e\uff0c\u7136\u540e\u8c03\u7528 eval \u5305\u8fdb\u884c\u6570\u636e\u8f6c\u6362\u3002\u987a\u85e4\u6478\u74dc\uff0c\u6700\u7ec8\u6267\u884c\u6570\u636e\u8f6c\u6362\u7684\u65b9\u6cd5\u662f Node \u63a5\u53e3\u7684 <a href=\"https:\/\/github.com\/grafana\/grafana\/blob\/main\/pkg\/expr\/graph.go#L41\">Execute<\/a> \u65b9\u6cd5\uff0c\u8be5\u65b9\u6cd5\u6709\u4e24\u4e2a\u5b9e\u73b0\uff0c\u5206\u522b\u662f CMDNode \u548c DSNode\uff0c\u800c debug \u65e5\u5fd7\u662f DSNode \u6253\u5370\u7684\uff0c\u6240\u4ee5\u8fdb\u5230 DSNode \u7684 Execute \u65b9\u6cd5\u8fdb\u884c\u6392\u67e5\u3002\u8be5\u65b9\u6cd5\u7684 284 \u884c\u8c03\u7528\u7684 <a href=\"https:\/\/github.com\/grafana\/grafana\/blob\/main\/pkg\/expr\/nodes.go#L407\">WideToMany<\/a> \u8fdb\u884c\u6570\u636e\u683c\u5f0f\u8f6c\u6362\uff0c\u7ee7\u7eed\u6392\u67e5\uff0c\u6700\u7ec8\u7ec8\u4e8e\u5b9a\u4f4d\u5230\u95ee\u9898\u3002<\/p><p>\u6570\u636e\u8f6c\u6362\u65f6\uff0c\u4f1a\u8c03\u7528 <a href=\"https:\/\/github.com\/grafana\/grafana\/blob\/main\/pkg\/expr\/mathexp\/type_series.go#L26\">SeriesFromFrame<\/a> \u51fd\u6570\uff0c\u8be5\u51fd\u6570\u6709<a href=\"https:\/\/github.com\/grafana\/grafana\/blob\/main\/pkg\/expr\/mathexp\/type_series.go#L122\">\u5982\u4e0b\u4ee3\u7801<\/a>\uff1a<\/p><pre tabindex=\"0\"><code>\/\/ We use the frame name as series name if the frame name is setif s.Frame.Name != &#34;&#34; { s.Frame.Fields[seriesTypeValIdx].Name = s.Frame.Name}<\/code><\/pre><p>\u63d2\u4ef6\u4ee3\u7801\u4e2d\uff0c\u5982\u679c\u8bbe\u7f6e\u4e86 Frame \u7684 name\uff0c \u4f1a\u62ff Frame.Name \u8986\u76d6\u6570\u636e\u5217\u7684 Name\u3002<\/p>"},{"title":"consul\u505agrpc\u670d\u52a1\u6ce8\u518c\u548c\u670d\u52a1\u53d1\u73b0","link":"https:\/\/sunpe.github.io\/posts\/2022-10-15-grpc-with-consol\/","pubDate":"Sat, 15 Oct 2022 22:00:00 +0800","guid":"https:\/\/sunpe.github.io\/posts\/2022-10-15-grpc-with-consol\/","description":"<p>\u5206\u5e03\u5f0f\u670d\u52a1\u901a\u5e38\u6709\u591a\u4e2a\u5b9e\u4f8b\uff0c\u6309\u8d1f\u8f7d\u5747\u8861\u5728\u670d\u52a1\u7aef\u4fa7\u6216\u5ba2\u6237\u7aef\u4fa7\u53ef\u4ee5\u5c06\u670d\u52a1\u7684\u8d1f\u8f7d\u5747\u8861\u5206\u4e3a\u670d\u52a1\u7aef\u8d1f\u8f7d\u5747\u8861\u548c\u5ba2\u6237\u7aef\u8d1f\u8f7d\u5747\u8861\u3002<\/p><h2 id=\"\u670d\u52a1\u7aef\u8d1f\u8f7d\">\u670d\u52a1\u7aef\u8d1f\u8f7d<\/h2><p>\u670d\u52a1\u7aef\u901a\u5e38\u4f9d\u8d56 HA Proxy \u7ec4\u4ef6\u5b9e\u73b0\u8d1f\u8f7d\u5747\u8861\uff0c\u6bd4\u5982 nginx \u7b49\uff0c\u800c\u4e14 nginx \u53ef\u4ee5\u505a grpc \u7684\u53cd\u5411\u4ee3\u7406\uff0c\u6574\u4f53\u7ed3\u6784\u5982\u56fe 1 \u6240\u793a\u3002<\/p><p><img src=\"https:\/\/sunpe.github.io\/images\/grpc_with_consul\/1.png\" alt=\"\"><\/p><p>\u56fe1 nginx \u505a grpc \u53cd\u5411\u4ee3\u7406<\/p><p>\u8fd9\u79cd\u65b9\u5f0f\u4e0d\u662f\u672c\u6587\u63a2\u8ba8\u7684\u91cd\u70b9\uff0c\u5177\u4f53\u5b9e\u73b0\u548c\u914d\u7f6e\u53ef\u4ee5\u53c2\u8003\u76f8\u5173 <a href=\"https:\/\/www.nginx.com\/blog\/nginx-1-13-10-grpc\/\">nginx blog<\/a>\u3002<\/p><h2 id=\"\u5ba2\u6237\u7aef\u8d1f\u8f7d\">\u5ba2\u6237\u7aef\u8d1f\u8f7d<\/h2><p>\u5ba2\u6237\u7aef\u8d1f\u8f7d\u4f9d\u8d56\u670d\u52a1\u6ce8\u518c\u4e2d\u5fc3\uff0c\u670d\u52a1\u7aef\u542f\u52a8\u65f6\uff0c\u5411\u6ce8\u518c\u4e2d\u5fc3\u6ce8\u518c\u670d\u52a1\u7684\u5730\u5740\u548c\u7aef\u53e3\uff0c\u5ba2\u6237\u7aef\u542f\u52a8\u65f6\u4ece\u6ce8\u518c\u4e2d\u5fc3\u62c9\u53d6\u670d\u52a1\u7684\u5730\u5740\uff0c\u6574\u4f53\u7ed3\u6784\u5982\u56fe 2 \u6240\u793a\u3002<\/p><p><img src=\"https:\/\/sunpe.github.io\/images\/grpc_with_consul\/2.png\" alt=\"\"><\/p><p>\u56fe2 \u670d\u52a1\u6ce8\u518c\u548c\u670d\u52a1\u53d1\u73b0<\/p><p>grpc \u63d0\u4f9b\u4e86 <a href=\"https:\/\/github.com\/grpc\/grpc-go\/tree\/master\/examples\/helloworld\">helloworld<\/a> demo\u3002<\/p><p>\u5ba2\u6237\u7aef\u901a\u8fc7 <code>grpc.DialContext<\/code> \u521b\u5efa grpc \u8fde\u63a5\uff0cgrpc \u7684 <a href=\"https:\/\/github.com\/grpc\/grpc-go\/blob\/master\/resolver\/resolver.go\">resolver<\/a> \u89e3\u6790 target \u53c2\u6570\u83b7\u5f97\u670d\u52a1\u7aef\u5730\u5740\u3002\u8fd9\u4e2a demo \u7684 target \u4e3a <code>localhost:50051<\/code>\uff0c\u8fd9\u79cd\u683c\u5f0f\u7684 target \u4f1a\u4f7f\u7528\u9ed8\u8ba4\u7684 passthrough \u89e3\u6790\u5668\u89e3\u6790\uff0c\u5373\u5c06 target \u5730\u5740\u76f4\u63a5\u8fd4\u56de\u7ed9<code>r.cc<\/code>\uff0c grpc \u5ba2\u6237\u7aef\u5229\u7528\u8fd9\u4e2a\u5730\u5740\u5efa\u7acb grpc \u94fe\u63a5\u3002<\/p><p>target \u7684\u89e3\u6790\u8fc7\u7a0b\uff1a<\/p><ul><li>\u89e3\u6790 target \u7684 scheme<\/li><li>\u901a\u8fc7 scheme \u83b7\u53d6\u5bf9\u5e94\u7684 resolver builder<\/li><li>\u901a\u8fc7 resolver builder \u521b\u5efa resolver<\/li><li>resolver \u89e3\u6790 target \u83b7\u53d6\u670d\u52a1\u7aef\u670d\u52a1\uff08ip + port\uff09\u5217\u8868<\/li><\/ul><p>grpc \u63d0\u4f9b\u4e86 &ldquo;passthrough&rdquo;\uff08\u9ed8\u8ba4\uff09 \u548c &ldquo;dns&rdquo; \u4e24\u79cd scheme resolver\u5b9e\u73b0\uff0c\u53ef\u4ee5\u53c2\u8003<a href=\"https:\/\/github.com\/grpc\/grpc\/blob\/master\/doc\/naming.md\">name resolve \u6587\u6863<\/a>\u3002\u91cd\u65b0\u5b9e\u73b0 resolver \u5373\u53ef\u81ea\u5b9a\u4e49 target \u89e3\u6790\u7b56\u7565\uff0c\u4ece\u800c\u5b9e\u73b0\u670d\u52a1\u53d1\u73b0\u3002<\/p><h2 id=\"consul-\u505a-grpc-\u670d\u52a1\u6ce8\u518c\u53d1\u73b0\u4e2d\u5fc3\">consul \u505a grpc \u670d\u52a1\u6ce8\u518c\u53d1\u73b0\u4e2d\u5fc3<\/h2><h3 id=\"target-\u683c\u5f0f\">target \u683c\u5f0f<\/h3><p>\u8bbe\u8ba1 target URL \u683c\u5f0f\uff1a<\/p><pre tabindex=\"0\"><code>consul:\/\/ip:port\/${group}\/${service_name}<\/code><\/pre><p>grpc target \u7ed3\u6784\u4f53\u5b9a\u4e49\uff1a<\/p><div class=\"highlight\"><pre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"><code class=\"language-go\" data-lang=\"go\"><span style=\"display:flex;\"><span><span style=\"color:#66d9ef\">type<\/span> <span style=\"color:#a6e22e\">Target<\/span> <span style=\"color:#66d9ef\">struct<\/span> {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">Scheme<\/span> <span style=\"color:#66d9ef\">string<\/span><\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">Authority<\/span> <span style=\"color:#66d9ef\">string<\/span><\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">Endpoint<\/span> <span style=\"color:#66d9ef\">string<\/span><\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">URL<\/span> <span style=\"color:#a6e22e\">url<\/span>.<span style=\"color:#a6e22e\">URL<\/span><\/span><\/span><span style=\"display:flex;\"><span>}<\/span><\/span><\/code><\/pre><\/div><p>target \u7684 scheme \u4e3a &ldquo;consul&rdquo;, Endpoint \u4e3a &ldquo;ip:port&rdquo;\u3002\u6ce8\u518c\u5230 consul \u7684\u670d\u52a1\u5fc5\u987b\u5305\u542b\u300c\u670d\u52a1\u540d\u300d\uff0c\u8fd9\u91cc\u662f &ldquo;service_name&rdquo;\uff0c\u670d\u52a1\u53ef\u4ee5\u5206\u7ec4\uff08tag\uff09\u3002<\/p><h3 id=\"\u670d\u52a1\u7aef\u5b9e\u73b0\">\u670d\u52a1\u7aef\u5b9e\u73b0<\/h3><p>\u670d\u52a1\u7aef\u542f\u52a8\u540e\uff0c\u9700\u8981\u5411 consul \u6ce8\u518c\u670d\u52a1\u7684 ip\u3001\u7aef\u53e3\u3001\u5206\u7ec4\uff08tag\uff09 \u548c \u670d\u52a1\u540d\u3002<\/p><div class=\"highlight\"><pre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"><code class=\"language-go\" data-lang=\"go\"><span style=\"display:flex;\"><span><span style=\"color:#a6e22e\">consul<\/span>, <span style=\"color:#a6e22e\">_<\/span> <span style=\"color:#f92672\">:=<\/span> <span style=\"color:#a6e22e\">api<\/span>.<span style=\"color:#a6e22e\">NewClient<\/span>(<span style=\"color:#f92672\">&amp;<\/span><span style=\"color:#a6e22e\">api<\/span>.<span style=\"color:#a6e22e\">Config<\/span>{<span style=\"color:#a6e22e\">Address<\/span>: <span style=\"color:#e6db74\">&#34;127.0.0.1:8500&#34;<\/span>, <span style=\"color:#a6e22e\">Transport<\/span>: <span style=\"color:#a6e22e\">cleanhttp<\/span>.<span style=\"color:#a6e22e\">DefaultPooledTransport<\/span>()})<\/span><\/span><span style=\"display:flex;\"><span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#a6e22e\">_<\/span> = <span style=\"color:#a6e22e\">consul<\/span>.<span style=\"color:#a6e22e\">Agent<\/span>().<span style=\"color:#a6e22e\">ServiceRegister<\/span>(<span style=\"color:#f92672\">&amp;<\/span><span style=\"color:#a6e22e\">api<\/span>.<span style=\"color:#a6e22e\">AgentServiceRegistration<\/span>{<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">ID<\/span>: <span style=\"color:#a6e22e\">uuid<\/span>.<span style=\"color:#a6e22e\">String<\/span>(),<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">Name<\/span>: <span style=\"color:#a6e22e\">service<\/span>,<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">Tags<\/span>: []<span style=\"color:#66d9ef\">string<\/span>{<span style=\"color:#a6e22e\">s<\/span>.<span style=\"color:#a6e22e\">group<\/span>},<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">Port<\/span>: <span style=\"color:#a6e22e\">s<\/span>.<span style=\"color:#a6e22e\">port<\/span>,<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">Address<\/span>: <span style=\"color:#a6e22e\">s<\/span>.<span style=\"color:#a6e22e\">ip<\/span>,<\/span><\/span><span style=\"display:flex;\"><span>})<\/span><\/span><\/code><\/pre><\/div><p>consul \u652f\u6301 grpc health check\uff0c\u53ef\u4ee5\u53c2\u8003 <a href=\"https:\/\/github.com\/grpc\/grpc\/blob\/master\/doc\/health-checking.md\">health check \u6587\u6863<\/a>\uff0c\u5b9e\u73b0 health check \u670d\u52a1\u3002<\/p><h3 id=\"\u5ba2\u6237\u7aef\u5b9e\u73b0\">\u5ba2\u6237\u7aef\u5b9e\u73b0<\/h3><p>\u5ba2\u6237\u7aef\u9700\u8981\u5b9e\u73b0\u76f8\u5e94\u7684 resolver\u3002\u8fd9\u91cc\u9700\u8981\u5b9e\u73b0 <code>resolver.Builder<\/code> \u63a5\u53e3\u548c <code>resolver.Resolver<\/code> \u63a5\u53e3\u3002<\/p><p><code>Builder<\/code> \u63a5\u53e3\u5b9e\u73b0\u5982\u4e0b\uff1a<\/p><div class=\"highlight\"><pre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"><code class=\"language-go\" data-lang=\"go\"><span style=\"display:flex;\"><span><span style=\"color:#66d9ef\">func<\/span> <span style=\"color:#a6e22e\">init<\/span>() {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">resolver<\/span>.<span style=\"color:#a6e22e\">Register<\/span>(<span style=\"color:#f92672\">&amp;<\/span><span style=\"color:#a6e22e\">consulBuilder<\/span>{})<\/span><\/span><span style=\"display:flex;\"><span>}<\/span><\/span><span style=\"display:flex;\"><span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#66d9ef\">type<\/span> <span style=\"color:#a6e22e\">consulBuilder<\/span> <span style=\"color:#66d9ef\">struct<\/span> {<\/span><\/span><span style=\"display:flex;\"><span>}<\/span><\/span><span style=\"display:flex;\"><span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#66d9ef\">func<\/span> (<span style=\"color:#f92672\">*<\/span><span style=\"color:#a6e22e\">consulBuilder<\/span>) <span style=\"color:#a6e22e\">Build<\/span>(<span style=\"color:#a6e22e\">target<\/span> <span style=\"color:#a6e22e\">resolver<\/span>.<span style=\"color:#a6e22e\">Target<\/span>, <span style=\"color:#a6e22e\">cc<\/span> <span style=\"color:#a6e22e\">resolver<\/span>.<span style=\"color:#a6e22e\">ClientConn<\/span>, <span style=\"color:#a6e22e\">opts<\/span> <span style=\"color:#a6e22e\">resolver<\/span>.<span style=\"color:#a6e22e\">BuildOptions<\/span>) (<span style=\"color:#a6e22e\">resolver<\/span>.<span style=\"color:#a6e22e\">Resolver<\/span>, <span style=\"color:#66d9ef\">error<\/span>) {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">consulHost<\/span> <span style=\"color:#f92672\">:=<\/span> <span style=\"color:#a6e22e\">target<\/span>.<span style=\"color:#a6e22e\">URL<\/span>.<span style=\"color:#a6e22e\">Host<\/span><\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">urlPath<\/span> <span style=\"color:#f92672\">:=<\/span> <span style=\"color:#a6e22e\">target<\/span>.<span style=\"color:#a6e22e\">URL<\/span>.<span style=\"color:#a6e22e\">Path<\/span><\/span><\/span><span style=\"display:flex;\"><span><\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">urlPath<\/span> = <span style=\"color:#a6e22e\">strings<\/span>.<span style=\"color:#a6e22e\">Trim<\/span>(<span style=\"color:#a6e22e\">urlPath<\/span>, <span style=\"color:#e6db74\">&#34;\/&#34;<\/span>)<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">ps<\/span> <span style=\"color:#f92672\">:=<\/span> <span style=\"color:#a6e22e\">strings<\/span>.<span style=\"color:#a6e22e\">Split<\/span>(<span style=\"color:#a6e22e\">urlPath<\/span>, <span style=\"color:#e6db74\">&#34;\/&#34;<\/span>)<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">group<\/span> <span style=\"color:#f92672\">:=<\/span> <span style=\"color:#a6e22e\">ps<\/span>[<span style=\"color:#ae81ff\">0<\/span>]<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">serviceName<\/span> <span style=\"color:#f92672\">:=<\/span> <span style=\"color:#a6e22e\">ps<\/span>[<span style=\"color:#ae81ff\">1<\/span>]<\/span><\/span><span style=\"display:flex;\"><span><\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">consulClient<\/span>, <span style=\"color:#a6e22e\">err<\/span> <span style=\"color:#f92672\">:=<\/span> <span style=\"color:#a6e22e\">api<\/span>.<span style=\"color:#a6e22e\">NewClient<\/span>(<span style=\"color:#f92672\">&amp;<\/span><span style=\"color:#a6e22e\">api<\/span>.<span style=\"color:#a6e22e\">Config<\/span>{<span style=\"color:#a6e22e\">Address<\/span>: <span style=\"color:#a6e22e\">consulHost<\/span>, <span style=\"color:#a6e22e\">Transport<\/span>: <span style=\"color:#a6e22e\">cleanhttp<\/span>.<span style=\"color:#a6e22e\">DefaultPooledTransport<\/span>()})<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">if<\/span> <span style=\"color:#a6e22e\">err<\/span> <span style=\"color:#f92672\">!=<\/span> <span style=\"color:#66d9ef\">nil<\/span> {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">return<\/span> <span style=\"color:#66d9ef\">nil<\/span>, <span style=\"color:#a6e22e\">fmt<\/span>.<span style=\"color:#a6e22e\">Errorf<\/span>(<span style=\"color:#e6db74\">&#34;resolve consul path error %v&#34;<\/span>, <span style=\"color:#a6e22e\">err<\/span>)<\/span><\/span><span style=\"display:flex;\"><span> }<\/span><\/span><span style=\"display:flex;\"><span><\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">r<\/span> <span style=\"color:#f92672\">:=<\/span> <span style=\"color:#f92672\">&amp;<\/span><span style=\"color:#a6e22e\">consulResolver<\/span>{<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">client<\/span>: <span style=\"color:#a6e22e\">consulClient<\/span>,<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">cc<\/span>: <span style=\"color:#a6e22e\">cc<\/span>,<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">disableServiceConfig<\/span>: <span style=\"color:#a6e22e\">opts<\/span>.<span style=\"color:#a6e22e\">DisableServiceConfig<\/span>,<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">group<\/span>: <span style=\"color:#a6e22e\">group<\/span>,<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">serviceName<\/span>: <span style=\"color:#a6e22e\">serviceName<\/span>,<\/span><\/span><span style=\"display:flex;\"><span> }<\/span><\/span><span style=\"display:flex;\"><span><\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#75715e\">\/\/ subscribe and watch<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span> <span style=\"color:#66d9ef\">go<\/span> <span style=\"color:#a6e22e\">r<\/span>.<span style=\"color:#a6e22e\">watch<\/span>()<\/span><\/span><span style=\"display:flex;\"><span><\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">return<\/span> <span style=\"color:#a6e22e\">r<\/span>, <span style=\"color:#66d9ef\">nil<\/span><\/span><\/span><span style=\"display:flex;\"><span>}<\/span><\/span><span style=\"display:flex;\"><span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#66d9ef\">func<\/span> (<span style=\"color:#f92672\">*<\/span><span style=\"color:#a6e22e\">consulBuilder<\/span>) <span style=\"color:#a6e22e\">Scheme<\/span>() <span style=\"color:#66d9ef\">string<\/span> {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">return<\/span> <span style=\"color:#e6db74\">&#34;consul&#34;<\/span><\/span><\/span><span style=\"display:flex;\"><span>}<\/span><\/span><\/code><\/pre><\/div><p>builder \u63a5\u53e3\u8fd4\u56de resolver\uff0c\u5728 <code>ResolveNow<\/code> \u65b9\u6cd5\u4e2d\u8c03\u7528 consul api \u83b7\u53d6\u670d\u52a1\u7aef\u5730\u5740\u3002<\/p><div class=\"highlight\"><pre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"><code class=\"language-go\" data-lang=\"go\"><span style=\"display:flex;\"><span><span style=\"color:#a6e22e\">services<\/span>, <span style=\"color:#a6e22e\">_<\/span>, <span style=\"color:#a6e22e\">_<\/span> <span style=\"color:#f92672\">:=<\/span> <span style=\"color:#a6e22e\">r<\/span>.<span style=\"color:#a6e22e\">client<\/span>.<span style=\"color:#a6e22e\">Health<\/span>().<span style=\"color:#a6e22e\">Service<\/span>(<span style=\"color:#a6e22e\">r<\/span>.<span style=\"color:#a6e22e\">serviceName<\/span>, <span style=\"color:#a6e22e\">r<\/span>.<span style=\"color:#a6e22e\">group<\/span>, <span style=\"color:#66d9ef\">true<\/span>,<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#f92672\">&amp;<\/span><span style=\"color:#a6e22e\">api<\/span>.<span style=\"color:#a6e22e\">QueryOptions<\/span>{<span style=\"color:#a6e22e\">WaitIndex<\/span>: <span style=\"color:#a6e22e\">r<\/span>.<span style=\"color:#a6e22e\">lastIndex<\/span>})<\/span><\/span><span style=\"display:flex;\"><span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#a6e22e\">addresses<\/span> <span style=\"color:#f92672\">:=<\/span> make([]<span style=\"color:#a6e22e\">resolver<\/span>.<span style=\"color:#a6e22e\">Address<\/span>, <span style=\"color:#ae81ff\">0<\/span>, len(<span style=\"color:#a6e22e\">services<\/span>))<\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#66d9ef\">for<\/span> <span style=\"color:#a6e22e\">_<\/span>, <span style=\"color:#a6e22e\">service<\/span> <span style=\"color:#f92672\">:=<\/span> <span style=\"color:#66d9ef\">range<\/span> <span style=\"color:#a6e22e\">services<\/span> {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">addr<\/span> <span style=\"color:#f92672\">:=<\/span> <span style=\"color:#a6e22e\">resolver<\/span>.<span style=\"color:#a6e22e\">Address<\/span>{<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">Addr<\/span>: <span style=\"color:#a6e22e\">fmt<\/span>.<span style=\"color:#a6e22e\">Sprintf<\/span>(<span style=\"color:#e6db74\">&#34;%v:%v&#34;<\/span>, <span style=\"color:#a6e22e\">service<\/span>.<span style=\"color:#a6e22e\">Service<\/span>.<span style=\"color:#a6e22e\">Address<\/span>, <span style=\"color:#a6e22e\">service<\/span>.<span style=\"color:#a6e22e\">Service<\/span>.<span style=\"color:#a6e22e\">Port<\/span>),<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">ServerName<\/span>: <span style=\"color:#a6e22e\">r<\/span>.<span style=\"color:#a6e22e\">serviceName<\/span>,<\/span><\/span><span style=\"display:flex;\"><span> }<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">addresses<\/span> = append(<span style=\"color:#a6e22e\">addresses<\/span>, <span style=\"color:#a6e22e\">addr<\/span>)<\/span><\/span><span style=\"display:flex;\"><span>}<\/span><\/span><span style=\"display:flex;\"><span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#a6e22e\">r<\/span>.<span style=\"color:#a6e22e\">cc<\/span>.<span style=\"color:#a6e22e\">UpdateState<\/span>(<span style=\"color:#a6e22e\">resolver<\/span>.<span style=\"color:#a6e22e\">State<\/span>{<span style=\"color:#a6e22e\">Addresses<\/span>: <span style=\"color:#a6e22e\">addresses<\/span>})<\/span><\/span><\/code><\/pre><\/div><p>\u8be6\u7ec6\u4ee3\u7801\u53ef\u4ee5\u53c2\u8003\u300c\u4ee3\u7801\u5b9e\u73b0\u300d\u7ae0\u8282\u3002<\/p><h3 id=\"\u6d4b\u8bd5\u4e00\u4e0b\">\u6d4b\u8bd5\u4e00\u4e0b<\/h3><ul><li>\u542f\u52a8 consul\uff1a<\/li><\/ul><div class=\"highlight\"><pre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"><code class=\"language-shell\" data-lang=\"shell\"><span style=\"display:flex;\"><span>consul agent --dev<\/span><\/span><\/code><\/pre><\/div><ul><li>\u542f\u52a8\u670d\u52a1\u7aef\uff1a<\/li><\/ul><div class=\"highlight\"><pre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"><code class=\"language-shell\" data-lang=\"shell\"><span style=\"display:flex;\"><span>go run .\/example\/server\/server.go<\/span><\/span><\/code><\/pre><\/div><p><img src=\"https:\/\/sunpe.github.io\/images\/grpc_with_consul\/3.png\" alt=\"\"><\/p><ul><li>\u542f\u52a8\u5ba2\u6237\u7aef\uff1a<\/li><\/ul><div class=\"highlight\"><pre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"><code class=\"language-shell\" data-lang=\"shell\"><span style=\"display:flex;\"><span>go run .\/example\/client\/client.go<\/span><\/span><\/code><\/pre><\/div><h2 id=\"\u4ee3\u7801\u5b9e\u73b0\">\u4ee3\u7801\u5b9e\u73b0<\/h2><ul><li>go \u7248\u672c\u4ee3\u7801\u5b9e\u73b0\uff1a <a href=\"https:\/\/github.com\/sunpe\/grpc_with_consul_go\">https:\/\/github.com\/sunpe\/grpc_with_consul_go<\/a><\/li><li>java \u7248\u672c\u4ee3\u7801\u5b9e\u73b0\uff1a <a href=\"https:\/\/github.com\/sunpe\/grpc_with_consul_java\">https:\/\/github.com\/sunpe\/grpc_with_consul_java<\/a><\/li><\/ul><h2 id=\"\u53c2\u8003\">\u53c2\u8003<\/h2><ol><li><a href=\"https:\/\/www.nginx.com\/blog\/nginx-1-13-10-grpc\/\">https:\/\/www.nginx.com\/blog\/nginx-1-13-10-grpc\/<\/a><\/li><li><a href=\"https:\/\/github.com\/grpc\/grpc-go\/tree\/master\/examples\/helloworld\">https:\/\/github.com\/grpc\/grpc-go\/tree\/master\/examples\/helloworld<\/a><\/li><li><a href=\"https:\/\/github.com\/grpc\/grpc\/blob\/master\/doc\/naming.md\">https:\/\/github.com\/grpc\/grpc\/blob\/master\/doc\/naming.md<\/a><\/li><li><a href=\"https:\/\/github.com\/grpc\/grpc\/blob\/master\/doc\/health-checking.md\">https:\/\/github.com\/grpc\/grpc\/blob\/master\/doc\/health-checking.md<\/a><\/li><\/ol>"},{"title":"Gin \u5f00\u542fpprof","link":"https:\/\/sunpe.github.io\/posts\/2022-07-20-gin-open-pprof\/","pubDate":"Wed, 20 Jul 2022 22:00:00 +0800","guid":"https:\/\/sunpe.github.io\/posts\/2022-07-20-gin-open-pprof\/","description":"<p>\u5728 gin \u4e2d\u5f00\u542fpprof\u4ee3\u7801\u793a\u4f8b\uff1a<\/p><div class=\"highlight\"><pre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"><code class=\"language-go\" data-lang=\"go\"><span style=\"display:flex;\"><span><span style=\"color:#a6e22e\">g<\/span> <span style=\"color:#f92672\">:=<\/span> <span style=\"color:#a6e22e\">gin<\/span>.<span style=\"color:#a6e22e\">New<\/span>()<\/span><\/span><span style=\"display:flex;\"><span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#a6e22e\">router<\/span> <span style=\"color:#f92672\">:=<\/span> <span style=\"color:#a6e22e\">engine<\/span>.<span style=\"color:#a6e22e\">Group<\/span>(<span style=\"color:#e6db74\">&#34;\/debug\/pprof&#34;<\/span>)<\/span><\/span><span style=\"display:flex;\"><span>{<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">router<\/span>.<span style=\"color:#a6e22e\">GET<\/span>(<span style=\"color:#e6db74\">&#34;\/&#34;<\/span>, <span style=\"color:#a6e22e\">gin<\/span>.<span style=\"color:#a6e22e\">WrapF<\/span>(<span style=\"color:#a6e22e\">pprof<\/span>.<span style=\"color:#a6e22e\">Index<\/span>))<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">router<\/span>.<span style=\"color:#a6e22e\">GET<\/span>(<span style=\"color:#e6db74\">&#34;\/cmdline&#34;<\/span>, <span style=\"color:#a6e22e\">gin<\/span>.<span style=\"color:#a6e22e\">WrapF<\/span>(<span style=\"color:#a6e22e\">pprof<\/span>.<span style=\"color:#a6e22e\">Cmdline<\/span>))<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">router<\/span>.<span style=\"color:#a6e22e\">GET<\/span>(<span style=\"color:#e6db74\">&#34;\/profile&#34;<\/span>, <span style=\"color:#a6e22e\">gin<\/span>.<span style=\"color:#a6e22e\">WrapF<\/span>(<span style=\"color:#a6e22e\">pprof<\/span>.<span style=\"color:#a6e22e\">Profile<\/span>))<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">router<\/span>.<span style=\"color:#a6e22e\">POST<\/span>(<span style=\"color:#e6db74\">&#34;\/symbol&#34;<\/span>, <span style=\"color:#a6e22e\">gin<\/span>.<span style=\"color:#a6e22e\">WrapF<\/span>(<span style=\"color:#a6e22e\">pprof<\/span>.<span style=\"color:#a6e22e\">Symbol<\/span>))<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">router<\/span>.<span style=\"color:#a6e22e\">GET<\/span>(<span style=\"color:#e6db74\">&#34;\/symbol&#34;<\/span>, <span style=\"color:#a6e22e\">gin<\/span>.<span style=\"color:#a6e22e\">WrapF<\/span>(<span style=\"color:#a6e22e\">pprof<\/span>.<span style=\"color:#a6e22e\">Symbol<\/span>))<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">router<\/span>.<span style=\"color:#a6e22e\">GET<\/span>(<span style=\"color:#e6db74\">&#34;\/trace&#34;<\/span>, <span style=\"color:#a6e22e\">gin<\/span>.<span style=\"color:#a6e22e\">WrapF<\/span>(<span style=\"color:#a6e22e\">pprof<\/span>.<span style=\"color:#a6e22e\">Trace<\/span>))<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">router<\/span>.<span style=\"color:#a6e22e\">GET<\/span>(<span style=\"color:#e6db74\">&#34;\/allocs&#34;<\/span>, <span style=\"color:#a6e22e\">gin<\/span>.<span style=\"color:#a6e22e\">WrapH<\/span>(<span style=\"color:#a6e22e\">pprof<\/span>.<span style=\"color:#a6e22e\">Handler<\/span>(<span style=\"color:#e6db74\">&#34;allocs&#34;<\/span>)))<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">router<\/span>.<span style=\"color:#a6e22e\">GET<\/span>(<span style=\"color:#e6db74\">&#34;\/block&#34;<\/span>, <span style=\"color:#a6e22e\">gin<\/span>.<span style=\"color:#a6e22e\">WrapH<\/span>(<span style=\"color:#a6e22e\">pprof<\/span>.<span style=\"color:#a6e22e\">Handler<\/span>(<span style=\"color:#e6db74\">&#34;block&#34;<\/span>)))<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">router<\/span>.<span style=\"color:#a6e22e\">GET<\/span>(<span style=\"color:#e6db74\">&#34;\/goroutine&#34;<\/span>, <span style=\"color:#a6e22e\">gin<\/span>.<span style=\"color:#a6e22e\">WrapH<\/span>(<span style=\"color:#a6e22e\">pprof<\/span>.<span style=\"color:#a6e22e\">Handler<\/span>(<span style=\"color:#e6db74\">&#34;goroutine&#34;<\/span>)))<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">router<\/span>.<span style=\"color:#a6e22e\">GET<\/span>(<span style=\"color:#e6db74\">&#34;\/heap&#34;<\/span>, <span style=\"color:#a6e22e\">gin<\/span>.<span style=\"color:#a6e22e\">WrapH<\/span>(<span style=\"color:#a6e22e\">pprof<\/span>.<span style=\"color:#a6e22e\">Handler<\/span>(<span style=\"color:#e6db74\">&#34;heap&#34;<\/span>)))<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">router<\/span>.<span style=\"color:#a6e22e\">GET<\/span>(<span style=\"color:#e6db74\">&#34;\/mutex&#34;<\/span>, <span style=\"color:#a6e22e\">gin<\/span>.<span style=\"color:#a6e22e\">WrapH<\/span>(<span style=\"color:#a6e22e\">pprof<\/span>.<span style=\"color:#a6e22e\">Handler<\/span>(<span style=\"color:#e6db74\">&#34;mutex&#34;<\/span>)))<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">router<\/span>.<span style=\"color:#a6e22e\">GET<\/span>(<span style=\"color:#e6db74\">&#34;\/threadcreate&#34;<\/span>, <span style=\"color:#a6e22e\">gin<\/span>.<span style=\"color:#a6e22e\">WrapH<\/span>(<span style=\"color:#a6e22e\">pprof<\/span>.<span style=\"color:#a6e22e\">Handler<\/span>(<span style=\"color:#e6db74\">&#34;threadcreate&#34;<\/span>)))<\/span><\/span><span style=\"display:flex;\"><span>}<\/span><\/span><\/code><\/pre><\/div><p>\u6b64\u5916\uff0c\u53ef\u4ee5\u5f15\u7528 <code>https:\/\/github.com\/gin-contrib\/pprof<\/code> \u5305\u5b9e\u73b0\u3002<\/p>"},{"title":"golang map","link":"https:\/\/sunpe.github.io\/posts\/2021-11-24-golang-map\/","pubDate":"Wed, 24 Nov 2021 22:00:00 +0800","guid":"https:\/\/sunpe.github.io\/posts\/2021-11-24-golang-map\/","description":"<p><img src=\"https:\/\/sunpe.github.io\/images\/golang_map\/1.png\" alt=\"\"><\/p><h2 id=\"hmap\">hmap<\/h2><p>map \u662f\u5f15\u7528\u7c7b\u578b\uff0c\u6307\u9488\u6307\u5411 hmap \u7ed3\u6784\u4f53\uff0chmap \u7684 <a href=\"https:\/\/github.com\/golang\/go\/blob\/master\/src\/runtime\/map.go#L116\">\u6e90\u7801<\/a> \u5982\u4e0b\uff1a<\/p><div class=\"highlight\"><pre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"><code class=\"language-go\" data-lang=\"go\"><span style=\"display:flex;\"><span><span style=\"color:#66d9ef\">type<\/span> <span style=\"color:#a6e22e\">hmap<\/span> <span style=\"color:#66d9ef\">struct<\/span> {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">count<\/span> <span style=\"color:#66d9ef\">int<\/span> <span style=\"color:#75715e\">\/\/ # live cells == size of map. Must be first (used by len() builtin)<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span> <span style=\"color:#a6e22e\">flags<\/span> <span style=\"color:#66d9ef\">uint8<\/span><\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">B<\/span> <span style=\"color:#66d9ef\">uint8<\/span> <span style=\"color:#75715e\">\/\/ log_2 of # of buckets (can hold up to loadFactor * 2^B items)<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span> <span style=\"color:#a6e22e\">noverflow<\/span> <span style=\"color:#66d9ef\">uint16<\/span> <span style=\"color:#75715e\">\/\/ approximate number of overflow buckets; see incrnoverflow for details<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span> <span style=\"color:#a6e22e\">hash0<\/span> <span style=\"color:#66d9ef\">uint32<\/span> <span style=\"color:#75715e\">\/\/ hash seed<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span><\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">buckets<\/span> <span style=\"color:#a6e22e\">unsafe<\/span>.<span style=\"color:#a6e22e\">Pointer<\/span> <span style=\"color:#75715e\">\/\/ array of 2^B Buckets. may be nil if count==0.<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span> <span style=\"color:#a6e22e\">oldbuckets<\/span> <span style=\"color:#a6e22e\">unsafe<\/span>.<span style=\"color:#a6e22e\">Pointer<\/span> <span style=\"color:#75715e\">\/\/ previous bucket array of half the size, non-nil only when growing<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span> <span style=\"color:#a6e22e\">nevacuate<\/span> <span style=\"color:#66d9ef\">uintptr<\/span> <span style=\"color:#75715e\">\/\/ progress counter for evacuation (buckets less than this have been evacuated)<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span><\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">extra<\/span> <span style=\"color:#f92672\">*<\/span><span style=\"color:#a6e22e\">mapextra<\/span> <span style=\"color:#75715e\">\/\/ optional fields<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span>}<\/span><\/span><\/code><\/pre><\/div><ul><li>count \u8868\u793amap\u4e2d\u5143\u7d20\u4e2a\u6570<\/li><li>flags \u662f\u4e00\u4e2a\u72b6\u6001\u6807\u8bc6\uff0c\u67094\u4e2a\u503c\uff0c\u5206\u522b\u662f<\/li><\/ul><pre tabindex=\"0\"><code>iterator = 1 \/\/ there may be an iterator using bucketsoldIterator = 2 \/\/ there may be an iterator using oldbucketshashWriting = 4 \/\/ a goroutine is writing to the mapsameSizeGrow = 8 \/\/ the current map growth is to a new map of the same size<\/code><\/pre><ul><li>B \u8868\u793a\u6876\u4e2a\u6570\u7684\u5bf9\u6570<\/li><li>noverflow \u662f\u6ea2\u51fa\u6876\u4e2a\u6570\u7684\u8fd1\u4f3c\u503c<\/li><li>buckets \u6307\u5411 bmap \u6570\u7ec4<\/li><li>oldbuckets \u548c\u6269\u5bb9\u6709\u5173\uff0c\u6307\u5411\u6269\u5bb9\u65f6\u7684\u65e7\u6876<\/li><\/ul><h2 id=\"bmap\">bmap<\/h2><p><img src=\"https:\/\/sunpe.github.io\/images\/golang_map\/2.png\" alt=\"\"><\/p><p>hmap \u4e2d\u7684 buckets \u548c oldbuckets \u6307\u5411\u7684\u662f bmap \u6570\u7ec4\uff0c\u4e00\u4e2a bmap \u53ef\u4ee5\u653e 8 \u4e2a\u5143\u7d20\uff0cbmap <a href=\"https:\/\/github.com\/golang\/go\/blob\/master\/src\/runtime\/map.go#L150\">\u6e90\u7801<\/a>\uff0c\u7f16\u8bd1\u8fc7\u7a0b\u4f1a\u52a0\u6599\uff0c\u6700\u7ec8 bmap \u7ed3\u6784\u4f53\u4f1a\u662f\u8fd9\u6837\u7684\uff1a<\/p><div class=\"highlight\"><pre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"><code class=\"language-go\" data-lang=\"go\"><span style=\"display:flex;\"><span><span style=\"color:#66d9ef\">type<\/span> <span style=\"color:#a6e22e\">bmap<\/span> <span style=\"color:#66d9ef\">struct<\/span> {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">tophash<\/span> [<span style=\"color:#ae81ff\">8<\/span>]<span style=\"color:#66d9ef\">uint8<\/span><\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">keys<\/span> [<span style=\"color:#ae81ff\">8<\/span>]<span style=\"color:#a6e22e\">keytype<\/span><\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">values<\/span> [<span style=\"color:#ae81ff\">8<\/span>]<span style=\"color:#a6e22e\">valuetype<\/span><\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">pad<\/span> <span style=\"color:#66d9ef\">uintptr<\/span><\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">overflow<\/span> <span style=\"color:#66d9ef\">uintptr<\/span><\/span><\/span><span style=\"display:flex;\"><span>}<\/span><\/span><\/code><\/pre><\/div><p>tophash \u5b58\u50a8 hash \u503c\u7684\u9ad88\u4f4d\uff0c\u9700\u8981\u6ce8\u610f\u7684\u662f\uff0ctophash \u503c\u5c0f\u4e8e\u7b49\u4e8e 5 \u5b58\u50a8\u7684\u662f\u72b6\u6001\u3002<\/p><div class=\"highlight\"><pre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"><code class=\"language-go\" data-lang=\"go\"><span style=\"display:flex;\"><span><span style=\"color:#a6e22e\">emptyRest<\/span> = <span style=\"color:#ae81ff\">0<\/span> <span style=\"color:#75715e\">\/\/ this cell is empty, and there are no more non-empty cells at higher indexes or overflows.<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span><span style=\"color:#a6e22e\">emptyOne<\/span> = <span style=\"color:#ae81ff\">1<\/span> <span style=\"color:#75715e\">\/\/ this cell is empty<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span><span style=\"color:#a6e22e\">evacuatedX<\/span> = <span style=\"color:#ae81ff\">2<\/span> <span style=\"color:#75715e\">\/\/ key\/elem is valid. Entry has been evacuated to first half of larger table.<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span><span style=\"color:#a6e22e\">evacuatedY<\/span> = <span style=\"color:#ae81ff\">3<\/span> <span style=\"color:#75715e\">\/\/ same as above, but evacuated to second half of larger table.<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span><span style=\"color:#a6e22e\">evacuatedEmpty<\/span> = <span style=\"color:#ae81ff\">4<\/span> <span style=\"color:#75715e\">\/\/ cell is empty, bucket is evacuated.<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span><span style=\"color:#a6e22e\">minTopHash<\/span> = <span style=\"color:#ae81ff\">5<\/span> <span style=\"color:#75715e\">\/\/ minimum tophash for a normal filled cell.<\/span><\/span><\/span><\/code><\/pre><\/div><p>\u901a\u8fc7 key \u7684 hash \u503c\u548c B-1 \u505a\u4e0e\u8fd0\u7b97\uff0c\u5224\u65ad\u5143\u7d20\u843d\u5728\u54ea\u4e2a\u6876\u4e2d\uff0c\u5728\u901a\u8fc7 tophash \u786e\u5b9a\u5728\u6876\u7684\u4f4d\u7f6e\uff0c\u7136\u540e\u6839\u636e tophash \u5224\u65ad bucket \u7684\u8be5\u4f4d\u7f6e\u662f\u5426\u53ef\u7528\uff0c\u5982\u679c 8 \u4e2a\u4f4d\u7f6e\u90fd\u4e0d\u53ef\u7528\uff0c\u5219\u4f1a\u94fe\u51fa\u4e00\u4e2a\u6307\u9488\u6307\u5411\u4e00\u4e2a\u65b0\u7684 bmap \u4f5c\u4e3a\u6ea2\u51fa\u6876\u3002<\/p><p>\u5f53 map \u7684 key \u548c value \u90fd\u4e0d\u662f\u6307\u9488\uff0c\u5e76\u4e14 size \u90fd\u5c0f\u4e8e 128 \u5b57\u8282\u7684\u65f6\u5019\uff0c\u4f1a\u628a bmap \u6807\u8bb0\u4e3a\u4e0d\u542b\u6307\u9488\uff0c\u4ee5\u907f\u514d GC \u626b\u63cf\u6574\u4e2a hmap\u3002\u8fd9\u65f6\u5019 overflow \u6307\u9488\u4f1a\u88ab\u653e\u5230 mapextract \u4e2d\uff0c\u4ee5\u4fdd\u8bc1 bmap \u4e2d\u4e0d\u5305\u542b\u6307\u9488\u3002<\/p><h2 id=\"loadfactor\">loadfactor<\/h2><p>golang map \u7684 loadfactor \u4e3a 6.5\u3002<\/p><h2 id=\"make-map\">make map<\/h2><p>\u521b\u5efa map \u4f1a\u8c03\u7528 makemap \u51fd\u6570\uff0c\u51fd\u6570 <a href=\"https:\/\/github.com\/golang\/go\/blob\/master\/src\/runtime\/map.go#L304\">\u6e90\u7801<\/a>\u3002<\/p><p>\u521b\u5efa map \u7684\u6d41\u7a0b\u5982\u4e0b\uff1a<\/p><ul><li>\u8ba1\u7b97 B<\/li><\/ul><div class=\"highlight\"><pre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"><code class=\"language-go\" data-lang=\"go\"><span style=\"display:flex;\"><span><span style=\"color:#a6e22e\">B<\/span> <span style=\"color:#f92672\">:=<\/span> uint8(<span style=\"color:#ae81ff\">0<\/span>)<\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#66d9ef\">for<\/span> <span style=\"color:#a6e22e\">overLoadFactor<\/span>(<span style=\"color:#a6e22e\">hint<\/span>, <span style=\"color:#a6e22e\">B<\/span>) {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">B<\/span><span style=\"color:#f92672\">++<\/span><\/span><\/span><span style=\"display:flex;\"><span>}<\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#a6e22e\">h<\/span>.<span style=\"color:#a6e22e\">B<\/span> = <span style=\"color:#a6e22e\">B<\/span><\/span><\/span><\/code><\/pre><\/div><ul><li>\u5982\u679c B != 0, \u5219\u7533\u8bf7\u6876\u7a7a\u95f4<\/li><\/ul><div class=\"highlight\"><pre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"><code class=\"language-go\" data-lang=\"go\"><span style=\"display:flex;\"><span><span style=\"color:#66d9ef\">if<\/span> <span style=\"color:#a6e22e\">h<\/span>.<span style=\"color:#a6e22e\">B<\/span> <span style=\"color:#f92672\">!=<\/span> <span style=\"color:#ae81ff\">0<\/span> {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">var<\/span> <span style=\"color:#a6e22e\">nextOverflow<\/span> <span style=\"color:#f92672\">*<\/span><span style=\"color:#a6e22e\">bmap<\/span><\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">h<\/span>.<span style=\"color:#a6e22e\">buckets<\/span>, <span style=\"color:#a6e22e\">nextOverflow<\/span> = <span style=\"color:#a6e22e\">makeBucketArray<\/span>(<span style=\"color:#a6e22e\">t<\/span>, <span style=\"color:#a6e22e\">h<\/span>.<span style=\"color:#a6e22e\">B<\/span>, <span style=\"color:#66d9ef\">nil<\/span>)<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">if<\/span> <span style=\"color:#a6e22e\">nextOverflow<\/span> <span style=\"color:#f92672\">!=<\/span> <span style=\"color:#66d9ef\">nil<\/span> {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">h<\/span>.<span style=\"color:#a6e22e\">extra<\/span> = new(<span style=\"color:#a6e22e\">mapextra<\/span>)<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">h<\/span>.<span style=\"color:#a6e22e\">extra<\/span>.<span style=\"color:#a6e22e\">nextOverflow<\/span> = <span style=\"color:#a6e22e\">nextOverflow<\/span><\/span><\/span><span style=\"display:flex;\"><span> }<\/span><\/span><span style=\"display:flex;\"><span>}<\/span><\/span><\/code><\/pre><\/div><h2 id=\"mapaccess\">mapaccess<\/h2><p>\u7531\u4e8e\u8bfb\u53d6 map \u7684\u8fd4\u56de\u503c\u6709\u4e09\u79cd\uff0c\u6240\u4ee5\u51fd\u6570\u6709\u4e09\u4e2a\uff0c\u5206\u522b\u5bf9\u5e94\u7740\u8fd4\u56de\u5355\u4e2a\u503c\u3001\u8fd4\u56de\u503c\u548cbool\uff0c\u8fd4\u56dekey\u548cvalue\u3002 <a href=\"https:\/\/github.com\/golang\/go\/blob\/master\/src\/runtime\/map.go#L395\">mapaccess1<\/a>, <a href=\"https:\/\/github.com\/golang\/go\/blob\/master\/src\/runtime\/map.go#L456\">mapaccess2<\/a>, <a href=\"https:\/\/github.com\/golang\/go\/blob\/master\/src\/runtime\/map.go#L518\">mapaccessK<\/a>\u3002<\/p><p>\u8bfb\u53d6\u6d41\u7a0b\u5982\u4e0b\uff1a<\/p><ul><li>\u8ba1\u7b97 key \u7684 hash<\/li><li>\u7528 key \u7684 hash \u7684\u4f4e B \u4f4d\u5b9a\u4f4d\u6876<\/li><\/ul><div class=\"highlight\"><pre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"><code class=\"language-go\" data-lang=\"go\"><span style=\"display:flex;\"><span><span style=\"color:#a6e22e\">hash<\/span> <span style=\"color:#f92672\">:=<\/span> <span style=\"color:#a6e22e\">t<\/span>.<span style=\"color:#a6e22e\">hasher<\/span>(<span style=\"color:#a6e22e\">key<\/span>, uintptr(<span style=\"color:#a6e22e\">h<\/span>.<span style=\"color:#a6e22e\">hash0<\/span>))<\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#a6e22e\">m<\/span> <span style=\"color:#f92672\">:=<\/span> <span style=\"color:#a6e22e\">bucketMask<\/span>(<span style=\"color:#a6e22e\">h<\/span>.<span style=\"color:#a6e22e\">B<\/span>)<\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#a6e22e\">b<\/span> <span style=\"color:#f92672\">:=<\/span> (<span style=\"color:#f92672\">*<\/span><span style=\"color:#a6e22e\">bmap<\/span>)(<span style=\"color:#a6e22e\">add<\/span>(<span style=\"color:#a6e22e\">h<\/span>.<span style=\"color:#a6e22e\">buckets<\/span>, (<span style=\"color:#a6e22e\">hash<\/span><span style=\"color:#f92672\">&amp;<\/span><span style=\"color:#a6e22e\">m<\/span>)<span style=\"color:#f92672\">*<\/span>uintptr(<span style=\"color:#a6e22e\">t<\/span>.<span style=\"color:#a6e22e\">bucketsize<\/span>)))<\/span><\/span><\/code><\/pre><\/div><ul><li>\u5224\u65ad\u662f\u5426\u9700\u8981\u4ece\u65e7\u6876\u91cc\u627e<\/li><\/ul><div class=\"highlight\"><pre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"><code class=\"language-go\" data-lang=\"go\"><span style=\"display:flex;\"><span><span style=\"color:#66d9ef\">if<\/span> <span style=\"color:#a6e22e\">c<\/span> <span style=\"color:#f92672\">:=<\/span> <span style=\"color:#a6e22e\">h<\/span>.<span style=\"color:#a6e22e\">oldbuckets<\/span>; <span style=\"color:#a6e22e\">c<\/span> <span style=\"color:#f92672\">!=<\/span> <span style=\"color:#66d9ef\">nil<\/span> {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">if<\/span> !<span style=\"color:#a6e22e\">h<\/span>.<span style=\"color:#a6e22e\">sameSizeGrow<\/span>() {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">m<\/span> <span style=\"color:#f92672\">&gt;&gt;=<\/span> <span style=\"color:#ae81ff\">1<\/span><\/span><\/span><span style=\"display:flex;\"><span> }<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">oldb<\/span> <span style=\"color:#f92672\">:=<\/span> (<span style=\"color:#f92672\">*<\/span><span style=\"color:#a6e22e\">bmap<\/span>)(<span style=\"color:#a6e22e\">add<\/span>(<span style=\"color:#a6e22e\">c<\/span>, (<span style=\"color:#a6e22e\">hash<\/span><span style=\"color:#f92672\">&amp;<\/span><span style=\"color:#a6e22e\">m<\/span>)<span style=\"color:#f92672\">*<\/span>uintptr(<span style=\"color:#a6e22e\">t<\/span>.<span style=\"color:#a6e22e\">bucketsize<\/span>)))<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">if<\/span> !<span style=\"color:#a6e22e\">evacuated<\/span>(<span style=\"color:#a6e22e\">oldb<\/span>) { <span style=\"color:#75715e\">\/\/ \u5224\u65ad top hash \u662f\u4e0d\u662f evacuatedX \u6216 evacuatedY<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span> <span style=\"color:#a6e22e\">b<\/span> = <span style=\"color:#a6e22e\">oldb<\/span><\/span><\/span><span style=\"display:flex;\"><span> }<\/span><\/span><span style=\"display:flex;\"><span>}<\/span><\/span><\/code><\/pre><\/div><ul><li>\u53d6 top hash<\/li><\/ul><div class=\"highlight\"><pre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"><code class=\"language-go\" data-lang=\"go\"><span style=\"display:flex;\"><span><span style=\"color:#a6e22e\">top<\/span> <span style=\"color:#f92672\">:=<\/span> <span style=\"color:#a6e22e\">tophash<\/span>(<span style=\"color:#a6e22e\">hash<\/span>)<\/span><\/span><\/code><\/pre><\/div><ul><li>\u901a\u8fc7 top hash \u548c key \u5728\u6876\u5185\u67e5\u627e key<\/li><\/ul><div class=\"highlight\"><pre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"><code class=\"language-go\" data-lang=\"go\"><span style=\"display:flex;\"><span><span style=\"color:#66d9ef\">for<\/span> ; <span style=\"color:#a6e22e\">b<\/span> <span style=\"color:#f92672\">!=<\/span> <span style=\"color:#66d9ef\">nil<\/span>; <span style=\"color:#a6e22e\">b<\/span> = <span style=\"color:#a6e22e\">b<\/span>.<span style=\"color:#a6e22e\">overflow<\/span>(<span style=\"color:#a6e22e\">t<\/span>) {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">for<\/span> <span style=\"color:#a6e22e\">i<\/span> <span style=\"color:#f92672\">:=<\/span> uintptr(<span style=\"color:#ae81ff\">0<\/span>); <span style=\"color:#a6e22e\">i<\/span> &lt; <span style=\"color:#a6e22e\">bucketCnt<\/span>; <span style=\"color:#a6e22e\">i<\/span><span style=\"color:#f92672\">++<\/span> {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">if<\/span> <span style=\"color:#a6e22e\">b<\/span>.<span style=\"color:#a6e22e\">tophash<\/span>[<span style=\"color:#a6e22e\">i<\/span>] <span style=\"color:#f92672\">!=<\/span> <span style=\"color:#a6e22e\">top<\/span> { <\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">if<\/span> <span style=\"color:#a6e22e\">b<\/span>.<span style=\"color:#a6e22e\">tophash<\/span>[<span style=\"color:#a6e22e\">i<\/span>] <span style=\"color:#f92672\">==<\/span> <span style=\"color:#a6e22e\">emptyRest<\/span> {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">break<\/span> <span style=\"color:#a6e22e\">bucketloop<\/span><\/span><\/span><span style=\"display:flex;\"><span> }<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">continue<\/span><\/span><\/span><span style=\"display:flex;\"><span> }<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">k<\/span> <span style=\"color:#f92672\">:=<\/span> <span style=\"color:#a6e22e\">add<\/span>(<span style=\"color:#a6e22e\">unsafe<\/span>.<span style=\"color:#a6e22e\">Pointer<\/span>(<span style=\"color:#a6e22e\">b<\/span>), <span style=\"color:#a6e22e\">dataOffset<\/span><span style=\"color:#f92672\">+<\/span><span style=\"color:#a6e22e\">i<\/span><span style=\"color:#f92672\">*<\/span>uintptr(<span style=\"color:#a6e22e\">t<\/span>.<span style=\"color:#a6e22e\">keysize<\/span>))<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">if<\/span> <span style=\"color:#a6e22e\">t<\/span>.<span style=\"color:#a6e22e\">indirectkey<\/span>() {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">k<\/span> = <span style=\"color:#f92672\">*<\/span>((<span style=\"color:#f92672\">*<\/span><span style=\"color:#a6e22e\">unsafe<\/span>.<span style=\"color:#a6e22e\">Pointer<\/span>)(<span style=\"color:#a6e22e\">k<\/span>))<\/span><\/span><span style=\"display:flex;\"><span> }<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">if<\/span> <span style=\"color:#a6e22e\">t<\/span>.<span style=\"color:#a6e22e\">key<\/span>.<span style=\"color:#a6e22e\">equal<\/span>(<span style=\"color:#a6e22e\">key<\/span>, <span style=\"color:#a6e22e\">k<\/span>) {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">e<\/span> <span style=\"color:#f92672\">:=<\/span> <span style=\"color:#a6e22e\">add<\/span>(<span style=\"color:#a6e22e\">unsafe<\/span>.<span style=\"color:#a6e22e\">Pointer<\/span>(<span style=\"color:#a6e22e\">b<\/span>), <span style=\"color:#a6e22e\">dataOffset<\/span><span style=\"color:#f92672\">+<\/span><span style=\"color:#a6e22e\">bucketCnt<\/span><span style=\"color:#f92672\">*<\/span>uintptr(<span style=\"color:#a6e22e\">t<\/span>.<span style=\"color:#a6e22e\">keysize<\/span>)<span style=\"color:#f92672\">+<\/span><span style=\"color:#a6e22e\">i<\/span><span style=\"color:#f92672\">*<\/span>uintptr(<span style=\"color:#a6e22e\">t<\/span>.<span style=\"color:#a6e22e\">elemsize<\/span>))<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">if<\/span> <span style=\"color:#a6e22e\">t<\/span>.<span style=\"color:#a6e22e\">indirectelem<\/span>() {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">e<\/span> = <span style=\"color:#f92672\">*<\/span>((<span style=\"color:#f92672\">*<\/span><span style=\"color:#a6e22e\">unsafe<\/span>.<span style=\"color:#a6e22e\">Pointer<\/span>)(<span style=\"color:#a6e22e\">e<\/span>))<\/span><\/span><span style=\"display:flex;\"><span> }<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">return<\/span> <span style=\"color:#a6e22e\">e<\/span><\/span><\/span><span style=\"display:flex;\"><span> }<\/span><\/span><span style=\"display:flex;\"><span> }<\/span><\/span><span style=\"display:flex;\"><span>}<\/span><\/span><\/code><\/pre><\/div><p><img src=\"https:\/\/sunpe.github.io\/images\/golang_map\/3.png\" alt=\"\"><\/p><h2 id=\"mapassign\">mapassign<\/h2><p>\u5199\u5165\u6570\u636e\u4f1a\u8c03\u7528 mapassign \u51fd\u6570\uff0c\u5199\u6570\u636e\u548c\u8bfb\u6570\u636e\u7684\u6d41\u7a0b\u76f8\u4f3c\uff0c\u53ea\u4e0d\u8fc7\u591a\u4e86\u6269\u5bb9\u5224\u65ad\u3002<\/p><ul><li>\u9996\u5148\u5224\u65ad\u662f\u5426\u662f\u5e76\u53d1\u5199\u5165\uff0c \u5e76\u8bbe\u7f6e flags<\/li><\/ul><div class=\"highlight\"><pre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"><code class=\"language-go\" data-lang=\"go\"><span style=\"display:flex;\"><span><span style=\"color:#66d9ef\">if<\/span> <span style=\"color:#a6e22e\">h<\/span>.<span style=\"color:#a6e22e\">flags<\/span><span style=\"color:#f92672\">&amp;<\/span><span style=\"color:#a6e22e\">hashWriting<\/span> <span style=\"color:#f92672\">!=<\/span> <span style=\"color:#ae81ff\">0<\/span> {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">fatal<\/span>(<span style=\"color:#e6db74\">&#34;concurrent map writes&#34;<\/span>)<\/span><\/span><span style=\"display:flex;\"><span>}<\/span><\/span><span style=\"display:flex;\"><span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#a6e22e\">h<\/span>.<span style=\"color:#a6e22e\">flags<\/span> ^= <span style=\"color:#a6e22e\">hashWriting<\/span><\/span><\/span><\/code><\/pre><\/div><ul><li>\u5224\u65ad\u662f\u5426\u9700\u8981\u6269\u5bb9<\/li><\/ul><div class=\"highlight\"><pre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"><code class=\"language-go\" data-lang=\"go\"><span style=\"display:flex;\"><span><span style=\"color:#a6e22e\">bucket<\/span> <span style=\"color:#f92672\">:=<\/span> <span style=\"color:#a6e22e\">hash<\/span> <span style=\"color:#f92672\">&amp;<\/span> <span style=\"color:#a6e22e\">bucketMask<\/span>(<span style=\"color:#a6e22e\">h<\/span>.<span style=\"color:#a6e22e\">B<\/span>)<\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#66d9ef\">if<\/span> <span style=\"color:#a6e22e\">h<\/span>.<span style=\"color:#a6e22e\">growing<\/span>() {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">growWork<\/span>(<span style=\"color:#a6e22e\">t<\/span>, <span style=\"color:#a6e22e\">h<\/span>, <span style=\"color:#a6e22e\">bucket<\/span>)<\/span><\/span><span style=\"display:flex;\"><span>}<\/span><\/span><\/code><\/pre><\/div><ul><li>\u5b9a\u4f4d\u6876\u548c\u8ba1\u7b97hash top<\/li><\/ul><div class=\"highlight\"><pre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"><code class=\"language-go\" data-lang=\"go\"><span style=\"display:flex;\"><span><span style=\"color:#a6e22e\">b<\/span> <span style=\"color:#f92672\">:=<\/span> (<span style=\"color:#f92672\">*<\/span><span style=\"color:#a6e22e\">bmap<\/span>)(<span style=\"color:#a6e22e\">add<\/span>(<span style=\"color:#a6e22e\">h<\/span>.<span style=\"color:#a6e22e\">buckets<\/span>, <span style=\"color:#a6e22e\">bucket<\/span><span style=\"color:#f92672\">*<\/span>uintptr(<span style=\"color:#a6e22e\">t<\/span>.<span style=\"color:#a6e22e\">bucketsize<\/span>)))<\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#a6e22e\">top<\/span> <span style=\"color:#f92672\">:=<\/span> <span style=\"color:#a6e22e\">tophash<\/span>(<span style=\"color:#a6e22e\">hash<\/span>)<\/span><\/span><\/code><\/pre><\/div><ul><li>\u904d\u5386\u6876\u627e\u5230\u63d2\u5165\u7684\u4f4d\u7f6e<\/li><li>\u5982\u679ckey \u5b58\u5728\uff0c\u5219\u66f4\u65b0<\/li><li>\u4fee\u6539flags<\/li><\/ul><div class=\"highlight\"><pre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"><code class=\"language-go\" data-lang=\"go\"><span style=\"display:flex;\"><span><span style=\"color:#a6e22e\">h<\/span>.<span style=\"color:#a6e22e\">flags<\/span> <span style=\"color:#f92672\">&amp;^=<\/span> <span style=\"color:#a6e22e\">hashWriting<\/span><\/span><\/span><\/code><\/pre><\/div><h2 id=\"mapdelete\">mapdelete<\/h2><p>\u5220\u9664\u64cd\u4f5c\u8c03\u7528 <a href=\"https:\/\/github.com\/golang\/go\/blob\/master\/src\/runtime\/map.go#L695\">mapdelete<\/a> \u51fd\u6570\u3002<\/p><ul><li>\u5199\u4fdd\u62a4<\/li><\/ul><div class=\"highlight\"><pre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"><code class=\"language-go\" data-lang=\"go\"><span style=\"display:flex;\"><span><span style=\"color:#66d9ef\">if<\/span> <span style=\"color:#a6e22e\">h<\/span>.<span style=\"color:#a6e22e\">flags<\/span><span style=\"color:#f92672\">&amp;<\/span><span style=\"color:#a6e22e\">hashWriting<\/span> <span style=\"color:#f92672\">!=<\/span> <span style=\"color:#ae81ff\">0<\/span> {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">fatal<\/span>(<span style=\"color:#e6db74\">&#34;concurrent map writes&#34;<\/span>)<\/span><\/span><span style=\"display:flex;\"><span>}<\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#a6e22e\">h<\/span>.<span style=\"color:#a6e22e\">flags<\/span> ^= <span style=\"color:#a6e22e\">hashWriting<\/span><\/span><\/span><\/code><\/pre><\/div><ul><li>\u786e\u5b9a\u6876\u7684\u4f4d\u7f6e<\/li><\/ul><div class=\"highlight\"><pre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"><code class=\"language-go\" data-lang=\"go\"><span style=\"display:flex;\"><span><span style=\"color:#a6e22e\">hash<\/span> <span style=\"color:#f92672\">:=<\/span> <span style=\"color:#a6e22e\">t<\/span>.<span style=\"color:#a6e22e\">hasher<\/span>(<span style=\"color:#a6e22e\">key<\/span>, uintptr(<span style=\"color:#a6e22e\">h<\/span>.<span style=\"color:#a6e22e\">hash0<\/span>))<\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#a6e22e\">bucket<\/span> <span style=\"color:#f92672\">:=<\/span> <span style=\"color:#a6e22e\">hash<\/span> <span style=\"color:#f92672\">&amp;<\/span> <span style=\"color:#a6e22e\">bucketMask<\/span>(<span style=\"color:#a6e22e\">h<\/span>.<span style=\"color:#a6e22e\">B<\/span>)<\/span><\/span><\/code><\/pre><\/div><ul><li>\u5224\u65ad\u6269\u5bb9<\/li><li>\u904d\u5386\u6876\u5bfb\u627ekey\uff0c\u627e\u5230key\u5219\u5220\u9664\u5143\u7d20\u5e76\u66f4\u65b0 tophash<\/li><\/ul><div class=\"highlight\"><pre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"><code class=\"language-go\" data-lang=\"go\"><span style=\"display:flex;\"><span><span style=\"color:#66d9ef\">if<\/span> <span style=\"color:#a6e22e\">t<\/span>.<span style=\"color:#a6e22e\">indirectelem<\/span>() {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#f92672\">*<\/span>(<span style=\"color:#f92672\">*<\/span><span style=\"color:#a6e22e\">unsafe<\/span>.<span style=\"color:#a6e22e\">Pointer<\/span>)(<span style=\"color:#a6e22e\">e<\/span>) = <span style=\"color:#66d9ef\">nil<\/span><\/span><\/span><span style=\"display:flex;\"><span>} <span style=\"color:#66d9ef\">else<\/span> <span style=\"color:#66d9ef\">if<\/span> <span style=\"color:#a6e22e\">t<\/span>.<span style=\"color:#a6e22e\">elem<\/span>.<span style=\"color:#a6e22e\">ptrdata<\/span> <span style=\"color:#f92672\">!=<\/span> <span style=\"color:#ae81ff\">0<\/span> {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">memclrHasPointers<\/span>(<span style=\"color:#a6e22e\">e<\/span>, <span style=\"color:#a6e22e\">t<\/span>.<span style=\"color:#a6e22e\">elem<\/span>.<span style=\"color:#a6e22e\">size<\/span>)<\/span><\/span><span style=\"display:flex;\"><span>} <span style=\"color:#66d9ef\">else<\/span> {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">memclrNoHeapPointers<\/span>(<span style=\"color:#a6e22e\">e<\/span>, <span style=\"color:#a6e22e\">t<\/span>.<span style=\"color:#a6e22e\">elem<\/span>.<span style=\"color:#a6e22e\">size<\/span>)<\/span><\/span><span style=\"display:flex;\"><span>}<\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#a6e22e\">b<\/span>.<span style=\"color:#a6e22e\">tophash<\/span>[<span style=\"color:#a6e22e\">i<\/span>] = <span style=\"color:#a6e22e\">emptyOne<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#f92672\">...<\/span><\/span><\/span><\/code><\/pre><\/div><ul><li>\u89e3\u9664\u5199\u4fdd\u62a4<\/li><\/ul><div class=\"highlight\"><pre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"><code class=\"language-go\" data-lang=\"go\"><span style=\"display:flex;\"><span><span style=\"color:#a6e22e\">h<\/span>.<span style=\"color:#a6e22e\">flags<\/span> <span style=\"color:#f92672\">&amp;^=<\/span> <span style=\"color:#a6e22e\">hashWriting<\/span><\/span><\/span><\/code><\/pre><\/div><h2 id=\"\u6269\u5bb9\">\u6269\u5bb9<\/h2><p><a href=\"https:\/\/github.com\/golang\/go\/blob\/master\/src\/runtime\/map.go#L1041\">\u6269\u5bb9\u4ee3\u7801<\/a><\/p><ul><li>\u5982\u679c loadfactor \u8d85\u8fc76.5\uff0c\u89e6\u53d1\u7ffb\u500d\u6269\u5bb9<\/li><li>\u5982\u679c\u6ea2\u51fa\u6876\u8fc7\u591a\u5219\u89e6\u53d1\u7b49\u91cf\u6269\u5bb9<\/li><\/ul><div class=\"highlight\"><pre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"><code class=\"language-go\" data-lang=\"go\"><span style=\"display:flex;\"><span><span style=\"color:#66d9ef\">func<\/span> <span style=\"color:#a6e22e\">tooManyOverflowBuckets<\/span>(<span style=\"color:#a6e22e\">noverflow<\/span> <span style=\"color:#66d9ef\">uint16<\/span>, <span style=\"color:#a6e22e\">B<\/span> <span style=\"color:#66d9ef\">uint8<\/span>) <span style=\"color:#66d9ef\">bool<\/span> {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">if<\/span> <span style=\"color:#a6e22e\">B<\/span> &gt; <span style=\"color:#ae81ff\">15<\/span> {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">B<\/span> = <span style=\"color:#ae81ff\">15<\/span><\/span><\/span><span style=\"display:flex;\"><span> }<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">return<\/span> <span style=\"color:#a6e22e\">noverflow<\/span> <span style=\"color:#f92672\">&gt;=<\/span> uint16(<span style=\"color:#ae81ff\">1<\/span>)<span style=\"color:#f92672\">&lt;&lt;<\/span>(<span style=\"color:#a6e22e\">B<\/span><span style=\"color:#f92672\">&amp;<\/span><span style=\"color:#ae81ff\">15<\/span>)<\/span><\/span><span style=\"display:flex;\"><span>}<\/span><\/span><\/code><\/pre><\/div><ul><li>\u6269\u5bb9\u8fc7\u7a0b\u4e3a\u6e10\u8fdb\u5f0f\u6269\u5bb9<\/li><\/ul>"},{"title":"golang gzip \u4f7f\u7528\u8fc7\u7a0b\u4e2d\u95ee\u9898\u6392\u67e5","link":"https:\/\/sunpe.github.io\/posts\/2021-08-17-golang-gzip-troubleshooting\/","pubDate":"Tue, 17 Aug 2021 22:00:00 +0800","guid":"https:\/\/sunpe.github.io\/posts\/2021-08-17-golang-gzip-troubleshooting\/","description":"<p>\u5728\u4f7f\u7528 golang \u7684 gzip \u5305\u538b\u7f29\u6570\u636e\u65f6\u53d1\u73b0\u4e00\u4e2a\u5751\uff0c\u51fa\u95ee\u9898\u7684\u4ee3\u7801\u5982\u4e0b\uff1a<\/p><div class=\"highlight\"><pre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"><code class=\"language-go\" data-lang=\"go\"><span style=\"display:flex;\"><span><span style=\"color:#75715e\">\/\/ \u4ee3\u78011<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span><span style=\"color:#ae81ff\">1<\/span> <span style=\"color:#66d9ef\">func<\/span> <span style=\"color:#a6e22e\">main<\/span>() {<\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#ae81ff\">2<\/span> <span style=\"color:#a6e22e\">fmt<\/span>.<span style=\"color:#a6e22e\">Println<\/span>(<span style=\"color:#a6e22e\">compressV1<\/span>([]byte(<span style=\"color:#e6db74\">&#34;test&#34;<\/span>)))<\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#ae81ff\">3<\/span> }<\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#ae81ff\">4<\/span> <\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#ae81ff\">5<\/span> <span style=\"color:#66d9ef\">func<\/span> <span style=\"color:#a6e22e\">compressV1<\/span>(<span style=\"color:#a6e22e\">data<\/span> []<span style=\"color:#66d9ef\">byte<\/span>) []<span style=\"color:#66d9ef\">byte<\/span> {<\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#ae81ff\">6<\/span> <span style=\"color:#66d9ef\">var<\/span> <span style=\"color:#a6e22e\">b<\/span> <span style=\"color:#a6e22e\">bytes<\/span>.<span style=\"color:#a6e22e\">Buffer<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#ae81ff\">7<\/span> <span style=\"color:#a6e22e\">w<\/span> <span style=\"color:#f92672\">:=<\/span> <span style=\"color:#a6e22e\">gzip<\/span>.<span style=\"color:#a6e22e\">NewWriter<\/span>(<span style=\"color:#f92672\">&amp;<\/span><span style=\"color:#a6e22e\">b<\/span>)<\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#ae81ff\">8<\/span> <span style=\"color:#66d9ef\">defer<\/span> <span style=\"color:#66d9ef\">func<\/span>() { <span style=\"color:#a6e22e\">_<\/span> = <span style=\"color:#a6e22e\">w<\/span>.<span style=\"color:#a6e22e\">Close<\/span>() }()<\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#ae81ff\">9<\/span> <\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#ae81ff\">10<\/span> <span style=\"color:#a6e22e\">_<\/span>, <span style=\"color:#a6e22e\">err<\/span> <span style=\"color:#f92672\">:=<\/span> <span style=\"color:#a6e22e\">w<\/span>.<span style=\"color:#a6e22e\">Write<\/span>(<span style=\"color:#a6e22e\">data<\/span>)<\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#ae81ff\">11<\/span> <span style=\"color:#66d9ef\">if<\/span> <span style=\"color:#a6e22e\">err<\/span> <span style=\"color:#f92672\">!=<\/span> <span style=\"color:#66d9ef\">nil<\/span> {<\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#ae81ff\">12<\/span> panic(<span style=\"color:#a6e22e\">err<\/span>)<\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#ae81ff\">13<\/span> }<\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#ae81ff\">14<\/span> <span style=\"color:#a6e22e\">_<\/span> = <span style=\"color:#a6e22e\">w<\/span>.<span style=\"color:#a6e22e\">Flush<\/span>()<\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#ae81ff\">15<\/span> <span style=\"color:#66d9ef\">return<\/span> <span style=\"color:#a6e22e\">b<\/span>.<span style=\"color:#a6e22e\">Bytes<\/span>()<\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#ae81ff\">16<\/span> }<\/span><\/span><\/code><\/pre><\/div><p>\u8f93\u51fa\u7684\u7ed3\u679c:<\/p><pre tabindex=\"0\"><code>[31 139 8 0 0 0 0 0 0 255 42 73 45 46 1 0 0 0 255 255]<\/code><\/pre><p>gzip \u7684 close \u51fd\u6570, \u5982\u300c\u4ee3\u78012\u300d\u6240\u793a\uff0c\u4ee3\u7801\u4f1a\u5728 15 \u884c\u7684 <code>compressor.Close<\/code> \u4e2d\u5199\u5165 5 \u4f4d StoredHeader \u4fe1\u606f\uff0c\u5728 19 \u884c\u5199\u5165 4 \u4f4d crc \u4fe1\u606f\uff0c20 \u884c\u5199\u5165 4 \u4f4d\u6570\u636e\u957f\u5ea6\u4fe1\u606f\u3002<\/p><div class=\"highlight\"><pre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"><code class=\"language-go\" data-lang=\"go\"><span style=\"display:flex;\"><span><span style=\"color:#75715e\">\/\/ \u4ee3\u78012<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span><span style=\"color:#ae81ff\">1<\/span> <span style=\"color:#66d9ef\">func<\/span> (<span style=\"color:#a6e22e\">z<\/span> <span style=\"color:#f92672\">*<\/span><span style=\"color:#a6e22e\">Writer<\/span>) <span style=\"color:#a6e22e\">Close<\/span>() <span style=\"color:#66d9ef\">error<\/span> {<\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#ae81ff\">2<\/span> <span style=\"color:#66d9ef\">if<\/span> <span style=\"color:#a6e22e\">z<\/span>.<span style=\"color:#a6e22e\">err<\/span> <span style=\"color:#f92672\">!=<\/span> <span style=\"color:#66d9ef\">nil<\/span> {<\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#ae81ff\">3<\/span> <span style=\"color:#66d9ef\">return<\/span> <span style=\"color:#a6e22e\">z<\/span>.<span style=\"color:#a6e22e\">err<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#ae81ff\">4<\/span> }<\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#ae81ff\">5<\/span> <span style=\"color:#66d9ef\">if<\/span> <span style=\"color:#a6e22e\">z<\/span>.<span style=\"color:#a6e22e\">closed<\/span> {<\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#ae81ff\">6<\/span> <span style=\"color:#66d9ef\">return<\/span> <span style=\"color:#66d9ef\">nil<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#ae81ff\">7<\/span> }<\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#ae81ff\">8<\/span> <span style=\"color:#a6e22e\">z<\/span>.<span style=\"color:#a6e22e\">closed<\/span> = <span style=\"color:#66d9ef\">true<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#ae81ff\">9<\/span> <span style=\"color:#66d9ef\">if<\/span> !<span style=\"color:#a6e22e\">z<\/span>.<span style=\"color:#a6e22e\">wroteHeader<\/span> {<\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#ae81ff\">10<\/span> <span style=\"color:#a6e22e\">z<\/span>.<span style=\"color:#a6e22e\">Write<\/span>(<span style=\"color:#66d9ef\">nil<\/span>)<\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#ae81ff\">11<\/span> <span style=\"color:#66d9ef\">if<\/span> <span style=\"color:#a6e22e\">z<\/span>.<span style=\"color:#a6e22e\">err<\/span> <span style=\"color:#f92672\">!=<\/span> <span style=\"color:#66d9ef\">nil<\/span> {<\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#ae81ff\">12<\/span> <span style=\"color:#66d9ef\">return<\/span> <span style=\"color:#a6e22e\">z<\/span>.<span style=\"color:#a6e22e\">err<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#ae81ff\">13<\/span> }<\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#ae81ff\">14<\/span> }<\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#ae81ff\">15<\/span> <span style=\"color:#a6e22e\">z<\/span>.<span style=\"color:#a6e22e\">err<\/span> = <span style=\"color:#a6e22e\">z<\/span>.<span style=\"color:#a6e22e\">compressor<\/span>.<span style=\"color:#a6e22e\">Close<\/span>()<\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#ae81ff\">16<\/span> <span style=\"color:#66d9ef\">if<\/span> <span style=\"color:#a6e22e\">z<\/span>.<span style=\"color:#a6e22e\">err<\/span> <span style=\"color:#f92672\">!=<\/span> <span style=\"color:#66d9ef\">nil<\/span> {<\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#ae81ff\">17<\/span> <span style=\"color:#66d9ef\">return<\/span> <span style=\"color:#a6e22e\">z<\/span>.<span style=\"color:#a6e22e\">err<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#ae81ff\">18<\/span> }<\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#ae81ff\">19<\/span> <span style=\"color:#a6e22e\">le<\/span>.<span style=\"color:#a6e22e\">PutUint32<\/span>(<span style=\"color:#a6e22e\">z<\/span>.<span style=\"color:#a6e22e\">buf<\/span>[:<span style=\"color:#ae81ff\">4<\/span>], <span style=\"color:#a6e22e\">z<\/span>.<span style=\"color:#a6e22e\">digest<\/span>)<\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#ae81ff\">20<\/span> <span style=\"color:#a6e22e\">le<\/span>.<span style=\"color:#a6e22e\">PutUint32<\/span>(<span style=\"color:#a6e22e\">z<\/span>.<span style=\"color:#a6e22e\">buf<\/span>[<span style=\"color:#ae81ff\">4<\/span>:<span style=\"color:#ae81ff\">8<\/span>], <span style=\"color:#a6e22e\">z<\/span>.<span style=\"color:#a6e22e\">size<\/span>)<\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#ae81ff\">21<\/span> <span style=\"color:#a6e22e\">_<\/span>, <span style=\"color:#a6e22e\">z<\/span>.<span style=\"color:#a6e22e\">err<\/span> = <span style=\"color:#a6e22e\">z<\/span>.<span style=\"color:#a6e22e\">w<\/span>.<span style=\"color:#a6e22e\">Write<\/span>(<span style=\"color:#a6e22e\">z<\/span>.<span style=\"color:#a6e22e\">buf<\/span>[:<span style=\"color:#ae81ff\">8<\/span>])<\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#ae81ff\">22<\/span> <span style=\"color:#66d9ef\">return<\/span> <span style=\"color:#a6e22e\">z<\/span>.<span style=\"color:#a6e22e\">err<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#ae81ff\">23<\/span> }<\/span><\/span><\/code><\/pre><\/div><p>\u6211\u4eec\u5199 golang \u65f6\u901a\u5e38\u559c\u6b22\u5728 <code>defer<\/code> \u4e2d\u91ca\u653e\u8d44\u6e90\uff0c\u5c31\u50cf\u662f\u300c\u4ee3\u78011\u300d\u4e2d\u7684\u7b2c 8 \u884c\u90a3\u6837\uff0cdefer \u4f1a\u5728 return \u4e4b\u540e\u8fd0\u884c\uff0c\u6240\u4ee5\u5bfc\u81f4 gzip \u7684 13 \u4f4d footer \u6570\u636e\u6ca1\u6709\u5199\u5165\u3002\u7a0d\u5fae\u4fee\u6539\u4e00\u4e0b\u4ee3\u7801\uff0c\u5f97\u5230\u300c\u4ee3\u78013\u300d\uff0c\u5728 return \u524d close \u6389 gzip \u7684 writer\uff0c\u5c31\u53ef\u4ee5\u5f97\u5230\u6b63\u786e\u7684\u7ed3\u679c\u4e86\u3002<\/p><div class=\"highlight\"><pre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"><code class=\"language-go\" data-lang=\"go\"><span style=\"display:flex;\"><span><span style=\"color:#75715e\">\/\/ \u4ee3\u7801 3<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span><span style=\"color:#66d9ef\">func<\/span> <span style=\"color:#a6e22e\">main<\/span>() {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">fmt<\/span>.<span style=\"color:#a6e22e\">Println<\/span>(<span style=\"color:#a6e22e\">compressV2<\/span>([]byte(<span style=\"color:#e6db74\">&#34;test&#34;<\/span>)))<\/span><\/span><span style=\"display:flex;\"><span>}<\/span><\/span><span style=\"display:flex;\"><span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#66d9ef\">func<\/span> <span style=\"color:#a6e22e\">compressV2<\/span>(<span style=\"color:#a6e22e\">data<\/span> []<span style=\"color:#66d9ef\">byte<\/span>) []<span style=\"color:#66d9ef\">byte<\/span> {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">var<\/span> <span style=\"color:#a6e22e\">b<\/span> <span style=\"color:#a6e22e\">bytes<\/span>.<span style=\"color:#a6e22e\">Buffer<\/span><\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">w<\/span> <span style=\"color:#f92672\">:=<\/span> <span style=\"color:#a6e22e\">gzip<\/span>.<span style=\"color:#a6e22e\">NewWriter<\/span>(<span style=\"color:#f92672\">&amp;<\/span><span style=\"color:#a6e22e\">b<\/span>)<\/span><\/span><span style=\"display:flex;\"><span><\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">_<\/span>, <span style=\"color:#a6e22e\">err<\/span> <span style=\"color:#f92672\">:=<\/span> <span style=\"color:#a6e22e\">w<\/span>.<span style=\"color:#a6e22e\">Write<\/span>(<span style=\"color:#a6e22e\">data<\/span>)<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">if<\/span> <span style=\"color:#a6e22e\">err<\/span> <span style=\"color:#f92672\">!=<\/span> <span style=\"color:#66d9ef\">nil<\/span> {<\/span><\/span><span style=\"display:flex;\"><span> panic(<span style=\"color:#a6e22e\">err<\/span>)<\/span><\/span><span style=\"display:flex;\"><span> }<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">_<\/span> = <span style=\"color:#a6e22e\">w<\/span>.<span style=\"color:#a6e22e\">Flush<\/span>()<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">_<\/span> = <span style=\"color:#a6e22e\">w<\/span>.<span style=\"color:#a6e22e\">Close<\/span>()<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">return<\/span> <span style=\"color:#a6e22e\">b<\/span>.<span style=\"color:#a6e22e\">Bytes<\/span>()<\/span><\/span><span style=\"display:flex;\"><span>}<\/span><\/span><\/code><\/pre><\/div><p>\u300c\u4ee3\u78013\u300d\u8f93\u51fa\u5982\u4e0b:<\/p><pre tabindex=\"0\"><code>[31 139 8 0 0 0 0 0 0 255 42 73 45 46 1 0 0 0 255 255 1 0 0 255 255 12 126 127 216 4 0 0 0]<\/code><\/pre><p>\u5982\u679c\u76f4\u63a5\u8fd4\u56de Buffer \u4f1a\u600e\u4e48\u6837\u3002<\/p><div class=\"highlight\"><pre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"><code class=\"language-go\" data-lang=\"go\"><span style=\"display:flex;\"><span><span style=\"color:#75715e\">\/\/ \u4ee3\u78014<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span><span style=\"color:#66d9ef\">func<\/span> <span style=\"color:#a6e22e\">main<\/span>() {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">b<\/span> <span style=\"color:#f92672\">:=<\/span> <span style=\"color:#a6e22e\">compressV3<\/span>([]byte(<span style=\"color:#e6db74\">&#34;test&#34;<\/span>))<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">fmt<\/span>.<span style=\"color:#a6e22e\">Println<\/span>(<span style=\"color:#a6e22e\">b<\/span>.<span style=\"color:#a6e22e\">Bytes<\/span>())<\/span><\/span><span style=\"display:flex;\"><span>}<\/span><\/span><span style=\"display:flex;\"><span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#66d9ef\">func<\/span> <span style=\"color:#a6e22e\">compressV3<\/span>(<span style=\"color:#a6e22e\">data<\/span> []<span style=\"color:#66d9ef\">byte<\/span>) <span style=\"color:#a6e22e\">bytes<\/span>.<span style=\"color:#a6e22e\">Buffer<\/span> {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">var<\/span> <span style=\"color:#a6e22e\">b<\/span> <span style=\"color:#a6e22e\">bytes<\/span>.<span style=\"color:#a6e22e\">Buffer<\/span><\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">w<\/span> <span style=\"color:#f92672\">:=<\/span> <span style=\"color:#a6e22e\">gzip<\/span>.<span style=\"color:#a6e22e\">NewWriter<\/span>(<span style=\"color:#f92672\">&amp;<\/span><span style=\"color:#a6e22e\">b<\/span>)<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">defer<\/span> <span style=\"color:#66d9ef\">func<\/span>() { <span style=\"color:#a6e22e\">_<\/span> = <span style=\"color:#a6e22e\">w<\/span>.<span style=\"color:#a6e22e\">Close<\/span>() }()<\/span><\/span><span style=\"display:flex;\"><span><\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">_<\/span>, <span style=\"color:#a6e22e\">err<\/span> <span style=\"color:#f92672\">:=<\/span> <span style=\"color:#a6e22e\">w<\/span>.<span style=\"color:#a6e22e\">Write<\/span>(<span style=\"color:#a6e22e\">data<\/span>)<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">if<\/span> <span style=\"color:#a6e22e\">err<\/span> <span style=\"color:#f92672\">!=<\/span> <span style=\"color:#66d9ef\">nil<\/span> {<\/span><\/span><span style=\"display:flex;\"><span> panic(<span style=\"color:#a6e22e\">err<\/span>)<\/span><\/span><span style=\"display:flex;\"><span> }<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">_<\/span> = <span style=\"color:#a6e22e\">w<\/span>.<span style=\"color:#a6e22e\">Flush<\/span>()<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">return<\/span> <span style=\"color:#a6e22e\">b<\/span><\/span><\/span><span style=\"display:flex;\"><span>}<\/span><\/span><\/code><\/pre><\/div><p>\u4f9d\u7136\u5728 <code>defer<\/code> \u4e2d\u5173\u95ed gzip \u7684 writer\uff0c\u8fd4\u56de <code>bytes.Buffer<\/code>\u3002\u7531\u4e8e\u8fd4\u56de\u7684\u662f\u503c\uff0c\u6240\u4ee5\u8f93\u51fa\u4f9d\u7136\u662f\u9519\u8bef\u7684\u3002\u4ee3\u7801\u8f93\u51fa\u5982\u4e0b<\/p><pre tabindex=\"0\"><code>[31 139 8 0 0 0 0 0 0 255 42 73 45 46 1 0 0 0 255 255]<\/code><\/pre><p>\u7ee7\u7eed\u4fee\u6539\u4ee3\u7801\u3002<\/p><div class=\"highlight\"><pre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"><code class=\"language-go\" data-lang=\"go\"><span style=\"display:flex;\"><span><span style=\"color:#75715e\">\/\/ \u4ee3\u78015<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span><span style=\"color:#66d9ef\">func<\/span> <span style=\"color:#a6e22e\">main<\/span>() {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">fmt<\/span>.<span style=\"color:#a6e22e\">Println<\/span>(<span style=\"color:#a6e22e\">compressV4<\/span>([]byte(<span style=\"color:#e6db74\">&#34;test&#34;<\/span>)).<span style=\"color:#a6e22e\">Bytes<\/span>())<\/span><\/span><span style=\"display:flex;\"><span>}<\/span><\/span><span style=\"display:flex;\"><span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#66d9ef\">func<\/span> <span style=\"color:#a6e22e\">compressV4<\/span>(<span style=\"color:#a6e22e\">data<\/span> []<span style=\"color:#66d9ef\">byte<\/span>) <span style=\"color:#f92672\">*<\/span><span style=\"color:#a6e22e\">bytes<\/span>.<span style=\"color:#a6e22e\">Buffer<\/span> {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">var<\/span> <span style=\"color:#a6e22e\">b<\/span> <span style=\"color:#a6e22e\">bytes<\/span>.<span style=\"color:#a6e22e\">Buffer<\/span><\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">w<\/span> <span style=\"color:#f92672\">:=<\/span> <span style=\"color:#a6e22e\">gzip<\/span>.<span style=\"color:#a6e22e\">NewWriter<\/span>(<span style=\"color:#f92672\">&amp;<\/span><span style=\"color:#a6e22e\">b<\/span>)<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">defer<\/span> <span style=\"color:#66d9ef\">func<\/span>() { <span style=\"color:#a6e22e\">_<\/span> = <span style=\"color:#a6e22e\">w<\/span>.<span style=\"color:#a6e22e\">Close<\/span>() }()<\/span><\/span><span style=\"display:flex;\"><span><\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">_<\/span>, <span style=\"color:#a6e22e\">err<\/span> <span style=\"color:#f92672\">:=<\/span> <span style=\"color:#a6e22e\">w<\/span>.<span style=\"color:#a6e22e\">Write<\/span>(<span style=\"color:#a6e22e\">data<\/span>)<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">if<\/span> <span style=\"color:#a6e22e\">err<\/span> <span style=\"color:#f92672\">!=<\/span> <span style=\"color:#66d9ef\">nil<\/span> {<\/span><\/span><span style=\"display:flex;\"><span> panic(<span style=\"color:#a6e22e\">err<\/span>)<\/span><\/span><span style=\"display:flex;\"><span> }<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">_<\/span> = <span style=\"color:#a6e22e\">w<\/span>.<span style=\"color:#a6e22e\">Flush<\/span>()<\/span><\/span><span style=\"display:flex;\"><span><\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">return<\/span> <span style=\"color:#f92672\">&amp;<\/span><span style=\"color:#a6e22e\">b<\/span><\/span><\/span><span style=\"display:flex;\"><span>}<\/span><\/span><\/code><\/pre><\/div><p>\u6539\u6210\u8fd4\u56de <code>bytes.Buffer<\/code> \u7684\u6307\u9488\uff0c\u5c31\u53ef\u4ee5\u5f97\u5230\u6b63\u786e\u7684\u7ed3\u679c\u4e86\u3002\u4ee3\u7801\u8f93\u51fa\u5982\u4e0b\uff1a<\/p><pre tabindex=\"0\"><code>[31 139 8 0 0 0 0 0 0 255 42 73 45 46 1 0 0 0 255 255 1 0 0 255 255 12 126 127 216 4 0 0 0]<\/code><\/pre><p>golang \u7684 gzip \u6700\u5751\u7684\u662f\uff0c\u5bf9\u4e8e\u6ca1\u6709\u5199\u5165 footer \u7684\u538b\u7f29\u6570\u636e\u53ef\u4ee5\u6b63\u5e38\u7684\u505a\u89e3\u538b\uff01\uff01\uff01<\/p><h2 id=\"\u603b\u7ed3\">\u603b\u7ed3<\/h2><p>\u5982\u679c\u6d89\u53ca\u5230\u5173\u95ed\u4e4b\u540e\u4f9d\u7136\u9700\u8981\u5199\u5165\u6570\u636e\u7684\u8d44\u6e90\uff0c\u5c3d\u91cf\u4e0d\u8981\u5728 defer \u4e2d\u8fdb\u884c close\uff0c\u8981\u5728 return \u4e4b\u524d\u786e\u4fdd\u8d44\u6e90\u5df2\u5173\u95ed\u3002<\/p>"},{"title":"spark 3.1.2 context\u5f02\u5e38\u5173\u95ed\u95ee\u9898\u6392\u67e5","link":"https:\/\/sunpe.github.io\/posts\/2021-07-01-spark-context\/","pubDate":"Thu, 01 Jul 2021 22:00:00 +0800","guid":"https:\/\/sunpe.github.io\/posts\/2021-07-01-spark-context\/","description":"<p>\u524d\u6bb5\u65f6\u95f4\uff0c\u57fa\u4e8espark\u548cspring boot\u5f00\u53d1\u4e86\u4e00\u4e2aweb\u670d\u52a1\uff0c\u5c06 spark session \u6ce8\u518c\u4e3aspring\u7684bean\uff0c\u4ee3\u7801\u5982\u4e0b\u6240\u793a\u3002<\/p><div class=\"highlight\"><pre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"><code class=\"language-java\" data-lang=\"java\"><span style=\"display:flex;\"><span><span style=\"color:#a6e22e\">@Bean<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#a6e22e\">@ConditionalOnMissingBean<\/span>(SparkSession.<span style=\"color:#a6e22e\">class<\/span>)<\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#66d9ef\">public<\/span> SparkSession <span style=\"color:#a6e22e\">sparkSession<\/span>(SparkConf conf) {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">return<\/span> SparkSession.<span style=\"color:#a6e22e\">builder<\/span>()<\/span><\/span><span style=\"display:flex;\"><span> .<span style=\"color:#a6e22e\">enableHiveSupport<\/span>()<\/span><\/span><span style=\"display:flex;\"><span> .<span style=\"color:#a6e22e\">config<\/span>(conf)<\/span><\/span><span style=\"display:flex;\"><span> .<span style=\"color:#a6e22e\">getOrCreate<\/span>();<\/span><\/span><span style=\"display:flex;\"><span>}<\/span><\/span><\/code><\/pre><\/div><p>\u7136\u800c\u5347\u7ea7spark\u52303.1.2\u7248\u672c\u4e4b\u540e\uff0c\u670d\u52a1\u542f\u52a8\u4e4b\u540e\uff0cspark context\u5c31\u4f1a\u5173\u95ed\uff0c\u800c\u9000\u56de3.0.2\u7248\u672c\u540e\u5c31\u6ca1\u6709\u8fd9\u95ee\u9898\u3002\u57fa\u4e8e3.1.2\u7248\u672c spark \u7684\u542f\u52a8\u65e5\u5fd7\u5982\u4e0b\u6240\u793a\uff1a<\/p><pre tabindex=\"0\"><code> . ____ _ __ _ _ \/\\\\ \/ ___&#39;_ __ _ _(_)_ __ __ _ \\ \\ \\ \\( ( )\\___ | &#39;_ | &#39;_| | &#39;_ \\\/ _` | \\ \\ \\ \\ \\\\\/ ___)| |_)| | | | | || (_| | ) ) ) ) &#39; |____| .__|_| |_|_| |_\\__, | \/ \/ \/ \/ =========|_|==============|___\/=\/_\/_\/_\/ :: Spring Boot :: (v2.5.2)...21\/07\/01 15:05:10 INFO YarnClientSchedulerBackend: Application application_1619358582322_6529891 has started running.21\/07\/01 15:05:10 INFO Utils: Successfully started service &#39;org.apache.spark.network.netty.NettyBlockTransferService&#39; on port 40461....21\/07\/01 15:05:10 INFO SaslDataTransferClient: SASL encryption trust check: localHostTrusted = false, remoteHostTrusted = false21\/07\/01 15:05:10 INFO Utils: Using initial executors = 1, max of spark.dynamicAllocation.initialExecutors, spark.dynamicAllocation.minExecutors and spark.executor.instances21\/07\/01 15:05:10 INFO YarnSchedulerBackend$YarnSchedulerEndpoint: ApplicationMaster registered as NettyRpcEndpointRef(spark-client:\/\/YarnAM)21\/07\/01 15:05:11 INFO YarnClientSchedulerBackend: SchedulerBackend is ready for scheduling beginning after waiting maxRegisteredResourcesWaitingTime: 30000000000(ns)21\/07\/01 15:05:11 INFO WelcomePageHandlerMapping: Adding welcome page template: index21\/07\/01 15:05:12 INFO Http11NioProtocol: Starting ProtocolHandler [&#34;http-nio-9000&#34;]21\/07\/01 15:05:12 INFO TomcatWebServer: Tomcat started on port(s): 9000 (http) with context path &#39;&#39;21\/07\/01 15:05:12 INFO SpringApplication: Started application in 2939.592 seconds (JVM running for 2942.937)21\/07\/01 15:05:12 INFO AbstractConnector: Stopped Spark@23cd4246{HTTP\/1.1, (http\/1.1)}{0.0.0.0:4040}21\/07\/01 15:05:12 INFO SparkUI: Stopped Spark web UI at http:\/\/xxxxxxxxx:404021\/07\/01 15:05:12 INFO YarnClientSchedulerBackend: Interrupting monitor thread21\/07\/01 15:05:12 INFO YarnClientSchedulerBackend: Shutting down all executors21\/07\/01 15:05:12 INFO YarnSchedulerBackend$YarnDriverEndpoint: Asking each executor to shut down21\/07\/01 15:05:12 INFO YarnClientSchedulerBackend: YARN client scheduler backend Stopped21\/07\/01 15:05:12 INFO MapOutputTrackerMasterEndpoint: MapOutputTrackerMasterEndpoint stopped!21\/07\/01 15:05:13 INFO MemoryStore: MemoryStore cleared21\/07\/01 15:05:13 INFO BlockManager: BlockManager stopped21\/07\/01 15:05:13 INFO BlockManagerMaster: BlockManagerMaster stopped21\/07\/01 15:05:13 INFO OutputCommitCoordinator$OutputCommitCoordinatorEndpoint: OutputCommitCoordinator stopped!21\/07\/01 15:05:13 INFO SparkContext: Successfully stopped SparkContext<\/code><\/pre><p>\u67e5\u770b\u4e863.1.2\u7248\u672c\u7684\u63d0\u4ea4\u5386\u53f2\uff0c\u53d1\u73b0\u95ee\u9898\u662f\u7531\u4e8e\u8be5 pr <a href=\"https:\/\/github.com\/apache\/spark\/commit\/c625eb4f9f970108d93bf3342c7ccb7ec873dc27\">c625eb4<\/a>\u5bfc\u81f4\u7684\uff0c\u8be5pr\u662f\u89e3\u51b3<a href=\"https:\/\/issues.apache.org\/jira\/browse\/SPARK-34674\">SPARK-34674<\/a>\u95ee\u9898\u3002\u8be5pr\u5728 core\/src\/main\/scala\/org\/apache\/spark\/deploy\/SparkSubmit.scala \u4ee3\u7801\u7684 955 \u884c\u6dfb\u52a0\u4e86<code>SparkContext.getActive.foreach(_.stop())<\/code>\u4ee3\u7801\u3002\u4e3a\u4e86\u9a8c\u8bc1\u731c\u60f3\uff0c\u4fee\u6539\u6e90\u7801\uff0c\u5e76\u91cd\u65b0\u6253\u5305\u3002<\/p><div class=\"highlight\"><pre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"><code class=\"language-java\" data-lang=\"java\"><span style=\"display:flex;\"><span><span style=\"color:#66d9ef\">try<\/span> {<\/span><\/span><span style=\"display:flex;\"><span> logInfo(<span style=\"color:#e6db74\">&#34;## app start &#34;<\/span>)<\/span><\/span><span style=\"display:flex;\"><span> app.<span style=\"color:#a6e22e\">start<\/span>(childArgs.<span style=\"color:#a6e22e\">toArray<\/span>, sparkConf)<\/span><\/span><span style=\"display:flex;\"><span> logInfo(<span style=\"color:#e6db74\">&#34;## app start over &#34;<\/span>)<\/span><\/span><span style=\"display:flex;\"><span>} <span style=\"color:#66d9ef\">catch<\/span> {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">case<\/span> t: Throwable <span style=\"color:#f92672\">=&gt;<\/span><\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">throw<\/span> findCause(t)<\/span><\/span><span style=\"display:flex;\"><span>} <span style=\"color:#66d9ef\">finally<\/span> {<\/span><\/span><span style=\"display:flex;\"><span> logInfo(<span style=\"color:#e6db74\">&#34;## finally clean spark context &#34;<\/span>)<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">if<\/span> (<span style=\"color:#f92672\">!<\/span>isShell(args.<span style=\"color:#a6e22e\">primaryResource<\/span>) <span style=\"color:#f92672\">&amp;&amp;<\/span> <span style=\"color:#f92672\">!<\/span>isSqlShell(args.<span style=\"color:#a6e22e\">mainClass<\/span>) <span style=\"color:#f92672\">&amp;&amp;<\/span><\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#f92672\">!<\/span>isThriftServer(args.<span style=\"color:#a6e22e\">mainClass<\/span>)) {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">try<\/span> {<\/span><\/span><span style=\"display:flex;\"><span> SparkContext.<span style=\"color:#a6e22e\">getActive<\/span>.<span style=\"color:#a6e22e\">foreach<\/span>(_.<span style=\"color:#a6e22e\">stop<\/span>())<\/span><\/span><span style=\"display:flex;\"><span> } <span style=\"color:#66d9ef\">catch<\/span> {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">case<\/span> e: Throwable <span style=\"color:#f92672\">=&gt;<\/span> logError(s<span style=\"color:#e6db74\">&#34;Failed to close SparkContext: $e&#34;<\/span>)<\/span><\/span><span style=\"display:flex;\"><span> }<\/span><\/span><span style=\"display:flex;\"><span> }<\/span><\/span><span style=\"display:flex;\"><span>}<\/span><\/span><\/code><\/pre><\/div><p>app\u542f\u52a8\u65e5\u5fd7\u5982\u4e0b\u3002<\/p><pre tabindex=\"0\"><code>## app start . ____ _ __ _ _ \/\\\\ \/ ___&#39;_ __ _ _(_)_ __ __ _ \\ \\ \\ \\( ( )\\___ | &#39;_ | &#39;_| | &#39;_ \\\/ _` | \\ \\ \\ \\ \\\\\/ ___)| |_)| | | | | || (_| | ) ) ) ) &#39; |____| .__|_| |_|_| |_\\__, | \/ \/ \/ \/ =========|_|==============|___\/=\/_\/_\/_\/ :: Spring Boot :: (v2.5.2)...21\/07\/01 15:05:10 INFO YarnClientSchedulerBackend: Application application_1619358582322_6529891 has started running.21\/07\/01 15:05:10 INFO Utils: Successfully started service &#39;org.apache.spark.network.netty.NettyBlockTransferService&#39; on port 40461....21\/07\/01 15:05:10 INFO SaslDataTransferClient: SASL encryption trust check: localHostTrusted = false, remoteHostTrusted = false21\/07\/01 15:05:10 INFO Utils: Using initial executors = 1, max of spark.dynamicAllocation.initialExecutors, spark.dynamicAllocation.minExecutors and spark.executor.instances21\/07\/01 15:05:10 INFO YarnSchedulerBackend$YarnSchedulerEndpoint: ApplicationMaster registered as NettyRpcEndpointRef(spark-client:\/\/YarnAM)21\/07\/01 15:05:11 INFO YarnClientSchedulerBackend: SchedulerBackend is ready for scheduling beginning after waiting maxRegisteredResourcesWaitingTime: 30000000000(ns)21\/07\/01 15:05:11 INFO WelcomePageHandlerMapping: Adding welcome page template: index21\/07\/01 15:05:12 INFO Http11NioProtocol: Starting ProtocolHandler [&#34;http-nio-9000&#34;]21\/07\/01 15:05:12 INFO TomcatWebServer: Tomcat started on port(s): 9000 (http) with context path &#39;&#39;21\/07\/01 15:05:12 INFO SpringApplication: Started application in 2939.592 seconds (JVM running for 2942.937)## app start over## finally clean spark context21\/07\/01 15:05:12 INFO AbstractConnector: Stopped Spark@23cd4246{HTTP\/1.1, (http\/1.1)}{0.0.0.0:4040}21\/07\/01 15:05:12 INFO SparkUI: Stopped Spark web UI at http:\/\/xxxxxxxxx:404021\/07\/01 15:05:12 INFO YarnClientSchedulerBackend: Interrupting monitor thread21\/07\/01 15:05:12 INFO YarnClientSchedulerBackend: Shutting down all executors21\/07\/01 15:05:12 INFO YarnSchedulerBackend$YarnDriverEndpoint: Asking each executor to shut down21\/07\/01 15:05:12 INFO YarnClientSchedulerBackend: YARN client scheduler backend Stopped21\/07\/01 15:05:12 INFO MapOutputTrackerMasterEndpoint: MapOutputTrackerMasterEndpoint stopped!21\/07\/01 15:05:13 INFO MemoryStore: MemoryStore cleared21\/07\/01 15:05:13 INFO BlockManager: BlockManager stopped21\/07\/01 15:05:13 INFO BlockManagerMaster: BlockManagerMaster stopped21\/07\/01 15:05:13 INFO OutputCommitCoordinator$OutputCommitCoordinatorEndpoint: OutputCommitCoordinator stopped!21\/07\/01 15:05:13 INFO SparkContext: Successfully stopped SparkContext<\/code><\/pre><p>\u4fee\u6539\u8be5\u6bb5\u4ee3\u7801\uff0c\u518d\u91cd\u65b0\u6253\u5305\u6d4b\u8bd5\uff0c\u95ee\u9898\u89e3\u51b3\u3002\u542f\u52a8\u65e5\u5fd7\u5982\u4e0b\u6240\u793a\u3002<\/p><pre tabindex=\"0\"><code>## app start . ____ _ __ _ _ \/\\\\ \/ ___&#39;_ __ _ _(_)_ __ __ _ \\ \\ \\ \\( ( )\\___ | &#39;_ | &#39;_| | &#39;_ \\\/ _` | \\ \\ \\ \\ \\\\\/ ___)| |_)| | | | | || (_| | ) ) ) ) &#39; |____| .__|_| |_|_| |_\\__, | \/ \/ \/ \/ =========|_|==============|___\/=\/_\/_\/_\/ :: Spring Boot :: (v2.5.2) ....21\/07\/01 16:05:51 INFO YarnClientSchedulerBackend: Application application_1619358582322_6532933 has started running.21\/07\/01 16:05:51 INFO Utils: Successfully started service &#39;org.apache.spark.network.netty.NettyBlockTransferService&#39; on port 42549.21\/07\/01 16:05:51 INFO NettyBlockTransferService: Server created on xxxxxxxxx:4254921\/07\/01 16:05:51 INFO BlockManager: Using org.apache.spark.storage.RandomBlockReplicationPolicy for block replication policy21\/07\/01 16:05:51 INFO BlockManagerMaster: Registering BlockManager BlockManagerId(driver, xxxxxxx, 42549, None)21\/07\/01 16:05:51 INFO BlockManagerMasterEndpoint: Registering block manager xxxxxxxxx:42549 with 5.2 GiB RAM, BlockManagerId(driver, xxxxxxx, 42549, None)21\/07\/01 16:05:51 INFO BlockManagerMaster: Registered BlockManager BlockManagerId(driver, xxxxxxxx, 42549, None)21\/07\/01 16:05:51 INFO BlockManager: external shuffle service port = 733721\/07\/01 16:05:51 INFO BlockManager: Initialized BlockManager: BlockManagerId(driver, xxxxxxxx, 42549, None)21\/07\/01 16:05:51 INFO ServerInfo: Adding filter to \/metrics\/json: org.apache.hadoop.yarn.server.webproxy.amfilter.AmIpFilter21\/07\/01 16:05:51 INFO ContextHandler: Started o.s.j.s.ServletContextHandler@60510791{\/metrics\/json,null,AVAILABLE,@Spark}21\/07\/01 16:05:52 INFO YarnSchedulerBackend$YarnSchedulerEndpoint: ApplicationMaster registered as NettyRpcEndpointRef(spark-client:\/\/YarnAM)21\/07\/01 16:05:54 INFO Utils: Using initial executors = 1, max of spark.dynamicAllocation.initialExecutors, spark.dynamicAllocation.minExecutors and spark.executor.instances21\/07\/01 16:05:54 INFO YarnClientSchedulerBackend: SchedulerBackend is ready for scheduling beginning after waiting maxRegisteredResourcesWaitingTime: 30000000000(ns)21\/07\/01 16:05:55 INFO WelcomePageHandlerMapping: Adding welcome page template: index21\/07\/01 16:05:55 INFO Http11NioProtocol: Starting ProtocolHandler [&#34;http-nio-9000&#34;]21\/07\/01 16:05:55 INFO TomcatWebServer: Tomcat started on port(s): 9000 (http) with context path &#39;&#39;21\/07\/01 16:05:55 INFO SpringApplication: Started application in 848.362 seconds (JVM running for 851.343)## app start over## finally clean spark context<\/code><\/pre><p>\u540e\u7eed\u548c\u516c\u53f8\u5185 spark \u4e13\u5bb6\u6c9f\u901a\u8fc7\u8be5\u95ee\u9898\uff0c\u4e13\u5bb6\u7ed9\u51fa\u7684\u5efa\u8bae\u662f\u6dfb\u52a0\u4e00\u4e2a\u542f\u52a8\u53c2\u6570\u6765\u63a7\u5236 main \u51fd\u6570\u4e4b\u540e\u662f\u5426\u9700\u8981\u5173\u95ed context\u3002\u6700\u7ec8\u63d0\u4ea4\u4e86\u8be5 pr <a href=\"https:\/\/github.com\/apache\/spark\/pull\/33154\">33154<\/a> \u5230spark\u793e\u533a\u3002\u4e0d\u8fc7\u6211\u63d0\u4ea4\u7684 pr \u6ca1\u6709\u88ab\u91c7\u7eb3\uff0c\u8be5\u95ee\u9898\u793e\u533a\u7684\u6700\u7ec8\u4fee\u590d\u65b9\u6848\u662f <a href=\"https:\/\/github.com\/apache\/spark\/commit\/fd3e9ce0b9ee09c7dce9f2e029fe96eac51eab96\">fd3e9ce<\/a> \u3002<\/p>"},{"title":"TCP\u534f\u8bae\u8be6\u89e3","link":"https:\/\/sunpe.github.io\/posts\/2021-03-12-tcp\/","pubDate":"Fri, 12 Mar 2021 22:00:00 +0800","guid":"https:\/\/sunpe.github.io\/posts\/2021-03-12-tcp\/","description":"<h2 id=\"tcp\u534f\u8bae\">TCP\u534f\u8bae<\/h2><p>TCP \u534f\u8bae\u662f TCP\/IP \u4f53\u7cfb\u4e2d\u975e\u5e38\u590d\u6742\u7684\u4e00\u4e2a\u534f\u8bae\uff0c\u4e0b\u9762\u4ecb\u7ecd TCP \u7684\u4e3b\u8981\u7279\u70b9\uff1a<\/p><ol><li>TCP \u662f\u9762\u5411\u8fde\u63a5\u7684\u4f20\u8f93\u5c42\u534f\u8bae\uff0c\u5e94\u7528\u7a0b\u5e8f\u5728\u4f7f\u7528 TCP \u534f\u8bae\u4e4b\u524d\uff0c\u5fc5\u987b\u5148\u5efa\u7acb TCP \u8fde\u63a5\uff0c\u4f20\u8f93\u6570\u636e\u7ed3\u675f\u540e\u5fc5\u987b\u8981\u8981\u91ca\u653e TCP \u8fde\u63a5\u3002<\/li><li>\u6bcf\u4e00\u6761 TCP \u8fde\u63a5\u53ea\u80fd\u6709\u4e24\u4e2a\u7aef\u70b9\uff08endpoint\uff09\uff0cTCP \u8fde\u63a5\u53ea\u80fd\u662f\u70b9\u5bf9\u70b9\u7684\u3002<\/li><li>TCP \u63d0\u4f9b\u53ef\u9760\u4ea4\u4ed8\u7684\u670d\u52a1\uff0c\u901a\u8fc7 TCP \u8fde\u63a5\u53ef\u4ee5\u65e0\u5dee\u9519\u3001\u4e0d\u4e22\u5931\u3001\u4e0d\u91cd\u590d\u5e76\u4e14\u6309\u987a\u5e8f\u7684\u4f20\u8f93\u7684\u6570\u636e\u3002<\/li><li>TCP \u63d0\u4f9b\u5168\u53cc\u5de5\u901a\u4fe1\u3002TCP \u5141\u8bb8\u901a\u4fe1\u53cc\u65b9\u8fdb\u7a0b\u5728\u4efb\u4f55\u65f6\u5019\u90fd\u53ef\u4ee5\u53d1\u9001\u6570\u636e\uff0cTCP \u4e24\u7aef\u90fd\u8bbe\u6709\u53d1\u9001\u7f13\u5b58\u548c\u63a5\u6536\u7f13\u5b58\uff0c\u7528\u6765\u4e34\u65f6\u5b58\u653e\u53cc\u7aef\u901a\u4fe1\u7684\u6570\u636e\u3002\u53d1\u9001\u65f6\uff0c\u5e94\u7528\u7a0b\u5e8f\u628a\u6570\u636e\u53d1\u9001\u7ed9 TCP \u7f13\u5b58\u540e\uff0c\u5c31\u53ef\u4ee5\u505a\u81ea\u5df1\u7684\u4e8b\u4e86\uff0cTCP \u5728\u5408\u9002\u7684\u65f6\u5019\u628a\u6570\u636e\u53d1\u9001\u51fa\u53bb\u3002\u63a5\u6536\u65f6\uff0cTCP \u5c06\u6570\u636e\u653e\u5165\u7f13\u5b58\uff0c\u4e0a\u5c42\u5e94\u7528\u8fdb\u7a0b\u5728\u5408\u9002\u7684\u65f6\u5019\u8bfb\u53d6\u7f13\u5b58\u4e2d\u7684\u6570\u636e\u3002<\/li><li>\u9762\u5411\u5b57\u8282\u6d41\u3002TCP \u4e2d\u7684\u300c\u6d41\u300d\uff08stream\uff09\u6307\u7684\u662f\u6d41\u5165\u5230\u8fdb\u7a0b\u6216\u4ece\u8fdb\u7a0b\u6d41\u51fa\u7684\u5b57\u8282\u5e8f\u5217\uff0c\u300c\u9762\u5411\u5b57\u8282\u6d41\u300d\u7684\u542b\u4e49\u662f\uff0c\u867d\u7136\u5e94\u7528\u7a0b\u5e8f\u8fdb\u7a0b\u548c TCP \u4ea4\u4e92\u662f\u4e00\u6b21\u4e00\u4e2a\u5927\u5c0f\u4e0d\u7b49\u7684\u6570\u636e\u5757\uff0c\u4f46 TCP \u628a\u5e94\u7528\u7a0b\u5e8f\u4ea4\u4e0b\u6765\u7684\u6570\u636e\u770b\u6210\u4ec5\u4ec5\u662f\u4e00\u8fde\u4e32\u65e0\u7ed3\u6784\u7684\u5b57\u8282\u6d41\uff0cTCP \u5e76\u4e0d\u77e5\u9053\u8981\u4f20\u9012\u7684\u5b57\u8282\u6d41\u7684\u542b\u4e49\u3002TCP \u4e0d\u4fdd\u8bc1\u63a5\u6536\u65b9\u6536\u5230\u7684\u6570\u636e\u5757\u548c\u53d1\u9001\u65b9\u53d1\u9001\u7684\u6570\u636e\u5757\u5177\u6709\u5bf9\u5e94\u7684\u5927\u5c0f\u5173\u7cfb\uff0c\u4f46\u63a5\u6536\u65b9\u6536\u5230\u7684\u5b57\u8282\u6d41\u5fc5\u987b\u548c\u53d1\u9001\u65b9\u53d1\u51fa\u7684\u5b57\u8282\u6d41\u5b8c\u5168\u4e00\u6837\uff0c\u63a5\u6536\u65b9\u5fc5\u987b\u6709\u80fd\u529b\u8bc6\u522b\u6536\u5230\u7684\u5b57\u8282\u6d41\uff0c\u5e76\u8fd8\u539f\u6210\u6709\u610f\u4e49\u7684\u6570\u636e\u3002<\/li><\/ol><p><img src=\"https:\/\/sunpe.github.io\/images\/tcp\/1.png\" alt=\"\u56fe 1 TCP \u9762\u5411\u6d41\u7684\u6982\u5ff5\"><\/p><p>\u56fe 1 TCP \u9762\u5411\u6d41\u7684\u6982\u5ff5<\/p><p>TCP \u4e0d\u5173\u5fc3\u5e94\u7528\u7a0b\u5e8f\u4e00\u6b21\u628a\u591a\u957f\u7684\u6570\u636e\u53d1\u9001\u5230 TCP \u7684\u7f13\u5b58\u4e2d\uff0c\u800c\u662f\u6839\u636e\u5bf9\u65b9\u7ed9\u51fa\u7684\u7a97\u53e3\u503c\u548c\u5f53\u524d\u7f51\u7edc\u7528\u585e\u7a0b\u5e8f\u6765\u51b3\u5b9a\u4e00\u4e2a\u62a5\u6587\u6bb5\u5e94\u5305\u542b\u591a\u5c11\u4e2a\u5b57\u8282\u3002\u5982\u679c\u5e94\u7528\u7a0b\u5e8f\u4f20\u9001\u5230 TCP \u7f13\u5b58\u7684\u6570\u636e\u5757\u592a\u957f\uff0cTCP \u53ef\u4ee5\u628a\u5b83\u5212\u5206\u77ed\u4e00\u4e9b\u518d\u4f20\u9001\u3002\u5982\u679c\u5e94\u7528\u7a0b\u5e8f\u4e00\u6b21\u53d1\u6765\u5f88\u77ed\u7684\u6570\u636e\uff0cTCP \u53ef\u4ee5\u7b49\u5f85\u57fa\u7c7b\u6709\u8db3\u591f\u591a\u7684\u5b57\u8282\u518d\u6784\u6210\u62a5\u6587\u6bb5\u53d1\u9001\u3002<\/p><p>\u300c\u8fde\u63a5\u300d\u662f TCP \u6700\u57fa\u672c\u7684\u62bd\u8c61\uff0cTCP \u8fde\u63a5\u4e24\u4e2a\u7aef\u70b9\uff0c\u7aef\u70b9\u662f\u300c\u5957\u63a5\u5b57\u300d\uff08socket\uff09\u6216\u300c\u63d2\u53e3\u300d\u3002\u7aef\u53e3\u53f7\u62fc\u63a5 IP \u5730\u5740\u6784\u6210\u4e86\u5957\u63a5\u5b57\uff0c\u6240\u4ee5 socket = IP:port\u3002<\/p><h2 id=\"\u53ef\u9760\u4f20\u8f93\">\u53ef\u9760\u4f20\u8f93<\/h2><p>TCP \u53d1\u9001\u7684\u62a5\u6587\u6bb5\u662f\u4ea4\u7ed9 IP \u5c42\u4f20\u8f93\uff0c\u800c IP \u5c42\u53ea\u80fd\u63d0\u4f9b\u5c3d\u6700\u5927\u52aa\u529b\u670d\u52a1\uff0c\u4e5f\u5c31\u662f\u8bf4\uff0cTCP \u4e0b\u5c42\u7684\u7f51\u7edc\u63d0\u4f9b\u7684\u662f\u4e0d\u53ef\u9760\u7684\u4f20\u8f93\uff0c\u56e0\u6b64 TCP \u5fc5\u987b\u91c7\u53d6\u9002\u5f53\u7684\u63aa\u65bd\u6765\u4fdd\u8bc1\u4f20\u8f93\u7684\u53ef\u9760\u6027\u3002<\/p><h3 id=\"\u505c\u7b49\u534f\u8bae\">\u505c\u7b49\u534f\u8bae<\/h3><p>\u300c\u505c\u7b49\u300d\u5c31\u662f\u6bcf\u53d1\u5b8c\u4e00\u4e2a\u62a5\u6587\u5206\u7ec4\u5c31\u505c\u6b62\u53d1\u9001\uff0c\u7b49\u5f85\u5bf9\u65b9\u786e\u8ba4\u540e\u518d\u53d1\u9001\u4e0b\u4e00\u5206\u7ec4\u3002<\/p><p><img src=\"https:\/\/sunpe.github.io\/images\/tcp\/2.png\" alt=\"\u56fe 2 \u505c\u7b49\u534f\u8bae\"><\/p><p>\u56fe 2 \u505c\u7b49\u534f\u8bae<\/p><p>\u65e0\u5dee\u9519\u7684\u60c5\u51b5\u4e0b\uff0cA \u53d1\u9001\u5206\u7ec4 M1 \u540e\u5c31\u6682\u505c\u53d1\u9001\uff0c\u7b49\u5f85 B \u786e\u8ba4\u4e4b\u540e\u518d\u7ee7\u7eed\u53d1\u9001\u3002\u5982\u56fe 2 \u4e2d\uff08a\uff09\u6240\u793a\u3002<\/p><p>\u5728\u56fe 2\uff08b\uff09\u4e2d\u5c55\u793a\u4e86\u51fa\u73b0\u5dee\u9519\u7684\u60c5\u51b5\uff0cM1 \u5728\u4f20\u8f93\u9014\u4e2d\u4e22\u5931\u4e86\uff0cB \u6ca1\u6536\u5230\u62a5\u6587\uff0c\u6216\u8005B \u6536\u5230 M1 \u65f6\u76d1\u6d4b\u5230\u51fa\u73b0\u5dee\u9519\uff0c\u5c31\u4e22\u5f03 M1\uff0c\u5176\u4ed6\u4ec0\u4e48\u4e5f\u4e0d\u505a\uff08\u4e0d\u901a\u77e5 A \u51fa\u73b0\u5dee\u9519\uff09\uff0c\u800c A \u5728\u4e00\u6bb5\u65f6\u95f4\u4e4b\u5185\u6ca1\u6536\u5230\u786e\u8ba4\uff0c\u5c31\u8ba4\u4e3a\u521a\u624d\u53d1\u9001\u7684\u5206\u7ec4 M1 \u4e22\u5931\u4e86\uff0c\u6240\u4ee5\u91cd\u4f20 M1 \u5206\u7ec4\u3002\u4e3a\u4e86\u5b9e\u73b0\u8d85\u65f6\u91cd\u4f20\uff0c\u53d1\u9001\u65b9\u6bcf\u53d1\u9001\u4e00\u4e2a\u5206\u7ec4\u90fd\u9700\u8981\u8bbe\u7f6e\u4e00\u4e2a\u300c\u8d85\u65f6\u8ba1\u65f6\u5668\u300d\uff0c\u5982\u679c\u5728\u8d85\u65f6\u4e4b\u524d\u6536\u5230\u5bf9\u65b9\u7684\u786e\u8ba4\uff0c\u5219\u64a4\u9500\u8ba1\u65f6\u5668\uff0c\u8ba1\u65f6\u5668\u7684\u8d85\u65f6\u65f6\u95f4\u5e94\u8be5\u6bd4\u5206\u7ec4\u4f20\u8f93\u7684\u5e73\u5747\u5f80\u8fd4\u65f6\u95f4\u66f4\u957f\u4e00\u4e9b\u3002\u800c\u4e14\u4e3a\u4e86\u6e05\u695a\u662f\u54ea\u4e2a\u5206\u7ec4\u51fa\u73b0\u4e86\u5dee\u9519\uff0c\u9700\u8981\u5bf9\u5206\u7ec4\u8fdb\u884c\u7f16\u53f7\u3002<\/p><p>\u5982\u679c B \u63a5\u6536\u5230\u4e86\u5206\u7ec4 M1\uff0c\u4f46\u662f\u53d1\u51fa\u7684\u5bf9 M1 \u786e\u8ba4\u62a5\u6587\u6bb5\u4e22\u5931\uff0c\u90a3\u4e48\u5728 A \u8d85\u65f6\u8ba1\u65f6\u5668\u5230\u671f\u540e\u6ca1\u6709\u6536\u5230\u786e\u8ba4\u62a5\u6587\u6bb5\uff0c\u5219\u9700\u8981\u91cd\u4f20 M1\uff0c\u90a3\u4e48 B \u5728\u62bd\u5230\u91cd\u590d\u7684 M1 \u5206\u7ec4\u540e\u5e94\u5f53\u4e22\u5f03\u5206\u7ec4\uff0c\u5e76\u91cd\u65b0\u53d1\u9001\u786e\u8ba4\u62a5\u6587\u6bb5\uff0c\u5982\u56fe 3\uff08a\uff09\u6240\u793a\u3002<\/p><p>\u5982\u679c M1 \u7684\u786e\u8ba4\u62a5\u6587\u6bb5\u51fa\u73b0\u4e86\u5ef6\u8fdf\uff0cA \u6700\u7ec8\u6536\u5230\u4e86\u8fdf\u5230\u7684\u786e\u8ba4\u62a5\u6587\u6bb5\uff0c\u90a3\u4e48 A \u5e94\u5f53\u4e22\u5f03\u6d88\u606f\uff0c\u7531\u4e8e M1 \u5206\u7ec4\u8d85\u65f6\u91cd\u4f20\uff0cB \u4ecd\u7136\u4f1a\u6536\u5230\u91cd\u590d\u7684 M1\uff0cB \u7167\u6837\u9700\u8981\u4e22\u5f03\u91cd\u590d\u7684\u5206\u7ec4\u3002<\/p><p><img src=\"https:\/\/sunpe.github.io\/images\/tcp\/3.png\" alt=\"\u56fe 3 \u786e\u8ba4\u62a5\u6587\u6bb5\u4e22\u5931\u548c\u786e\u8ba4\u62a5\u6587\u6bb5\u8fdf\u5230\"><\/p><p>\u56fe 3 \u786e\u8ba4\u62a5\u6587\u6bb5\u4e22\u5931\u548c\u786e\u8ba4\u62a5\u6587\u6bb5\u8fdf\u5230<\/p><p>\u901a\u8fc7\u786e\u8ba4\u548c\u91cd\u4f20\u673a\u5236\u5c31\u53ef\u4ee5\u5728\u4e0d\u53ef\u9760\u7684\u7f51\u7edc\u4e0a\u5b9e\u73b0\u53ef\u9760\u7684\u901a\u4fe1\uff0c\u63a5\u6536\u65b9\u4e0d\u9700\u8981\u8bf7\u6c42\u53d1\u9001\u65b9\u91cd\u4f20\u67d0\u4e2a\u5206\u7ec4\uff0c\u91cd\u4f20\u662f\u81ea\u52a8\u8fdb\u884c\uff0c\u8fd9\u79cd\u4f20\u8f93\u534f\u8bae\u5e38\u79f0\u4e3a\u300c\u81ea\u52a8\u91cd\u4f20\u8bf7\u6c42\u300d\uff08ARQ automatic repeat re-quest\uff09\u3002<\/p><p>ARQ \u534f\u8bae\u53ef\u4ee5\u5f88\u65b9\u4fbf\u7684\u5b9e\u73b0\u53ef\u9760\u7684\u4f20\u8f93\uff0c\u4f46\u662f\u4fe1\u9053\u7684\u5229\u7528\u7387\u592a\u4f4e\uff0c\u5047\u5b9a A \u53d1\u9001\u5206\u7ec4\u9700\u8981\u7684\u65f6\u95f4\u662f $T_D$\uff0cB \u6536\u5230\u5206\u7ec4\u540e\u7acb\u523b\u53d1\u9001\u786e\u8ba4\u62a5\u6587\u6bb5\uff0c\u53d1\u9001\u786e\u8ba4\u5206\u7ec4\u7684\u65f6\u95f4\u662f $T_A$\uff0cA \u5904\u7406\u786e\u8ba4\u5206\u7ec4\u7684\u65f6\u95f4\u5ffd\u7565\u4e0d\u8bb0\uff0c\u5206\u7ec4\u5f80\u8fd4\u65f6\u95f4\u662f RTT\uff0c\u90a3\u4e48 A \u5728\u7ecf\u8fc7\u65f6\u95f4( $T_D + RTT + T_A$)\u540e\u624d\u53ef\u4ee5\u53d1\u9001\u4e0b\u4e00\u4e2a\u5206\u7ec4\u3002\u56e0\u4e3a\u53ea\u6709 $T_D$ \u662f\u7528\u6765\u4f20\u8f93\u6709\u7528\u7684\u6570\u636e\uff0c\u6240\u4ee5\u4fe1\u9053\u5229\u7528\u7387 <code>U = $T_D$ \/ ($T_D$ + RTT + $T_A$)<\/code>\u3002<\/p><p><img src=\"https:\/\/sunpe.github.io\/images\/tcp\/4.png\" alt=\"\u56fe 4 \u505c\u7b49\u534f\u8bae\u4fe1\u9053\u5229\u7528\u7387\u592a\u4f4e\"><\/p><p>\u56fe 4 \u505c\u7b49\u534f\u8bae\u4fe1\u9053\u5229\u7528\u7387\u592a\u4f4e<\/p><p>\u6bd4\u5982\u5f80\u8fd4\u65f6\u5ef6 RTT = 20ms\uff0c\u53d1\u9001\u901f\u7387 1Mb\/s\uff0c\u53d1\u9001 1200 bit \u5206\u7ec4\uff0c\u5ffd\u7565\u5904\u7406\u65f6\u95f4\u548c $T_A$\uff08 $T_A$ \u901a\u5e38\u8fdc\u5c0f\u4e8e $T_D$\uff09\uff0c\u4fe1\u9053\u5229\u7528\u7387 U = 5.66%\uff0c\u5982\u679c\u53d1\u9001\u901f\u7387\u63d0\u5347\u5230 10 Mb\/s\uff0c\u90a3\u4e48 U = 5.96 * $10^{-4}$\u3002\u4fe1\u9053\u5728\u7edd\u5927\u591a\u6570\u65f6\u95f4\u5185\u662f\u7a7a\u95f2\u7684\uff0c\u800c\u5728\u51fa\u73b0\u5dee\u9519\u65f6\uff0c\u4fe1\u9053\u5229\u7528\u7387\u4f1a\u66f4\u4f4e\u3002<\/p><h3 id=\"\u8fde\u7eed\u505c\u7b49\u534f\u8bae\">\u8fde\u7eed\u505c\u7b49\u534f\u8bae<\/h3><p>\u4e3a\u4e86\u63d0\u9ad8\u4fe1\u9053\u5229\u7528\u7387\uff0c\u53d1\u9001\u65b9\u53ef\u4ee5\u4e0d\u4f7f\u7528\u4f4e\u6548\u7387\u7684\u505c\u7b49\u534f\u8bae\uff0c\u800c\u91c7\u7528\u6d41\u6c34\u7ebf\u4f20\u8f93\uff0c\u53d1\u9001\u65b9\u53ef\u4ee5\u8fde\u7eed\u53d1\u9001\u591a\u4e2a\u5206\u7ec4\uff0c\u4e0d\u5fc5\u6bcf\u6b21\u53d1\u9001\u5b8c\u5c31\u505c\u4e0b\u6765\u7b49\u5f85\u5bf9\u65b9\u786e\u8ba4\uff0c\u8fd9\u6837\u53ef\u4ee5\u4f7f\u4fe1\u9053\u4e0a\u4e00\u76f4\u6709\u6570\u636e\u4f20\u8f93\uff0c\u4ece\u800c\u83b7\u5f97\u66f4\u9ad8\u7684\u4fe1\u9053\u5229\u7528\u7387\u3002\u8fd9\u79cd\u65b9\u5f0f\u533a\u522b\u4e8e ARQ \u534f\u8bae\uff0c\u53eb\u505a\u300c\u8fde\u7eed ARQ \u534f\u8bae\u300d<\/p><p><img src=\"https:\/\/sunpe.github.io\/images\/tcp\/5.png\" alt=\"\u56fe 5 \u901a\u8fc7\u6d41\u6c34\u7ebf\u4f20\u8f93\u63d0\u9ad8\u4fe1\u9053\u5229\u7528\u7387\"><\/p><p>\u56fe 5 \u901a\u8fc7\u6d41\u6c34\u7ebf\u4f20\u8f93\u63d0\u9ad8\u4fe1\u9053\u5229\u7528\u7387<\/p><p>\u5982\u56fe 6 \u6240\u793a\uff0c\u5206\u7ec4\u6309\u5e8f\u53f7\u4ece\u5927\u5230\u5c0f\u6392\u5217\uff0c\u53d1\u9001\u65b9\u7ef4\u62a4\u4e86\u4e00\u4e2a\u53d1\u9001\u7a97\u53e3\uff0c\u4f4d\u4e8e\u7a97\u53e3\u5185\u7684 5 \u4e2a\u5206\u7ec4\u53ef\u4ee5\u8fde\u7eed\u53d1\u9001\u51fa\u53bb\uff0c\u800c\u4e0d\u9700\u8981\u7b49\u5f85\u5bf9\u65b9\u786e\u8ba4\uff0c\u53d1\u9001\u65b9\u6bcf\u6536\u5230\u4e00\u4e2a\u786e\u8ba4\uff0c\u5c31\u628a\u53d1\u9001\u7a97\u53e3\u5411\u524d\u79fb\u52a8\u4e00\u4e2a\u5206\u7ec4\u7684\u4f4d\u7f6e\u3002\u63a5\u6536\u65b9\u901a\u5e38\u662f\u91c7\u7528\u7d2f\u79ef\u786e\u8ba4\u7684\u65b9\u5f0f\uff0c\u63a5\u6536\u65b9\u4e0d\u5fc5\u5bf9\u6536\u5230\u7684\u5206\u7ec4\u9010\u4e2a\u53d1\u9001\u786e\u8ba4\uff0c\u800c\u662f\u5728\u6536\u5230\u6309\u5e8f\u5230\u8fbe\u7684\u591a\u4e2a\u5206\u7ec4\u4e4b\u540e\uff0c\u5bf9\u6700\u540e\u4e00\u4e2a\u5206\u7ec4\u53d1\u9001\u786e\u8ba4\uff0c\u8868\u793a\u5230\u8fd9\u4e2a\u5206\u7ec4\u4e3a\u6b62\u7684\u6240\u6709\u5206\u7ec4\u90fd\u5df2\u7ecf\u6b63\u786e\u6536\u5230\u4e86\u3002<\/p><p><img src=\"https:\/\/sunpe.github.io\/images\/tcp\/6.png\" alt=\"\u56fe 6 \u8fde\u7eed ARQ \u534f\u8bae\u539f\u7406\"><\/p><p>\u56fe 6 \u8fde\u7eed ARQ \u534f\u8bae\u539f\u7406<\/p><p>\u7d2f\u79ef\u786e\u8ba4\u7684\u65b9\u5f0f\u5f88\u5bb9\u6613\u5b9e\u73b0\uff0c\u5373\u4f7f\u786e\u8ba4\u62a5\u6587\u6bb5\u4e22\u5931\u4e5f\u4e0d\u5fc5\u91cd\u4f20\uff0c\u4f46\u4e0d\u80fd\u5411\u53d1\u9001\u65b9\u53cd\u9988\u63a5\u6536\u65b9\u5df2\u6b63\u786e\u63a5\u6536\u7684\u6240\u6709\u5206\u7ec4\u7684\u4fe1\u606f\u3002\u4f8b\u5982\u53d1\u9001\u65b9\u53d1\u9001\u4e86\u524d 5 \u4e2a\u5206\u7ec4\uff0c\u7b2c 3 \u4e2a\u5206\u7ec4\u4e22\u5931\uff0c\u8fd9\u662f\u63a5\u6536\u65b9\u53ea\u80fd\u5bf9\u524d 2 \u4e2a\u5206\u7ec4\u786e\u8ba4\uff0c\u53d1\u9001\u65b9\u53ea\u597d\u91cd\u4f20\u540e\u9762 3 \u4e2a\u5206\u7ec4\uff0c\u8fd9\u79cd\u56de\u9000\u5230 N \u7684\u91cd\u4f20\u65b9\u5f0f\u53eb Go-back-N\uff0c\u8868\u793a\u9700\u8981\u9000\u56de\u91cd\u4f20\u5df2\u53d1\u9001\u7684 N \u4e2a\u5206\u7ec4\u3002\u5728\u7ebf\u8def\u8d28\u91cf\u4e0d\u597d\u7684\u65f6\u5019\uff0c\u8fde\u7eed ARQ \u534f\u8bae\u4f1a\u5e26\u6765\u4e00\u5b9a\u7684\u8d1f\u9762\u5f71\u54cd\u3002<\/p><h3 id=\"tcp-\u6ed1\u52a8\u7a97\u53e3\">TCP \u6ed1\u52a8\u7a97\u53e3<\/h3><p>TCP \u7684\u6ed1\u52a8\u7a97\u53e3\u662f\u4ee5\u5b57\u8282\u4e3a\u5355\u4f4d\u7684\uff0c\u53d1\u9001\u300c\u7a97\u53e3\u300d\u8868\u793a\u5728\u6ca1\u6709\u6536\u5230\u786e\u8ba4\u62a5\u6587\u4e4b\u524d\uff0c\u53ef\u4ee5\u8fde\u7eed\u7684\u628a\u7a97\u53e3\u5185\u7684\u6570\u636e\u90fd\u53d1\u9001\u51fa\u53bb\uff0c\u5df2\u7ecf\u53d1\u9001\u7684\u6570\u636e\uff0c\u5728\u672a\u786e\u8ba4\u524d\u9700\u8981\u6682\u65f6\u4fdd\u7559\uff0c\u4ee5\u4fbf\u8d85\u65f6\u91cd\u4f20\u3002\u53d1\u9001\u7a97\u53e3\u7684\u4f4d\u7f6e\u7531\u7a97\u53e3\u524d\u6cbf\u548c\u540e\u6cbf\u5171\u540c\u51b3\u5b9a\uff0c\u540e\u6cbf\u4e4b\u540e\u7684\u6570\u636e\u8868\u793a\u5df2\u7ecf\u53d1\u9001\u5e76\u4e14\u786e\u8ba4\u8fc7\uff0c\u7ee7\u7eed\u6536\u5230\u786e\u8ba4\u540e\u540e\u6cbf\u53ef\u4ee5\u5f80\u524d\u79fb\u52a8\uff0c\u4e0d\u4f1a\u5411\u540e\u79fb\u52a8\u3002\u524d\u6cbf\u901a\u5e38\u4e0d\u65ad\u5411\u524d\u79fb\u52a8\uff0c\u5982\u679c\u4e00\u76f4\u6ca1\u6536\u5230\u786e\u8ba4\u62a5\u6587\uff0c\u90a3\u4e48\u524d\u6cbf\u548c\u540e\u6cbf\u4e0d\u4f1a\u79fb\u52a8\u3002\u5982\u679c\u63a5\u6536\u65b9\u901a\u77e5\u7f29\u5c0f\u7a97\u53e3\uff0c\u524d\u6cbf\u4e5f\u4e0d\u4f1a\u5411\u524d\u79fb\u52a8\uff0c\u524d\u6cbf\u5728\u8fd9\u79cd\u60c5\u51b5\u4e0b\u7406\u8bba\u4e0a\u53ef\u4ee5\u5411\u540e\u79fb\u52a8\uff0c\u4f46\u662f\u5f3a\u70c8\u4e0d\u8d5e\u6210\u524d\u6cbf\u5411\u540e\u79fb\u52a8\uff0c\u56e0\u4e3a\u524d\u6cbf\u540e\u7684\u90e8\u5206\u6570\u636e\u5df2\u7ecf\u53d1\u9001\u51fa\u53bb\u4e86\u3002<\/p><p>\u56fe 7 \u6240\u793a\uff0cA \u662f\u53d1\u9001\u65b9\uff0cB \u662f\u63a5\u6536\u65b9\uff0c\u7a97\u53e3\u662f 20 \u5b57\u8282\uff0cA \u6536\u5230 B \u7684\u786e\u8ba4\u62a5\u6587\uff0c\u786e\u8ba4\u53f7\u662f 30\uff0c\u8868\u660e 30 \u53f7\u4e3a\u6b62\u7684\u6570\u636e\u5df2\u7ecf\u63a5\u6536\uff0c\u671f\u671b\u6536\u5230\u7684\u4e0b\u4e00\u4e2a\u5e8f\u53f7\u662f 31\u3002A \u7ee7\u7eed\u53d1\u9001\u4e86 31 \uff5e 41 \u7684\u6570\u636e\uff0c\u4f46\u8fd8\u672a\u6536\u5230\u786e\u8ba4\u62a5\u6587\u6bb5\uff0c\u53d1\u9001\u7a97\u53e3\u4f4d\u7f6e\u5e76\u672a\u6539\u53d8\uff0c\u5982\u56fe 8 \u6240\u793a\uff0c31 \uff5e 40 \u8fd9 10 \u4e2a\u5b57\u8282\u662f\u5df2\u53d1\u9001\u4f46\u672a\u6536\u5230\u786e\u8ba4\u7684\u6d88\u606f\uff0c42 \uff5e 50 \u662f\u5141\u8bb8\u53d1\u9001\u4f46\u5c1a\u672a\u53d1\u9001\u7684\u6d88\u606f\u3002<\/p><p><img src=\"https:\/\/sunpe.github.io\/images\/tcp\/7.png\" alt=\"\u56fe 7 \"><\/p><p>\u56fe 7<\/p><p>\u63cf\u8ff0\u7a97\u53e3\u72b6\u6001\u9700\u8981 3 \u4e2a\u6307\u9488\uff0c$P_1$\uff0c$P_2$ \u548c $P_3$ \uff08\u56fe 8\uff09\u3002\u5176\u4e2d\u5c0f\u4e8e $P_1$ \u7684\u662f\u5df2\u53d1\u9001\u5e76\u786e\u8ba4\u7684\u90e8\u5206\uff0c\u5927\u4e8e $P_3$ \u7684\u662f\u4e0d\u5141\u8bb8\u53d1\u9001\u7684\u90e8\u5206\uff0c$P_3$ ~ $P_1$ \u662f\u7a97\u53e3\u5927\u5c0f\uff0c$P_2$ ~ $P_1$ \u662f\u5df2\u53d1\u9001\u4f46\u5c1a\u672a\u786e\u8ba4\u7684\u5b57\u8282\u6570\uff0c$P_3$ ~ $P_2$ \u662f\u5141\u8bb8\u53d1\u9001\u4f46\u5c1a\u672a\u53d1\u9001\u7684\u5b57\u8282\u6570\uff08\u4e5f\u53eb\u53ef\u7528\u7a97\u53e3\u6216\u6709\u6548\u7a97\u53e3\uff09\u3002<\/p><p><img src=\"https:\/\/sunpe.github.io\/images\/tcp\/8.png\" alt=\"\u56fe 8\"><\/p><p>\u56fe 8<\/p><p>\u56fe 8 \u4e2d B \u7684\u63a5\u6536\u7a97\u53e3\u5927\u5c0f\u662f 20\uff0c\u7a97\u53e3\u4e4b\u5916\uff0c\u5230 30 \u4e3a\u6b62\u7684\u6570\u636e\u662f\u5df2\u53d1\u9001\u786e\u8ba4\u62a5\u6587\u6bb5\u7684\u6570\u636e\uff0c\u5e76\u4e14\u5df2\u4ea4\u4ed8\u5e94\u7528\u5c42\uff0c\u56e0\u6b64 B \u53ef\u4ee5\u4e0d\u518d\u4fdd\u7559\u8fd9\u90e8\u5206\u6570\u636e\u300231 \uff5e 50 \u5728\u63a5\u6536\u7a97\u53e3\u5185\uff0c\u5047\u5982 31 \u7531\u4e8e\u5f02\u5e38\u539f\u56e0\u4e22\u5931\uff0cB \u6536\u5230\u4e86 32 \u548c 33\uff0c\u8fd9\u4e9b\u6570\u636e\u672a\u6309\u5e8f\u5230\u8fbe\uff0c\u9700\u8981\u6ce8\u610f\u7684\u662f B \u53ea\u80fd\u5bf9\u6309\u5e8f\u5230\u8fbe\u7684\u6570\u636e\u4e2d\u6700\u9ad8\u5e8f\u53f7\u7ed9\u51fa\u786e\u8ba4\u62a5\u6587\u6bb5\uff0c\u56e0\u6b64 B \u7ed9\u51fa\u7684\u786e\u8ba4\u62a5\u6587\u6bb5\u4f9d\u7136\u662f 31\uff0c\u800c\u4e0d\u662f 32 \u6216 33\u3002<\/p><p>B \u6536\u5230\u5e8f\u53f7\u4e3a 31 \u7684\u6570\u636e\uff0c\u5e76\u628a31 \uff5e 33 \u7684\u6570\u636e\u4ea4\u4ed8\u5e94\u7528\u5c42\uff0c\u7136\u540e B \u5220\u9664\u8fd9\u4e9b\u6570\u636e\uff0c\u5e76\u628a\u63a5\u6536\u7a97\u53e3\u5411\u524d\u79fb\u52a8 3 \u4e2a\u5e8f\u53f7\uff0c\u540c\u65f6\u7ed9 A \u53d1\u9001\u786e\u8ba4\u62a5\u6587\u6bb5\uff0c\u7a97\u53e3\u5927\u5c0f\u4e3a 20\uff0c\u786e\u8ba4\u53f7\u662f 34\u3002\u9664\u6b64\u4e4b\u5916\uff0cB \u8fd8\u6536\u5230\u5e8f\u53f7\u4e3a 37\u300138 \u548c 40 \u7684\u6570\u636e\uff0c\u8fd9\u4e9b\u6570\u636e\u6ca1\u6709\u6309\u5e8f\u5230\u8fbe\uff0c\u53ea\u80fd\u6682\u5b58\u5728\u63a5\u6536\u7a97\u53e3\u4e2d\u3002A \u6536\u5230 B \u7684\u786e\u8ba4\u62a5\u6587\u6bb5\u540e\u5c06\u53d1\u9001\u7a97\u53e3\u5411\u524d\u6ed1\u52a8 3 \u4e2a\u5e8f\u53f7\uff0c\u4f46 P2 \u4e0d\u53d8\uff0c\u73b0\u5728 A \u7684\u53ef\u7528\u7a97\u53e3\u589e\u5927\u4e86\uff0c\u53ef\u4ee5\u53d1\u9001 42 \uff5e 53\u3002\u5982\u56fe 9 \u6240\u793a\u3002<\/p><p><img src=\"https:\/\/sunpe.github.io\/images\/tcp\/9.png\" alt=\"\u56fe 9 \"><\/p><p>\u56fe 9<\/p><p>A \u53d1\u9001\u5b8c 42 \uff5e 53 \u540e\uff0c\u6307\u9488 P_2 \u5411\u524d\u79fb\u52a8\u548c P_3 \u91cd\u5408\uff0c\u53d1\u9001\u7a97\u53e3\u5185\u7684\u5e8f\u53f7\u90fd\u5df2\u7528\u5b8c\uff0c\u4f46\u6ca1\u6709\u518d\u6536\u5230\u786e\u8ba4\uff0c\u7531\u4e8e A \u7684\u53d1\u9001\u7a97\u53e3\u5df2\u6ee1\uff0c\u53ef\u7528\u7a97\u53e3\u5df2\u51cf\u5c0f\u5230 0\uff0c\u9700\u8981\u505c\u6b62\u53d1\u9001\u3002\u5982\u56fe 10\u3002\u73b0\u5b9e\u4e2d\u5b58\u5728\u8fd9\u79cd\u60c5\u51b5\uff0cA \u53d1\u9001\u7684\u6570\u636e\u8fd8\u6ca1\u5230\u8fbe B\uff0c\u6216\u8005 B \u7684\u786e\u8ba4\u6570\u636e\u6ede\u7559\u5728\u7f51\u7edc\u4e2d\u3002\u4e3a\u4fdd\u8bc1\u53ef\u9760\u4f20\u8f93\uff0cA \u53ea\u80fd\u8ba4\u4e3a B \u8fd8\u6ca1\u6536\u5230\u6570\u636e\uff0cA \u5728\u8d85\u65f6\u63a7\u5236\u5668\u8d85\u65f6\u540e\u9700\u8981\u91cd\u4f20\u8fd9\u90e8\u5206\u6570\u636e\uff0c\u91cd\u65b0\u8bbe\u7f6e\u8d85\u65f6\u8ba1\u65f6\u5668\uff0c\u76f4\u5230 B \u786e\u8ba4\u4e3a\u6b62\u3002<\/p><p><img src=\"https:\/\/sunpe.github.io\/images\/tcp\/10.png\" alt=\"\u56fe 10 \u53d1\u9001\u7a97\u53e3\u5df2\u6ee1\"><\/p><p>\u56fe 10 \u53d1\u9001\u7a97\u53e3\u5df2\u6ee1<\/p><p>\u4e0a\u6587\u63d0\u5230\u8fc7\u5e94\u7528\u5c42\u5c06\u6570\u636e\u53d1\u9001\u5230 TCP \u7f13\u5b58\uff0c\u548c\u5e94\u7528\u5c42\u4ece TCP \u7f13\u5b58\u8bfb\u53d6\u6570\u636e\uff0c\u7a97\u53e3\u548c TCP \u7f13\u5b58\u7684\u5173\u7cfb\u5982\u56fe 11\u3002<\/p><p>\u53d1\u9001\u7a97\u53e3\u901a\u5e38\u53ea\u662f\u53d1\u9001\u7f13\u5b58\u7684\u4e00\u90e8\u5206\uff0c\u53d1\u9001\u7f13\u5b58\u5b58\u50a8\u53d1\u9001\u65b9\u51c6\u5907\u53d1\u9001\u7684\u6570\u636e\u548c\u5df2\u53d1\u9001\u4f46\u5c1a\u672a\u6536\u5230\u786e\u8ba4\u7684\u6570\u636e\uff0c\u5df2\u53d1\u9001\u7684\u6570\u636e\u5e94\u5f53\u4ece\u53d1\u9001\u7f13\u5b58\u4e2d\u5220\u9664\uff0c\u53d1\u9001\u7f13\u5b58\u548c\u53d1\u9001\u7a97\u53e3\u7684\u540e\u6cbf\u91cd\u53e0\uff0c\u5e94\u7528\u5c42\u6700\u540e\u5199\u5165\u53d1\u9001\u7f13\u5b58\u7684\u5b57\u8282\u51cf\u53bb\u6700\u540e\u88ab\u786e\u8ba4\u7684\u5b57\u8282\uff0c\u5c31\u662f\u4fdd\u7559\u5728\u53d1\u9001\u7f13\u5b58\u4e2d\u7684\u5b57\u8282\u6570\u3002<\/p><p>\u540c\u6837\u63a5\u6536\u7a97\u53e3\u4e5f\u662f\u63a5\u6536\u7f13\u5b58\u7684\u4e00\u90e8\u5206\uff0c\u63a5\u6536\u7f13\u5b58\u50a8\u5b58\u6309\u5e8f\u5230\u8fbe\u4f46\u5c1a\u672a\u88ab\u5e94\u7528\u5c42\u8bfb\u53d6\u7684\u6570\u636e\u548c\u672a\u6309\u5e8f\u5230\u8fbe\u7684\u6570\u636e\u3002\u5982\u679c\u6536\u5230\u7684\u5206\u7ec4\u6709\u5dee\u9519\uff0c\u5219\u9700\u8981\u4e22\u5f03\u6389\uff0c\u5982\u679c\u5e94\u7528\u5c42\u6765\u4e0d\u53ca\u8bfb\u53d6\u6536\u5230\u7684\u6570\u636e\uff0c\u63a5\u6536\u7f13\u5b58\u6700\u7ec8\u4f1a\u88ab\u5360\u6ee1\uff0c\u4f7f\u7684\u63a5\u6536\u7a97\u53e3\u51cf\u5230 0\u3002\u5982\u679c\u5e94\u7528\u5c42\u53ef\u4ee5\u5f88\u5feb\u7684\u8bfb\u53d6\u63a5\u6536\u5230\u7684\u6570\u636e\uff0c\u63a5\u6536\u7a97\u53e3\u5c31\u53ef\u4ee5\u589e\u5927\uff0c\u4f46\u6700\u5927\u4e0d\u80fd\u8d85\u8fc7\u63a5\u6536\u7f13\u5b58\u7684\u5927\u5c0f\u3002<\/p><p><img src=\"https:\/\/sunpe.github.io\/images\/tcp\/11.png\" alt=\"\u56fe 11 TCP \u7f13\u5b58\u548c\u7a97\u53e3\u7684\u5173\u7cfb\"><\/p><p>\u56fe 11 TCP \u7f13\u5b58\u548c\u7a97\u53e3\u7684\u5173\u7cfb<\/p><p>\u867d\u7136\u53d1\u9001\u7a97\u53e3\u5927\u5c0f\u662f\u6839\u636e\u63a5\u6536\u7a97\u53e3\u5927\u5c0f\u8bbe\u7f6e\u7684\uff0c\u4f46\u5728\u540c\u4e00\u65f6\u523b\uff0c\u53d1\u9001\u7a97\u53e3\u548c\u63a5\u6536\u7a97\u53e3\u5927\u5c0f\u4e0d\u4e00\u5b9a\u4e00\u6837\uff0c\u56e0\u4e3a\u901a\u8fc7\u7f51\u7edc\u4f20\u9012\u7a97\u53e3\u503c\u9700\u8981\u4e00\u5b9a\u7684\u65f6\u95f4\uff0c\u800c\u4e14\u53d1\u9001\u65b9\u4f1a\u6839\u636e\u7f51\u7edc\u7528\u585e\u60c5\u51b5\u4f1a\u9002\u5f53\u8c03\u6574\u53d1\u9001\u7a97\u53e3\u3002<\/p><h3 id=\"\u8d85\u65f6\u91cd\u4f20\u65f6\u95f4\u7684\u9009\u62e9\">\u8d85\u65f6\u91cd\u4f20\u65f6\u95f4\u7684\u9009\u62e9<\/h3><p>TCP \u53d1\u9001\u65b9\u5728\u89c4\u5b9a\u7684\u65f6\u95f4\u5185\u6ca1\u6536\u5230\u786e\u8ba4\u5c31\u9700\u8981\u91cd\u4f20\u5df2\u53d1\u9001\u7684\u62a5\u6587\u6bb5\uff0c\u5176\u4e2d\u91cd\u4f20\u65f6\u95f4\u9009\u62e9\u662f TCP \u6700\u590d\u6742\u7684\u95ee\u9898\u4e4b\u4e00\u3002\u7531\u4e8e\u7f51\u7edc\u73af\u5883\u7684\u4e0d\u786e\u5b9a\u6027\uff0c\u5982\u679c\u91cd\u4f20\u65f6\u95f4\u8bbe\u7f6e\u5f97\u592a\u77ed\uff0c\u5c31\u4f1a\u5f15\u8d77\u5f88\u591a\u62a5\u6587\u6bb5\u7684\u4e0d\u5fc5\u8981\u7684\u91cd\u4f20\uff0c\u662f\u7f51\u7edc\u8d1f\u8377\u589e\u5927\uff1b\u5982\u679c\u91cd\u4f20\u65f6\u95f4\u8bbe\u7f6e\u5927\u592a\u957f\uff0c\u4f1a\u4f7f\u7f51\u7edc\u7a7a\u95f2\u65f6\u95f4\u589e\u5927\uff0c\u964d\u4f4e\u4e86\u4f20\u8f93\u6548\u7387\u3002<\/p><p>TCP \u91c7\u7528\u81ea\u9002\u5e94\u7b97\u6cd5\uff0c\u8bb0\u5f55\u62a5\u6587\u53d1\u9001\u7684\u65f6\u95f4\u548c\u63a5\u6536\u5230\u786e\u8ba4\u7684\u65f6\u95f4\uff0c\u8fd9\u4e24\u4e2a\u65f6\u95f4\u4e4b\u5dee\u5c31\u662f\u300c\u62a5\u6587\u6bb5\u7684\u5f80\u8fd4\u65f6\u95f4 RTT\u300d\u3002TCP \u4f7f\u7528 RTT \u7684\u52a0\u6743\u5e73\u5747\u8fd4\u56de\u65f6\u95f4 $RTT_S$\uff08\u53c8\u53eb\u300c\u5e73\u6ed1\u7684\u5f80\u8fd4\u65f6\u95f4\u300d\uff09\uff0c\u7b2c\u4e00\u6b21\u6d4b\u91cf\u5230 RTT \u6837\u672c\u65f6\uff0c$RTT_S$ \u53d6\u503c\u4e3a\u6d4b\u91cf\u5230\u7684 RTT \u6837\u672c\u503c\uff0c\u4e4b\u540e\u6bcf\u6b21\u6d4b\u91cf\u4e4b\u540e\uff0c\u5c31\u91cd\u65b0\u8ba1\u7b97 $RTT_S$\u3002<\/p><p>$$\u65b0\u7684 RTT_S = (1 - \\alpha) * ( \u65e7\u7684 RTT_S ) + \\alpha * (\u65b0\u7684 RTT \u6837\u672c)$$<\/p><p>$\\alpha$ \u53d6\u503c\u533a\u95f4\u4e3a 0\uff5e1\uff08\u4e0d\u5305\u542b 1 \uff09\uff0c\u82e5 $\\alpha$ \u63a5\u8fd1\u4e8e 0\uff0c\u8868\u793a\u65b0\u7684 $RTT_S$ \u548c\u65e7\u7684 $RTT_S$ \u53d8\u5316\u4e0d\u5927\uff0c$RTT_S$ \u53d7\u65b0\u7684 RTT \u6837\u672c\u5f71\u54cd\u4e0d\u5927\uff08RTT \u503c\u66f4\u65b0\u6162\uff09\uff1b\u82e5 $\\alpha$ \u63a5\u8fd1 1\uff0c\u5219\u8868\u793a\u65b0\u7684 $RTT_S$ \u53d7 RTT \u6837\u672c\u5f71\u54cd\u8f83\u5927\uff08RTT \u503c\u66f4\u65b0\u5feb\uff09\u3002RFC 2988 \u63a8\u8350\u7684 $\\alpha$ \u503c\u4e3a 0.125 \u3002<\/p><p>\u8d85\u65f6\u91cd\u4f20\u65f6\u95f4 RTO\uff08Retransmission Time-Out\uff09\u5e94\u8be5\u7565\u5927\u4e8e\u52a0\u6743\u5e73\u5747\u5f80\u8fd4\u65f6\u95f4 $RTT_S$:<\/p><p>$$RTO = RTT_S + 4 * RTT_D$$<\/p><p>$RTT_D$ \u662f RTT \u7684\u504f\u5dee\u7684\u52a0\u6743\u5e73\u5747\u503c\uff0c\u4e0e $RTT_S$ \u548c\u65b0\u7684 RTT \u6837\u672c\u4e4b\u5dee\u6709\u5173\u3002\u5728\u7b2c\u4e00\u6b21\u6d4b\u91cf RTT \u65f6\uff0c$RTT_D$ \u503c\u4e3a RTT \u6837\u672c\u503c\u7684\u4e00\u534a\uff0c\u4e4b\u540e\u6bcf\u6b21\u6d4b\u91cf RTT\uff0c\u5c31\u91cd\u65b0\u8ba1\u7b97 $RTT_D$\uff1a<\/p><p>$$\u65b0\u7684 RTT_D = ( 1 - \\beta ) * (\u65e7\u7684 RTT_D ) + \\beta * | RTT_S - \u65b0\u7684 RTT \u6837\u672c\u503c|$$<\/p><p>$\\beta$ \u662f\u5c0f\u4e8e 1 \u7684\u7cfb\u6570\uff0c\u63a8\u8350\u503c\u662f 0.25\u3002<\/p><p>\u8d85\u65f6\u91cd\u4f20\u7684\u60c5\u51b5\u4f1a\u5bf9\u8ba1\u7b97 $RTT_S$ \u548c RTO \u6709\u5f88\u5927\u7684\u5f71\u54cd\uff0c\u6bd4\u5982\u8d85\u65f6\u91cd\u4f20\u540e\u6536\u5230\u4e86\u786e\u8ba4\u62a5\u6587\u6bb5\uff0c\u8fd9\u6837\u5c31\u65e0\u6cd5\u5224\u65ad\u786e\u8ba4\u62a5\u6587\u6bb5\u662f\u5bf9\u5148\u524d\u62a5\u6587\u6bb5\u7684\u786e\u8ba4\uff0c\u8fd8\u662f\u5bf9\u540e\u6765\u91cd\u4f20\u62a5\u6587\u6bb5\u7684\u786e\u8ba4\u3002\u9488\u5bf9\u8fd9\u4e2a\u95ee\u9898 Karn \u63d0\u51fa\u4e86\u4e00\u4e2a\u7b97\u6cd5\uff1a\u5728\u8ba1\u7b97\u52a0\u6743\u5e73\u5747 $RTT_S$ \u65f6\uff0c\u53ea\u8981\u62a5\u6587\u91cd\u4f20\u4e86\uff0c\u5c31\u4e0d\u91c7\u7528\u5176\u5f80\u8fd4\u65f6\u95f4\u6837\u672c\u3002<\/p><p>\u4f46\u5982\u679c\u7f51\u7edc\u65f6\u5ef6\u7a81\u7136\u589e\u5927\uff0c\u5728\u91cd\u4f20\u65f6\u95f4\u5185\u4e0d\u4f1a\u6536\u5230\u786e\u8ba4\u62a5\u6587\u6bb5\uff0c\u4e8e\u662f\u5c31\u91cd\u4f20\u62a5\u6587\u6bb5\uff0c\u4f46\u6839\u636e Karn \u7b97\u6cd5\uff0c\u4e0d\u8003\u8651\u91cd\u4f20\u62a5\u6587\u6bb5\u7684\u5f80\u8fd4\u65f6\u95f4\u6837\u672c\uff0c\u8fd9\u6837\u91cd\u4f20\u65f6\u95f4\u65e0\u6cd5\u5f97\u5230\u66f4\u65b0\u3002<\/p><p>\u6240\u4ee5\u8981\u5bf9 Karn \u7b97\u6cd5\u4f5c\u51fa\u4fee\u6b63\uff0c\u62a5\u6587\u6bb5\u6bcf\u91cd\u4f20\u4e00\u6b21\uff0c\u5c31\u628a\u8d85\u65f6\u91cd\u4f20\u65f6\u95f4 RTO \u589e\u5927\u4e00\u4e9b\u3002\u5178\u578b\u7684\u505a\u6cd5\u662f\u65b0\u7684\u91cd\u4f20\u65f6\u95f4\u8bbe\u7f6e\u4e3a\u539f\u6765\u7684\u91cd\u4f20\u65f6\u95f4\u7684 2 \u500d\uff0c\u5f53\u4e0d\u518d\u53d1\u751f\u62a5\u6587\u6bb5\u91cd\u4f20\uff0c\u624d\u6839\u636e\u516c\u5f0f\u8ba1\u7b97\u8d85\u65f6\u91cd\u4f20\u65f6\u95f4\u3002<\/p><h3 id=\"\u9009\u62e9\u786e\u8ba4-sack\">\u9009\u62e9\u786e\u8ba4 SACK<\/h3><p>\u82e5\u6536\u5230\u7684\u62a5\u6587\u6bb5\u65e0\u5dee\u9519\uff0c\u4f46\u662f\u672a\u6309\u5e8f\u53f7\u5230\u8fbe\uff0c\u4e2d\u95f4\u8fd8\u7f3a\u5c11\u4e86\u4e00\u4e9b\u5e8f\u53f7\u7684\u6570\u636e\uff0c\u53ef\u4ee5\u901a\u8fc7\u300c\u9009\u62e9\u786e\u8ba4\u300d\uff08selective ACK\uff09\u53ea\u4f20\u9001\u7f3a\u5c11\u7684\u6570\u636e\u800c\u4e0d\u91cd\u4f20\u5df2\u7ecf\u5230\u8fbe\u63a5\u6536\u65b9\u7684\u6570\u636e\u3002<\/p><p>TCP \u63a5\u6536\u65b9\u63a5\u6536\u5230\u7684\u6570\u636e\u5b57\u8282\u6d41\u5e8f\u53f7\u4e0d\u8fde\u7eed\uff0c\u5c31\u5f62\u6210\u4e86\u4e00\u4e9b\u4e0d\u8fde\u7eed\u7684\u5b57\u8282\u5757\uff0c\u5982\u56fe 12\uff0c\u5e8f\u53f7 1 \uff5e 1000\u6536\u5230\u4e86\uff0c\u4f46 1001 \uff5e 1500 \u6ca1\u6709\u6536\u5230\uff0c\u63a5\u4e0b\u6765 1501 \uff5e 3000\u6536\u5230\u4e86\uff0c\u7f3a\u5c11 3001 \uff5e 3501\uff0c\u518d\u540e\u9762 4501 \u4e4b\u540e\u7684\u6570\u636e\u6ca1\u6536\u5230\u3002\u5982\u679c\u8fd9\u4e9b\u5b57\u8282\u7684\u5e8f\u53f7\u90fd\u5728\u63a5\u6536\u7a97\u53e3\u5185\uff0c\u63a5\u6536\u65b9\u53ef\u4ee5\u5148\u63a5\u6536\u4e0b\u8fd9\u4e9b\u6570\u636e\uff0c\u5e76\u4e14\u5c06\u4fe1\u606f\u544a\u77e5\u53d1\u9001\u65b9\u3002<\/p><p><img src=\"https:\/\/sunpe.github.io\/images\/tcp\/12.png\" alt=\"\u56fe 12 \u4e0d\u8fde\u7eed\u7684\u5b57\u8282\u5757\"><\/p><p>\u56fe 12 \u4e0d\u8fde\u7eed\u7684\u5b57\u8282\u5757<\/p><p>\u8981\u4f7f\u7528 SACK\uff0c\u90a3\u4e48\u5728\u521b\u5efa\u94fe\u63a5\u65f6\u9700\u8981\u5728 TCP \u9996\u90e8\u52a0\u4e0a\u300c\u5141\u8bb8 SACK\u300d\u9009\u9879\uff0c\u4f7f\u7528\u4e86 SACK\uff0c\u539f\u6765\u9996\u90e8\u4e2d\u7684\u300c\u786e\u8ba4\u5b57\u6bb5\u53f7\u300d\u7528\u6cd5\u4e0d\u53d8\uff0c\u53ea\u662f\u4e4b\u540e\u7684 TCP \u62a5\u6587\u6bb5\u9996\u90e8\u90fd\u589e\u52a0\u4e86 SACK \u9009\u9879\uff0c\u4ee5\u4fbf\u62a5\u544a\u6536\u5230\u7684\u4e0d\u8fde\u7eed\u7684\u5b57\u8282\u5757\u8fb9\u754c\u3002<\/p><h2 id=\"\u6d41\u91cf\u63a7\u5236\">\u6d41\u91cf\u63a7\u5236<\/h2><h3 id=\"\u5229\u7528\u6ed1\u52a8\u7a97\u53e3\u5b9e\u73b0\u6d41\u91cf\u63a7\u5236\">\u5229\u7528\u6ed1\u52a8\u7a97\u53e3\u5b9e\u73b0\u6d41\u91cf\u63a7\u5236<\/h3><p>\u5982\u679c\u53d1\u9001\u65b9\u6570\u636e\u53d1\u9001\u7684\u8fc7\u5feb\uff0c\u63a5\u6536\u65b9\u53ef\u80fd \u6765\u4e0d\u53ca\u63a5\u6536\uff0c\u8fd9\u5c31\u53ef\u80fd\u9020\u6210\u6570\u636e\u4e22\u5931\uff0c\u6240\u4ee5\u9700\u8981\u8ba9\u53d1\u9001\u65b9\u53d1\u9001\u901f\u7387\u4e0d\u8981\u592a\u5feb\uff0c\u4ee5\u4fbf\u63a5\u6536\u65b9\u6765\u5f97\u53ca\u5904\u7406\uff0c\u8fd9\u5c31\u662f\u6d41\u91cf\u63a7\u5236\u3002<\/p><p>\u5229\u7528\u6ed1\u52a8\u7a97\u53e3\u673a\u5236\u53ef\u4ee5\u5f88\u65b9\u4fbf\u5728 TCP \u94fe\u63a5\u4e0a\u5b9e\u73b0\u5bf9\u53d1\u9001\u65b9\u7684\u6d41\u91cf\u63a7\u5236\u3002\u5982\u56fe 13 \u6240\u793a\uff0c\u5efa\u7acb\u94fe\u63a5\u65f6\uff0cB \u544a\u8bc9 A \u300c\u6211\u7684\u63a5\u6536\u7a97\u53e3 rwnd = 400\u300d\uff08rwnd \u8868\u793a receiver window\uff09\uff0c\u53d1\u9001\u65b9\u7684\u53d1\u9001\u7a97\u53e3\u4e0d\u80fd\u8d85\u8fc7\u63a5\u6536\u65b9\u7ed9\u51fa\u7684\u63a5\u6536\u7a97\u53e3\u3002\u9700\u8981\u6ce8\u610f\u7684\u662f\uff0cTCP \u7a97\u53e3\u5355\u4f4d\u662f\u5b57\u8282\uff0c\u800c\u4e0d\u662f\u62a5\u6587\u6bb5\u3002\u5047\u8bbe\u6bcf\u4e2a\u62a5\u6587\u957f\u5ea6\u662f 100 \u5b57\u8282\uff0c\u62a5\u6587\u6bb5\u5e8f\u53f7\u521d\u59cb\u503c\u662f 1\uff0c\u7bad\u5934\u4e2d\u5927\u5199\u7684 ACK \u8868\u793a\u9996\u90e8\u4e2d\u786e\u8ba4\u4f4d ACK\uff0c\u5c0f\u5199\u7684 ack \u8868\u793a\u786e\u8ba4\u5b57\u6bb5\u7684\u503c\u3002<\/p><p><img src=\"https:\/\/sunpe.github.io\/images\/tcp\/13.png\" alt=\"\u56fe 13 \u5229\u7528\u53ef\u53d8\u7a97\u53e3\u8fdb\u884c\u6d41\u91cf\u63a7\u5236\"><\/p><p>\u56fe 13 \u5229\u7528\u53ef\u53d8\u7a97\u53e3\u8fdb\u884c\u6d41\u91cf\u63a7\u5236<\/p><p>\u63a5\u6536\u65b9\u4e3b\u673a\u8fdb\u884c\u4e86 3 \u6b21\u6d41\u91cf\u63a7\u5236\uff0c\u7b2c\u4e00\u6b21\u5c06\u7a97\u53e3\u51cf\u5c0f\u5230 rwnd=300\uff0c\u7b2c\u4e8c\u6b21\u53c8\u51cf\u5230 rwnd=100\uff0c\u6700\u540e\u51cf\u5230 rwnd=0\uff0c\u5373\u4e0d\u5141\u8bb8\u5bf9\u65b9\u518d\u53d1\u9001\u6570\u636e\u4e86\uff0c\u6682\u505c\u72b6\u6001\u76f4\u5230 B \u518d\u53d1\u9001\u4e00\u4e2a\u65b0\u7684\u7a97\u53e3\u503c\u4e3a\u6b62\u3002<\/p><p>\u5982\u679c\u5728 B \u5411 A \u53d1\u9001\u96f6\u7a97\u53e3\u7684\u62a5\u6587\u6bb5\u540e\u4e0d\u4e45\uff0cB \u7684\u63a5\u6536\u7f13\u5b58\u53c8\u6709\u4e86\u4e00\u4e9b\u7a7a\u95f4\uff0c\u4e8e\u662f B \u5411 A \u53d1\u9001\u4e86 rwnd=400 \u7684\u62a5\u6587\u6bb5\u3002\u7136\u800c\u62a5\u6587\u5728\u4f20\u8f93\u8fc7\u7a0b\u4e2d\u4e22\u5931\uff0cA \u4e00\u76f4\u5728\u7b49\u5f85 B \u7684\u975e\u96f6\u7a97\u53e3\u901a\u77e5\uff0c\u800c B \u4e5f\u4e00\u76f4\u5728\u7b49\u5f85 A \u53d1\u9001\u6570\u636e\uff0c\u5982\u679c\u6ca1\u6709\u5176\u4ed6\u63aa\u65bd\uff0c\u8fd9\u79cd\u4e92\u76f8\u7b49\u5f85\u7684\u6b7b\u9501\u5c40\u9762\u4f1a\u4e00\u76f4\u6301\u7eed\u4e0b\u53bb\u3002\u4e3a\u89e3\u51b3\u8fd9\u95ee\u9898\uff0cTCP \u4e3a\u6bcf\u4e00\u4e2a\u8fde\u63a5\u8bbe\u6709\u4e00\u4e2a\u300c\u6301\u7eed\u8ba1\u6570\u5668\u300d\uff0c\u53ea\u8981 TCP \u8fde\u63a5\u7684\u4e00\u65b9\u6536\u5230\u5bf9\u65b9\u7684\u96f6\u7a97\u53e3\u901a\u77e5\uff0c\u5c31\u542f\u52a8\u6301\u7eed\u8ba1\u6570\u5668\uff0c\u5982\u679c\u8ba1\u6570\u5668\u5230\u671f\uff0c\u5c31\u53d1\u9001\u4e00\u4e2a\u96f6\u7a97\u53e3\u7684\u63a2\u6d4b\u62a5\u6587\uff08\u4ec5\u643a\u5e26 1 \u5b57\u8282\u6570\u636e\uff09\uff0c\u800c\u5bf9\u65b9\u5728\u786e\u8ba4\u8fd9\u4e2a\u63a2\u6d4b\u62a5\u6587\u65f6\u7ed9\u51fa\u4e86\u73b0\u5728\u7684\u7a97\u53e3\u503c\u3002\u5982\u679c\u7a97\u53e3\u503c\u4ecd\u7136\u662f\u96f6\uff0c\u90a3\u4e48\u6536\u5230\u8fd9\u4e2a\u62a5\u6587\u7684\u4e00\u65b9\u5c31\u91cd\u65b0\u8bbe\u7f6e\u8ba1\u6570\u5668\uff0c\u5982\u679c\u7a97\u53e3\u4e0d\u662f\u96f6\uff0c\u90a3\u4e48\u5c31\u53ef\u4ee5\u6253\u7834\u6b7b\u9501\u50f5\u5c40\u3002<\/p><h2 id=\"\u62e5\u585e\u63a7\u5236\">\u62e5\u585e\u63a7\u5236<\/h2><p>\u8ba1\u7b97\u673a\u7f51\u7edc\u4e2d\uff0c\u94fe\u8def\u5e26\u5bbd\u3001\u4ea4\u6362\u8282\u70b9\u7684\u7f13\u5b58\u548c\u5904\u7406\u673a\u7b49\u90fd\u662f\u7f51\u7edc\u7684\u8d44\u6e90\uff0c\u5728\u67d0\u6bb5\u65f6\u95f4\uff0c\u5982\u679c\u5bf9\u7f51\u7edc\u4e2d\u67d0\u4e00\u8d44\u6e90\u7684\u9700\u6c42\u8d85\u8fc7\u4e86\u8be5\u8d44\u6e90\u6240\u80fd\u63d0\u4f9b\u7684\u53ef\u7528\u90e8\u5206\uff0c\u7f51\u7edc\u6027\u80fd\u5c31\u8981\u53d8\u574f\uff0c\u5373\u4ea7\u751f\u4e86\u62e5\u585e\uff08congestion\uff09\u3002<\/p><p>\u7f51\u7edc\u62e5\u585e\u5f80\u5f80\u662f\u7531\u8bb8\u591a\u56e0\u7d20\u5f15\u8d77\u7684\uff0c\u7b80\u5355\u7684\u589e\u52a0\u4e00\u4e9b\u8d44\u6e90\uff0c\u5f80\u5f80\u4e0d\u80fd\u89e3\u51b3\u62e5\u585e\u95ee\u9898\uff0c\u751a\u81f3\u6709\u65f6\u5019\u4f1a\u4f7f\u7f51\u7edc\u6027\u80fd\u53d8\u574f\u3002\u4f8b\u5982\uff0c\u5f53\u67d0\u4e2a\u8282\u70b9\u7684\u7f13\u5b58\u5bb9\u91cf\u592a\u5c0f\uff0c\u5230\u8fbe\u7684\u5206\u7ec4\u56e0\u7a7a\u95f4\u4e0d\u8db3\u800c\u4e0d\u5f97\u4e0d\u4e22\u5f03\uff0c\u5982\u679c\u4ec5\u4ec5\u662f\u6269\u5927\u63a5\u6536\u7f13\u5b58\uff0c\u5230\u8fbe\u8be5\u8282\u70b9\u7684\u5206\u7ec4\u4f1a\u5728\u7f13\u5b58\u4e2d\u6392\u961f\u3002\u7531\u4e8e\u94fe\u8def\u5bb9\u91cf\u548c\u5904\u7406\u673a\u6027\u80fd\u5e76\u672a\u63d0\u9ad8\uff0c\u56e0\u6b64\u7f13\u5b58\u4e2d\u7684\u5206\u7ec4\u7b49\u5f85\u65f6\u95f4\u5927\u5927\u589e\u52a0\uff0c\u7ed3\u679c\u4e0a\u5c42\u8f6f\u4ef6\u4f1a\u56e0\u4e3a\u7b49\u5f85\u8d85\u65f6\u800c\u91cd\u4f20\u5206\u7ec4\u3002\u7531\u4e8e\u62e5\u585e\u63a7\u5236\u5f15\u8d77\u7684\u91cd\u4f20\u4f1a\u7ee7\u800c\u52a0\u5267\u7f51\u7edc\u7684\u62e5\u585e\u3002<\/p><p>\u62e5\u585e\u63a7\u5236\u5c31\u662f\u9632\u6b62\u8fc7\u591a\u7684\u6570\u636e\u6ce8\u5165\u5230\u7f51\u7edc\u4e2d\uff0c\u8fd9\u6837\u53ef\u4ee5\u4f7f\u7f51\u7edc\u4e2d\u8def\u7531\u5668\u6216\u94fe\u8def\u4e0d\u81f3\u4e8e\u8fc7\u8f7d\uff0c\u4f7f\u7f51\u7edc\u80fd\u591f\u627f\u53d7\u73b0\u6709\u7684\u7f51\u7edc\u8d1f\u8377\u3002<\/p><p>\u62e5\u585e\u63a7\u5236\u548c\u6d41\u91cf\u63a7\u5236\u5bc6\u5207\u76f8\u5173\uff0c\u4f46\u4e5f\u5b58\u5728\u4e00\u4e9b\u5dee\u5f02\uff0c\u6d41\u91cf\u63a7\u5236\u901a\u5e38\u662f\u6307\u70b9\u5bf9\u70b9\u901a\u4fe1\u91cf\u7684\u63a7\u5236\uff0c\u89e3\u51b3\u7684\u662f\u7aef\u5230\u7aef\u7684\u95ee\u9898\uff08\u63a5\u6536\u6bb5\u63a7\u5236\u53d1\u9001\u7aef\uff09\uff0c\u6d41\u91cf\u63a7\u5236\u6240\u8981\u505a\u7684\u5c31\u662f\u6291\u5236\u53d1\u9001\u7aef\u53d1\u9001\u6570\u636e\u7684\u901f\u7387\uff0c\u4ee5\u4fbf\u63a5\u6536\u6bb5\u6765\u5f97\u53ca\u63a5\u6536\u3002\u800c\u62e5\u585e\u63a7\u5236\u662f\u4e00\u4e2a\u5168\u5c40\u6027\u7684\u8fc7\u7a0b\uff0c\u6d89\u53ca\u5230\u6240\u6709\u4e3b\u673a\u3001\u8def\u7531\u5668\uff0c\u4ee5\u53ca\u4e0e\u7f51\u7edc\u4f20\u8f93\u6027\u80fd\u76f8\u5173\u7684\u6240\u6709\u56e0\u7d20\u3002<\/p><p>\u62e5\u585e\u63a7\u5236\u6d41\u6d41\u91cf\u63a7\u5236\u4e4b\u6240\u4ee5\u4f1a\u88ab\u5f04\u6df7\uff0c\u662f\u56e0\u4e3a\u67d0\u4e9b\u62e5\u585e\u63a7\u5236\u7b97\u6cd5\u548c\u6d41\u91cf\u63a7\u5236\u7b97\u6cd5\u7c7b\u4f3c\uff0c\u5411\u53d1\u9001\u7aef\u53d1\u9001\u63a7\u5236\u62a5\u6587\uff0c\u6765\u544a\u8bc9\u53d1\u9001\u7aef\u7f51\u7edc\u51fa\u73b0\u9ebb\u70e6\uff0c\u5fc5\u987b\u653e\u6162\u901f\u5ea6\u3002<\/p><p>\u5047\u8bbe\u67d0\u4e2a\u7f51\u7edc\u5e26\u5bbd\u662f 1000 Gb\/s\uff0c\u6709\u4e00\u4e2a\u670d\u52a1\u5668\u5411\u4e00\u53f0 PC \u673a\u4ee5 1 Gb\/s \u7684\u901f\u7387\u4f20\u9001\u6570\u636e\uff0c\u663e\u7136\u7f51\u7edc\u5e26\u5bbd\u8db3\u591f\u5927\uff0c\u56e0\u800c\u4e0d\u5b58\u5728\u62e5\u585e\u95ee\u9898\uff0c\u4f46\u4e5f\u5fc5\u987b\u8981\u6709\u6d41\u91cf\u63a7\u5236\uff0c\u8ba9\u670d\u52a1\u5668\u7ecf\u5e38\u505c\u4e0b\u6765\uff0c\u4ee5\u4fbf\u8ba9 PC \u673a\u6765\u5f97\u53ca\u63a5\u6536\u3002<\/p><p>\u800c\u53e6\u4e00\u4e2a\u7f51\u7edc\u5e26\u5bbd\u662f 1 Mb\/s\uff0c\u6709 1000 \u53f0\u4e3b\u673a\uff0c\u5176\u4e2d 500 \u53f0\u5206\u522b\u5411\u53e6\u5916 500 \u53f0\u4e3b\u673a\u4ee5 100k\/s \u7684\u901f\u7387\u53d1\u9001\u6570\u636e\uff0c\u90a3\u4e48\u73b0\u5728\u7684\u95ee\u9898\u5c31\u4e0d\u662f\u63a5\u6536\u6bb5\u662f\u5426\u80fd\u6765\u5f97\u53ca\u63a5\u6536\u6570\u636e\uff0c\u800c\u662f\u6574\u4e2a\u7f51\u7edc\u7684\u8f93\u5165\u8d1f\u8f7d\u662f\u5426\u8d85\u8fc7\u4e86\u7f51\u7edc\u7684\u627f\u53d7\u80fd\u529b\u3002<\/p><p>\u8fdb\u884c\u62e5\u585e\u63a7\u5236\u9700\u8981\u4ed8\u51fa\u4ee3\u4ef7\uff0c\u9996\u5148\u9700\u8981\u83b7\u5f97\u7f51\u7edc\u5185\u90e8\u6d41\u91cf\u5206\u5e03\u7684\u4fe1\u606f\uff0c\u8fd8\u8981\u5728\u8282\u70b9\u4e4b\u95f4\u4ea4\u6362\u4fe1\u606f\u548c\u5404\u79cd\u547d\u4ee4\uff0c\u4ee5\u4fbf\u9009\u62e9\u63a7\u5236\u7b56\u7565\u548c\u5b9e\u65bd\u63a7\u5236\u3002\u8fd9\u5c31\u4ea7\u751f\u4e86\u989d\u5916\u7684\u5f00\u9500\uff0c\u6709\u65f6\u5019\u8fd8\u9700\u8981\u5c06\u4e00\u4e9b\u8d44\u6e90\uff08\u7f13\u5b58\u3001\u5e26\u5bbd\u7b49\uff09\u5206\u914d\u7ed9\u4e2a\u522b\u7528\u6237\uff08\u6216\u4e00\u4e9b\u7c7b\u522b\u7684\u7528\u6237\uff09\u5355\u72ec\u4f7f\u7528\uff0c\u4f7f\u5f97\u7f51\u7edc\u8d44\u6e90\u4e0d\u80fd\u66f4\u597d\u7684\u5b9e\u73b0\u5171\u4eab\u3002\u6240\u4ee5\u5728\u8bbe\u8ba1\u62e5\u585e\u63a7\u5236\u7b56\u7565\u65f6\uff0c\u5fc5\u987b\u5168\u9762\u8861\u91cf\u5f97\u5931\u3002<\/p><p><img src=\"https:\/\/sunpe.github.io\/images\/tcp\/14.png\" alt=\"\u56fe 14 \u62e5\u585e\u63a7\u5236\u7684\u4f5c\u7528\"><\/p><p>\u56fe 14 \u62e5\u585e\u63a7\u5236\u7684\u4f5c\u7528<\/p><p>\u5982\u56fe 14 \u6240\u793a\uff0c\u6a2a\u8f74\u662f\u300c\u63d0\u4f9b\u7684\u8d1f\u8f7d\u300d\uff0c\u4ee3\u8868\u5355\u4f4d\u65f6\u95f4\u8f93\u5165\u5230\u7f51\u7edc\u7684\u5206\u7ec4\u6570\u76ee\uff0c\u4e5f\u79f0\u4f5c\u300c\u8f93\u5165\u8d1f\u8f7d\u300d\u6216\u300c\u7f51\u7edc\u8d1f\u8f7d\u300d\u3002\u7eb5\u8f74\u662f\u300c\u541e\u5410\u91cf\u300d\uff0c\u4ee3\u8868\u5355\u4f4d\u65f6\u95f4\u4ece\u7f51\u7edc\u8f93\u51fa\u7684\u5206\u7ec4\u6570\u76ee\u3002\u5177\u6709\u7406\u60f3\u62e5\u585e\u63a7\u5236\u7684\u7f51\u7edc\uff0c\u5728\u541e\u5410\u91cf\u9971\u548c\u4e4b\u524d\uff0c\u541e\u5410\u91cf\u5e94\u7b49\u4e8e\u7f51\u7edc\u8d1f\u8f7d\uff0c\u5f53\u8d1f\u8f7d\u8d85\u8fc7\u67d0\u4e00\u9650\u5ea6\u65f6\uff0c\u7531\u4e8e\u7f51\u7edc\u8d44\u6e90\u6709\u9650\uff0c\u541e\u5410\u91cf\u4e0d\u518d\u589e\u957f\u800c\u4fdd\u6301\u4e3a\u6c34\u5e73\u7ebf\uff0c\u5373\u541e\u5410\u91cf\u8fbe\u5230\u9971\u548c\uff0c\u8fd9\u5c31\u8868\u660e\u8f93\u5165\u5230\u7f51\u7edc\u7684\u67d0\u4e9b\u5206\u7ec4\u88ab\u67d0\u4e2a\u8282\u70b9\u4e22\u5f03\u4e86\u3002<\/p><p>\u4f46\u5b9e\u9645\u60c5\u51b5\u4e0b\uff0c\u968f\u7740\u7f51\u7edc\u8d1f\u8f7d\u7684\u589e\u5927\uff0c\u7f51\u7edc\u541e\u5410\u91cf\u589e\u957f\u7387\u9010\u6e10\u51cf\u5c0f\uff0c\u4e5f\u5c31\u662f\u8bf4\u5728\u7f51\u7edc\u8fd8\u6ca1\u6709\u8fbe\u5230\u9971\u548c\u65f6\uff0c\u5c31\u5df2\u7ecf\u6709\u4e00\u90e8\u5206\u5206\u7ec4\u88ab\u4e22\u5f03\u4e86\uff0c\u5f53\u8d1f\u8f7d\u660e\u663e\u7684\u5c0f\u4e8e\u7406\u60f3\u7684\u541e\u5410\u91cf\u7684\u65f6\u5019\u7f51\u7edc\u5c31\u8fdb\u5165\u4e86\u300c\u8f7b\u5ea6\u62e5\u585e\u300d\u7684\u72b6\u6001\u3002\u5f53\u8d1f\u8f7d\u8fbe\u5230\u67d0\u4e00\u6570\u503c\u65f6\uff0c\u7f51\u7edc\u541e\u5410\u91cf\u53cd\u800c\u968f\u7740\u8d1f\u8f7d\u7684\u589e\u5927\u800c\u4e0b\u964d\uff0c\u7f51\u7edc\u5df2\u7ecf\u8fdb\u5165\u62e5\u585e\u72b6\u6001\u4e86\u3002\u5f53\u8d1f\u8f7d\u7ee7\u7eed\u589e\u5927\u5230\u67d0\u4e00\u6570\u503c\u65f6\uff0c\u7f51\u7edc\u541e\u5410\u91cf\u5c31\u4e0b\u964d\u5230\u96f6\uff0c\u7f51\u7edc\u5df2\u7ecf\u65e0\u6cd5\u5de5\u4f5c\u3002<\/p><p>\u4ece\u539f\u7406\u4e0a\u8bb2\uff0c\u62e5\u585e\u63a7\u5236\u7684\u65b9\u6848\u5c31\u662f\u8ba9\u5bf9\u7f51\u7edc\u8d44\u6e90\u7684\u9700\u6c42\u4e0d\u518d\u5927\u4e8e\u53ef\u7528\u7684\u7f51\u7edc\u8d44\u6e90\uff0c\u6216\u8005\u662f\u589e\u5927\u7f51\u7edc\u4e2d\u67d0\u4e9b\u53ef\u7528\u8d44\u6e90\uff08\u589e\u52a0\u4e00\u4e9b\u94fe\u8def\u3001\u589e\u52a0\u5e26\u5bbd\u7b49\uff09\uff0c\u6216\u8005\u51cf\u5c0f\u7528\u6237\u5bf9\u8d44\u6e90\u7684\u9700\u6c42\uff08\u62d2\u7edd\u65b0\u7684\u5efa\u7acb\u8fde\u63a5\u8bf7\u6c42\u3001\u8ba9\u7528\u6237\u51cf\u8f7b\u8d1f\u8377\uff09\u3002\u5728\u91c7\u53d6\u67d0\u9879\u63aa\u65bd\u65f6\uff0c\u8fd8\u5fc5\u987b\u8003\u8651\u5230\u8be5\u63aa\u65bd\u6240\u5e26\u6765\u7684\u5f71\u54cd\u3002<\/p><p>\u62e5\u585e\u63a7\u5236\u662f\u4e00\u4e2a\u52a8\u6001\u7684\u95ee\u9898\uff0c\u7f51\u7edc\u6b63\u671d\u7740\u9ad8\u901f\u5316\u7684\u65b9\u5411\u53d1\u5c55\uff0c\u5f88\u5bb9\u6613\u51fa\u73b0\u7f13\u5b58\u4e0d\u591f\u5927\u800c\u9020\u6210\u5206\u7ec4\u7684\u4e22\u5931\uff0c\u5206\u7ec4\u4e22\u5931\u662f\u7f51\u7edc\u62e5\u585e\u7684\u5f81\u5146\u800c\u4e0d\u662f\u539f\u56e0\uff0c\u6709\u4e9b\u60c5\u51b5\u4e0b\uff0c\u62e5\u585e\u63a7\u5236\u673a\u5236\u672c\u8eab\u4f1a\u5f15\u8d77\u7f51\u7edc\u6027\u80fd\u6076\u5316\u751a\u81f3\u53d1\u751f\u6b7b\u9501\u3002<\/p><p>\u68c0\u6d4b\u7f51\u7edc\u62e5\u585e\u7684\u65b9\u6cd5\u5f88\u591a\uff0c\u4e3b\u8981\u7684\u68c0\u6d4b\u6307\u6807\u6709\uff1a\u7531\u4e8e\u7f3a\u5c11\u7f13\u5b58\u7a7a\u95f4\u800c\u88ab\u4e22\u5f03\u7684\u5206\u7ec4\u7684\u767e\u5206\u6bd4\u3001\u5e73\u5747\u961f\u5217\u957f\u5ea6\u3001\u8d85\u65f6\u91cd\u4f20\u7684\u5206\u7ec4\u6570\u3001\u5e73\u5747\u5206\u7ec4\u65f6\u5ef6\u3001\u5206\u7ec4\u65f6\u5ef6\u7684\u6807\u51c6\u5dee\u7b49\u5f85\u3002<\/p><p>\u4e00\u822c\u5728\u68c0\u6d4b\u5230\u62e5\u585e\u53d1\u751f\u65f6\uff0c\u8981\u5c06\u62e5\u585e\u53d1\u751f\u7684\u4fe1\u606f\u4f20\u9001\u5230\u4ea7\u751f\u5206\u7ec4\u7684\u6e90\uff0c\u901a\u77e5\u62e5\u585e\u7684\u6d88\u606f\u5206\u7ec4\u540c\u6837\u4f1a\u4f7f\u7f51\u7edc\u66f4\u52a0\u62e5\u585e\u3002\u53e6\u4e00\u79cd\u65b9\u6cd5\u662f\u5728\u8def\u7531\u5668\u8f6c\u53d1\u7684\u5206\u7ec4\u4e2d\u4fdd\u7559\u4e00\u4e2a\u6bd4\u7279\u6216\u5b57\u6bb5\uff0c\u7528\u8be5\u6bd4\u7279\u6216\u5b57\u6bb5\u8868\u793a\u7f51\u7edc\u662f\u5426\u62e5\u585e\u3002\u4e5f\u53ef\u4ee5\u901a\u8fc7\u5468\u671f\u6027\u7684\u53d1\u9001\u63a2\u6d4b\u5206\u7ec4\uff0c\u8be2\u95ee\u62e5\u585e\u662f\u5426\u53d1\u751f\u3002<\/p><p>\u6b64\u5916\u8fc7\u4e8e\u9891\u7e41\u7684\u62e5\u585e\u63a7\u5236\u4f1a\u4f7f\u7cfb\u7edf\u4ea7\u751f\u4e0d\u7a33\u5b9a\u7684\u632f\u8361\uff0c\u8fc7\u4e8e\u8fdf\u7f13\u7684\u62e5\u585e\u63a7\u5236\u53c8\u4e0d\u5177\u6709\u4efb\u4f55\u5b9e\u7528\u4ef7\u503c\u3002\u56e0\u6b64\u8981\u91c7\u53d6\u67d0\u79cd\u6298\u4e2d\u7684\u65b9\u6848\uff0c\u9009\u62e9\u6b63\u786e\u7684\u65f6\u95f4\u5e38\u6570\u3002<\/p><p>RFC 2581 \u5b9a\u4e49\u4e86\u62e5\u585e\u63a7\u5236\u7684\u56db\u79cd\u7b97\u6cd5\uff1a\u6162\u5f00\u59cb\uff08slow-start\uff09\u3001\u62e5\u585e\u907f\u514d\uff08congestion avoidance\uff09\u3001\u5feb\u91cd\u4f20\uff08fast retransmit\uff09\u548c\u5feb\u6062\u590d\uff08fast recovery\uff09\u3002<\/p><h3 id=\"\u6162\u5f00\u59cb\u548c\u62e5\u585e\u907f\u514d\">\u6162\u5f00\u59cb\u548c\u62e5\u585e\u907f\u514d<\/h3><p>\u53d1\u9001\u65b9\u7ef4\u6301\u4e00\u4e2a\u53eb\u300c\u62e5\u585e\u7a97\u53e3\u300dcwnd\uff08congestion window\uff09\u7684\u72b6\u6001\u53d8\u91cf\uff0c\u62e5\u585e\u7a97\u53e3\u5927\u5c0f\u53d6\u51b3\u4e8e\u7f51\u7edc\u62e5\u585e\u7a0b\u5ea6\uff0c\u5e76\u4e14\u52a8\u6001\u53d8\u5316\u3002\u53d1\u9001\u65b9\u8ba9\u81ea\u5df1\u7684\u53d1\u9001\u7a97\u53e3\u7b49\u4e8e\u62e5\u585e\u7a97\u53e3\uff0c\u5982\u679c\u518d\u8003\u8651\u63a5\u6536\u65b9\u7684\u63a5\u6536\u80fd\u529b\uff0c\u53d1\u9001\u7a97\u53e3\u8fd8\u53ef\u80fd\u5c0f\u4e8e\u62e5\u585e\u7a97\u53e3\u3002<\/p><p>\u53d1\u9001\u65b9\u63a7\u5236\u62e5\u585e\u7a97\u53e3\u7684\u539f\u5219\u662f\uff1a\u53ea\u8981\u7f51\u7edc\u6ca1\u6709\u51fa\u73b0\u62e5\u585e\uff0c\u62e5\u585e\u7a97\u53e3\u5c31\u518d\u589e\u5927\u4e00\u4e9b\uff0c\u4ee5\u4fbf\u53d1\u9001\u66f4\u591a\u7684\u5206\u7ec4\uff1b\u5982\u679c\u7f51\u7edc\u51fa\u73b0\u62e5\u585e\uff0c\u62e5\u585e\u7a97\u53e3\u5c31\u51cf\u5c0f\u4e00\u4e9b\uff0c\u4ee5\u51cf\u5c0f\u6ce8\u5165\u5230\u7f51\u7edc\u7684\u5206\u7ec4\u6570\u3002<\/p><p>\u7f51\u7edc\u53d1\u9001\u62e5\u585e\u65f6\uff0c\u8def\u7531\u5668\u5c31\u8981\u4e22\u5f03\u5206\u7ec4\uff0c\u56e0\u6b64\u53ea\u8981\u53d1\u9001\u65b9\u6ca1\u6709\u6309\u65f6\u63a5\u6536\u5230\u5e94\u8be5\u5230\u8fbe\u7684\u786e\u8ba4\u62a5\u6587\uff0c\u5c31\u53ef\u4ee5\u8ba4\u4e3a\u7f51\u7edc\u4e2d\u51fa\u73b0\u4e86\u62e5\u585e\u3002<\/p><p>\u6162\u5f00\u59cb\u7b97\u6cd5\u7684\u601d\u8def\u662f\u8fd9\u6837\u7684\uff0c\u5f53\u4e3b\u673a\u5f00\u59cb\u53d1\u9001\u6570\u636e\u65f6\uff0c\u5982\u679c\u7acb\u5373\u5c06\u5927\u91cf\u5206\u7ec4\u6ce8\u5165\u5230\u7f51\u7edc\uff0c\u90a3\u4e48\u5c31\u6709\u53ef\u80fd\u5f15\u8d77\u62e5\u585e\u3002\u8f83\u597d\u7684\u65b9\u6cd5\u662f\u5148\u63a2\u6d4b\u4e00\u4e0b\uff0c\u5373\u7531\u5c0f\u5230\u5927\u9010\u6e10\u589e\u5927\u53d1\u9001\u7a97\u53e3\uff0c\u4e5f\u5c31\u662f\u8bf4\u4ece\u5c0f\u5230\u8fbe\u9010\u6e10\u589e\u5927\u62e5\u585e\u7a97\u53e3\u6570\u503c\u3002\u521a\u5f00\u59cb\u53d1\u9001\u62a5\u6587\u6bb5\u65f6\uff0c\u5148\u628a\u62e5\u585e\u7a97\u53e3 cwnd \u8bbe\u7f6e\u4e3a\u4e00\u4e2a\u6700\u5927\u62a5\u6587\u6bb5 MSS \u7684\u6570\u503c\uff0c\u6bcf\u6536\u5230\u4e00\u4e2a\u5bf9\u65b0\u7684\u62a5\u6587\u6bb5\u786e\u8ba4\u540e\uff0c\u628a\u62e5\u585e\u7a97\u53e3\u589e\u52a0\u81f3\u591a\u4e00\u4e2a MSS \u7684\u6570\u503c\u3002\u7528\u8fd9\u6837\u7684\u65b9\u5f0f\u9010\u6b65\u589e\u5927\u53d1\u9001\u65b9\u62e5\u585e\u7a97\u53e3 cwnd\uff0c\u4ee5\u4f7f\u5206\u7ec4\u6ce8\u5165\u5230\u7f51\u7edc\u7684\u901f\u7387\u66f4\u52a0\u5408\u7406\u3002<\/p><p>\u5728\u4e00\u5f00\u59cb\u53d1\u9001\u65b9\u5148\u8bbe\u7f6e cwnd=1 \uff08\u4f7f\u7528\u62a5\u6587\u6bb5\u4e2a\u6570\u4f5c\u4e3a\u7a97\u53e3\u5927\u5c0f\u7684\u5355\u4f4d\uff0c\u5b9e\u9645\u4e0a TCP \u7a97\u53e3\u7684\u5355\u4f4d\u662f\u5b57\u8282\uff09\u3002\u53d1\u9001\u7b2c\u4e00\u4e2a\u62a5\u6587\u6bb5 $M_1$\uff0c\u63a5\u6536\u65b9\u6536\u5230\u540e\u786e\u8ba4 $M_1$\uff0c\u53d1\u9001\u65b9\u6536\u5230\u5bf9 $M_1$ \u7684\u786e\u8ba4\u540e\uff0c\u628a cwnd \u589e\u5927\u5230 2\uff0c\u53d1\u9001\u65b9\u63a5\u7740\u53d1\u9001 $M_2$ \u548c $M_3$ \u4e24\u4e2a\u62a5\u6587\u6bb5\uff0c\u63a5\u6536\u65b9\u8fd4\u56de\u5bf9 $M_2$ \u548c $M_3$ \u7684\u786e\u8ba4\u3002\u53d1\u9001\u65b9\u6bcf\u6536\u5230\u4e00\u4e2a\u5bf9\u65b0\u62a5\u6587\u6bb5\u7684\u786e\u8ba4\uff08\u91cd\u4f20\u7684\u4e0d\u7b97\u5728\u5185\uff09\uff0c\u5c31\u4f7f\u53d1\u9001\u65b9\u7684\u62e5\u585e\u7a97\u53e3\u52a0 1\uff0c\u56e0\u6b64\u6536\u5230\u8fd9\u4e24\u4e2a\u786e\u8ba4\u540e\uff0c cwnd \u4ece 2 \u589e\u5927\u5230 4\uff0c\u53ef\u4ee5\u53d1\u9001 $M_4$ ~ $M_7$ \u5171 4 \u4e2a\u62a5\u6587\u6bb5\u3002\u4f7f\u7528\u6162\u5f00\u59cb\u7b97\u6cd5\uff0c\u6bcf\u7ecf\u8fc7\u4e00\u4e2a\u4f20\u8f93\u8f6e\u6b21\uff08transmission round\uff09\uff0c\u62e5\u585e\u7a97\u53e3 cwnd \u5c31\u52a0\u500d\u3002<\/p><p>\u628a\u62e5\u585e\u7a97\u53e3 cwnd \u6240\u5141\u8bb8\u53d1\u9001\u7684\u62a5\u6587\u6bb5\u90fd\u8fde\u7eed\u53d1\u9001\u51fa\u53bb\uff0c\u5e76\u6536\u5230\u6700\u540e\u4e00\u4e2a\u5b57\u8282\u7684\u786e\u8ba4\uff0c\u5373\u4e00\u4e2a\u53d1\u9001\u8f6e\u6b21\u3002\u4e00\u4e2a\u4f20\u8f93\u8f6e\u6b21\u6240\u7ecf\u5386\u7684\u65f6\u95f4\u5176\u5b9e\u5c31\u662f\u5f80\u8fd4\u65f6\u95f4 RTT\u3002\u4f8b\u5982\uff0c\u62e5\u585e\u7a97\u53e3 cwnd \u7684\u5927\u5c0f\u662f 4 \u4e2a\u62a5\u6587\u6bb5\uff0c\u90a3\u4e48\u5f80\u8fd4\u65f6\u95f4 RTT \u5c31\u662f\u53d1\u9001\u65b9\u8fde\u7eed\u53d1\u9001 4 \u4e2a\u62a5\u6587\u6bb5\uff0c\u5e76\u6536\u5230\u8fd9 4 \u4e2a\u62a5\u6587\u6bb5\u7684\u786e\u8ba4\uff0c\u603b\u5171\u7ecf\u5386\u7684\u65f6\u95f4\u3002<\/p><p><img src=\"https:\/\/sunpe.github.io\/images\/tcp\/15.png\" alt=\"\u56fe 15 \u53d1\u9001\u65b9\u6bcf\u6536\u5230\u4e00\u4e2a\u786e\u8ba4\u5c31\u628a\u7a97\u53e3 cwnd \u52a0 1\"><\/p><p>\u56fe 15 \u53d1\u9001\u65b9\u6bcf\u6536\u5230\u4e00\u4e2a\u786e\u8ba4\u5c31\u628a\u7a97\u53e3 cwnd \u52a0 1<\/p><p>\u6162\u5f00\u59cb\u7684\u300c\u6162\u300d\u5e76\u4e0d\u662f\u6307 cwnd \u7684\u589e\u957f\u901f\u7387\u6162\uff0c\u800c\u662f\u6307\u5728 TCP \u5f00\u59cb\u53d1\u9001\u62a5\u6587\u6bb5\u65f6\u5148\u8bbe\u7f6e cwnd=1\uff0c\u4f7f\u5f97\u53d1\u9001\u65b9\u5728\u5f00\u59cb\u65f6\u53ea\u53d1\u9001\u4e00\u4e2a\u62a5\u6587\u6bb5\uff08\u76ee\u7684\u662f\u63a2\u6d4b\u7f51\u7edc\u7684\u62e5\u585e\u60c5\u51b5\uff09\uff0c\u7136\u540e\u9010\u6e10\u589e\u5927 cwnd\u3002\u4e3a\u4e86\u9632\u6b62\u62e5\u585e\u7a97\u53e3 cwnd \u589e\u5927\u7684\u8fc7\u5927\u5f15\u8d77\u7684\u7f51\u7edc\u62e5\u585e\uff0c\u8fd8\u9700\u8981\u8bbe\u7f6e\u4e00\u4e2a\u300c\u6162\u5f00\u59cb\u95e8\u9650 ssthresh\u300d\u72b6\u6001\u53d8\u91cf\uff0c\u5f53 cwnd &lt; ssthresh \u65f6\uff0c\u4f7f\u7528\u6162\u5f00\u59cb\u7b97\u6cd5\uff0c\u5f53 cwnd &gt; ssthresh \u65f6\u8be5\u7528\u62e5\u585e\u907f\u514d\u7b97\u6cd5\u3002<\/p><p>\u62e5\u585e\u907f\u514d\u7b97\u6cd5\u7684\u601d\u8def\u662f\u8ba9\u62e5\u585e\u7a97\u53e3 cwnd \u7f13\u6162\u589e\u5927\uff0c\u6bcf\u7ecf\u8fc7\u4e00\u4e2a\u5f80\u8fd4\u65f6\u95f4 RTT \u5c31\u628a\u53d1\u9001\u65b9\u7684\u62e5\u585e\u7a97\u53e3 cwnd \u52a0 1\uff0c\u800c\u4e0d\u662f\u52a0\u500d\u3002\u8fd9\u6837\uff0c\u62e5\u585e\u7a97\u53e3 cwnd \u6309\u7ebf\u6027\u89c4\u5f8b\u7f13\u6162\u589e\u957f\u3002<\/p><p>\u65e0\u8bba\u5728\u6162\u5f00\u59cb\u9636\u6bb5\u8fd8\u662f\u5728\u62e5\u585e\u907f\u514d\u9636\u6bb5\uff0c\u53ea\u8981\u53d1\u9001\u65b9\u5224\u65ad\u7f51\u7edc\u51fa\u73b0\u62e5\u585e\uff08\u6ca1\u6309\u65f6\u6536\u5230\u786e\u8ba4\uff09\uff0c\u5c31\u8981\u628a\u6162\u5f00\u59cb\u95e8\u9650 ssthresh \u8bbe\u7f6e\u4e3a\u51fa\u73b0\u62e5\u585e\u65f6\u53d1\u9001\u7a97\u53e3\u503c\u7684\u4e00\u534a\uff08\u4f46\u4e0d\u80fd\u5c0f\u4e8e 2 \uff09\uff0c\u7136\u540e\u628a\u62e5\u585e\u7a97\u53e3 cwnd \u91cd\u65b0\u8bbe\u7f6e\u4e3a 1\uff0c\u6267\u884c\u6162\u5f00\u59cb\u7b97\u6cd5\u3002\u8fc5\u901f\u51cf\u5c11\u4e3b\u673a\u53d1\u9001\u5230\u7f51\u7edc\u4e2d\u7684\u5206\u7ec4\u6570\uff0c\u4f7f\u5f97\u53d1\u751f\u62e5\u585e\u7684\u8def\u7531\u5668\u6709\u8db3\u591f\u7684\u65f6\u95f4\u628a\u961f\u5217\u4e2d\u79ef\u538b\u7684\u5206\u7ec4\u5904\u7406\u5b8c\u3002<\/p><p><img src=\"https:\/\/sunpe.github.io\/images\/tcp\/16.png\" alt=\"\u56fe 16 \u6162\u5f00\u59cb\u548c\u62e5\u585e\u907f\u514d\u7b97\u6cd5\"><\/p><p>\u56fe 16 \u6162\u5f00\u59cb\u548c\u62e5\u585e\u907f\u514d\u7b97\u6cd5<\/p><p>\u5982\u56fe 16 \u6240\u793a\uff0c\u5f53 TCP \u8fde\u63a5\u521d\u59cb\u5316\u65f6\uff0c\u628a\u62e5\u585e\u7a97\u53e3 cwnd \u7f6e\u4e3a 1\uff0c\u6162\u5f00\u59cb\u95e8\u9650 ssthresh \u8bbe\u7f6e\u4e3a 16\u3002\u53d1\u9001\u65b9\u6bcf\u6536\u5230\u4e00\u4e2a\u5bf9\u65b0\u62a5\u6587\u6bb5\u7684\u786e\u8ba4 ACK\uff0c\u5c31\u628a\u62e5\u585e\u7a97\u53e3\u503c\u52a0 1\uff0c\u7136\u540e\u8fdb\u884c\u4e0b\u4e00\u8f6e\u6b21\u7684\u4f20\u8f93\uff0c\u62e5\u585e\u7a97\u53e3 cwnd \u968f\u7740\u4f20\u64ad\u8f6e\u6b21\u6309\u6307\u6570\u89c4\u5219\u589e\u957f\uff08 $2^N$)\u3002\u5f53\u62e5\u585e\u7a97\u53e3 cwnd \u589e\u957f\u5230\u6162\u5f00\u59cb\u95e8\u9650 ssthresh \u65f6\uff08\u5373 cwnd=16\uff09\uff0c\u5c31\u6539\u4e3a\u6267\u884c\u62e5\u585e\u907f\u514d\u7b97\u6cd5\uff0c\u62e5\u585e\u7a97\u53e3\u6309\u7ebf\u6027\u89c4\u5f8b\u589e\u957f\u3002\u5047\u8bbe\u62e5\u585e\u7a97\u53e3 cwnd \u6570\u503c\u589e\u957f\u5230 24 \u65f6\uff0c\u7f51\u7edc\u51fa\u73b0\u8d85\u65f6\uff08\u7f51\u7edc\u53ef\u80fd\u53d1\u751f\u62e5\u585e\uff09\uff0c\u5c31\u5c06\u6162\u5f00\u59cb\u95e8\u9650 ssthresh \u66f4\u65b0\u4e3a 12 \uff08\u5373\u53d8\u4e3a\u51fa\u73b0\u62e5\u585e\u65f6\u62e5\u585e\u7a97\u53e3 cwnd \u5927\u5c0f\u7684\u4e00\u534a\uff09\uff0c\u62e5\u585e\u7a97\u53e3 cwnd \u91cd\u65b0\u8bbe\u7f6e\u4e3a 1\uff0c\u5e76\u6267\u884c\u6162\u5f00\u59cb\u7b97\u6cd5\uff0c\u5f53\u62e5\u585e\u7a97\u53e3 cwnd \u8fbe\u5230\u6162\u5f00\u59cb\u95e8\u9650 ssthresh \u65f6\uff0c\u6539\u4e3a\u62e5\u585e\u907f\u514d\u7b97\u6cd5\uff0c\u62e5\u585e\u7a97\u53e3\u7ebf\u6027\u589e\u957f\u3002<\/p><p>\u56fe 16 \u4e2d\u300c\u4e58\u6cd5\u51cf\u5c0f\u300d\u662f\u6307\u4e0d\u8bba\u5728\u6162\u5f00\u59cb\u9636\u6bb5\u8fd8\u662f\u62e5\u585e\u907f\u514d\u9636\u6bb5\uff0c\u53ea\u8981\u51fa\u73b0\u8d85\u65f6\uff08\u5373\u53ef\u80fd\u51fa\u73b0\u4e86\u7f51\u7edc\u62e5\u585e\uff09\uff0c\u5c31\u628a\u6162\u5f00\u59cb\u95e8\u9650\u503c ssthresh \u51cf\u534a\uff0c\u5373\u8bbe\u7f6e\u4e3a\u5f53\u524d\u62e5\u585e\u7a97\u53e3\u7684\u4e00\u534a\u3002\u5f53\u7f51\u7edc\u9891\u7e41\u51fa\u73b0\u62e5\u585e\u65f6\uff0cssthresh \u4e0b\u964d\u7684\u5f88\u5feb\uff0c\u5927\u5927\u51cf\u5c0f\u4e86\u6ce8\u5165\u5230\u7f51\u7edc\u4e2d\u7684\u5206\u7ec4\u6570\u3002\u300c\u52a0\u5206\u589e\u5927\u300d\u662f\u6307\u62e5\u585e\u907f\u514d\u9636\u6bb5\uff0c\u4f7f\u62e5\u585e\u7a97\u53e3\u7f13\u6162\u589e\u5927\uff0c\u4ee5\u9632\u6b62\u7f51\u7edc\u8fc7\u65e9\u51fa\u73b0\u62e5\u585e\u3002\u8fd9\u4e24\u79cd\u7b97\u6cd5\u5408\u8d77\u6765\u79f0\u4e3a AIMD \u7b97\u6cd5\uff08\u52a0\u6cd5\u589e\u5927\u4e58\u6cd5\u51cf\u5c0f\uff09\u3002<\/p><h3 id=\"\u5feb\u91cd\u4f20\u548c\u5feb\u6062\u590d\">\u5feb\u91cd\u4f20\u548c\u5feb\u6062\u590d<\/h3><p>\u5feb\u91cd\u4f20\u7b97\u6cd5\u8981\u6c42\u63a5\u6536\u65b9\u6bcf\u6536\u5230\u4e00\u4e2a\u5931\u5e8f\u7684\u62a5\u6587\u6bb5\u540e\u5c31\u7acb\u5373\u53d1\u51fa\u91cd\u590d\u786e\u8ba4\uff08\u4e3a\u4e86\u8ba9\u53d1\u9001\u65b9\u53ca\u65e9\u77e5\u9053\u6709\u62a5\u6587\u6bb5\u6ca1\u6709\u5230\u8fbe\u5bf9\u65b9\uff09\uff0c\u800c\u4e0d\u662f\u7b49\u5f85\u81ea\u5df1\u53d1\u9001\u6570\u636e\u65f6\u624d\u8fdb\u884c\u634e\u5e26\u786e\u8ba4\u3002\u5982\u56fe 17\uff0c\u63a5\u6536\u65b9\u6536\u5230 $M_1$\u548c $M_2$ \u540e\u90fd\u5206\u522b\u53d1\u51fa\u4e86\u786e\u8ba4\uff0c\u5047\u8bbe\u63a5\u6536\u65b9\u6ca1\u6536\u5230 $M_3$ \u4f46\u63a5\u7740\u6536\u5230\u4e86 $M_4$\uff0c\u56e0\u4e3a $M_4$ \u662f\u5931\u5e8f\u7684\u62a5\u6587\uff0c\u6240\u4ee5\u63a5\u6536\u65b9\u4e0d\u5bf9 $M_4$ \u8fdb\u884c\u786e\u8ba4\uff0c\u6839\u636e\u53ef\u9760\u4f20\u8f93\u539f\u7406\uff0c\u63a5\u6536\u65b9\u53ef\u4ee5\u4ec0\u4e48\u90fd\u4e0d\u505a\uff0c\u4e5f\u53ef\u4ee5\u5728\u9002\u5f53\u65f6\u673a\u53d1\u9001\u5bf9 $M_2$ \u7684\u786e\u8ba4\uff0c\u4f46\u6309\u5feb\u91cd\u4f20\u7b97\u6cd5\u7684\u89c4\u5b9a\uff0c\u63a5\u6536\u65b9\u5e94\u53ca\u65f6\u5e76\u4e14\u91cd\u590d\u7684\u53d1\u9001\u5bf9 $M_2$ \u7684\u786e\u8ba4\uff0c\u8ba9\u53d1\u9001\u65b9\u53ca\u65e9\u7684\u77e5\u9053\u62a5\u6587\u6bb5 $M_3$ \u6ca1\u6709\u5230\u8fbe\u63a5\u6536\u65b9\u3002\u53d1\u9001\u65b9\u63a5\u7740\u4f20\u9001 $M_5$ \u548c $M_6$\uff0c\u63a5\u6536\u65b9\u4f9d\u7136\u518d\u6b21\u53d1\u9001\u5bf9 $M_2$ \u7684\u786e\u8ba4\uff0c\u8fd9\u6837\u63a5\u6536\u65b9\u603b\u5171\u63a5\u5230\u4e86\u56db\u4e2a\u5bf9 $M_2$ \u7684\u786e\u8ba4\uff0c\u5176\u4e2d\u540e\u9762\u4e09\u4e2a\u90fd\u662f\u91cd\u590d\u7684\u3002\u5feb\u91cd\u4f20\u7b97\u6cd5\u89c4\u5b9a\uff0c\u53d1\u9001\u65b9\u53ea\u8981\u4e00\u8fde\u6536\u5230\u4e09\u4e2a\u91cd\u590d\u786e\u8ba4\u5c31\u5e94\u5f53\u7acb\u5373\u4f20\u9001\u5bf9\u65b9\u5c1a\u672a\u6536\u5230\u7684\u62a5\u6587\u6bb5 $M_3$\uff0c\u800c\u4e0d\u5fc5\u7b49\u5f85\u4e3a $M_3$ \u8bbe\u7f6e\u7684\u91cd\u4f20\u8ba1\u6570\u5668\u5230\u671f\u3002\u7531\u4e8e\u53d1\u9001\u65b9\u80fd\u591f\u53ca\u65e9\u7684\u91cd\u4f20\u672a\u88ab\u786e\u8ba4\u7684\u62a5\u6587\u6bb5\uff0c\u56e0\u6b64\u91c7\u7528\u5feb\u91cd\u4f20\u540e\u53ef\u4ee5\u662f\u6574\u4e2a\u7f51\u7edc\u541e\u5410\u91cf\u63d0\u9ad8\u7ea6 20%\u3002<\/p><p><img src=\"https:\/\/sunpe.github.io\/images\/tcp\/17.png\" alt=\"\u56fe 17 \u5feb\u91cd\u4f20\u793a\u610f\u56fe\"><\/p><p>\u56fe 17 \u5feb\u91cd\u4f20\u793a\u610f\u56fe<\/p><p>\u4e0e\u5feb\u91cd\u4f20\u7b97\u6cd5\u914d\u5408\u7684\u8fd8\u6709\u5feb\u6062\u590d\u7b97\u6cd5\uff0c\u5f53\u53d1\u9001\u65b9\u8fde\u7eed\u6536\u5230\u4e09\u4e2a\u91cd\u590d\u786e\u8ba4\u65f6\uff0c\u5c31\u6267\u884c\u300c\u4e58\u6cd5\u51cf\u5c0f\u300d\u7b97\u6cd5\uff0c\u628a\u6162\u5f00\u59cb\u95e8\u9650 ssthresh \u51cf\u534a\uff0c\u4ee5\u9632\u7f51\u7edc\u62e5\u585e\uff0c\u53d1\u9001\u65b9\u8ba4\u4e3a\u7f51\u7edc\u53ef\u80fd\u6ca1\u6709\u53d1\u751f\u62e5\u585e\uff08\u5982\u679c\u7f51\u7edc\u53d1\u751f\u62e5\u585e\uff0c\u5c31\u4e0d\u4f1a\u4e00\u8fde\u6709\u597d\u51e0\u4e2a\u62a5\u6587\u6bb5\u8fde\u7eed\u7684\u5230\u8fbe\u63a5\u6536\u65b9\uff0c\u4e5f\u5c31\u4e0d\u4f1a\u5bfc\u81f4\u63a5\u6536\u65b9\u8fde\u7eed\u53d1\u9001\u91cd\u590d\u786e\u8ba4\uff09\uff0c\u8fd9\u662f\u4e0d\u6267\u884c\u6162\u5f00\u59cb\u7b97\u6cd5\uff08\u5373\u62e5\u585e\u7a97\u53e3 cwnd \u4e0d\u8bbe\u7f6e\u4e3a 1 \uff09\uff0c\u800c\u662f\u628a cwnd \u503c\u8bbe\u7f6e\u4e3a\u6162\u5f00\u59cb\u95e8\u9650 ssthresh \u51cf\u534a\u540e\u7684\u503c\uff0c\u7136\u540e\u5f00\u59cb\u6267\u884c\u62e5\u585e\u907f\u514d\u7b97\u6cd5\uff08\u52a0\u6cd5\u589e\u5927\uff09\uff0c\u4f7f\u62e5\u585e\u7a97\u53e3\u7f13\u6162\u7684\u7ebf\u6027\u589e\u5927\u3002<\/p><p><img src=\"https:\/\/sunpe.github.io\/images\/tcp\/18.png\" alt=\"\u56fe 18 \u8fde\u7eed\u6536\u5230\u4e09\u4e2a\u91cd\u590d\u786e\u8ba4\u540e\u8f6c\u5165\u62e5\u585e\u907f\u514d\"><\/p><p>\u56fe 18 \u8fde\u7eed\u6536\u5230\u4e09\u4e2a\u91cd\u590d\u786e\u8ba4\u540e\u8f6c\u5165\u62e5\u585e\u907f\u514d<\/p><p>\u5982\u56fe 18 \u6240\u793a\uff0c\u300cTCP Reno \u7248\u672c\u300d\uff08\u5feb\u56de\u590d\u548c\u5feb\u91cd\u4f20\u7b97\u6cd5\uff09\u662f\u76ee\u524d\u5e7f\u6cdb\u4f7f\u7528\u7684\u7248\u672c\uff0c\u300cTCP Tahoe \u7248\u672c\u300d\uff08\u6162\u5f00\u59cb\u7b97\u6cd5\uff09\u5df2\u5e9f\u5f03\u4e0d\u7528\uff0c\u4e8c\u8005\u7684\u533a\u522b\u662f TCP Reno \u7248\u672c\u5728\u5feb\u91cd\u4f20\u4e4b\u540e\u91c7\u7528\u5feb\u6062\u590d\u7b97\u6cd5\uff0c\u800c\u4e0d\u662f\u6162\u5f00\u59cb\u7b97\u6cd5\u3002<\/p><p>\u4e5f\u6709\u5feb\u91cd\u4f20\u5b9e\u73b0\u662f\u5c06\u5f00\u59cb\u65f6\u7684\u62e5\u585e\u7a97\u53e3 cwnd \u503c\u518d\u589e\u5927\u4e00\u4e9b\uff08\u589e\u52a0 3 \u4e2a\u62a5\u6587\u6bb5\u957f\u5ea6\uff09\uff0c\u5373 cwnd = ssthresh + 3 * MSS\u3002\u539f\u56e0\u662f\u65e2\u7136\u53d1\u9001\u65b9\u6536\u5230\u4e09\u4e2a\u91cd\u590d\u7684\u786e\u8ba4\uff0c\u5c31\u8868\u660e\u6709\u4e09\u4e2a\u5206\u7ec4\u5df2\u7ecf\u79bb\u5f00\u7f51\u7edc\uff0c\u8fd9\u4e09\u4e2a\u5206\u7ec4\u505c\u7559\u5728\u63a5\u6536\u65b9\u7684\u7f13\u5b58\u4e2d\uff0c\u4e0d\u518d\u6d88\u8017\u7f51\u7edc\u8d44\u6e90\uff0c\u56e0\u6b64\u53ef\u4ee5\u9002\u5f53\u7684\u628a\u7a97\u53e3\u589e\u5927\u4e00\u4e9b\u3002<\/p><p>\u91c7\u7528\u5feb\u6062\u590d\u7b97\u6cd5\u65f6\uff0c\u6162\u5f00\u59cb\u7b97\u6cd5\u53ea\u662f\u5728 TCP \u8fde\u63a5\u5efa\u7acb\u65f6\u548c\u7f51\u7edc\u51fa\u73b0\u8d85\u65f6\u7684\u65f6\u5019\u624d\u4f7f\u7528\u3002<\/p><p>\u63a5\u6536\u65b9\u7684\u7f13\u5b58\u540c\u6837\u662f\u6709\u9650\u7684\uff0c\u63a5\u6536\u65b9\u6839\u636e\u81ea\u5df1\u7684\u63a5\u6536\u80fd\u529b\u8bbe\u7f6e\u63a5\u6536\u7a97\u53e3 rwnd\uff0c\u5e76\u5c06\u7a97\u53e3\u503c\u5199\u5165 TCP \u9996\u90e8\uff0c\u4f20\u9001\u7ed9\u53d1\u9001\u65b9\uff0c\u53d1\u9001\u65b9\u7684\u53d1\u9001\u7a97\u53e3 cwnd \u4e00\u5b9a\u4e0d\u80fd\u8d85\u8fc7\u63a5\u6536\u65b9\u7ed9\u7684\u63a5\u6536\u7a97\u53e3\u7684\u503c rwnd\u3002<\/p><h3 id=\"\u968f\u673a\u65e9\u671f\u68c0\u6d4b-red\">\u968f\u673a\u65e9\u671f\u68c0\u6d4b RED<\/h3><p>\u5f53\u8def\u7531\u5668\u5bf9\u5206\u7ec4\u5904\u7406\u65f6\u95f4\u7279\u522b\u957f\uff0c\u90a3\u4e48\u5c31\u53ef\u80fd\u4f7f\u8fd9\u4e9b\u5206\u7ec4\u7ecf\u8fc7\u5f88\u957f\u65f6\u95f4\u624d\u80fd\u5230\u8fbe\u7ec8\u70b9\uff0c\u7ed3\u679c\u5f15\u8d77\u53d1\u9001\u65b9\u5bf9\u8fd9\u4e9b\u62a5\u6587\u7684\u91cd\u4f20\u3002\u91cd\u4f20\u4f1a\u5f15\u8d77 TCP \u53d1\u9001\u7aef\u8ba4\u4e3a\u7f51\u7edc\u51fa\u73b0\u62e5\u585e\uff0c\u4e8e\u662f TCP \u53d1\u9001\u7aef\u5c31\u91c7\u53d6\u4e86\u62e5\u585e\u63a7\u5236\u63aa\u65bd\uff0c\u4f46\u5b9e\u9645\u7f51\u7edc\u5e76\u672a\u62e5\u585e\u3002\u7f51\u7edc\u5c42\u5bf9 TCP \u62e5\u585e\u63a7\u5236\u5f71\u54cd\u6700\u5927\u7684\u5c31\u662f\u8def\u7531\u5668\u7684\u5206\u7ec4\u4e22\u5f03\u7b56\u7565\u3002\u8def\u7531\u5668\u901a\u5e38\u6309\u7167\u300c\u5148\u8fdb\u5148\u51fa\u300d\u7684\u7b56\u7565\u5904\u7406\u5230\u8fbe\u7684\u5206\u7ec4\uff0c\u7531\u4e8e\u961f\u5217\u957f\u5ea6\u6709\u9650\uff0c\u56e0\u6b64\u5f53\u961f\u5217\u6ee1\u4e86\u4e4b\u540e\uff0c\u518d\u5230\u8fbe\u7684\u5206\u7ec4\u90fd\u5c06\u88ab\u4e22\u5f03\uff0c\u8fd9\u5c31\u662f\u300c\u5c3e\u90e8\u4e22\u5f03\u7b56\u7565\u300d\u3002<\/p><p>\u8def\u7531\u5668\u7684\u5c3e\u90e8\u4e22\u5f03\u5f80\u5f80\u5bfc\u81f4\u4e00\u8fde\u4e32\u7684\u5206\u7ec4\u4e22\u5931\uff0c\u4f7f\u53d1\u9001\u65b9\u51fa\u73b0\u8d85\u65f6\u91cd\u4f20\uff0c\u4f7f TCP \u8fdb\u5165\u62e5\u585e\u63a7\u5236\uff0c\u7ed3\u679c TCP \u53d1\u9001\u65b9\u7a81\u7136\u628a\u6570\u636e\u53d1\u9001\u901f\u7387\u964d\u4f4e\u5230\u5f88\u5c0f\u7684\u6570\u503c\u3002\u66f4\u4e25\u91cd\u7684\u662f\uff0c\u7f51\u7edc\u4e2d\u901a\u5e38\u6709\u5f88\u591a TCP \u8fde\u63a5\uff0c\u8fd9\u79cd\u60c5\u51b5\u4e0b\u5982\u679c\u53d1\u751f\u8def\u7531\u5668\u5c3e\u90e8\u4e22\u5f03\uff0c\u5c31\u53ef\u80fd\u4f1a\u540c\u65f6\u5f71\u54cd\u5230\u5f88\u591a\u6761 TCP \u8fde\u63a5\uff0c\u4f7f\u8bb8\u591a TCP \u8fde\u63a5\u5728\u540c\u4e00\u65f6\u95f4\u7a81\u7136\u5f00\u59cb\u62e5\u585e\u63a7\u5236\uff0c\u8fd9\u53eb\u300c\u5168\u5c40\u540c\u6b65\u300d\uff0c\u4f7f\u5168\u7f51\u901a\u4fe1\u91cf\u7a81\u7136\u4e0b\u964d\u5f88\u591a\uff0c\u800c\u5728\u7f51\u7edc\u6062\u590d\u540e\uff0c\u901a\u4fe1\u91cf\u6709\u7a81\u7136\u589e\u5927\u5f88\u591a\u3002<\/p><p>\u4e3a\u4e86\u907f\u514d\u53d1\u751f\u5168\u5c40\u540c\u6b65\uff0c\u53ef\u4ee5\u5728\u8def\u7531\u5668\u91c7\u53d6\u300c\u968f\u673a\u65e9\u671f\u68c0\u6d4b\u300d\uff08RED Random \uff09\u63aa\u65bd\u3002\u8def\u7531\u5668\u961f\u5217\u7ef4\u62a4\u4e24\u4e2a\u53c2\u6570\uff0c\u961f\u5217\u957f\u5ea6\u6700\u5c0f\u95e8\u9650 $TH_{min}$ \u548c\u6700\u5927\u95e8\u9650 $TH_{max}$\u3002\u5206\u7ec4\u5230\u8fbe\u65f6\uff0c\u5148\u8ba1\u7b97\u5e73\u5747\u961f\u5217\u957f\u5ea6 $L_{AV}$\uff0c\u82e5\u5e73\u5747\u961f\u5217\u957f\u5ea6\u5c0f\u4e8e\u6700\u5c0f\u95e8\u9650 $TH_{min}$\uff0c\u5219\u628a\u5206\u7ec4\u653e\u5165\u961f\u5217\uff1b\u82e5\u5e73\u5747\u961f\u5217\u957f\u5ea6\u8d85\u8fc7\u6700\u5927\u95e8\u9650 $TH_{max}$\uff0c\u5219\u4e22\u5f03\u5206\u7ec4\uff0c\u82e5\u5e73\u5747\u961f\u5217\u957f\u5ea6\u4ecb\u4e8e\u6700\u5c0f\u95e8\u9650 $TH_{min}$ \u548c\u6700\u5927\u95e8\u9650 $TH_{max}$\uff0c\u5219\u6309\u67d0\u4e00\u6982\u7387 p \u5c06\u5206\u7ec4\u4e22\u5f03\u3002<\/p><p><img src=\"https:\/\/sunpe.github.io\/images\/tcp\/19.png\" alt=\"\u56fe 19 RED \u7b97\u6cd5\u628a\u8def\u7531\u5668\u7684\u5230\u8fbe\u961f\u5217\u5212\u5206\u6210\u4e09\u4e2a\u533a\u57df\"><\/p><p>\u56fe 19 RED \u7b97\u6cd5\u628a\u8def\u7531\u5668\u7684\u5230\u8fbe\u961f\u5217\u5212\u5206\u6210\u4e09\u4e2a\u533a\u57df<\/p><p>\u968f\u673a\u65e9\u671f\u68c0\u6d4b RED \u4e0d\u662f\u7b49\u5df2\u53d1\u751f\u7f51\u7edc\u62e5\u585e\u624d\u628a\u961f\u5217\u5c3e\u7684\u5206\u7ec4\u5168\u90e8\u4e22\u5f03\uff0c\u800c\u662f\u5728\u68c0\u6d4b\u5230\u7f51\u7edc\u62e5\u585e\u7684\u65e9\u671f\u5f81\u5146\u65f6\uff08\u5373\u8def\u7531\u5668\u7684\u5e73\u5747\u961f\u5217\u957f\u5ea6\u8d85\u8fc7\u4e00\u5b9a\u95e8\u9650\u503c\uff09\uff0c\u5c31\u5148\u4ee5\u6982\u7387 p \u968f\u673a\u4e22\u5f03\u4e2a\u522b\u5206\u7ec4\uff0c\u8ba9\u62e5\u585e\u63a7\u5236\u53ea\u5728\u4e2a\u522b TCP \u8fde\u63a5\u4e0a\u8fdb\u884c\uff0c\u4ece\u800c\u907f\u514d\u5168\u5c40\u6027\u7684\u62e5\u585e\u63a7\u5236\u3002<\/p><p>\u968f\u673a\u65e9\u671f\u68c0\u6d4b RED \u7b97\u6cd5\u6b63\u5e38\u5de5\u4f5c\u7684\u5173\u952e\u662f\u8981\u9009\u62e9\u597d\u4e09\u4e2a\u53c2\u6570\uff1a\u6700\u5c0f\u95e8\u9650 $TH_{min}$\u3001\u6700\u5927\u95e8\u9650 $TH_{max}$ \u548c\u6982\u7387 p\u3002\u6700\u5c0f\u95e8\u9650 $TH_{min}$ \u5fc5\u987b\u8db3\u591f\u5927\uff0c\u4ee5\u4fdd\u8bc1\u8def\u7531\u5668\u7684\u8f93\u51fa\u94fe\u8def\u6709\u8f83\u9ad8\u7684\u5229\u7528\u7387\uff0c\u6700\u5c0f\u95e8\u9650 $TH_{min}$ \u548c\u6700\u5927\u95e8\u9650 $TH_{max}$ \u4e4b\u95f4\u7684\u5dee\u503c\u4e5f\u5e94\u5f53\u8db3\u591f\u5927\uff0c\u4f7f\u5f97\u5728\u4e00\u4e2a TCP \u5f80\u8fd4\u65f6\u95f4 RTT \u4e2d\u961f\u5217\u7684\u6b63\u5e38\u589e\u957f\u4ecd\u5728\u6700\u5927\u95e8\u9650 $TH_{max}$ \u5185\u3002\u901a\u8fc7\u6700\u5927\u95e8\u9650 $TH_{max}$ \u7b49\u4e8e\u6700\u5c0f\u95e8\u9650 $TH_{min}$ \u7684\u4e24\u500d\u662f\u5408\u9002\u7684\u3002\u5982\u679c\u95e8\u9650\u503c\u8bbe\u7f6e\u7684\u4e0d\u5408\u9002\uff0cRED \u4e5f\u53ef\u80fd\u4f1a\u5f15\u8d77\u7c7b\u4f3c\u4e8e\u5c3e\u90e8\u4e22\u5f03\u90a3\u6837\u7684\u5168\u5c40\u632f\u8361\u3002<\/p><p>RED \u4e2d\u6700\u590d\u6742\u7684\u5c31\u662f\u4e22\u5f03\u6982\u7387 p \u7684\u9009\u62e9\uff0cp \u4e0d\u662f\u5e38\u6570\uff0c\u5bf9\u4e8e\u6bcf\u4e2a\u65b0\u5230\u8fbe\u7684\u5206\u7ec4\uff0c\u90fd\u5fc5\u987b\u8ba1\u7b97\u4e22\u5f03\u6982\u7387 p\uff0cp \u53d6\u51b3\u4e8e\u5f53\u524d\u7684\u5e73\u5747\u961f\u5217\u957f\u5ea6 $L_{AV}$ \u548c\u6240\u8bbe\u5b9a\u7684\u4e24\u4e2a\u95e8\u9650\u503c $TH_{min}$ \u548c $TH_{max}$\u3002\u5f53\u5e73\u5747\u961f\u5217\u957f\u5ea6 $L_{AV}$ \u5c0f\u4e8e\u6700\u5c0f\u95e8\u9650\u503c $TH_{min}$ \u65f6\uff0c\u4e22\u5f03\u6982\u7387 p = 0\uff1b\u5f53\u5e73\u5747\u961f\u5217\u957f\u5ea6 $L_{AV}$ \u5927\u4e8e\u6700\u5927\u95e8\u9650\u503c $TH_{max}$ \u65f6\uff0c\u4e22\u5f03\u6982\u7387 p = 1\uff1b\u5f53\u5e73\u5747\u961f\u5217\u957f\u5ea6 $L_{AV}$ \u5728 $TH_{min}$ \u548c $TH_{max}$ \u4e4b\u95f4\u65f6\uff0c\u5206\u7ec4\u4e22\u5f03\u6982\u7387 p \u5728 0 \u5230 1 \u4e4b\u95f4\u3002<\/p><p><img src=\"https:\/\/sunpe.github.io\/images\/tcp\/20.png\" alt=\"\u56fe 20 \u5206\u7ec4\u4e22\u5f03\u6982\u7387 p \u548c\u4e24\u4e2a\u95e8\u9650\u503c $TH_{min}$ \u548c $TH_{max}$ \u7684\u5173\u7cfb\"><\/p><p>\u56fe 20 \u5206\u7ec4\u4e22\u5f03\u6982\u7387 p \u548c\u4e24\u4e2a\u95e8\u9650\u503c $TH_{min}$ \u548c $TH_{max}$ \u7684\u5173\u7cfb<\/p><p>\u7531\u4e8e\u8ba1\u7b97\u673a\u6570\u636e\u5177\u6709\u7a81\u53d1\u6027\u7684\u7279\u70b9\uff0c\u8def\u7531\u5668\u4e2d\u961f\u5217\u957f\u5ea6\u7ecf\u5e38\u4f1a\u51fa\u73b0\u5f88\u5feb\u7684\u8d77\u4f0f\u53d8\u5316\uff0c\u5982\u679c\u4ec5\u56e0\u4e3a\u77ac\u65f6\u961f\u5217\u957f\u5ea6\u8d85\u8fc7\u4e86\u6700\u5c0f\u95e8\u9650\u503c $TH_{min}$ \u5c31\u4e22\u5f03\u5206\u7ec4\u4f1a\u4ea7\u751f\u4e0d\u5fc5\u8981\u7684\u62e5\u585e\u63a7\u5236\uff0c\u56e0\u6b64 RED \u91c7\u7528\u52a0\u6743\u5e73\u5747\u7684\u65b9\u6cd5\u8ba1\u7b97\u5e73\u5747\u961f\u5217\u957f\u5ea6 $L_{AV}$\u3002<\/p><p><img src=\"https:\/\/sunpe.github.io\/images\/tcp\/21.png\" alt=\"\u56fe 21 \u77ac\u65f6\u961f\u5217\u957f\u5ea6\u548c\u5e73\u5747\u961f\u5217\u957f\u5ea6\u7684\u533a\u522b\"><\/p><p>\u56fe 21 \u77ac\u65f6\u961f\u5217\u957f\u5ea6\u548c\u5e73\u5747\u961f\u5217\u957f\u5ea6\u7684\u533a\u522b<\/p><p>$\u5e73\u5747\u961f\u5217\u957f\u5ea6 L_{AV} = ( 1 - \\delta ) * (\u65e7L_{AV}) + \\delta * (\u5f53\u524d\u961f\u5217\u957f\u5ea6)$\u3002\u516c\u5f0f\u4e2d $\\delta$ \u662f\u5728 0 \u5230 1 \u4e4b\u95f4\u7684\u6570\uff0c\u5982\u679c $\\delta$ \u8db3\u591f\u5c0f\uff0c\u90a3\u4e48\u5e73\u5747\u961f\u5217\u957f\u5ea6 $L_{AV}$ \u53d6\u51b3\u4e8e\u961f\u5217\u957f\u5ea6\u7684\u957f\u671f\u53d8\u5316\u8d8b\u52bf\uff0c\u800c\u4e0d\u53d7\u77ac\u65f6\u7a81\u53d1\u6570\u636e\u7684\u5f71\u54cd\u3002<\/p><p>\u5206\u7ec4\u4e22\u5f03\u6982\u7387 $p = p_{temp} \/ (1 - count * p_{temp})$\u3002count \u662f\u5e38\u91cf\uff0c\u4ee3\u8868\u65b0\u5230\u8fbe\u7684\u5206\u7ec4\u6709\u591a\u5c11\u4e2a\u5df2\u7ecf\u8fdb\u5165\u5230\u4e86\u961f\u5217\uff08\u6ca1\u6709\u88ab\u4e22\u5f03\uff09\uff1b$p_{temp}$ \u662f\u8fc7\u6e21\u7684\u5206\u7ec4\u4e22\u5f03\u6982\u7387\uff0c$p_{temp} = p_{max} * (L_{AV} - TH_{min})\/(TH_{max} - TH_{min})$\u3002<\/p><p>\u5047\u8bbe $p_{max} = 0.02$\uff0ccount \u521d\u59cb\u503c\u662f 0\uff0c\u5047\u8bbe\u5e73\u5747\u961f\u5217\u957f\u5ea6 $L_{AV}$\u5728\u4e24\u4e2a\u95e8\u9650\u4e4b\u95f4\uff0c\u7b97\u51fa\u8fc7\u6e21\u7684\u5206\u7ec4\u4e22\u5f03\u6982\u7387 $p_{temp}$ = 0.01\uff0c\u7531\u4e8ecount = 0\uff0c\u6240\u4ee5 $p=p_{temp}=0.01$\uff0c\u4e5f\u5c31\u662f\u8bf4\u73b0\u5728\u5230\u8fbe\u7684\u5206\u7ec4\u8fdb\u5165\u8def\u7531\u5668\u961f\u5217\u6982\u7387\u662f0.99\uff0c\u968f\u7740\u5206\u7ec4\u7684\u4e0d\u65ad\u5230\u8fbe\uff0ccount\u4e0d\u65ad\u589e\u5927\uff0c\u5206\u7ec4\u4e22\u5f03\u6982\u7387\u4e5f\u9010\u6e10\u589e\u5927\u3002\u5047\u8bbe\u4e00\u8fde\u6709 50 \u4e2a\u5206\u7ec4\u8fdb\u5165\u961f\u5217\u800c\u6ca1\u6709\u88ab\u4e22\u5f03\uff0c\u8fd9\u65f6\u5206\u7ec4\u4e22\u5f03\u6982\u7387\u589e\u5927\u4e00\u500d\uff0c\u5373 $p=0.02$\u3002\u518d\u5047\u8bbe\u4e00\u8fde\u670999 \u4e2a\u5206\u7ec4\u8fdb\u5165\u961f\u5217\u800c\u6ca1\u6709\u88ab\u4e22\u5f03\uff0c\u90a3\u4e48\u5206\u7ec4\u4e22\u5f03\u6982\u7387 $p = 1$\uff08\u8bbe\u5e73\u5747\u961f\u5217\u957f\u5ea6\u4e00\u76f4\u4e0d\u53d8\uff09\uff0c\u4e0b\u4e00\u4e2a\u5206\u7ec4\u4e00\u5b9a\u4f1a\u88ab\u4e22\u5f03\u3002\u5206\u7ec4\u4e22\u5f03\u6982\u7387 p \u4e0d\u4ec5\u4e0e\u5e73\u5747\u961f\u5217\u957f\u5ea6\u6709\u5173\uff0c\u8fd8\u968f\u7740\u961f\u5217\u4e2d\u4e0d\u88ab\u4e22\u5f03\u7684\u5206\u7ec4\u6570\u76ee\u7684\u589e\u591a\u800c\u9010\u6e10\u589e\u5927\uff0c\u5c31\u53ef\u4ee5\u907f\u514d\u5206\u7ec4\u4e22\u5f03\u7684\u8fc7\u4e8e\u96c6\u4e2d\u3002<\/p><p>\u603b\u4e4b\uff0c\u968f\u673a\u65e9\u671f\u68c0\u6d4b RED \u597d\u5904\u5c31\u662f\u5f53\u5e73\u5747\u961f\u5217\u957f\u5ea6\u8d85\u8fc7\u95e8\u9650\u503c $TH_{min}$\u65f6\uff0c\u5c31\u4f1a\u6709\u5c11\u91cf\u7684\u5206\u7ec4\u88ab\u4e22\u5f03\uff0c\u4f7f\u5f97\u5c11\u91cf\u7684 TCP \u8fde\u63a5\u4f1a\u51cf\u5c0f\u7a97\u53e3\u503c\uff0c\u4f7f\u5f97\u5230\u8fbe\u8def\u7531\u5668\u5206\u7ec4\u7684\u6570\u91cf\u51cf\u5c11\uff0c\u4ece\u800c\u5e73\u5747\u961f\u5217\u957f\u5ea6\u51cf\u5c11\u4e86\uff0c\u907f\u514d\u4e86\u7f51\u7edc\u62e5\u585e\u3002\u9700\u8981\u6ce8\u610f\uff0c\u8def\u7531\u5668\u5728\u67d0\u4e00\u65f6\u523b\u7684\u77ac\u65f6\u961f\u5217\u957f\u5ea6\u5b8c\u5168\u6709\u53ef\u80fd\u8d85\u8fc7\u5e73\u5747\u961f\u5217\u957f\u5ea6\uff0c\u91c7\u7528\u968f\u673a\u65e9\u671f\u68c0\u6d4b RED \u7b97\u6cd5\u4e22\u5f03\u6982\u7387\u5f88\u5c0f\uff0c\u4f46\u8def\u7531\u5668\u961f\u5217\u5df2\u7ecf\u6ca1\u6709\u7a7a\u95f4\u63a5\u7eb3\u65b0\u5230\u7684\u5206\u7ec4\uff0c\u90a3\u4e48 RED \u7684\u64cd\u4f5c\u548c\u300c\u5c3e\u90e8\u4e22\u5f03\u300d\u65b9\u5f0f\u4e00\u6837\uff0cRED \u4ec5\u5728\u53ef\u80fd\u7684\u6761\u4ef6\u4e0b\u5c3d\u91cf\u4f7f\u300c\u5c3e\u90e8\u4e22\u5f03\u300d\u4e0d\u8981\u53d1\u751f\u3002<\/p><h2 id=\"tcp-\u8fde\u63a5\u7ba1\u7406\">TCP \u8fde\u63a5\u7ba1\u7406<\/h2><h3 id=\"\u4e09\u6b21\u63e1\u624b\">\u4e09\u6b21\u63e1\u624b<\/h3><p>TCP \u8fde\u63a5\u5efa\u7acb\u7684\u8fc7\u7a0b\u4e2d\u8981\u89e3\u51b3\u4e09\u4e2a\u95ee\u9898\uff1a<\/p><ul><li>\u6bcf\u4e00\u65b9\u90fd\u80fd\u786e\u77e5\u5bf9\u65b9\u7684\u5b58\u5728<\/li><li>\u5141\u8bb8\u53cc\u65b9\u534f\u5546\u4e00\u4e9b\u53c2\u6570\uff08\u6700\u5927\u7a97\u53e3\u503c\u3001\u662f\u5426\u4f7f\u7528\u7a97\u53e3\u6269\u5927\u9009\u9879\u548c\u65f6\u95f4\u6233\u9009\u9879\u4ee5\u53ca\u670d\u52a1\u8d28\u91cf\u7b49\uff09<\/li><li>\u80fd\u591f\u5bf9\u8fd0\u8f93\u5b9e\u4f53\u8d44\u6e90\uff08\u7f13\u5b58\u5927\u5c0f\u3001\u8fde\u63a5\u8868\u4e2d\u7684\u9879\u76ee\u7b49\uff09\u8fdb\u884c\u5206\u914d<\/li><\/ul><p>TCP \u91c7\u7528\u5ba2\u6237\u7aef\/\u670d\u52a1\u5668\u6a21\u5f0f\uff0c\u4e3b\u52a8\u53d1\u8d77\u8fde\u63a5\u5efa\u7acb\u7684\u5e94\u7528\u8fdb\u7a0b\u53eb\u300c\u5ba2\u6237\u300d\uff0c\u88ab\u52a8\u7b49\u5f85\u8fde\u63a5\u5efa\u7acb\u7684\u5e94\u7528\u53eb\u300c\u670d\u52a1\u5668\u300d\u3002<\/p><p><img src=\"https:\/\/sunpe.github.io\/images\/tcp\/22.png\" alt=\"\u56fe 22 \u4f7f\u7528\u4e09\u6b21\u63e1\u624b\u5efa\u7acb TCP \u8fde\u63a5\"><\/p><p>\u56fe 22 \u4f7f\u7528\u4e09\u6b21\u63e1\u624b\u5efa\u7acb TCP \u8fde\u63a5<\/p><p>\u56fe 22 \u5c55\u793a\u4e86 TCP \u5efa\u7acb\u8fde\u63a5\u7684\u8fc7\u7a0b\uff0cA \u662f\u5ba2\u6237\uff0cB\u662f\u670d\u52a1\u5668\uff0c\u6700\u521d\u4e24\u7aef\u7684 TCP \u8fdb\u7a0b\u90fd\u5904\u4e8e CLOSED \u72b6\u6001\u3002B \u7684 TCP \u670d\u52a1\u5668\u8fdb\u7a0b\u5148\u521b\u5efa\u300c\u4f20\u8f93\u63a7\u5236\u5757\u300dTCB\uff0cTCB \u4e2d\u5b58\u50a8\u7740\u8fde\u63a5\u7684\u4e00\u4e9b\u91cd\u8981\u4fe1\u606f\uff0c\u6bd4\u5982 TCP \u8fde\u63a5\u8868\u3001\u5230\u53d1\u9001\u548c\u63a5\u6536\u7f13\u5b58\u7684\u6307\u9488\u3001\u5230\u91cd\u4f20\u961f\u5217\u7684\u6307\u9488\u3001\u5f53\u524d\u53d1\u9001\u548c\u63a5\u6536\u7684\u5e8f\u5217\u53f7\u7b49\u7b49\u3002\u4e4b\u540e\u670d\u52a1\u5668\u5c31\u5904\u4e8e LISTEN\uff08\u6536\u542c\uff09 \u72b6\u6001\uff0c\u7b49\u5f85\u5ba2\u6237\u7684\u8fde\u63a5\u8bf7\u6c42\u3002<\/p><p>A \u7684 TCP \u5ba2\u6237\u8fdb\u7a0b\u4e5f\u662f\u5148\u521b\u5efa\u4f20\u8f93\u63a7\u5236\u5757 TCB\uff0c\u7136\u540e\u5411 B \u53d1\u51fa\u8fde\u63a5\u8bf7\u6c42\u5b57\u6bb5\uff0c\u9996\u90e8\u7684\u540c\u6b65\u4f4d SYN = 1\uff0c\u540c\u65f6\u9009\u62e9\u4e00\u4e2a\u521d\u59cb\u5e8f\u5217\u53f7 seq = x\u3002TCP \u89c4\u5b9a\uff0cSYN \u62a5\u6587\u6bb5\u4e0d\u80fd\u643a\u5e26\u6570\u636e\uff0c\u4f46\u8981\u6d88\u8017\u6389\u4e00\u4e2a\u5e8f\u53f7\u3002\u8fd9\u65f6 A \u7684\u5ba2\u6237\u8fdb\u7a0b\u8fdb\u5165 SYN-SENT\uff08\u540c\u6b65\u5df2\u53d1\u9001\uff09\u72b6\u6001\u3002<\/p><p>B \u6536\u5230\u5ba2\u6237\u7684\u8fde\u63a5\u8bf7\u6c42\u540e\uff0c\u5982\u679c\u540c\u610f\u5efa\u7acb\u8fde\u63a5\uff0c\u5219\u5411 A \u53d1\u9001\u786e\u8ba4\uff0c\u786e\u8ba4\u62a5\u6587\u6bb5\u4e2d SYN \u548c ACK \u90fd\u7f6e\u4e3a 1\uff0c\u786e\u8ba4\u53f7 ack = x + 1\uff0c\u540c\u65f6\u4e5f\u4e3a\u81ea\u5df1\u9009\u62e9\u4e00\u4e2a\u5e8f\u5217\u53f7 seq = y\u3002\u8fd9\u4e2a\u62a5\u6587\u6bb5\u4e5f\u4e0d\u80fd\u643a\u5e26\u6570\u636e\uff0c\u540c\u610f\u8981\u6d88\u8017\u6389\u4e00\u4e2a\u5e8f\u5217\u53f7\u3002\u8fd9\u65f6 B \u7684\u670d\u52a1\u5668\u8fdb\u7a0b\u8fdb\u5165 SYN-RCVD\uff08\u540c\u6b65\u5df2\u6536\u5230\uff09\u72b6\u6001\u3002<\/p><p>A \u5ba2\u6237\u8fdb\u7a0b\u6536\u5230 B \u7684\u786e\u8ba4\u540e\uff0c\u8fd8\u8981\u5411 B \u7ed9\u51fa\u786e\u8ba4\uff0c\u786e\u8ba4\u62a5\u6587\u6bb5 ACK \u7f6e\u4e3a 1\uff0c\u786e\u8ba4\u53f7 ack = y + 1\uff0c\u81ea\u5df1\u7684\u5e8f\u5217\u53f7 seq = x + 1\u3002TCP \u89c4\u5b9a\uff0cACK \u62a5\u6587\u53ef\u4ee5\u643a\u5e26\u6570\u636e\uff0c\u5982\u679c\u4e0d\u643a\u5e26\u6570\u636e\u5219\u4e0d\u6d88\u8017\u5e8f\u5217\u53f7\uff0c\u4e0b\u4e00\u4e2a\u62a5\u6587\u6bb5\u7684\u5e8f\u5217\u53f7\u4ecd\u7136\u662f seq = x + 1\u3002\u8fd9\u65f6 TCP \u8fde\u63a5\u5df2\u7ecf\u5efa\u7acb\uff0cA \u8fdb\u5165 ESTABLISH\uff08\u5df2\u5efa\u7acb\u8fde\u63a5\uff09\u72b6\u6001\uff0c\u5f53 B \u6536\u5230 A \u7684\u786e\u8ba4\u4e4b\u540e\u4e5f\u8fdb\u53bb ESTABLISH\uff08\u5df2\u5efa\u7acb\u8fde\u63a5\uff09\u72b6\u6001\u3002<\/p><p>\u4e3a\u4ec0\u4e48 A \u8fd8\u8981\u518d\u53d1\u9001\u4e00\u6b21\u786e\u8ba4\u5462\uff1f\u4e3b\u8981\u662f\u4e3a\u4e86\u9632\u6b62\u300c\u5df2\u5931\u6548\u7684\u8fde\u63a5\u8bf7\u6c42\u62a5\u6587\u6bb5\u300d\u7a81\u7136\u53c8\u4f20\u5230\u4e86 B\u3002\u8003\u8651\u4e00\u79cd\u60c5\u51b5\uff0c\u5982\u679c A \u53d1\u51fa\u8fde\u63a5\u8bf7\u6c42\u5728\u7f51\u7edc\u8282\u70b9\u957f\u65f6\u95f4\u6ede\u7559\u4e86\uff0c\u5bfc\u81f4 A \u518d\u91cd\u4f20\u4e86\u4e00\u6b21\u8fde\u63a5\u8bf7\u6c42\uff0c\u800c\u6ede\u7559\u7684\u62a5\u6587\u6bb5\u5728\u8fde\u63a5\u91ca\u653e\u540e\u7684\u67d0\u4e2a\u65f6\u95f4\u624d\u5230\u8fbe B\uff0c\u8fd9\u672c\u5e94\u8be5\u662f\u4e00\u4e2a\u65e9\u5df2\u5931\u6548\u7684\u62a5\u6587\u6bb5\uff0c\u4f46 B \u6536\u5230\u8fd9\u4e2a\u5931\u6548\u7684\u62a5\u6587\u6bb5\u540e\uff0c\u8bef\u4ee5\u4e3a A \u53c8\u53d1\u9001\u4e86\u4e00\u6b21\u8fde\u63a5\u8bf7\u6c42\uff0c\u4e8e\u662f\u5411 A \u53d1\u51fa\u786e\u8ba4\u62a5\u6587\uff0c\u540c\u610f\u5efa\u7acb\u8fde\u63a5\u3002\u5047\u5b9a\u4e0d\u91c7\u7528\u4e09\u6b21\u63e1\u624b\uff0c\u90a3\u4e48 B \u53d1\u51fa\u786e\u8ba4\u62a5\u6587\uff0c\u8fde\u63a5\u5c31\u5efa\u7acb\u4e86\u3002\u800c A \u5e76\u6ca1\u6709\u53d1\u51fa\u8fde\u63a5\u8bf7\u6c42\uff0c\u6240\u4ee5\u4e0d\u4f1a\u56de\u5e94 B \u7684\u786e\u8ba4\u62a5\u6587\u6bb5\uff0c\u4e5f\u4e0d\u4f1a\u5411 B \u53d1\u9001\u6570\u636e\uff0c\u4f46\u662f B \u4ee5\u4e3a\u8fde\u63a5\u5df2\u7ecf\u5efa\u7acb\uff0c\u5e76\u4e00\u76f4\u7b49 A \u7684\u6570\u636e\u3002\u800c\u91c7\u7528\u4e09\u6b21\u63e1\u624b\u7684\u529e\u6cd5\u5c31\u53ef\u4ee5\u9632\u6b62\u8fd9\u4e2a\u95ee\u9898\u3002<\/p><p>\u7b80\u5355\u7684\u7406\u89e3\u4e09\u6b21\u63e1\u624b\uff0c\u7b2c\u4e00\u6b21\u63e1\u624b\u53ef\u4ee5\u786e\u8ba4\u5ba2\u6237\u8fdb\u7a0b\u53d1\u9001\u6ca1\u95ee\u9898\uff0c\u7b2c\u4e8c\u6b21\u63e1\u624b\u53ef\u4ee5\u786e\u8ba4\u670d\u52a1\u8fdb\u7a0b\u63a5\u6536\u6ca1\u548c\u53d1\u9001\u95ee\u9898\uff0c\u7b2c\u4e09\u6b21\u63e1\u624b\u53ef\u4ee5\u786e\u8ba4\u5ba2\u6237\u8fdb\u7a0b\u63a5\u6536\u6ca1\u95ee\u9898\u3002<\/p><h3 id=\"\u56db\u6b21\u6325\u624b\">\u56db\u6b21\u6325\u624b<\/h3><p>\u6570\u636e\u4f20\u8f93\u7ed3\u675f\u540e\uff0c\u901a\u4fe1\u7684\u53cc\u65b9\u90fd\u53ef\u4ee5\u91ca\u653e\u8fde\u63a5\u3002<\/p><p><img src=\"https:\/\/sunpe.github.io\/images\/tcp\/23.png\" alt=\"\u56fe 23 \u4f7f\u7528\u56db\u6b21\u6325\u624b\u91ca\u653e TCP \u8fde\u63a5\"><\/p><p>\u56fe 23 \u4f7f\u7528\u56db\u6b21\u6325\u624b\u91ca\u653e TCP \u8fde\u63a5<\/p><p>\u5982\u56fe 23 \u6240\u793a\uff0c\u73b0\u5728 A \u548c B \u90fd\u5904\u4e8e ESTABLISH \u72b6\u6001\uff0cA \u5148\u53d1\u51fa\u4e86\u8fde\u63a5\u91ca\u653e\u62a5\u6587\u6bb5\uff0c\u5e76\u505c\u6b62\u53d1\u9001\u6570\u636e\u3002A \u628a\u8fde\u63a5\u91ca\u653e\u62a5\u6587\u6bb5\u9996\u90e8\u7684\u7ec8\u6b62\u63a7\u5236\u4f4d FIN \u7f6e\u4e3a 1\uff0c\u5e8f\u5217\u53f7 seq = u\uff0c\u503c\u7b49\u4e8e\u524d\u9762\u4f20\u9001\u8fc7\u7684\u6570\u636e\u6700\u540e\u4e00\u4e2a\u5b57\u8282\u7684\u5e8f\u5217\u53f7\u52a0 1\uff0c\u8fd9\u65f6 A \u8fdb\u5165 FIN-WAIT-1\uff08\u7ec8\u6b62\u7b49\u5f85 1\uff09\u72b6\u6001\uff0c\u7b49\u5f85 B \u7684\u786e\u8ba4\u3002TCP \u89c4\u5b9a\uff0cFIN \u62a5\u6587\u6bb5\u5373\u4f7f\u4e0d\u643a\u5e26\u6570\u636e\uff0c\u4e5f\u8981\u6d88\u8017\u6389\u4e00\u4e2a\u5e8f\u5217\u53f7\u3002<\/p><p>B \u6536\u5230\u8fde\u63a5\u91ca\u653e\u62a5\u6587\u540e\u7acb\u5373\u786e\u8ba4\uff0c\u786e\u8ba4\u53f7 ack = u + 1\uff0c\u8fd9\u4e2a\u62a5\u6587\u6bb5\u7684\u5e8f\u5217\u53f7 seq = v\uff0c\u503c\u7b49\u4e8e\u524d\u9762\u5df2\u53d1\u9001\u8fc7\u6570\u636e\u7684\u6700\u540e\u4e00\u4e2a\u5b57\u8282\u7684\u5e8f\u53f7\u52a0 1\uff0c\u4e4b\u540e B \u8fdb\u5165 CLOSE-WAIT \uff08\u5173\u95ed\u7b49\u5f85\uff09\u72b6\u6001\uff0c\u4ece A \u5230 B \u8fd9\u4e2a\u65b9\u5411\u7684\u8fde\u63a5\u5c31\u91ca\u653e\u4e86\uff0cTCP \u5904\u4e8e\u534a\u5173\u95ed\u72b6\u6001\uff0c\u5373 A \u5df2\u7ecf\u6ca1\u6709\u6570\u636e\u8981\u53d1\u9001\u4e86\uff0c\u4f46\u5982\u679c B \u8981\u53d1\u9001\u6570\u636e\uff0cA \u4ecd\u8981\u63a5\u6536\uff0c\u4e5f\u5c31\u662f\u8bf4 B \u5230 A \u8fd9\u4e2a\u65b9\u5411\u7684\u8fde\u63a5\u5c1a\u672a\u5173\u95ed\u3002<\/p><p>A \u6536\u5230 B \u7684\u786e\u8ba4\u540e\uff0c\u8fdb\u5165 FIN-WAIT-2 \uff08\u7ec8\u6b62\u7b49\u5f852\uff09\u72b6\u6001\uff0c\u7b49\u5f85 B \u53d1\u51fa\u7684\u8fde\u63a5\u91ca\u653e\u62a5\u6587\u6bb5\u3002\u5982\u679c B \u5df2\u7ecf\u6ca1\u6709\u8981\u5411 A \u53d1\u9001\u7684\u6570\u636e\uff0c\u5e94\u7528\u8fdb\u7a0b\u5c31\u901a\u77e5 TCP \u91ca\u653e\u8fde\u63a5\u3002B \u53d1\u51fa\u8fde\u63a5\u91ca\u653e\u62a5\u6587\u6bb5\uff0c\u7f6e FIN \u4e3a 1\uff0c\u5e8f\u5217\u53f7\u4e3a w \uff08\u534a\u5173\u95ed\u72b6\u6001 B \u53ef\u80fd\u4f1a\u53d1\u9001\u4e00\u4e9b\u6570\u636e\uff09\uff0c\u8fd8\u9700\u8981\u91cd\u590d\u4e0a\u6b21\u5df2\u53d1\u9001\u7684\u786e\u8ba4\u53f7 ack = u + 1\uff0c\u8fd9\u662f B\u8fdb\u5165 LAST-ACK\uff08\u6700\u540e\u786e\u8ba4\uff09\u72b6\u6001\uff0c\u7b49\u5f85 A \u7684\u786e\u8ba4\u3002A \u5728\u6536\u5230 B \u7684\u8fde\u63a5\u91ca\u653e\u62a5\u6587\u6bb5\u540e\uff0c\u5fc5\u987b\u5bf9\u6b64\u53d1\u9001\u786e\u8ba4\uff0c\u7f6e ACK \u4e3a 1\uff0c\u786e\u8ba4\u53f7 ack = w + 1\uff0c\u5e8f\u5217\u53f7 seq = u + 1\uff08\u524d\u9762\u53d1\u9001\u7684 FIN \u62a5\u6587\u6bb5\u9700\u8981\u6d88\u8017\u4e00\u4e2a\u5e8f\u53f7\uff09\uff0c\u7136\u540e\u8fdb\u5165 TIME-WAIT\uff08\u65f6\u95f4\u7b49\u5f85\uff09\u72b6\u6001\uff0c\u8fd9\u65f6\u5019 TCP \u8fde\u63a5\u8fd8\u6ca1\u6709\u91ca\u653e\uff0c\u5fc5\u987b\u7b49\u5f85\u65f6\u95f4\u7b49\u5f85\u8ba1\u65f6\u5668\uff08time-wait timer\uff09\u8bbe\u7f6e\u7684\u65f6\u95f4 2MSL \u540e\uff0cA \u624d\u8fdb\u5165\u5230 CLOSED \u72b6\u6001\u3002\u65f6\u95f4 MSL \u53eb\u6700\u957f\u62a5\u6587\u6bb5\u5bff\u547d\uff0c\u5efa\u8bae\u8bbe\u7f6e\u4e3a 2 \u5206\u949f\u3002<\/p><p>\u4e3a\u4ec0\u4e48 A \u5728\u53d1\u51fa\u6700\u540e\u4e00\u4e2a ACK \u62a5\u6587\u6bb5\u540e\u5fc5\u987b\u7b49\u5f85 2 MSL \u65f6\u95f4\uff1f\u6709\u4e24\u4e2a\u539f\u56e0\u3002\u7b2c\u4e00\uff0c\u4e3a\u4e86\u4fdd\u8bc1 A \u53d1\u9001\u7684 ACK \u62a5\u6587\u6bb5\u80fd\u591f\u5230\u8fbe B\uff0c\u5904\u4e8e LASK-ACK \u72b6\u6001\u7684 B \u5982\u679c\u6536\u4e0d\u5230 A \u7684\u786e\u8ba4\u62a5\u6587\u6bb5\uff0cB \u4f1a\u8d85\u65f6\u91cd\u4f20 FIN + ACK \u62a5\u6587\u6bb5\u3002\u7b2c\u4e8c\uff0c\u9632\u6b62\u300c\u5df2\u5931\u6548\u7684\u8fde\u63a5\u8bf7\u6c42\u62a5\u6587\u6bb5\u300d\uff0cA \u7b49\u5f85 2MSL\uff0c\u53ef\u4ee5\u4f7f\u672c\u8fde\u63a5\u6301\u7eed\u65f6\u95f4\u5185\u4ea7\u751f\u7684\u6240\u6709\u62a5\u6587\u6bb5\u90fd\u4ece\u7f51\u7edc\u4e2d\u6d88\u5931\uff0c\u4f7f\u4e0b\u4e00\u4e2a\u65b0\u7684\u8fde\u63a5\u4e2d\u4e0d\u4f1a\u51fa\u73b0\u65e7\u7684\u8fde\u63a5\u62a5\u6587\u6bb5\u3002<\/p><p>\u9664\u4e86\u7b49\u5f85\u8ba1\u65f6\u5668\u5916\uff0cTCP \u8fd8\u8bbe\u6709\u4e00\u4e2a\u300c\u4fdd\u6d3b\u8ba1\u65f6\u5668\u300d\uff0c\u4ee5\u9632\u6b62\u5ba2\u6237\u8fdb\u7a0b\u6545\u969c\u5bfc\u81f4\u670d\u52a1\u5668\u8fdb\u7a0b\u7684\u4e0d\u5fc5\u8981\u7684\u7b49\u5f85\u3002\u670d\u52a1\u5668\u6bcf\u6b21\u6536\u5230\u5ba2\u6237\u7684\u6570\u636e\uff0c\u5c31\u91cd\u65b0\u8bbe\u7f6e\u4fdd\u6d3b\u8ba1\u65f6\u5668\uff0c\u65f6\u95f4\u8bbe\u7f6e\u901a\u5e38\u662f\u4e24\u5c0f\u65f6\uff0c\u82e5\u4e24\u5c0f\u65f6\u6ca1\u6709\u6536\u5230\u5ba2\u6237\u7684\u6570\u636e\uff0c\u670d\u52a1\u5668\u5c31\u53d1\u9001\u4e00\u4e2a\u63a2\u6d4b\u62a5\u6587\u6bb5\uff0c\u4e4b\u540e\u6bcf\u9694 75 \u5206\u949f\u53d1\u9001\u4e00\u6b21\uff0c\u5982\u679c\u4e00\u8fde 10 \u4e2a\u63a2\u6d4b\u62a5\u6587\u6bb5\u540e\u5ba2\u6237\u4ecd\u65e0\u54cd\u5e94\uff0c\u670d\u52a1\u5668\u5c31\u5173\u95ed\u8fd9\u4e2a\u8fde\u63a5\u3002<\/p><h3 id=\"tcp-\u7684\u6709\u9650\u72b6\u6001\u673a\">TCP \u7684\u6709\u9650\u72b6\u6001\u673a<\/h3><p><img src=\"https:\/\/sunpe.github.io\/images\/tcp\/24.png\" alt=\"\u56fe 24 TCP \u7684\u6709\u9650\u72b6\u6001\u673a\"><\/p><p>\u56fe 24 TCP \u7684\u6709\u9650\u72b6\u6001\u673a<\/p><p>\u56fe 24 \u5c55\u793a\u4e86 TCP \u7684\u6709\u9650\u72b6\u6001\u673a\uff0c\u65b9\u6846\u8868\u793a TCP \u53ef\u80fd\u5177\u6709\u7684\u72b6\u6001\uff0c\u72b6\u6001\u95f4\u7684\u7bad\u5934\u8868\u793a\u53ef\u80fd\u53d1\u751f\u7684\u72b6\u6001\u53d8\u8fc1\u3002\u7c97\u5b9e\u73b0\u7bad\u5934\u8868\u793a\u5ba2\u6237\u8fdb\u7a0b\u7684\u6b63\u5e38\u53d8\u8fc1\uff0c\u7c97\u865a\u7ebf\u7bad\u5934\u8868\u793a\u670d\u52a1\u5668\u8fdb\u7a0b\u7684\u6b63\u5e38\u53d8\u8fc1\uff0c\u7ec6\u7ebf\u7bad\u5934\u8868\u793a\u5f02\u5e38\u53d8\u8fc1\u3002<\/p>"},{"title":"\u5927\u5e74\u521d\u4e94--\u5317\u4eac\u6545\u5bab","link":"https:\/\/sunpe.github.io\/posts\/2021-02-16-forbidden-city\/","pubDate":"Tue, 16 Feb 2021 22:00:00 +0800","guid":"https:\/\/sunpe.github.io\/posts\/2021-02-16-forbidden-city\/","description":"<p>\u6545\u5bab\u535a\u7269\u9662\u53c8\u53eb\u300c\u7d2b\u7981\u57ce\u300d\uff0c\u662f\u660e\u6e05\u4e24\u4ee3\u7684\u7687\u5bab\uff0c\u603b\u5171\u6709 24 \u4f4d\u7687\u5e1d\u5c45\u4f4f\u8fc7\uff0c\u59cb\u5efa\u4e8e\u6c38\u4e50\u56db\u5e74\uff081406 \u5e74\uff09\uff0c\u5efa\u6210\u4e8e\u6c38\u4e50\u5341\u516b\u5e74\uff081420 \u5e74\uff09\uff0c\u5360\u5730\u9762\u79ef 72 \u4e07\u5e73\u65b9\u7c73\u3002<\/p><p>\u5927\u5e74\u521d\u4e94\u5929\u6c14\u8fd8\u662f\u6709\u4e9b\u51b7\u7684\uff0c\u4eca\u5929\u5f00\u8bbe\u4e86\u633a\u591a\u7684\u5c55\u89c8\uff0c\u770b\u8fc7\u300c\u666f\u4ec1\u5bab\u300d\u7684\u300c\u5fa1\u74f7\u65b0\u89c1\u300d\u5c55\u89c8\uff0c\u5c55\u51fa\u4e86\u666f\u5fb7\u9547\u7684\u9752\u82b1\u74f7\u548c\u6597\u5f69\u9752\u82b1\u74f7\u3002<\/p><p><img src=\"https:\/\/sunpe.github.io\/images\/forbidden_city\/1.jpg\" alt=\"\"><img src=\"https:\/\/sunpe.github.io\/images\/forbidden_city\/2.jpg\" alt=\"\"><img src=\"https:\/\/sunpe.github.io\/images\/forbidden_city\/3.jpg\" alt=\"\"><img src=\"https:\/\/sunpe.github.io\/images\/forbidden_city\/4.jpg\" alt=\"\"><img src=\"https:\/\/sunpe.github.io\/images\/forbidden_city\/5.jpg\" alt=\"\"><img src=\"https:\/\/sunpe.github.io\/images\/forbidden_city\/6.jpg\" alt=\"\"><img src=\"https:\/\/sunpe.github.io\/images\/forbidden_city\/7.jpg\" alt=\"\"><img src=\"https:\/\/sunpe.github.io\/images\/forbidden_city\/8.jpg\" alt=\"\"><img src=\"https:\/\/sunpe.github.io\/images\/forbidden_city\/9.jpg\" alt=\"\"><img src=\"https:\/\/sunpe.github.io\/images\/forbidden_city\/10.jpg\" alt=\"\"><\/p><p>\u8fd8\u6709\u5728\u53e6\u5916\u4e00\u4e2a\u5c55\u89c8\u7684\u6700\u957f\u7684\u300c\u7b97\u76d8\u300d\uff0c\u6709 117 \u4f4d\uff0c\u6bd4\u8ba1\u7b97\u673a\u4e2d\u7684 64 \u4f4d\u6574\u5f62\u8fd8\u8981\u957f\u3002<img src=\"https:\/\/sunpe.github.io\/images\/forbidden_city\/11.jpg\" alt=\"\"><\/p><p>\u5230\u4e86\u4e0b\u5348\u95ed\u9986\u524d\u7684\u4e00\u6bb5\u65f6\u95f4\uff0c\u8d81\u7740\u4eba\u5c11\u62cd\u4e86\u6545\u5bab\u7684\u4e3b\u4f53\u5efa\u7b51\u3002\u544a\u8bc9\u5927\u5bb6\u4e00\u4e2a\u5c0f\u7684\u6444\u5f71\u77e5\u8bc6\uff0c\u60f3\u62cd\u4eba\u5c11\u65f6\u5019\u7684\u6545\u5bab\uff0c\u53ef\u4ee5\u5728\u95ed\u9986\u524d\u534a\u5c0f\u65f6\u53bb\u62cd\u6444\u3002<\/p><p><img src=\"https:\/\/sunpe.github.io\/images\/forbidden_city\/12.jpg\" alt=\"\"><img src=\"https:\/\/sunpe.github.io\/images\/forbidden_city\/13.jpg\" alt=\"\"><img src=\"https:\/\/sunpe.github.io\/images\/forbidden_city\/14.jpg\" alt=\"\"><img src=\"https:\/\/sunpe.github.io\/images\/forbidden_city\/15.jpg\" alt=\"\"><img src=\"https:\/\/sunpe.github.io\/images\/forbidden_city\/16.jpg\" alt=\"\"><img src=\"https:\/\/sunpe.github.io\/images\/forbidden_city\/17.jpg\" alt=\"\"><img src=\"https:\/\/sunpe.github.io\/images\/forbidden_city\/18.jpg\" alt=\"\"><img src=\"https:\/\/sunpe.github.io\/images\/forbidden_city\/19.jpg\" alt=\"\"><\/p><p>\u4ece\u300c\u795e\u6b66\u95e8\u300d\u51fa\u6765\u4e4b\u540e\uff0c\u5c31\u6765\u5230\u4e86\u6545\u5bab\u7684\u540e\u9762\uff0c\u8fd9\u65f6\u5019\u5929\u8272\u5df2\u665a\u3002\u6625\u8282\u671f\u95f4\uff0c\u89d2\u697c\u3001\u795e\u6b66\u95e8\u4f1a\u88ab\u5c04\u706f\u6253\u4eae\uff0c\u53ef\u4ee5\u7a0d\u7b49\u7247\u523b\uff0c\u62cd\u6444\u89d2\u697c\u3002\u4e5f\u53ef\u4ee5\u53bb\u666f\u5c71\u516c\u56ed\uff0c\u5728\u666f\u5c71\u4e0a\u4fef\u89c8\u6545\u5bab\u3002<\/p><p><img src=\"https:\/\/sunpe.github.io\/images\/forbidden_city\/20.jpeg\" alt=\"\"><img src=\"https:\/\/sunpe.github.io\/images\/forbidden_city\/21.jpg\" alt=\"\"><img src=\"https:\/\/sunpe.github.io\/images\/forbidden_city\/22.jpg\" alt=\"\"><\/p>"},{"title":"\u5927\u5e74\u521d\u4e00--\u5317\u4eac\u56fd\u5b50\u76d1","link":"https:\/\/sunpe.github.io\/posts\/2021-02-12-guozijian\/","pubDate":"Fri, 01 Jan 2021 22:00:00 +0800","guid":"https:\/\/sunpe.github.io\/posts\/2021-02-12-guozijian\/","description":"<p>\u5317\u4eac\u56fd\u5b50\u76d1\u662f\u5143\u3001\u660e\u3001\u6e05\u4e09\u671d\u6700\u9ad8\u5b66\u5e9c\u548c\u6559\u80b2\u7ba1\u7406\u673a\u6784\uff0c\u5750\u843d\u4e8e\u4e1c\u57ce\u533a\u56fd\u5b50\u76d1\u8857\uff08\u65e7\u79f0\u6210\u8d24\u8857\uff09\u3002\u56fd\u5b50\u76d1\u4e1c\u4fa7\u5373\u4e3a\u56fd\u5185\u7b2c\u4e8c\u5927\u7684\u5b54\u5e99\u3002<\/p><p><img src=\"https:\/\/sunpe.github.io\/images\/guozijian\/1.jpg\" alt=\"\"><\/p><p>\u5b54\u5e99\u548c\u56fd\u5b50\u76d1\u5728\u4e00\u8d77\uff0c\u53c2\u89c2\u9700\u8981\u4ece\u5b54\u5e99\u8fdb\u53bb\u3002\u5b54\u5e99\u4e3b\u4f53\u5efa\u7b51\u662f\u4f9b\u5949\u5b54\u5b50\u7684\u300c\u5927\u6210\u6bbf\u300d\uff0c\u4f9b\u5949\u5b54\u5b50\u724c\u4f4d\u548c\u300c\u56db\u914d\u5341\u4e8c\u54f2\u300d\u724c\u4f4d\u3002<\/p><p><img src=\"https:\/\/sunpe.github.io\/images\/guozijian\/2.jpg\" alt=\"\"><\/p><p>\u9664\u6b64\u4e4b\u5916\u8fd8\u6709\u7531 180 \u591a\u5ea7\u77f3\u7891\u7ec4\u6210\u7684\u7891\u6797\uff0c\u77f3\u7891\u4e0a\u954c\u523b\u7740 13 \u90e8\u5112\u5bb6\u7ecf\u5178\uff0c\u851a\u7136\u58ee\u89c2\u3002<\/p><p><img src=\"https:\/\/sunpe.github.io\/images\/guozijian\/3.jpg\" alt=\"\"><\/p><p>\u91d1\u699c\u9898\u540d\u662f\u6bcf\u4e2a\u8bfb\u4e66\u4eba\u7684\u68a6\u60f3\uff0c\u56fd\u5b50\u76d1\u5e73\u65f6\u4f1a\u6709\u79d1\u4e3e\u5c55\uff0c\u4f46\u9057\u61be\u7684\u662f\u7531\u4e8e\u75ab\u60c5\uff0c\u5c55\u89c8\u6ca1\u6709\u5f00\u653e\u3002<\/p><p><img src=\"https:\/\/sunpe.github.io\/images\/guozijian\/4.jpg\" alt=\"\"><\/p><p>\u56fd\u5b50\u76d1\u6838\u5fc3\u5efa\u7b51\u662f\u300c\u8f9f\u96cd\u300d\uff0c\u4e7e\u9686\u7687\u5e1d\u66fe\u7ecf\u5728\u6b64\u8bb2\u5b66\uff0c\u5f53\u65f6\u56fd\u5b50\u76d1\u548c\u6210\u8d24\u8857\u4e0a\u8dea\u62dc\u542c\u8bb2\u7684\u5b66\u751f\u8fbe\u5230\u4e86 3000 \u591a\u540d\u3002<\/p><p><img src=\"https:\/\/sunpe.github.io\/images\/guozijian\/5.jpg\" alt=\"\"><\/p><p>\u300c\u8f9f\u96cd\u300d\u5185\u666f<\/p><p><img src=\"https:\/\/sunpe.github.io\/images\/guozijian\/6.jpg\" alt=\"\"><\/p>"},{"title":"\u9762\u5411\u5bf9\u8c61\u7684\u8bbe\u8ba1\u539f\u5219-SOLID","link":"https:\/\/sunpe.github.io\/posts\/2020-12-12-solid\/","pubDate":"Sat, 12 Dec 2020 22:00:00 +0800","guid":"https:\/\/sunpe.github.io\/posts\/2020-12-12-solid\/","description":"<h2 id=\"\u5355\u4e00\u804c\u8d23\u539f\u5219single-responsibility-principlesrp\">\u5355\u4e00\u804c\u8d23\u539f\u5219\uff08Single responsibility principle\uff0cSRP\uff09<\/h2><h3 id=\"\u7b80\u4ecb\">\u7b80\u4ecb<\/h3><p>\u5c31\u4e00\u4e2a\u7c7b\u800c\u8a00\uff0c\u5e94\u8be5\u4ec5\u6709\u4e00\u4e2a\u5f15\u8d77\u5b83\u53d8\u5316\u7684\u539f\u56e0\u3002<\/p><p>\u5982\u679c\u4e00\u4e2a\u7c7b\u627f\u62c5\u7684\u804c\u8d23\u8fc7\u591a\uff0c\u5c31\u7b49\u4e8e\u628a\u8fd9\u4e9b\u804c\u8d23\u8026\u5408\u5728\u4e86\u4e00\u8d77\uff0c\u4e00\u4e2a\u804c\u8d23\u53d8\u5316\u53ef\u80fd\u4f1a\u6291\u5236\u6216\u6d88\u5f31\u7c7b\u5b8c\u6210\u5176\u4ed6\u804c\u8d23\u7684\u80fd\u529b\uff0c\u8fd9\u79cd\u8026\u5408\u4f1a\u5bfc\u81f4\u8106\u5f31\u7684\u8bbe\u8ba1\uff0c\u5f53\u53d8\u5316\u53d1\u751f\u65f6\uff0c\u8bbe\u8ba1\u4f1a\u906d\u5230\u610f\u60f3\u4e0d\u5230\u7684\u7834\u574f\u3002<\/p><p>\u56fe 1 \u6240\u793a\uff0cRetangle \u7c7b\u5177\u6709\u4e24\u4e2a\u65b9\u6cd5\uff0c\u4e00\u4e2a\u65b9\u6cd5\u7528\u6765\u7ed8\u5236\u77e9\u5f62\uff0c\u4e00\u4e2a\u65b9\u6cd5\u7528\u6765\u8ba1\u7b97\u77e9\u5f62\u9762\u79ef\u3002\u6709\u4e24\u4e2a\u5e94\u7528\u7a0b\u5e8f\u4f7f\u7528 Rectangle \u7c7b\uff0c\u53ea\u4f1a\u4f7f\u7528 Rectangle \u7c7b\u8ba1\u7b97\u77e9\u5f62\u9762\u79ef\u7684\u65b9\u6cd5\uff0c\u53e6\u5916\u4e00\u4e2a\u5e94\u7528\u7a0b\u5e8f\u53ea\u4f1a\u5728\u5c4f\u5e55\u4e0a\u7ed8\u5236\u77e9\u5f62\u3002<\/p><p><img src=\"https:\/\/sunpe.github.io\/images\/solid\/1.png\" alt=\"\">\u56fe1 \u591a\u4e8e\u4e00\u4e2a\u7684\u804c\u8d23<\/p><p>Rectangle \u7c7b\u5177\u6709\u4e24\u4e2a\u804c\u8d23\uff0c\u8fdd\u53cd\u4e86 SRP\u3002\u5e26\u6765\u7684\u95ee\u9898\uff0c\u9996\u5148\uff0c\u5fc5\u987b\u5728 ComputationalGeometryApplication \u4e2d\u5305\u542b \u7ed8\u5236\u77e9\u5f62 \u4ee3\u7801\uff1b\u5176\u6b21\uff0c\u5982\u679c GraphicalApplication \u7684\u6539\u53d8\u7531\u4e8e\u4e00\u4e9b\u539f\u56e0\u5bfc\u81f4 Rectangle \u7c7b\u7684\u6539\u53d8\uff0c\u8fd9\u4e2a\u6539\u53d8\u9700\u8981\u91cd\u65b0\u6784\u5efa\u3001\u6d4b\u8bd5\u5e76\u90e8\u7f72 ComputationalGeometryApplication\uff0c\u5426\u5219 ComputationalGeometryApplication \u53ef\u80fd\u4f1a\u4ee5\u4e0d\u53ef\u9884\u6d4b\u7684\u65b9\u5f0f\u51fa\u73b0\u95ee\u9898\u3002<\/p><p>\u4e00\u4e2a\u8f83\u597d\u7684\u8bbe\u8ba1\u662f\u628a\u8fd9\u4e24\u4e2a\u804c\u8d23\u62c6\u5206\u5230\u4e24\u4e2a\u4e0d\u540c\u7684\u7c7b\u4e2d\uff0c\u5982\u56fe 2 \u6240\u793a\uff0c\u5c06Rectangle\u4e2d\u8ba1\u7b97\u903b\u8f91\u79fb\u5230 GeometricRectangle \u7c7b\u4e2d\uff0c\u73b0\u5728 GraphicalApplication \u7684\u6539\u53d8\u4e0d\u4f1a\u5bf9 ComputationalGeometryApplication \u9020\u6210\u5f71\u54cd\u3002<\/p><p><img src=\"https:\/\/sunpe.github.io\/images\/solid\/2.png\" alt=\"\">\u56fe2 \u5206\u79bb\u7684\u804c\u8d23<\/p><p>SRP\u4e2d\uff0c\u804c\u8d23\u5b9a\u4e49\u4e3a\u300c\u53d8\u5316\u7684\u539f\u56e0\u300d\uff0c\u5982\u679c\u6709\u591a\u4e8e\u4e00\u4e2a\u52a8\u673a\u53ef\u4ee5\u6539\u53d8\u4e00\u4e2a\u7c7b\uff0c\u90a3\u4e48\u8fd9\u4e2a\u7c7b\u5c31\u5177\u6709\u591a\u4e8e\u4e00\u4e2a\u804c\u8d23\u3002\u7a0b\u5e8f 1 \u7684 Modem \u63a5\u53e3\uff0c\u63a5\u53e3\u58f0\u660e\u7684 4 \u4e2a\u51fd\u6570\u786e\u5b9e\u662f Modem \u6240\u5177\u6709\u7684\u529f\u80fd\u3002\u4f46 Modem \u63a5\u53e3\u6709\u4e24\u4e2a\u804c\u8d23\uff0cdial \u548c hangup \u662f\u7528\u6765\u8fde\u63a5\u7ba1\u7406\uff0csend \u548c recv \u662f\u7528\u6765\u6570\u636e\u901a\u4fe1\u3002<\/p><div class=\"highlight\"><pre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"><code class=\"language-java\" data-lang=\"java\"><span style=\"display:flex;\"><span><span style=\"color:#66d9ef\">interface<\/span> <span style=\"color:#a6e22e\">Modem<\/span> {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">void<\/span> <span style=\"color:#a6e22e\">dial<\/span>(String pno);<\/span><\/span><span style=\"display:flex;\"><span><\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">void<\/span> <span style=\"color:#a6e22e\">hangup<\/span>();<\/span><\/span><span style=\"display:flex;\"><span><\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">void<\/span> <span style=\"color:#a6e22e\">send<\/span>(<span style=\"color:#66d9ef\">char<\/span> c);<\/span><\/span><span style=\"display:flex;\"><span><\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">void<\/span> <span style=\"color:#a6e22e\">recv<\/span>();<\/span><\/span><span style=\"display:flex;\"><span>} <\/span><\/span><\/code><\/pre><\/div><p>\u8fd9\u4e24\u4e2a\u4e24\u4e2a\u804c\u8d23\u662f\u5426\u5e94\u8be5\u5206\u5f00\u5462\uff1f\u8fd9\u4f9d\u8d56\u4e8e\u7a0b\u5e8f\u53d8\u5316\u7684\u65b9\u5f0f\u3002\u5982\u679c\u5e94\u7528\u7a0b\u5e8f\u53d8\u5316\u4f1a\u5f71\u54cd\u8fde\u63a5\u51fd\u6570\u7684\u7b7e\u540d\uff0c\u90a3\u4e48\u8c03\u7528 send \u548c recv \u51fd\u6570\u7684\u7c7b\u90fd\u9700\u8981\u91cd\u65b0\u6d4b\u8bd5\u3001\u7f16\u8bd1\u548c\u90e8\u7f72\uff0c\u8fd9\u6837\u7684\u8bbe\u8ba1\u5c31\u5177\u6709\u50f5\u5316\u6027\u3002\u8fd9\u79cd\u60c5\u51b5\u4e0b\uff0c\u8fd9\u4e24\u4e2a\u804c\u8d23\u5e94\u8be5\u5206\u5f00\uff0c\u5982\u56fe 3 \u6240\u793a\uff0c\u8fd9\u6837\u5c31\u907f\u514d\u4e86\u5ba2\u6237\u5e94\u7528\u7a0b\u5e8f\u548c\u8fd9\u4e24\u4e2a\u804c\u8d23\u8026\u5408\u5728\u4e00\u8d77\u4e86\u3002<\/p><p><img src=\"https:\/\/sunpe.github.io\/images\/solid\/3.png\" alt=\"\">\u56fe3 \u5206\u79bb\u7684Modem\u63a5\u53e3<\/p><p>\u5982\u679c\u5e94\u7528\u7a0b\u5e8f\u7684\u53d8\u5316\u65b9\u5f0f\u603b\u662f\u5bfc\u81f4\u8fd9\u4e24\u4e2a\u804c\u8d23\u540c\u65f6\u53d8\u5316\uff0c\u90a3\u4e48\u5c31\u4e0d\u5fc5\u5c06\u8fd9\u4e24\u4e2a\u804c\u8d23\u62c6\u5206\u5f00\uff0c\u62c6\u5206\u4e86\u4e4b\u540e\u4f1a\u589e\u52a0\u4e0d\u5fc5\u8981\u7684\u590d\u6742\u6027\u3002<\/p><p>\u56e0\u6b64\uff0c\u300c\u53d8\u5316\u300d\u53ea\u6709\u300c\u53d8\u5316\u300d\u5b9e\u9645\u53d1\u751f\u65f6\u624d\u5177\u6709\u610f\u4e49\uff0c\u5982\u679c\u6ca1\u6709\u53d8\u5316\u7684\u5f81\u5146\uff0c\u90a3\u4e48\u53bb\u5e94\u7528SRP\u6d3b\u7740\u5176\u4ed6\u539f\u5219\u90fd\u662f\u4e0d\u660e\u667a\u7684\u3002<\/p><p>\u5355\u4e00\u804c\u8d23\u539f\u5219\uff08SRP\uff09\u662f\u5176\u4ed6\u539f\u5219\u7684\u57fa\u7840\uff0c\u662fSOLID\u4e2d\u6700\u7b80\u5355\u7684\u539f\u5219\uff0c\u4e5f\u662f\u6700\u96be\u6b63\u786e\u8fd0\u7528\u7684\u539f\u5219\uff0c\u8f6f\u4ef6\u8bbe\u8ba1\u4e2d\u8bb8\u591a\u5de5\u4f5c\u5c31\u662f\u53d1\u73b0\u804c\u8d23\u5e76\u628a\u8fd9\u4e9b\u804c\u8d23\u4e92\u76f8\u5206\u79bb\u3002<\/p><h2 id=\"\u5f00\u653e-\u5c01\u95ed\u539f\u5219open-closed-principleocp\">\u5f00\u653e-\u5c01\u95ed\u539f\u5219\uff08Open-Closed principle\uff0cOCP\uff09<\/h2><p>\u8f6f\u4ef6\u5b9e\u4f53\uff08\u7c7b\u3001\u6a21\u5757\u3001\u51fd\u6570\u7b49\uff09\u5e94\u8be5\u662f\u53ef\u4ee5\u6269\u5c55\u7684\uff0c\u5e76\u4e14\u662f\u4e0d\u53ef\u4fee\u6539\u7684\u3002<\/p><p>\u5982\u679c\u7a0b\u5e8f\u4e2d\u4e00\u5904\u6539\u52a8\u5c31\u4f1a\u4ea7\u751f\u8fde\u9501\u53cd\u5e94\uff0c\u5bfc\u81f4\u4e00\u7cfb\u5217\u76f8\u5173\u6a21\u5757\u7684\u6539\u52a8\uff0c\u90a3\u4e48\u8fd9\u6837\u7684\u8bbe\u8ba1\u662f\u50f5\u5316\u7684\u3002OCP \u5efa\u8bae\u5bf9\u50f5\u5316\u7684\u7a0b\u5e8f\u8fdb\u884c\u91cd\u6784\uff0c\u5982\u679c\u6b63\u786e\u7684\u8fd0\u7528\u4e86 OCP\uff0c\u90a3\u4e48\u8fdb\u884c\u6539\u52a8\u65f6\uff0c\u53ea\u9700\u8981\u6dfb\u52a0\u4ee3\u7801\uff0c\u800c\u4e0d\u5fc5\u6539\u52a8\u5df2\u7ecf\u6b63\u5e38\u8fd0\u884c\u7684\u4ee3\u7801\u3002<\/p><p>\u9075\u5faa\u5f00\u653e-\u5c01\u95ed\u539f\u5219\u800c\u8bbe\u8ba1\u51fa\u7684\u6a21\u5757\u5177\u6709\u4e24\u4e2a\u7279\u5f81\uff1a<\/p><ol><li>\u5bf9\u4e8e\u6269\u5c55\u5f00\u653e\uff08open for extension\uff09\u3002 \u6a21\u5757\u7684\u884c\u4e3a\u662f\u53ef\u6269\u5c55\u7684\uff0c\u5f53\u9700\u6c42\u6539\u53d8\u65f6\uff0c\u53ef\u4ee5\u5bf9\u6a21\u5757\u8fdb\u884c\u6269\u5c55\uff0c\u4f7f\u5176\u5177\u6709\u6ee1\u8db3\u90a3\u4e9b\u6539\u53d8\u7684\u65b0\u884c\u4e3a\u3002<\/li><li>\u5bf9\u4e8e\u4fee\u6539\u5173\u95ed\uff08closed for modification\uff09\u3002\u5bf9\u6a21\u5757\u8fdb\u884c\u6269\u5c55\u65f6\uff0c\u4e0d\u5fc5\u6539\u52a8\u6a21\u5757\u7684\u6e90\u4ee3\u7801\u3002<\/li><\/ol><p>\u8fd9\u4e24\u4e2a\u7279\u5f81\u597d\u50cf\u662f\u4e92\u76f8\u77db\u76fe\u7684\uff0c\u901a\u5e38\u6269\u5c55\u6a21\u5757\u884c\u4e3a\u7684\u65b9\u6cd5\u5c31\u662f\u4fee\u6539\u6a21\u5757\u7684\u6e90\u4ee3\u7801\u3002\u600e\u6837\u624d\u80fd\u4e0d\u6539\u52a8\u6a21\u5757\u6e90\u4ee3\u7801\u7684\u60c5\u51b5\u4e0b\u53bb\u66f4\u6539\u6a21\u5757\u7684\u884c\u4e3a\u5462\uff1f\u5173\u952e\u662f\u8fd0\u7528<strong>\u62bd\u8c61<\/strong>\u3002<\/p><p>\u62bd\u8c61\u57fa\u7c7b\u6216\u63a5\u53e3\u53ef\u4ee5\u63cf\u8ff0\u4e00\u7ec4\u884c\u4e3a\uff0c\u6d3e\u751f\u7c7b\u6216\u5b9e\u73b0\u7c7b\u53ef\u4ee5\u7ee7\u627f\u57fa\u7c7b\u6216\u63a5\u53e3\u6765\u5b9e\u73b0\u63a5\u53e3\u7684\u884c\u4e3a\u3002\u6a21\u5757\u53ef\u4ee5\u4f9d\u8d56\u62bd\u8c61\u57fa\u7c7b\u6216\u63a5\u53e3\uff0c\u7531\u4e8e\u6a21\u5757\u4f9d\u8d56\u56fa\u5b9a\u7684\u62bd\u8c61\u57fa\u7c7b\u6216\u63a5\u53e3\uff0c\u6240\u4ee5\u5bf9\u4e8e\u6a21\u5757\u7684\u66f4\u6539\u53ef\u4ee5\u662f\u5173\u95ed\u7684\uff0c\u901a\u8fc7\u4ece\u57fa\u7c7b\u6216\u63a5\u53e3\u6765\u5b9e\u73b0\u6d3e\u751f\u7c7b\u6216\u5b9e\u73b0\u7c7b\uff0c\u4e5f\u53ef\u4ee5\u6269\u5c55\u6a21\u5757\u7684\u884c\u4e3a\u3002<\/p><p><img src=\"https:\/\/sunpe.github.io\/images\/solid\/4.png\" alt=\"\">\u56fe 4 \u5373\u4e0d\u5f00\u653e\u6709\u4e0d\u5c01\u95ed\u7684 Client<\/p><p>\u56fe 4 \u5c55\u793a\u4e86\u4e00\u4e2a\u7b80\u5355\u7684\u4e0d\u9075\u5faa OCP \u7684\u8bbe\u8ba1\uff0cClient \u7c7b\u548c Server \u7c7b\u90fd\u662f\u5177\u4f53\u7c7b\uff0cclient \u7c7b\u4f9d\u8d56 Server \u7c7b\uff0c\u5982\u679c Client \u5bf9\u8c61\u9700\u8981\u4f9d\u8d56\u5176\u4ed6\u7684\u670d\u52a1\u5668\u5bf9\u8c61\uff0c\u5219\u9700\u8981\u628a Client \u7c7b\u4e2d\u4f9d\u8d56 Server \u7c7b\u7684\u5730\u65b9\u66f4\u6539\u7ed9\u65b0\u7684\u670d\u52a1\u5668\u7c7b\u3002<\/p><p><img src=\"https:\/\/sunpe.github.io\/images\/solid\/5.png\" alt=\"\">\u56fe 5 strategy\u6a21\u5f0f\uff0c\u5373\u5f00\u653e\u53c8\u5c01\u95ed\u7684 Client<\/p><p>\u56fe 5 \u5c55\u793a\u4e86\u9075\u5faa OCP \u7684\u8bbe\u8ba1\uff0cClient \u7c7b\u4f9d\u8d56 IClient \u63a5\u53e3\uff0cServer \u7c7b\u5b9e\u73b0 IClient \u58f0\u660e\u7684\u65b9\u6cd5\uff0c\u5982\u679c Client \u5bf9\u8c61\u9700\u8981\u4f9d\u8d56\u53e6\u5916\u7684\u670d\u52a1\u5668\u65f6\uff0c\u53ea\u9700\u8981\u4ece IClient \u63a5\u53e3\u91cd\u65b0\u5b9e\u73b0\u4e00\u4e2a\u65b0\u7684\u7c7b\uff0c\u65e0\u9700\u4fee\u6539 Client \u7c7b\u3002<\/p><p><img src=\"https:\/\/sunpe.github.io\/images\/solid\/6.png\" alt=\"\">\u56fe 6 template method \u6a21\u5f0f\uff0c\u5373\u5f00\u653e\u53c8\u5c01\u95ed\u7684\u57fa\u7c7b<\/p><p>\u56fe 6 \u5c55\u793a\u4e86\u53e6\u4e00\u4e2a\u53ef\u9009\u7684\u7ed3\u6784\uff0cPolicy \u7c7b\u662f\u4e00\u4e2a\u62bd\u8c61\u7c7b\uff0c\u58f0\u660e\u4e86\u516c\u6709\u7684 policyFunction \u65b9\u6cd5\uff0c\u51fd\u6570\u5728\u5b50\u7c7b\u4e2d\u5b9e\u73b0\uff0c\u8fd9\u6837\u53ef\u4ee5\u901a\u8fc7\u4ece Policy \u7c7b\u6d3e\u751f\u51fa\u65b0\u7c7b\u7684\u65b9\u5f0f\uff0c\u5bf9 Policy \u4e2d\u7684\u884c\u4e3a\u8fdb\u884c\u6269\u5c55\u3002<\/p><p>\u56fe 5 \u548c\u56fe 6 \u4e24\u79cd\u6a21\u5f0f\u662f\u5b9e\u73b0 OCP \u7684\u5e38\u7528\u65b9\u6cd5\uff0c\u901a\u8fc7\u8fd9\u4e24\u79cd\u65b9\u6cd5\uff0c\u53ef\u4ee5\u5c06\u6a21\u5757\u7684\u901a\u7528\u90e8\u5206\u548c\u53ef\u80fd\u4f1a\u6539\u52a8\u7684\u90e8\u5206\u5206\u79bb\u5f00\u6765\u3002<\/p><p>\u4e00\u822c\u800c\u8a00\uff0c\u65e0\u8bba\u6a21\u5757\u591a\u4e48\u300c\u5c01\u95ed\u300d\uff0c\u90fd\u4f1a\u5b58\u5728\u4e00\u4e9b\u65e0\u6cd5\u5bf9\u4e4b\u5c01\u95ed\u7684\u53d8\u5316\uff0c\u6ca1\u6709\u5bf9\u6240\u6709\u60c5\u51b5\u90fd\u8d34\u5207\u7684\u6a21\u578b\uff0c\u8bbe\u8ba1\u4eba\u5458\u5fc5\u987b\u5bf9\u5176\u8bbe\u8ba1\u7684\u6a21\u5757\u8981\u5bf9\u54ea\u79cd\u53d8\u5316\u5c01\u95ed\u4f5c\u51fa\u9009\u62e9\uff0c\u5fc5\u987b\u5148\u6839\u636e\u7ecf\u9a8c\u731c\u6d4b\u51fa\u6700\u6709\u53ef\u80fd\u53d1\u751f\u53d8\u5316\u7684\u79cd\u7c7b\uff0c\u7136\u540e\u6784\u9020\u62bd\u8c61\u6765\u9694\u79bb\u53d8\u5316\u3002\u8bbe\u8ba1\u4eba\u5458\u9700\u8981\u4e86\u89e3\u7a0b\u5e8f\u7684\u7528\u6237\u548c\u5e94\u7528\u9886\u57df\uff0c\u4ee5\u6b64\u6765\u5224\u65ad\u5404\u79cd\u53d8\u5316\u7684\u53ef\u80fd\u6027\uff0c\u8ba9\u8bbe\u8ba1\u5bf9\u4e8e\u6700\u6709\u53ef\u80fd\u53d1\u751f\u53d8\u5316\u9075\u5faa OCP\u3002<\/p><p>\u901a\u5e38\u5f88\u96be\u5224\u65ad\u53d8\u5316\u7684\u53ef\u80fd\u6027\uff0c\u800c\u4e14\u9075\u5faa OCP \u7684\u4ee3\u4ef7\u4e5f\u662f\u9ad8\u6602\u7684\uff0c\u521b\u5efa\u62bd\u8c61\u9700\u8981\u82b1\u8d39\u7cbe\u529b\u548c\u65f6\u95f4\uff0c\u62bd\u8c61\u4e5f\u589e\u52a0\u4e86\u8bbe\u8ba1\u7684\u590d\u6742\u6027\u3002\u6bd4\u8d77\u8fc7\u6e21\u8bbe\u8ba1\u800c\u5e26\u6765\u7684\u4e0d\u5fc5\u8981\u7684\u590d\u6742\u6027\u6765\u8bf4\uff0c\u5728\u53d8\u5316\u53d1\u751f\u65f6\u624d\u5e94\u7528 OCP \u539f\u5219\u91cd\u6784\u7a0b\u5e8f\u7684\u65b9\u5f0f\u53ef\u80fd\u4f1a\u66f4\u597d\u3002<\/p><p>OCP \u662f\u9762\u5411\u5bf9\u8c61\u8bbe\u8ba1\u7684\u6838\u5fc3\u6240\u5728\uff0c\u9075\u5faa\u8fd9\u4e2a\u539f\u5219\u53ef\u4ee5\u5e26\u6765\u7075\u6d3b\u6027\u3001\u53ef\u91cd\u7528\u6027\u4ee5\u53ca\u53ef\u7ef4\u62a4\u6027\uff0c\u7136\u800c\u5bf9\u7a0b\u5e8f\u4e2d\u7684\u6bcf\u4e2a\u90e8\u5206\u90fd\u8086\u610f\u7684\u8fdb\u884c\u62bd\u8c61\u540c\u6837\u4e0d\u53ef\u53d6\u3002\u6b63\u786e\u7684\u505a\u6cd5\u662f\uff0c\u5f00\u653e\u4eba\u5458\u5e94\u8be5\u4ec5\u4ec5\u5bf9\u7a0b\u5e8f\u4e2d\u8868\u73b0\u51fa\u9891\u7e41\u53d8\u5316\u7684\u90a3\u90e8\u5206\u505a\u62bd\u8c61\uff0c\u62d2\u7edd\u4e0d\u6210\u719f\u7684\u62bd\u8c61\u548c\u521b\u5efa\u62bd\u8c61\u4e00\u6837\u91cd\u8981\u3002<\/p><h2 id=\"\u91cc\u6c0f\u66ff\u4ee3\u539f\u5219liskov-substitution-principlelsp\">\u91cc\u6c0f\u66ff\u4ee3\u539f\u5219\uff08Liskov substitution principle\uff0cLSP\uff09<\/h2><p>LSP \u662f\u5173\u4e8e\u57fa\u7c7b\u7ee7\u627f\uff08inheritance\uff09\u7684\u539f\u5219\u3002Barbara Liskov \u6307\u51fa\uff0c\u82e5\u5bf9\u4e8e<em>\u6bcf\u4e2a\u7c7b\u578b S \u7684\u5bf9\u8c61 o1\uff0c\u90fd\u5b58\u5728\u4e00\u4e2a\u7c7b\u578b T \u7684\u5bf9\u8c61 o2\uff0c\u4f7f\u5f97\u5bf9\u4e8e\u6240\u6709\u9488\u5bf9 T \u7f16\u5199\u7684\u7a0b\u5e8f P \u4e2d\uff0c\u7528 o1 \u66ff\u6362 o2 \u540e\uff0c\u7a0b\u5e8f P \u7684\u884c\u4e3a\u529f\u80fd\u4e0d\u53d8\uff0c\u90a3\u4e48 S \u662f T \u7684\u5b50\u7c7b\u578b<\/em>\u3002\u5bf9\u91cc\u6c0f\u66ff\u4ee3\u539f\u5219\u7684\u7b80\u5355\u89e3\u91ca\u662f\uff1a \u5b50\u7c7b\u578b\uff08subtype\uff09\u5fc5\u987b\u80fd\u591f\u66ff\u6362\u6389\u4ed6\u4eec\u7684\u57fa\u7c7b\u578b\uff08base type\uff09\u3002<\/p><p>\u7ee7\u627f\u662f IS-A \u7684\u5173\u7cfb\uff0c\u5982\u679c\u4e00\u4e2a\u65b0\u7c7b\u578b\u7684\u5bf9\u8c61\u548c\u4e00\u4e2a\u5df2\u77e5\u7c7b\u578b\u7684\u5bf9\u8c61\u4e4b\u95f4\u6ee1\u8db3 IS-A \u5173\u7cfb\uff0c\u90a3\u4e48\u8fd9\u4e2a\u65b0\u5bf9\u8c61\u7684\u7c7b\u5e94\u8be5\u662f\u4ece\u8fd9\u4e2a\u5df2\u77e5\u5bf9\u8c61\u7684\u7c7b\u6d3e\u751f\u7684\u3002<\/p><p>\u4e00\u822c\u6765\u8bf4\uff0c\u6b63\u65b9\u5f62\u662f\u4e00\u4e2a\uff08IS-A\uff09\u77e9\u5f62\uff0c\u56e0\u6b64 Square \u7c7b\u53ef\u4ee5\u4f5c\u4e3a Rectangle \u7c7b\u7684\u5b50\u7c7b\uff0c\u5982\u56fe 7\u3002<\/p><p><img src=\"https:\/\/sunpe.github.io\/images\/solid\/7.png\" alt=\"\">\u56fe 7 Square \u7c7b\u662f Rectangle \u7c7b\u7684\u5b50\u7c7b<\/p><p>\u8fd9\u6837\u7684\u8bbe\u8ba1\u53ef\u80fd\u4f1a\u5b58\u5728\u4e00\u4e9b\u95ee\u9898\uff0c\u9996\u5148 Square \u7c7b\u5e76\u4e0d\u9700\u8981\u540c\u65f6\u5177\u6709 setWidth \u548c setHeight \u65b9\u6cd5\uff0c\u800c\u4e14\u5bf9\u4e8e Square \u7c7b\u6765\u8bf4 width \u548c height \u5e94\u8be5\u59cb\u7ec8\u662f\u76f8\u540c\u7684\uff0c\u66f4\u4e3a\u4e25\u91cd\u7684\u662f\uff0c\u5bf9\u4e8e\u7a0b\u5e8f 2 \u7684\u6d4b\u8bd5\u7528\u4f8b\u6765\u8bf4\uff0c\u5982\u679c\u628a Square \u4f5c\u4e3a\u6d4b\u8bd5\u7684\u53c2\u6570\u662f\u9519\u8bef\u7684\u3002<\/p><div class=\"highlight\"><pre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"><code class=\"language-java\" data-lang=\"java\"><span style=\"display:flex;\"><span><span style=\"color:#66d9ef\">void<\/span> <span style=\"color:#a6e22e\">test<\/span>(Rectangle r) {<\/span><\/span><span style=\"display:flex;\"><span> r.<span style=\"color:#a6e22e\">setWidth<\/span>(4);<\/span><\/span><span style=\"display:flex;\"><span> r.<span style=\"color:#a6e22e\">setWidth<\/span>(5);<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">assert<\/span>(r.<span style=\"color:#a6e22e\">area<\/span>() <span style=\"color:#f92672\">==<\/span> 20);<\/span><\/span><span style=\"display:flex;\"><span>}<\/span><\/span><\/code><\/pre><\/div><p>\u4e00\u4e2a\u6a21\u578b\uff0c\u5982\u679c\u5b64\u7acb\u7684\u770b\uff0c\u5e76\u4e0d\u5177\u6709\u771f\u6b63\u610f\u4e49\u4e0a\u7684\u6709\u6548\u6027\uff0c\u6a21\u578b\u7684\u6709\u6548\u6027\u662f\u901a\u8fc7\u6a21\u578b\u7684\u4f7f\u7528\u8005\u6765\u8868\u73b0\u7684\u3002\u4f8b\u5982\uff0c\u5982\u679c\u5b64\u7acb\u7684\u770b\uff0c\u56fe 7 \u7684\u6a21\u578b\u662f\u6709\u6548\u7684\uff0c\u4f46\u662f\u4ece\u6a21\u578b\u7684\u4f7f\u7528\u8005\u6765\u8bf4\uff0c\u56fe 7 \u8fd9\u4e2a\u6a21\u578b\u662f\u6709\u95ee\u9898\u7684\uff0c\u5728\u8003\u8651\u4e00\u4e2a\u8bbe\u8ba1\u662f\u5426\u6070\u5f53\u65f6\uff0c\u4e0d\u80fd\u5b8c\u5168\u5b64\u7acb\u7684\u770b\u8bbe\u8ba1\uff0c\u5fc5\u987b\u8981\u5728\u8bbe\u8ba1\u7684\u4f7f\u7528\u8005\u7684\u89c6\u89d2\u6765\u5ba1\u89c6\u8fd9\u4e2a\u8bbe\u8ba1\u3002<\/p><p>\u5bf9\u4e8e\u56fe 7 \u7684\u8bbe\u8ba1\u8fd9\u6765\u8bf4\uff0c\u6b63\u65b9\u5f62\u53ef\u4ee5\u662f\u957f\u65b9\u5f62\uff0c\u4f46\u5bf9\u4e8e\u4f7f\u7528\u8fd9\u6765\u8bf4\uff0cSquare \u5bf9\u8c61 \u7edd\u5bf9\u4e0d\u662f Rectangle \u5bf9\u8c61\uff0c\u56e0\u4e3a Square \u5bf9\u8c61\u7684\u884c\u4e3a\u65b9\u5f0f\u548c\u4f7f\u7528\u8005\u6240\u671f\u671b\u7684 Rectangle \u5bf9\u8c61\u7684\u884c\u4e3a\u65b9\u5f0f\u4e0d\u76f8\u5bb9\uff0c\u4ece\u884c\u4e3a\u65b9\u5f0f\u7684\u89d2\u5ea6\u6765\u770b\uff0cSquare \u4e0d\u662f Rectangle\uff0c\u5bf9\u8c61\u7684\u884c\u4e3a\u65b9\u5f0f\u624d\u662f\u8f6f\u4ef6\u8bbe\u8ba1\u771f\u6b63\u9700\u8981\u5173\u6ce8\u7684\u95ee\u9898\u3002LSP\u6e05\u6670\u7684\u6307\u51fa\uff0c\u9762\u5411\u5bf9\u8c61\u8bbe\u8ba1\u7684 IS-A \u5173\u7cfb\u662f\u5c31\u884c\u4e3a\u65b9\u5f0f\u800c\u8a00\u7684\uff0c\u884c\u4e3a\u65b9\u5f0f\u624d\u662f\u4f7f\u7528\u8005\u6240\u9700\u8981\u7684\u3002<\/p><h2 id=\"\u4f9d\u8d56\u5012\u7f6e\u539f\u5219dependency-inversion-principledip\">\u4f9d\u8d56\u5012\u7f6e\u539f\u5219\uff08Dependency Inversion principle\uff0cDIP\uff09<\/h2><p>\u9ad8\u5c42\u6a21\u5757\u4e0d\u5e94\u8be5\u4f9d\u8d56\u4f4e\u5c42\u6a21\u5757\uff0c\u4e8c\u8005\u90fd\u5e94\u8be5\u4f9d\u8d56\u62bd\u8c61\uff1b\u62bd\u8c61\u4e0d\u5e94\u8be5\u4f9d\u8d56\u7ec6\u8282\uff0c\u7ec6\u8282\u5e94\u8be5\u4f9d\u8d56\u62bd\u8c61\u3002<\/p><p>\u8bb8\u591a\u7684\u4f20\u7edf\u8f6f\u4ef6\u5f00\u53d1\u65b9\u6cd5\uff0c\u6bd4\u5982\u7ed3\u6784\u5316\u5206\u6790\u548c\u8bbe\u8ba1\uff0c\u603b\u662f\u503e\u5411\u4e8e\u521b\u5efa\u4e00\u4e9b\u9ad8\u5c42\u6a21\u5757\u4f9d\u8d56\u4f4e\u5c42\u6a21\u5757\u3001\u4e1a\u52a1\u903b\u8f91\u4f9d\u8d56\u4f4e\u5c42\u7ec6\u8282\u7684\u8f6f\u4ef6\u7ed3\u6784\uff0c\u5b9e\u9645\u4e0a\u4e9b\u4f20\u7edf\u7684\u5f00\u53d1\u65b9\u6cd5\u7684\u76ee\u7684\u4e4b\u4e00\u662f\u8981\u5b9a\u4e49\u7a0b\u5e8f\u5c42\u6b21\u7684\u7ed3\u6784\uff0c\u8be5\u5c42\u6b21\u7ed3\u6784\u63cf\u8ff0\u4e86\u9ad8\u5c42\u6a21\u5757\u600e\u6837\u8c03\u7528\u4f4e\u5c42\u6a21\u5757\u3002\u4e00\u4e2a\u826f\u597d\u7684\u9762\u5411\u5bf9\u8c61\u7684\u7a0b\u5e8f\uff0c\u5176\u4f9d\u8d56\u5c42\u6b21\u7ed3\u6784\u76f8\u5bf9\u4e8e\u4f20\u7edf\u7684\u8fc7\u7a0b\u5f0f\u65b9\u6cd5\u8bbe\u8ba1\u6765\u8bf4\u5c31\u662f\u88ab\u300c\u5012\u7f6e\u300d\u4e86\u3002<\/p><p>\u5982\u679c\u9ad8\u5c42\u6a21\u5757\u76f4\u63a5\u4f9d\u8d56\u4e86\u4f4e\u5c42\u6a21\u5757\uff0c\u90a3\u4e48\u4f4e\u5c42\u6a21\u5757\u7684\u6539\u52a8\u5c31\u4f1a\u76f4\u63a5\u5f71\u54cd\u9ad8\u5c42\u6a21\u5757\uff0c\u8fd9\u79cd\u60c5\u5f62\u662f\u975e\u5e38\u8352\u8c2c\u7684\uff0c\u672c\u5e94\u8be5\u662f\u9ad8\u5c42\u6a21\u5757\u53bb\u5f71\u54cd\u4f4e\u5c42\u7684\u7ec6\u8282\u5b9e\u73b0\u6a21\u5757\uff0c\u5305\u542b\u4e1a\u52a1\u903b\u8f91\u7684\u9ad8\u5c42\u6a21\u5757\u5e94\u8be5\u4f18\u5148\u5e76\u72ec\u7acb\u4e8e\u5305\u542b\u7ec6\u8282\u7684\u4f4e\u5c42\u6a21\u5757\u3002\u800c\u4e14\u5982\u679c\u9ad8\u5c42\u6a21\u5757\u4f9d\u8d56\u4e86\u4f4e\u5c42\u6a21\u5757\uff0c\u4f1a\u5bfc\u81f4\u91cd\u7528\u9ad8\u5c42\u6a21\u5757\u96be\u4ee5\u88ab\u91cd\u7528\u3002\u6240\u4ee5\u9ad8\u5c42\u6a21\u5757\u4e0d\u5e94\u8be5\u76f4\u63a5\u4f9d\u8d56\u4e8e\u4f4e\u5c42\u6a21\u5757\u3002<\/p><p>\u4f20\u7edf\u7684\u5206\u6790\u548c\u8bbe\u8ba1\u65b9\u6cd5\u7684\u77e5\u9053\u601d\u60f3\u662f\uff0c\u300c\u6240\u6709\u7ed3\u6784\u826f\u597d\u7684\u9762\u5411\u5bf9\u8c61\u67b6\u6784\u90fd\u5177\u6709\u6e05\u6670\u7684\u5c42\u6b21\u5b9a\u4e49\uff0c\u6bcf\u4e2a\u5c42\u6b21\u901a\u8fc7\u4e00\u4e2a\u5b9a\u4e49\u826f\u597d\u7684\u3001\u53d7\u63a7\u7684\u63a5\u53e3\u5411\u5916\u63d0\u4f9b\u4e00\u7ec4\u5185\u805a\u7684\u670d\u52a1\u300d\u3002\u6839\u636e\u8fd9\u4e2a\u601d\u60f3\u53ef\u80fd\u8bbe\u8ba1\u51fa\u7c7b\u4f3c\u4e8e\u56fe 8 \u7684\u63a5\u53e3\uff0c\u9ad8\u5c42\u7684 Policy Layer \u4f9d\u8d56\u4e86\u4f4e\u5c42\u7684 Mechanism Layer\uff0c\u800c Mechanism Layer \u53c8\u4f9d\u8d56\u4e86\u66f4\u7ec6\u8282\u7684 Utility Layer\u3002\u8fd9\u6837\u7684\u8bbe\u8ba1\u4f7f\u5f97\u9ad8\u5c42\u6a21\u5757 Policy Layer \u5bf9\u4e8e\u5176\u4e0b\u4e00\u76f4\u5230 Utility Layer \u7684\u6539\u52a8\u90fd\u662f\u654f\u611f\u7684\u3002<\/p><p><img src=\"https:\/\/sunpe.github.io\/images\/solid\/8.png\" alt=\"\">\u56fe 8 \u7b80\u5355\u7684\u5c42\u6b21\u5316\u65b9\u6848<\/p><p>\u56fe 9 \u5c55\u793a\u4e86\u4f9d\u8d56\u5173\u7cfb\u5012\u7f6e\u7684\u6a21\u578b\uff0c\u6bcf\u4e2a\u8f83\u9ad8\u5c42\u6b21 Policy Layer \u548c Mechanism Layer \u4e3a\u5176\u9700\u8981\u7684\u670d\u52a1\u58f0\u660e\u4e86\u62bd\u8c61\u63a5\u53e3\uff0c\u8f83\u4f4e\u7684\u5c42\u6b21 Mechanism Layer \u548c Utility \u5b9e\u73b0\u4e86\u8f83\u9ad8\u5c42\u6b21\u6a21\u5757\u7684\u63a5\u53e3\uff0c\u9ad8\u5c42\u7c7b\u901a\u8fc7\u62bd\u8c61\u63a5\u53e3\u6765\u4f7f\u7528\u4e0b\u4e00\u5c42\uff0c\u8fd9\u6837\u9ad8\u5c42\u4e0d\u4f9d\u8d56\u4f4e\u5c42\uff0c\u4f4e\u5c42\u53cd\u800c\u4f9d\u8d56\u4e8e\u5728\u9ad8\u5c42\u4e2d\u58f0\u660e\u7684\u62bd\u8c61\u63a5\u53e3\u3002\u4f9d\u8d56\u5173\u7cfb\u88ab\u5012\u7f6e\u4e86\uff0c\u63a5\u53e3\u6240\u6709\u6743\u4e5f\u5012\u7f6e\u4e86\uff0c\u6211\u4eec\u901a\u5e38\u8ba4\u4e3a\u5de5\u5177\u5e93\u5e94\u8be5\u62e5\u6709\u81ea\u5df1\u7684\u63a5\u53e3\uff0c\u4f46\u4f7f\u7528\u4e86 DIP \u540e\uff0c\u5ba2\u6237\u62e5\u6709\u62bd\u8c61\u63a5\u53e3\uff0c\u800c\u670d\u52a1\u8fd9\u9700\u8981\u4ece\u8fd9\u4e9b\u62bd\u8c61\u63a5\u53e3\u4e2d\u6d3e\u751f\u3002<\/p><p><img src=\"https:\/\/sunpe.github.io\/images\/solid\/9.png\" alt=\"\">\u56fe 9 \u5012\u7f6e\u7684\u4f9d\u8d56\u5173\u7cfb<\/p><p>Hollywood \u539f\u5219 \u2014\u300cdon&rsquo;t call us, we&rsquo;ll call you\u300d,\u4f4e\u5c42\u6a21\u5757\u5b9e\u73b0\u4e86\u9ad8\u5c42\u6a21\u5757\u4e2d\u58f0\u660e\u7684\u63a5\u53e3\uff0c\u901a\u8fc7\u63a5\u53e3\u6240\u6709\u6743\u5012\u7f6e\uff0c Mechanism Layer \u548c Utility \u7684\u4efb\u4f55\u6539\u52a8\u90fd\u4e0d\u4f1a\u518d\u5f71\u54cd Policy Layer\uff0c\u800c\u4e14 Policy Layer \u53ef\u4ee5\u5728\u5b9e\u73b0\u4e86 IPolicyService \u7684\u4efb\u4f55\u4e0a\u4e0b\u6587\u4e2d\u91cd\u7528\u3002<\/p><p>\u5bf9\u4e8e DIP \u7a0d\u5fae\u7b80\u5355\u7684\u89e3\u91ca\u2014 \u300c\u4f9d\u8d56\u4e8e\u62bd\u8c61\u300d\u3002\u5373\u4e0d\u4f9d\u8d56\u4e8e\u5177\u4f53\u7c7b\uff0c\u7a0b\u5e8f\u4e2d\u7684\u6240\u6709\u4f9d\u8d56\u5173\u7cfb\u90fd\u5e94\u8be5\u7ec8\u6b62\u4e8e\u62bd\u8c61\u7c7b\u6216\u63a5\u53e3\u3002\u4efb\u4f55\u53d8\u91cf\u90fd\u4e0d\u5e94\u8be5\u6301\u6709\u4e00\u4e2a\u6307\u5411\u5177\u4f53\u7c7b\u7684\u6307\u9488\u6216\u5f15\u7528\uff0c\u4efb\u4f55\u7c7b\u90fd\u4e0d\u5e94\u8be5\u4ece\u5177\u4f53\u7c7b\u6d3e\u751f\uff0c\u4efb\u4f55\u6d3e\u751f\u7c7b\u90fd\u4e0d\u5e94\u8be5\u8986\u5199\u57fa\u7c7b\u4e2d\u5df2\u5b9e\u73b0\u7684\u65b9\u6cd5\u3002<\/p><p>\u51e1\u4e8b\u7686\u6709\u4f8b\u5916\uff0c\u7a0b\u5e8f\u4e2d\u6709\u65f6\u5019\u5fc5\u987b\u8981\u521b\u5efa\u5177\u4f53\u7c7b\u7684\u6d3e\u751f\u7c7b\uff1b\u800c\u4e14\u4f9d\u8d56\u5177\u4f53\u4f46\u662f\u7a33\u5b9a\u7684\u7c7b\u4e5f\u4e0d\u4f1a\u9020\u6210\u4ec0\u4e48\u95ee\u9898\u3002\u6bd4\u5982\uff0cJava \u4e2d\u76f4\u63a5\u4f9d\u8d56 String \u7c7b\u5c31\u4e0d\u4f1a\u9020\u6210\u4ec0\u4e48\u95ee\u9898\u3002<\/p><p>\u7136\u800c\u6211\u4eec\u6211\u4eec\u7a0b\u5e8f\u4e2d\u7684\u5927\u591a\u6570\u5177\u4f53\u7c7b\u90fd\u4e0d\u662f\u7a33\u5b9a\u7684\uff0c\u6211\u4eec\u4e0d\u5e94\u8be5\u4f9d\u8d56\u4e8e\u4e0d\u7a33\u5b9a\u7684\u5177\u4f53\u7c7b\uff0c\u901a\u8fc7\u62bd\u8c61\u63a5\u53e3\u9690\u85cf\u4e0d\u7a33\u5b9a\u7684\u5177\u4f53\u7c7b\uff0c\u53ef\u4ee5\u9694\u79bb\u4e0d\u7a33\u5b9a\u6027\u3002<\/p><p>\u56fe 10 \u5c55\u793a\u4e86\u4f7f\u7528 Button \u63a7\u5236 Lamp \u5bf9\u8c61\u7684\u6a21\u578b\uff0cButton \u63a5\u6536 Poll \u6d88\u606f\uff0c\u7136\u540e\u5411\u8c03\u7528 Lamp \u7684 turnOn \u6216 turnOff \u65b9\u6cd5\u3002<\/p><p><img src=\"https:\/\/sunpe.github.io\/images\/solid\/10.png\" alt=\"\">\u56fe 10 \u4e0d\u6210\u719f\u7684 Button \u548c Lamp \u6a21\u578b<\/p><p>\u56fe 10 \u6a21\u578b\u5bf9\u5e94\u7684\u4ee3\u7801\u5982 \u7a0b\u5e8f 3\u3002Button \u7c7b\u76f4\u63a5\u4f9d\u8d56 Lamp \u7c7b\uff0c\u8fd9\u4e2a\u4f9d\u8d56\u5173\u7cfb\u610f\u5473\u7740\u5f53 Lamp \u7c7b\u6539\u52a8\u65f6 Button \u7c7b\u4f1a\u53d7\u5f71\u54cd\uff0c\u800c\u4e14\u8981\u91cd\u7528 Button \u6765\u63a7\u5236\u53e6\u5916\u7684\u8bbe\u5907\u662f\u4e0d\u53ef\u80fd\u7684\u3002\u7a0b\u5e8f\u4e2d\u9ad8\u5c42\u548c\u4f4e\u5c42\u6ca1\u6709\u5b9e\u73b0\u5206\u79bb\uff0c\u62bd\u8c61\u548c\u5177\u4f53\u4e5f\u6ca1\u6709\u5206\u79bb\uff0c\u9ad8\u5c42\u4f9d\u8d56\u4e86\u4f4e\u5c42\u6a21\u5757\uff0c\u62bd\u8c61\u4f9d\u8d56\u4e86\u5177\u4f53\u7ec6\u8282\u3002<\/p><div class=\"highlight\"><pre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"><code class=\"language-java\" data-lang=\"java\"><span style=\"display:flex;\"><span><span style=\"color:#66d9ef\">public<\/span> <span style=\"color:#66d9ef\">class<\/span> <span style=\"color:#a6e22e\">Button<\/span> {<\/span><\/span><span style=\"display:flex;\"><span><\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">private<\/span> Lamp lamp;<\/span><\/span><span style=\"display:flex;\"><span><\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">public<\/span> <span style=\"color:#66d9ef\">void<\/span> <span style=\"color:#a6e22e\">poll<\/span>() {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">if<\/span> (<span style=\"color:#75715e\">\/* some condition *\/<\/span>) {<\/span><\/span><span style=\"display:flex;\"><span> lamp.<span style=\"color:#a6e22e\">turnOn<\/span>();<\/span><\/span><span style=\"display:flex;\"><span> }<\/span><\/span><span style=\"display:flex;\"><span> }<\/span><\/span><span style=\"display:flex;\"><span>}<\/span><\/span><\/code><\/pre><\/div><p>\u901a\u8fc7\u5012\u7f6e Lamp \u5bf9\u8c61\u7684\u4f9d\u8d56\u5173\u7cfb\uff0c\u5f97\u5230\u56fe 11 \u7684\u8bbe\u8ba1\uff0cButton \u73b0\u5728\u548c ButtonService \u63a5\u53e3\u5173\u8054\uff0cButtonService \u58f0\u660e\u4e86\u4e00\u4e9b\u65b9\u6cd5\uff0cButton \u53ef\u4ee5\u4f7f\u7528 ButtonService \u7684\u65b9\u6cd5\u5f00\u542f\u6216\u5173\u95ed\u4e00\u4e9b\u8bbe\u5907\uff0cLamp \u5b9e\u73b0\u4e86 ButtonService \u63a5\u53e3\uff0c\u8fd9\u6837 Lamp \u4e0d\u518d\u88ab Button \u76f4\u63a5\u4f9d\u8d56\uff0c\u800c\u4e14 Button \u53ef\u4ee5\u63a7\u5236\u4efb\u4f55\u5b9e\u73b0\u4e86 ButtonService \u63a5\u53e3\u7684\u8bbe\u5907\u3002<\/p><p><img src=\"https:\/\/sunpe.github.io\/images\/solid\/11.png\" alt=\"\">\u56fe 11 \u5bf9 Lamp \u5e94\u7528\u4f9d\u8d56\u5012\u7f6e\u539f\u5219<\/p><p>\u9762\u5411\u5bf9\u8c61\u7684\u7a0b\u5e8f\u8bbe\u8ba1\u5012\u7f6e\u4e86\u4f9d\u8d56\u5173\u7cfb\uff0c\u7ec6\u8282\u548c\u9ad8\u5c42\u6a21\u5757\u90fd\u4f9d\u8d56\u4e8e\u62bd\u8c61\uff0c\u5e76\u4e14\u5e38\u5e38\u662f\u63a5\u53e3\u4f7f\u7528\u65b9\u63d0\u4f9b\u670d\u52a1\u63a5\u53e3\uff0c\u5373\u63a5\u53e3\u6240\u6709\u6743\u4e5f\u5012\u7f6e\u4e86\u3002\u9996\u76f8\u548c\u7ec6\u8282\u5f7c\u6b64\u9694\u79bb\uff0c\u4ee3\u7801\u4e5f\u66f4\u5bb9\u6613\u7ef4\u62a4\u3002<\/p><h2 id=\"\u63a5\u53e3\u9694\u79bb\u539f\u5219interface-segregation-principlesisp\">\u63a5\u53e3\u9694\u79bb\u539f\u5219\uff08Interface-Segregation principles\uff0cISP\uff09<\/h2><p>\u4e0d\u5e94\u8be5\u5f3a\u8feb\u5ba2\u6237\u7a0b\u5e8f\u4f9d\u8d56\u4e8e\u5b83\u4eec\u4e0d\u4f7f\u7528\u7684\u65b9\u6cd5\u3002<\/p><p>\u63a5\u53e3\u9694\u79bb\u539f\u5219\u7528\u6765\u5904\u7406\u300c\u80d6\u63a5\u53e3\u300d\u7684\u7f3a\u70b9\u3002\u5982\u679c\u63a5\u53e3\u4e0d\u662f\u5185\u805a\u7684\uff0c\u5c31\u8868\u793a\u8be5\u63a5\u53e3\u662f\u300c\u80d6\u63a5\u53e3\u300d\u3002\u300c\u80d6\u63a5\u53e3\u300d\u53ef\u4ee5\u5206\u89e3\u6210\u591a\u7ec4\u65b9\u6cd5\uff0c\u6bcf\u7ec4\u65b9\u6cd5\u670d\u52a1\u4e8e\u4e00\u7ec4\u4e0d\u540c\u7684\u5ba2\u6237\u7a0b\u5e8f\u3002<\/p><p>\u5982\u679c\u5f3a\u8feb\u5ba2\u6237\u7a0b\u5e8f\u4f9d\u8d56\u4e8e\u5b83\u4eec\u4e0d\u4f7f\u7528\u7684\u65b9\u6cd5\uff0c\u90a3\u4e48\u5ba2\u6237\u7a0b\u5e8f\u5c31\u53ef\u80fd\u4f1a\u7531\u4e8e\u8fd9\u4e9b\u672a\u4f7f\u7528\u7684\u65b9\u6cd5\u7684\u6539\u53d8\u800c\u53d8\u66f4\uff0c\u65e0\u610f\u4e2d\u5bfc\u81f4\u4e86\u6240\u6709\u5ba2\u6237\u7a0b\u5e8f\u4e4b\u95f4\u7684\u8026\u5408\u3002\u6362\u53e5\u8bdd\u8bf4\uff0c\u5982\u679c\u4e00\u4e2a\u5ba2\u6237\u7a0b\u5e8f\u4f9d\u8d56\u4e8e\u4e00\u4e2a\u5305\u542b\u5b83\u4e0d\u4f7f\u7528\u7684\u65b9\u6cd5\u7684\u7c7b\uff0c\u4f46\u662f\u5176\u4ed6\u5ba2\u6237\u7a0b\u5e8f\u5374\u8981\u4f7f\u7528\u8fd9\u4e2a\u65b9\u6cd5\uff0c\u90a3\u4e48\u5f53\u5176\u4ed6\u5ba2\u6237\u8981\u6c42\u8fd9\u4e2a\u7c7b\u6539\u53d8\u65f6\uff0c\u5c31\u4f1a\u5f71\u54cd\u5230\u8fd9\u4e2a\u5ba2\u6237\u7a0b\u5e8f\u3002\u6211\u4eec\u5e0c\u671b\u5c3d\u53ef\u80fd\u7684\u907f\u514d\u8fd9\u79cd\u8026\u5408\uff0c\u56e0\u6b64\u9700\u8981\u5206\u79bb\u63a5\u53e3\u3002<\/p><p>\u8bbe\u8ba1\u4e00\u4e2a\u5b89\u5168\u7cfb\u7edf\uff0c\u6709\u4e00\u4e9b Door \u5bf9\u8c61\uff0c\u53ef\u4ee5\u88ab\u52a0\u9501\u548c\u89e3\u9501\uff0c\u5e76\u4e14 Door \u5bf9\u8c61\u77e5\u9053\u81ea\u5df1\u7684\u5f00\u5173\u72b6\u6001\uff1b\u8bbe\u8ba1\u4e00\u4e2a TimeDoor \u5bf9\u8c61\uff0c\u5982\u679c\u4eec\u5f00\u7740\u65f6\u95f4\u8fc7\u957f\uff0c\u5219\u53d1\u51fa\u8b66\u544a\u58f0\u3002\u6240\u4ee5 TimeDoor \u5bf9\u8c61\u9700\u8981\u548c\u5b9a\u65f6\u5668 Timer\u4ea4\u4e92\u3002\u5b9a\u65f6\u5668 Timer \u5982\u7a0b\u5e8f 4\u3002<\/p><div class=\"highlight\"><pre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"><code class=\"language-java\" data-lang=\"java\"><span style=\"display:flex;\"><span><span style=\"color:#66d9ef\">public<\/span> <span style=\"color:#66d9ef\">class<\/span> <span style=\"color:#a6e22e\">Timer<\/span> {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">void<\/span> <span style=\"color:#a6e22e\">register<\/span>(<span style=\"color:#66d9ef\">int<\/span> timeout, TimeClient client) {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#75715e\">\/\/ ...<\/span><\/span><\/span><span style=\"display:flex;\"><span> }<\/span><\/span><span style=\"display:flex;\"><span>}<\/span><\/span><span style=\"display:flex;\"><span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#66d9ef\">public<\/span> <span style=\"color:#66d9ef\">interface<\/span> <span style=\"color:#a6e22e\">TimeClient<\/span> {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">void<\/span> <span style=\"color:#a6e22e\">timeout<\/span>();<\/span><\/span><span style=\"display:flex;\"><span>}<\/span><\/span><\/code><\/pre><\/div><p>\u600e\u4e48\u5c06 TimeClient \u548c TimeDoor \u8054\u7cfb\u8d77\u6765\u5462\uff1f\u56fe 12 \u5c55\u793a\u4e86\u4e00\u4e2a\u6613\u4e8e\u7406\u89e3\u7684\u65b9\u6848\uff0c\u8ba9 Door \u6d3e\u751f\u81ea TimeClient\uff0c\u8fd9\u6837 TimeDoor \u5c31\u81ea\u7136\u7684\u53ef\u4ee5\u6ce8\u518c\u5230 Timer \u4e2d\uff0c\u5e76\u63a5\u6536\u5230 Timeout \u6d88\u606f\u3002<\/p><p><img src=\"https:\/\/sunpe.github.io\/images\/solid\/12.png\" alt=\"\">\u56fe 12<\/p><p>\u56fe 12 \u65b9\u6848\u7684\u4e3b\u8981\u95ee\u9898\u662f\uff0cDoor \u7c7b\u9700\u8981\u4f9d\u8d56\u4e8e TimeClient \u4e86\uff0c\u5e76\u4e0d\u662f\u6240\u6709\u7684 Door \u90fd\u9700\u8981\u5b9a\u65f6\u529f\u80fd\uff0c\u5982\u679c\u5b58\u5728\u65e0\u9700\u5b9a\u65f6\u7684 Door\uff0c\u90a3\u4e48\u5728\u65b0\u7684 Door \u4e2d\u9700\u8981\u63d0\u4f9b timeout \u65b9\u6cd5\u7684\u9000\u5316\u5b9e\u73b0\u3002\u800c\u4e14\u5176\u4ed6\u7684 Door \u4e5f\u4e0d\u9700\u8981 TimeClient \u5bf9\u8c61\uff0c\u4f46\u662f\u4f9d\u7136\u9700\u8981\u5f15\u5165 TimeClient\u3002\u8fd9\u6837 Door \u5177\u6709\u4e86\u4e0d\u5fc5\u8981\u7684\u590d\u6742\u6027\u4ee5\u53ca\u4e0d\u5fc5\u8981\u7684\u91cd\u590d\uff0cDoor \u88ab\u6c61\u67d3\u4e86\u3002<\/p><p>Door \u548c TimeClient \u63a5\u53e3\u662f\u88ab\u4e0d\u540c\u7684\u5ba2\u6237\u7a0b\u5e8f\u4f7f\u7528\u7684\uff0cTimer \u4f7f\u7528 TimeClient\uff0cTimeDoor \u4f7f\u7528 Door\uff0c\u65e2\u7136\u5ba2\u6237\u7a0b\u5e8f\u662f\u5206\u79bb\u7684\uff0c\u90a3\u4e48\u63a5\u53e3\u4e5f\u5e94\u8be5\u4fdd\u6301\u5206\u79bb\u3002<\/p><p>\u4e00\u79cd\u5206\u79bb\u65b9\u5f0f\u662f\u521b\u5efa\u4e00\u4e2a TimeClient\u7684\u6d3e\u751f\u7c7b DoorTimeAdapter\uff0c\u4f9d\u8d56 TimeDoor\uff0c\u5982 \u56fe13 \u6240\u793a\u3002DoorTimeAdapter \u6ce8\u518c\u5230 Timer\uff0c\u5f53 Timer \u5bf9\u8c61\u53d1\u9001 timeout \u6d88\u606f\u7ed9 DoorTimeAdapter \u65f6\uff0cDoorTimeAdapter \u628a\u8fd9\u4e2a\u6d88\u606f\u59d4\u6258\u7ed9 TimeDoor\u3002\u8fd9\u4e2a\u65b9\u6848\u907f\u514d\u4e86 Door \u548c Timer \u4e4b\u95f4\u7684\u8026\u5408\uff0cTimer \u7684\u6539\u52a8\u4e0d\u4f1a\u5f71\u54cd\u5230 Door \u7684\u4f7f\u7528\u8005\uff0cDoorTimeAdapter \u4f1a\u5c06 TimeDoor \u8f6c\u6362\u6210 TimeClient\uff0cTimeDoor \u4e5f\u65e0\u9700\u5b9e\u73b0 TimeClient \u7684\u65b9\u6cd5\u3002<\/p><p><img src=\"https:\/\/sunpe.github.io\/images\/solid\/13.png\" alt=\"\">\u56fe 13<\/p><p>\u4f46\u662f\u8fd9\u79cd adapter \u7684\u5904\u7406\u65b9\u5f0f\u6709\u4e9b\u590d\u6742\uff0c\u6211\u4eec\u53ef\u4ee5\u8ba9 TimeDoor \u540c\u65f6\u6d3e\u751f\u81ea TimeClient \u548c Door\uff0c\u5982\u56fe 14 \u6240\u793a\uff0c\u8fd9\u6837 Timer \u548c Door \u4e5f\u53ef\u4ee5\u505a\u5230\u89e3\u85d5\u3002\u901a\u5e38\u6211\u4eec\u4f1a\u4f18\u5148\u9009\u62e9\u8fd9\u4e2a\u65b9\u6848\u3002<\/p><p><img src=\"https:\/\/sunpe.github.io\/images\/solid\/14.png\" alt=\"\">\u56fe 14<\/p><p>\u300c\u80d6\u63a5\u53e3\u300d\u4f1a\u5bfc\u81f4\u5ba2\u6237\u7a0b\u5e8f\u4e4b\u95f4\u4ea7\u751f\u4e0d\u5fc5\u8981\u7684\u8026\u5408\u5173\u7cfb\uff0c\u300c\u80d6\u63a5\u53e3\u300d\u7684\u6539\u52a8\u53ef\u80fd\u4f1a\u5f71\u54cd\u6240\u6709\u5ba2\u6237\u7a0b\u5e8f\u3002\u5ba2\u6237\u7a0b\u5e8f\u5e94\u8be5\u4ec5\u4ec5\u4f9d\u8d56\u4ed6\u4eec\u5b9e\u9645\u9700\u8981\u7684\u65b9\u6cd5\uff0c\u53ef\u4ee5\u901a\u8fc7\u628a\u300c\u80d6\u63a5\u53e3\u300d\u5206\u89e3\u4e3a\u591a\u4e2a\u63a5\u53e3\u6765\u5b9e\u73b0\u5ba2\u6237\u7a0b\u5e8f\u548c\u4e0d\u9700\u8981\u7684\u65b9\u6cd5\u95f4\u7684\u89e3\u85d5\uff0c\u5e76\u4f7f\u5ba2\u6237\u7a0b\u5e8f\u4e4b\u95f4\u4e92\u4e0d\u4f9d\u8d56\u3002<\/p>"},{"title":"\u654f\u6377\u8f6f\u4ef6\u5f00\u53d1\u539f\u5219","link":"https:\/\/sunpe.github.io\/posts\/2020-11-25-principles-of-agile-software-development\/","pubDate":"Wed, 25 Nov 2020 22:00:00 +0800","guid":"https:\/\/sunpe.github.io\/posts\/2020-11-25-principles-of-agile-software-development\/","description":"<h2 id=\"\u6211\u4eec\u6700\u4f18\u5148\u8981\u505a\u7684\u662f\u901a\u8fc7\u8fde\u7eed\u4e0d\u65ad\u7684\u53ca\u65e9\u7684\u4ea4\u4ed8\u6709\u4ef7\u503c\u7684\u8f6f\u4ef6\u4f7f\u5ba2\u6237\u6ee1\u610f\">\u6211\u4eec\u6700\u4f18\u5148\u8981\u505a\u7684\u662f\u901a\u8fc7\u8fde\u7eed\u4e0d\u65ad\u7684\u53ca\u65e9\u7684\u4ea4\u4ed8\u6709\u4ef7\u503c\u7684\u8f6f\u4ef6\u4f7f\u5ba2\u6237\u6ee1\u610f<\/h2><p>\u300aProduct-Development Practices That Work: How Internet Companies Build Software\u300b\u8bba\u6587\u5206\u6790\u4e86\u5bf9\u4e8e\u516c\u53f8\u6784\u5efa\u9ad8\u8d28\u91cf\u4ea7\u54c1\u65b9\u9762\u6709\u5e2e\u52a9\u7684\u8f6f\u4ef6\u5f00\u53d1\u5b9e\u8df5, \u53d1\u73b0\u5c3d\u65e9\u4ea4\u4ed8\u5177\u6709\u90e8\u5206\u529f\u80fd\u7684\u7cfb\u7edf\u548c\u7cfb\u7edf\u8d28\u91cf\u4e4b\u95f4\u5177\u6709\u5f88\u5f3a\u7684\u76f8\u5173\u6027, \u8bba\u6587\u6307\u51fa \u521d\u671f\u4ea4\u4ed8\u7684\u7cfb\u7edf\u4e2d\u6240\u5305\u542b\u7684\u529f\u80fd\u8d8a\u5c11, \u6700\u7ec8\u4ea4\u4ed8\u7684\u7cfb\u7edf\u8d28\u91cf\u5c31\u4f1a\u8d8a\u9ad8. \u8be5\u8bba\u6587\u7684\u53e6\u4e00\u9879\u53d1\u73b0\u662f, \u4ee5\u9010\u6e10\u589e\u52a0\u529f\u80fd\u7684\u65b9\u5f0f\u7ecf\u5e38\u6027\u7684\u4ea4\u4ed8\u7cfb\u7edf\u548c\u6700\u7ec8\u8d28\u91cf\u4e4b\u95f4\u6709\u7740\u975e\u5e38\u5f3a\u7684\u76f8\u5173\u6027, \u4ea4\u4ed8\u7684\u8d8a\u9891\u7e41, \u6700\u7ec8\u4ea7\u54c1\u7684\u8d28\u91cf\u5c31\u8d8a\u9ad8.<\/p><p>\u654f\u6377\u5b9e\u8df5\u4f1a\u5c3d\u65e9\u3001\u7ecf\u5e38\u7684\u8fdb\u884c\u4ea4\u4ed8, \u6211\u4eec\u52aa\u529b\u5728\u9879\u76ee\u521a\u5f00\u59cb\u7684\u51e0\u5468\u5185\u4ea4\u4ed8\u4e00\u4e2a\u5177\u6709\u57fa\u672c\u529f\u80fd\u7684\u7cfb\u7edf, \u7136\u540e\u52aa\u529b\u575a\u6301\u6bcf\u4e24\u5468\u5c31\u4ea4\u4ed8\u4e00\u4e2a\u529f\u80fd\u6e10\u589e\u7684\u7cfb\u7edf.<\/p><h2 id=\"\u6b23\u7136\u9762\u5bf9\u9700\u6c42\u53d8\u5316-\u5373\u4f7f\u5230\u4e86\u5f00\u53d1\u540e\u671f\u4e5f\u4e00\u6837-\u654f\u6377\u8fc7\u7a0b\u5229\u7528\u53d8\u5316\u6765\u4e3a\u5ba2\u6237\u521b\u9020\u7ade\u4e89\u4f18\u52bf\">\u6b23\u7136\u9762\u5bf9\u9700\u6c42\u53d8\u5316, \u5373\u4f7f\u5230\u4e86\u5f00\u53d1\u540e\u671f\u4e5f\u4e00\u6837. \u654f\u6377\u8fc7\u7a0b\u5229\u7528\u53d8\u5316\u6765\u4e3a\u5ba2\u6237\u521b\u9020\u7ade\u4e89\u4f18\u52bf<\/h2><p>\u654f\u6377\u8fc7\u7a0b\u7684\u53c2\u4e0e\u8005\u4e0d\u60e7\u6015\u53d8\u5316, \u4ed6\u4eec\u8ba4\u4e3a\u6539\u53d8\u9700\u6c42\u662f\u597d\u7684\u4e8b\u60c5. \u654f\u6377\u56e2\u961f\u4f1a\u975e\u5e38\u52aa\u529b\u7684\u4fdd\u6301\u8f6f\u4ef6\u7ed3\u6784\u7684\u7075\u6d3b\u6027, \u8fd9\u6837\u5f53\u9700\u6c42\u53d8\u5316\u65f6, \u5bf9\u4e8e\u7cfb\u7edf\u9020\u6210\u7684\u5f71\u54cd\u662f\u6700\u5c0f\u7684.<\/p><h2 id=\"\u7ecf\u5e38\u6027\u7684\u4ea4\u4ed8\u53ef\u4ee5\u5de5\u4f5c\u7684\u8f6f\u4ef6-\u4ea4\u4ed8\u7684\u95f4\u9694\u53ef\u4ee5\u4ece\u51e0\u5468\u5230\u51e0\u4e2a\u6708-\u503e\u5411\u4e8e\u91c7\u53d6\u8f83\u77ed\u7684\u5468\u671f\">\u7ecf\u5e38\u6027\u7684\u4ea4\u4ed8\u53ef\u4ee5\u5de5\u4f5c\u7684\u8f6f\u4ef6, \u4ea4\u4ed8\u7684\u95f4\u9694\u53ef\u4ee5\u4ece\u51e0\u5468\u5230\u51e0\u4e2a\u6708, \u503e\u5411\u4e8e\u91c7\u53d6\u8f83\u77ed\u7684\u5468\u671f<\/h2><p>\u6211\u4eec\u4ea4\u4ed8\u53ef\u4ee5\u5de5\u4f5c\u7684\u8f6f\u4ef6, \u5e76\u4e14\u5c3d\u65e9\u7684(\u9879\u76ee\u521a\u5f00\u59cb\u7684\u51e0\u5468\u540e)\u3001 \u7ecf\u5e38\u6027\u7684(\u6b64\u540e\u6bcf\u9694\u51e0\u5468)\u4ea4\u4ed8\u5b83. \u6211\u4eec\u4e0d\u8d5e\u6210\u4ea4\u4ed8\u5927\u91cf\u7684\u6587\u6863\u6216\u8005\u8ba1\u5212, \u6211\u4eec\u8ba4\u4e3a\u90a3\u4e0d\u662f\u771f\u6b63\u8981\u4ea4\u4ed8\u7684\u4e1c\u897f, \u6211\u4eec\u5173\u6ce8\u7684\u76ee\u6807\u662f\u4ea4\u4ed8\u6ee1\u8db3\u5ba2\u6237\u9700\u8981\u7684\u8f6f\u4ef6.<\/p><h2 id=\"\u4e1a\u52a1\u4eba\u5458\u548c\u5f00\u53d1\u4eba\u5458\u5fc5\u987b\u76f8\u4e92\u5408\u4f5c-\u9879\u76ee\u7684\u6bcf\u4e00\u5929\u90fd\u4e0d\u4f8b\u5916\">\u4e1a\u52a1\u4eba\u5458\u548c\u5f00\u53d1\u4eba\u5458\u5fc5\u987b\u76f8\u4e92\u5408\u4f5c, \u9879\u76ee\u7684\u6bcf\u4e00\u5929\u90fd\u4e0d\u4f8b\u5916<\/h2><p>\u4e3a\u4e86\u80fd\u591f\u4ee5\u654f\u6377\u7684\u65b9\u5f0f\u8fdb\u884c\u9879\u76ee\u7684\u5f00\u53d1, \u5ba2\u6237\u3001 \u5f00\u53d1\u4eba\u5458\u4ee5\u53ca\u6d89\u4f17\u4e4b\u95f4\u5c31\u5fc5\u987b\u8981\u8fdb\u884c\u6709\u610f\u4e49\u7684\u9891\u7e41\u7684\u4ea4\u4e92<\/p><h2 id=\"\u6fc0\u53d1\u4e2a\u4f53\u7684\u6597\u5fd7-\u4ee5\u4ed6\u4eec\u4e3a\u6838\u5fc3\u642d\u5efa\u9879\u76ee-\u63d0\u4f9b\u6240\u9700\u7684\u73af\u5883\u548c\u652f\u6301\u5e76\u4e14\u4fe1\u4efb\u4ed6\u4eec\u80fd\u591f\u5b8c\u6210\u5de5\u4f5c\">\u6fc0\u53d1\u4e2a\u4f53\u7684\u6597\u5fd7, \u4ee5\u4ed6\u4eec\u4e3a\u6838\u5fc3\u642d\u5efa\u9879\u76ee. \u63d0\u4f9b\u6240\u9700\u7684\u73af\u5883\u548c\u652f\u6301\uff0c\u5e76\u4e14\u4fe1\u4efb\u4ed6\u4eec\u80fd\u591f\u5b8c\u6210\u5de5\u4f5c<\/h2><p>\u654f\u6377\u9879\u76ee\u4e2d, \u4eba\u88ab\u8ba4\u4e3a\u662f\u9879\u76ee\u53d6\u5f97\u6210\u529f\u7684\u6700\u91cd\u8981\u7684\u56e0\u7d20. \u6240\u6709\u5176\u4ed6\u56e0\u7d20\u2014\u8fc7\u7a0b\u3001\u73af\u5883\u3001\u7ba1\u7406\u7b49\u7b49\u2014\u90fd\u88ab\u8ba4\u4e3a\u662f\u6b21\u8981\u7684, \u5e76\u4e14\u5f53\u5b83\u4eec\u5bf9\u4e8e\u4eba\u6709\u8d1f\u9762\u7684\u5f71\u54cd\u65f6, \u5c31\u8981\u5bf9\u5b83\u4eec\u8fdb\u884c\u6539\u53d8. \u4f8b\u5982\u5982\u679c\u529e\u516c\u73af\u5883\u5bf9\u962e\u5bf9\u7684\u5de5\u4f5c\u9020\u6210\u963b\u788d, \u5c31\u5fc5\u987b\u5bf9\u529e\u516c\u73af\u5883\u8fdb\u884c\u6539\u53d8; \u5982\u679c\u67d0\u4e9b\u8fc7\u7a0b\u6b65\u9aa4\u5bf9\u56e2\u961f\u7684\u5de5\u4f5c\u9020\u6210\u963b\u788d, \u5c31\u5fc5\u987b\u5bf9\u90a3\u4e9b\u8fc7\u7a0b\u548c\u6b65\u9aa4\u8fdb\u884c\u6539\u53d8.<\/p><h2 id=\"\u4e0d\u8bba\u56e2\u961f\u5185\u5916-\u6700\u6709\u6548\u679c\u5e76\u4e14\u5bcc\u6709\u6548\u7387\u7684\u4f20\u9012\u4fe1\u606f\u7684\u65b9\u6cd5-\u5c31\u662f\u9762\u5bf9\u9762\u4ea4\u8c08\">\u4e0d\u8bba\u56e2\u961f\u5185\u5916, \u6700\u6709\u6548\u679c\u5e76\u4e14\u5bcc\u6709\u6548\u7387\u7684\u4f20\u9012\u4fe1\u606f\u7684\u65b9\u6cd5, \u5c31\u662f\u9762\u5bf9\u9762\u4ea4\u8c08<\/h2><p>\u654f\u6377\u9879\u76ee\u4e2d, \u4eba\u4eec\u4e4b\u95f4\u76f8\u4e92\u6c9f\u901a, \u9996\u8981\u7684\u65b9\u5f0f\u5c31\u662f\u4ea4\u8c08. \u56e2\u961f\u53ef\u80fd\u4f1a\u7f16\u5199\u6587\u6863, \u4f46\u6587\u6863\u4e0d\u662f\u9ed8\u8ba4\u7684\u6c9f\u901a\u65b9\u5f0f, \u56e2\u961f\u6210\u5458\u8fdb\u515a\u8feb\u5207\u9700\u8981\u5e76\u610f\u4e49\u91cd\u5927\u7684\u60c5\u51b5\u4e0b\u624d\u53bb\u7f16\u5199\u6587\u6863, \u9ed8\u8ba4\u7684\u6c9f\u901a\u65b9\u5f0f\u662f\u4ea4\u8c08<\/p><h2 id=\"\u53ef\u5de5\u4f5c\u7684\u8f6f\u4ef6\u662f\u8fdb\u5ea6\u7684\u9996\u8981\u5ea6\u91cf\u6807\u51c6\">\u53ef\u5de5\u4f5c\u7684\u8f6f\u4ef6\u662f\u8fdb\u5ea6\u7684\u9996\u8981\u5ea6\u91cf\u6807\u51c6<\/h2><p>\u654f\u6377\u9879\u76ee\u901a\u8fc7\u5ea6\u91cf\u5f53\u524d\u8f6f\u4ef6\u6ee1\u8db3\u5ba2\u6237\u9700\u6c42\u7684\u6570\u91cf\u6765\u5ea6\u91cf\u5f00\u53d1\u8fdb\u5ea6.<\/p><h2 id=\"\u654f\u6377\u8fc7\u7a0b\u5021\u5bfc\u53ef\u6301\u7eed\u7684\u5f00\u53d1\u901f\u5ea6-\u8d23\u4efb\u4eba\u5f00\u53d1\u8005\u548c\u7528\u6237\u5e94\u8be5\u4fdd\u6301\u4e00\u4e2a\u957f\u671f\u7684-\u6052\u5b9a\u7684\u5f00\u53d1\u901f\u5ea6\">\u654f\u6377\u8fc7\u7a0b\u5021\u5bfc\u53ef\u6301\u7eed\u7684\u5f00\u53d1\u901f\u5ea6. \u8d23\u4efb\u4eba\u3001\u5f00\u53d1\u8005\u548c\u7528\u6237\u5e94\u8be5\u4fdd\u6301\u4e00\u4e2a\u957f\u671f\u7684\u3001 \u6052\u5b9a\u7684\u5f00\u53d1\u901f\u5ea6<\/h2><p>\u654f\u6377\u9879\u76ee\u4e0d\u662f50m\u77ed\u8dd1, \u800c\u662f\u9a6c\u62c9\u677e\u957f\u8dd1. \u8dd1\u7684\u8fc7\u5feb\u4f1a\u5bfc\u81f4\u56e2\u961f\u7cbe\u529b\u8017\u5c3d. \u654f\u6377\u56e2\u961f\u4e0d\u5141\u8bb8\u81ea\u5df1\u8fc7\u4e8e\u75b2\u60eb, \u4e0d\u4f1a\u501f\u7528\u660e\u5929\u7684\u7cbe\u529b\u6765\u5728\u4eca\u5929\u591a\u5b8c\u6210\u4e00\u70b9\u5de5\u4f5c. \u4ed6\u4eec\u5de5\u4f5c\u5728\u4e00\u4e2a\u53ef\u4ee5\u4f7f\u5728\u6574\u4e2a\u9879\u76ee\u5f00\u53d1\u671f\u95f4\u4fdd\u6301\u6700\u9ad8\u8d28\u91cf\u6807\u51c6\u7684\u901f\u5ea6\u4e0a.<\/p><h2 id=\"\u4e0d\u65ad\u5173\u6ce8\u4f18\u79c0\u7684\u6280\u80fd\u548c\u597d\u7684\u8bbe\u8ba1\u4f1a\u589e\u5f3a\u654f\u6377\u80fd\u529b\">\u4e0d\u65ad\u5173\u6ce8\u4f18\u79c0\u7684\u6280\u80fd\u548c\u597d\u7684\u8bbe\u8ba1\u4f1a\u589e\u5f3a\u654f\u6377\u80fd\u529b<\/h2><p>\u5feb\u901f\u5f00\u53d1\u7684\u5173\u952e\u662f\u9ad8\u7684\u4ea7\u54c1\u8d28\u91cf, \u4fdd\u6301\u8f6f\u4ef6\u5c3d\u53ef\u80fd\u7684\u7b80\u6d01\u3001\u5065\u58ee\u624d\u80fd\u505a\u5230\u5feb\u901f\u5f00\u53d1. \u56e0\u6b64\u6240\u6709\u56e2\u961f\u6210\u5458\u90fd\u81f4\u529b\u4e8e\u53ea\u7f16\u5199\u4ed6\u4eec\u80fd\u591f\u7f16\u5199\u7684\u6700\u9ad8\u8d28\u91cf\u7684\u4ee3\u7801. \u4ed6\u4eec\u4e0d\u4f1a\u7f16\u5199\u6df7\u4e71\u7684\u4ee3\u7801\u7136\u540e\u544a\u8bc9\u81ea\u5df1\u7b49\u6709\u66f4\u591a\u7684\u5b9e\u8df5\u518d\u6765\u6e05\u7406\u4ed6\u4eec.<\/p><h2 id=\"\u4ee5\u7b80\u6d01\u4e3a\u672c\u662f\u6781\u529b\u51cf\u5c11\u4e0d\u5fc5\u8981\u5de5\u4f5c\u91cf\u7684\u827a\u672f\">\u4ee5\u7b80\u6d01\u4e3a\u672c,\u662f\u6781\u529b\u51cf\u5c11\u4e0d\u5fc5\u8981\u5de5\u4f5c\u91cf\u7684\u827a\u672f<\/h2><p>\u654f\u6377\u56e2\u961f\u4e0d\u4f1a\u8bd5\u56fe\u6784\u5efa\u534e\u800c\u4e0d\u5b9e\u7684\u7cfb\u7edf, \u4ed6\u4eec\u66f4\u613f\u610f\u91c7\u7528\u548c\u76ee\u6807\u4e00\u81f4\u7684\u6700\u7b80\u5355\u7684\u65b9\u6cd5. \u4ed6\u4eec\u4e0d\u4f1a\u770b\u91cd\u660e\u5929\u4f1a\u4e0d\u4f1a\u51fa\u73b0\u95ee\u9898, \u4e5f\u4e0d\u4f1a\u5728\u4eca\u5929\u5c31\u5bf9\u90a3\u4e9b\u53ef\u80fd\u51fa\u73b0\u7684\u95ee\u9898\u8fdb\u884c\u9632\u536b. \u76f8\u53cd, \u4ed6\u4eec\u5728\u4eca\u5929\u4ee5\u6700\u9ad8\u8d28\u91cf\u5b8c\u6210\u6700\u7b80\u5355\u7684\u5de5\u4f5c, \u8eab\u5fc3\u5982\u679c\u660e\u5929\u53d1\u751f\u4e86\u95ee\u9898, \u4e5f\u4f1a\u5f88\u5bb9\u6613\u5904\u7406.<\/p><h2 id=\"\u6700\u597d\u7684\u67b6\u6784-\u9700\u6c42\u548c\u8bbe\u8ba1\u51fa\u81ea\u4e8e\u81ea\u7ec4\u7ec7\u7684\u56e2\u961f\">\u6700\u597d\u7684\u67b6\u6784\u3001 \u9700\u6c42\u548c\u8bbe\u8ba1\u51fa\u81ea\u4e8e\u81ea\u7ec4\u7ec7\u7684\u56e2\u961f<\/h2><p>\u654f\u6377\u56e2\u961f\u662f\u81ea\u7ec4\u7ec7\u7684\u56e2\u961f, \u4efb\u52a1\u4e0d\u662f\u4ece\u5916\u90e8\u5206\u914d\u7ed9\u5355\u4e2a\u56e2\u961f\u6210\u5458, \u800c\u662f\u5206\u914d\u7ed9\u6574\u4e2a\u56e2\u961f, \u7136\u540e\u518d\u6709\u56e2\u961f\u6765\u786e\u5b9a\u5b8c\u6210\u4efb\u52a1\u7684\u6700\u597d\u65b9\u6cd5. \u654f\u6377\u56e2\u961f\u7684\u6210\u5458\u5171\u540c\u89e3\u51b3\u9879\u76ee\u4e2d\u6240\u6709\u7684\u95ee\u9898. \u6bcf\u4e00\u4e2a\u6210\u5458\u90fd\u5177\u6709\u9879\u76ee\u4e2d\u6240\u6709\u65b9\u9762\u7684\u53c2\u4e0e\u6743\u5229. \u4e0d\u5b58\u5728\u5355\u4e00\u7684\u56e2\u961f\u6210\u5458\u5bf9\u7cfb\u7edf\u7684\u67b6\u6784\u3001\u9700\u6c42\u6216\u8005\u6d4b\u8bd5\u8d1f\u8d23\u7684\u60c5\u51b5, \u6574\u4e2a\u56e2\u961f\u5171\u540c\u627f\u62c5\u90a3\u4e9b\u8d23\u4efb, \u6bcf\u4e00\u4e2a\u56e2\u961f\u6210\u5458\u90fd\u80fd\u591f\u5f71\u54cd\u5b83\u4eec<\/p><h2 id=\"\u56e2\u961f\u5b9a\u671f\u7684\u53cd\u601d\u5982\u4f55\u80fd\u63d0\u9ad8\u6210\u6548-\u5e76\u4ee5\u6b64\u8c03\u6574\u81ea\u8eab\u7684\u4e3e\u6b62\u8868\u73b0\">\u56e2\u961f\u5b9a\u671f\u7684\u53cd\u601d\u5982\u4f55\u80fd\u63d0\u9ad8\u6210\u6548, \u5e76\u4ee5\u6b64\u8c03\u6574\u81ea\u8eab\u7684\u4e3e\u6b62\u8868\u73b0<\/h2><p>\u654f\u6377\u56e2\u961f\u4f1a\u4e0d\u65ad\u7684\u5bf9\u56e2\u961f\u7684\u7ec4\u7ec7\u65b9\u5f0f\u3001\u89c4\u5219\u3001\u89c4\u8303\u3001\u5173\u7cfb\u7b49\u8fdb\u884c\u8c03\u6574, \u654f\u6377\u56e2\u961f\u76f4\u5230\u56e2\u961f\u6240\u5904\u7684\u73af\u5883\u5728\u4e0d\u65ad\u53d8\u5316, \u5e76\u4e14\u76f4\u5230\u4e3a\u4e86\u4fdd\u6301\u56e2\u961f\u7684\u654f\u6377\u6027, \u56e2\u961f\u9700\u8981\u968f\u7740\u73af\u5883\u4e00\u8d77\u53d8\u5316.<\/p><h2 id=\"\u603b\u7ed3\">\u603b\u7ed3<\/h2><p>\u6bcf\u4e00\u4f4d\u8f6f\u4ef6\u5f00\u53d1\u4eba\u5458\u3001\u6bcf\u4e00\u4e2a\u5f00\u53d1\u56e2\u961f\u7684\u804c\u4e1a\u76ee\u6807\u90fd\u662f\u7ed9\u5ba2\u6237\u4ea4\u4ed8\u6700\u5927\u53ef\u80fd\u7684\u4ef7\u503c. \u53ef\u662f, \u6211\u4eec\u7684\u9879\u76ee\u4ee5\u4ee4\u4eba\u6cae\u4e27\u7684\u901f\u5ea6\u5931\u8d25, \u6216\u8005\u672a\u80fd\u4ea4\u4ed8\u4efb\u4f55\u4ef7\u503c. \u867d\u7136\u5728\u9879\u76ee\u4e2d\u91c7\u7528\u8fc7\u7a0b\u65b9\u6cd5\u662f\u51fa\u4e8e\u597d\u610f, \u4f46\u662f\u81a8\u80c0\u7684\u8fc7\u7a0b\u5bf9\u4e0e\u9879\u76ee\u7684\u5931\u8d25\u6216\u591a\u6216\u5c11\u7684\u5e94\u8be5\u8d1f\u4e00\u4e9b\u8d23\u4efb. \u654f\u6377\u8f6f\u4ef6\u5f00\u53d1\u7684\u539f\u5219\u548c\u4ef7\u503c\u89c2\u6784\u6210\u4e86\u4e00\u4e2a\u53ef\u4ee5\u5e2e\u52a9\u56e2\u961f\u6253\u7834\u8fc7\u7a0b\u81a8\u80c0\u5faa\u73af\u7684\u65b9\u6cd5, \u8fd9\u4e2a\u65b9\u6cd5\u5173\u6ce8\u7684\u662f\u53ef\u4ee5\u8fbe\u5230\u56e2\u961f\u76ee\u6807\u7684\u4e00\u4e9b\u7b80\u5355\u6280\u672f\u3002<\/p>"},{"title":"\u654f\u6377\u8f6f\u4ef6\u5f00\u53d1\u5ba3\u8a00","link":"https:\/\/sunpe.github.io\/posts\/2020-11-20-manifesto-for-agile-software-development\/","pubDate":"Fri, 20 Nov 2020 22:00:00 +0800","guid":"https:\/\/sunpe.github.io\/posts\/2020-11-20-manifesto-for-agile-software-development\/","description":"<p>\u7531\u4e8e\u770b\u5230\u4f17\u591a\u56e2\u961f\u9677\u5165\u4e86\u4e0d\u65ad\u589e\u957f\u7684\u8fc7\u7a0b\u7684\u6ce5\u6f6d\uff0c\u4e00\u6279\u4e1a\u754c\u4e13\u5bb6\u6982\u62ec\u51fa\u4e86\u4e00\u4e9b\u53ef\u4ee5\u8ba9\u8f6f\u4ef6\u5f00\u53d1\u56e2\u961f\u5177\u6709\u5feb\u901f\u5de5\u4f5c\u3001\u54cd\u5e94\u53d8\u5316\u80fd\u529b\u7684\u4ef7\u503c\u89c2\u548c\u539f\u5219\uff0c\u8fd9\u4e9b\u4e13\u5bb6\u79f0\u81ea\u5df1\u4e3a\u654f\u6377\uff08Agile\uff09\u8054\u76df\uff0c\u5e76\u521b\u9020\u51fa\u4e86\u4e00\u4efd\u4ef7\u503c\u89c2\u58f0\u660e\uff0c\u4e5f\u5c31\u662f\u654f\u6377\u8054\u76df\u5ba3\u8a00\u3002<\/p><h2 id=\"\u4e2a\u4f53\u548c\u4ea4\u4e92\u80dc\u8fc7\u8fc7\u7a0b\u548c\u5de5\u5177\">\u4e2a\u4f53\u548c\u4ea4\u4e92\u80dc\u8fc7\u8fc7\u7a0b\u548c\u5de5\u5177<\/h2><p>\u4eba\u662f\u83b7\u5f97\u6210\u529f\u7684\u6700\u4e3b\u8981\u56e0\u7d20\u3002\u5982\u679c\u56e2\u961f\u4e2d\u6ca1\u6709\u4f18\u79c0\u7684\u6210\u5458\uff0c\u90a3\u4e48\u5c31\u662f\u518d\u597d\u7684\u8fc7\u7a0b\u4e5f\u4e0d\u80fd\u633d\u6551\u5931\u8d25\u7684\u9879\u76ee\u3002\u4f46\u662f\u4e0d\u597d\u7684\u8fc7\u7a0b\u53ef\u4ee5\u4f7f\u4f18\u79c0\u7684\u56e2\u961f\u6210\u5458\u5931\u53bb\u4f5c\u7528\u3002\u5982\u679c\u56e2\u961f\u6210\u5458\u4e0d\u80fd\u4f5c\u4e3a\u4e00\u4e2a\u56e2\u961f\u8fdb\u884c\u5de5\u4f5c\uff0c\u90a3\u4e48\u5373\u4f7f\u62e5\u6709\u4e00\u6279\u4f18\u79c0\u7684\u6210\u5458\u4e5f\u4e00\u6837\u4f1a\u5931\u8d25\u3002<\/p><p>\u4e00\u4e2a\u4f18\u79c0\u7684\u56e2\u961f\u6210\u5458\u4e0d\u4e00\u5b9a\u8981\u662f\u4e00\u4e2a\u4e00\u6d41\u7684\u7a0b\u5e8f\u5458\uff0c\u53ef\u4ee5\u662f\u4e00\u4e2a\u5e73\u5747\u6c34\u5e73\u7684\u7a0b\u5e8f\u5458\uff0c\u4f46\u662f\u5374\u80fd\u591f\u5f88\u597d\u7684\u548c\u4ed6\u4eba\u5408\u4f5c\u3002\u5408\u4f5c\u3001 \u6c9f\u901a\u4ee5\u53ca\u4ea4\u4e92\u80fd\u529b\u8981\u6bd4\u5355\u7eaf\u7684\u7f16\u7a0b\u80fd\u529b\u66f4\u91cd\u8981\u3002<\/p><p>\u5408\u9002\u7684\u5de5\u5177\u975e\u5e38\u91cd\u8981\uff0c\u6bd4\u5982\u7f16\u8bd1\u5668\u3001 IDE\u3001 \u6e90\u7801\u7ba1\u7406\u7cfb\u7edf\u7b49\u3002\u7136\u800c\u4f7f\u7528\u8fc7\u591a\u7684\u5e9e\u5927\u3001\u7b28\u91cd\u7684\u5de5\u5177\u548c\u7f3a\u5c11\u5de5\u5177\u4e00\u6837\uff0c\u90fd\u662f\u4e0d\u597d\u7684\u3002\u5927\u800c\u7b28\u91cd\u7684\u5de5\u5177\u5e26\u6765\u7684\u969c\u788d\u5f80\u5f80\u5927\u4e8e\u5e26\u6765\u7684\u5e2e\u52a9\u3002\u4ece\u4f7f\u7528\u5c0f\u5de5\u5177\u5f00\u59cb\uff0c\u611f\u89c9\u5de5\u5177\u4e0d\u591f\u7528\u4e86\u518d\u53bb\u5bfb\u627e\u5148\u8fdb\u7684\u3001\u4ef7\u683c\u6602\u8d35\u7684\u5de5\u5177\u3002<\/p><p>\u56e2\u961f\u7684\u6784\u5efa\u6bd4\u73af\u5883\u6784\u5efa\u8981\u91cd\u8981\u7684\u591a\u3002\u8bb8\u591a\u7ba1\u7406\u8005\u5f80\u5f80\u5e0c\u671b\u5148\u6784\u5efa\u73af\u5883\uff0c\u7136\u540e\u671f\u671b\u56e2\u961f\u53ef\u4ee5\u81ea\u52a8\u51dd\u805a\u5728\u4e00\u8d77\uff0c \u7136\u800c\u5f80\u5f80\u4e8b\u4e0e\u613f\u8fdd\u3002\u5e94\u8be5\u9996\u5148\u81f4\u529b\u4e8e\u56e2\u961f\u5efa\u8bbe\uff0c\u7136\u540e\u518d\u8ba9\u56e2\u961f\u57fa\u4e8e\u9700\u8981\u6765\u914d\u7f6e\u73af\u5883\u3002<\/p><h2 id=\"\u53ef\u4ee5\u5de5\u4f5c\u7684\u8f6f\u4ef6\u80dc\u8fc7\u9762\u9762\u4ff1\u5230\u7684\u6587\u6863\">\u53ef\u4ee5\u5de5\u4f5c\u7684\u8f6f\u4ef6\u80dc\u8fc7\u9762\u9762\u4ff1\u5230\u7684\u6587\u6863<\/h2><p>\u6ca1\u6709\u6587\u6863\u7684\u8f6f\u4ef6\u662f\u4e00\u79cd\u707e\u96be\uff0c\u4ee3\u7801\u4e0d\u662f\u4f20\u8fbe\u7cfb\u7edf\u539f\u7406\u548c\u7ed3\u6784\u7684\u7406\u60f3\u5a92\u4ecb\uff0c\u56e2\u961f\u66f4\u9700\u8981\u7f16\u5199\u6613\u4e8e\u9605\u8bfb\u7684\u6587\u6863\uff0c\u6765\u63cf\u8ff0\u7cfb\u7edf\u4ee5\u53ca\u5176\u4ed6\u8bbe\u8ba1\u51b3\u7b56\u7684\u4f9d\u636e\u3002<\/p><p>\u7136\u800c\uff0c\u8fc7\u591a\u7684\u6587\u6863\u6bd4\u8fc7\u5c11\u7684\u6587\u6863\u66f4\u7cdf\u7cd5\u3002\u7f16\u5236\u4f17\u591a\u7684\u6587\u6863\u9700\u8981\u82b1\u8d39\u5927\u91cf\u65f6\u95f4\uff0c\u5e76\u4e14\u8981\u4f7f\u6587\u6863\u548c\u4ee3\u7801\u4fdd\u6301\u540c\u6b65\u5c31\u9700\u8981\u82b1\u8d39\u66f4\u591a\u65f6\u95f4\uff0c\u5982\u679c\u4ee3\u7801\u548c\u6587\u6863\u4e4b\u95f4\u5931\u53bb\u4e86\u540c\u6b65\uff0c\u90a3\u4e48\u6587\u6863\u5c31\u5931\u53bb\u4e86\u4f5c\u7528\uff0c\u751a\u81f3\u4f1a\u9020\u6210\u8bef\u5bfc\u3002<\/p><p>\u5bf9\u4e8e\u56e2\u961f\u6765\u8bf4\uff0c\u6709\u5fc5\u8981\u7f16\u5199\u5e76\u7ef4\u62a4\u4e00\u4efd\u7cfb\u7edf\u539f\u7406\u548c\u7ed3\u6784\u65b9\u9762\u7684\u6587\u6863\uff0c\u6587\u6863\u5e94\u8be5\u662f\u7bc7\u5e45\u77ed\u5c0f\u7684\u5e76\u4e14\u4e3b\u9898\u7a81\u51fa\u7684\uff0c\u5e94\u8be5\u4ec5\u8bba\u8ff0\u7cfb\u7edf\u7684\u9ad8\u5c42\u7ed3\u6784\u548c\u6982\u62ec\u7684\u8bbe\u8ba1\u539f\u7406\u3002<\/p><p>\u5728\u7ed9\u65b0\u7684\u56e2\u961f\u6210\u5458\u4f20\u6388\u77e5\u8bc6\u65b9\u9762\uff0c\u6700\u597d\u7684\u4e24\u4efd\u6587\u6863\u5c31\u662f\u4ee3\u7801\u548c\u56e2\u961f\u3002\u4ee3\u7801\u771f\u5b9e\u7684\u8868\u8fbe\u4e86\u5b83\u6240\u505a\u7684\u4e8b\u60c5\uff0c\u662f\u552f\u4e00\u6ca1\u6709\u4e8c\u4e49\u6027\u7684\u4fe1\u606f\u6e90\u3002\u5728\u56e2\u961f\u6210\u5458\u7684\u5927\u8111\u4e2d\uff0c\u4fdd\u5b58\u7740\u5e02\u573a\u53d8\u5316\u7684\u7cfb\u7edf\u8109\u7edc\u56fe\uff0c\u4eba\u548c\u4eba\u4e4b\u95f4\u7684\u4ea4\u4e92\u662f\u628a\u8fd9\u4efd\u8109\u7edc\u56fe\u4f20\u6388\u7ed9\u4ed6\u4eba\u7684\u6700\u5feb\u3001\u6700\u6709\u6548\u7684\u65b9\u5f0f\u3002<\/p><p>\u6240\u4ee5\u76f4\u5230\u8feb\u5207\u9700\u8981\u5e76\u4e14\u610f\u4e49\u91cd\u5927\u65f6\uff0c\u624d\u6765\u7f16\u5236\u6587\u6863\u3002<\/p><h2 id=\"\u5ba2\u6237\u5408\u4f5c\u80dc\u8fc7\u5408\u540c\u8c08\u5224\">\u5ba2\u6237\u5408\u4f5c\u80dc\u8fc7\u5408\u540c\u8c08\u5224<\/h2><p>\u544a\u8bc9\u7814\u53d1\u56e2\u961f\u60f3\u8981\u7684\u4e1c\u897f\uff0c\u7136\u540e\u671f\u671b\u7814\u53d1\u56e2\u961f\u6d88\u5931\u4e00\u6bb5\u65f6\u95f4\u540e\u5c31\u80fd\u591f\u4ea4\u4ed8\u4e00\u4e2a\u9700\u8981\u7684\u7cfb\u7edf\uff0c\u8fd9\u5bf9\u4e8e\u516c\u53f8\u7684\u7ba1\u7406\u8005\u6765\u8bf4\u662f\u5177\u6709\u8bf1\u60d1\u529b\u7684\uff0c\u7136\u540e\u8fd9\u79cd\u6a21\u5f0f\u7ec8\u5c06\u5bfc\u81f4\u4f4e\u52a3\u7684\u8d28\u91cf\u548c\u5931\u8d25\u3002\u6210\u529f\u7684\u9879\u76ee\u9700\u8981\u6709\u5e8f\u3001\u9891\u7e41\u7684\u5ba2\u6237\u53cd\u9988\u3002<\/p><p>\u4e00\u4e2a\u6307\u660e\u4e86\u9700\u6c42\u3001\u8fdb\u5ea6\u4ee5\u53ca\u9879\u76ee\u6210\u672c\u7684\u5408\u540c\u5b58\u5728\u6839\u672c\u4e0a\u7684\u7f3a\u9677\uff0c\u90a3\u4e9b\u4e3a\u7814\u53d1\u56e2\u961f\u548c\u5ba2\u6237\u7684\u534f\u540c\u5de5\u4f5c\u65b9\u5f0f\u63d0\u4f9b\u6307\u5bfc\u7684\u5408\u540c\u624d\u662f\u6700\u597d\u7684\u5408\u540c\u3002<\/p><h2 id=\"\u54cd\u5e94\u53d8\u5316\u80dc\u8fc7\u9075\u5faa\u8ba1\u5212\">\u54cd\u5e94\u53d8\u5316\u80dc\u8fc7\u9075\u5faa\u8ba1\u5212<\/h2><p>\u54cd\u5e94\u53d8\u5316\u7684\u80fd\u529b\u5e38\u5e38\u51b3\u5b9a\u7740\u4e00\u4e2a\u8f6f\u4ef6\u7684\u6210\u8d25\uff0c\u5f53\u6211\u4eec\u6784\u5efa\u8ba1\u5212\u65f6\uff0c\u5e94\u5f53\u786e\u4fdd\u8ba1\u5212\u662f\u7075\u6d3b\u7684\uff0c\u5e76\u4e14\u6613\u4e8e\u9002\u5e94\u5546\u52a1\u548c\u6280\u672f\u65b9\u9762\u7684\u53d8\u5316\u3002<\/p><p>\u8ba1\u5212\u4e0d\u80fd\u8003\u8651\u7684\u8fc7\u8fdc\u3002\u9996\u5148\uff0c\u5546\u52a1\u73af\u5883\u53ef\u80fd\u4f1a\u53d8\u5316\uff0c\u4f1a\u5f15\u8d77\u9700\u6c42\u7684\u53d8\u52a8\uff1b\u5176\u6b21\uff0c\u5ba2\u6237\u770b\u5230\u7cfb\u7edf\u540e\uff0c\u4ed6\u4eec\u5f88\u53ef\u80fd\u4f1a\u4fee\u6539\u9700\u6c42\uff1b\u6700\u540e\uff0c\u5373\u4f7f\u6211\u4eec\u719f\u6089\u9700\u6c42\uff0c\u5e76\u4e14\u786e\u4fe1\u4ed6\u4eec\u4e0d\u4f1a\u6539\u53d8\uff0c\u6211\u4eec\u4ecd\u7136\u4e0d\u80fd\u5f88\u597d\u7684\u4f30\u7b97\u51fa\u5f00\u53d1\u4ed6\u4eec\u9700\u8981\u7684\u65f6\u95f4\u3002<\/p><p>\u4e3a\u672a\u6765\u4e24\u5468\u505a\u8be6\u7ec6\u7684\u8ba1\u5212\uff0c\u4e3a\u672a\u6765\u4e09\u4e2a\u6708\u505a\u7c97\u7565\u7684\u8ba1\u5212\uff0c\u66f4\u8fdc\u7684\u65f6\u95f4\u5c31\u505a\u66f4\u4e3a\u7c97\u7cd9\u7684\u8ba1\u5212\u3002\u6211\u4eec\u5e94\u8be5\u6e05\u695a\u7684\u77e5\u9053\u672a\u6765\u4e24\u5468\u8981\u5b8c\u6210\u7684\u4efb\u52a1\uff0c\u7c97\u7565\u7684\u4e86\u89e3\u4e00\u4e0b\u672a\u6765\u4e09\u4e2a\u6708\u7684\u8ba1\u5212\uff0c\u81f3\u4e8e\u534a\u5e74\u540e\u751a\u81f3\u66f4\u4e45\u8fdc\u7684\u65f6\u95f4\uff0c\u6709\u4e00\u4e2a\u6a21\u7cca\u7684\u60f3\u6cd5\u5c31\u884c\u4e86\u3002\u7531\u8fd1\u53ca\u8fdc\u9010\u6e10\u964d\u4f4e\u7ec6\u81f4\u7a0b\u5ea6\uff0c\u4ec5\u4ec5\u5bf9\u4e8e\u8feb\u5207\u7684\u4efb\u52a1\u624d\u8017\u8d39\u65f6\u95f4\u8fdb\u884c\u8be6\u7ec6\u7684\u8ba1\u5212\uff0c\u4e00\u65e6\u5236\u5b9a\u4e86\u8fd9\u4e2a\u8be6\u7ec6\u7684\u8ba1\u5212\uff0c\u5c31\u5c3d\u91cf\u4e0d\u8981\u6539\u53d8\u3002\u8ba1\u5212\u4ec5\u4ec5\u652f\u914d\u4e86\u51e0\u5468\u7684\u65f6\u95f4\uff0c\u8ba1\u5212\u7684\u5176\u4f59\u90e8\u5206\u4ecd\u7136\u4fdd\u6301\u7740\u7075\u6d3b\u6027\u3002<\/p>"},{"title":"\u8bbe\u8ba1\u7684\u81ed\u5473\u2014\u8f6f\u4ef6\u8150\u5316\u7684\u6c14\u5473","link":"https:\/\/sunpe.github.io\/posts\/2020-11-10-the-smell-of-software-corruption\/","pubDate":"Tue, 10 Nov 2020 22:00:00 +0800","guid":"https:\/\/sunpe.github.io\/posts\/2020-11-10-the-smell-of-software-corruption\/","description":"<p>\u8bbe\u8ba1\u4e0d\u662f\u4e00\u7ec4\u548c\u4ee3\u7801\u5206\u79bb\u7684UML\u56fe, UML\u56fe\u4e5f\u8bb8\u63cf\u7ed8\u4e86\u8bbe\u8ba1\u7684\u4e00\u90e8\u5206, \u4f46\u662f\u5b83\u4e0d\u662f\u8bbe\u8ba1. \u8f6f\u4ef6\u9879\u76ee\u7684\u8bbe\u8ba1\u662f\u4e00\u4e2a\u62bd\u8c61\u7684\u6982\u5ff5, \u548c\u7a0b\u5e8f\u7684\u6982\u62ec\u5f62\u72b6(shape)\u3001\u7ed3\u6784\u3001\u4ee5\u53ca\u6bcf\u4e00\u4e2a\u6a21\u5757\u3001\u7c7b\u548c\u65b9\u6cd5\u7684\u8be6\u7ec6\u5f62\u72b6\u548c\u7ed3\u6784\u6709\u5173, \u53ef\u4ee5\u4f7f\u7528\u4e0d\u540c\u7684\u5a92\u4ecb\u53bb\u63cf\u7ed8\u5b83, \u4f46\u6700\u7ec8\u4f53\u73b0\u4e3a\u6e90\u7801, \u6700\u540e, \u6e90\u7801\u5c31\u662f\u8bbe\u8ba1.<\/p><h2 id=\"\u8bbe\u8ba1\u7684\u81ed\u5473\u8f6f\u4ef6\u8150\u5316\u7684\u6c14\u5473\">\u8bbe\u8ba1\u7684\u81ed\u5473\u2014\u8f6f\u4ef6\u8150\u5316\u7684\u6c14\u5473<\/h2><p>\u9879\u76ee\u521a\u5f00\u59cb\u751a\u81f3\u9996\u6b21\u53d1\u5e03\u65f6, \u7cfb\u7edf\u8bbe\u8ba1\u662f\u6e05\u6670\u7684, \u968f\u7740\u65f6\u95f4\u6d41\u5931, \u4e11\u964b\u7684\u8bbe\u8ba1\u548c\u5f0a\u75c5\u5728\u4ee3\u7801\u4e2d\u79ef\u7d2f, \u4f7f\u5176\u8d8a\u6765\u8d8a\u96be\u4ee5\u7ef4\u62a4, \u6700\u540e\u4ec5\u4ec5\u662f\u6700\u7b80\u5355\u7684\u66f4\u6539\u4e5f\u8981\u82b1\u8d39\u5de8\u5927\u7684\u4ee3\u4ef7, \u4ee5\u81f3\u4e8e\u5f00\u53d1\u4eba\u5458\u548c\u4e00\u7ebf\u7ba1\u7406\u4eba\u5458\u5f3a\u70c8\u8981\u6c42\u91cd\u65b0\u8bbe\u8ba1. \u8fd9\u6837\u7684\u8bbe\u8ba1\u5f88\u5c11\u4f1a\u6210\u529f, \u8001\u7cfb\u7edf\u4e0d\u65ad\u53d1\u5c55\u548c\u53d8\u5316, \u65b0\u7684\u8bbe\u8ba1\u5fc5\u987b\u8ddf\u4e0a\u8fd9\u4e9b\u53d8\u5316, \u6240\u4ee5\u65b0\u7cfb\u7edf\u7b2c\u4e00\u6b21\u53d1\u5e03\u5c31\u79ef\u7d2f\u4e86\u5f88\u591a\u7455\u75b5\u548c\u5f0a\u75c5.<\/p><p>\u5f53\u8f6f\u4ef6\u51fa\u73b0\u4e0b\u9762\u4efb\u4f55\u4e00\u79cd\u574f\u5473\u9053\u65f6, \u5c31\u8868\u660e\u8f6f\u4ef6\u6b63\u5728\u8150\u5316.<\/p><h3 id=\"1-\u50f5\u5316\u6027\">1. \u50f5\u5316\u6027<\/h3><p>\u5f88\u96be\u5bf9\u8f6f\u4ef6\u8fdb\u884c\u6539\u52a8, \u5373\u4fbf\u662f\u7b80\u5355\u7684\u6539\u52a8. \u5982\u679c\u5355\u4e00\u7684\u6539\u52a8\u4f1a\u5bfc\u81f4\u6709\u4f9d\u8d56\u5173\u7cfb\u7684\u6a21\u5757\u4e2d\u7684\u8fde\u9501\u6539\u52a8, \u90a3\u4e48\u8fd9\u6837\u7684\u8bbe\u8ba1\u5c31\u662f\u50f5\u5316\u7684, \u8981\u6539\u52a8\u7684\u6a21\u5757\u8d8a\u591a, \u8bbe\u8ba1\u5c31\u8d8a\u50f5\u5316<\/p><h3 id=\"2-\u8106\u5f31\u6027\">2. \u8106\u5f31\u6027<\/h3><p>\u5bf9\u7cfb\u7edf\u8fdb\u884c\u6539\u52a8\u65f6, \u4f1a\u5bfc\u81f4\u7cfb\u7edf\u4e2d\u548c\u6539\u52a8\u5730\u65b9\u5728\u6982\u5ff5\u4e0a\u65e0\u5173\u7684\u8bb8\u591a\u5730\u65b9\u51fa\u73b0\u95ee\u9898, \u8981\u4fee\u6b63\u8fd9\u4e9b\u95ee\u9898\u53c8\u4f1a\u5f15\u5165\u66f4\u591a\u7684\u95ee\u9898. \u968f\u7740\u8106\u5f31\u6027\u7684\u589e\u52a0, \u6539\u52a8\u4f1a\u8d8a\u5bb9\u6613\u5f15\u51fa\u610f\u60f3\u4e0d\u5230\u7684\u95ee\u9898. \u5f00\u53d1\u4eba\u5458\u77e5\u9053\u9700\u8981\u5bf9\u5b83\u4eec\u8fdb\u884c\u91cd\u65b0\u8bbe\u8ba1, \u4f46\u662f\u8d8a\u4fee\u6b63, \u5c31\u53d8\u5f97\u8d8a\u7cdf.<\/p><h3 id=\"3-\u7262\u56fa\u6027\">3. \u7262\u56fa\u6027<\/h3><p>\u8bbe\u8ba1\u4e2d\u5305\u542b\u4e86\u5bf9\u5176\u4ed6\u7cfb\u7edf\u6709\u7528\u7684\u90e8\u5206, \u4f46\u662f\u5f88\u96be\u89e3\u5f00\u7cfb\u7edf\u95f4\u7684\u7ea0\u7ed3, \u8981\u628a\u8fd9\u90e8\u5206\u4ece\u7cfb\u7edf\u4e2d\u5206\u79bb\u51fa\u6765\u9700\u8981\u7684\u52aa\u529b\u548c\u98ce\u9669\u90fd\u662f\u5de8\u5927\u7684.<\/p><h3 id=\"4-\u7c98\u6ede\u6027\">4. \u7c98\u6ede\u6027<\/h3><p>\u7c98\u6ede\u6027\u6709\u4e24\u79cd\u8868\u73b0: \u8f6f\u4ef6\u7684\u7c98\u6ede\u6027\u548c\u73af\u5883\u7684\u7c98\u6ede\u6027<\/p><p>\u8fdb\u884c\u7cfb\u7edf\u6539\u52a8\u65f6, \u5f00\u53d1\u4eba\u5458\u4f1a\u6709\u591a\u79cd\u6539\u52a8\u65b9\u5f0f, \u5176\u4e2d\u4e00\u4e9b\u4f1a\u4fdd\u6301\u8bbe\u8ba1, \u53e6\u5916\u4e00\u4e9b\u4f1a\u7834\u574f\u8bbe\u8ba1. \u5f53\u90a3\u4e9b\u53ef\u4ee5\u4fdd\u6301\u7cfb\u7edf\u8bbe\u8ba1\u7684\u65b9\u6cd5\u6bd4\u90a3\u4e9b\u7834\u574f\u7cfb\u7edf\u8bbe\u8ba1\u7684\u65b9\u6cd5\u66f4\u96be\u5e94\u7528\u65f6, \u5c31\u8868\u660e\u7cfb\u7edf\u5177\u6709\u9ad8\u7684\u7c98\u6ede\u6027. \u505a\u9519\u8bef\u7684\u4e8b\u60c5\u5f88\u5bb9\u6613, \u800c\u505a\u6b63\u786e\u7684\u4e8b\u60c5\u5f88\u96be. \u6211\u4eec\u7cfb\u7edf\u5728\u8f6f\u4ef6\u8bbe\u8ba1\u4e2d\u53ef\u4ee5\u5bb9\u6613\u7684\u8fdb\u884c\u90a3\u4e9b\u4fdd\u6301\u8bbe\u8ba1\u7684\u6539\u52a8.<\/p><p>\u5f53\u5f00\u53d1\u73af\u5883\u8fdf\u949d\u3001\u4f4e\u6548\u65f6, \u5c31\u4f1a\u4ea7\u751f\u73af\u5883\u7c98\u6ede\u6027. \u4f8b\u5982, \u5982\u679c\u7f16\u8bd1\u82b1\u8d39\u65f6\u95f4\u5f88\u957f, \u90a3\u4e48\u5f00\u53d1\u4eba\u5458\u5c31\u4f1a\u88ab\u5f15\u8bf1\u53bb\u505a\u4e0d\u4f1a\u5bfc\u81f4\u5927\u89c4\u6a21\u91cd\u65b0\u7f16\u8bd1\u7684\u6539\u52a8, \u5373\u4f7f\u90a3\u4e9b\u6539\u52a8\u4e0d\u518d\u4fdd\u6301\u8bbe\u8ba1; \u5982\u679c\u6e90\u7801\u63a7\u5236\u7cfb\u7edfcheck in\u5f88\u56f0\u96be, \u90a3\u4e48\u5f00\u53d1\u4eba\u5458\u5c31\u4f1a\u88ab\u5f15\u8bf1\u53bb\u505a\u90a3\u4e9b\u9700\u8981\u5c3d\u53ef\u80fd\u5c11check in\u7684\u6539\u52a8, \u800c\u4e0d\u7ba1\u6539\u52a8\u662f\u5426\u4f1a\u4fdd\u6301\u8bbe\u8ba1.<\/p><p>\u65e0\u8bba\u9879\u76ee\u5177\u6709\u54ea\u79cd\u7c98\u6ede\u6027, \u90fd\u5f88\u96be\u4fdd\u6301\u9879\u76ee\u4e2d\u7684\u8f6f\u4ef6\u8bbe\u8ba1. \u6211\u4eec\u5e0c\u671b\u521b\u5efa\u6613\u4e8e\u4fdd\u6301\u8bbe\u8ba1\u7684\u7cfb\u7edf\u548c\u9879\u76ee\u73af\u5883.<\/p><h3 id=\"5-\u4e0d\u5fc5\u8981\u7684\u590d\u6742\u6027\">5. \u4e0d\u5fc5\u8981\u7684\u590d\u6742\u6027<\/h3><p>\u5982\u679c\u8bbe\u8ba1\u4e2d\u5305\u542b\u5f53\u524d\u6ca1\u7528\u7684\u7ec4\u6210\u90e8\u5206, \u5c31\u542b\u6709\u4e86\u4e0d\u5fc5\u8981\u7684\u590d\u6742\u6027. \u5f00\u53d1\u4eba\u5458\u5e38\u5e38\u9884\u6d4b\u9700\u6c42\u7684\u53d8\u5316, \u5e76\u5728\u8f6f\u4ef6\u4e2d\u653e\u7f6e\u4e86\u5904\u7406\u90a3\u4e9b\u6f5c\u5728\u53d8\u5316\u7684\u4ee3\u7801. \u8d77\u521d, \u770b\u8d77\u6765\u50cf\u662f\u4e00\u4ef6\u597d\u4e8b, \u4f46\u8fc7\u591a\u7684\u53ef\u80fd\u6027\u51c6\u5907\u5bfc\u81f4\u8bbe\u8ba1\u4e2d\u5305\u542b\u7edd\u4e0d\u4f1a\u7528\u5230\u7684\u7ed3\u6784, \u4ece\u800c\u53d8\u5f97\u6df7\u4e71. \u4e00\u4e9b\u51c6\u5907\u53ef\u80fd\u4f1a\u5e26\u6765\u56de\u62a5, \u4f46\u66f4\u591a\u7684\u4e0d\u4f1a\u6709\u4f5c\u7528. \u8bbe\u8ba1\u80cc\u8d1f\u8fd9\u8fd9\u4e9b\u4e0d\u4f1a\u7528\u5230\u7684\u90e8\u5206, \u662f\u8f6f\u4ef6\u53d8\u7684\u590d\u6742, \u5e76\u96be\u4ee5\u7406\u89e3<\/p><h3 id=\"6-\u4e0d\u5fc5\u8981\u7684\u91cd\u590d\u6027\">6. \u4e0d\u5fc5\u8981\u7684\u91cd\u590d\u6027<\/h3><p>\u590d\u5236\u548c\u7c98\u8d34\u64cd\u4f5c\u5e38\u5e38\u4f1a\u5bfc\u81f4\u91cd\u590d\u7684\u4ee3\u7801\u7247\u6bb5, \u5f53\u540c\u6837\u7684\u4ee3\u7801\u4ee5\u7a0d\u5fae\u4e0d\u540c\u7684\u5f62\u5f0f\u91cd\u590d\u51fa\u73b0\u65f6, \u5c31\u8868\u793a\u5f00\u53d1\u4eba\u5458\u5ffd\u7565\u4e86\u62bd\u8c61. \u53d1\u73b0\u6240\u6709\u7684\u91cd\u590d\u5e76\u901a\u8fc7\u9002\u5f53\u7684\u62bd\u8c61\u53bb\u6d88\u9664\u91cd\u590d, \u4f1a\u4f7f\u7cfb\u7edf\u7684\u66f4\u52a0\u6613\u4e8e\u7406\u89e3\u548c\u7ef4\u62a4. \u5f53\u7cfb\u7edf\u6709\u91cd\u590d\u7684\u4ee3\u7801\u65f6, \u5bf9\u7cfb\u7edf\u8fdb\u884c\u6539\u52a8\u4f1a\u53d8\u5f97\u56f0\u96be, \u5728\u4e00\u4e2a\u91cd\u590d\u7684\u4ee3\u7801\u4f53\u4e2d\u53d1\u73b0\u7684\u9519\u8bef\u603b\u662f\u9700\u8981\u5728\u6bcf\u4e2a\u91cd\u590d\u4f53\u4e2d\u4e00\u4e00\u4fee\u6b63, \u7531\u4e8e\u6bcf\u4e2a\u91cd\u590d\u4f53\u4e4b\u95f4\u90fd\u6709\u7ec6\u5fae\u7684\u533a\u522b, \u6240\u4ee5\u4fee\u6b63\u7684\u65b9\u5f0f\u4e5f\u4e0d\u5c3d\u76f8\u540c.<\/p><h3 id=\"7-\u6666\u6da9\u6027\">7. \u6666\u6da9\u6027<\/h3><p>\u6666\u6da9\u6027\u662f\u6307\u6a21\u5757\u96be\u4ee5\u7406\u89e3\u3002\u4ee3\u7801\u53ef\u4ee5\u662f\u6e05\u6670\u3001\u5bcc\u6709\u8868\u73b0\u529b\u7684\uff0c\u4e5f\u53ef\u4ee5\u662f\u6666\u6da9\u7684\u8d39\u89e3\u7684\uff0c\u4ee3\u7801\u968f\u7740\u65f6\u95f4\u5f80\u5f80\u4f1a\u53d8\u5f97\u8d8a\u6765\u8d8a\u6666\u6da9\uff0c\u4e3a\u4e86\u662f\u4ee3\u7801\u6666\u6da9\u6027\u4fdd\u6301\u6700\u4f4e\uff0c\u5c31\u9700\u8981\u6301\u7eed\u7684\u4fdd\u6301\u4ee3\u7801\u6e05\u6670\u5e76\u5bcc\u6709\u8868\u73b0\u529b\u3002\u5f00\u53d1\u8005\u6700\u521d\u7f16\u5199\u6a21\u5757\u65f6\uff0c\u53ef\u80fd\u4f1a\u5f88\u719f\u6089\u4ee3\u7801\uff0c\u968f\u7740\u65f6\u95f4\u63a8\u79fb\uff0c\u719f\u6089\u51cf\u9000\uff0c\u518d\u770b\u8fd9\u4e2a\u6a21\u5757\uff0c\u540c\u6837\u4f1a\u89c9\u5f97\u4ee3\u7801\u5f88\u7cdf\u7cd5\uff0c\u4e3a\u4e86\u907f\u514d\u8fd9\u79cd\u60c5\u51b5\uff0c\u5f00\u53d1\u8005\u9700\u8981\u7ad9\u5728\u4ee3\u7801\u9605\u8bfb\u8005\u7684\u89d2\u5ea6\uff0c\u5bf9\u4ed6\u4eec\u4ee3\u7801\u8fdb\u884c\u91cd\u6784\uff0c\u8fd9\u6837\u4ee3\u7801\u9605\u8bfb\u8005\u5c31\u53ef\u4ee5\u7406\u89e3\u4ee3\u7801\u3002<\/p><h2 id=\"\u654f\u6377\u56e2\u961f\u4e0d\u5141\u8bb8\u8f6f\u4ef6\u8150\u5316\">\u654f\u6377\u56e2\u961f\u4e0d\u5141\u8bb8\u8f6f\u4ef6\u8150\u5316<\/h2><p>\u5728\u975e\u654f\u6377\u73af\u5883\u4e2d\uff0c\u9700\u6c42\u6ca1\u6709\u6309\u7167\u521d\u59cb\u8bbe\u8ba1\u548c\u8ba1\u5212\u7684\u65b9\u5f0f\u8fdb\u884c\u53d8\u5316\uff0c\u4ece\u800c\u5bfc\u81f4\u4e86\u8bbe\u8ba1\u7684\u9000\u5316\u3002\u901a\u5e38\u6539\u52a8\u75d8\u75d5\u6025\u8feb\uff0c\u5e76\u4e14\u8fdb\u884c\u6539\u52a8\u7684\u5f00\u53d1\u4eba\u5458\u5bf9\u4e8e\u539f\u59cb\u8bbe\u8ba1\u601d\u8def\u53ef\u80fd\u5e76\u4e0d\u719f\u6089\uff0c\u56e0\u800c\u867d\u7136\u6539\u52a8\u53ef\u4ee5\u5de5\u4f5c\uff0c\u4f46\u662f\u5374\u4ee5\u67d0\u79cd\u65b9\u5f0f\u8fdd\u53cd\u4e86\u539f\u59cb\u7684\u8bbe\u8ba1\u3002\u968f\u7740\u6539\u52a8\u7684\u4e0d\u65ad\u8fdb\u884c\uff0c\u8fd9\u4e9b\u8fdd\u53cd\u8bbe\u8ba1\u7684\u884c\u4e3a\u4e0d\u65ad\u79ef\u7d2f\uff0c\u8bbe\u8ba1\u5f00\u59cb\u51fa\u73b0\u81ed\u5473\u3002<\/p><p>\u654f\u6377\u56e2\u961f\u4f9d\u9760\u53d8\u5316\u6765\u83b7\u53d6\u6d3b\u529b\uff0c\u56e2\u961f\u51e0\u4e4e\u4e0d\u8fdb\u884c\u9884\u5148\u8bbe\u8ba1\uff0c\u56e0\u6b64\u4e0d\u9700\u8981\u4e00\u4e2a\u6210\u719f\u7684\u8bbe\u8ba1\u3002\u4ed6\u4eec\u66f4\u613f\u610f\u4fdd\u6301\u7cfb\u7edf\u5c3d\u53ef\u80fd\u5e72\u51c0\u3001\u7b80\u5355\uff0c\u5e76\u4f7f\u7528\u8bb8\u591a\u5355\u5143\u6d4b\u8bd5\u548c\u9a8c\u6536\u6d4b\u8bd5\uff0c\u4fdd\u6301\u4e86\u8bbe\u8ba1\u7684\u7075\u6d3b\u6027\u548c\u53ef\u7406\u89e3\u6027\u3002<\/p>"},{"title":"\u7f13\u5b58\u5e38\u89c1\u95ee\u9898","link":"https:\/\/sunpe.github.io\/posts\/2020-10-30-use-case-of-cache\/","pubDate":"Fri, 30 Oct 2020 22:00:00 +0800","guid":"https:\/\/sunpe.github.io\/posts\/2020-10-30-use-case-of-cache\/","description":"<p>Redis \u4e00\u4e2a\u6bd4\u8f83\u5e38\u89c1\u7684\u573a\u666f\u5c31\u662f\u4f5c\u4e3a\u5e94\u7528\u7684\u7f13\u5b58\uff0c\u5408\u7406\u7684\u5229\u7528\u7f13\u5b58\u53ef\u4ee5\u63d0\u5347\u7cfb\u7edf\u6027\u80fd\uff0c\u4f7f\u7528\u8fc7\u7a0b\u4e2d\u6bd4\u8f83\u5e38\u89c1\u7684\u95ee\u9898\u6709\uff1a\u7f13\u5b58\u7a7f\u900f\u3001 \u7f13\u5b58\u96ea\u5d29\u3001 \u70ed\u70b9key\u95ee\u9898\u3002<\/p><h2 id=\"\u7f13\u5b58\u51fb\u7a7f\">\u7f13\u5b58\u51fb\u7a7f<\/h2><p>\u5728\u505a\u6570\u636e\u5e93\u7f13\u5b58\u7684\u4f7f\u7528\u573a\u666f\u4e2d\uff0c\u6211\u4eec\u901a\u5e38\u4f1a\u5148\u4ece Redis \u4e2d\u67e5\u8be2\u6570\u636e\uff0c\u5982\u679c\u5728 Redis \u4e2d\u67e5\u8be2\u4e0d\u5230\u6570\u636e\uff0c\u5219\u4f1a\u67e5\u8be2\u6570\u636e\u5e93\u4e2d\u7684\u6570\u636e\u3002\u5982\u679c\u67e5\u8be2\u7684\u662f\u4e0d\u5b58\u5728\u7684\u6570\u636e\uff0c\u6bd4\u5982 id \u662f\u300c-1\u300d\u7684\u7528\u6237\uff0c\u5219\u4f1a\u5bfc\u81f4\u6bcf\u6b21\u8bf7\u6c42\u90fd\u4f1a\u53bb\u6570\u636e\u5e93\u4e2d\u67e5\u8be2\uff0c\u5982\u679c\u8fd9\u79cd\u8bf7\u6c42\u8fc7\u591a\uff0c\u4f1a\u5bfc\u81f4\u6570\u636e\u5e93\u538b\u529b\u8fc7\u5927\uff0c\u9020\u6210\u7f13\u5b58\u51fb\u7a7f\u95ee\u9898\u3002<\/p><p>\u89e3\u51b3\u300c\u7f13\u5b58\u51fb\u7a7f\u300d\u95ee\u9898\u5927\u81f4\u6709\u4e09\u79cd\u65b9\u6848\uff0c\u4ece\u4e1a\u52a1\u89d2\u5ea6\u89e3\u51b3\u3001\u7f13\u5b58\u7a7a\u503c\u548c\u91c7\u7528\u5e03\u9686\u8fc7\u6ee4\u5668\u3002<\/p><h3 id=\"\u4ece\u4e1a\u52a1\u89d2\u5ea6\u89e3\u51b3\">\u4ece\u4e1a\u52a1\u89d2\u5ea6\u89e3\u51b3<\/h3><p>\u53ef\u4ee5\u5224\u65ad\u67e5\u8be2\u7684\u6570\u636e\u662f\u5426\u7b26\u5408\u89c4\u8303\uff0c\u6bd4\u5982\u5c0f\u4e8e 0 \u7684 ID \u53ef\u4ee5\u4e0d\u8fdb\u884c\u67e5\u8be2\u3002\u67e5\u8be2\u524d\u5148\u6821\u9a8c\u8981\u67e5\u8be2\u7684 ID \u662f\u5426\u662f\u7b26\u5408\u89c4\u8303\u7684 ID\u3002<\/p><h3 id=\"\u7f13\u5b58\u7a7a\u503c\">\u7f13\u5b58\u7a7a\u503c<\/h3><p>\u67e5\u8be2\u6570\u636e\u5e93\u4e4b\u540e\uff0c\u5bf9\u4e8e\u6570\u636e\u5e93\u4e2d\u4e0d\u5b58\u5728\u7684\u6570\u636e\u6211\u4eec\u53ef\u4ee5\u628a Redis \u4e2d\u5bf9\u5e94\u7684 key \u8bbe\u7f6e\u4e3a\u4e00\u4e2a\u7a7a\u503c\uff0c\u8fd9\u6837\u518d\u6b21\u6536\u5230\u76f8\u540c\u7684\u8bf7\u6c42\u5c31\u53ef\u4ee5\u547d\u4e2d\u7f13\u5b58\u4e86\u3002\u9700\u8981\u6ce8\u610f\u7684\u662f\u5982\u679c\u5bf9\u5e94\u7684 key \u8bbe\u7f6e\u4e86\u65b0\u7684\u6709\u6548\u7684\u503c\uff0c\u5219\u9700\u8981\u5c06\u7f13\u5b58\u4e2d\u7684\u6570\u636e\u5220\u6389\u3002\u8fd9\u79cd\u65b9\u6848\u6709\u4e00\u4e2a\u95ee\u9898\u662f\uff0c\u5982\u679c\u653b\u51fb\u8005\u91c7\u7528\u4e0d\u540c\u7684\u4f2a\u9020\u8bf7\u6c42\u8fdb\u884c\u653b\u51fb\u65f6\uff0c\u53ef\u80fd\u4f1a\u5bfc\u81f4\u7f13\u5b58\u7a7a\u95f4\u66b4\u6da8\uff0c\u8fdb\u800c\u5f71\u54cd\u4e86\u6b63\u5e38\u7684\u6570\u636e\u67e5\u8be2\u3002<\/p><h3 id=\"\u91c7\u7528\u5e03\u9686\u8fc7\u6ee4\u5668\">\u91c7\u7528\u5e03\u9686\u8fc7\u6ee4\u5668<\/h3><p>\u5e03\u9686\u8fc7\u6ee4\u5668\uff08Bloom Filter\uff09\u5b9e\u9645\u4e0a\u662f\u4e00\u4e2a\u5f88\u957f\u7684\u4e8c\u8fdb\u5236\u5411\u91cf\u548c\u4e00\u4e9b\u5217\u6620\u5c04\u51fd\u6570\uff0c\u53ef\u4ee5\u68c0\u6d4b\u4e00\u4e2a\u5143\u7d20\u662f\u5426\u5728\u4e00\u4e2a\u96c6\u5408\u4e2d\u3002\u4f18\u70b9\u662f\u7a7a\u95f4\u5229\u7528\u7387\u548c\u67e5\u8be2\u6548\u7387\u90fd\u6bd4\u8f83\u9ad8\uff1b\u7f3a\u70b9\u662f\u6709\u4e00\u5b9a\u7684\u8bef\u8bc6\u522b\u7387\u548c\u5220\u9664\u56f0\u96be\u3002\u57284.0\u4ee5\u4e0a\u7248\u672c Redis \u4e2d\u53ef\u4ee5\u901a\u8fc7 module \u52a0\u8f7d RedisBloom \u6765\u5b9e\u73b0\u5e03\u9686\u8fc7\u6ee4\u5668\u3002<\/p><h2 id=\"\u7f13\u5b58\u96ea\u5d29\">\u7f13\u5b58\u96ea\u5d29<\/h2><p>\u6211\u4eec\u4f7f\u7528 Redis \u901a\u5e38\u4f1a\u8bbe\u7f6e key \u7684\u8fc7\u671f\u65f6\u95f4\uff0c\u5982\u679c\u5927\u91cf\u7684 key \u8bbe\u7f6e\u4e86\u76f8\u540c\u7684\u8fc7\u671f\u65f6\u95f4\uff0c\u53ef\u80fd\u4f1a\u5bfc\u81f4\u540c\u4e00\u65f6\u95f4\u5927\u91cfkey\u5931\u6548\uff0c\u5bfc\u81f4\u5927\u91cf\u8bf7\u6c42\u5230\u4e86\u6570\u636e\u5e93\uff0c\u9020\u6210\u6570\u636e\u5e93\u77ac\u65f6\u538b\u529b\u8fc7\u5927\uff0c\u9020\u6210\u7f13\u5b58\u96ea\u5d29\u7684\u95ee\u9898\u3002\u53e6\u5916\u7f13\u5b58\u6545\u969c\u4e5f\u53ef\u80fd\u5bfc\u81f4\u7f13\u5b58\u96ea\u5d29\u95ee\u9898\uff0c\u6bd4\u5982Redis\u4e0d\u53ef\u7528\u7b49\u3002<\/p><h3 id=\"\u89e3\u51b3\u65b9\u6848\">\u89e3\u51b3\u65b9\u6848<\/h3><p>\u7f13\u5b58\u5931\u6548\u5bfc\u81f4\u7684\u7f13\u5b58\u96ea\u5d29\u95ee\u9898\u53ef\u4ee5\u901a\u8fc7\u8bbe\u7f6e\u4e0d\u540c\u7684\u8fc7\u671f\u65f6\u95f4\u7684\u65b9\u5f0f\u6765\u89e3\u51b3\u3002\u6bd4\u5982\u8bbe\u7f6e\u7f13\u5b58 key \u7684\u8fc7\u671f\u65f6\u95f4\u53ef\u4ee5\u91c7\u7528\u300c\u56fa\u5b9a\u7684\u65f6\u95f4\u300d\u52a0\u968f\u673a\u6570\u7684\u65b9\u5f0f\u3002\u53e6\u5916\u5e94\u5f53\u4f7f\u7528\u96c6\u7fa4\u6a21\u5f0f\uff0c\u6bd4\u5982 Redis Sentinel \u548c Redis Cluster \uff0c\u907f\u514d\u5355\u70b9\u95ee\u9898\u3002<\/p><h2 id=\"\u70ed\u70b9key\">\u70ed\u70b9key<\/h2><p>\u67d0\u4e9b\u573a\u666f\uff0c\u6bd4\u5982\u79d2\u6740\u3001 \u5fae\u535a\u5927V\u3001 \u70ed\u70b9\u65b0\u95fb\u7b49\uff0c\u4f1a\u5bfc\u81f4\u7f13\u5b58\u4e2d\u67d0\u4e2akey\u8bbf\u95ee\u91cf\u7279\u522b\u5927\uff0c\u6781\u7aef\u60c5\u51b5\u53ef\u80fd\u4f1a\u8d85\u51fa\u5355\u53f0 server \u7684\u627f\u8f7d\u80fd\u529b\u3002<\/p><h3 id=\"\u670d\u52a1\u7aef\u7f13\u5b58\">\u670d\u52a1\u7aef\u7f13\u5b58<\/h3><p>\u5bf9\u4e8e\u8bfb\u591a\u5199\u5c11\u7684\u573a\u666f\uff0c\u53ef\u4ee5\u5c06\u70ed\u70b9\u6570\u636e\u7f13\u5b58\u5230\u670d\u52a1\u7aef\u672c\u5730\uff0c\u53ef\u4ee5\u51cf\u5c11\u5bf9\u540e\u7aef\u7f13\u5b58\u6216\u6570\u636e\u5e93\u7684\u538b\u529b\u3002\u672c\u5730\u7f13\u5b58\u53ef\u4ee5\u4f7f\u7528 Map \u6570\u636e\u7ed3\u6784\uff0c\u6216\u8005\u4f7f\u7528\u6210\u719f\u7684\u5f00\u6e90\u65b9\u6848\uff0c\u6bd4\u5982 Guava \u4e2d\u7684 <code>LocalCache<\/code>\uff0c<code>LocalCache<\/code> \u81ea\u5e26key\u8fc7\u671f\u529f\u80fd\uff0c\u4f7f\u7528\u4e5f\u6bd4\u8f83\u65b9\u4fbf\u3002<\/p><p>\u672c\u5730\u7f13\u5b58\u65b9\u6848\u7b80\u5355\uff0c\u53ef\u4ee5\u660e\u663e\u63d0\u5347\u7cfb\u7edf\u7cfb\u80fd\uff0c\u4f46\u4e5f\u53ef\u80fd\u5e26\u6765\u300c\u810f\u6570\u636e\u300d\u95ee\u9898\uff0c\u6bd4\u5982\u6570\u636e\u5e93\u548c\u5168\u5c40\u7f13\u5b58\u4e2d\u67d0\u6761\u6570\u636e\u66f4\u65b0\u6216\u5220\u9664\uff0c\u672c\u5730\u7f13\u5b58\u66f4\u65b0\u4e0d\u53ca\u65f6\uff0c\u4f9d\u65e7\u8fd4\u56de\u7684\u662f\u65e7\u6570\u636e\u3002\u53ef\u4ee5\u642d\u914d\u300c\u5b9a\u65f6\u8f6e\u8be2\u300d\u6216\u300c\u53d1\u5e03-\u8ba2\u9605\u300d\u7684\u65b9\u5f0f\u6765\u89e3\u51b3\u672c\u5730\u7f13\u5b58\u66f4\u65b0\u4e0d\u53ca\u65f6\u7684\u95ee\u9898\u3002\u672c\u5730server\u53ef\u4ee5\u5b9a\u671f\u8f6e\u8be2\u7f13\u5b58\u548c\u6570\u636e\u5e93\u4e2d\u76f8\u5e94key\u7684\u6570\u636e\uff0c\u6765\u66f4\u65b0\u672c\u5730\u7f13\u5b58\uff1b\u6216\u8005\u5f53\u6570\u636e\u53d8\u66f4\u65f6\u901a\u8fc7\u6d88\u606f\u961f\u5217\u300c\u5e7f\u64ad\u300d\u6216\u8005 zk \u6765\u901a\u77e5\u6240\u6709 server \u66f4\u65b0\u6570\u636e\u3002<\/p><h3 id=\"\u62c6\u5206key\">\u62c6\u5206key<\/h3><p>\u5728 Redis \u96c6\u7fa4\u4e2d\uff0ckey \u6309\u4e00\u5b9a\u7684\u5206\u7247\u7b97\u6cd5\u5206\u5e03\u5728\u4e0d\u540c\u7684\u5206\u7247\u4e0a\uff0c\u6211\u4eec\u53ef\u4ee5\u5c06\u70ed\u70b9\u7684 key \u62c6\u5206\u6210\u591a\u4e2a key\uff0c\u6bd4\u5982\u5c06 key \u52a0\u4e0a\u540e\u7f00\u6216\u524d\u7f00\uff0c\u4ee5\u8ba9key\u5206\u5e03\u5728\u4e0d\u540c\u7684\u5206\u7247\uff0c\u6765\u5206\u62c5\u5355\u4e2a\u5206\u7247\u7684\u538b\u529b\u3002\u70ed\u70b9 key \u6309\u300c\u8bfb\u591a\u5199\u5c11\u300d\u6216\u300c\u5199\u591a\u8bfb\u5c11\u300d\u53ef\u4ee5\u5206\u4e3a\u300c\u8bfb\u70ed\u70b9key\u300d\u548c\u300c\u5199\u70ed\u70b9key\u300d\u3002\u5bf9\u4e8e\u8bfb\u53d6\u70ed\u70b9 key\uff0c\u66f4\u65b0\u65f6\u9700\u8981\u66f4\u65b0\u6240\u6709 key \u7684\u6570\u636e\uff0c\u901a\u8fc7\u653e\u5927\u5199\u5165\u7684\u65b9\u5f0f\u6765\u63d0\u9ad8\u8bfb\u53d6\u6027\u80fd\uff1b\u5bf9\u4e8e\u5199\u70ed\u70b9key\uff0c\u66f4\u65b0\u65f6\u9009\u62e9\u5176\u4e2d\u4e00\u4e2akey\u505a\u66f4\u65b0\uff0c\u8bfb\u53d6\u65f6\u9700\u8981\u5408\u5e76\u6240\u6709key\uff0c\u91c7\u7528\u8bfb\u653e\u5927\u7684\u65b9\u5f0f\u6765\u63d0\u9ad8\u5199\u5165\u6027\u80fd\u3002<\/p><h2 id=\"\u70ed\u70b9key\u53d1\u73b0\">\u70ed\u70b9key\u53d1\u73b0<\/h2><h3 id=\"\u4eba\u5de5\u5224\u65ad\">\u4eba\u5de5\u5224\u65ad<\/h3><p>\u67d0\u4e9b\u7279\u5b9a\u7684\u573a\u666f\u53ef\u4ee5\u9884\u6d4b\u51fa\u53ef\u80fd\u5b58\u5728\u7684\u70ed\u70b9 key\uff0c\u6bd4\u5982\u79d2\u6740\u7684\u4ea7\u54c1\u6216\u8005\u5927V\u7b49\u7b49\uff0c\u53ef\u4ee5\u63d0\u524d\u5728\u7cfb\u7edf\u4e2d\u63d0\u524d\u914d\u7f6e\u70ed\u70b9 key\uff0c\u901a\u8fc7\u914d\u7f6e\u4e2d\u5fc3\u6216\u961f\u5217\u4e0b\u53d1\u5230\u670d\u52a1\u7aef\u3002<\/p><h3 id=\"\u81ea\u52a8\u53d1\u73b0\u70edkey\">\u81ea\u52a8\u53d1\u73b0\u70edkey<\/h3><p>\u53ef\u4ee5\u901a\u8fc7\u76d1\u63a7\u6253\u70b9\u6765\u68c0\u6d4b\u70ed\u70b9 key\uff0c\u5f53 key \u7684\u8bbf\u95ee\u9891\u7387\u8fbe\u5230\u67d0\u4e2a\u9608\u503c\u540e\uff0c\u5c06\u5176\u6807\u8bb0\u4e3a\u70ed\u70b9 key\uff0c\u901a\u8fc7\u914d\u7f6e\u4e2d\u5fc3\u6216\u961f\u5217\u4e0b\u53d1\u5230\u670d\u52a1\u7aef\u3002\u6b64\u5916 Redis 4.0 \u65b0\u589e\u4e86 allkey-lfu \u548c volatile-lfu \u4e24\u79cd\u6570\u636e\u8fc7\u671f\u7b56\u7565\uff0c\u5e76\u4e14\u53ef\u4ee5\u901a\u8fc7 OBJECT \u547d\u4ee4\u83b7\u53d6\u67d0\u4e2a key \u7684\u8bbf\u95ee\u9891\u7387\uff0c\u5728\u5ba2\u6237\u7aef\u53ef\u4ee5\u901a\u8fc7<code>--hotkeys<\/code>\u5feb\u901f\u627e\u5230\u70ed\u70b9 key, \u4f7f\u7528\u65b9\u5f0f <code>redis-cli -h &lt;host&gt; -a &lt;password&gt; --hotkeys<\/code>\u3002<\/p><p><img src=\"https:\/\/sunpe.github.io\/images\/use_case_of_cache\/1.png\" alt=\"\"><\/p><p>\u901a\u5e38\u4f1a\u91c7\u7528\u4eba\u5de5\u914d\u7f6e\u548c\u81ea\u52a8\u53d1\u73b0\u4e00\u8d77\u7684\u65b9\u5f0f\u6765\u53d1\u73b0\u70ed\u70b9key\uff0c\u901a\u8fc7\u4eba\u5de5\u7684\u65b9\u5f0f\u63d0\u524d\u914d\u7f6e\u5df2\u77e5\u7684\u70edkey\uff0c\u5e76\u901a\u8fc7\u6d41\u5f0f\u8ba1\u7b97\u7b49\u65b9\u5f0f\u81ea\u52a8\u53d1\u73b0\u6f5c\u5728\u7684\u70edkey\u3002<\/p><h2 id=\"\u603b\u7ed3\">\u603b\u7ed3<\/h2><p>\u5e94\u7528\u7f13\u5b58\u662f\u63d0\u5347\u7cfb\u7edf\u6027\u80fd\u7684\u6709\u6548\u624b\u6bb5\uff0c\u7531\u7f13\u5b58\u5f15\u5165\u7684\u95ee\u9898\u53ef\u4ee5\u6839\u636e\u4e1a\u52a1\u548c\u73b0\u5b9e\u60c5\u51b5\u4e0d\u540c\uff0c\u5e94\u8be5\u9009\u62e9\u9002\u5408\u81ea\u5df1\u7684\u65b9\u6848\u6765\u89e3\u51b3\u3002<\/p>"},{"title":"\u5f00\u542fgoroutine\u524d\u786e\u4fddgoroutine\u53ef\u4ee5\u9000\u51fa","link":"https:\/\/sunpe.github.io\/posts\/2020-10-17-make-sure-goroutine-willstop\/","pubDate":"Sat, 17 Oct 2020 22:00:00 +0800","guid":"https:\/\/sunpe.github.io\/posts\/2020-10-17-make-sure-goroutine-willstop\/","description":"<p>golang \u53ef\u4ee5\u901a\u8fc7 goroutine \u6765\u5b9e\u73b0\u9ad8\u5e76\u53d1\uff0c\u5e76\u4e14\u521b\u5efa goroutine \u7684\u5f00\u9500\u5f88\u5c0f\uff0c\u53ef\u4ee5\u5f88\u8f7b\u677e\u7684\u521b\u5efa\u6210\u5343\u4e0a\u4e07\u7684 goroutine\u3002\u4f46\u6709\u4e2a\u95ee\u9898\u9700\u8981\u6ce8\u610f\uff0c\u5728\u521b\u5efa goroutine \u4e4b\u524d\uff0c\u5fc5\u987b\u8981\u6e05\u695a\u521b\u5efa\u7684 goroutine \u5c06\u5982\u4f55\u9000\u51fa\uff0c\u5426\u5219 goroutine \u5c06\u5e38\u9a7b\u5185\u5b58\uff0c\u53ef\u80fd\u4f1a\u5bfc\u81f4\u5185\u5b58\u6cc4\u6f0f\u7b49\u95ee\u9898\u3002<\/p><p>\u7a0b\u5e8f 1 \u5c55\u793a\u4e86\u56e0\u4e3a goroutine \u5bfc\u81f4\u5185\u5b58\u6cc4\u6f0f\u7684 demo\u3002leak \u51fd\u6570\u4e2d\uff0c\u521b\u5efa\u4e00\u4e2achannel\uff0c\u5e76\u542f\u52a8\u4e00\u4e2agoroutine \u6765\u6d88\u8d39\u8fd9\u4e2achannel\u3002\u8fd9\u4e2a goroutine \u7ed3\u675f\u7684\u552f\u4e00\u6761\u4ef6\u662f\u5173\u95ed ch\u3002\u4f46\u662f leak \u51fd\u6570\u8fd4\u56de\u4e4b\u540e\uff0cch \u6ca1\u6709\u88ab\u5173\u95ed\uff0c\u8fd9\u6837 goroutine \u4f1a\u4e00\u76f4\u5728\u5185\u5b58\u4e2d\uff0c\u968f\u7740 leak \u51fd\u6570\u8c03\u7528\u6b21\u6570\u7684\u589e\u591a\uff0c\u5360\u7528\u5185\u5b58\u4e5f\u968f\u7740\u589e\u957f\uff0c\u6700\u7ec8\u5bfc\u81f4\u5185\u5b58\u6cc4\u6f0f\u3002<\/p><div class=\"highlight\"><pre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"><code class=\"language-go\" data-lang=\"go\"><span style=\"display:flex;\"><span><span style=\"color:#75715e\">\/\/ \u7a0b\u5e8f 1<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span><span style=\"color:#66d9ef\">func<\/span> <span style=\"color:#a6e22e\">leak<\/span>() {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">ch<\/span> <span style=\"color:#f92672\">:=<\/span> make(<span style=\"color:#66d9ef\">chan<\/span> <span style=\"color:#66d9ef\">int<\/span>)<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">go<\/span> <span style=\"color:#66d9ef\">func<\/span>() {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">for<\/span> <span style=\"color:#66d9ef\">range<\/span> <span style=\"color:#a6e22e\">ch<\/span> { }<\/span><\/span><span style=\"display:flex;\"><span> }() <\/span><\/span><span style=\"display:flex;\"><span>}<\/span><\/span><\/code><\/pre><\/div><p>\u6240\u4ee5\u5728\u4f7f\u7528 go \u5173\u952e\u8bcd\u5f00\u542f goroutine \u4e4b\u524d\uff0c\u5fc5\u987b\u8981\u6e05\u695a goroutine \u7684\u9000\u51fa\u6761\u4ef6\u3002<\/p><h2 id=\"\u53c2\u8003\u8d44\u6599\">\u53c2\u8003\u8d44\u6599<\/h2><ol><li><a href=\"https:\/\/dave.cheney.net\/2016\/12\/22\/never-start-a-goroutine-without-knowing-how-it-will-stop\">https:\/\/dave.cheney.net\/2016\/12\/22\/never-start-a-goroutine-without-knowing-how-it-will-stop<\/a><\/li><\/ol>"},{"title":"\u70ed\u70b9\u8d26\u6237\u5904\u7406","link":"https:\/\/sunpe.github.io\/posts\/2020-09-26-hot-account\/","pubDate":"Sat, 26 Sep 2020 22:00:00 +0800","guid":"https:\/\/sunpe.github.io\/posts\/2020-09-26-hot-account\/","description":"<p>\u4e92\u8054\u7f51\u4ea4\u6613\u4e2d\uff0c\u5f53\u67d0\u4e00\u5546\u5bb6\u4ea4\u6613\u91cf\u5927\u7684\u65f6\u5019\uff0c\u5546\u5bb6\u5bf9\u5e94\u7684\u8d26\u6237\u66f4\u65b0\u7684\u6bd4\u8f83\u9891\u7e41\uff0c\u8be5\u5546\u5bb6\u5bf9\u5e94\u7684\u8d26\u6237\u8bb0\u5f55\u4f1a\u53d8\u6210\u70ed\u70b9\u884c\uff0c\u8be5\u5546\u5bb6\u7684\u8d26\u6237\u5c31\u662f\u70ed\u70b9\u8d26\u6237\u3002\u901a\u5e38\u70ed\u70b9\u8d26\u6237\u4f1a\u5bfc\u81f4\u5404\u79cd\u7cfb\u7edf\u95ee\u9898\uff0c\u5bf9\u6570\u636e\u5e93\u4e5f\u4f1a\u9020\u6210\u5f88\u5927\u538b\u529b\u3002<\/p><h2 id=\"\u70ed\u70b9\u8d26\u6237\u5206\u7c7b\">\u70ed\u70b9\u8d26\u6237\u5206\u7c7b<\/h2><p>\u6839\u636e\u8d44\u91d1\u6d41\u52a8\u7684\u65b9\u5411\u53ef\u4ee5\u628a\u70ed\u70b9\u8d26\u6237\u5206\u4e3a\u300c\u52a0\u9891\u8d26\u6237\u300d\u3001\u300c\u51cf\u9891\u8d26\u6237\u300d\u548c\u300c\u53cc\u9891\u8d26\u6237\u300d\u3002 \u5176\u4e2d\u300c\u52a0\u9891\u8d26\u6237\u300d\u662f\u6307\u8d44\u91d1\u6d41\u5165\u6bd4\u8f83\u9891\u7e41\u7684\u8d26\u6237\uff0c\u6bd4\u5982\u5546\u5bb6\u7684\u6536\u6b3e\u8d26\u6237\uff1b\u300c\u51cf\u9891\u8d26\u6237\u300d\u662f\u6307\u8d44\u91d1\u6d41\u51fa\u6bd4\u8f83\u9891\u7e41\u7684\u8d26\u6237\uff0c\u6bd4\u5982\u5546\u5bb6\u7684\u9000\u6b3e\u8d26\u6237\uff1b\u300c\u53cc\u9891\u8d26\u6237\u300d\u6307\u6d41\u5165\u548c\u6d41\u51fa\u90fd\u6bd4\u8f83\u9891\u7e41\u7684\u8d26\u6237\uff0c\u6bd4\u5982\u5546\u5bb6\u5728\u7535\u5546\u5e73\u53f0\u5f00\u8bbe\u7684\u5185\u90e8\u6237\u3002<\/p><h2 id=\"\u70ed\u70b9\u8d26\u6237\u8bc6\u522b\">\u70ed\u70b9\u8d26\u6237\u8bc6\u522b<\/h2><p>\u5728\u4ea4\u6613\u7cfb\u7edf\u4e2d\u53ef\u4ee5\u901a\u8fc7\u63d0\u524d\u914d\u7f6e\u3001 \u5b9e\u65f6\u7edf\u8ba1\u548c\u540c\u6b65\u7684\u65b9\u5f0f\u6765\u8bc6\u522b\u70ed\u70b9\u8d26\u6237\u3002\u5386\u53f2\u7684\u70ed\u70b9\u8d26\u6237\u53ef\u4ee5\u63d0\u524d\u914d\u7f6e\u5230\u7cfb\u7edf\u4e2d\uff0c\u5728\u4ea4\u6613\u8fc7\u7a0b\u4e2d\u53ef\u4ee5\u5229\u7528\u6d41\u5f0f\u8ba1\u7b97\u7684\u601d\u8def\u5b9e\u65f6\u7edf\u8ba1\u8d26\u6237\u8bf7\u6c42\u91cf\uff0c\u5f53\u8bf7\u6c42\u91cf\u8fbe\u5230\u9608\u503c\u5c06\u8d26\u6237\u4fe1\u606f\u540c\u6b65\u5230\u7cfb\u7edf\u7684\u70ed\u70b9\u8d26\u6237\u540d\u5355\u4e2d\u3002\u7cfb\u7edf\u6574\u4f53\u67b6\u6784\u5982\u56fe 1 \u6240\u793a\u3002<\/p><p><img src=\"https:\/\/sunpe.github.io\/images\/hot_account\/1.png\" alt=\"\">\u56fe 1<\/p><h2 id=\"\u70ed\u70b9\u8d26\u6237\u95ee\u9898\u89e3\u51b3\u65b9\u6848\">\u70ed\u70b9\u8d26\u6237\u95ee\u9898\u89e3\u51b3\u65b9\u6848<\/h2><h3 id=\"1-\u9650\u6d41\">1. \u9650\u6d41<\/h3><p>\u70ed\u70b9\u8d26\u6237\u95ee\u9898\u7684\u6839\u6e90\u662f\u5927\u91cf\u8bf7\u6c42\u5e76\u53d1\u7ade\u4e89\u8d26\u6237\u7684\u64cd\u4f5c\u6743\uff0c\u8d26\u6237\u7684\u64cd\u4f5c\u6743\u662f\u7a00\u7f3a\u8d44\u6e90\uff0c\u6240\u4ee5\u6211\u4eec\u53ef\u4ee5\u51cf\u5c11\u5355\u4f4d\u65f6\u95f4\u5185\u5bf9\u8d26\u6237\u7684\u64cd\u4f5c\u6b21\u6570\uff0c\u6240\u4ee5\u300c\u9650\u6d41\u300d\u901a\u5e38\u662f\u6700\u76f4\u63a5\u6709\u6548\u7684\u89e3\u51b3\u65b9\u5f0f\u3002\u9650\u6d41\u7b80\u5355\u6765\u8bf4\u5c31\u662f\u8d85\u51fa\u6211\u80fd\u529b\u8303\u56f4\u7684\u4e0d\u5904\u7406\u3002\u5982\u56fe 2 \u6240\u793a\u3002<\/p><p><img src=\"https:\/\/sunpe.github.io\/images\/hot_account\/2.png\" alt=\"\">\u56fe 2<\/p><p>\u867d\u7136\u9650\u6d41\u80fd\u660e\u663e\u51cf\u5c11\u5bf9\u8d26\u6237\u7684\u64cd\u4f5c\uff0c\u4f46\u9650\u6d41\u662f\u901a\u8fc7\u62d2\u7edd\u4ea4\u6613\u6765\u8fbe\u5230\u76ee\u7684\uff0c\u901a\u5e38\u4f1a\u5f71\u54cd\u5ba2\u6237\u4f53\u9a8c\uff0c\u8fd9\u79cd\u65b9\u5f0f\u901a\u5e38\u4f5c\u4e3a\u7cfb\u7edf\u4fdd\u969c\u7684\u515c\u5e95\u63aa\u65bd\u3002<\/p><h3 id=\"2-\u7f13\u51b2\">2. \u7f13\u51b2<\/h3><p>\u7f13\u51b2\u7684\u65b9\u5f0f\u5c31\u662f\u540c\u6b65\u8f6c\u5f02\u6b65\u6765\u5904\u7406\u4ea4\u6613\u8bf7\u6c42\u3002\u4e92\u8054\u7f51\u4ea4\u6613\u70ed\u70b9\u901a\u5e38\u5177\u6709\u77ac\u65f6\u6027\uff0c\u53ef\u4ee5\u5148\u628a\u8bf7\u6c42\u63a5\u4e0b\u6765\uff0c\u6bd4\u5982\u7f13\u51b2\u5230\u6d88\u606f\u961f\u5217\u4e2d\uff0c\u5e76\u5c06\u7ed3\u679c\u8fd4\u56de\u7ed9\u8c03\u7528\u65b9\u3002\u7136\u540e\u5728\u4ece\u6d88\u606f\u961f\u5217\u4e2d\u53d6\u51fa\u4ea4\u6613\u6570\u636e\u8fdb\u884c\u5904\u7406\uff0c\u501f\u52a9\u6d88\u606f\u961f\u5217\u7684\u300c\u524a\u5cf0\u586b\u8c37\u300d\u7684\u7279\u6027\u6765\u6d88\u9664\u77ac\u65f6\u7684\u70ed\u70b9\u3002\u5982\u56fe 3 \u6240\u793a\u3002<\/p><p><img src=\"https:\/\/sunpe.github.io\/images\/hot_account\/3.png\" alt=\"\">\u56fe 3<\/p><p>\u4f46\u7f13\u51b2\u7684\u65b9\u5f0f\u53ef\u80fd\u4f1a\u5bfc\u81f4\u8bf7\u6c42\u5927\u91cf\u79ef\u538b\uff0c\u5982\u679c\u79ef\u538b\u7684\u91cf\u8d85\u8fc7\u65e5\u5904\u7406\u80fd\u529b\u7684\u4e0a\u9650\uff0c\u53ef\u80fd\u4f1a\u5bfc\u81f4\u5faa\u73af\u79ef\u538b\u7684\u95ee\u9898\u3002\u7531\u4e8e\u7f13\u51b2\u961f\u5217\u6d88\u8d39\u4e0d\u53ca\u65f6\u53ef\u80fd\u4f1a\u5bfc\u81f4\u8d26\u6237\u91d1\u989d\u66f4\u65b0\u4e0d\u53ca\u65f6\uff0c\u8fd9\u79cd\u60c5\u51b5\u4e0b\u53ef\u4ee5\u91c7\u7528\u5168\u5c40\u7f13\u5b58\u6765\u7f13\u5b58\u8d26\u6237\u4fe1\u606f\uff0c\u5c06\u6570\u636e\u653e\u5230\u7f13\u51b2\u961f\u5217\u524d\uff0c\u5148\u66f4\u65b0\u7f13\u5b58\u4e2d\u8d26\u6237\u6570\u636e\u3002\u8fd9\u79cd\u65b9\u5f0f\u6bd4\u8f83\u9002\u5408\u5904\u7406\u77ac\u65f6\u7684\u70ed\u70b9\u6570\u636e\u3002<\/p><h3 id=\"3-\u5408\u5e76\u8bf7\u6c42\u6570\u636e\">3. \u5408\u5e76\u8bf7\u6c42\u6570\u636e<\/h3><p>\u6211\u4eec\u8fd8\u53ef\u4ee5\u5408\u5e76\u7528\u6237\u7684\u8bf7\u6c42\u7684\u65b9\u5f0f\u6765\u524a\u51cf\u5355\u4f4d\u65f6\u95f4\u5185\u5bf9\u8d26\u6237\u7684\u64cd\u4f5c\u6b21\u6570\u3002\u5148\u5c06\u660e\u7ec6\u6570\u636e\u4fdd\u5b58\u4e0b\u6765\uff0c\u7136\u540e\u4f7f\u7528\u5355\u72ec\u7684 worker \u6765\u6c47\u603b\u660e\u7ec6\u6570\u636e\uff0c\u5e76\u66f4\u65b0\u8d26\u6237\u6570\u636e\u3002\u5982\u56fe 4 \u6240\u793a\u3002<\/p><p><img src=\"https:\/\/sunpe.github.io\/images\/hot_account\/4.png\" alt=\"\">\u56fe 4<\/p><p>\u8fd9\u79cd\u65b9\u5f0f\u4e5f\u4f1a\u9020\u6210\u8d26\u6237\u6570\u636e\u66f4\u65b0\u4e0a\u7684\u5ef6\u8fdf\uff0c\u540c\u6837\u53ef\u4ee5\u91c7\u7528\u5168\u5c40\u7f13\u5b58\u7684\u65b9\u5f0f\u6765\u7f13\u5b58\u8d26\u6237\u4fe1\u606f\uff0c\u4fdd\u5b58\u660e\u7ec6\u6570\u636e\u7684\u540c\u65f6\u66f4\u65b0\u7f13\u5b58\u4e2d\u7684\u8d26\u6237\u4fe1\u606f\u3002<\/p><h3 id=\"4-\u5206\u6cbb\">4. \u5206\u6cbb<\/h3><p>\u8d26\u6237\u7684\u64cd\u4f5c\u6743\u662f\u7a00\u7f3a\u8d44\u6e90\uff0c\u9664\u4e86\u51cf\u5c11\u8d26\u6237\u64cd\u4f5c\u6b21\u6570\u8fd9\u4e00\u601d\u8def\u4e4b\u5916\uff0c\u6211\u4eec\u8fd8\u53ef\u4ee5\u5229\u7528\u5206\u6cbb\u7684\u601d\u60f3\uff0c\u7ed9\u4e3b\u8d26\u6237\u521b\u5efa\u591a\u4e2a\u5f71\u5b50\u8d26\u6237\uff0c\u5c06\u4e3b\u8d26\u6237\u7684\u8d44\u91d1\u5206\u6563\u5230\u5f71\u5b50\u8d26\u6237\u4e2d\uff0c\u901a\u8fc7\u4e00\u5b9a\u7684\u8def\u7531\u89c4\u5219\uff0c\u5c06\u4ea4\u6613\u8bf7\u6c42\u53d1\u9001\u5230\u4e0d\u540c\u7684\u5f71\u5b50\u8d26\u6237\u4e0a\u3002\u5982\u56fe 5 \u6240\u793a\u3002<\/p><p><img src=\"https:\/\/sunpe.github.io\/images\/hot_account\/5.png\" alt=\"\">\u56fe 5<\/p><p>\u8fd9\u79cd\u65b9\u5f0f\u5e26\u6765\u7684\u95ee\u9898\u662f\uff0c\u5982\u4f55\u6765\u5e73\u8861\u5f71\u5b50\u8d26\u6237\u7684\u8d44\u91d1\u548c\u5982\u679c\u8d26\u6237\u8d44\u91d1\u4e0d\u8db3\u8981\u6263\u51cf\u591a\u4e2a\u8d26\u6237\u7684\u65f6\u5019\u600e\u4e48\u5904\u7406\u3002<\/p><h3 id=\"\u7f13\u5b58\">\u7f13\u5b58<\/h3><p>\u7f13\u5b58\u662f\u9ad8\u5e76\u53d1\u7cfb\u7edf\u7684\u53c8\u4e00\u5927\u5229\u5668\uff0c\u5728\u4ee5\u4e0a\u65b9\u6848\u4e2d\u4e5f\u6709\u7f13\u5b58\u7684\u5e94\u7528\uff0c\u603b\u4f53\u601d\u8def\u662f\u5c06\u8d26\u6237\u6570\u636e\u540c\u6b65\u5230\u7f13\u5b58\u4e2d\uff0c\u7f13\u5b58\u6570\u636e\u5f02\u6b65\u5237\u65b0\u5230\u6570\u636e\u5e93\u4e2d\u3002\u8fd9\u79cd\u65b9\u5f0f\u9700\u8981\u8003\u8651\u7f13\u5b58\u548c\u6570\u636e\u5e93\u6570\u636e\u4e00\u81f4\u6027\u7684\u95ee\u9898\uff0c\u5982\u679c\u53d1\u751f\u6570\u636e\u4e0d\u4e00\u81f4\u7684\u60c5\u51b5\uff0c\u53ef\u80fd\u9700\u8981\u6839\u636e\u660e\u7ec6\u6570\u636e\u8fdb\u884c\u5bf9\u8d26\u64cd\u4f5c\u3002<\/p><h2 id=\"\u603b\u7ed3\">\u603b\u7ed3<\/h2><p>\u5904\u7406\u70ed\u70b9\u8d26\u6237\u7684\u95ee\u9898\u9700\u8981\u6839\u636e\u5177\u4f53\u4e1a\u52a1\u548c\u5e94\u7528\u573a\u666f\u6765\u5177\u4f53\u5904\u7406\uff0c\u9009\u62e9\u5408\u9002\u7684\u89e3\u51b3\u65b9\u6848\uff0c\u6700\u91cd\u8981\u7684\u662f\u9700\u8981\u4fdd\u8bc1\u8d26\u6237\u6570\u636e\u7684\u4e00\u81f4\u6027\u3002<\/p>"},{"title":"golang \u8bed\u8a00\u673a\u5236\u4e4b\u5185\u5b58\u5256\u6790","link":"https:\/\/sunpe.github.io\/posts\/2020-09-04-golang-memory-analyst\/","pubDate":"Fri, 04 Sep 2020 22:00:00 +0800","guid":"https:\/\/sunpe.github.io\/posts\/2020-09-04-golang-memory-analyst\/","description":"<p>\u300a<a href=\"https:\/\/sunpe.github.io\/posts\/golang-escape\/\">Golang \u8bed\u8a00\u673a\u5236\u4e4b\u9003\u9038\u5206\u6790<\/a>\u300b\u4e2d\u4ecb\u7ecd\u4e86\u7f16\u8bd1\u5668\u9003\u9038\u5206\u6790\u7684\u57fa\u7840\u77e5\u8bc6\uff0c\u9664\u4e86\u5171\u4eab\u53d8\u91cf\u8fd9\u79cd\u60c5\u51b5\u4e4b\u5916\uff0c\u8fd8\u6709\u5176\u4ed6\u60c5\u51b5\u4e5f\u4f1a\u5bfc\u81f4\u53d8\u91cf\u9003\u9038\u3002<\/p><h2 id=\"\u793a\u4f8b\u4ee3\u7801\">\u793a\u4f8b\u4ee3\u7801<\/h2><p>\u793a\u4f8b\u4ee3\u7801\u662f\u8bfb\u53d6byte\u6570\u7ec4\uff0c\u627e\u5230 <code>elvis<\/code> \u5b57\u7b26\u4e32\u5e76\u66ff\u6362\u6210 <code>Elvis<\/code>\u3002\u793a\u4f8b\u4ee3\u7801\u5728 <a href=\"https:\/\/play.golang.org\/p\/n_SzF4Cer4\">https:\/\/play.golang.org\/p\/n_SzF4Cer4<\/a>\uff0cbenchmark \u5728 <a href=\"https:\/\/play.golang.org\/p\/TnXrxJVfLV\">https:\/\/play.golang.org\/p\/TnXrxJVfLV<\/a>\u3002\u793a\u4f8b\u4ee3\u7801\u4e2d\u6709\u4e24\u4e2a\u51fd\u6570\u5b9e\u73b0\u8fd9\u4e2a\u529f\u80fd\uff0c\u8fd9\u7bc7\u6587\u7ae0\u53ea\u5173\u6ce8\u5176\u4e2d\u7684 <code>algOne<\/code> \u51fd\u6570\u3002<\/p><p>\u4ee5\u4e0b\u662f\u5165\u53c2\u548c\u671f\u671b <code>algOne<\/code> \u51fd\u6570\u8f93\u51fa\u7684\u7ed3\u679c\u3002<\/p><pre tabindex=\"0\"><code>Input:abcelvisaElvisabcelviseelvisaelvisaabeeeelvise l v i saa bb e l v i saa elviselvielviselvielvielviselvi1elvielviselvisOutput:abcElvisaElvisabcElviseElvisaElvisaabeeeElvise l v i saa bb e l v i saa elviselviElviselvielviElviselvi1elviElvisElvis<\/code><\/pre><p>\u7a0b\u5e8f 1 \u662f <code>algOne<\/code> \u51fd\u6570\u4ee3\u7801\u3002<\/p><div class=\"highlight\"><pre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"><code class=\"language-go\" data-lang=\"go\"><span style=\"display:flex;\"><span><span style=\"color:#75715e\">\/\/ \u7a0b\u5e8f 1<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span> <span style=\"color:#ae81ff\">80<\/span> <span style=\"color:#66d9ef\">func<\/span> <span style=\"color:#a6e22e\">algOne<\/span>(<span style=\"color:#a6e22e\">data<\/span> []<span style=\"color:#66d9ef\">byte<\/span>, <span style=\"color:#a6e22e\">find<\/span> []<span style=\"color:#66d9ef\">byte<\/span>, <span style=\"color:#a6e22e\">repl<\/span> []<span style=\"color:#66d9ef\">byte<\/span>, <span style=\"color:#a6e22e\">output<\/span> <span style=\"color:#f92672\">*<\/span><span style=\"color:#a6e22e\">bytes<\/span>.<span style=\"color:#a6e22e\">Buffer<\/span>) {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#ae81ff\">81<\/span><\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#ae81ff\">82<\/span> <span style=\"color:#75715e\">\/\/ Use a bytes Buffer to provide a stream to process.<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span> <span style=\"color:#ae81ff\">83<\/span> <span style=\"color:#a6e22e\">input<\/span> <span style=\"color:#f92672\">:=<\/span> <span style=\"color:#a6e22e\">bytes<\/span>.<span style=\"color:#a6e22e\">NewBuffer<\/span>(<span style=\"color:#a6e22e\">data<\/span>)<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#ae81ff\">84<\/span><\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#ae81ff\">85<\/span> <span style=\"color:#75715e\">\/\/ The number of bytes we are looking for.<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span> <span style=\"color:#ae81ff\">86<\/span> <span style=\"color:#a6e22e\">size<\/span> <span style=\"color:#f92672\">:=<\/span> len(<span style=\"color:#a6e22e\">find<\/span>)<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#ae81ff\">87<\/span><\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#ae81ff\">88<\/span> <span style=\"color:#75715e\">\/\/ Declare the buffers we need to process the stream.<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span> <span style=\"color:#ae81ff\">89<\/span> <span style=\"color:#a6e22e\">buf<\/span> <span style=\"color:#f92672\">:=<\/span> make([]<span style=\"color:#66d9ef\">byte<\/span>, <span style=\"color:#a6e22e\">size<\/span>)<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#ae81ff\">90<\/span> <span style=\"color:#a6e22e\">end<\/span> <span style=\"color:#f92672\">:=<\/span> <span style=\"color:#a6e22e\">size<\/span> <span style=\"color:#f92672\">-<\/span> <span style=\"color:#ae81ff\">1<\/span><\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#ae81ff\">91<\/span><\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#ae81ff\">92<\/span> <span style=\"color:#75715e\">\/\/ Read in an initial number of bytes we need to get started.<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span> <span style=\"color:#ae81ff\">93<\/span> <span style=\"color:#66d9ef\">if<\/span> <span style=\"color:#a6e22e\">n<\/span>, <span style=\"color:#a6e22e\">err<\/span> <span style=\"color:#f92672\">:=<\/span> <span style=\"color:#a6e22e\">io<\/span>.<span style=\"color:#a6e22e\">ReadFull<\/span>(<span style=\"color:#a6e22e\">input<\/span>, <span style=\"color:#a6e22e\">buf<\/span>[:<span style=\"color:#a6e22e\">end<\/span>]); <span style=\"color:#a6e22e\">err<\/span> <span style=\"color:#f92672\">!=<\/span> <span style=\"color:#66d9ef\">nil<\/span> {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#ae81ff\">94<\/span> <span style=\"color:#a6e22e\">output<\/span>.<span style=\"color:#a6e22e\">Write<\/span>(<span style=\"color:#a6e22e\">buf<\/span>[:<span style=\"color:#a6e22e\">n<\/span>])<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#ae81ff\">95<\/span> <span style=\"color:#66d9ef\">return<\/span><\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#ae81ff\">96<\/span> }<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#ae81ff\">97<\/span><\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#ae81ff\">98<\/span> <span style=\"color:#66d9ef\">for<\/span> {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#ae81ff\">99<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#ae81ff\">100<\/span> <span style=\"color:#75715e\">\/\/ Read in one byte from the input stream.<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span><span style=\"color:#ae81ff\">101<\/span> <span style=\"color:#66d9ef\">if<\/span> <span style=\"color:#a6e22e\">_<\/span>, <span style=\"color:#a6e22e\">err<\/span> <span style=\"color:#f92672\">:=<\/span> <span style=\"color:#a6e22e\">io<\/span>.<span style=\"color:#a6e22e\">ReadFull<\/span>(<span style=\"color:#a6e22e\">input<\/span>, <span style=\"color:#a6e22e\">buf<\/span>[<span style=\"color:#a6e22e\">end<\/span>:]); <span style=\"color:#a6e22e\">err<\/span> <span style=\"color:#f92672\">!=<\/span> <span style=\"color:#66d9ef\">nil<\/span> {<\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#ae81ff\">102<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#ae81ff\">103<\/span> <span style=\"color:#75715e\">\/\/ Flush the reset of the bytes we have.<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span><span style=\"color:#ae81ff\">104<\/span> <span style=\"color:#a6e22e\">output<\/span>.<span style=\"color:#a6e22e\">Write<\/span>(<span style=\"color:#a6e22e\">buf<\/span>[:<span style=\"color:#a6e22e\">end<\/span>])<\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#ae81ff\">105<\/span> <span style=\"color:#66d9ef\">return<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#ae81ff\">106<\/span> }<\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#ae81ff\">107<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#ae81ff\">108<\/span> <span style=\"color:#75715e\">\/\/ If we have a match, replace the bytes.<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span><span style=\"color:#ae81ff\">109<\/span> <span style=\"color:#66d9ef\">if<\/span> <span style=\"color:#a6e22e\">bytes<\/span>.<span style=\"color:#a6e22e\">Compare<\/span>(<span style=\"color:#a6e22e\">buf<\/span>, <span style=\"color:#a6e22e\">find<\/span>) <span style=\"color:#f92672\">==<\/span> <span style=\"color:#ae81ff\">0<\/span> {<\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#ae81ff\">110<\/span> <span style=\"color:#a6e22e\">output<\/span>.<span style=\"color:#a6e22e\">Write<\/span>(<span style=\"color:#a6e22e\">repl<\/span>)<\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#ae81ff\">111<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#ae81ff\">112<\/span> <span style=\"color:#75715e\">\/\/ Read a new initial number of bytes.<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span><span style=\"color:#ae81ff\">113<\/span> <span style=\"color:#66d9ef\">if<\/span> <span style=\"color:#a6e22e\">n<\/span>, <span style=\"color:#a6e22e\">err<\/span> <span style=\"color:#f92672\">:=<\/span> <span style=\"color:#a6e22e\">io<\/span>.<span style=\"color:#a6e22e\">ReadFull<\/span>(<span style=\"color:#a6e22e\">input<\/span>, <span style=\"color:#a6e22e\">buf<\/span>[:<span style=\"color:#a6e22e\">end<\/span>]); <span style=\"color:#a6e22e\">err<\/span> <span style=\"color:#f92672\">!=<\/span> <span style=\"color:#66d9ef\">nil<\/span> {<\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#ae81ff\">114<\/span> <span style=\"color:#a6e22e\">output<\/span>.<span style=\"color:#a6e22e\">Write<\/span>(<span style=\"color:#a6e22e\">buf<\/span>[:<span style=\"color:#a6e22e\">n<\/span>])<\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#ae81ff\">115<\/span> <span style=\"color:#66d9ef\">return<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#ae81ff\">116<\/span> }<\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#ae81ff\">117<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#ae81ff\">118<\/span> <span style=\"color:#66d9ef\">continue<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#ae81ff\">119<\/span> }<\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#ae81ff\">120<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#ae81ff\">121<\/span> <span style=\"color:#75715e\">\/\/ Write the front byte since it has been compared.<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span><span style=\"color:#ae81ff\">122<\/span> <span style=\"color:#a6e22e\">output<\/span>.<span style=\"color:#a6e22e\">WriteByte<\/span>(<span style=\"color:#a6e22e\">buf<\/span>[<span style=\"color:#ae81ff\">0<\/span>])<\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#ae81ff\">123<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#ae81ff\">124<\/span> <span style=\"color:#75715e\">\/\/ Slice that front byte out.<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span><span style=\"color:#ae81ff\">125<\/span> copy(<span style=\"color:#a6e22e\">buf<\/span>, <span style=\"color:#a6e22e\">buf<\/span>[<span style=\"color:#ae81ff\">1<\/span>:])<\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#ae81ff\">126<\/span> }<\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#ae81ff\">127<\/span> }<\/span><\/span><\/code><\/pre><\/div><p>\u6211\u4eec\u901a\u8fc7 benchmark \u6765\u4e86\u89e3 <code>algOne<\/code> \u51fd\u6570\u7684\u6027\u80fd\u8868\u73b0\u548c\u5bf9\u5806\u7684\u538b\u529b\u3002<\/p><h2 id=\"benchmarking\">Benchmarking<\/h2><p>\u7a0b\u5e8f2\u662f <code>algOne<\/code> \u51fd\u6570\u7684 benchmark \u4ee3\u7801\u3002<\/p><div class=\"highlight\"><pre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"><code class=\"language-go\" data-lang=\"go\"><span style=\"display:flex;\"><span><span style=\"color:#75715e\">\/\/ \u7a0b\u5e8f 2<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span><span style=\"color:#66d9ef\">func<\/span> <span style=\"color:#a6e22e\">BenchmarkAlgorithmOne<\/span>(<span style=\"color:#a6e22e\">b<\/span> <span style=\"color:#f92672\">*<\/span><span style=\"color:#a6e22e\">testing<\/span>.<span style=\"color:#a6e22e\">B<\/span>) {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">var<\/span> <span style=\"color:#a6e22e\">output<\/span> <span style=\"color:#a6e22e\">bytes<\/span>.<span style=\"color:#a6e22e\">Buffer<\/span><\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">in<\/span> <span style=\"color:#f92672\">:=<\/span> <span style=\"color:#a6e22e\">assembleInputStream<\/span>()<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">find<\/span> <span style=\"color:#f92672\">:=<\/span> []byte(<span style=\"color:#e6db74\">&#34;elvis&#34;<\/span>)<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">repl<\/span> <span style=\"color:#f92672\">:=<\/span> []byte(<span style=\"color:#e6db74\">&#34;Elvis&#34;<\/span>)<\/span><\/span><span style=\"display:flex;\"><span><\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">b<\/span>.<span style=\"color:#a6e22e\">ResetTimer<\/span>()<\/span><\/span><span style=\"display:flex;\"><span><\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">for<\/span> <span style=\"color:#a6e22e\">i<\/span> <span style=\"color:#f92672\">:=<\/span> <span style=\"color:#ae81ff\">0<\/span>; <span style=\"color:#a6e22e\">i<\/span> &lt; <span style=\"color:#a6e22e\">b<\/span>.<span style=\"color:#a6e22e\">N<\/span>; <span style=\"color:#a6e22e\">i<\/span><span style=\"color:#f92672\">++<\/span> {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">output<\/span>.<span style=\"color:#a6e22e\">Reset<\/span>()<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">algOne<\/span>(<span style=\"color:#a6e22e\">in<\/span>, <span style=\"color:#a6e22e\">find<\/span>, <span style=\"color:#a6e22e\">repl<\/span>, <span style=\"color:#f92672\">&amp;<\/span><span style=\"color:#a6e22e\">output<\/span>)<\/span><\/span><span style=\"display:flex;\"><span> }<\/span><\/span><span style=\"display:flex;\"><span>}<\/span><\/span><\/code><\/pre><\/div><p>\u6211\u4eec\u901a\u8fc7 <code>go test -run none -bench AlgorithmOne -benchtime 3s -benchmem<\/code> \u8fd0\u884c benchmark\uff0c\u8f93\u51fa\u5982\u4e0b\uff1a<\/p><pre tabindex=\"0\"><code>$go test -run none -bench AlgorithmOne -benchtime 3s -benchmemBenchmarkAlgorithmOne-8 2000000 2522 ns\/op 117 B\/op 2 allocs\/op<\/code><\/pre><p>\u6211\u4eec\u53ef\u4ee5\u770b\u5230 <code>algOne<\/code> \u51fd\u6570\u6709\u4e24\u6b21\u5185\u5b58\u5206\u914d\uff0c\u6bcf\u6b21\u5206\u914d\u4e86 117 \u4e2a\u5b57\u8282\u3002\u6211\u4eec\u901a\u8fc7 profiling \u6570\u636e\u6765\u770b\u4e00\u4e0b\u54ea\u884c\u4ee3\u7801\u9020\u6210\u4e86\u5185\u5b58\u5206\u914d\u3002<\/p><h2 id=\"profiling\">Profiling<\/h2><p>\u5728 <code>go test<\/code> \u540e\u52a0\u4e0a <code>memprofile<\/code> \u53c2\u6570\uff0c\u91cd\u65b0\u6267\u884c\u6d4b\u8bd5\u3002<\/p><pre tabindex=\"0\"><code>$ go test -run none -bench AlgorithmOne -benchtime 3s -benchmem -memprofile mem.outBenchmarkAlgorithmOne-8 2000000 2570 ns\/op 117 B\/op 2 allocs\/op<\/code><\/pre><p>benchmark \u6267\u884c\u7ed3\u675f\u540e\uff0c\u4f1a\u751f\u6210\u4e24\u4e2a\u65b0\u6587\u4ef6\u3002<\/p><pre tabindex=\"0\"><code>~\/code\/go\/src\/...\/memcpu$ ls -ltotal 9248-rw-r--r-- 1 bill staff 209 May 22 18:11 mem.out (NEW)-rwxr-xr-x 1 bill staff 2847600 May 22 18:10 memcpu.test (NEW)-rw-r--r-- 1 bill staff 4761 May 22 18:01 stream.go-rw-r--r-- 1 bill staff 880 May 22 14:49 stream_test.go<\/code><\/pre><p>\u6e90\u7801\u5728 memcpu \u76ee\u5f55\u4e2d\uff0c<code>algOne<\/code> \u51fd\u6570\u5728 stream.go \u6587\u4ef6\u4e2d\uff0cbenchmark \u6d4b\u8bd5\u5728 stream_test.go \u6587\u4ef6\u4e2d\u3002mem.out \u548c memcpu.test \u662f\u65b0\u751f\u6210\u7684\u6587\u4ef6\uff0c\u5185\u5bb9\u662fprofile\u6570\u636e\uff0c\u6709\u4e86\u8fd9\u4fe9\u6587\u4ef6\uff0c\u5c31\u53ef\u4ee5\u4f7f\u7528 <code>pprof<\/code> \u5de5\u5177\u8fdb\u884c\u5206\u6790\u4e86<\/p><div class=\"highlight\"><pre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"><code class=\"language-go\" data-lang=\"go\"><span style=\"display:flex;\"><span><span style=\"color:#960050;background-color:#1e0010\">$<\/span> <span style=\"color:#66d9ef\">go<\/span> <span style=\"color:#a6e22e\">tool<\/span> <span style=\"color:#a6e22e\">pprof<\/span> <span style=\"color:#f92672\">-<\/span><span style=\"color:#a6e22e\">alloc_space<\/span> <span style=\"color:#a6e22e\">memcpu<\/span>.<span style=\"color:#a6e22e\">test<\/span> <span style=\"color:#a6e22e\">mem<\/span>.<span style=\"color:#a6e22e\">out<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#a6e22e\">Entering<\/span> <span style=\"color:#a6e22e\">interactive<\/span> <span style=\"color:#a6e22e\">mode<\/span> (<span style=\"color:#66d9ef\">type<\/span> <span style=\"color:#e6db74\">&#34;help&#34;<\/span> <span style=\"color:#66d9ef\">for<\/span> <span style=\"color:#a6e22e\">commands<\/span>)<\/span><\/span><span style=\"display:flex;\"><span>(<span style=\"color:#a6e22e\">pprof<\/span>) <span style=\"color:#a6e22e\">_<\/span><\/span><\/span><\/code><\/pre><\/div><p>\u8fd9\u91cc\u6211\u4eec\u4f7f\u7528 <code>-alloc_space<\/code> \u6765\u5206\u6790\u5185\u5b58\u5206\u914d\u3002\u6211\u4eec\u4f7f\u7528 <code>list algOne<\/code> \u547d\u4ee4\u67e5\u770b <code>algOne<\/code> \u51fd\u6570\u7684\u5185\u5b58\u5206\u914d\u3002<\/p><div class=\"highlight\"><pre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"><code class=\"language-go\" data-lang=\"go\"><span style=\"display:flex;\"><span>(<span style=\"color:#a6e22e\">pprof<\/span>) <span style=\"color:#a6e22e\">list<\/span> <span style=\"color:#a6e22e\">algOne<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#a6e22e\">Total<\/span>: <span style=\"color:#ae81ff\">335.03<\/span><span style=\"color:#a6e22e\">MB<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#a6e22e\">ROUTINE<\/span> <span style=\"color:#f92672\">========================<\/span> <span style=\"color:#f92672\">...\/<\/span><span style=\"color:#a6e22e\">memcpu<\/span>.<span style=\"color:#a6e22e\">algOne<\/span> <span style=\"color:#a6e22e\">in<\/span> <span style=\"color:#a6e22e\">code<\/span><span style=\"color:#f92672\">\/<\/span><span style=\"color:#66d9ef\">go<\/span><span style=\"color:#f92672\">\/<\/span><span style=\"color:#a6e22e\">src<\/span><span style=\"color:#f92672\">\/...\/<\/span><span style=\"color:#a6e22e\">memcpu<\/span><span style=\"color:#f92672\">\/<\/span><span style=\"color:#a6e22e\">stream<\/span>.<span style=\"color:#66d9ef\">go<\/span><\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#ae81ff\">335.03<\/span><span style=\"color:#a6e22e\">MB<\/span> <span style=\"color:#ae81ff\">335.03<\/span><span style=\"color:#a6e22e\">MB<\/span> (<span style=\"color:#a6e22e\">flat<\/span>, <span style=\"color:#a6e22e\">cum<\/span>) <span style=\"color:#ae81ff\">100<\/span><span style=\"color:#f92672\">%<\/span> <span style=\"color:#a6e22e\">of<\/span> <span style=\"color:#a6e22e\">Total<\/span><\/span><\/span><span style=\"display:flex;\"><span> . . <span style=\"color:#ae81ff\">78<\/span>:<\/span><\/span><span style=\"display:flex;\"><span> . . <span style=\"color:#ae81ff\">79<\/span>:<span style=\"color:#75715e\">\/\/ algOne is one way to solve the problem.<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span> . . <span style=\"color:#ae81ff\">80<\/span>:<span style=\"color:#66d9ef\">func<\/span> <span style=\"color:#a6e22e\">algOne<\/span>(<span style=\"color:#a6e22e\">data<\/span> []<span style=\"color:#66d9ef\">byte<\/span>, <span style=\"color:#a6e22e\">find<\/span> []<span style=\"color:#66d9ef\">byte<\/span>, <span style=\"color:#a6e22e\">repl<\/span> []<span style=\"color:#66d9ef\">byte<\/span>, <span style=\"color:#a6e22e\">output<\/span> <span style=\"color:#f92672\">*<\/span><span style=\"color:#a6e22e\">bytes<\/span>.<span style=\"color:#a6e22e\">Buffer<\/span>) {<\/span><\/span><span style=\"display:flex;\"><span> . . <span style=\"color:#ae81ff\">81<\/span>:<\/span><\/span><span style=\"display:flex;\"><span> . . <span style=\"color:#ae81ff\">82<\/span>: <span style=\"color:#75715e\">\/\/ Use a bytes Buffer to provide a stream to process.<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span> <span style=\"color:#ae81ff\">318.53<\/span><span style=\"color:#a6e22e\">MB<\/span> <span style=\"color:#ae81ff\">318.53<\/span><span style=\"color:#a6e22e\">MB<\/span> <span style=\"color:#ae81ff\">83<\/span>: <span style=\"color:#a6e22e\">input<\/span> <span style=\"color:#f92672\">:=<\/span> <span style=\"color:#a6e22e\">bytes<\/span>.<span style=\"color:#a6e22e\">NewBuffer<\/span>(<span style=\"color:#a6e22e\">data<\/span>)<\/span><\/span><span style=\"display:flex;\"><span> . . <span style=\"color:#ae81ff\">84<\/span>:<\/span><\/span><span style=\"display:flex;\"><span> . . <span style=\"color:#ae81ff\">85<\/span>: <span style=\"color:#75715e\">\/\/ The number of bytes we are looking for.<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span> . . <span style=\"color:#ae81ff\">86<\/span>: <span style=\"color:#a6e22e\">size<\/span> <span style=\"color:#f92672\">:=<\/span> len(<span style=\"color:#a6e22e\">find<\/span>)<\/span><\/span><span style=\"display:flex;\"><span> . . <span style=\"color:#ae81ff\">87<\/span>:<\/span><\/span><span style=\"display:flex;\"><span> . . <span style=\"color:#ae81ff\">88<\/span>: <span style=\"color:#75715e\">\/\/ Declare the buffers we need to process the stream.<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span> <span style=\"color:#ae81ff\">16.50<\/span><span style=\"color:#a6e22e\">MB<\/span> <span style=\"color:#ae81ff\">16.50<\/span><span style=\"color:#a6e22e\">MB<\/span> <span style=\"color:#ae81ff\">89<\/span>: <span style=\"color:#a6e22e\">buf<\/span> <span style=\"color:#f92672\">:=<\/span> make([]<span style=\"color:#66d9ef\">byte<\/span>, <span style=\"color:#a6e22e\">size<\/span>)<\/span><\/span><span style=\"display:flex;\"><span> . . <span style=\"color:#ae81ff\">90<\/span>: <span style=\"color:#a6e22e\">end<\/span> <span style=\"color:#f92672\">:=<\/span> <span style=\"color:#a6e22e\">size<\/span> <span style=\"color:#f92672\">-<\/span> <span style=\"color:#ae81ff\">1<\/span><\/span><\/span><span style=\"display:flex;\"><span> . . <span style=\"color:#ae81ff\">91<\/span>:<\/span><\/span><span style=\"display:flex;\"><span> . . <span style=\"color:#ae81ff\">92<\/span>: <span style=\"color:#75715e\">\/\/ Read in an initial number of bytes we need to get started.<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span> . . <span style=\"color:#ae81ff\">93<\/span>: <span style=\"color:#66d9ef\">if<\/span> <span style=\"color:#a6e22e\">n<\/span>, <span style=\"color:#a6e22e\">err<\/span> <span style=\"color:#f92672\">:=<\/span> <span style=\"color:#a6e22e\">io<\/span>.<span style=\"color:#a6e22e\">ReadFull<\/span>(<span style=\"color:#a6e22e\">input<\/span>, <span style=\"color:#a6e22e\">buf<\/span>[:<span style=\"color:#a6e22e\">end<\/span>]); <span style=\"color:#a6e22e\">err<\/span> <span style=\"color:#f92672\">!=<\/span> <span style=\"color:#66d9ef\">nil<\/span> <span style=\"color:#f92672\">||<\/span> <span style=\"color:#a6e22e\">n<\/span> &lt; <span style=\"color:#a6e22e\">end<\/span> {<\/span><\/span><span style=\"display:flex;\"><span> . . <span style=\"color:#ae81ff\">94<\/span>: <span style=\"color:#a6e22e\">output<\/span>.<span style=\"color:#a6e22e\">Write<\/span>(<span style=\"color:#a6e22e\">buf<\/span>[:<span style=\"color:#a6e22e\">n<\/span>])<\/span><\/span><span style=\"display:flex;\"><span>(<span style=\"color:#a6e22e\">pprof<\/span>) <span style=\"color:#a6e22e\">_<\/span><\/span><\/span><\/code><\/pre><\/div><p>\u5206\u6790\u4fe1\u606f\u5c55\u793a\u4e86 <code>input<\/code> \u53d8\u91cf\u548c <code>buf<\/code> slice\u5728\u5806\u4e0a\u521b\u5efa\u3002<\/p><p><code>input<\/code> \u53d8\u91cf\u662f\u6307\u9488\uff0c\u5373 <code>input<\/code> \u6307\u5411\u7684 <code>bytes.Buffer<\/code> \u503c\u5206\u914d\u5728\u5806\u4e0a\u3002flat\u5217\uff08pprof\u8f93\u51fa\u7684\u7b2c\u4e00\u5217\uff09\u5c55\u793a\u7531\u4e8e <code>algOne<\/code> \u51fd\u6570\u5171\u4eab\u5bfc\u81f4\u53d8\u91cf\u9003\u9038\uff0c\u800c <code>algOne<\/code> \u51fd\u6570\u5728 benchmark \u4e2d\u8c03\u7528\uff0c\u6211\u4eec\u7528 <code>list Benchmark<\/code> \u51fd\u6570\u770b\u4e00\u4e0b Benchmark \u7684\u5185\u5b58\u5206\u914d\u3002<\/p><div class=\"highlight\"><pre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"><code class=\"language-go\" data-lang=\"go\"><span style=\"display:flex;\"><span>(<span style=\"color:#a6e22e\">pprof<\/span>) <span style=\"color:#a6e22e\">list<\/span> <span style=\"color:#a6e22e\">Benchmark<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#a6e22e\">Total<\/span>: <span style=\"color:#ae81ff\">335.03<\/span><span style=\"color:#a6e22e\">MB<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#a6e22e\">ROUTINE<\/span> <span style=\"color:#f92672\">========================<\/span> <span style=\"color:#f92672\">...\/<\/span><span style=\"color:#a6e22e\">memcpu<\/span>.<span style=\"color:#a6e22e\">BenchmarkAlgorithmOne<\/span> <span style=\"color:#a6e22e\">in<\/span> <span style=\"color:#a6e22e\">code<\/span><span style=\"color:#f92672\">\/<\/span><span style=\"color:#66d9ef\">go<\/span><span style=\"color:#f92672\">\/<\/span><span style=\"color:#a6e22e\">src<\/span><span style=\"color:#f92672\">\/...\/<\/span><span style=\"color:#a6e22e\">memcpu<\/span><span style=\"color:#f92672\">\/<\/span><span style=\"color:#a6e22e\">stream_test<\/span>.<span style=\"color:#66d9ef\">go<\/span><\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#ae81ff\">0<\/span> <span style=\"color:#ae81ff\">335.03<\/span><span style=\"color:#a6e22e\">MB<\/span> (<span style=\"color:#a6e22e\">flat<\/span>, <span style=\"color:#a6e22e\">cum<\/span>) <span style=\"color:#ae81ff\">100<\/span><span style=\"color:#f92672\">%<\/span> <span style=\"color:#a6e22e\">of<\/span> <span style=\"color:#a6e22e\">Total<\/span><\/span><\/span><span style=\"display:flex;\"><span> . . <span style=\"color:#ae81ff\">18<\/span>: <span style=\"color:#a6e22e\">find<\/span> <span style=\"color:#f92672\">:=<\/span> []byte(<span style=\"color:#e6db74\">&#34;elvis&#34;<\/span>)<\/span><\/span><span style=\"display:flex;\"><span> . . <span style=\"color:#ae81ff\">19<\/span>: <span style=\"color:#a6e22e\">repl<\/span> <span style=\"color:#f92672\">:=<\/span> []byte(<span style=\"color:#e6db74\">&#34;Elvis&#34;<\/span>)<\/span><\/span><span style=\"display:flex;\"><span> . . <span style=\"color:#ae81ff\">20<\/span>:<\/span><\/span><span style=\"display:flex;\"><span> . . <span style=\"color:#ae81ff\">21<\/span>: <span style=\"color:#a6e22e\">b<\/span>.<span style=\"color:#a6e22e\">ResetTimer<\/span>()<\/span><\/span><span style=\"display:flex;\"><span> . . <span style=\"color:#ae81ff\">22<\/span>:<\/span><\/span><span style=\"display:flex;\"><span> . <span style=\"color:#ae81ff\">335.03<\/span><span style=\"color:#a6e22e\">MB<\/span> <span style=\"color:#ae81ff\">23<\/span>: <span style=\"color:#66d9ef\">for<\/span> <span style=\"color:#a6e22e\">i<\/span> <span style=\"color:#f92672\">:=<\/span> <span style=\"color:#ae81ff\">0<\/span>; <span style=\"color:#a6e22e\">i<\/span> &lt; <span style=\"color:#a6e22e\">b<\/span>.<span style=\"color:#a6e22e\">N<\/span>; <span style=\"color:#a6e22e\">i<\/span><span style=\"color:#f92672\">++<\/span> {<\/span><\/span><span style=\"display:flex;\"><span> . . <span style=\"color:#ae81ff\">24<\/span>: <span style=\"color:#a6e22e\">output<\/span>.<span style=\"color:#a6e22e\">Reset<\/span>()<\/span><\/span><span style=\"display:flex;\"><span> . . <span style=\"color:#ae81ff\">25<\/span>: <span style=\"color:#a6e22e\">algOne<\/span>(<span style=\"color:#a6e22e\">in<\/span>, <span style=\"color:#a6e22e\">find<\/span>, <span style=\"color:#a6e22e\">repl<\/span>, <span style=\"color:#f92672\">&amp;<\/span><span style=\"color:#a6e22e\">output<\/span>)<\/span><\/span><span style=\"display:flex;\"><span> . . <span style=\"color:#ae81ff\">26<\/span>: }<\/span><\/span><span style=\"display:flex;\"><span> . . <span style=\"color:#ae81ff\">27<\/span>:}<\/span><\/span><span style=\"display:flex;\"><span> . . <span style=\"color:#ae81ff\">28<\/span>:<\/span><\/span><span style=\"display:flex;\"><span>(<span style=\"color:#a6e22e\">pprof<\/span>) <span style=\"color:#a6e22e\">_<\/span><\/span><\/span><\/code><\/pre><\/div><p>cum\u5217\uff08pprof\u4fe1\u606f\u7684\u7b2c\u4e8c\u5217\uff09\u53ea\u6709\u4e00\u4e2a\u503c\uff0c\u6240\u4ee5 Benchmark \u51fd\u6570\u6ca1\u6709\u76f4\u63a5\u8fdb\u884c\u5185\u5b58\u5206\u914d\uff0c\u5185\u5b58\u5206\u914d\u5168\u90e8\u53d1\u751f\u5728for\u5faa\u73af\u4e2d\u3002pprof \u5de5\u5177\u53ea\u80fd\u5206\u6790\u51fa\u6709\u53d8\u91cf\u9003\u9038\uff0c\u6211\u4eec\u9700\u8981\u901a\u8fc7 <code>go build gcflags &quot;-m -m&quot;<\/code> \u547d\u4ee4\u6765\u770b\u4e00\u4e0b <code>bytes.Buffer<\/code> \u7684\u503c\u4e3a\u4ec0\u4e48\u4f1a\u53d1\u751f\u9003\u9038\u3002<\/p><h2 id=\"\u7f16\u8bd1\u5668\u62a5\u544acompiler-reporting\">\u7f16\u8bd1\u5668\u62a5\u544a\uff08Compiler Reporting\uff09<\/h2><div class=\"highlight\"><pre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"><code class=\"language-go\" data-lang=\"go\"><span style=\"display:flex;\"><span><span style=\"color:#960050;background-color:#1e0010\">$<\/span> <span style=\"color:#66d9ef\">go<\/span> <span style=\"color:#a6e22e\">build<\/span> <span style=\"color:#f92672\">-<\/span><span style=\"color:#a6e22e\">gcflags<\/span> <span style=\"color:#e6db74\">&#34;-m -m&#34;<\/span><\/span><\/span><\/code><\/pre><\/div><p><code>go build<\/code> \u8f93\u51fa\u4fe1\u606f\u5f88\u591a\uff0c\u7531\u4e8e\u662f\u5728\u7b2c83\u884c\u521b\u5efa\u7684 <code>bytes.buffer<\/code> \u503c\uff0c\u6240\u4ee5\u6211\u4eec\u53ea\u5173\u6ce8 <code>stream.go:83\u3002<\/code><\/p><div class=\"highlight\"><pre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"><code class=\"language-go\" data-lang=\"go\"><span style=\"display:flex;\"><span>.<span style=\"color:#f92672\">\/<\/span><span style=\"color:#a6e22e\">stream<\/span>.<span style=\"color:#66d9ef\">go<\/span>:<span style=\"color:#ae81ff\">83<\/span>: <span style=\"color:#a6e22e\">inlining<\/span> <span style=\"color:#a6e22e\">call<\/span> <span style=\"color:#a6e22e\">to<\/span> <span style=\"color:#a6e22e\">bytes<\/span>.<span style=\"color:#a6e22e\">NewBuffer<\/span> <span style=\"color:#66d9ef\">func<\/span>([]<span style=\"color:#66d9ef\">byte<\/span>) <span style=\"color:#f92672\">*<\/span><span style=\"color:#a6e22e\">bytes<\/span>.<span style=\"color:#a6e22e\">Buffer<\/span> { <span style=\"color:#66d9ef\">return<\/span> <span style=\"color:#f92672\">&amp;<\/span><span style=\"color:#a6e22e\">bytes<\/span>.<span style=\"color:#a6e22e\">Buffer<\/span> <span style=\"color:#a6e22e\">literal<\/span> }<\/span><\/span><span style=\"display:flex;\"><span><\/span><\/span><span style=\"display:flex;\"><span>.<span style=\"color:#f92672\">\/<\/span><span style=\"color:#a6e22e\">stream<\/span>.<span style=\"color:#66d9ef\">go<\/span>:<span style=\"color:#ae81ff\">83<\/span>: <span style=\"color:#f92672\">&amp;<\/span><span style=\"color:#a6e22e\">bytes<\/span>.<span style=\"color:#a6e22e\">Buffer<\/span> <span style=\"color:#a6e22e\">literal<\/span> <span style=\"color:#a6e22e\">escapes<\/span> <span style=\"color:#a6e22e\">to<\/span> <span style=\"color:#a6e22e\">heap<\/span><\/span><\/span><span style=\"display:flex;\"><span>.<span style=\"color:#f92672\">\/<\/span><span style=\"color:#a6e22e\">stream<\/span>.<span style=\"color:#66d9ef\">go<\/span>:<span style=\"color:#ae81ff\">83<\/span>: <span style=\"color:#a6e22e\">from<\/span> <span style=\"color:#960050;background-color:#1e0010\">~<\/span><span style=\"color:#a6e22e\">r0<\/span> (<span style=\"color:#a6e22e\">assign<\/span><span style=\"color:#f92672\">-<\/span><span style=\"color:#a6e22e\">pair<\/span>) <span style=\"color:#a6e22e\">at<\/span> .<span style=\"color:#f92672\">\/<\/span><span style=\"color:#a6e22e\">stream<\/span>.<span style=\"color:#66d9ef\">go<\/span>:<span style=\"color:#ae81ff\">83<\/span><\/span><\/span><span style=\"display:flex;\"><span>.<span style=\"color:#f92672\">\/<\/span><span style=\"color:#a6e22e\">stream<\/span>.<span style=\"color:#66d9ef\">go<\/span>:<span style=\"color:#ae81ff\">83<\/span>: <span style=\"color:#a6e22e\">from<\/span> <span style=\"color:#a6e22e\">input<\/span> (<span style=\"color:#a6e22e\">assigned<\/span>) <span style=\"color:#a6e22e\">at<\/span> .<span style=\"color:#f92672\">\/<\/span><span style=\"color:#a6e22e\">stream<\/span>.<span style=\"color:#66d9ef\">go<\/span>:<span style=\"color:#ae81ff\">83<\/span><\/span><\/span><span style=\"display:flex;\"><span>.<span style=\"color:#f92672\">\/<\/span><span style=\"color:#a6e22e\">stream<\/span>.<span style=\"color:#66d9ef\">go<\/span>:<span style=\"color:#ae81ff\">83<\/span>: <span style=\"color:#a6e22e\">from<\/span> <span style=\"color:#a6e22e\">input<\/span> (<span style=\"color:#66d9ef\">interface<\/span><span style=\"color:#f92672\">-<\/span><span style=\"color:#a6e22e\">converted<\/span>) <span style=\"color:#a6e22e\">at<\/span> .<span style=\"color:#f92672\">\/<\/span><span style=\"color:#a6e22e\">stream<\/span>.<span style=\"color:#66d9ef\">go<\/span>:<span style=\"color:#ae81ff\">93<\/span><\/span><\/span><span style=\"display:flex;\"><span>.<span style=\"color:#f92672\">\/<\/span><span style=\"color:#a6e22e\">stream<\/span>.<span style=\"color:#66d9ef\">go<\/span>:<span style=\"color:#ae81ff\">83<\/span>: <span style=\"color:#a6e22e\">from<\/span> <span style=\"color:#a6e22e\">input<\/span> (<span style=\"color:#a6e22e\">passed<\/span> <span style=\"color:#a6e22e\">to<\/span> <span style=\"color:#a6e22e\">call<\/span>[<span style=\"color:#a6e22e\">argument<\/span> <span style=\"color:#a6e22e\">escapes<\/span>]) <span style=\"color:#a6e22e\">at<\/span> .<span style=\"color:#f92672\">\/<\/span><span style=\"color:#a6e22e\">stream<\/span>.<span style=\"color:#66d9ef\">go<\/span>:<span style=\"color:#ae81ff\">93<\/span><\/span><\/span><\/code><\/pre><\/div><p>\u4ece\u7b2c\u4e00\u884c\u4fe1\u606f\u53ef\u4ee5\u770b\u51fa\u6765\uff0c<code>bytes.Buffer<\/code> \u503c\u4e00\u5f00\u59cb\u5e76\u6ca1\u9003\u9038\uff0c<code>bytes.NewBuffer<\/code> \u51fd\u6570\u8fd4\u56de <code>bytes.Buffer<\/code> \u503c\u7684\u5730\u5740\uff0c\u63a5\u4e0b\u6765\u76845\u884c\u4fe1\u606f\u5c55\u793a\u4e86\u7b2c93\u884c\u5bfc\u81f4 <code>bytes.Buffer<\/code> \u503c\u4ece<code>algOne<\/code> \u6808\u9003\u9038\uff0c<code>input<\/code> \u53d8\u91cf\u88ab\u8d4b\u503c\u7ed9\u4e00\u4e2a\u63a5\u53e3\u53d8\u91cf\u3002<\/p><h2 id=\"\u63a5\u53e3interface\">\u63a5\u53e3\uff08interface\uff09<\/h2><p><code>algOne<\/code> \u51fd\u6570\u7684\u7b2c 93 \u884c\u4ee3\u7801\u8c03\u7528 <code>io.ReadFull<\/code> \u51fd\u6570\u9020\u6210\u4e86\u63a5\u53e3\u8d4b\u503c\u3002<\/p><div class=\"highlight\"><pre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"><code class=\"language-go\" data-lang=\"go\"><span style=\"display:flex;\"><span><span style=\"color:#66d9ef\">type<\/span> <span style=\"color:#a6e22e\">Reader<\/span> <span style=\"color:#66d9ef\">interface<\/span> {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">Read<\/span>(<span style=\"color:#a6e22e\">p<\/span> []<span style=\"color:#66d9ef\">byte<\/span>) (<span style=\"color:#a6e22e\">n<\/span> <span style=\"color:#66d9ef\">int<\/span>, <span style=\"color:#a6e22e\">err<\/span> <span style=\"color:#66d9ef\">error<\/span>)<\/span><\/span><span style=\"display:flex;\"><span>}<\/span><\/span><span style=\"display:flex;\"><span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#66d9ef\">func<\/span> <span style=\"color:#a6e22e\">ReadFull<\/span>(<span style=\"color:#a6e22e\">r<\/span> <span style=\"color:#a6e22e\">Reader<\/span>, <span style=\"color:#a6e22e\">buf<\/span> []<span style=\"color:#66d9ef\">byte<\/span>) (<span style=\"color:#a6e22e\">n<\/span> <span style=\"color:#66d9ef\">int<\/span>, <span style=\"color:#a6e22e\">err<\/span> <span style=\"color:#66d9ef\">error<\/span>) {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">return<\/span> <span style=\"color:#a6e22e\">ReadAtLeast<\/span>(<span style=\"color:#a6e22e\">r<\/span>, <span style=\"color:#a6e22e\">buf<\/span>, len(<span style=\"color:#a6e22e\">buf<\/span>))<\/span><\/span><span style=\"display:flex;\"><span>}<\/span><\/span><\/code><\/pre><\/div><p>\u901a\u8fc7 <code>ReadFull<\/code> \u51fd\u6570\u4ee3\u7801\u6211\u4eec\u53d1\u73b0\uff0c<code>bytes.Buffer<\/code> \u7684\u6307\u9488\u53d8\u91cf\u8d4b\u503c\u7ed9\u4e86 Reader \u63a5\u53e3\u3002\u73b0\u5728\u6211\u4eec\u77e5\u9053\u4e86\u4f7f\u7528\u63a5\u53e3\u53d8\u91cf\u7684\u5f00\u9500\uff1a\u5206\u914d\u548c\u91cd\u5b9a\u5411\u3002\u6240\u4ee5\u5982\u679c\u6ca1\u6709\u5fc5\u987b\u7684\u4f7f\u7528\u63a5\u53e3\u53d8\u91cf\u7684\u539f\u56e0\uff0c\u53ef\u4ee5\u4e0d\u4f7f\u7528\u63a5\u53e3\u53d8\u91cf\u3002<\/p><p>\u4fee\u6539\u76f4<code>algOne<\/code> \u51fd\u6570\uff0c\u63a5\u7528 <code>io<\/code> \u5305\u7684 <code>Read<\/code> \u51fd\u6570\u6765\u4ee3\u66ff <code>ReadFull<\/code> \u51fd\u6570\u3002<\/p><div class=\"highlight\"><pre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"><code class=\"language-go\" data-lang=\"go\"><span style=\"display:flex;\"><span><span style=\"color:#f92672\">import<\/span> (<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#e6db74\">&#34;bytes&#34;<\/span><\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#e6db74\">&#34;fmt&#34;<\/span><\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">_<\/span> <span style=\"color:#e6db74\">&#34;io&#34;<\/span><\/span><\/span><span style=\"display:flex;\"><span>)<\/span><\/span><span style=\"display:flex;\"><span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#66d9ef\">func<\/span> <span style=\"color:#a6e22e\">algOne<\/span>(<span style=\"color:#a6e22e\">data<\/span> []<span style=\"color:#66d9ef\">byte<\/span>, <span style=\"color:#a6e22e\">find<\/span> []<span style=\"color:#66d9ef\">byte<\/span>, <span style=\"color:#a6e22e\">repl<\/span> []<span style=\"color:#66d9ef\">byte<\/span>, <span style=\"color:#a6e22e\">output<\/span> <span style=\"color:#f92672\">*<\/span><span style=\"color:#a6e22e\">bytes<\/span>.<span style=\"color:#a6e22e\">Buffer<\/span>) {<\/span><\/span><span style=\"display:flex;\"><span><\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#75715e\">\/\/ Use a bytes Buffer to provide a stream to process.<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span> <span style=\"color:#a6e22e\">input<\/span> <span style=\"color:#f92672\">:=<\/span> <span style=\"color:#a6e22e\">bytes<\/span>.<span style=\"color:#a6e22e\">NewBuffer<\/span>(<span style=\"color:#a6e22e\">data<\/span>)<\/span><\/span><span style=\"display:flex;\"><span><\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#75715e\">\/\/ The number of bytes we are looking for.<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span> <span style=\"color:#a6e22e\">size<\/span> <span style=\"color:#f92672\">:=<\/span> len(<span style=\"color:#a6e22e\">find<\/span>)<\/span><\/span><span style=\"display:flex;\"><span><\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#75715e\">\/\/ Declare the buffers we need to process the stream.<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span> <span style=\"color:#a6e22e\">buf<\/span> <span style=\"color:#f92672\">:=<\/span> make([]<span style=\"color:#66d9ef\">byte<\/span>, <span style=\"color:#a6e22e\">size<\/span>)<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">end<\/span> <span style=\"color:#f92672\">:=<\/span> <span style=\"color:#a6e22e\">size<\/span> <span style=\"color:#f92672\">-<\/span> <span style=\"color:#ae81ff\">1<\/span><\/span><\/span><span style=\"display:flex;\"><span><\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#75715e\">\/\/ Read in an initial number of bytes we need to get started.<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span> <span style=\"color:#66d9ef\">if<\/span> <span style=\"color:#a6e22e\">n<\/span>, <span style=\"color:#a6e22e\">err<\/span> <span style=\"color:#f92672\">:=<\/span> <span style=\"color:#a6e22e\">input<\/span>.<span style=\"color:#a6e22e\">Read<\/span>(<span style=\"color:#a6e22e\">buf<\/span>[:<span style=\"color:#a6e22e\">end<\/span>]); <span style=\"color:#a6e22e\">err<\/span> <span style=\"color:#f92672\">!=<\/span> <span style=\"color:#66d9ef\">nil<\/span> <span style=\"color:#f92672\">||<\/span> <span style=\"color:#a6e22e\">n<\/span> &lt; <span style=\"color:#a6e22e\">end<\/span> {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">output<\/span>.<span style=\"color:#a6e22e\">Write<\/span>(<span style=\"color:#a6e22e\">buf<\/span>[:<span style=\"color:#a6e22e\">n<\/span>])<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">return<\/span><\/span><\/span><span style=\"display:flex;\"><span> }<\/span><\/span><span style=\"display:flex;\"><span><\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">for<\/span> {<\/span><\/span><span style=\"display:flex;\"><span><\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#75715e\">\/\/ Read in one byte from the input stream.<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span> <span style=\"color:#66d9ef\">if<\/span> <span style=\"color:#a6e22e\">_<\/span>, <span style=\"color:#a6e22e\">err<\/span> <span style=\"color:#f92672\">:=<\/span> <span style=\"color:#a6e22e\">input<\/span>.<span style=\"color:#a6e22e\">Read<\/span>(<span style=\"color:#a6e22e\">buf<\/span>[<span style=\"color:#a6e22e\">end<\/span>:]); <span style=\"color:#a6e22e\">err<\/span> <span style=\"color:#f92672\">!=<\/span> <span style=\"color:#66d9ef\">nil<\/span> {<\/span><\/span><span style=\"display:flex;\"><span><\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#75715e\">\/\/ Flush the reset of the bytes we have.<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span> <span style=\"color:#a6e22e\">output<\/span>.<span style=\"color:#a6e22e\">Write<\/span>(<span style=\"color:#a6e22e\">buf<\/span>[:<span style=\"color:#a6e22e\">end<\/span>])<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">return<\/span><\/span><\/span><span style=\"display:flex;\"><span> }<\/span><\/span><span style=\"display:flex;\"><span><\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#75715e\">\/\/ If we have a match, replace the bytes.<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span> <span style=\"color:#66d9ef\">if<\/span> <span style=\"color:#a6e22e\">bytes<\/span>.<span style=\"color:#a6e22e\">Compare<\/span>(<span style=\"color:#a6e22e\">buf<\/span>, <span style=\"color:#a6e22e\">find<\/span>) <span style=\"color:#f92672\">==<\/span> <span style=\"color:#ae81ff\">0<\/span> {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">output<\/span>.<span style=\"color:#a6e22e\">Write<\/span>(<span style=\"color:#a6e22e\">repl<\/span>)<\/span><\/span><span style=\"display:flex;\"><span><\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#75715e\">\/\/ Read a new initial number of bytes.<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span> <span style=\"color:#66d9ef\">if<\/span> <span style=\"color:#a6e22e\">n<\/span>, <span style=\"color:#a6e22e\">err<\/span> <span style=\"color:#f92672\">:=<\/span> <span style=\"color:#a6e22e\">input<\/span>.<span style=\"color:#a6e22e\">Read<\/span>(<span style=\"color:#a6e22e\">buf<\/span>[:<span style=\"color:#a6e22e\">end<\/span>]); <span style=\"color:#a6e22e\">err<\/span> <span style=\"color:#f92672\">!=<\/span> <span style=\"color:#66d9ef\">nil<\/span> <span style=\"color:#f92672\">||<\/span> <span style=\"color:#a6e22e\">n<\/span> &lt; <span style=\"color:#a6e22e\">end<\/span> {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">output<\/span>.<span style=\"color:#a6e22e\">Write<\/span>(<span style=\"color:#a6e22e\">buf<\/span>[:<span style=\"color:#a6e22e\">n<\/span>])<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">return<\/span><\/span><\/span><span style=\"display:flex;\"><span> }<\/span><\/span><span style=\"display:flex;\"><span><\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">continue<\/span><\/span><\/span><span style=\"display:flex;\"><span> }<\/span><\/span><span style=\"display:flex;\"><span><\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#75715e\">\/\/ Write the front byte since it has been compared.<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span> <span style=\"color:#a6e22e\">output<\/span>.<span style=\"color:#a6e22e\">WriteByte<\/span>(<span style=\"color:#a6e22e\">buf<\/span>[<span style=\"color:#ae81ff\">0<\/span>])<\/span><\/span><span style=\"display:flex;\"><span><\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#75715e\">\/\/ Slice that front byte out.<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span> copy(<span style=\"color:#a6e22e\">buf<\/span>, <span style=\"color:#a6e22e\">buf<\/span>[<span style=\"color:#ae81ff\">1<\/span>:])<\/span><\/span><span style=\"display:flex;\"><span> }<\/span><\/span><span style=\"display:flex;\"><span>}<\/span><\/span><\/code><\/pre><\/div><p>\u518d\u6b21\u8fd0\u884c benchmark\uff0c\u6bcf\u6b21\u64cd\u4f5c\u7684\u5185\u5b58\u5206\u914d\u6b21\u6570\u53d8\u6210\u4e86\u4e00\u6b21\uff0c<code>bytes.Buffer<\/code> \u53d8\u91cf\u4e0d\u518d\u9003\u9038\u4e86\u3002\u6027\u80fd\u63d0\u5347\u4e8629%\uff08\u4ece 2570 ns\/op \u5230 1814 ns\/op\uff09\uff0c<\/p><div class=\"highlight\"><pre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"><code class=\"language-go\" data-lang=\"go\"><span style=\"display:flex;\"><span><span style=\"color:#960050;background-color:#1e0010\">$<\/span> <span style=\"color:#66d9ef\">go<\/span> <span style=\"color:#a6e22e\">test<\/span> <span style=\"color:#f92672\">-<\/span><span style=\"color:#a6e22e\">run<\/span> <span style=\"color:#a6e22e\">none<\/span> <span style=\"color:#f92672\">-<\/span><span style=\"color:#a6e22e\">bench<\/span> <span style=\"color:#a6e22e\">AlgorithmOne<\/span> <span style=\"color:#f92672\">-<\/span><span style=\"color:#a6e22e\">benchtime<\/span> <span style=\"color:#ae81ff\">3<\/span><span style=\"color:#a6e22e\">s<\/span> <span style=\"color:#f92672\">-<\/span><span style=\"color:#a6e22e\">benchmem<\/span> <span style=\"color:#f92672\">-<\/span><span style=\"color:#a6e22e\">memprofile<\/span> <span style=\"color:#a6e22e\">mem<\/span>.<span style=\"color:#a6e22e\">out<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#a6e22e\">BenchmarkAlgorithmOne<\/span><span style=\"color:#f92672\">-<\/span><span style=\"color:#ae81ff\">8<\/span> <span style=\"color:#ae81ff\">2000000<\/span> <span style=\"color:#ae81ff\">1814<\/span> <span style=\"color:#a6e22e\">ns<\/span><span style=\"color:#f92672\">\/<\/span><span style=\"color:#a6e22e\">op<\/span> <span style=\"color:#ae81ff\">5<\/span> <span style=\"color:#a6e22e\">B<\/span><span style=\"color:#f92672\">\/<\/span><span style=\"color:#a6e22e\">op<\/span> <span style=\"color:#ae81ff\">1<\/span> <span style=\"color:#a6e22e\">allocs<\/span><span style=\"color:#f92672\">\/<\/span><span style=\"color:#a6e22e\">op<\/span><\/span><\/span><\/code><\/pre><\/div><p>\u6211\u4eec\u7ee7\u7eed\u6765\u770b <code>buf<\/code> \u53d8\u91cf\u3002<\/p><h2 id=\"\u6808\u5e27stack-frames\">\u6808\u5e27\uff08Stack Frames\uff09<\/h2><p>\u518d\u6b21\u8fd0\u884c <code>go build -gcflags &quot;-m -m&quot;<\/code>\uff0c\u5e76\u5173\u6ce8 <code>stream.go:89<\/code> \u3002<\/p><div class=\"highlight\"><pre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"><code class=\"language-go\" data-lang=\"go\"><span style=\"display:flex;\"><span><span style=\"color:#960050;background-color:#1e0010\">$<\/span> <span style=\"color:#66d9ef\">go<\/span> <span style=\"color:#a6e22e\">build<\/span> <span style=\"color:#f92672\">-<\/span><span style=\"color:#a6e22e\">gcflags<\/span> <span style=\"color:#e6db74\">&#34;-m -m&#34;<\/span><\/span><\/span><span style=\"display:flex;\"><span>.<span style=\"color:#f92672\">\/<\/span><span style=\"color:#a6e22e\">stream<\/span>.<span style=\"color:#66d9ef\">go<\/span>:<span style=\"color:#ae81ff\">89<\/span>: make([]<span style=\"color:#66d9ef\">byte<\/span>, <span style=\"color:#a6e22e\">size<\/span>) <span style=\"color:#a6e22e\">escapes<\/span> <span style=\"color:#a6e22e\">to<\/span> <span style=\"color:#a6e22e\">heap<\/span><\/span><\/span><span style=\"display:flex;\"><span>.<span style=\"color:#f92672\">\/<\/span><span style=\"color:#a6e22e\">stream<\/span>.<span style=\"color:#66d9ef\">go<\/span>:<span style=\"color:#ae81ff\">89<\/span>: <span style=\"color:#a6e22e\">from<\/span> make([]<span style=\"color:#66d9ef\">byte<\/span>, <span style=\"color:#a6e22e\">size<\/span>) (<span style=\"color:#a6e22e\">too<\/span> <span style=\"color:#a6e22e\">large<\/span> <span style=\"color:#66d9ef\">for<\/span> <span style=\"color:#a6e22e\">stack<\/span>) <span style=\"color:#a6e22e\">at<\/span> .<span style=\"color:#f92672\">\/<\/span><span style=\"color:#a6e22e\">stream<\/span>.<span style=\"color:#66d9ef\">go<\/span>:<span style=\"color:#ae81ff\">89<\/span><\/span><\/span><\/code><\/pre><\/div><p>\u8fd9\u91cc\u8bf4 slice \u5e95\u5c42\u7684\u6570\u7ec4\u5bf9\u4e8e\u6808\u6765\u8bf4\u592a\u5927\u4e86\uff08too large for stack\uff09\u3002\u8fd9\u4e2a\u4fe1\u606f\u6709\u4e9b\u8bef\u5bfc\u6027\uff0c\u5176\u5b9e\u4e0d\u662f\u56e0\u4e3a\u6570\u7ec4\u592a\u5927\uff0c\u800c\u662f\u56e0\u4e3a\u7f16\u8bd1\u5668\u5728\u7f16\u8bd1\u9636\u6bb5\u4e0d\u77e5\u9053\u6570\u7ec4\u7684\u5927\u5c0f\u3002<\/p><p>\u53ea\u6709\u7f16\u8bd1\u5668\u5728\u7f16\u8bd1\u671f\u95f4\u77e5\u9053\u53d8\u91cf\u7684\u5927\u5c0f\u7684\u60c5\u51b5\u4e0b\uff0c\u53d8\u91cf\u624d\u4f1a\u88ab\u5206\u914d\u5728\u6808\u4e0a\uff0c\u8fd9\u662f\u56e0\u4e3a\u51fd\u6570\u6808\u5e27\u7684\u5927\u5c0f\u662f\u5728\u7f16\u8bd1\u9636\u6bb5\u786e\u5b9a\u7684\uff0c\u5982\u679c\u7f16\u8bd1\u5668\u5728\u7f16\u8bd1\u8fc7\u7a0b\u4e2d\u4e0d\u77e5\u9053\u53d8\u91cf\u7684\u5927\u5c0f\uff0c\u90a3\u4e48\u53d8\u91cf\u5c31\u4f1a\u5206\u914d\u5230\u5806\u4e0a\u3002<\/p><p>\u4fee\u6539 89 \u884c\u4ee3\u7801\uff0c\u5c06 <code>buf<\/code> \u53d8\u91cf\u7684\u521d\u59cb\u957f\u5ea6\u8bbe\u7f6e\u4e3a 5\uff0c\u518d\u6b21\u8fd0\u884c benchmark\u3002<\/p><div class=\"highlight\"><pre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"><code class=\"language-go\" data-lang=\"go\"><span style=\"display:flex;\"><span><span style=\"color:#a6e22e\">buf<\/span> <span style=\"color:#f92672\">:=<\/span> make([]<span style=\"color:#66d9ef\">byte<\/span>, <span style=\"color:#ae81ff\">5<\/span>)<\/span><\/span><\/code><\/pre><\/div><p>\u5185\u5b58\u5206\u914d\u6b21\u6570\u53d8\u6210\u4e86 0 \u6b21\u3002<\/p><div class=\"highlight\"><pre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"><code class=\"language-go\" data-lang=\"go\"><span style=\"display:flex;\"><span><span style=\"color:#960050;background-color:#1e0010\">$<\/span> <span style=\"color:#66d9ef\">go<\/span> <span style=\"color:#a6e22e\">test<\/span> <span style=\"color:#f92672\">-<\/span><span style=\"color:#a6e22e\">run<\/span> <span style=\"color:#a6e22e\">none<\/span> <span style=\"color:#f92672\">-<\/span><span style=\"color:#a6e22e\">bench<\/span> <span style=\"color:#a6e22e\">AlgorithmOne<\/span> <span style=\"color:#f92672\">-<\/span><span style=\"color:#a6e22e\">benchtime<\/span> <span style=\"color:#ae81ff\">3<\/span><span style=\"color:#a6e22e\">s<\/span> <span style=\"color:#f92672\">-<\/span><span style=\"color:#a6e22e\">benchmem<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#a6e22e\">BenchmarkAlgorithmOne<\/span><span style=\"color:#f92672\">-<\/span><span style=\"color:#ae81ff\">8<\/span> <span style=\"color:#ae81ff\">3000000<\/span> <span style=\"color:#ae81ff\">1720<\/span> <span style=\"color:#a6e22e\">ns<\/span><span style=\"color:#f92672\">\/<\/span><span style=\"color:#a6e22e\">op<\/span> <span style=\"color:#ae81ff\">0<\/span> <span style=\"color:#a6e22e\">B<\/span><span style=\"color:#f92672\">\/<\/span><span style=\"color:#a6e22e\">op<\/span> <span style=\"color:#ae81ff\">0<\/span> <span style=\"color:#a6e22e\">allocs<\/span><span style=\"color:#f92672\">\/<\/span><span style=\"color:#a6e22e\">op<\/span><\/span><\/span><\/code><\/pre><\/div><p>\u518d\u6b21\u8fd0\u884c <code>go build -gcflags &quot;-m -m&quot;<\/code> \u4f1a\u53d1\u73b0\uff0c\u6240\u6709\u53d8\u91cf\u90fd\u6ca1\u9003\u9038\u3002<\/p><div class=\"highlight\"><pre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"><code class=\"language-go\" data-lang=\"go\"><span style=\"display:flex;\"><span><span style=\"color:#960050;background-color:#1e0010\">$<\/span> <span style=\"color:#66d9ef\">go<\/span> <span style=\"color:#a6e22e\">build<\/span> <span style=\"color:#f92672\">-<\/span><span style=\"color:#a6e22e\">gcflags<\/span> <span style=\"color:#e6db74\">&#34;-m -m&#34;<\/span><\/span><\/span><span style=\"display:flex;\"><span>.<span style=\"color:#f92672\">\/<\/span><span style=\"color:#a6e22e\">stream<\/span>.<span style=\"color:#66d9ef\">go<\/span>:<span style=\"color:#ae81ff\">83<\/span>: <span style=\"color:#a6e22e\">algOne<\/span> <span style=\"color:#f92672\">&amp;<\/span><span style=\"color:#a6e22e\">bytes<\/span>.<span style=\"color:#a6e22e\">Buffer<\/span> <span style=\"color:#a6e22e\">literal<\/span> <span style=\"color:#a6e22e\">does<\/span> <span style=\"color:#a6e22e\">not<\/span> <span style=\"color:#a6e22e\">escape<\/span><\/span><\/span><span style=\"display:flex;\"><span>.<span style=\"color:#f92672\">\/<\/span><span style=\"color:#a6e22e\">stream<\/span>.<span style=\"color:#66d9ef\">go<\/span>:<span style=\"color:#ae81ff\">89<\/span>: <span style=\"color:#a6e22e\">algOne<\/span> make([]<span style=\"color:#66d9ef\">byte<\/span>, <span style=\"color:#ae81ff\">5<\/span>) <span style=\"color:#a6e22e\">does<\/span> <span style=\"color:#a6e22e\">not<\/span> <span style=\"color:#a6e22e\">escape<\/span><\/span><\/span><\/code><\/pre><\/div><p>\u4f46\u662f\u9664\u975e\u80fd\u786e\u8ba4 slice \u7684\u957f\u5ea6\uff0c\u5426\u5219\u6211\u4eec\u4e0d\u80fd\u901a\u8fc7\u786c\u7f16\u7801\u6765\u6307\u5b9a slice \u7684\u521d\u59cb\u5927\u5c0f\uff0c\u6240\u4ee5\u8fd9\u6bb5\u4ee3\u7801 <code>algOne<\/code> \u51fd\u6570\u53ef\u80fd\u9700\u8981\u4e00\u6b21\u5185\u5b58\u5206\u914d\u3002<\/p><h2 id=\"\u5185\u5b58\u5206\u914d\u548c\u6027\u80fdallocations-and-performance\">\u5185\u5b58\u5206\u914d\u548c\u6027\u80fd\uff08Allocations and Performance\uff09<\/h2><p>\u6bd4\u8f83\u4e00\u4e0b\u6bcf\u6b21\u4f18\u5316\u8fc7\u7a0b\u4e2d\u7684\u65b0\u80fd\u63d0\u5347\uff1a<\/p><div class=\"highlight\"><pre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"><code class=\"language-go\" data-lang=\"go\"><span style=\"display:flex;\"><span><span style=\"color:#a6e22e\">Before<\/span> <span style=\"color:#a6e22e\">any<\/span> <span style=\"color:#a6e22e\">optimization<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#a6e22e\">BenchmarkAlgorithmOne<\/span><span style=\"color:#f92672\">-<\/span><span style=\"color:#ae81ff\">8<\/span> <span style=\"color:#ae81ff\">2000000<\/span> <span style=\"color:#ae81ff\">2570<\/span> <span style=\"color:#a6e22e\">ns<\/span><span style=\"color:#f92672\">\/<\/span><span style=\"color:#a6e22e\">op<\/span> <span style=\"color:#ae81ff\">117<\/span> <span style=\"color:#a6e22e\">B<\/span><span style=\"color:#f92672\">\/<\/span><span style=\"color:#a6e22e\">op<\/span> <span style=\"color:#ae81ff\">2<\/span> <span style=\"color:#a6e22e\">allocs<\/span><span style=\"color:#f92672\">\/<\/span><span style=\"color:#a6e22e\">op<\/span><\/span><\/span><span style=\"display:flex;\"><span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#a6e22e\">Removing<\/span> <span style=\"color:#a6e22e\">the<\/span> <span style=\"color:#a6e22e\">bytes<\/span>.<span style=\"color:#a6e22e\">Buffer<\/span> <span style=\"color:#a6e22e\">allocation<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#a6e22e\">BenchmarkAlgorithmOne<\/span><span style=\"color:#f92672\">-<\/span><span style=\"color:#ae81ff\">8<\/span> <span style=\"color:#ae81ff\">2000000<\/span> <span style=\"color:#ae81ff\">1814<\/span> <span style=\"color:#a6e22e\">ns<\/span><span style=\"color:#f92672\">\/<\/span><span style=\"color:#a6e22e\">op<\/span> <span style=\"color:#ae81ff\">5<\/span> <span style=\"color:#a6e22e\">B<\/span><span style=\"color:#f92672\">\/<\/span><span style=\"color:#a6e22e\">op<\/span> <span style=\"color:#ae81ff\">1<\/span> <span style=\"color:#a6e22e\">allocs<\/span><span style=\"color:#f92672\">\/<\/span><span style=\"color:#a6e22e\">op<\/span><\/span><\/span><span style=\"display:flex;\"><span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#a6e22e\">Removing<\/span> <span style=\"color:#a6e22e\">the<\/span> <span style=\"color:#a6e22e\">backing<\/span> <span style=\"color:#a6e22e\">array<\/span> <span style=\"color:#a6e22e\">allocation<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#a6e22e\">BenchmarkAlgorithmOne<\/span><span style=\"color:#f92672\">-<\/span><span style=\"color:#ae81ff\">8<\/span> <span style=\"color:#ae81ff\">3000000<\/span> <span style=\"color:#ae81ff\">1720<\/span> <span style=\"color:#a6e22e\">ns<\/span><span style=\"color:#f92672\">\/<\/span><span style=\"color:#a6e22e\">op<\/span> <span style=\"color:#ae81ff\">0<\/span> <span style=\"color:#a6e22e\">B<\/span><span style=\"color:#f92672\">\/<\/span><span style=\"color:#a6e22e\">op<\/span> <span style=\"color:#ae81ff\">0<\/span> <span style=\"color:#a6e22e\">allocs<\/span><span style=\"color:#f92672\">\/<\/span><span style=\"color:#a6e22e\">op<\/span><\/span><\/span><\/code><\/pre><\/div><p>\u4f18\u5316\u6389 <code>bytes.Buffer<\/code> \u53d8\u91cf\u7684\u5185\u5b58\u5206\u914d\u4e4b\u540e\uff0c\u63d0\u5347\u4e86\u5927\u7ea6 29% \u7684\u6027\u80fd\uff0c\u6240\u6709\u5185\u5b58\u5206\u914d\u90fd\u53c8\u5212\u6389\u4e4b\u540e\uff0c\u63d0\u5347\u4e86\u5927\u7ea6 33% \u7684\u6027\u80fd\u3002\u7531\u6b64\u53ef\u89c1\uff0c\u5185\u5b58\u5206\u914d\u662f\u5f71\u54cd\u5e94\u7528\u7a0b\u5e8f\u6027\u80fd\u7684\u56e0\u7d20\u4e4b\u4e00\u3002<\/p><h2 id=\"\u7ed3\u8bba\">\u7ed3\u8bba<\/h2><p>golang\u6709\u4e00\u4e9b\u5f88\u65b9\u4fbf\u7684\u5de5\u5177\u6765\u5206\u6790\u5185\u5b58\uff0c\u57fa\u4e8e\u8fd9\u4e9b\u5de5\u5177\uff0c\u53ef\u4ee5\u91cd\u6784\u4ee3\u7801\u4f7f\u5f97\u53d8\u91cf\u53ea\u5206\u914d\u5728\u6808\u7a7a\u95f4\u4e0a\uff0c\u800c\u4e0d\u9700\u8981\u91cd\u65b0\u5206\u914d\u5230\u5806\u4e0a\u3002\u5199\u4ee3\u7801\u65f6\u4e0d\u8981\u628a\u6027\u80fd\u4f5c\u4e3a\u7b2c\u4e00\u4f18\u5148\u7ea7\uff0c\u56e0\u4e3a\u4f60\u5e76\u4e0d\u60f3\u5728\u4ee3\u7801\u5e8f\u65f6\u4e00\u76f4\u731c\u6d4b\u4ee3\u7801\u7684\u6027\u80fd\uff0c\u5199\u6b63\u786e\u7684\u4ee3\u7801\u624d\u662f\u7b2c\u4e00\u4f18\u5148\u7ea7\u3002\u6211\u4eec\u9996\u5148\u8981\u5173\u6ce8\u7684\u662f\u5b8c\u6574\u6027\u3001\u53ef\u8bfb\u6027\u548c\u7b80\u5355\u6027\u3002\u6709\u4e86\u53ef\u4ee5\u8fd0\u884c\u7684\u7a0b\u5e8f\uff0c\u518d\u6765\u786e\u5b9a\u7a0b\u5e8f\u6027\u80fd\u662f\u5426\u6ee1\u8db3\u8981\u6c42\u3002\u5047\u5982\u7a0b\u5e8f\u8fd8\u4e0d\u591f\u5feb\uff0c\u53ef\u4ee5\u4f7f\u7528golang\u63d0\u4f9b\u7684\u5de5\u5177\u6765\u67e5\u627e\u548c\u89e3\u51b3\u6027\u80fd\u95ee\u9898\u3002<\/p><h2 id=\"\u53c2\u8003\u8d44\u6599\">\u53c2\u8003\u8d44\u6599<\/h2><ol><li><a href=\"https:\/\/www.ardanlabs.com\/blog\/2017\/06\/language-mechanics-on-memory-profiling.html\">https:\/\/www.ardanlabs.com\/blog\/2017\/06\/language-mechanics-on-memory-profiling.html<\/a><\/li><\/ol>"},{"title":"golang\u8bed\u8a00\u673a\u5236\u4e4b\u9003\u9038\u5206\u6790","link":"https:\/\/sunpe.github.io\/posts\/2020-07-31-golang-escape\/","pubDate":"Fri, 31 Jul 2020 22:00:00 +0800","guid":"https:\/\/sunpe.github.io\/posts\/2020-07-31-golang-escape\/","description":"<p>Golang \u4e2d\u9003\u9038\u662f\u53ea\u6808\u7a7a\u95f4\u7684\u53d8\u91cf\u9003\u9038\u5230\u4e86\u5806\u7a7a\u95f4\uff0c\u9003\u9038\u5206\u6790\u662f\u7f16\u8bd1\u5668\u901a\u8fc7\u9759\u6001\u4ee3\u7801\u5206\u6790\u51b3\u5b9a\u7a0b\u5e8f\u4e2d\u53d8\u91cf\u5b58\u50a8\u4f4d\u7f6e\u7684\u8fc7\u7a0b\u3002\u4ee3\u7801\u4e2d\u6ca1\u6709\u4efb\u4f55\u7684\u5173\u952e\u8bcd\u6216\u8005\u51fd\u6570\u53ef\u4ee5\u51b3\u5b9a\u53d8\u91cf\u653e\u7f6e\u5728\u6808\u7a7a\u95f4\u8fd8\u662f\u5806\u7a7a\u95f4\uff0c\u53ea\u80fd\u8ba9\u7f16\u8bd1\u5668\u901a\u8fc7\u4ee3\u7801\u6765\u51b3\u5b9a\u53d8\u91cf\u503c\u7684\u5b58\u50a8\u4f4d\u7f6e\u3002<\/p><h2 id=\"\u5806heaps\">\u5806\uff08Heaps\uff09<\/h2><p>\u5806\u662f\u5185\u5b58\u4e2d\u9664\u4e86\u6808\u4e4b\u5916\u7528\u6765\u5b58\u50a8\u53d8\u91cf\u503c\u7684\u533a\u57df\uff0c\u5806\u4e0d\u80fd\u50cf\u6808\u4e00\u6837\u81ea\u5df1\u91ca\u653e\u7a7a\u95f4\uff0c\u6240\u4ee5\u4f7f\u7528\u8fd9\u5757\u533a\u57df\u4f1a\u6bd4\u4f7f\u7528\u6808\u6709\u66f4\u5927\u7684\u5f00\u9500\u3002\u5176\u4e2d\u5f00\u9500\u4e3b\u8981\u7528\u6765\u8fdb\u884c\u5783\u573e\u56de\u6536\uff08GC\uff09\uff0c\u5f53\u8fdb\u884c\u5783\u573e\u56de\u6536\u65f6\uff0c\u4f1a\u6d88\u8017 25% \u7684 CPU\uff0c\u5e76\u4e14\u5f88\u53ef\u80fd\u4f1a\u9020\u6210\u5fae\u79d2\u7ea7\u7684\u300cstop the world\u300d\u5ef6\u8fdf\u3002\u800c GC \u7684\u597d\u5904\u662f\u4e0d\u9700\u8981\u518d\u624b\u52a8\u6765\u5206\u914d\u548c\u91ca\u653e\u5185\u5b58\u3002Golang \u4e2d\u4e00\u90e8\u5206\u53d8\u91cf\u503c\u5206\u914d\u5728\u5806\u4e0a\uff0c\u800c\u4e0d\u5728\u4f7f\u7528\u7684\u53d8\u91cf\u503c\u90fd\u9700\u8981\u6e05\u7406\u6389\uff0c\u5806\u4e0a\u7684\u6570\u636e\u8fc7\u591a\u4f1a\u7ed9 GC \u9020\u6210\u538b\u529b\u3002<\/p><h2 id=\"\u5171\u4eab\u6808sharing-stacks\">\u5171\u4eab\u6808\uff08Sharing Stacks\uff09<\/h2><p>Golang \u4e0d\u5141\u8bb8 goroutine \u8bbf\u95ee\u5176\u4ed6 goroutine \u7684\u6808\u7a7a\u95f4\uff0c\u8fd9\u662f\u56e0\u4e3a goroutine \u7684\u6808\u7a7a\u95f4\u589e\u957f\u6216\u6536\u7f29\u65f6\uff0c\u6808\u7a7a\u95f4\u4f1a\u586b\u5145\u8fdb\u65b0\u7684\u5185\u5bb9\u3002<\/p><p>\u7a0b\u5e8f1\u5c55\u793a\u4e86\u6808\u88ab\u66ff\u6362\u597d\u51e0\u6b21\u7684\u4f8b\u5b50\u3002<\/p><div class=\"highlight\"><pre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"><code class=\"language-go\" data-lang=\"go\"><span style=\"display:flex;\"><span><span style=\"color:#75715e\">\/\/ \u7a0b\u5e8f1<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\">\/\/ All material is licensed under the Apache License Version 2.0, January 2004<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\">\/\/ http:\/\/www.apache.org\/licenses\/LICENSE-2.0<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\">\/\/ Sample program to show how stacks grow\/change.<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span><span style=\"color:#f92672\">package<\/span> <span style=\"color:#a6e22e\">main<\/span><\/span><\/span><span style=\"display:flex;\"><span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\">\/\/ Number of elements to grow each stack frame.<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\">\/\/ Run with 10 and then with 1024<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span><span style=\"color:#66d9ef\">const<\/span> <span style=\"color:#a6e22e\">size<\/span> = <span style=\"color:#ae81ff\">1024<\/span><\/span><\/span><span style=\"display:flex;\"><span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\">\/\/ main is the entry point for the application.<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span><span style=\"color:#66d9ef\">func<\/span> <span style=\"color:#a6e22e\">main<\/span>() {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">s<\/span> <span style=\"color:#f92672\">:=<\/span> <span style=\"color:#e6db74\">&#34;HELLO&#34;<\/span><\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">stackCopy<\/span>(<span style=\"color:#f92672\">&amp;<\/span><span style=\"color:#a6e22e\">s<\/span>, <span style=\"color:#ae81ff\">0<\/span>, [<span style=\"color:#a6e22e\">size<\/span>]<span style=\"color:#66d9ef\">int<\/span>{})<\/span><\/span><span style=\"display:flex;\"><span>}<\/span><\/span><span style=\"display:flex;\"><span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\">\/\/ stackCopy recursively runs increasing the size<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\">\/\/ of the stack.<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span><span style=\"color:#66d9ef\">func<\/span> <span style=\"color:#a6e22e\">stackCopy<\/span>(<span style=\"color:#a6e22e\">s<\/span> <span style=\"color:#f92672\">*<\/span><span style=\"color:#66d9ef\">string<\/span>, <span style=\"color:#a6e22e\">c<\/span> <span style=\"color:#66d9ef\">int<\/span>, <span style=\"color:#a6e22e\">a<\/span> [<span style=\"color:#a6e22e\">size<\/span>]<span style=\"color:#66d9ef\">int<\/span>) {<\/span><\/span><span style=\"display:flex;\"><span> println(<span style=\"color:#a6e22e\">c<\/span>, <span style=\"color:#a6e22e\">s<\/span>, <span style=\"color:#f92672\">*<\/span><span style=\"color:#a6e22e\">s<\/span>)<\/span><\/span><span style=\"display:flex;\"><span><\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">c<\/span><span style=\"color:#f92672\">++<\/span><\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">if<\/span> <span style=\"color:#a6e22e\">c<\/span> <span style=\"color:#f92672\">==<\/span> <span style=\"color:#ae81ff\">10<\/span> {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">return<\/span><\/span><\/span><span style=\"display:flex;\"><span> }<\/span><\/span><span style=\"display:flex;\"><span><\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">stackCopy<\/span>(<span style=\"color:#a6e22e\">s<\/span>, <span style=\"color:#a6e22e\">c<\/span>, <span style=\"color:#a6e22e\">a<\/span>)<\/span><\/span><span style=\"display:flex;\"><span>}<\/span><\/span><\/code><\/pre><\/div><p>\u8f93\u51fa\u7ed3\u679c\u7684\u7b2c 2 \u548c\u7b2c 6 \u884c\uff0c\u4f1a\u770b\u5230 <code>main<\/code> \u51fd\u6570\u6808\u7684 <code>s<\/code> \u53d8\u91cf\u5730\u5740\u503c\u6539\u53d8\u4e86\u4e24\u6b21\u3002<\/p><div class=\"highlight\"><pre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"><code class=\"language-go\" data-lang=\"go\"><span style=\"display:flex;\"><span><span style=\"color:#ae81ff\">0<\/span> <span style=\"color:#ae81ff\">0xc00006ff68<\/span> <span style=\"color:#a6e22e\">HELLO<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#ae81ff\">1<\/span> <span style=\"color:#ae81ff\">0xc00006ff68<\/span> <span style=\"color:#a6e22e\">HELLO<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#ae81ff\">2<\/span> <span style=\"color:#ae81ff\">0xc00007ff68<\/span> <span style=\"color:#a6e22e\">HELLO<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#ae81ff\">3<\/span> <span style=\"color:#ae81ff\">0xc00007ff68<\/span> <span style=\"color:#a6e22e\">HELLO<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#ae81ff\">4<\/span> <span style=\"color:#ae81ff\">0xc00007ff68<\/span> <span style=\"color:#a6e22e\">HELLO<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#ae81ff\">5<\/span> <span style=\"color:#ae81ff\">0xc00007ff68<\/span> <span style=\"color:#a6e22e\">HELLO<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#ae81ff\">6<\/span> <span style=\"color:#ae81ff\">0xc00011ff68<\/span> <span style=\"color:#a6e22e\">HELLO<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#ae81ff\">7<\/span> <span style=\"color:#ae81ff\">0xc00011ff68<\/span> <span style=\"color:#a6e22e\">HELLO<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#ae81ff\">8<\/span> <span style=\"color:#ae81ff\">0xc00011ff68<\/span> <span style=\"color:#a6e22e\">HELLO<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#ae81ff\">9<\/span> <span style=\"color:#ae81ff\">0xc00011ff68<\/span> <span style=\"color:#a6e22e\">HELLO<\/span><\/span><\/span><\/code><\/pre><\/div><h2 id=\"\u9003\u9038\u673a\u5236escape-mechanics\">\u9003\u9038\u673a\u5236\uff08Escape Mechanics\uff09<\/h2><p>\u5982\u679c\u53d8\u91cf\u503c\u9700\u8981\u5728\u51fd\u6570\u6808\u5e27\u5916\u8bbf\u95ee\uff0c\u90fd\u4f1a\u5c06\u8be5\u53d8\u91cf\u503c\u91cd\u65b0\u5206\u914d\u5230\u5806\u4e0a\uff0c\u8fd9\u5c31\u662f\u9003\u9038\u5206\u6790\u7b97\u6cd5\u8981\u505a\u7684\u4e8b\u60c5\uff0c\u786e\u4fdd\u5bf9\u4efb\u4f55\u53d8\u91cf\u503c\u7684\u8bbf\u95ee\u59cb\u7ec8\u662f\u51c6\u786e\u3001\u4e00\u81f4\u548c\u9ad8\u6548\u7684\u3002<\/p><p>\u8ba9\u6211\u4eec\u901a\u8fc7\u7a0b\u5e8f 2 \u6765\u4e86\u89e3\u9003\u9038\u5206\u6790\u3002<\/p><div class=\"highlight\"><pre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"><code class=\"language-go\" data-lang=\"go\"><span style=\"display:flex;\"><span><span style=\"color:#75715e\">\/\/ \u7a0b\u5e8f2<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span><span style=\"color:#f92672\">package<\/span> <span style=\"color:#a6e22e\">main<\/span><\/span><\/span><span style=\"display:flex;\"><span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#66d9ef\">type<\/span> <span style=\"color:#a6e22e\">user<\/span> <span style=\"color:#66d9ef\">struct<\/span> {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">name<\/span> <span style=\"color:#66d9ef\">string<\/span><\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">email<\/span> <span style=\"color:#66d9ef\">string<\/span><\/span><\/span><span style=\"display:flex;\"><span>}<\/span><\/span><span style=\"display:flex;\"><span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#66d9ef\">func<\/span> <span style=\"color:#a6e22e\">main<\/span>() {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">u1<\/span> <span style=\"color:#f92672\">:=<\/span> <span style=\"color:#a6e22e\">createUserV1<\/span>()<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">u2<\/span> <span style=\"color:#f92672\">:=<\/span> <span style=\"color:#a6e22e\">createUserV2<\/span>()<\/span><\/span><span style=\"display:flex;\"><span><\/span><\/span><span style=\"display:flex;\"><span> println(<span style=\"color:#e6db74\">&#34;u1&#34;<\/span>, <span style=\"color:#f92672\">&amp;<\/span><span style=\"color:#a6e22e\">u1<\/span>, <span style=\"color:#e6db74\">&#34;u2&#34;<\/span>, <span style=\"color:#f92672\">&amp;<\/span><span style=\"color:#a6e22e\">u2<\/span>)<\/span><\/span><span style=\"display:flex;\"><span>}<\/span><\/span><span style=\"display:flex;\"><span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\">\/\/go:noinline<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span><span style=\"color:#66d9ef\">func<\/span> <span style=\"color:#a6e22e\">createUserV1<\/span>() <span style=\"color:#a6e22e\">user<\/span> {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">u<\/span> <span style=\"color:#f92672\">:=<\/span> <span style=\"color:#a6e22e\">user<\/span>{<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">name<\/span>: <span style=\"color:#e6db74\">&#34;Bill&#34;<\/span>,<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">email<\/span>: <span style=\"color:#e6db74\">&#34;bill@ardanlabs.com&#34;<\/span>,<\/span><\/span><span style=\"display:flex;\"><span> }<\/span><\/span><span style=\"display:flex;\"><span><\/span><\/span><span style=\"display:flex;\"><span> println(<span style=\"color:#e6db74\">&#34;V1&#34;<\/span>, <span style=\"color:#f92672\">&amp;<\/span><span style=\"color:#a6e22e\">u<\/span>)<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">return<\/span> <span style=\"color:#a6e22e\">u<\/span><\/span><\/span><span style=\"display:flex;\"><span>}<\/span><\/span><span style=\"display:flex;\"><span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\">\/\/go:noinline<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span><span style=\"color:#66d9ef\">func<\/span> <span style=\"color:#a6e22e\">createUserV2<\/span>() <span style=\"color:#f92672\">*<\/span><span style=\"color:#a6e22e\">user<\/span> {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">u<\/span> <span style=\"color:#f92672\">:=<\/span> <span style=\"color:#a6e22e\">user<\/span>{<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">name<\/span>: <span style=\"color:#e6db74\">&#34;Bill&#34;<\/span>,<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">email<\/span>: <span style=\"color:#e6db74\">&#34;bill@ardanlabs.com&#34;<\/span>,<\/span><\/span><span style=\"display:flex;\"><span> }<\/span><\/span><span style=\"display:flex;\"><span><\/span><\/span><span style=\"display:flex;\"><span> println(<span style=\"color:#e6db74\">&#34;V2&#34;<\/span>, <span style=\"color:#f92672\">&amp;<\/span><span style=\"color:#a6e22e\">u<\/span>)<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">return<\/span> <span style=\"color:#f92672\">&amp;<\/span><span style=\"color:#a6e22e\">u<\/span><\/span><\/span><span style=\"display:flex;\"><span>}<\/span><\/span><\/code><\/pre><\/div><p>\u7a0b\u5e8f 2 \u4e2d\u4f7f\u7528\u4e86 <code>[\/\/go:noinline](\/\/go:noinline)<\/code> \u6307\u4ee4\u6765\u963b\u6b62\u7f16\u8bd1\u5668\u4f7f\u7528\u5185\u8054\u4ee3\u7801\u4f18\u5316\uff0c\u5185\u8054\u4ee3\u7801\u4f18\u5316\u4f1a\u5c06\u51fd\u6570\u8c03\u7528\u53d8\u6210\u5185\u8054\u4ee3\u7801\u3002\u7a0b\u5e8f 2 \u4e2d\u6709\u4e24\u4e2a\u7248\u672c\u7684 <code>createUserXX<\/code> \u51fd\u6570\uff0c<code>createUserV1()<\/code> \u8fd4\u56de\u7684\u662f <code>user<\/code> \u53d8\u91cf\u7684\u526f\u672c\u3002<\/p><div class=\"highlight\"><pre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"><code class=\"language-go\" data-lang=\"go\"><span style=\"display:flex;\"><span><span style=\"color:#66d9ef\">func<\/span> <span style=\"color:#a6e22e\">createUserV1<\/span>() <span style=\"color:#a6e22e\">user<\/span> {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">u<\/span> <span style=\"color:#f92672\">:=<\/span> <span style=\"color:#a6e22e\">user<\/span>{<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">name<\/span>: <span style=\"color:#e6db74\">&#34;Bill&#34;<\/span>,<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">email<\/span>: <span style=\"color:#e6db74\">&#34;bill@ardanlabs.com&#34;<\/span>,<\/span><\/span><span style=\"display:flex;\"><span> }<\/span><\/span><span style=\"display:flex;\"><span><\/span><\/span><span style=\"display:flex;\"><span> println(<span style=\"color:#e6db74\">&#34;V1&#34;<\/span>, <span style=\"color:#f92672\">&amp;<\/span><span style=\"color:#a6e22e\">u<\/span>)<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">return<\/span> <span style=\"color:#a6e22e\">u<\/span><\/span><\/span><span style=\"display:flex;\"><span>}<\/span><\/span><\/code><\/pre><\/div><p><code>createUserV1()<\/code> \u51fd\u6570\u8fd4\u56de\u4e4b\u540e\uff0c\u6808\u7a7a\u95f4\u5e94\u8be5\u662f\u56fe 1 \u8fd9\u6837\u7684\uff1a<\/p><p><img src=\"https:\/\/sunpe.github.io\/images\/golang_escape\/1.png\" alt=\"\">\u56fe1<\/p><p><code>createUserV2()<\/code> \u51fd\u6570\u8fd4\u56de\u7684\u662f user \u53d8\u91cf\u7684\u6307\u9488\uff0c\u6240\u4ee5\u8c03\u7528\u65b9\u6536\u5230\u7684\u662f user \u53d8\u91cf\u5730\u5740\u7684\u526f\u672c\uff1a<\/p><div class=\"highlight\"><pre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"><code class=\"language-go\" data-lang=\"go\"><span style=\"display:flex;\"><span><span style=\"color:#66d9ef\">func<\/span> <span style=\"color:#a6e22e\">createUserV2<\/span>() <span style=\"color:#f92672\">*<\/span><span style=\"color:#a6e22e\">user<\/span> {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">u<\/span> <span style=\"color:#f92672\">:=<\/span> <span style=\"color:#a6e22e\">user<\/span>{<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">name<\/span>: <span style=\"color:#e6db74\">&#34;Bill&#34;<\/span>,<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">email<\/span>: <span style=\"color:#e6db74\">&#34;bill@ardanlabs.com&#34;<\/span>,<\/span><\/span><span style=\"display:flex;\"><span> }<\/span><\/span><span style=\"display:flex;\"><span><\/span><\/span><span style=\"display:flex;\"><span> println(<span style=\"color:#e6db74\">&#34;V2&#34;<\/span>, <span style=\"color:#f92672\">&amp;<\/span><span style=\"color:#a6e22e\">u<\/span>)<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">return<\/span> <span style=\"color:#f92672\">&amp;<\/span><span style=\"color:#a6e22e\">u<\/span><\/span><\/span><span style=\"display:flex;\"><span>}<\/span><\/span><\/code><\/pre><\/div><p>\u6309\u300a<a href=\"https:\/\/sunpe.github.io\/posts\/golang-stack-and-pointer\/\">Golang \u8bed\u8a00\u673a\u5236\u4e4b\u6808\u4e0e\u6307\u9488<\/a>\u300b\u4e00\u6587\uff0c<code>createUserV2()<\/code> \u51fd\u6570\u8fd4\u56de\u540e\u6808\u7a7a\u95f4\u5e94\u8be5\u5982\u56fe 2 \u6240\u793a\uff1a<\/p><p><img src=\"https:\/\/sunpe.github.io\/images\/golang_escape\/2.png\" alt=\"\">\u56fe2<\/p><p>\u4f46\u662f\u56fe 2 \u6240\u793a\u7684\u6808\u7a7a\u95f4\u6709\u4e00\u4e2a\u4e25\u91cd\u7684\u95ee\u9898\uff0c<code>main<\/code> \u51fd\u6570\u6808\u5e27 <code>u2<\/code> \u6307\u5411\u4e86\u65e0\u6548\u7684\u5185\u5b58\u7a7a\u95f4\uff0c\u8fd9\u6bb5\u5730\u5740\u7a7a\u95f4\u5728\u4e0b\u4e00\u6b21\u51fd\u6570\u8c03\u7528\u65f6\u53ef\u80fd\u4f1a\u88ab\u91cd\u65b0\u521d\u59cb\u5316\u3002 \u8fd9\u79cd\u60c5\u51b5\u4e0b\uff0c\u7f16\u8bd1\u5668\u8ba4\u4e3a\u5728 <code>createUserV2<\/code> \u51fd\u6570\u6808\u5e27\u4e2d\u6784\u9020 <code>user<\/code> \u662f\u4e0d\u5b89\u5168\u7684\uff0c\u56e0\u6b64\u4f1a\u6539\u4e3a\u5728\u5806\u4e2d\u6784\u9020 <code>user<\/code>\uff0c\u5728\u7a0b\u5e8f 2 \u7684\u6267\u884c\u5230\u7b2c 28 \u884c\u5f00\u59cb\u6784\u9020 user \u65f6\u5c31\u4f1a\u5728\u5806\u4e0a\u6784\u9020\u3002<\/p><p><a href=\"https:\/\/sunpe.github.io\/posts\/golang-stack-and-pointer\/\">Golang \u8bed\u8a00\u673a\u5236\u4e4b\u6808\u4e0e\u6307\u9488<\/a>\u4e00\u6587\u6307\u51fa\uff0c\u51fd\u6570\u53ea\u80fd\u76f4\u63a5\u8bbf\u95ee\u81ea\u5df1\u6808\u5e27\u5185\u7684\u5185\u5b58\u7a7a\u95f4\uff0c\u6216\u901a\u8fc7\u6307\u9488\u95f4\u63a5\u8bbf\u95ee\u6808\u5e27\u5916\u7684\u5185\u5b58\u7a7a\u95f4\uff0c\u6240\u4ee5\u8bbf\u95ee\u9003\u9038\u5230\u5806\u4e0a\u7684\u53d8\u91cf\u503c\u4e5f\u9700\u8981\u901a\u8fc7\u6307\u9488\u6765\u95f4\u63a5\u8bbf\u95ee\u3002\u6240\u4ee5\u6267\u884c\u5b8c <code>createUserV2<\/code> \u51fd\u6570\u540e\u6808\u7a7a\u95f4\u5e94\u8be5\u5f00\u8d77\u6765\u5982\u56fe 3:<\/p><p><img src=\"https:\/\/sunpe.github.io\/images\/golang_escape\/3.png\" alt=\"\">\u56fe3<\/p><p><code>createUserV2<\/code> \u51fd\u6570\u6808\u5e27\u7684\u53d8\u91cf <code>u<\/code> \u7684\u503c\u5b58\u50a8\u5728\u5806\u4e0a\u800c\u4e0d\u662f\u5728\u6808\u4e0a\uff0c\u6240\u4ee5\u8bbf\u95ee\u53d8\u91cf <code>u<\/code> \u7684\u503c\u4e5f\u9700\u8981\u901a\u8fc7\u6307\u9488\u6765\u95f4\u63a5\u8bbf\u95ee\u3002<\/p><h2 id=\"\u53ef\u8bfb\u6027readability\">\u53ef\u8bfb\u6027\uff08Readability\uff09<\/h2><p><code>createUserV2<\/code> \u51fd\u6570\u5148\u6784\u5efa\u4e86 <code>user<\/code> \u53d8\u91cf\uff0c\u7136\u540e\u518d\u901a\u8fc7 <code>&amp;<\/code> \u64cd\u4f5c\u83b7\u53d6\u53d8\u91cf\u5730\u5740\u5e76\u8fd4\u56de\u3002\u5982\u679c\u76f4\u63a5\u6784\u9020\u6210\u6307\u9488\uff0c\u5982\u7a0b\u5e8f 3 \u6240\u793a\u3002<\/p><div class=\"highlight\"><pre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"><code class=\"language-go\" data-lang=\"go\"><span style=\"display:flex;\"><span><span style=\"color:#75715e\">\/\/ \u7a0b\u5e8f 3<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span><span style=\"color:#66d9ef\">func<\/span> <span style=\"color:#a6e22e\">createUserV2<\/span>() <span style=\"color:#f92672\">*<\/span><span style=\"color:#a6e22e\">user<\/span> {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">u<\/span> <span style=\"color:#f92672\">:=<\/span> <span style=\"color:#f92672\">&amp;<\/span><span style=\"color:#a6e22e\">user<\/span>{<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">name<\/span>: <span style=\"color:#e6db74\">&#34;Bill&#34;<\/span>,<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">email<\/span>: <span style=\"color:#e6db74\">&#34;bill@ardanlabs.com&#34;<\/span>,<\/span><\/span><span style=\"display:flex;\"><span> }<\/span><\/span><span style=\"display:flex;\"><span><\/span><\/span><span style=\"display:flex;\"><span> println(<span style=\"color:#e6db74\">&#34;V2&#34;<\/span>, <span style=\"color:#a6e22e\">u<\/span>)<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">return<\/span> <span style=\"color:#a6e22e\">u<\/span><\/span><\/span><span style=\"display:flex;\"><span>}<\/span><\/span><\/code><\/pre><\/div><p>\u5982\u679c\u6211\u4eec\u53ea\u5173\u6ce8 <code>return<\/code>\uff0c\u7a0b\u5e8f 3 <code>return u<\/code> \u544a\u8bc9\u6211\u4eec\u8981\u8fd4\u56de\u7ed9\u8c03\u7528\u8005\u7684\u662f <code>u<\/code> \u7684\u526f\u672c\uff0c\u7a0b\u5e8f 2 <code>return &amp;u<\/code> \u544a\u8bc9\u6211\u4eec\u8fd4\u56de\u7ed9\u8c03\u7528\u8005\u7684\u662f <code>u<\/code> \u7684\u5730\u5740\u503c\uff0c\u5e76\u4e14\u53d8\u91cf <code>u<\/code> \u5df2\u7ecf\u9003\u9038\u5230\u5806\u4e0a\u3002\u6240\u4ee5\uff0c\u8bfb\u4ee3\u7801\u65f6\u8981\u8bb0\u4f4f\uff0c\u6307\u9488\u662f\u4e3a\u4e86\u5171\u4eab\u53d8\u91cf\uff0c<code>&amp;<\/code> \u64cd\u4f5c\u7b26\u5bf9\u5e94\u7684\u5355\u8bcd\u662f\u300csharing\u300d\uff0c\u8fd9\u6837\u5199\u6709\u52a9\u4e8e\u63d0\u9ad8\u4ee3\u7801\u7684\u53ef\u8bfb\u6027\u3002<\/p><p>\u6765\u770b\u4e00\u4e0b\u7a0b\u5e8f 4 \u7684\u4f8b\u5b50\u3002<\/p><div class=\"highlight\"><pre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"><code class=\"language-go\" data-lang=\"go\"><span style=\"display:flex;\"><span><span style=\"color:#75715e\">\/\/ \u7a0b\u5e8f 4<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span><span style=\"color:#66d9ef\">var<\/span> <span style=\"color:#a6e22e\">u<\/span> <span style=\"color:#f92672\">*<\/span><span style=\"color:#a6e22e\">user<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#a6e22e\">err<\/span> <span style=\"color:#f92672\">:=<\/span> <span style=\"color:#a6e22e\">json<\/span>.<span style=\"color:#a6e22e\">Unmarshal<\/span>([]byte(<span style=\"color:#a6e22e\">r<\/span>), <span style=\"color:#f92672\">&amp;<\/span><span style=\"color:#a6e22e\">u<\/span>)<\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#66d9ef\">return<\/span> <span style=\"color:#a6e22e\">u<\/span>, <span style=\"color:#a6e22e\">err<\/span><\/span><\/span><\/code><\/pre><\/div><p>\u7b2c\u4e8c\u884c\u7684 <code>json.Unmarshal<\/code> \u7b2c\u4e8c\u4e2a\u53c2\u6570\u5fc5\u987b\u662f\u6307\u9488\u7c7b\u578b\uff0c\u6240\u4ee5\u9700\u8981\u4f20\u9012 <code>&amp;u<\/code> \u4f5c\u4e3a\u53c2\u6570\u3002\u8fd9\u6bb5\u4ee3\u7801\u7b2c\u4e00\u884c\u521b\u5efa\u4e86 user \u7684\u6307\u9488\u7c7b\u578b\u5e76\u521d\u59cb\u5316\u96f6\u503c\uff0c\u7b2c\u4e8c\u884c\u901a\u8fc7 <code>u<\/code> \u7684\u5730\u5740\u8c03\u7528 <code>json.Unmarshal<\/code>\uff0c\u7b2c\u4e09\u884c\u548c\u8c03\u7528\u8005\u5171\u4eab <code>u<\/code> \u7684\u526f\u672c\u3002<\/p><p>\u8fd9\u6bb5\u4ee3\u7801\u5e76\u4e0d\u76f4\u89c2\uff0c\u53ef\u4ee5\u7a0d\u4f5c\u4fee\u6539\uff0c\u5f97\u5230\u7a0b\u5e8f5.<\/p><div class=\"highlight\"><pre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"><code class=\"language-go\" data-lang=\"go\"><span style=\"display:flex;\"><span><span style=\"color:#75715e\">\/\/ \u7a0b\u5e8f 5<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span><span style=\"color:#66d9ef\">var<\/span> <span style=\"color:#a6e22e\">u<\/span> <span style=\"color:#a6e22e\">user<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#a6e22e\">err<\/span> <span style=\"color:#f92672\">:=<\/span> <span style=\"color:#a6e22e\">json<\/span>.<span style=\"color:#a6e22e\">Unmarshal<\/span>([]byte(<span style=\"color:#a6e22e\">r<\/span>), <span style=\"color:#f92672\">&amp;<\/span><span style=\"color:#a6e22e\">u<\/span>)<\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#66d9ef\">return<\/span> <span style=\"color:#f92672\">&amp;<\/span><span style=\"color:#a6e22e\">u<\/span>, <span style=\"color:#a6e22e\">err<\/span><\/span><\/span><\/code><\/pre><\/div><p>\u7a0b\u5e8f 5 \u7684\u7b2c\u4e00\u884c\u521b\u5efa\u4e86 user \u53d8\u91cf\u5e76\u521d\u59cb\u5316\u96f6\u503c\uff0c\u7b2c\u4e8c\u884c\u901a\u8fc7 <code>u<\/code> \u7684\u5730\u5740\u8c03\u7528 <code>json.Unmarshal<\/code>\uff0c\u7b2c\u4e09\u884c\u548c\u8c03\u7528\u8005\u5171\u4eab <code>u<\/code>\uff0c\u6bd4\u7a0b\u5e8f 4 \u66f4\u76f4\u89c2\uff0c\u8fd4\u56de <code>&amp;u<\/code> \u8bf4\u660e <code>u<\/code> \u4f1a\u9003\u9038\u5230\u5806\u4e0a\u3002<\/p><p>\u5982\u679c\u9700\u8981\u548c\u8c03\u7528\u8005\u5171\u4eab\u53d8\u91cf\u503c\u65f6\uff0c\u5728\u6784\u9020\u503c\u7684\u65f6\u5019\u4f7f\u7528\u503c\u8bed\u4e49\uff0c\u5229\u7528 <code>&amp;<\/code> \u64cd\u4f5c\u7b26\u7684\u53ef\u8bfb\u6027\u6765\u660e\u786e\u503c\u662f\u88ab\u5171\u4eab\u7684\u3002<\/p><h2 id=\"\u7f16\u8bd1\u5668\u65e5\u5fd7compiler-reporting\">\u7f16\u8bd1\u5668\u65e5\u5fd7\uff08Compiler Reporting\uff09<\/h2><p>\u5728\u6784\u5efa\u65f6\uff0c\u53ef\u4ee5\u901a\u8fc7\u7f16\u8bd1\u5668\u65e5\u5fd7\uff08Compiler Reporting\uff09\u6765\u67e5\u770b\u7f16\u8bd1\u5668\u7684\u9003\u9038\u5206\u6790\uff0c\u5728 <code>go build<\/code> \u6307\u4ee4\u540e\u6dfb\u52a0 <code>-gcflags<\/code> \u6307\u4ee4\u548c <code>-m<\/code> \u53c2\u6570\uff0c\u5c31\u53ef\u4ee5\u770b\u5230\u7f16\u8bd1\u5668\u65e5\u5fd7\uff1a<\/p><div class=\"highlight\"><pre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"><code class=\"language-go\" data-lang=\"go\"><span style=\"display:flex;\"><span><span style=\"color:#960050;background-color:#1e0010\">$<\/span> <span style=\"color:#66d9ef\">go<\/span> <span style=\"color:#a6e22e\">build<\/span> <span style=\"color:#f92672\">-<\/span><span style=\"color:#a6e22e\">gcflags<\/span> <span style=\"color:#e6db74\">&#34;-m -m&#34;<\/span><\/span><\/span><span style=\"display:flex;\"><span>.<span style=\"color:#f92672\">\/<\/span><span style=\"color:#a6e22e\">main<\/span>.<span style=\"color:#66d9ef\">go<\/span>:<span style=\"color:#ae81ff\">16<\/span>: <span style=\"color:#a6e22e\">cannot<\/span> <span style=\"color:#a6e22e\">inline<\/span> <span style=\"color:#a6e22e\">createUserV1<\/span>: <span style=\"color:#a6e22e\">marked<\/span> <span style=\"color:#66d9ef\">go<\/span>:<span style=\"color:#a6e22e\">noinline<\/span><\/span><\/span><span style=\"display:flex;\"><span>.<span style=\"color:#f92672\">\/<\/span><span style=\"color:#a6e22e\">main<\/span>.<span style=\"color:#66d9ef\">go<\/span>:<span style=\"color:#ae81ff\">27<\/span>: <span style=\"color:#a6e22e\">cannot<\/span> <span style=\"color:#a6e22e\">inline<\/span> <span style=\"color:#a6e22e\">createUserV2<\/span>: <span style=\"color:#a6e22e\">marked<\/span> <span style=\"color:#66d9ef\">go<\/span>:<span style=\"color:#a6e22e\">noinline<\/span><\/span><\/span><span style=\"display:flex;\"><span>.<span style=\"color:#f92672\">\/<\/span><span style=\"color:#a6e22e\">main<\/span>.<span style=\"color:#66d9ef\">go<\/span>:<span style=\"color:#ae81ff\">8<\/span>: <span style=\"color:#a6e22e\">cannot<\/span> <span style=\"color:#a6e22e\">inline<\/span> <span style=\"color:#a6e22e\">main<\/span>: <span style=\"color:#a6e22e\">non<\/span><span style=\"color:#f92672\">-<\/span><span style=\"color:#a6e22e\">leaf<\/span> <span style=\"color:#a6e22e\">function<\/span><\/span><\/span><span style=\"display:flex;\"><span>.<span style=\"color:#f92672\">\/<\/span><span style=\"color:#a6e22e\">main<\/span>.<span style=\"color:#66d9ef\">go<\/span>:<span style=\"color:#ae81ff\">22<\/span>: <span style=\"color:#a6e22e\">createUserV1<\/span> <span style=\"color:#f92672\">&amp;<\/span><span style=\"color:#a6e22e\">u<\/span> <span style=\"color:#a6e22e\">does<\/span> <span style=\"color:#a6e22e\">not<\/span> <span style=\"color:#a6e22e\">escape<\/span><\/span><\/span><span style=\"display:flex;\"><span>.<span style=\"color:#f92672\">\/<\/span><span style=\"color:#a6e22e\">main<\/span>.<span style=\"color:#66d9ef\">go<\/span>:<span style=\"color:#ae81ff\">34<\/span>: <span style=\"color:#f92672\">&amp;<\/span><span style=\"color:#a6e22e\">u<\/span> <span style=\"color:#a6e22e\">escapes<\/span> <span style=\"color:#a6e22e\">to<\/span> <span style=\"color:#a6e22e\">heap<\/span><\/span><\/span><span style=\"display:flex;\"><span>.<span style=\"color:#f92672\">\/<\/span><span style=\"color:#a6e22e\">main<\/span>.<span style=\"color:#66d9ef\">go<\/span>:<span style=\"color:#ae81ff\">34<\/span>: <span style=\"color:#a6e22e\">from<\/span> <span style=\"color:#960050;background-color:#1e0010\">~<\/span><span style=\"color:#a6e22e\">r0<\/span> (<span style=\"color:#66d9ef\">return<\/span>) <span style=\"color:#a6e22e\">at<\/span> .<span style=\"color:#f92672\">\/<\/span><span style=\"color:#a6e22e\">main<\/span>.<span style=\"color:#66d9ef\">go<\/span>:<span style=\"color:#ae81ff\">34<\/span><\/span><\/span><span style=\"display:flex;\"><span>.<span style=\"color:#f92672\">\/<\/span><span style=\"color:#a6e22e\">main<\/span>.<span style=\"color:#66d9ef\">go<\/span>:<span style=\"color:#ae81ff\">31<\/span>: <span style=\"color:#a6e22e\">moved<\/span> <span style=\"color:#a6e22e\">to<\/span> <span style=\"color:#a6e22e\">heap<\/span>: <span style=\"color:#a6e22e\">u<\/span><\/span><\/span><span style=\"display:flex;\"><span>.<span style=\"color:#f92672\">\/<\/span><span style=\"color:#a6e22e\">main<\/span>.<span style=\"color:#66d9ef\">go<\/span>:<span style=\"color:#ae81ff\">33<\/span>: <span style=\"color:#a6e22e\">createUserV2<\/span> <span style=\"color:#f92672\">&amp;<\/span><span style=\"color:#a6e22e\">u<\/span> <span style=\"color:#a6e22e\">does<\/span> <span style=\"color:#a6e22e\">not<\/span> <span style=\"color:#a6e22e\">escape<\/span><\/span><\/span><span style=\"display:flex;\"><span>.<span style=\"color:#f92672\">\/<\/span><span style=\"color:#a6e22e\">main<\/span>.<span style=\"color:#66d9ef\">go<\/span>:<span style=\"color:#ae81ff\">12<\/span>: <span style=\"color:#a6e22e\">main<\/span> <span style=\"color:#f92672\">&amp;<\/span><span style=\"color:#a6e22e\">u1<\/span> <span style=\"color:#a6e22e\">does<\/span> <span style=\"color:#a6e22e\">not<\/span> <span style=\"color:#a6e22e\">escape<\/span><\/span><\/span><span style=\"display:flex;\"><span>.<span style=\"color:#f92672\">\/<\/span><span style=\"color:#a6e22e\">main<\/span>.<span style=\"color:#66d9ef\">go<\/span>:<span style=\"color:#ae81ff\">12<\/span>: <span style=\"color:#a6e22e\">main<\/span> <span style=\"color:#f92672\">&amp;<\/span><span style=\"color:#a6e22e\">u2<\/span> <span style=\"color:#a6e22e\">does<\/span> <span style=\"color:#a6e22e\">not<\/span> <span style=\"color:#a6e22e\">escape<\/span><\/span><\/span><\/code><\/pre><\/div><p>\u5b9e\u9645\u4e0a\u53ef\u4ee5\u4f7f\u7528 4 \u4e2a <code>-m<\/code>\uff0c\u4f46\u662f\u8d85\u8fc7 2 \u4e2a\u63a7\u5236\u53f0\u4fe1\u606f\u5c31\u5f88\u591a\uff0c\u6240\u4ee5\u8fd9\u91cc\u4f7f\u7528\u4e86 2 \u4e2a <code>-m<\/code>\u3002<\/p><p>\u53ef\u4ee5\u770b\u5230\u65e5\u5fd7\u91cc\u6709\u4e86\u9003\u9038\u5206\u6790\u7684\u65e5\u5fd7\u3002<\/p><div class=\"highlight\"><pre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"><code class=\"language-go\" data-lang=\"go\"><span style=\"display:flex;\"><span>.<span style=\"color:#f92672\">\/<\/span><span style=\"color:#a6e22e\">main<\/span>.<span style=\"color:#66d9ef\">go<\/span>:<span style=\"color:#ae81ff\">22<\/span>: <span style=\"color:#a6e22e\">createUserV1<\/span> <span style=\"color:#f92672\">&amp;<\/span><span style=\"color:#a6e22e\">u<\/span> <span style=\"color:#a6e22e\">does<\/span> <span style=\"color:#a6e22e\">not<\/span> <span style=\"color:#a6e22e\">escape<\/span><\/span><\/span><\/code><\/pre><\/div><p>\u901a\u8fc7\u65e5\u5fd7\uff0c\u6211\u4eec\u53ef\u4ee5\u77e5\u9053\u7a0b\u5e8f 2 \u7b2c 22 \u884c\u8c03\u7528 <code>println<\/code> \u51fd\u6570\u65f6\u6ca1\u6709\u53d1\u751f\u9003\u9038\u3002<\/p><div class=\"highlight\"><pre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"><code class=\"language-go\" data-lang=\"go\"><span style=\"display:flex;\"><span>.<span style=\"color:#f92672\">\/<\/span><span style=\"color:#a6e22e\">main<\/span>.<span style=\"color:#66d9ef\">go<\/span>:<span style=\"color:#ae81ff\">34<\/span>: <span style=\"color:#f92672\">&amp;<\/span><span style=\"color:#a6e22e\">u<\/span> <span style=\"color:#a6e22e\">escapes<\/span> <span style=\"color:#a6e22e\">to<\/span> <span style=\"color:#a6e22e\">heap<\/span><\/span><\/span><span style=\"display:flex;\"><span>.<span style=\"color:#f92672\">\/<\/span><span style=\"color:#a6e22e\">main<\/span>.<span style=\"color:#66d9ef\">go<\/span>:<span style=\"color:#ae81ff\">34<\/span>: <span style=\"color:#a6e22e\">from<\/span> <span style=\"color:#960050;background-color:#1e0010\">~<\/span><span style=\"color:#a6e22e\">r0<\/span> (<span style=\"color:#66d9ef\">return<\/span>) <span style=\"color:#a6e22e\">at<\/span> .<span style=\"color:#f92672\">\/<\/span><span style=\"color:#a6e22e\">main<\/span>.<span style=\"color:#66d9ef\">go<\/span>:<span style=\"color:#ae81ff\">34<\/span><\/span><\/span><span style=\"display:flex;\"><span>.<span style=\"color:#f92672\">\/<\/span><span style=\"color:#a6e22e\">main<\/span>.<span style=\"color:#66d9ef\">go<\/span>:<span style=\"color:#ae81ff\">31<\/span>: <span style=\"color:#a6e22e\">moved<\/span> <span style=\"color:#a6e22e\">to<\/span> <span style=\"color:#a6e22e\">heap<\/span>: <span style=\"color:#a6e22e\">u<\/span><\/span><\/span><\/code><\/pre><\/div><p>\u8fd9\u51e0\u884c\u662f\u8bf4\uff0c\u7b2c 31 \u884c\u521b\u5efa\u7684 <code>u<\/code> \u53d8\u91cf\uff0c\u56e0\u4e3a\u7b2c 34 \u884c\u7684 return \u8bed\u53e5\u53d1\u751f\u4e86\u9003\u9038\u3002<\/p><h2 id=\"\u53d8\u91cf\u9003\u9038\u60c5\u51b5\u603b\u7ed3\">\u53d8\u91cf\u9003\u9038\u60c5\u51b5\u603b\u7ed3<\/h2><p>\u603b\u7684\u6765\u8bf4\uff0c\u5982\u679c\u51fa\u73b0\u4e86\u4ee5\u4e0b\u4e09\u79cd\u60c5\u51b5\uff0c\u5219\u5fc5\u7136\u53d1\u751f\u9003\u9038\uff1a<\/p><ul><li>\u51fd\u6570\u4e2dnew\u6216\u5b57\u9762\u91cf\u521b\u5efa\u51fa\u7684\u53d8\u91cf\uff0c\u5c06\u5176\u6307\u9488\u4f5c\u4e3a\u51fd\u6570\u8fd4\u56de\u503c\uff0c\u5219\u8be5\u53d8\u91cf\u4e00\u5b9a\u53d1\u751f\u9003\u9038\uff08\u6784\u9020\u51fd\u6570\u8fd4\u56de\u7684\u6307\u9488\u53d8\u91cf\u4e00\u5b9a\u9003\u9038\uff09<\/li><li>\u88ab\u5df2\u7ecf\u9003\u9038\u7684\u53d8\u91cf\u5f15\u7528\u7684\u6307\u9488\uff0c\u4e00\u5b9a\u53d1\u751f\u9003\u9038<\/li><li>\u88ab\u6307\u9488\u7c7b\u578b\u7684slice\u3001map\u548cchan\u5f15\u7528\u7684\u6307\u9488\uff0c\u4e00\u5b9a\u53d1\u751f\u9003\u9038<\/li><\/ul><p>\u800c\u5728\u4ee5\u4e0b\u4e24\u79cd\u60c5\u51b5\u4e0b\uff0c\u5219\u4e0d\u4f1a\u53d1\u751f\u9003\u9038\u7684\u60c5\u51b5\uff1a<\/p><ul><li>\u6307\u9488\u88ab\u672a\u53d1\u751f\u9003\u9038\u7684\u53d8\u91cf\u5f15\u7528<\/li><li>\u4ec5\u4ec5\u5728\u51fd\u6570\u5185\u5bf9\u53d8\u91cf\u505a\u53d6\u5740\u64cd\u4f5c\uff0c\u800c\u672a\u5c06\u6307\u9488\u4f20\u51fa<\/li><\/ul><h2 id=\"\u603b\u7ed3\">\u603b\u7ed3<\/h2><p>\u53d8\u91cf\u662f\u5426\u9003\u9038\u662f\u6709\u53d8\u91cf\u7684\u5206\u4eab\u65b9\u5f0f\u51b3\u5b9a\u7684\uff0c\u53ea\u6709\u5f53\u4e00\u4e2a\u53d8\u91cf\u88ab\u5171\u4eab\u4e86\uff08\u901a\u8fc7\u53d8\u91cf\u7684\u5730\u5740\u7684\u65b9\u5f0f\u5171\u4eab\uff09\uff0c\u53d8\u91cf\u624d\u4f1a\u9003\u9038\u5230\u5806\u4e0a\u3002\u53d8\u91cf\u9003\u9038\u5230\u5806\u4e0a\u4f1a\u589e\u52a0 GC \u7684\u538b\u529b\uff0c\u800c\u901a\u8fc7\u53d8\u91cf\u526f\u672c\u7684\u65b9\u5f0f\u9700\u8981\u5b58\u50a8\u548c\u7ef4\u62a4\u4e0d\u540c\u7684\u526f\u672c\uff0c\u6bcf\u79cd\u65b9\u5f0f\u90fd\u6709\u597d\u5904\u548c\u5f00\u9500\uff0c\u5173\u952e\u7684\u65f6\u8981\u6b63\u786e\u3001\u4e00\u81f4\u4e14\u5e73\u8861\u7684\u4f7f\u7528\u6bcf\u79cd\u8bed\u4e49\u3002<\/p><h2 id=\"\u53c2\u8003\u8d44\u6599\">\u53c2\u8003\u8d44\u6599<\/h2><ol><li><a href=\"https:\/\/www.ardanlabs.com\/blog\/2017\/05\/language-mechanics-on-escape-analysis.html\">https:\/\/www.ardanlabs.com\/blog\/2017\/05\/language-mechanics-on-escape-analysis.html<\/a><\/li><\/ol>"},{"title":"golang\u8bed\u8a00\u673a\u5236\u4e4b\u6808\u4e0e\u6307\u9488","link":"https:\/\/sunpe.github.io\/posts\/2020-07-17-golang-stack-and-pointer\/","pubDate":"Fri, 17 Jul 2020 22:00:00 +0800","guid":"https:\/\/sunpe.github.io\/posts\/2020-07-17-golang-stack-and-pointer\/","description":"<p>\u5b66\u4e60\u548c\u4f7f\u7528 golang\uff0c\u5c31\u4e0d\u5f97\u4e0d\u4e86\u89e3 golang \u7684\u6307\u9488\u3002\u5982\u679c\u4e0d\u80fd\u5f88\u597d\u7684\u7406\u89e3\u6307\u9488\uff0c\u5f88\u96be\u5199\u51fa\u7b80\u5355\u3001\u6574\u6d01\u5e76\u9ad8\u6548\u7684\u4ee3\u7801\u3002<\/p><h2 id=\"\u5e27\u8fb9\u754cframe-boundaries\">\u5e27\u8fb9\u754c\uff08Frame Boundaries\uff09<\/h2><p>\u5e27\u8fb9\u754c\u4e3a\u51fd\u6570\u6267\u884c\u63d0\u4f9b\u4e86\u72ec\u6709\u7684\u5185\u5b58\u7a7a\u95f4\u3001\u4e0a\u4e0b\u6587\uff08context\uff09\u73af\u5883\u548c\u4e00\u4e9b\u6d41\u63a7\u5236\u3002\u51fd\u6570\u53ef\u4ee5\u901a\u8fc7\u5e27\u8fb9\u754c\u6307\u9488\u76f4\u63a5\u8bbf\u95ee\u5e27\u8fb9\u754c\u7684\u5185\u5b58\uff0c\u6216\u8005\u95f4\u63a5\u8bbf\u95ee\u5e27\u8fb9\u754c\u5916\u7684\u5185\u5b58\uff08\u4e0d\u80fd\u76f4\u63a5\u8bbf\u95ee\u5e27\u8fb9\u754c\u5916\u7684\u5185\u5b58\uff09\u3002\u51fd\u6570\u8981\u95f4\u63a5\u8bbf\u95ee\u5e27\u8fb9\u754c\u5916\u7684\u5185\u5b58\uff0c\u88ab\u8bbf\u95ee\u7684\u5185\u5b58\u5fc5\u987b\u548c\u51fd\u6570\u5171\u4eab\u3002\u6211\u4eec\u9996\u5148\u6765\u4e86\u89e3\u4e00\u4e0b\u5e27\u8fb9\u754c\u5efa\u7acb\u7684\u673a\u5236\u548c\u9650\u5236\u3002<\/p><p>\u51fd\u6570\u8c03\u7528\u65f6\uff0c\u4f1a\u5728\u4e24\u4e2a\u76f8\u5173\u7684\u5e27\u8fb9\u754c\u95f4\u8fdb\u884c\u5207\u6362\uff0c\u4ece\u8c03\u7528\u51fd\u6570\u5207\u6362\u5230\u88ab\u8c03\u7528\u51fd\u6570\uff0c\u5982\u679c\u51fd\u6570\u8c03\u7528\u65f6\u9700\u8981\u4f20\u9012\u53c2\u6570\uff0c\u90a3\u4e48\u8fd9\u4e9b\u53c2\u6570\u503c\u4e5f\u8981\u4f20\u9012\u5230\u88ab\u8c03\u7528\u51fd\u6570\u7684\u5e27\u8fb9\u754c\u4e2d\u3002Go \u8bed\u8a00\u4e2d\u5e27\u8fb9\u754c\u95f4\u7684\u6570\u636e\u4f20\u9012\u662f\u6309\u503c\uff08by value\uff09\u4f20\u9012\u7684\u3002<\/p><p>\u6309\u503c\u4f20\u9012\u7684\u597d\u5904\u662f\u53ef\u8bfb\u6027\u597d\uff0c\u51fd\u6570\u8c03\u7528\u65f6\u4f20\u5165\u7684\u503c\u5c31\u662f\u51fd\u6570\u771f\u6b63\u63a5\u6536\u5230\u7684\u503c\u3002\u6309\u503c\u4f20\u9012\u53c8\u53eb\u505a WYSIWYG\uff08what you see is what you get\uff09\u3002\u5728\u53d1\u751f\u5207\u6362\u65f6\uff0c\u6211\u4eec\u53ef\u4ee5\u5f88\u6e05\u695a\u7684\u4e86\u89e3\u51fd\u6570\u8c03\u7528\u5c06\u5982\u4f55\u5f71\u54cd\u7a0b\u5e8f\u6267\u884c\u3002<\/p><p>\u7a0b\u5e8f 1 \u5c55\u793a\u4e86\u51fd\u6570\u8c03\u7528\u6309\u503c\u4f20\u9012\u3002<\/p><div class=\"highlight\"><pre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"><code class=\"language-go\" data-lang=\"go\"><span style=\"display:flex;\"><span><span style=\"color:#75715e\">\/\/ \u7a0b\u5e8f 1 <\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span><span style=\"color:#f92672\">package<\/span> <span style=\"color:#a6e22e\">main<\/span><\/span><\/span><span style=\"display:flex;\"><span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#66d9ef\">func<\/span> <span style=\"color:#a6e22e\">main<\/span>() {<\/span><\/span><span style=\"display:flex;\"><span><\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#75715e\">\/\/ Declare variable of type int with a value of 10.<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span> <span style=\"color:#a6e22e\">count<\/span> <span style=\"color:#f92672\">:=<\/span> <span style=\"color:#ae81ff\">10<\/span><\/span><\/span><span style=\"display:flex;\"><span><\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#75715e\">\/\/ Display the &#34;value of&#34; and &#34;address of&#34; count.<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span> println(<span style=\"color:#e6db74\">&#34;count:\\tValue Of[&#34;<\/span>, <span style=\"color:#a6e22e\">count<\/span>, <span style=\"color:#e6db74\">&#34;]\\tAddr Of[&#34;<\/span>, <span style=\"color:#f92672\">&amp;<\/span><span style=\"color:#a6e22e\">count<\/span>, <span style=\"color:#e6db74\">&#34;]&#34;<\/span>)<\/span><\/span><span style=\"display:flex;\"><span><\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#75715e\">\/\/ Pass the &#34;value of&#34; the count.<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span> <span style=\"color:#a6e22e\">increment<\/span>(<span style=\"color:#a6e22e\">count<\/span>)<\/span><\/span><span style=\"display:flex;\"><span><\/span><\/span><span style=\"display:flex;\"><span> println(<span style=\"color:#e6db74\">&#34;count:\\tValue Of[&#34;<\/span>, <span style=\"color:#a6e22e\">count<\/span>, <span style=\"color:#e6db74\">&#34;]\\tAddr Of[&#34;<\/span>, <span style=\"color:#f92672\">&amp;<\/span><span style=\"color:#a6e22e\">count<\/span>, <span style=\"color:#e6db74\">&#34;]&#34;<\/span>)<\/span><\/span><span style=\"display:flex;\"><span>}<\/span><\/span><span style=\"display:flex;\"><span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\">\/\/go:noinline<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span><span style=\"color:#66d9ef\">func<\/span> <span style=\"color:#a6e22e\">increment<\/span>(<span style=\"color:#a6e22e\">inc<\/span> <span style=\"color:#66d9ef\">int<\/span>) {<\/span><\/span><span style=\"display:flex;\"><span><\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#75715e\">\/\/ Increment the &#34;value of&#34; inc.<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span> <span style=\"color:#a6e22e\">inc<\/span><span style=\"color:#f92672\">++<\/span><\/span><\/span><span style=\"display:flex;\"><span> println(<span style=\"color:#e6db74\">&#34;inc:\\tValue Of[&#34;<\/span>, <span style=\"color:#a6e22e\">inc<\/span>, <span style=\"color:#e6db74\">&#34;]\\tAddr Of[&#34;<\/span>, <span style=\"color:#f92672\">&amp;<\/span><span style=\"color:#a6e22e\">inc<\/span>, <span style=\"color:#e6db74\">&#34;]&#34;<\/span>)<\/span><\/span><span style=\"display:flex;\"><span>}<\/span><\/span><\/code><\/pre><\/div><p>\u7a0b\u5e8f\u6267\u884c\u65f6\uff0c\u8fd0\u884c\u65f6\uff08runtime\uff09\u521b\u5efa main goroutine \u6765\u521d\u59cb\u5316\u4ee3\u7801\u3002goroutine \u6700\u7ec8\u5728\u64cd\u4f5c\u7cfb\u7edf\u7ebf\u7a0b\uff08os threads\uff09\u4e0a\u6267\u884c\uff0c\u4ece golang 1.8 \u5f00\u59cb\uff0c\u6bcf\u4e2a goroutine \u7684\u6808\u7a7a\u95f4\u662f 2048 \u5b57\u8282\u8fde\u7eed\u7684\u5185\u5b58\u7a7a\u95f4\uff0c\u6808\u7a7a\u95f4\u5927\u5c0f\u672a\u6765\u53ef\u80fd\u8fd8\u4f1a\u53d8\u5316\u3002<\/p><p>\u6808\u7a7a\u95f4\u4e3a\u6bcf\u4e2a\u51fd\u6570\u7684\u5e27\u8fb9\u754c\u63d0\u4f9b\u4e86\u7269\u7406\u5185\u5b58\u7a7a\u95f4\uff0cmain goroutine \u6267\u884c\u7a0b\u5e8f1\u4e2d\u7684 <code>main()<\/code> \u65b9\u6cd5\u65f6\u6808\u7a7a\u95f4\u770b\u8d77\u6765\u5e94\u8be5\u662f\u5982\u56fe1\u8fd9\u6837\u7684\uff1a<\/p><p><img src=\"https:\/\/sunpe.github.io\/images\/golang_stack_and_pointer\/1.png\" alt=\"\">\u56fe 1<\/p><p>\u5982\u56fe 1 \u6240\u793a\uff0c\u6808\u7a7a\u95f4\u5df2\u7ecf\u5212\u51fa\u4e86\u4e00\u5757\u4f5c\u4e3a main frame\uff0c\u8fd9\u5757\u533a\u57df\u53eb\u300c\u6808\u5e27\u300d\uff0c\u754c\u5b9a\u4e86 main \u51fd\u6570\u5728\u6808\u4e0a\u7684\u8fb9\u754c\u3002\u8fd9\u5757\u6808\u7a7a\u95f4\u968f\u7740\u4ee3\u7801\u7684\u6267\u884c\u800c\u88ab\u521b\u5efa\uff0c\u53d8\u91cf <code>count<\/code> \u5728\u8fd9\u5757\u6808\u7a7a\u95f4\u7684\u5730\u5740\u662f <code>0x10429fa4<\/code>\u3002<\/p><p>\u56fe1\u8fd8\u5c55\u793a\u4e86\u4e00\u70b9\uff0c\u5728\u6d3b\u8dc3\u7684\u6808\u5e27\u5916\u7684\u5185\u5b58\u7a7a\u95f4\u662f\u4e0d\u53ef\u7528\u7684\uff0c\u53ef\u4ee5\u5185\u5b58\u7a7a\u95f4\u548c\u4e0d\u53ef\u7528\u5185\u5b58\u7a7a\u95f4\u7684\u8fb9\u754c\u9700\u8981\u660e\u786e\u4e00\u4e0b\u3002<\/p><h2 id=\"\u5730\u5740\">\u5730\u5740<\/h2><p>\u53d8\u91cf\u540d\u8868\u793a\u4e00\u4e2a\u5185\u5b58\u5730\u5740\uff0c\u5982\u679c\u5b58\u5728\u53d8\u91cf\u503c\u90a3\u4e48\u5185\u5b58\u4e2d\u4e00\u5b9a\u5b58\u5728\u53d8\u91cf\u503c\uff0c\u53d8\u91cf\u503c\u4e00\u5b9a\u4f1a\u6709\u5185\u5b58\u5730\u5740\u3002\u7a0b\u5e8f 1 \u7684\u7b2c 9 \u884c\u6253\u5370\u51fa\u4e86 <code>count<\/code> \u53d8\u91cf\u7684\u503c\u548c\u5730\u5740\uff1a<\/p><div class=\"highlight\"><pre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"><code class=\"language-go\" data-lang=\"go\"><span style=\"display:flex;\"><span>println(<span style=\"color:#e6db74\">&#34;count:\\tValue Of[&#34;<\/span>, <span style=\"color:#a6e22e\">count<\/span>, <span style=\"color:#e6db74\">&#34;]\\tAddr Of[&#34;<\/span>, <span style=\"color:#f92672\">&amp;<\/span><span style=\"color:#a6e22e\">count<\/span>, <span style=\"color:#e6db74\">&#34;]&#34;<\/span>)<\/span><\/span><\/code><\/pre><\/div><p>golang \u4e2d\u4f7f\u7528 <code>&amp;<\/code> \u64cd\u4f5c\u7b26\u83b7\u53d6\u53d8\u91cf\u7684\u5185\u5b58\u5730\u5740\uff0c\u8fd9\u4e00\u884c\u4ee3\u7801\u7684\u8f93\u51fa\u5982\u4e0b\uff08\u6bcf\u6b21\u8fd0\u884c\u53d8\u91cf\u7684\u5730\u5740\u53ef\u80fd\u4e0d\u4e00\u6837\uff09\uff1a<\/p><div class=\"highlight\"><pre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"><code class=\"language-go\" data-lang=\"go\"><span style=\"display:flex;\"><span><span style=\"color:#a6e22e\">count<\/span>: <span style=\"color:#a6e22e\">Value<\/span> <span style=\"color:#a6e22e\">Of<\/span>[ <span style=\"color:#ae81ff\">10<\/span> ] <span style=\"color:#a6e22e\">Addr<\/span> <span style=\"color:#a6e22e\">Of<\/span>[ <span style=\"color:#ae81ff\">0x10429fa4<\/span> ]<\/span><\/span><\/code><\/pre><\/div><h2 id=\"\u51fd\u6570\u8c03\u7528\">\u51fd\u6570\u8c03\u7528<\/h2><p>\u7a0b\u5e8f 1 \u7684\u7b2c 12 \u884c\u8c03\u7528\u4e86 <code>increment<\/code> \u51fd\u6570\u3002<\/p><div class=\"highlight\"><pre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"><code class=\"language-go\" data-lang=\"go\"><span style=\"display:flex;\"><span><span style=\"color:#a6e22e\">increment<\/span>(<span style=\"color:#a6e22e\">count<\/span>)<\/span><\/span><\/code><\/pre><\/div><p>\u51fd\u6570\u8c03\u7528\u610f\u5473\u7740\u9700\u8981\u5728\u6808\u4e0a\u5f00\u8f9f\u65b0\u7684\u7a7a\u95f4\uff0c\u9664\u6b64\u4e4b\u5916\uff0c\u9700\u8981\u5c06\u53c2\u6570\u8de8\u8d8a\u5e27\u8fb9\u754c\u4f20\u5230\u65b0\u7684\u6808\u5e27\u4e2d\u3002\u8fd9\u91cc\u9700\u8981\u5c06 <code>count<\/code> \u53d8\u91cf\u4f20\u9012\u7ed9<code>increment<\/code>\u51fd\u6570\u3002\u7a0b\u5e8f 1 \u7684\u7b2c 12 \u884c\u8c03\u7528 <code>increment<\/code> \u51fd\u6570\u4f20\u9012\u7684\u662f <code>count<\/code> \u53d8\u91cf\u7684\u503c\uff0c\u4f1a\u590d\u5236 count \u53d8\u91cf\u7684\u503c\u5e76\u4f20\u9012\u5230 <code>increment<\/code> \u51fd\u6570\u7684\u6808\u5e27\u3002\u800c <code>increment<\/code> \u53ea\u80fd\u4fee\u6539\u81ea\u5df1\u6808\u5e27\u7684 <code>count<\/code> \u53d8\u91cf\u7684\u526f\u672c\u3002\u8c03\u7528 <code>increment<\/code> \u65b9\u6cd5\u6808\u7a7a\u95f4\u5982\u56fe 2:<\/p><p><img src=\"https:\/\/sunpe.github.io\/images\/golang_stack_and_pointer\/2.png\" alt=\"\">\u56fe2<\/p><p>\u73b0\u5728\u6808\u7a7a\u95f4\u6709\u4e24\u4e2a\u6808\u5e27\uff0c<code>main<\/code> \u51fd\u6570\u6808\u5e27\u548c <code>increment<\/code> \u51fd\u6570\u6808\u5e27\u3002\u5728 <code>increment<\/code> \u51fd\u6570\u6808\u5e27\uff0c\u53ef\u4ee5\u770b\u5230 <code>inc<\/code> \u53d8\u91cf\uff0c\u53d8\u91cf\u503c\u662f 10\uff0c\u5730\u5740\u662f <code>0x10429f98<\/code>\u3002\u56e0\u4e3a\u6808\u662f\u4ece\u4e0a\u5f80\u4e0b\u4f7f\u7528\u6808\u7a7a\u95f4\uff0c\u6240\u4ee5 <code>inc<\/code> \u53d8\u91cf\u5730\u5740\u503c\u6bd4 <code>count<\/code> \u53d8\u91cf\u5730\u5740\u503c\u5c0f\uff08\u8fd9\u53ea\u662f\u5b9e\u73b0\u7ec6\u8282\uff09\u3002\u7b80\u5355\u6765\u8bf4\uff0cgoroutine \u628a\u51fd\u6570 <code>main<\/code> \u6808\u5e27\u4e2d\u7684 <code>count<\/code> \u53d8\u91cf\u7684\u503c\u62f7\u8d1d\u5e76\u4f20\u9012\u7ed9\u4e86\u51fd\u6570 <code>increment<\/code> \u6808\u5e27\u4e2d\u7684 <code>inc<\/code> \u53d8\u91cf\u3002<\/p><p><code>increment<\/code> \u51fd\u6570\u4e2d\u5c06 inc \u53d8\u91cf\u7684\u503c\u52a0 1 \u5e76\u6253\u5370\uff1a<\/p><div class=\"highlight\"><pre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"><code class=\"language-go\" data-lang=\"go\"><span style=\"display:flex;\"><span><span style=\"color:#a6e22e\">inc<\/span><span style=\"color:#f92672\">++<\/span><\/span><\/span><span style=\"display:flex;\"><span>println(<span style=\"color:#e6db74\">&#34;inc:\\tValue Of[&#34;<\/span>, <span style=\"color:#a6e22e\">inc<\/span>, <span style=\"color:#e6db74\">&#34;]\\tAddr Of[&#34;<\/span>, <span style=\"color:#f92672\">&amp;<\/span><span style=\"color:#a6e22e\">inc<\/span>, <span style=\"color:#e6db74\">&#34;]&#34;<\/span>)<\/span><\/span><\/code><\/pre><\/div><p>\u7a0b\u5e8f 1 \u4e2d\u7b2c 22 \u884c\u4ee3\u7801\u8f93\u51fa\u5e94\u8be5\u662f\uff1a<\/p><div class=\"highlight\"><pre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"><code class=\"language-go\" data-lang=\"go\"><span style=\"display:flex;\"><span><span style=\"color:#a6e22e\">inc<\/span>: <span style=\"color:#a6e22e\">Value<\/span> <span style=\"color:#a6e22e\">Of<\/span>[ <span style=\"color:#ae81ff\">11<\/span> ] <span style=\"color:#a6e22e\">Addr<\/span> <span style=\"color:#a6e22e\">Of<\/span>[ <span style=\"color:#ae81ff\">0x10429f98<\/span> ]<\/span><\/span><\/code><\/pre><\/div><p>\u6267\u884c\u5b8c <code>incr<\/code> \u53d8\u91cf\u81ea\u589e\u540e\uff0c\u6808\u7a7a\u95f4\u53d8\u6210\u56fe 3:<\/p><p><img src=\"https:\/\/sunpe.github.io\/images\/golang_stack_and_pointer\/3.png\" alt=\"\">\u56fe3<\/p><p>\u7a0b\u5e8f 1 \u6267\u884c\u5b8c\u7b2c 21 \u548c 22 \u884c\u4ee3\u7801\u4e4b\u540e\uff0c<code>increment<\/code> \u51fd\u6570\u8fd4\u56de\uff0c\u6d41\u7a0b\u63a7\u5236\u6743\u53c8\u56de\u5230\u4e86 <code>main<\/code> \u51fd\u6570\uff0c<code>main<\/code> \u51fd\u6570\u6267\u884c\u7b2c14\u884c\u4ee3\u7801\uff0c\u6253\u5370 <code>count<\/code> \u53d8\u91cf\u7684\u503c\u548c\u5730\u5740\u3002<\/p><div class=\"highlight\"><pre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"><code class=\"language-go\" data-lang=\"go\"><span style=\"display:flex;\"><span>println(<span style=\"color:#e6db74\">&#34;count:\\tValue Of[&#34;<\/span>,<span style=\"color:#a6e22e\">count<\/span>, <span style=\"color:#e6db74\">&#34;]\\tAddr Of[&#34;<\/span>, <span style=\"color:#f92672\">&amp;<\/span><span style=\"color:#a6e22e\">count<\/span>, <span style=\"color:#e6db74\">&#34;]&#34;<\/span>)<\/span><\/span><\/code><\/pre><\/div><p>\u7a0b\u5e8f1\u7684\u5b8c\u6574\u7684\u8f93\u51fa\u5982\u4e0b\uff1a<\/p><div class=\"highlight\"><pre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"><code class=\"language-go\" data-lang=\"go\"><span style=\"display:flex;\"><span><span style=\"color:#a6e22e\">count<\/span>: <span style=\"color:#a6e22e\">Value<\/span> <span style=\"color:#a6e22e\">Of<\/span>[ <span style=\"color:#ae81ff\">10<\/span> ] <span style=\"color:#a6e22e\">Addr<\/span> <span style=\"color:#a6e22e\">Of<\/span>[ <span style=\"color:#ae81ff\">0x10429fa4<\/span> ]<\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#a6e22e\">inc<\/span>: <span style=\"color:#a6e22e\">Value<\/span> <span style=\"color:#a6e22e\">Of<\/span>[ <span style=\"color:#ae81ff\">11<\/span> ] <span style=\"color:#a6e22e\">Addr<\/span> <span style=\"color:#a6e22e\">Of<\/span>[ <span style=\"color:#ae81ff\">0x10429f98<\/span> ]<\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#a6e22e\">count<\/span>: <span style=\"color:#a6e22e\">Value<\/span> <span style=\"color:#a6e22e\">Of<\/span>[ <span style=\"color:#ae81ff\">10<\/span> ] <span style=\"color:#a6e22e\">Addr<\/span> <span style=\"color:#a6e22e\">Of<\/span>[ <span style=\"color:#ae81ff\">0x10429fa4<\/span> ]<\/span><\/span><\/code><\/pre><\/div><p><code>main<\/code> \u51fd\u6570\u6808\u5e27\u4e2d <code>count<\/code> \u53d8\u91cf\u7684\u503c\u5728\u8c03\u7528 <code>increment<\/code> \u51fd\u6570\u524d\u540e\u503c\u6ca1\u53d8\u3002<\/p><h2 id=\"\u51fd\u6570\u8fd4\u56de\">\u51fd\u6570\u8fd4\u56de<\/h2><p>\u88ab\u8c03\u7528\u7684\u51fd\u6570\u8fd4\u56de\u5e76\u5c06\u63a7\u5236\u6743\u4ea4\u8fd8\u7ed9\u8c03\u7528\u51fd\u6570\u65f6\u6808\u7a7a\u95f4\u53d1\u751f\u4e86\u4ec0\u4e48\uff1f\u7b80\u5355\u7684\u56de\u7b54\u662f\uff0c\u4ec0\u4e48\u4e5f\u6ca1\u53d1\u751f\u3002\u56fe 4 \u662f increment \u51fd\u6570\u8fd4\u56de\u540e\u7684\u6808\u7a7a\u95f4\uff1a<\/p><p><img src=\"https:\/\/sunpe.github.io\/images\/golang_stack_and_pointer\/4.png\" alt=\"\">\u56fe4<\/p><p>\u56fe 4 \u6240\u793a\u6808\u7a7a\u95f4\u770b\u8d77\u6765\u548c\u56fe3\u76f8\u4f3c\uff0c\u53ea\u662f <code>increment<\/code> \u6808\u7a7a\u95f4\u73b0\u5728\u53d8\u6210\u4e86\u4e0d\u53ef\u7528\u5185\u5b58\uff0c\u8fd9\u662f\u56e0\u4e3a\u73b0\u5728 <code>main<\/code> \u51fd\u6570\u6808\u5e27\u662f\u6d3b\u8dc3\u7684\u6808\u5e27\u3002\u51fd\u6570\u8fd4\u56de\u4e4b\u540e\uff0c\u6ca1\u6709\u7acb\u5373\u6e05\u7406\u51fd\u6570\u7684\u6808\u7a7a\u95f4\uff0c\u56e0\u4e3a\u4e0d\u786e\u5b9a\u662f\u5426\u8fd8\u9700\u8981\u4f7f\u7528\u8fd9\u5757\u5185\u5b58\u7a7a\u95f4\uff0c\u53ea\u6709\u518d\u6b21\u6709\u51fd\u6570\u88ab\u8c03\u7528\u5e76\u4e14\u4f7f\u7528\u5230\u4e86\u8fd9\u5757\u5185\u5b58\u7a7a\u95f4\u65f6\uff0c\u624d\u4f1a\u53bb\u6e05\u7406\u3002<\/p><h2 id=\"\u503c\u7684\u5171\u4eab\">\u503c\u7684\u5171\u4eab<\/h2><p>\u5982\u679c\u60f3\u5728 <code>increment<\/code> \u51fd\u6570\u76f4\u63a5\u64cd\u4f5c <code>main<\/code> \u51fd\u6570\u6808\u5e27\u7684 <code>count<\/code> \u53d8\u91cf\u8981\u600e\u4e48\u529e\uff1f\u8fd9\u65f6\u5019\u5c31\u9700\u8981\u7528\u5230\u6307\u9488\u3002\u6307\u9488\u53ef\u4ee5\u548c\u51fd\u6570\u5171\u4eab\u53d8\u91cf\uff0c\u8ba9\u51fd\u6570\u53ef\u4ee5\u76f4\u63a5\u8bfb\u5199\u8fd9\u4e2a\u5171\u4eab\u53d8\u91cf\u7684\u503c\uff0c\u5373\u4f7f\u5171\u4eab\u53d8\u91cf\u4e0d\u5728\u81ea\u5df1\u7684\u6808\u5e27\u5185\u3002<\/p><p>\u5982\u679c\u4e0d\u9700\u8981\u5171\u4eab\u53d8\u91cf\uff0c\u90a3\u4e48\u5c31\u4e0d\u9700\u8981\u4f7f\u7528\u6307\u9488\uff0c\u4f7f\u7528\u6307\u9488\u662f\u4e3a\u4e86\u5171\u4eab\uff0c\u5e76\u4e14\u5f53\u9605\u8bfb\u4ee3\u7801\u65f6\uff0c\u4e5f\u5e94\u8be5\u628a <code>&amp;<\/code> \u64cd\u4f5c\u7b26\u5f53\u505a\u5171\u4eab\u6765\u770b\u3002<\/p><h2 id=\"\u6307\u9488\u7c7b\u578b\">\u6307\u9488\u7c7b\u578b<\/h2><p>\u4efb\u4f55\u7c7b\u578b\uff08\u65e0\u8bba\u662f\u81ea\u5b9a\u4e49\u7684\u7c7b\u578b\u8fd8\u662f\u5185\u7f6e\u7c7b\u578b\uff09\u90fd\u6709\u4e00\u4e2a\u4e0e\u4e4b\u5bf9\u5e94\u7684\u6307\u9488\u7c7b\u578b\uff0c\u7528\u6765\u5171\u4eab\u6570\u636e\u3002\u6bd4\u5982\u5185\u7f6e\u7c7b\u578b <code>int<\/code> \u7684\u6307\u9488\u7c7b\u578b\u662f <code>*int<\/code>\uff0c\u81ea\u5b9a\u4e49\u7684 <code>User<\/code> \u7c7b\u578b\u7684\u6307\u9488\u7c7b\u578b\u662f <code>*User<\/code>\u3002<\/p><p>\u6307\u9488\u7c7b\u578b\u4ee5 <code>*<\/code> \u5f00\u5934\uff0c\u5e76\u4e14\u6240\u6709\u6307\u9488\u7c7b\u578b\u7528\u76f8\u540c\u7684\u5185\u5b58\u5927\u5c0f\uff084 \u4e2a\u5b57\u8282\u6216 8 \u4e2a\u5b57\u8282\uff09\u6765\u8868\u793a\u5185\u5b58\u5730\u5740\u3002\u5728 32 \u4e3a\u7cfb\u7edf\uff08\u6bd4\u5982 playground\uff09\uff0c\u6307\u9488\u7c7b\u578b\u5927\u5c0f\u662f 4 \u4e2a\u5b57\u8282\uff0c\u5728 64 \u4f4d\u7cfb\u7edf\u4e2d\uff0c\u6307\u9488\u7c7b\u578b\u5927\u5c0f\u662f 8 \u4e2a\u5b57\u8282\u3002<\/p><p>\u89c4\u8303\u7684\u8bf4\uff0c \u6307\u9488\u7c7b\u578b\u88ab\u8ba4\u4e3a\u662f\u5b57\u9762\u7c7b\u578b\uff08type literals\uff09\uff0c\u4e5f\u5c31\u662f\u8bf4\u6307\u9488\u7c7b\u578b\u662f\u901a\u8fc7\u5df2\u6709\u7c7b\u578b\u7ec4\u5408\u800c\u6210\u7684\u3002<\/p><h2 id=\"\u76f4\u63a5\u5185\u5b58\u8bbf\u95ee\">\u76f4\u63a5\u5185\u5b58\u8bbf\u95ee<\/h2><p>\u7a0b\u5e8f 2 \u5c55\u793a\u4e86\u4ee5\u53d8\u91cf\u7684\u5730\u5740\u4f5c\u4e3a\u53c2\u6570\u6765\u8c03\u7528\u51fd\u6570\uff0c\u5728 main \u51fd\u6570\u6808\u548c increment \u51fd\u6570\u6808\u4e4b\u95f4\u5171\u4eab count \u53d8\u91cf<\/p><div class=\"highlight\"><pre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"><code class=\"language-go\" data-lang=\"go\"><span style=\"display:flex;\"><span><span style=\"color:#75715e\">\/\/ \u7a0b\u5e8f 2<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span><span style=\"color:#f92672\">package<\/span> <span style=\"color:#a6e22e\">main<\/span><\/span><\/span><span style=\"display:flex;\"><span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#66d9ef\">func<\/span> <span style=\"color:#a6e22e\">main<\/span>() {<\/span><\/span><span style=\"display:flex;\"><span><\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#75715e\">\/\/ Declare variable of type int with a value of 10.<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span> <span style=\"color:#a6e22e\">count<\/span> <span style=\"color:#f92672\">:=<\/span> <span style=\"color:#ae81ff\">10<\/span><\/span><\/span><span style=\"display:flex;\"><span><\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#75715e\">\/\/ Display the &#34;value of&#34; and &#34;address of&#34; count.<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span> println(<span style=\"color:#e6db74\">&#34;count:\\tValue Of[&#34;<\/span>, <span style=\"color:#a6e22e\">count<\/span>, <span style=\"color:#e6db74\">&#34;]\\t\\tAddr Of[&#34;<\/span>, <span style=\"color:#f92672\">&amp;<\/span><span style=\"color:#a6e22e\">count<\/span>, <span style=\"color:#e6db74\">&#34;]&#34;<\/span>)<\/span><\/span><span style=\"display:flex;\"><span><\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#75715e\">\/\/ Pass the &#34;address of&#34; count.<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span> <span style=\"color:#a6e22e\">increment<\/span>(<span style=\"color:#f92672\">&amp;<\/span><span style=\"color:#a6e22e\">count<\/span>)<\/span><\/span><span style=\"display:flex;\"><span><\/span><\/span><span style=\"display:flex;\"><span> println(<span style=\"color:#e6db74\">&#34;count:\\tValue Of[&#34;<\/span>, <span style=\"color:#a6e22e\">count<\/span>, <span style=\"color:#e6db74\">&#34;]\\t\\tAddr Of[&#34;<\/span>, <span style=\"color:#f92672\">&amp;<\/span><span style=\"color:#a6e22e\">count<\/span>, <span style=\"color:#e6db74\">&#34;]&#34;<\/span>)<\/span><\/span><span style=\"display:flex;\"><span>}<\/span><\/span><span style=\"display:flex;\"><span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\">\/\/go:noinline<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span><span style=\"color:#66d9ef\">func<\/span> <span style=\"color:#a6e22e\">increment<\/span>(<span style=\"color:#a6e22e\">inc<\/span> <span style=\"color:#f92672\">*<\/span><span style=\"color:#66d9ef\">int<\/span>) {<\/span><\/span><span style=\"display:flex;\"><span><\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#75715e\">\/\/ Increment the &#34;value of&#34; count that the &#34;pointer points to&#34;. (dereferencing)<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span> <span style=\"color:#f92672\">*<\/span><span style=\"color:#a6e22e\">inc<\/span><span style=\"color:#f92672\">++<\/span><\/span><\/span><span style=\"display:flex;\"><span> println(<span style=\"color:#e6db74\">&#34;inc:\\tValue Of[&#34;<\/span>,<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">inc<\/span>, <span style=\"color:#e6db74\">&#34;]\\tAddr Of[&#34;<\/span>, <span style=\"color:#f92672\">&amp;<\/span><span style=\"color:#a6e22e\">inc<\/span>, <span style=\"color:#e6db74\">&#34;]\\tValue Points To[&#34;<\/span>, <span style=\"color:#f92672\">*<\/span><span style=\"color:#a6e22e\">inc<\/span>, <span style=\"color:#e6db74\">&#34;]&#34;<\/span>)<\/span><\/span><span style=\"display:flex;\"><span>}<\/span><\/span><\/code><\/pre><\/div><p>\u5728\u7a0b\u5e8f 2 \u7684\u7b2c 12 \u884c\uff0c\u8c03\u7528 <code>increment<\/code> \u51fd\u6570\u4f20\u9012\u7684\u53c2\u6570\u662f <code>count<\/code> \u53d8\u91cf\u7684\u5730\u5740\u800c\u4e0d\u662f <code>count<\/code> \u53d8\u91cf\u7684\u526f\u672c\uff0c\u901a\u8fc7&amp;\u64cd\u4f5c\u7b26\u6765\u83b7\u53d6\u4e86 <code>count<\/code> \u53d8\u91cf\u7684\u5730\u5740\u3002\u8fd9\u91cc\u4f9d\u7136\u662f\u300c\u6309\u503c\u4f20\u9012\uff08pass by value\uff09\u300d\uff0c\u4e0d\u540c\u7684\u662f\uff0c\u4f20\u9012\u7684\u662f\u5730\u5740\u7684\u503c\u800c\u4e0d\u662fint\u7c7b\u578b\u53d8\u91cf\u7684\u503c\u3002<\/p><div class=\"highlight\"><pre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"><code class=\"language-go\" data-lang=\"go\"><span style=\"display:flex;\"><span><span style=\"color:#a6e22e\">increment<\/span>(<span style=\"color:#f92672\">&amp;<\/span><span style=\"color:#a6e22e\">count<\/span>)<\/span><\/span><\/code><\/pre><\/div><p>\u5728 increment \u51fd\u6570\u4e2d\uff0c\u9700\u8981\u80fd\u63a5\u53d7 int \u7c7b\u578b\u5730\u5740\u53c2\u6570\u7684\u5f62\u5f0f\u53c2\u6570\uff0c\u6240\u4ee5\u7a0b\u5e8f 2 \u7684\u7b2c 18 \u884c\u51fd\u6570\u53c2\u6570\u7c7b\u578b\u58f0\u660e\u4e3a <code>*int<\/code>\uff1a<\/p><div class=\"highlight\"><pre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"><code class=\"language-go\" data-lang=\"go\"><span style=\"display:flex;\"><span><span style=\"color:#66d9ef\">func<\/span> <span style=\"color:#a6e22e\">increment<\/span>(<span style=\"color:#a6e22e\">inc<\/span> <span style=\"color:#f92672\">*<\/span><span style=\"color:#66d9ef\">int<\/span>) {<\/span><\/span><\/code><\/pre><\/div><p>\u8c03\u7528\u4e86 increment \u51fd\u6570\u4e4b\u540e\uff0c\u6808\u7a7a\u95f4\u5982\u56fe 5 \u6240\u793a\uff1a<\/p><p><img src=\"https:\/\/sunpe.github.io\/images\/golang_stack_and_pointer\/5.png\" alt=\"\">\u56fe 5<\/p><p><code>increment<\/code> \u51fd\u6570\u6808\u7a7a\u95f4\u4e2d\u7684 <code>*int<\/code> \u7c7b\u578b\u7684 <code>inc<\/code> \u53d8\u91cf\u6307\u5411\u4e86 main \u51fd\u6570\u6808\u7a7a\u95f4\u4e2d\u7684 <code>count<\/code> \u53d8\u91cf\u3002\u4f7f\u7528\u8fd9\u4e2a\u6307\u9488\u7c7b\u578b\u53d8\u91cf\uff0c<code>increment<\/code> \u51fd\u6570\u53ef\u4ee5\u95f4\u63a5\u8bfb\u5199 <code>main<\/code> \u51fd\u6570\u7a7a\u95f4\u7684 <code>count<\/code> \u53d8\u91cf\u3002<\/p><p>\u5728\u7a0b\u5e8f 2 \u7684 21 \u884c\uff0c<code>*<\/code> \u7b26\u53f7\u548c\u6307\u9488\u7c7b\u578b\u53d8\u91cf\u4e00\u8d77\u4f7f\u7528\u65f6\uff0c\u8868\u793a\u53d6\u6307\u9488\u53d8\u91cf\u6307\u5411\u7684\u503c\u7684\u64cd\u4f5c\uff0c\u5728\u8fd9\u91cc\u5c31\u662f\u83b7\u53d6 main \u51fd\u6570\u4e2d\u7684 count \u53d8\u91cf\u3002\u6307\u9488\u7c7b\u578b\u53d8\u91cf\u5141\u8bb8\u5728\u51fd\u6570\u6808\u5e27\u7a7a\u95f4\u5916\u95f4\u63a5\u8bfb\u5199\u6307\u9488\u53d8\u91cf\u6307\u5411\u7684\u5185\u5b58\u7a7a\u95f4\uff0c\u6211\u4eec\u628a\u901a\u8fc7 <code>*<\/code> \u7b26\u53f7\u95f4\u63a5\u8bbf\u95ee\u5185\u5b58\u7a7a\u95f4\u7684\u65b9\u5f0f\u53eb\u6307\u9488\u7684\u89e3\u5f15\u7528\u3002<\/p><div class=\"highlight\"><pre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"><code class=\"language-go\" data-lang=\"go\"><span style=\"display:flex;\"><span><span style=\"color:#f92672\">*<\/span><span style=\"color:#a6e22e\">inc<\/span><span style=\"color:#f92672\">++<\/span><\/span><\/span><\/code><\/pre><\/div><p>\u5f53\u7a0b\u5e8f 2 \u6267\u884c\u5230 21 \u884c\u65f6\uff0c\u6808\u7a7a\u95f4\u5982\u56fe 6 \u6240\u793a\uff1a<\/p><p><img src=\"https:\/\/sunpe.github.io\/images\/golang_stack_and_pointer\/6.png\" alt=\"\">\u56fe 6<\/p><p>\u7a0b\u5e8f 2 \u7684\u5b8c\u6574\u8f93\u51fa\uff1a<\/p><div class=\"highlight\"><pre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"><code class=\"language-go\" data-lang=\"go\"><span style=\"display:flex;\"><span><span style=\"color:#a6e22e\">count<\/span>: <span style=\"color:#a6e22e\">Value<\/span> <span style=\"color:#a6e22e\">Of<\/span>[ <span style=\"color:#ae81ff\">10<\/span> ] <span style=\"color:#a6e22e\">Addr<\/span> <span style=\"color:#a6e22e\">Of<\/span>[ <span style=\"color:#ae81ff\">0x10429fa4<\/span> ]<\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#a6e22e\">inc<\/span>: <span style=\"color:#a6e22e\">Value<\/span> <span style=\"color:#a6e22e\">Of<\/span>[ <span style=\"color:#ae81ff\">0x10429fa4<\/span> ] <span style=\"color:#a6e22e\">Addr<\/span> <span style=\"color:#a6e22e\">Of<\/span>[ <span style=\"color:#ae81ff\">0x10429f98<\/span> ] <span style=\"color:#a6e22e\">Value<\/span> <span style=\"color:#a6e22e\">Points<\/span> <span style=\"color:#a6e22e\">To<\/span>[ <span style=\"color:#ae81ff\">11<\/span> ]<\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#a6e22e\">count<\/span>: <span style=\"color:#a6e22e\">Value<\/span> <span style=\"color:#a6e22e\">Of<\/span>[ <span style=\"color:#ae81ff\">11<\/span> ] <span style=\"color:#a6e22e\">Addr<\/span> <span style=\"color:#a6e22e\">Of<\/span>[ <span style=\"color:#ae81ff\">0x10429fa4<\/span> ]<\/span><\/span><\/code><\/pre><\/div><p>\u53ef\u4ee5\u770b\u5230\uff0cinc \u6307\u9488\u53d8\u91cf\u7684\u503c\u548c count \u53d8\u91cf\u7684\u5730\u5740\u503c\u76f8\u540c\uff0c\u901a\u8fc7\u6307\u9488\u7c7b\u578b\u53ef\u4ee5\u95f4\u63a5\u7684\u8bbf\u95ee\u6808\u7a7a\u95f4\u5916\u7684\u5185\u5b58\uff0cincrement \u51fd\u6570\u901a\u8fc7\u6307\u9488\u4fee\u6539\u4e86 inc \u6307\u9488\u53d8\u91cf\u6307\u5411\u7684\u503c\uff08\u4e5f\u5c31\u662f count \u53d8\u91cf\uff09\uff0c\u5f53 main \u51fd\u6570\u91cd\u65b0\u83b7\u5f97\u63a7\u5236\u6743\u540e\uff0c\u5c31\u53ef\u4ee5\u8bfb\u53d6\u5230 count \u53d8\u91cf\u7684\u65b0\u503c\u3002<\/p><h2 id=\"\u6307\u9488\u53d8\u91cf\u5e76\u4e0d\u7279\u522b\">\u6307\u9488\u53d8\u91cf\u5e76\u4e0d\u7279\u522b<\/h2><p>\u6307\u9488\u53d8\u91cf\u548c\u5176\u4ed6\u53d8\u91cf\u4e00\u6837\uff0c\u5e76\u4e0d\u7279\u522b\uff0c\u540c\u6837\u9700\u8981\u5185\u5b58\u7a7a\u95f4\uff0c\u540c\u6837\u5b58\u50a8\u8fd9\u503c\u3002\u9664\u4e86\u6307\u9488\u7c7b\u578b\u6307\u5411\u7684\u7c7b\u578b\u548c\u6307\u9488\u7c7b\u578b\u5927\u5c0f\u76f8\u540c\u5916\uff0c\u552f\u4e00\u8ba9\u6211\u4eec\u611f\u5230\u7591\u60d1\u7684\u662f <code>*<\/code> \u5b57\u7b26\uff0c\u5728\u51fd\u6570 increment \u4e2d\uff0c<code>*<\/code> \u8868\u793a\u64cd\u4f5c\u7b26\uff0c\u8868\u793a\u6307\u9488\u89e3\u5f15\u7528\uff0c\u800c\u5728\u51fd\u6570\u58f0\u660e\u4e2d\u7528\u6765\u58f0\u660e\u6307\u9488\u7c7b\u578b\u53d8\u91cf\u3002\u5982\u679c\u53ef\u4ee5\u6124\u9752\u6307\u9488\u7c7b\u578b\u58f0\u660e\u548c\u6307\u9488\u89e3\u5f15\u7528\u64cd\u4f5c\uff0c\u5e94\u8be5\u5c31\u6ca1\u90a3\u4e48\u56f0\u60d1\u4e86\u3002<\/p><h2 id=\"\u603b\u7ed3\">\u603b\u7ed3<\/h2><p>\u8fd9\u7bc7\u6587\u7ae0\u63cf\u8ff0\u4e86\u6307\u9488\u80cc\u540e\u7684\u76ee\u7684\u4ee5\u53ca golang \u4e2d\u6808\u548c\u6307\u9488\u673a\u5236\u7684\u5de5\u4f5c\u65b9\u5f0f\uff0c\u8fd9\u662f\u7406\u89e3 golang \u8bed\u8a00\u673a\u5236\u3001\u8bbe\u8ba1\u54f2\u5b66\u7684\u7b2c\u4e00\u6b65\uff0c\u4e5f\u6709\u52a9\u4e8e\u5199\u51fa\u4e00\u81f4\u7684\u3001\u53ef\u8bfb\u6027\u597d\u7684\u4ee3\u7801\u3002<\/p><p>\u4ece\u8fd9\u7bc7\u6587\u7ae0\u6211\u4eec\u5b66\u5230\u4e86\uff1a<\/p><ul><li>\u5e27\u8fb9\u754c\u4e3a\u6bcf\u4e2a\u51fd\u6570\u63d0\u4f9b\u4e86\u72ec\u7acb\u7684\u5185\u5b58\u7a7a\u95f4\uff0c\u51fd\u6570\u5728\u81ea\u5df1\u7684\u5e27\u8fb9\u754c\u5185\u6267\u884c<\/li><li>\u5982\u679c\u51fd\u6570\u88ab\u8c03\u7528\uff0c\u4f1a\u5b58\u5728\u4e24\u4e2a\u6808\u7a7a\u95f4\u7684\u8f6c\u6362<\/li><li>\u503c\u4f20\u9012\uff08by value\uff09\u7684\u597d\u5904\u662f\u53ef\u8bfb\u6027\u9ad8<\/li><li>\u6808\u7a7a\u95f4\u5f88\u91cd\u8981\uff0c\u6808\u4e3a\u5e27\u8fb9\u754c\u63d0\u4f9b\u7269\u7406\u7a7a\u95f4<\/li><li>\u5728\u6d3b\u8dc3\u6808\u5e27\u4ee5\u4e0b\u7684\u6808\u7a7a\u95f4\u662f\u4e0d\u53ef\u7528\u7684\uff0c\u53ea\u6709\u6d3b\u8dc3\u6808\u5e27\u548c\u5b83\u4ee5\u4e0a\u7684\u6808\u7a7a\u95f4\u53ef\u7528<\/li><li>\u51fd\u6570\u8c03\u7528\u610f\u5473\u7740 goroutine \u9700\u8981\u5728\u6808\u7a7a\u95f4\u4e0a\u5f00\u8f9f\u4e00\u5757\u65b0\u7684\u6808\u5e27<\/li><li>\u5728\u51fd\u6570\u8c03\u7528\u65f6\uff0c\u5982\u679c\u88ab\u5206\u914d\u7684\u6808\u7528\u5230\u4e86\u6808\u7a7a\u95f4\uff0c\u76f8\u5e94\u7684\u6808\u7a7a\u95f4\u624d\u4f1a\u88ab\u521d\u59cb\u5316<\/li><li>\u6307\u9488\u662f\u7528\u6765\u5171\u4eab\u53d8\u91cf\u7684\uff0c\u4ee5\u4fbf\u4e8e\u51fd\u6570\u53ef\u4ee5\u95f4\u63a5\u8bbf\u95ee\u81ea\u5df1\u6808\u5e27\u5916\u7684\u53d8\u91cf<\/li><li>\u6240\u6709\u7c7b\u578b\u90fd\u53ef\u4ee5\u901a\u8fc7\u5176\u6307\u9488\u7c7b\u578b\u6765\u5171\u4eab<\/li><li>\u6307\u9488\u7c7b\u578b\u53d8\u91cf\u5141\u8bb8\u95f4\u63a5\u8bbf\u95ee\u51fd\u6570\u6808\u5e27\u5916\u7684\u5185\u5b58\u7a7a\u95f4<\/li><li>\u6307\u9488\u53d8\u91cf\u548c\u5176\u4ed6\u53d8\u91cf\u4e00\u6837\uff0c\u5e76\u4e0d\u7279\u522b\uff0c\u5360\u7528\u5185\u5b58\u7a7a\u95f4\uff0c\u5e76\u4e14\u5b58\u653e\u503c<\/li><\/ul><h2 id=\"\u53c2\u8003\u8d44\u6599\">\u53c2\u8003\u8d44\u6599<\/h2><ol><li><a href=\"https:\/\/www.ardanlabs.com\/blog\/2017\/05\/language-mechanics-on-stacks-and-pointers.html\">https:\/\/www.ardanlabs.com\/blog\/2017\/05\/language-mechanics-on-stacks-and-pointers.html<\/a><\/li><\/ol>"},{"title":"\u7406\u89e3Golang channel","link":"https:\/\/sunpe.github.io\/posts\/2020-07-03-golang-channel\/","pubDate":"Fri, 03 Jul 2020 22:00:00 +0800","guid":"https:\/\/sunpe.github.io\/posts\/2020-07-03-golang-channel\/","description":"<p>channel \u662f golang \u7684\u6838\u5fc3\u7279\u6027\u4e4b\u4e00\uff0c\u63d0\u4f9b\u4e86 goroutine \u901a\u4fe1\u7684\u673a\u5236\uff0c\u7b80\u5316\u4e86\u5e76\u53d1\u6a21\u5f0f\u3002<\/p><h2 id=\"csp\">CSP<\/h2><p>golang \u901a\u8fc7 goroutine \u548c channel \u90e8\u5206\u5b9e\u73b0\u4e86 CSP\uff08Communicating Sequential Process\uff09\u3002CSP \u5373\u901a\u4fe1\u987a\u5e8f\u8fdb\u7a0b\uff0c\u662f Tony Hoare \u4e8e 1977 \u5e74\u63d0\u51fa\u7684\u4e00\u79cd\u5e76\u53d1\u6a21\u578b\u3002CSP \u6a21\u578b\u7531\u5e76\u53d1\u6267\u884c\u7684\u5b9e\u4f53\uff08\u7ebf\u7a0b\u6216\u8005\u8fdb\u7a0b\uff09\u6240\u7ec4\u6210\uff0c\u5b9e\u4f53\u4e4b\u95f4\u901a\u8fc7\u53d1\u9001\u6d88\u606f\u8fdb\u884c\u901a\u4fe1\uff0c\u8fd9\u91cc\u53d1\u9001\u6d88\u606f\u65f6\u4f7f\u7528\u7684\u5c31\u662f\u901a\u9053\uff0c\u6216\u8005\u53eb channel\u3002CSP \u6a21\u578b\u7684\u5173\u952e\u662f\u5173\u6ce8 channel\uff0c\u800c\u4e0d\u5173\u6ce8\u53d1\u9001\u6d88\u606f\u7684\u5b9e\u4f53\uff0cgolang \u4e2d goroutine \u5bf9\u5e94 CSP \u4e2d\u5e76\u53d1\u6267\u884c\u7684\u5b9e\u4f53\uff0cchannel \u4e5f\u5c31\u5bf9\u5e94\u7740 CSP \u4e2d\u7684 channel\u3002<\/p><h2 id=\"channel\u57fa\u7840\">channel\u57fa\u7840<\/h2><p>channel \u5e95\u5c42\u662f hchan \u7ed3\u6784\u4f53\uff0c\u6e90\u7801\u5728 src\/runtime\/chan.go\u3002<\/p><div class=\"highlight\"><pre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"><code class=\"language-go\" data-lang=\"go\"><span style=\"display:flex;\"><span><span style=\"color:#75715e\">\/\/ \u7a0b\u5e8f 1<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span><span style=\"color:#66d9ef\">type<\/span> <span style=\"color:#a6e22e\">hchan<\/span> <span style=\"color:#66d9ef\">struct<\/span> {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">qcount<\/span> <span style=\"color:#66d9ef\">uint<\/span> <span style=\"color:#75715e\">\/\/ total data in the queue<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span> <span style=\"color:#a6e22e\">dataqsiz<\/span> <span style=\"color:#66d9ef\">uint<\/span> <span style=\"color:#75715e\">\/\/ \u961f\u5217\u5927\u5c0f, \u503c\u5927\u4e8e0\u8868\u793a\u6709\u7f13\u51b2, \u503c\u7b49\u4e8e0\u8868\u793a\u6ca1\u6709\u7f13\u51b2<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span> <span style=\"color:#a6e22e\">buf<\/span> <span style=\"color:#a6e22e\">unsafe<\/span>.<span style=\"color:#a6e22e\">Pointer<\/span> <span style=\"color:#75715e\">\/\/ \u7f13\u51b2\u961f\u5217buffer\u7684\u6307\u9488<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span> <span style=\"color:#a6e22e\">elemsize<\/span> <span style=\"color:#66d9ef\">uint16<\/span> <span style=\"color:#75715e\">\/\/ \u5355\u4e2a\u5143\u7d20\u5927\u5c0f<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span> <span style=\"color:#a6e22e\">closed<\/span> <span style=\"color:#66d9ef\">uint32<\/span> <span style=\"color:#75715e\">\/\/ \u5173\u95ed\u6807\u8bc6\u7b26<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span> <span style=\"color:#a6e22e\">elemtype<\/span> <span style=\"color:#f92672\">*<\/span><span style=\"color:#a6e22e\">_type<\/span> <span style=\"color:#75715e\">\/\/ \u5143\u7d20\u7c7b\u578b<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span> <span style=\"color:#a6e22e\">sendx<\/span> <span style=\"color:#66d9ef\">uint<\/span> <span style=\"color:#75715e\">\/\/ \u53d1\u9001\u6570\u636e\u7d22\u5f15<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span> <span style=\"color:#a6e22e\">recvx<\/span> <span style=\"color:#66d9ef\">uint<\/span> <span style=\"color:#75715e\">\/\/ \u63a5\u6536\u6570\u636e\u7d22\u5f15<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span> <span style=\"color:#a6e22e\">recvq<\/span> <span style=\"color:#a6e22e\">waitq<\/span> <span style=\"color:#75715e\">\/\/ \u7b49\u5f85\u63a5\u6536\u6570\u636e\u7684sudog(goroutine)\u94fe\u8868<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span> <span style=\"color:#a6e22e\">sendq<\/span> <span style=\"color:#a6e22e\">waitq<\/span> <span style=\"color:#75715e\">\/\/ \u7b49\u5f85\u53d1\u9001\u6570\u636e\u7684sudog(goroutine)\u94fe\u8868<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span> <span style=\"color:#75715e\">\/\/ lock protects all fields in hchan, as well as several<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span> <span style=\"color:#75715e\">\/\/ fields in sudogs blocked on this channel.<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span> <span style=\"color:#75715e\">\/\/<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span> <span style=\"color:#75715e\">\/\/ Do not change another G&#39;s status while holding this lock<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span> <span style=\"color:#75715e\">\/\/ (in particular, do not ready a G), as this can deadlock<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span> <span style=\"color:#75715e\">\/\/ with stack shrinking.<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span> <span style=\"color:#a6e22e\">lock<\/span> <span style=\"color:#a6e22e\">mutex<\/span><\/span><\/span><span style=\"display:flex;\"><span>}<\/span><\/span><\/code><\/pre><\/div><p>sudog \u8868\u793a\u5728\u7b49\u5f85\u961f\u5217\u4e2d\u7684 goroutine\u3002<\/p><div class=\"highlight\"><pre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"><code class=\"language-go\" data-lang=\"go\"><span style=\"display:flex;\"><span><span style=\"color:#75715e\">\/\/ \u7a0b\u5e8f 2<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span><span style=\"color:#66d9ef\">type<\/span> <span style=\"color:#a6e22e\">sudog<\/span> <span style=\"color:#66d9ef\">struct<\/span> {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#75715e\">\/\/ The following fields are protected by the hchan.lock of the<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span> <span style=\"color:#75715e\">\/\/ channel this sudog is blocking on. shrinkstack depends on<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span> <span style=\"color:#75715e\">\/\/ this for sudogs involved in channel ops.<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span> <span style=\"color:#a6e22e\">g<\/span> <span style=\"color:#f92672\">*<\/span><span style=\"color:#a6e22e\">g<\/span><\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#75715e\">\/\/ isSelect indicates g is participating in a select, so<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span> <span style=\"color:#75715e\">\/\/ g.selectDone must be CAS&#39;d to win the wake-up race.<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span> <span style=\"color:#a6e22e\">isSelect<\/span> <span style=\"color:#66d9ef\">bool<\/span><\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">next<\/span> <span style=\"color:#f92672\">*<\/span><span style=\"color:#a6e22e\">sudog<\/span><\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">prev<\/span> <span style=\"color:#f92672\">*<\/span><span style=\"color:#a6e22e\">sudog<\/span><\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">elem<\/span> <span style=\"color:#a6e22e\">unsafe<\/span>.<span style=\"color:#a6e22e\">Pointer<\/span> <span style=\"color:#75715e\">\/\/ data element (may point to stack)<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span> <span style=\"color:#75715e\">\/\/ The following fields are never accessed concurrently.<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span> <span style=\"color:#75715e\">\/\/ For channels, waitlink is only accessed by g.<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span> <span style=\"color:#75715e\">\/\/ For semaphores, all fields (including the ones above)<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span> <span style=\"color:#75715e\">\/\/ are only accessed when holding a semaRoot lock.<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span> <span style=\"color:#a6e22e\">acquiretime<\/span> <span style=\"color:#66d9ef\">int64<\/span><\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">releasetime<\/span> <span style=\"color:#66d9ef\">int64<\/span><\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">ticket<\/span> <span style=\"color:#66d9ef\">uint32<\/span><\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">parent<\/span> <span style=\"color:#f92672\">*<\/span><span style=\"color:#a6e22e\">sudog<\/span> <span style=\"color:#75715e\">\/\/ semaRoot binary tree<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span> <span style=\"color:#a6e22e\">waitlink<\/span> <span style=\"color:#f92672\">*<\/span><span style=\"color:#a6e22e\">sudog<\/span> <span style=\"color:#75715e\">\/\/ g.waiting list or semaRoot<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span> <span style=\"color:#a6e22e\">waittail<\/span> <span style=\"color:#f92672\">*<\/span><span style=\"color:#a6e22e\">sudog<\/span> <span style=\"color:#75715e\">\/\/ semaRoot<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span> <span style=\"color:#a6e22e\">c<\/span> <span style=\"color:#f92672\">*<\/span><span style=\"color:#a6e22e\">hchan<\/span> <span style=\"color:#75715e\">\/\/ channel<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span>}<\/span><\/span><\/code><\/pre><\/div><h2 id=\"\u521b\u5efachannel\">\u521b\u5efachannel<\/h2><p>\u901a\u8fc7\u5185\u7f6e\u7684 make \u51fd\u6570\u53ef\u4ee5\u521b\u5efa\u5e26\u7f13\u51b2\u533a\u6216\u4e0d\u5e26\u7f13\u51b2\u533a\u7684 channel\uff1a<\/p><div class=\"highlight\"><pre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"><code class=\"language-go\" data-lang=\"go\"><span style=\"display:flex;\"><span><span style=\"color:#75715e\">\/\/ \u7a0b\u5e8f 3<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span><span style=\"color:#a6e22e\">ch<\/span> <span style=\"color:#f92672\">:=<\/span> make(<span style=\"color:#66d9ef\">chan<\/span> <span style=\"color:#a6e22e\">Task<\/span>) <span style=\"color:#75715e\">\/\/ \u521b\u5efa\u975e\u7f13\u51b2channel<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span><span style=\"color:#a6e22e\">ch<\/span> <span style=\"color:#f92672\">:=<\/span> make(<span style=\"color:#66d9ef\">chan<\/span> <span style=\"color:#a6e22e\">Task<\/span>, <span style=\"color:#ae81ff\">3<\/span>) <span style=\"color:#75715e\">\/\/ \u521b\u5efa\u7f13\u51b2channel<\/span><\/span><\/span><\/code><\/pre><\/div><p><img src=\"https:\/\/sunpe.github.io\/images\/golang_channel\/1.png\" alt=\"\"><\/p><p>make \u51fd\u6570\u521b\u5efa\u5e76\u5b9e\u4f8b\u5316 hchan \u7ed3\u6784\u4f53\uff0c\u5e76\u8fd4\u56de hchan \u7684\u6307\u9488\uff0c\u6240\u4ee5\u6211\u4eec\u53ef\u4ee5\u76f4\u63a5\u5c06 channel \u4f5c\u4e3a\u65b9\u6cd5\u7684\u53c2\u6570\u3002<\/p><p><img src=\"https:\/\/sunpe.github.io\/images\/golang_channel\/2.png\" alt=\"\"><\/p><p>\u521b\u5efa channel \u7684\u51fd\u6570\u662f <code>func makechan(t *chantype, size int) *hchan<\/code><\/p><div class=\"highlight\"><pre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"><code class=\"language-go\" data-lang=\"go\"><span style=\"display:flex;\"><span><span style=\"color:#75715e\">\/\/ \u7a0b\u5e8f 4<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span><span style=\"color:#66d9ef\">func<\/span> <span style=\"color:#a6e22e\">makechan<\/span>(<span style=\"color:#a6e22e\">t<\/span> <span style=\"color:#f92672\">*<\/span><span style=\"color:#a6e22e\">chantype<\/span>, <span style=\"color:#a6e22e\">size<\/span> <span style=\"color:#66d9ef\">int<\/span>) <span style=\"color:#f92672\">*<\/span><span style=\"color:#a6e22e\">hchan<\/span> {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">elem<\/span> <span style=\"color:#f92672\">:=<\/span> <span style=\"color:#a6e22e\">t<\/span>.<span style=\"color:#a6e22e\">elem<\/span><\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#75715e\">\/\/ \u5b89\u5168\u68c0\u6d4b<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span> <span style=\"color:#75715e\">\/\/ compiler checks this but be safe.<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span> <span style=\"color:#66d9ef\">if<\/span> <span style=\"color:#a6e22e\">elem<\/span>.<span style=\"color:#a6e22e\">size<\/span> <span style=\"color:#f92672\">&gt;=<\/span> <span style=\"color:#ae81ff\">1<\/span><span style=\"color:#f92672\">&lt;&lt;<\/span><span style=\"color:#ae81ff\">16<\/span> {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">throw<\/span>(<span style=\"color:#e6db74\">&#34;makechan: invalid channel element type&#34;<\/span>)<\/span><\/span><span style=\"display:flex;\"><span> }<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">if<\/span> <span style=\"color:#a6e22e\">hchanSize<\/span><span style=\"color:#f92672\">%<\/span><span style=\"color:#a6e22e\">maxAlign<\/span> <span style=\"color:#f92672\">!=<\/span> <span style=\"color:#ae81ff\">0<\/span> <span style=\"color:#f92672\">||<\/span> <span style=\"color:#a6e22e\">elem<\/span>.<span style=\"color:#a6e22e\">align<\/span> &gt; <span style=\"color:#a6e22e\">maxAlign<\/span> {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">throw<\/span>(<span style=\"color:#e6db74\">&#34;makechan: bad alignment&#34;<\/span>)<\/span><\/span><span style=\"display:flex;\"><span> }<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">mem<\/span>, <span style=\"color:#a6e22e\">overflow<\/span> <span style=\"color:#f92672\">:=<\/span> <span style=\"color:#a6e22e\">math<\/span>.<span style=\"color:#a6e22e\">MulUintptr<\/span>(<span style=\"color:#a6e22e\">elem<\/span>.<span style=\"color:#a6e22e\">size<\/span>, uintptr(<span style=\"color:#a6e22e\">size<\/span>))<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">if<\/span> <span style=\"color:#a6e22e\">overflow<\/span> <span style=\"color:#f92672\">||<\/span> <span style=\"color:#a6e22e\">mem<\/span> &gt; <span style=\"color:#a6e22e\">maxAlloc<\/span><span style=\"color:#f92672\">-<\/span><span style=\"color:#a6e22e\">hchanSize<\/span> <span style=\"color:#f92672\">||<\/span> <span style=\"color:#a6e22e\">size<\/span> &lt; <span style=\"color:#ae81ff\">0<\/span> {<\/span><\/span><span style=\"display:flex;\"><span> panic(<span style=\"color:#a6e22e\">plainError<\/span>(<span style=\"color:#e6db74\">&#34;makechan: size out of range&#34;<\/span>))<\/span><\/span><span style=\"display:flex;\"><span> }<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">var<\/span> <span style=\"color:#a6e22e\">c<\/span> <span style=\"color:#f92672\">*<\/span><span style=\"color:#a6e22e\">hchan<\/span><\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">switch<\/span> {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">case<\/span> <span style=\"color:#a6e22e\">mem<\/span> <span style=\"color:#f92672\">==<\/span> <span style=\"color:#ae81ff\">0<\/span>:<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#75715e\">\/\/ \u5982\u679c\u961f\u5217\u6216\u5143\u7d20\u5927\u5c0f\u662f0\uff0c\u5219\u4e0d\u5206\u914dbuffer<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span> <span style=\"color:#75715e\">\/\/ Queue or element size is zero.<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span> <span style=\"color:#a6e22e\">c<\/span> = (<span style=\"color:#f92672\">*<\/span><span style=\"color:#a6e22e\">hchan<\/span>)(<span style=\"color:#a6e22e\">mallocgc<\/span>(<span style=\"color:#a6e22e\">hchanSize<\/span>, <span style=\"color:#66d9ef\">nil<\/span>, <span style=\"color:#66d9ef\">true<\/span>))<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#75715e\">\/\/ \u5c06buf\u6307\u5411\u81ea\u8eab\uff0c\u4e0d\u5206\u914d\u7f13\u5b58\u7a7a\u95f4<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span> <span style=\"color:#75715e\">\/\/ Race detector uses this location for synchronization.<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span> <span style=\"color:#a6e22e\">c<\/span>.<span style=\"color:#a6e22e\">buf<\/span> = <span style=\"color:#a6e22e\">c<\/span>.<span style=\"color:#a6e22e\">raceaddr<\/span>()<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">case<\/span> <span style=\"color:#a6e22e\">elem<\/span>.<span style=\"color:#a6e22e\">ptrdata<\/span> <span style=\"color:#f92672\">==<\/span> <span style=\"color:#ae81ff\">0<\/span>:<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#75715e\">\/\/ \u5982\u679c\u5143\u7d20\u4e0d\u5305\u542b\u6307\u9488\uff0c\u5219\u5206\u914d\u4e00\u6574\u5757\u5185\u5b58\uff0c\u7528\u4e8ehchan\u548cbuf<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span> <span style=\"color:#75715e\">\/\/ Elements do not contain pointers.<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span> <span style=\"color:#75715e\">\/\/ Allocate hchan and buf in one call.<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span> <span style=\"color:#a6e22e\">c<\/span> = (<span style=\"color:#f92672\">*<\/span><span style=\"color:#a6e22e\">hchan<\/span>)(<span style=\"color:#a6e22e\">mallocgc<\/span>(<span style=\"color:#a6e22e\">hchanSize<\/span><span style=\"color:#f92672\">+<\/span><span style=\"color:#a6e22e\">mem<\/span>, <span style=\"color:#66d9ef\">nil<\/span>, <span style=\"color:#66d9ef\">true<\/span>))<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">c<\/span>.<span style=\"color:#a6e22e\">buf<\/span> = <span style=\"color:#a6e22e\">add<\/span>(<span style=\"color:#a6e22e\">unsafe<\/span>.<span style=\"color:#a6e22e\">Pointer<\/span>(<span style=\"color:#a6e22e\">c<\/span>), <span style=\"color:#a6e22e\">hchanSize<\/span>)<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">default<\/span>:<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#75715e\">\/\/ \u5982\u679c\u662f\u6307\u9488\u7c7b\u578b\uff0c\u6b63\u5e38\u521b\u5efa\u7ed3\u6784\u4f53\uff0cbuf\u5355\u72ec\u5206\u914d\u7a7a\u95f4<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span> <span style=\"color:#75715e\">\/\/ Elements contain pointers.<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span> <span style=\"color:#a6e22e\">c<\/span> = new(<span style=\"color:#a6e22e\">hchan<\/span>)<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">c<\/span>.<span style=\"color:#a6e22e\">buf<\/span> = <span style=\"color:#a6e22e\">mallocgc<\/span>(<span style=\"color:#a6e22e\">mem<\/span>, <span style=\"color:#a6e22e\">elem<\/span>, <span style=\"color:#66d9ef\">true<\/span>)<\/span><\/span><span style=\"display:flex;\"><span> }<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#75715e\">\/\/ \u8bbe\u7f6echannel\u7684\u5c5e\u6027<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span> <span style=\"color:#a6e22e\">c<\/span>.<span style=\"color:#a6e22e\">elemsize<\/span> = uint16(<span style=\"color:#a6e22e\">elem<\/span>.<span style=\"color:#a6e22e\">size<\/span>)<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">c<\/span>.<span style=\"color:#a6e22e\">elemtype<\/span> = <span style=\"color:#a6e22e\">elem<\/span><\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">c<\/span>.<span style=\"color:#a6e22e\">dataqsiz<\/span> = uint(<span style=\"color:#a6e22e\">size<\/span>)<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">if<\/span> <span style=\"color:#a6e22e\">debugChan<\/span> {<\/span><\/span><span style=\"display:flex;\"><span> print(<span style=\"color:#e6db74\">&#34;makechan: chan=&#34;<\/span>, <span style=\"color:#a6e22e\">c<\/span>, <span style=\"color:#e6db74\">&#34;; elemsize=&#34;<\/span>, <span style=\"color:#a6e22e\">elem<\/span>.<span style=\"color:#a6e22e\">size<\/span>, <span style=\"color:#e6db74\">&#34;; <\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#e6db74\"> dataqsiz=&#34;<\/span>, <span style=\"color:#a6e22e\">size<\/span>, <span style=\"color:#e6db74\">&#34;\\n&#34;<\/span>)<\/span><\/span><span style=\"display:flex;\"><span> }<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">return<\/span> <span style=\"color:#a6e22e\">c<\/span><\/span><\/span><span style=\"display:flex;\"><span>}<\/span><\/span><\/code><\/pre><\/div><h2 id=\"\u4f7f\u7528channel\">\u4f7f\u7528channel<\/h2><h3 id=\"\u53d1\u9001\u548c\u63a5\u6536\u6570\u636e\u8fc7\u7a0b\">\u53d1\u9001\u548c\u63a5\u6536\u6570\u636e\u8fc7\u7a0b<\/h3><p><img src=\"https:\/\/sunpe.github.io\/images\/golang_channel\/3.png\" alt=\"\"><\/p><p>G1 \u662f\u751f\u4ea7\u8005\uff0cG2 \u662f\u6d88\u8d39\u8005\uff0c<code>ch<\/code> \u662f\u5bb9\u91cf\u4e3a 3 \u7684\u5e26\u7f13\u51b2 channel\uff0c\u521d\u59cb\u7684\u65f6\u5019 <code>hchan<\/code> \u7ed3\u6784\u4f53\u7684 buf \u4e3a\u7a7a\uff0c<code>sendx<\/code> \u548c <code>recvx<\/code> \u90fd\u4e3a0\u3002G1 \u83b7\u53d6\u9501\uff0c\u5e76\u5c06 task \u53d1\u9001\u5230 channel\uff0c\u5e76\u589e\u52a0 sendx\uff0c\u53d1\u9001\u5230 channel \u4e2d\u7684\u6570\u636e\u5176\u5b9e\u662ftask\u7684\u526f\u672c\u3002\u7136\u540e G2 \u83b7\u53d6\u9501\uff0c\u5e76\u4ece channel \u4e2d\u83b7\u53d6\u6570\u636e\uff0c\u5e76\u589e\u52a0 recvx\uff0c\u53d6\u5230\u7684\u6570\u636e\u4f9d\u65e7\u662f task \u7684\u526f\u672c\u3002channel \u53d7\u4e92\u65a5\u9501\u4fdd\u62a4\uff0c\u4f20\u9012\u526f\u672c\u53ef\u4ee5\u4fdd\u8bc1\u6570\u636e\u7684\u5b89\u5168\u3002<\/p><p>\u6574\u4e2a\u8fc7\u7a0b\u6ca1\u6709\u5185\u5b58\u5171\u4eab\uff08shared memory\uff09\uff0c\u5145\u5206\u4f53\u73b0\u4e86 CSP \u7684 do not communicate by sharing memory; instead, share memory by communicating\u3002<\/p><h3 id=\"blockingunblocking\u8fc7\u7a0b\">blocking\/unblocking\u8fc7\u7a0b<\/h3><p><img src=\"https:\/\/sunpe.github.io\/images\/golang_channel\/4.png\" alt=\"\"><\/p><p>\u5982\u679c G2 \u7684\u8bfb\u53d6\u901f\u5ea6\u6bd4 G1 \u7684\u5199\u5165\u901f\u5ea6\u6162\uff0c\u90a3\u4e48\u4e00\u6bb5\u65f6\u95f4\u4e4b\u540e\uff0cchanne l\u7684 buffer \u4f1a\u88ab\u585e\u6ee1\u3002\u5f53 channel \u6ee1\u4e86\u4e4b\u540e G1 \u7ee7\u7eed\u5f80 channel \u4e2d\u53d1\u9001\u6570\u636e\u3002G1 \u4f1a block\u3002\u57fa\u4e8e golang \u7684\u8c03\u5ea6\u6a21\u578b\uff0c\u6682\u505c\u7684\u5176\u5b9e\u662f goroutine\uff0c\u800c\u4e0d\u662f os \u7ebf\u7a0b\u3002<\/p><p><img src=\"https:\/\/sunpe.github.io\/images\/golang_channel\/5.png\" alt=\"\"><\/p><p>\u5982\u679c\u9700\u8981 block G1\uff0cG1 \u4f1a\u521b\u5efa\u4e00\u4e2a sudog\uff0c\u653e\u5230 channel \u7684 <code>sendq<\/code> \u4e2d\uff0c\u5f53 channel \u7684 buffer \u6709\u4e86\u7a7a\u95f4\u65f6\uff0cG2 \u4f1a\u4ece <code>sendq<\/code> \u4e2d pop \u51fa <code>sudog<\/code>\uff0c\u53d6\u51fa elem\uff0c\u5c06 G1 \u72b6\u6001\u53d8\u6210 <code>runnable<\/code>\uff0c\u8c03\u5ea6\u5668\u5c31\u53ef\u4ee5\u518d\u6b21\u8c03\u5ea6 G1 \u4e86\u3002<\/p><p><img src=\"https:\/\/sunpe.github.io\/images\/golang_channel\/6.png\" alt=\"\"><\/p><p>\u5982\u679c G2 \u5148\u8fd0\u884c\uff0c\u8fd9\u65f6\u5019 channel \u4e2d\u6ca1\u6709\u6570\u636e\uff0cG2 \u4ece\u4e00\u4e2a\u7a7a\u7684 channel \u4e2d\u8bfb\u53d6\u6570\u636e\uff0cG2 \u4e5f\u4f1a block\uff0c\u548c G1 block \u7684\u903b\u8f91\u76f8\u4f3c\uff0cG2 \u4e5f\u4f1a\u521b\u5efa <code>sudog<\/code>\uff0c\u7136\u540e\u653e\u5230 <code>recvq<\/code> \u4e2d\u3002<\/p><p><img src=\"https:\/\/sunpe.github.io\/images\/golang_channel\/7.png\" alt=\"\"><\/p><p>\u5f53\u6b64\u65f6 G1 \u5411 channel \u53d1\u9001\u6570\u636e\uff0cruntime \u4f1a\u76f4\u63a5\u5c06 G1 \u8981\u53d1\u9001\u7684\u6570\u636e copy \u5230 G2 \u7684\u6808\u7a7a\u95f4\uff0c\u770b\u8d77\u6765\u5c31\u597d\u50cf\u662f G1 \u76f4\u63a5\u5c06\u6570\u636e\u53d1\u9001\u7ed9\u4e86 G2\uff0c\u8fd9\u4e2a\u8fc7\u7a0b\u53eb\u300cdirect send\u300d\uff0c\u6574\u4e2a\u8fc7\u7a0b G1 \u548c G2 \u90fd\u4e0d\u9700\u8981\u518d\u83b7\u53d6\u9501\u548c\u8bfb\u5199 buffer\u3002<\/p><p><img src=\"https:\/\/sunpe.github.io\/images\/golang_channel\/8.png\" alt=\"\"><\/p><p>\u975e\u7f13\u51b2 channel \u603b\u662f\u300cdirect send\u300d\u7684\uff0c\u5982\u679c receiver \u5148\u8fd0\u884c\uff0csender \u76f4\u63a5\u5c06\u6570\u636e\u5199\u5165 receiver \u7684\u6808\u7a7a\u95f4\uff0c\u5982\u679c sennder \u5148\u8fd0\u884c\uff0creceiver \u76f4\u63a5\u4ece sudog \u63a5\u6536\u6570\u636e\u3002<\/p><h2 id=\"\u5411channel\u53d1\u9001\u6570\u636e\u7684\u6e90\u7801\">\u5411channel\u53d1\u9001\u6570\u636e\u7684\u6e90\u7801<\/h2><p>\u53d1\u9001\u6570\u636e\u5bf9\u5e94\u7684\u65b9\u6cd5\u662f <code>func chansend(c *hchan, ep unsafe.Pointer, block bool, callerpc uintptr) bool<\/code>\u3002<\/p><ol><li>\u5982\u679c\u5411 nil channel \u53d1\u9001\u6570\u636e\uff0c\u4f1a\u4e00\u76f4block\uff1a<\/li><\/ol><div class=\"highlight\"><pre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"><code class=\"language-go\" data-lang=\"go\"><span style=\"display:flex;\"><span><span style=\"color:#75715e\">\/\/ \u7a0b\u5e8f 5<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span><span style=\"color:#66d9ef\">if<\/span> <span style=\"color:#a6e22e\">c<\/span> <span style=\"color:#f92672\">==<\/span> <span style=\"color:#66d9ef\">nil<\/span> {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">if<\/span> !<span style=\"color:#a6e22e\">block<\/span> {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">return<\/span> <span style=\"color:#66d9ef\">false<\/span><\/span><\/span><span style=\"display:flex;\"><span> }<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">gopark<\/span>(<span style=\"color:#66d9ef\">nil<\/span>, <span style=\"color:#66d9ef\">nil<\/span>, <span style=\"color:#a6e22e\">waitReasonChanSendNilChan<\/span>, <span style=\"color:#a6e22e\">traceEvGoStop<\/span>, <span style=\"color:#ae81ff\">2<\/span>)<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">throw<\/span>(<span style=\"color:#e6db74\">&#34;unreachable&#34;<\/span>)<\/span><\/span><span style=\"display:flex;\"><span>}<\/span><\/span><\/code><\/pre><\/div><p><code>gopark<\/code> \u8868\u793a\u5c06\u5f53\u524d goroutine \u4f11\u7720\uff0c\u4f46\u662f unlockf \u662f nil\uff0c\u6240\u4ee5 goroutine \u4f1a\u4e00\u76f4\u4f11\u7720\u3002\u5982\u679c\u6240\u6709 goroutine \u90fd\u5904\u4e8e\u4f11\u7720\u72b6\u6001\uff0c\u5728 runtime \u7684 <code>checkdead()<\/code> \u4f1a\u68c0\u6d4b\u5f02\u5e38\u60c5\u51b5, \u629b\u51fa <code>all goroutines are asleep - deadlock!<\/code><\/p><ol start=\"2\"><li>\u5982\u679c <code>recvq<\/code> \u4e2d\u6709\u7b49\u5f85\u7684 sudog\uff1a<\/li><\/ol><div class=\"highlight\"><pre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"><code class=\"language-go\" data-lang=\"go\"><span style=\"display:flex;\"><span><span style=\"color:#75715e\">\/\/ \u7a0b\u5e8f 6<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span><span style=\"color:#66d9ef\">if<\/span> <span style=\"color:#a6e22e\">sg<\/span> <span style=\"color:#f92672\">:=<\/span> <span style=\"color:#a6e22e\">c<\/span>.<span style=\"color:#a6e22e\">recvq<\/span>.<span style=\"color:#a6e22e\">dequeue<\/span>(); <span style=\"color:#a6e22e\">sg<\/span> <span style=\"color:#f92672\">!=<\/span> <span style=\"color:#66d9ef\">nil<\/span> {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#75715e\">\/\/ Found a waiting receiver. We pass the value we want to send<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span> <span style=\"color:#75715e\">\/\/ directly to the receiver, bypassing the channel buffer (if any).<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span> <span style=\"color:#a6e22e\">send<\/span>(<span style=\"color:#a6e22e\">c<\/span>, <span style=\"color:#a6e22e\">sg<\/span>, <span style=\"color:#a6e22e\">ep<\/span>, <span style=\"color:#66d9ef\">func<\/span>() { <span style=\"color:#a6e22e\">unlock<\/span>(<span style=\"color:#f92672\">&amp;<\/span><span style=\"color:#a6e22e\">c<\/span>.<span style=\"color:#a6e22e\">lock<\/span>) }, <span style=\"color:#ae81ff\">3<\/span>)<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">return<\/span> <span style=\"color:#66d9ef\">true<\/span><\/span><\/span><span style=\"display:flex;\"><span>}<\/span><\/span><\/code><\/pre><\/div><p>\u8fd9\u91cc\u76f4\u63a5\u5c06\u6570\u636e\u590d\u5236\u7ed9 receiver\uff0c\u5373\u4e0a\u6587\u63d0\u5230\u7684\u300cdirect send\u300d\u3002<\/p><ol start=\"3\"><li>\u5982\u679c buffered channel \u5e76\u4e14 buffer \u6709\u7a7a\u95f4\uff1a<\/li><\/ol><div class=\"highlight\"><pre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"><code class=\"language-go\" data-lang=\"go\"><span style=\"display:flex;\"><span><span style=\"color:#75715e\">\/\/ \u7a0b\u5e8f 7<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span><span style=\"color:#66d9ef\">if<\/span> <span style=\"color:#a6e22e\">c<\/span>.<span style=\"color:#a6e22e\">qcount<\/span> &lt; <span style=\"color:#a6e22e\">c<\/span>.<span style=\"color:#a6e22e\">dataqsiz<\/span> {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#75715e\">\/\/ Space is available in the channel buffer. Enqueue the element to send.<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span> <span style=\"color:#a6e22e\">qp<\/span>: = <span style=\"color:#a6e22e\">chanbuf<\/span>(<span style=\"color:#a6e22e\">c<\/span>, <span style=\"color:#a6e22e\">c<\/span>.<span style=\"color:#a6e22e\">sendx<\/span>)<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">if<\/span> <span style=\"color:#a6e22e\">raceenabled<\/span> {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">raceacquire<\/span>(<span style=\"color:#a6e22e\">qp<\/span>)<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">racerelease<\/span>(<span style=\"color:#a6e22e\">qp<\/span>)<\/span><\/span><span style=\"display:flex;\"><span> }<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">typedmemmove<\/span>(<span style=\"color:#a6e22e\">c<\/span>.<span style=\"color:#a6e22e\">elemtype<\/span>, <span style=\"color:#a6e22e\">qp<\/span>, <span style=\"color:#a6e22e\">ep<\/span>)<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">c<\/span>.<span style=\"color:#a6e22e\">sendx<\/span><span style=\"color:#f92672\">++<\/span><\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">if<\/span> <span style=\"color:#a6e22e\">c<\/span>.<span style=\"color:#a6e22e\">sendx<\/span> <span style=\"color:#f92672\">==<\/span> <span style=\"color:#a6e22e\">c<\/span>.<span style=\"color:#a6e22e\">dataqsiz<\/span> {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">c<\/span>.<span style=\"color:#a6e22e\">sendx<\/span> = <span style=\"color:#ae81ff\">0<\/span><\/span><\/span><span style=\"display:flex;\"><span> }<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">c<\/span>.<span style=\"color:#a6e22e\">qcount<\/span><span style=\"color:#f92672\">++<\/span><\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">unlock<\/span>( <span style=\"color:#f92672\">&amp;<\/span> <span style=\"color:#a6e22e\">c<\/span>.<span style=\"color:#a6e22e\">lock<\/span>)<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">return<\/span> <span style=\"color:#66d9ef\">true<\/span><\/span><\/span><span style=\"display:flex;\"><span>}<\/span><\/span><\/code><\/pre><\/div><p>\u901a\u8fc7 <code>qcount<\/code> \u548c <code>dataqsiz<\/code> \u5c5e\u6027\u5224\u65ad <code>hchan.buf<\/code> \u662f\u5426\u6709\u53ef\u7528\u7a7a\u95f4\uff0c\u5982\u679c buffer \u6709\u7a7a\u95f4\uff0c\u5219\u5c06\u6570\u636e copy \u8fdb buffer\u3002<\/p><ol start=\"4\"><li>\u5982\u679c buffer \u6ee1\u4e86\uff0c\u6216\u8005\u6ca1\u5f00\u542f buffer\uff0c\u5219 block\u3002<\/li><\/ol><div class=\"highlight\"><pre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"><code class=\"language-go\" data-lang=\"go\"><span style=\"display:flex;\"><span><span style=\"color:#75715e\">\/\/ \u7a0b\u5e8f 8<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\">\/\/ Block on the channel. Some receiver will complete our operation for us.<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span><span style=\"color:#a6e22e\">gp<\/span> <span style=\"color:#f92672\">:=<\/span> <span style=\"color:#a6e22e\">getg<\/span>()<\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#a6e22e\">mysg<\/span> <span style=\"color:#f92672\">:=<\/span> <span style=\"color:#a6e22e\">acquireSudog<\/span>()<\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#a6e22e\">mysg<\/span>.<span style=\"color:#a6e22e\">releasetime<\/span> = <span style=\"color:#ae81ff\">0<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#66d9ef\">if<\/span> <span style=\"color:#a6e22e\">t0<\/span> <span style=\"color:#f92672\">!=<\/span> <span style=\"color:#ae81ff\">0<\/span> {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">mysg<\/span>.<span style=\"color:#a6e22e\">releasetime<\/span> = <span style=\"color:#f92672\">-<\/span><span style=\"color:#ae81ff\">1<\/span><\/span><\/span><span style=\"display:flex;\"><span>}<\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\">\/\/ No stack splits between assigning elem and enqueuing mysg<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\">\/\/ on gp.waiting where copystack can find it.<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span><span style=\"color:#a6e22e\">mysg<\/span>.<span style=\"color:#a6e22e\">elem<\/span> = <span style=\"color:#a6e22e\">ep<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#a6e22e\">mysg<\/span>.<span style=\"color:#a6e22e\">waitlink<\/span> = <span style=\"color:#66d9ef\">nil<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#a6e22e\">mysg<\/span>.<span style=\"color:#a6e22e\">g<\/span> = <span style=\"color:#a6e22e\">gp<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#a6e22e\">mysg<\/span>.<span style=\"color:#a6e22e\">isSelect<\/span> = <span style=\"color:#66d9ef\">false<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#a6e22e\">mysg<\/span>.<span style=\"color:#a6e22e\">c<\/span> = <span style=\"color:#a6e22e\">c<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#a6e22e\">gp<\/span>.<span style=\"color:#a6e22e\">waiting<\/span> = <span style=\"color:#a6e22e\">mysg<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#a6e22e\">gp<\/span>.<span style=\"color:#a6e22e\">param<\/span> = <span style=\"color:#66d9ef\">nil<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#a6e22e\">c<\/span>.<span style=\"color:#a6e22e\">sendq<\/span>.<span style=\"color:#a6e22e\">enqueue<\/span>(<span style=\"color:#a6e22e\">mysg<\/span>)<\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#a6e22e\">gopark<\/span>(<span style=\"color:#a6e22e\">chanparkcommit<\/span>, <span style=\"color:#a6e22e\">unsafe<\/span>.<span style=\"color:#a6e22e\">Pointer<\/span>(<span style=\"color:#f92672\">&amp;<\/span><span style=\"color:#a6e22e\">c<\/span>.<span style=\"color:#a6e22e\">lock<\/span>), <span style=\"color:#a6e22e\">waitReasonChanSend<\/span>, <\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">traceEvGoBlockSend<\/span>, <span style=\"color:#ae81ff\">2<\/span>)<\/span><\/span><\/code><\/pre><\/div><h2 id=\"\u4ecechannel\u8bfb\u53d6\u6570\u636e\u7684\u6e90\u7801\">\u4ecechannel\u8bfb\u53d6\u6570\u636e\u7684\u6e90\u7801<\/h2><p>\u8bfb\u53d6\u6570\u636e\u5bf9\u5e94\u7684\u65b9\u6cd5\u662f <code>func chanrecv(c *hchan, ep unsafe.Pointer, block bool) (selected, received bool)<\/code>\u3002<\/p><ol><li>\u5982\u679c\u4ece nil channel \u4e2d\u63a5\u53d7\u6570\u636e\u4f1a\u4e00\u76f4 block\u3002<\/li><\/ol><div class=\"highlight\"><pre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"><code class=\"language-go\" data-lang=\"go\"><span style=\"display:flex;\"><span><span style=\"color:#75715e\">\/\/ \u7a0b\u5e8f 9<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span><span style=\"color:#66d9ef\">if<\/span> <span style=\"color:#a6e22e\">c<\/span> <span style=\"color:#f92672\">==<\/span> <span style=\"color:#66d9ef\">nil<\/span> {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">if<\/span> !<span style=\"color:#a6e22e\">block<\/span> {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">return<\/span><\/span><\/span><span style=\"display:flex;\"><span> }<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">gopark<\/span>(<span style=\"color:#66d9ef\">nil<\/span>, <span style=\"color:#66d9ef\">nil<\/span>, <span style=\"color:#a6e22e\">waitReasonChanReceiveNilChan<\/span>, <span style=\"color:#a6e22e\">traceEvGoStop<\/span>, <span style=\"color:#ae81ff\">2<\/span>)<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">throw<\/span>(<span style=\"color:#e6db74\">&#34;unreachable&#34;<\/span>)<\/span><\/span><span style=\"display:flex;\"><span>}<\/span><\/span><\/code><\/pre><\/div><p>\u548c\u5411 nil channel \u53d1\u9001\u6570\u636e\u7c7b\u4f3c\uff0c\u4ece nil channel \u63a5\u6536\u6570\u636e\u4e5f\u4f1a\u4e00\u76f4 block\u3002<\/p><ol start=\"2\"><li>\u4ece closed \u72b6\u6001\u7684channel\u63a5\u53d7\u6570\u636e\uff1a<\/li><\/ol><div class=\"highlight\"><pre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"><code class=\"language-go\" data-lang=\"go\"><span style=\"display:flex;\"><span><span style=\"color:#75715e\">\/\/ \u7a0b\u5e8f 10<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span><span style=\"color:#66d9ef\">if<\/span> <span style=\"color:#a6e22e\">c<\/span>.<span style=\"color:#a6e22e\">closed<\/span> <span style=\"color:#f92672\">!=<\/span> <span style=\"color:#ae81ff\">0<\/span> <span style=\"color:#f92672\">&amp;&amp;<\/span> <span style=\"color:#a6e22e\">c<\/span>.<span style=\"color:#a6e22e\">qcount<\/span> <span style=\"color:#f92672\">==<\/span> <span style=\"color:#ae81ff\">0<\/span> {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">if<\/span> <span style=\"color:#a6e22e\">raceenabled<\/span> {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">raceacquire<\/span>(<span style=\"color:#a6e22e\">c<\/span>.<span style=\"color:#a6e22e\">raceaddr<\/span>())<\/span><\/span><span style=\"display:flex;\"><span> }<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">unlock<\/span>(<span style=\"color:#f92672\">&amp;<\/span><span style=\"color:#a6e22e\">c<\/span>.<span style=\"color:#a6e22e\">lock<\/span>)<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">if<\/span> <span style=\"color:#a6e22e\">ep<\/span> <span style=\"color:#f92672\">!=<\/span> <span style=\"color:#66d9ef\">nil<\/span> {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">typedmemclr<\/span>(<span style=\"color:#a6e22e\">c<\/span>.<span style=\"color:#a6e22e\">elemtype<\/span>, <span style=\"color:#a6e22e\">ep<\/span>)<\/span><\/span><span style=\"display:flex;\"><span> }<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">return<\/span> <span style=\"color:#66d9ef\">true<\/span>, <span style=\"color:#66d9ef\">false<\/span><\/span><\/span><span style=\"display:flex;\"><span>}<\/span><\/span><\/code><\/pre><\/div><p>\u5982\u679c buffer \u4e2d\u6709\u6570\u636e\uff08<code>if raceenabled<\/code>\uff09\uff0c\u5219\u8fd4\u56de buffer \u4e2d\u7684\u6570\u636e\uff1b\u5982\u679c buffer \u4e2d\u6ca1\u6570\u636e\u4e86\uff0c\u5219\u8fd4\u56de\u9ed8\u8ba4\u503c\uff0c\u5e76\u4e14\u7b2c\u4e8c\u4e2a\u8fd4\u56de\u53c2\u6570\u8fd4\u56de false\u3002<\/p><ol start=\"3\"><li>\u5982\u679c <code>sendq<\/code> \u4e2d\u6709\u7b49\u5f85\u53d1\u9001\u7684 <code>sudgo<\/code><\/li><\/ol><div class=\"highlight\"><pre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"><code class=\"language-go\" data-lang=\"go\"><span style=\"display:flex;\"><span><span style=\"color:#75715e\">\/\/ \u7a0b\u5e8f 11<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span><span style=\"color:#66d9ef\">if<\/span> <span style=\"color:#a6e22e\">sg<\/span> <span style=\"color:#f92672\">:=<\/span> <span style=\"color:#a6e22e\">c<\/span>.<span style=\"color:#a6e22e\">sendq<\/span>.<span style=\"color:#a6e22e\">dequeue<\/span>(); <span style=\"color:#a6e22e\">sg<\/span> <span style=\"color:#f92672\">!=<\/span> <span style=\"color:#66d9ef\">nil<\/span> {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#75715e\">\/\/ Found a waiting sender. If buffer is size 0, receive value<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span> <span style=\"color:#75715e\">\/\/ directly from sender. Otherwise, receive from head of queue<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span> <span style=\"color:#75715e\">\/\/ and add sender&#39;s value to the tail of the queue (both map to<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span> <span style=\"color:#75715e\">\/\/ the same buffer slot because the queue is full).<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span> <span style=\"color:#a6e22e\">recv<\/span>(<span style=\"color:#a6e22e\">c<\/span>, <span style=\"color:#a6e22e\">sg<\/span>, <span style=\"color:#a6e22e\">ep<\/span>, <span style=\"color:#66d9ef\">func<\/span>() { <span style=\"color:#a6e22e\">unlock<\/span>(<span style=\"color:#f92672\">&amp;<\/span><span style=\"color:#a6e22e\">c<\/span>.<span style=\"color:#a6e22e\">lock<\/span>) }, <span style=\"color:#ae81ff\">3<\/span>)<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">return<\/span> <span style=\"color:#66d9ef\">true<\/span>, <span style=\"color:#66d9ef\">true<\/span><\/span><\/span><span style=\"display:flex;\"><span>}<\/span><\/span><\/code><\/pre><\/div><p>\u8bf4\u660e\u961f\u5217\u5df2\u6ee1\uff0c\u5982\u679c\u6ca1\u5f00\u542f buffer\uff0c\u5219\u76f4\u63a5\u4ece sender \u8bfb\u53d6\u6570\u636e\u3002\u5426\u5219\uff0c\u4ece\u961f\u5217\u5934\u8bfb\u53d6\u6570\u636e\uff0c\u5e76\u628a sender \u7684\u6570\u636e\u653e\u5230\u961f\u5217\u5c3e\uff08\u7531\u4e8e buffer \u662f\u5faa\u73af\u961f\u5217, \u6240\u4ee5\u961f\u5217\u5c3e\u5c31\u662f\u521a\u624d\u8bfb\u53d6\u6570\u636e\u7684\u4f4d\u7f6e\uff09\u3002<\/p><ol start=\"4\"><li>\u5982\u679c\u961f\u5217\u4e2d\u6709\u6570\u636e<\/li><\/ol><div class=\"highlight\"><pre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"><code class=\"language-go\" data-lang=\"go\"><span style=\"display:flex;\"><span><span style=\"color:#75715e\">\/\/ \u7a0b\u5e8f 12<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span><span style=\"color:#66d9ef\">if<\/span> <span style=\"color:#a6e22e\">c<\/span>.<span style=\"color:#a6e22e\">qcount<\/span> &gt; <span style=\"color:#ae81ff\">0<\/span> {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#75715e\">\/\/ Receive directly from queue<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span> <span style=\"color:#a6e22e\">qp<\/span> <span style=\"color:#f92672\">:=<\/span> <span style=\"color:#a6e22e\">chanbuf<\/span>(<span style=\"color:#a6e22e\">c<\/span>, <span style=\"color:#a6e22e\">c<\/span>.<span style=\"color:#a6e22e\">recvx<\/span>)<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">if<\/span> <span style=\"color:#a6e22e\">raceenabled<\/span> {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">raceacquire<\/span>(<span style=\"color:#a6e22e\">qp<\/span>)<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">racerelease<\/span>(<span style=\"color:#a6e22e\">qp<\/span>)<\/span><\/span><span style=\"display:flex;\"><span> }<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">if<\/span> <span style=\"color:#a6e22e\">ep<\/span> <span style=\"color:#f92672\">!=<\/span> <span style=\"color:#66d9ef\">nil<\/span> {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">typedmemmove<\/span>(<span style=\"color:#a6e22e\">c<\/span>.<span style=\"color:#a6e22e\">elemtype<\/span>, <span style=\"color:#a6e22e\">ep<\/span>, <span style=\"color:#a6e22e\">qp<\/span>)<\/span><\/span><span style=\"display:flex;\"><span> }<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">typedmemclr<\/span>(<span style=\"color:#a6e22e\">c<\/span>.<span style=\"color:#a6e22e\">elemtype<\/span>, <span style=\"color:#a6e22e\">qp<\/span>)<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">c<\/span>.<span style=\"color:#a6e22e\">recvx<\/span><span style=\"color:#f92672\">++<\/span><\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">if<\/span> <span style=\"color:#a6e22e\">c<\/span>.<span style=\"color:#a6e22e\">recvx<\/span> <span style=\"color:#f92672\">==<\/span> <span style=\"color:#a6e22e\">c<\/span>.<span style=\"color:#a6e22e\">dataqsiz<\/span> {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">c<\/span>.<span style=\"color:#a6e22e\">recvx<\/span> = <span style=\"color:#ae81ff\">0<\/span><\/span><\/span><span style=\"display:flex;\"><span> }<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">c<\/span>.<span style=\"color:#a6e22e\">qcount<\/span><span style=\"color:#f92672\">--<\/span><\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">unlock<\/span>(<span style=\"color:#f92672\">&amp;<\/span><span style=\"color:#a6e22e\">c<\/span>.<span style=\"color:#a6e22e\">lock<\/span>)<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">return<\/span> <span style=\"color:#66d9ef\">true<\/span>, <span style=\"color:#66d9ef\">true<\/span><\/span><\/span><span style=\"display:flex;\"><span>}<\/span><\/span><\/code><\/pre><\/div><p>\u5982\u679c\u961f\u5217\u4e2d\u6709\u6570\u636e\uff0c\u5219\u76f4\u63a5\u4ece\u961f\u5217\u4e2d\u8bfb\u53d6\u6570\u636e\u3002<\/p><ol start=\"5\"><li>\u5982\u679c\u961f\u5217\u4e2d\u6ca1\u6570\u636e\uff0c\u4e5f\u6ca1\u6709 goroutine \u5411\u961f\u5217\u4e2d\u53d1\u9001\u6570\u636e<\/li><\/ol><div class=\"highlight\"><pre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"><code class=\"language-go\" data-lang=\"go\"><span style=\"display:flex;\"><span><span style=\"color:#75715e\">\/\/ \u7a0b\u5e8f 13<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span><span style=\"color:#a6e22e\">gp<\/span> <span style=\"color:#f92672\">:=<\/span> <span style=\"color:#a6e22e\">getg<\/span>()<\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#a6e22e\">mysg<\/span> <span style=\"color:#f92672\">:=<\/span> <span style=\"color:#a6e22e\">acquireSudog<\/span>()<\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#a6e22e\">mysg<\/span>.<span style=\"color:#a6e22e\">releasetime<\/span> = <span style=\"color:#ae81ff\">0<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#66d9ef\">if<\/span> <span style=\"color:#a6e22e\">t0<\/span> <span style=\"color:#f92672\">!=<\/span> <span style=\"color:#ae81ff\">0<\/span> {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">mysg<\/span>.<span style=\"color:#a6e22e\">releasetime<\/span> = <span style=\"color:#f92672\">-<\/span><span style=\"color:#ae81ff\">1<\/span><\/span><\/span><span style=\"display:flex;\"><span>}<\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\">\/\/ No stack splits between assigning elem and enqueuing mysg<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\">\/\/ on gp.waiting where copystack can find it.<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span><span style=\"color:#a6e22e\">mysg<\/span>.<span style=\"color:#a6e22e\">elem<\/span> = <span style=\"color:#a6e22e\">ep<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#a6e22e\">mysg<\/span>.<span style=\"color:#a6e22e\">waitlink<\/span> = <span style=\"color:#66d9ef\">nil<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#a6e22e\">gp<\/span>.<span style=\"color:#a6e22e\">waiting<\/span> = <span style=\"color:#a6e22e\">mysg<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#a6e22e\">mysg<\/span>.<span style=\"color:#a6e22e\">g<\/span> = <span style=\"color:#a6e22e\">gp<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#a6e22e\">mysg<\/span>.<span style=\"color:#a6e22e\">isSelect<\/span> = <span style=\"color:#66d9ef\">false<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#a6e22e\">mysg<\/span>.<span style=\"color:#a6e22e\">c<\/span> = <span style=\"color:#a6e22e\">c<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#a6e22e\">gp<\/span>.<span style=\"color:#a6e22e\">param<\/span> = <span style=\"color:#66d9ef\">nil<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#a6e22e\">c<\/span>.<span style=\"color:#a6e22e\">recvq<\/span>.<span style=\"color:#a6e22e\">enqueue<\/span>(<span style=\"color:#a6e22e\">mysg<\/span>)<\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#a6e22e\">gopark<\/span>(<span style=\"color:#a6e22e\">chanparkcommit<\/span>, <span style=\"color:#a6e22e\">unsafe<\/span>.<span style=\"color:#a6e22e\">Pointer<\/span>(<span style=\"color:#f92672\">&amp;<\/span><span style=\"color:#a6e22e\">c<\/span>.<span style=\"color:#a6e22e\">lock<\/span>), <span style=\"color:#a6e22e\">waitReasonChanReceive<\/span>, <\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">traceEvGoBlockRecv<\/span>, <span style=\"color:#ae81ff\">2<\/span>)<\/span><\/span><\/code><\/pre><\/div><p>\u5982\u679c\u961f\u5217\u4e2d\u6ca1\u6570\u636e\uff0c\u4e5f\u6ca1\u6709 goroutine \u5411\u961f\u5217\u4e2d\u53d1\u9001\u6570\u636e\uff0cgoroutine \u4f1a block\u3002<\/p><h2 id=\"channel\u662f\u5426\u5fc5\u987bclose\">channel\u662f\u5426\u5fc5\u987bclose<\/h2><p>channel \u53ef\u4ee5\u4e0d\u5173\u95ed\uff0c\u5982\u679c channel \u4e0d\u518d\u88ab\u4f7f\u7528\uff0c\u5373\u4f7f\u4e0d\u5173\u95ed\u4e5f\u4f1a\u88ab\u56de\u6536\u3002\u901a\u5e38 close channel \u4f1a\u4f5c\u4e3a channel \u4e0d\u4f1a\u518d\u6709\u6570\u636e\u7684\u63a7\u5236\u4fe1\u53f7\uff0c\u5982\u679c\u63a5\u6536\u65b9\u4e0d\u5173\u5fc3 channel \u4e2d\u662f\u5426\u8fd8\u4f1a\u6709\u6570\u636e\uff0c\u90a3\u4e48\u6ca1\u5fc5\u8981\u4e3b\u52a8\u5173\u95ed channel\u3002\u53ef\u4ee5\u53c2\u8003 <a href=\"https:\/\/groups.google.com\/d\/msg\/golang-nuts\/pZwdYRGxCIk\/qpbHxRRPJdUJ\">Design Question: Channel Closing<\/a>\u3002\u5982\u679c\u8981\u5173\u95ed channel\uff0c\u5219\u6700\u597d\u662f\u7531\u53d1\u9001\u65b9\u6765\u5173\u95ed\u3002<\/p><blockquote><p>Note that it is only necessary to close a channel if the receiver is looking for a close. Closing the channel is a control signal on the channel indicating that no more data follows.<\/p><\/blockquote><h2 id=\"\u603b\u7ed3\">\u603b\u7ed3<\/h2><p>\u8fd9\u7bc7\u6587\u7ae0\u63cf\u8ff0\u4e86 channel \u7684\u57fa\u672c\u7528\u6cd5\u548c\u5185\u90e8\u7684\u673a\u5236\uff0c\u6211\u4eec\u4ece\u8fd9\u7bc7\u6587\u7ae0\u4e86\u89e3\u5230\u4e86\uff1a<\/p><ul><li>channel \u7684\u96f6\u503c\u662fnil\uff0c\u5fc5\u987b\u521d\u59cb\u5316\u624d\u80fd\u4f7f\u7528\u3002<\/li><li>\u53d1\u9001\u7684\u662f\u6570\u636e\u7684\u526f\u672c\uff0c\u4f46\u662f\u53d1\u9001\u6307\u9488\u6216\u5f15\u7528\u7c7b\u578b\u4e0d\u662f goroutine \u5b89\u5168\u7684\uff0creceiver \u63a5\u6536\u5230\u7684\u6570\u636e\u53ef\u80fd\u88ab sender \u4fee\u6539\u3002<\/li><li>\u5f80\u4e00\u4e2a\u5df2\u7ecf closed \u7684 channel \u4e2d\u53d1\u9001\u6570\u636e\u4f1a\u5bfc\u81f4 panic\uff0c\u5f80 nil channel \u53d1\u9001\u6570\u636e\u4f1a block\u3002\u4ece\u4e00\u4e2a nil channel \u4e2d\u63a5\u6536\u6570\u636e\u4f1a block\uff0c\u4ece\u4e00\u4e2a\u88ab close \u7684 channel \u4e2d\u63a5\u6536\u6570\u636e\u4e0d\u4f1a block\uff0c\u5982\u679c\u961f\u5217\u4e2d\u6709\u6570\u636e\uff0c\u5219\u6b63\u5e38\u8bfb\u53d6\uff0c\u5426\u5219\u7acb\u5373\u8fd4\u5143\u7d20\u7c7b\u578b\u7684\u96f6\u503c\u3002<\/li><li><code>select case<\/code> \u4e2d\uff0c\u5982\u679c\u6709\u591a\u4e2a case \u5c31\u7eea\uff0c\u90a3\u4e48\u4f1a\u968f\u673a\u9009\u62e9\u4e00\u4e2a case \u6267\u884c\uff0cselect \u4e2d\u7684 break \u53ea\u80fd\u8df3\u5230 select \u8fd9\u4e00\u5c42\uff0cselect \u4e2d\u4e00\u822c\u914d\u5408 label \u6765\u4f7f\u7528 break\u3002<\/li><li>channel \u4f7f\u7528\u5b8c\u53ef\u4ee5\u4e0d\u5173\u95ed, \u5982\u679c\u8981\u5173\u95ed, \u6700\u597d\u662f\u53d1\u9001\u65b9\u6765\u5173\u95ed.<\/li><\/ul><h2 id=\"\u53c2\u8003\u8d44\u6599\">\u53c2\u8003\u8d44\u6599<\/h2><ol><li><a href=\"https:\/\/about.sourcegraph.com\/go\/understanding-channels-kavya-joshi\">https:\/\/about.sourcegraph.com\/go\/understanding-channels-kavya-joshi<\/a><\/li><li><a href=\"https:\/\/github.com\/gophercon\/2017-talks\/blob\/master\/KavyaJoshi-UnderstandingChannels\/Kavya%20Joshi%20-%20Understanding%20Channels.pdf\">https:\/\/github.com\/gophercon\/2017-talks\/blob\/master\/KavyaJoshi-UnderstandingChannels\/Kavya Joshi - Understanding Channels.pdf<\/a><\/li><\/ol>"},{"title":"golang\u4e2d\u7684defer, panic\u548crecover","link":"https:\/\/sunpe.github.io\/posts\/2020-06-18-golang-panic-defer-recover\/","pubDate":"Thu, 18 Jun 2020 22:00:00 +0800","guid":"https:\/\/sunpe.github.io\/posts\/2020-06-18-golang-panic-defer-recover\/","description":"<p>Go\u63d0\u4f9b\u4e86 <code>defer<\/code>, <code>panic<\/code> \u548c <code>recover<\/code> \u4e09\u4e2a\u5185\u7f6e\u65b9\u6cd5\u3002\u5176\u4e2d <code>panic<\/code> \u4f1a\u8ba9\u7a0b\u5e8f\u5d29\u6e83\uff0c<code>defer<\/code> \u53ef\u4ee5\u5728\u51fd\u6570 return \u4e4b\u524d\u6267\u884c\u64cd\u4f5c\uff0c <code>defer<\/code> \u548c <code>recover<\/code> \u914d\u5408\u53ef\u4ee5\u6355\u83b7 panic\u3002<\/p><h2 id=\"defer\">defer<\/h2><p><code>defer<\/code> \u58f0\u660e\u7684\u8bed\u53e5\u53ef\u4ee5\u5728\u51fd\u6570\u6216\u65b9\u6cd5\u8fd4\u56de\uff08\u4e0d\u7ba1\u662f\u6b63\u5e38\u8fd4\u56de\u6216\u5f02\u5e38\u8fd4\u56de\uff09\u4e4b\u524d\u8c03\u7528\uff0c\u7c7b\u4f3c\u4e8e Java \u91cc\u9762\u7684 <code>finally<\/code>\uff0c\u53ef\u4ee5\u505a\u4e00\u4e9b\u6e05\u7406\u7684\u5de5\u4f5c\uff0c\u6bd4\u5982\u5173\u95ed\u6587\u4ef6\u3001 \u91ca\u653e\u8d44\u6e90\u7b49\u64cd\u4f5c\u3002<\/p><p>\u7a0b\u5e8f 1 \u5c55\u793a\u4e86 <code>defer<\/code> \u7684\u4e00\u822c\u7684\u7528\u6cd5\uff0c\u901a\u8fc7 <code>defer<\/code> \u8bed\u53e5\u4fdd\u8bc1 <code>src<\/code> \u548c <code>dst<\/code> \u6700\u7ec8\u4f1a\u88ab\u91ca\u653e\u3002<\/p><div class=\"highlight\"><pre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"><code class=\"language-go\" data-lang=\"go\"><span style=\"display:flex;\"><span><span style=\"color:#75715e\">\/\/ \u7a0b\u5e8f 1<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span><span style=\"color:#66d9ef\">func<\/span> <span style=\"color:#a6e22e\">CopyFile<\/span>(<span style=\"color:#a6e22e\">dstName<\/span>, <span style=\"color:#a6e22e\">srcName<\/span> <span style=\"color:#66d9ef\">string<\/span>) (<span style=\"color:#a6e22e\">written<\/span> <span style=\"color:#66d9ef\">int64<\/span>, <span style=\"color:#a6e22e\">err<\/span> <span style=\"color:#66d9ef\">error<\/span>) {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">src<\/span>, <span style=\"color:#a6e22e\">err<\/span> <span style=\"color:#f92672\">:=<\/span> <span style=\"color:#a6e22e\">os<\/span>.<span style=\"color:#a6e22e\">Open<\/span>(<span style=\"color:#a6e22e\">srcName<\/span>)<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">if<\/span> <span style=\"color:#a6e22e\">err<\/span> <span style=\"color:#f92672\">!=<\/span> <span style=\"color:#66d9ef\">nil<\/span> {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">return<\/span><\/span><\/span><span style=\"display:flex;\"><span> }<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">defer<\/span> <span style=\"color:#a6e22e\">src<\/span>.<span style=\"color:#a6e22e\">Close<\/span>()<\/span><\/span><span style=\"display:flex;\"><span><\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">dst<\/span>, <span style=\"color:#a6e22e\">err<\/span> <span style=\"color:#f92672\">:=<\/span> <span style=\"color:#a6e22e\">os<\/span>.<span style=\"color:#a6e22e\">Create<\/span>(<span style=\"color:#a6e22e\">dstName<\/span>)<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">if<\/span> <span style=\"color:#a6e22e\">err<\/span> <span style=\"color:#f92672\">!=<\/span> <span style=\"color:#66d9ef\">nil<\/span> {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">return<\/span><\/span><\/span><span style=\"display:flex;\"><span> }<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">defer<\/span> <span style=\"color:#a6e22e\">dst<\/span>.<span style=\"color:#a6e22e\">Close<\/span>()<\/span><\/span><span style=\"display:flex;\"><span><\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">return<\/span> <span style=\"color:#a6e22e\">io<\/span>.<span style=\"color:#a6e22e\">Copy<\/span>(<span style=\"color:#a6e22e\">dst<\/span>, <span style=\"color:#a6e22e\">src<\/span>)<\/span><\/span><span style=\"display:flex;\"><span>}<\/span><\/span><\/code><\/pre><\/div><p>defer \u8bed\u53e5\u6709\u4e09\u4e2a\u7ea6\u5b9a\uff1a<\/p><ol><li><p>defer \u8bed\u53e5\u53c2\u6570\u7684\u503c\u5728 defer \u8bed\u53e5\u58f0\u660e\u65f6\u5c31\u5df2\u7ecf\u786e\u5b9a\u4e86<\/p><div class=\"highlight\"><pre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"><code class=\"language-go\" data-lang=\"go\"><span style=\"display:flex;\"><span><span style=\"color:#75715e\">\/\/ \u7a0b\u5e8f 2<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span><span style=\"color:#66d9ef\">func<\/span> <span style=\"color:#a6e22e\">a<\/span>() {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">i<\/span> <span style=\"color:#f92672\">:=<\/span> <span style=\"color:#ae81ff\">0<\/span><\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">defer<\/span> <span style=\"color:#a6e22e\">fmt<\/span>.<span style=\"color:#a6e22e\">Println<\/span>(<span style=\"color:#a6e22e\">i<\/span>)<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">i<\/span><span style=\"color:#f92672\">++<\/span><\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">return<\/span><\/span><\/span><span style=\"display:flex;\"><span>}<\/span><\/span><\/code><\/pre><\/div><p>defer \u8bed\u53e5\u5e76\u4e0d\u662f\u7b80\u5355\u7684\u5ef6\u8fdf\u6267\u884c\uff0c\u7a0b\u5e8f 2 \u4e2d\u7684 <code>a()<\/code> \u65b9\u6cd5\u6267\u884c\u5230 <code>defer fmt.Println(i)<\/code> \u65f6\uff0c\u4f1a\u5c06i\u7684\u503c copy \u4e00\u4efd\u548cdefer\u8bed\u53e5\u7684\u58f0\u660e\u4e00\u8d77\u5165\u6808\uff0c\u5728 return \u4e4b\u524d\uff0c\u58f0\u660e\u7684 defer \u8bed\u53e5\u51fa\u6808\u6267\u884c\uff0c\u6240\u4ee5\u7a0b\u5e8f 2 \u6700\u7ec8\u6253\u5370\u51fai\u7684\u503c\u662f<code>0<\/code>\u3002<\/p><\/li><li><p>defer \u8bed\u53e5\u7684\u6267\u884c\u987a\u5e8f\u662f\u540e\u8fdb\u5148\u51fa\uff08LIFO\uff09<\/p><div class=\"highlight\"><pre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"><code class=\"language-go\" data-lang=\"go\"><span style=\"display:flex;\"><span><span style=\"color:#75715e\">\/\/ \u7a0b\u5e8f 3<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span><span style=\"color:#66d9ef\">func<\/span> <span style=\"color:#a6e22e\">b<\/span>() {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">for<\/span> <span style=\"color:#a6e22e\">i<\/span> <span style=\"color:#f92672\">:=<\/span> <span style=\"color:#ae81ff\">0<\/span>; <span style=\"color:#a6e22e\">i<\/span> &lt; <span style=\"color:#ae81ff\">4<\/span>; <span style=\"color:#a6e22e\">i<\/span><span style=\"color:#f92672\">++<\/span> {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">defer<\/span> <span style=\"color:#a6e22e\">fmt<\/span>.<span style=\"color:#a6e22e\">Print<\/span>(<span style=\"color:#a6e22e\">i<\/span>)<\/span><\/span><span style=\"display:flex;\"><span> }<\/span><\/span><span style=\"display:flex;\"><span>}<\/span><\/span><\/code><\/pre><\/div><p>defer \u8bed\u53e5\u7684\u58f0\u660e\u548c\u6267\u884c\u53ef\u4ee5\u770b\u4f5c\u662f defer \u8bed\u53e5\u5757\u7684\u300c\u5165\u6808\u300d\u548c\u300c\u51fa\u6808\u300d\u64cd\u4f5c\uff0c\u5148\u58f0\u660e\u7684 defer \u8bed\u53e5\u6700\u540e\u6267\u884c\uff0c\u6240\u4ee5\u7a0b\u5e8f 3 \u7684\u8f93\u51fa\u662f <code>3201<\/code><\/p><\/li><li><p>defer \u8bed\u53e5\u53ef\u4ee5\u8bfb\u53d6\u5e76\u4fee\u6539\u5916\u90e8\u51fd\u6570\u547d\u540d\u7684\u8fd4\u56de\u503c\uff08named return values\uff09<\/p><div class=\"highlight\"><pre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"><code class=\"language-go\" data-lang=\"go\"><span style=\"display:flex;\"><span><span style=\"color:#75715e\">\/\/ \u7a0b\u5e8f 4<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span><span style=\"color:#66d9ef\">func<\/span> <span style=\"color:#a6e22e\">c<\/span>() (<span style=\"color:#a6e22e\">i<\/span> <span style=\"color:#66d9ef\">int<\/span>) {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">defer<\/span> <span style=\"color:#66d9ef\">func<\/span>() { <span style=\"color:#a6e22e\">i<\/span><span style=\"color:#f92672\">++<\/span> }()<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">return<\/span> <span style=\"color:#a6e22e\">i<\/span><\/span><\/span><span style=\"display:flex;\"><span>}<\/span><\/span><\/code><\/pre><\/div><p>defer \u8bed\u53e5\u53ef\u4ee5\u5728 return \u4e4b\u524d\u6267\u884c, \u5e76\u4e14\u53ef\u4ee5\u4fee\u6539\u5916\u90e8\u51fd\u6570\u547d\u540d\u7684\u8fd4\u56de\u503c\uff08named return values\uff09\u3002\u7a0b\u5e8f 4 \u5728 return \u4e4b\u524d\u4f1a\u6267\u884c defer \u8bed\u53e5\uff0c\u6240\u4ee5\u7a0b\u5e8f 4 \u6700\u7ec8\u8fd4\u56de\u7684\u662f <code>1<\/code>\u3002<\/p><div class=\"highlight\"><pre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"><code class=\"language-go\" data-lang=\"go\"><span style=\"display:flex;\"><span><span style=\"color:#75715e\">\/\/ \u7a0b\u5e8f 5<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span> <span style=\"color:#66d9ef\">func<\/span> <span style=\"color:#a6e22e\">c<\/span>() <span style=\"color:#66d9ef\">int<\/span> {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">var<\/span> <span style=\"color:#a6e22e\">i<\/span> <span style=\"color:#66d9ef\">int<\/span><\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">defer<\/span> <span style=\"color:#66d9ef\">func<\/span>() { <span style=\"color:#a6e22e\">i<\/span><span style=\"color:#f92672\">++<\/span> }()<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">return<\/span> <span style=\"color:#a6e22e\">i<\/span><\/span><\/span><span style=\"display:flex;\"><span>}<\/span><\/span><\/code><\/pre><\/div><p>\u4f46\u7a0b\u5e8f 5 \u6700\u7ec8\u8f93\u51fa\u7684\u662f <code>0<\/code>\u3002<\/p><\/li><\/ol><h2 id=\"panic\u548crecover\">panic\u548crecover<\/h2><p><code>panic<\/code> \u5185\u7f6e\u51fd\u6570\u53ef\u4ee5\u8ba9\u8ba9\u5f53\u524d goroutine \u5d29\u6e83\uff0c\u5f53\u51fd\u6570 F \u4e2d\u8c03\u7528\u4e86\u6216\u8005\u89e6\u53d1\u4e86 <code>panic<\/code>\uff0cF \u4f1a\u7acb\u5373\u7ec8\u6b62\u8fd0\u884c\uff0c\u7136\u540e\u6267\u884c F \u4e2d\u7684 <code>defer<\/code> \u8bed\u53e5\uff0c\u7136\u540e F \u8fd4\u56de\u5230\u8c03\u7528\u8005 G\uff0cG \u4e5f\u4f1a\u7acb\u5373\u7ec8\u6b62\u8fd0\u884c\uff0c\u7136\u540e\u6267\u884c G \u4e2d\u7684 <code>defer<\/code> \u8bed\u53e5\uff0c\u8fd9\u6837\u4e00\u5c42\u4e00\u5c42\u7684\u5411\u4e0a\u8fd4\u56de\uff0c\u76f4\u5230\u9876\u5c42\u7684 goroutine\uff08\u51fd\u6570\u8c03\u7528\u94fe\u7684\u9876\u5c42 goroutine\uff0c\u4e0d\u4e00\u5b9a\u662f main goroutine\uff09\uff0c\u7136\u540e\u7a0b\u5e8f\u5d29\u6e83\u3002<\/p><p><code>recover<\/code> \u5185\u7f6e\u65b9\u6cd5\u53ef\u4ee5\u518d\u6b21\u63a7\u5236 panic \u7684 goroutine\u3002<code>recover<\/code> \u65b9\u6cd5\u53ea\u6709\u5728 <code>defer<\/code> \u4e2d\u624d\u6709\u6548\u679c\u3002\u6b63\u5e38\u60c5\u51b5\u4e0b\uff0c<code>recover<\/code> \u4f1a\u8fd4\u56de <code>nil<\/code>\uff0c\u5982\u679c\u5f53\u524d goroutine \u53d1\u751f\u4e86 panic\uff0c<code>recover<\/code> \u65b9\u6cd5\u4f1a\u6355\u83b7 panic \u7684\u503c\uff0c\u5e76\u4e14\u518d\u6b21\u83b7\u5f97\u7a0b\u5e8f\u7684\u63a7\u5236\u6743\u3002<\/p><div class=\"highlight\"><pre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"><code class=\"language-go\" data-lang=\"go\"><span style=\"display:flex;\"><span><span style=\"color:#75715e\">\/\/ \u7a0b\u5e8f 6<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span><span style=\"color:#f92672\">package<\/span> <span style=\"color:#a6e22e\">main<\/span><\/span><\/span><span style=\"display:flex;\"><span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#f92672\">import<\/span> <span style=\"color:#e6db74\">&#34;fmt&#34;<\/span><\/span><\/span><span style=\"display:flex;\"><span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#66d9ef\">func<\/span> <span style=\"color:#a6e22e\">main<\/span>() {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">f<\/span>()<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">fmt<\/span>.<span style=\"color:#a6e22e\">Println<\/span>(<span style=\"color:#e6db74\">&#34;Returned normally from f.&#34;<\/span>)<\/span><\/span><span style=\"display:flex;\"><span>}<\/span><\/span><span style=\"display:flex;\"><span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#66d9ef\">func<\/span> <span style=\"color:#a6e22e\">f<\/span>() {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">defer<\/span> <span style=\"color:#66d9ef\">func<\/span>() {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">if<\/span> <span style=\"color:#a6e22e\">r<\/span> <span style=\"color:#f92672\">:=<\/span> recover(); <span style=\"color:#a6e22e\">r<\/span> <span style=\"color:#f92672\">!=<\/span> <span style=\"color:#66d9ef\">nil<\/span> {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">fmt<\/span>.<span style=\"color:#a6e22e\">Println<\/span>(<span style=\"color:#e6db74\">&#34;Recovered in f&#34;<\/span>, <span style=\"color:#a6e22e\">r<\/span>)<\/span><\/span><span style=\"display:flex;\"><span> }<\/span><\/span><span style=\"display:flex;\"><span> }()<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">fmt<\/span>.<span style=\"color:#a6e22e\">Println<\/span>(<span style=\"color:#e6db74\">&#34;Calling g.&#34;<\/span>)<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">g<\/span>(<span style=\"color:#ae81ff\">0<\/span>)<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">fmt<\/span>.<span style=\"color:#a6e22e\">Println<\/span>(<span style=\"color:#e6db74\">&#34;Returned normally from g.&#34;<\/span>)<\/span><\/span><span style=\"display:flex;\"><span>}<\/span><\/span><span style=\"display:flex;\"><span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#66d9ef\">func<\/span> <span style=\"color:#a6e22e\">g<\/span>(<span style=\"color:#a6e22e\">i<\/span> <span style=\"color:#66d9ef\">int<\/span>) {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">if<\/span> <span style=\"color:#a6e22e\">i<\/span> &gt; <span style=\"color:#ae81ff\">3<\/span> {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">fmt<\/span>.<span style=\"color:#a6e22e\">Println<\/span>(<span style=\"color:#e6db74\">&#34;Panicking!&#34;<\/span>)<\/span><\/span><span style=\"display:flex;\"><span> panic(<span style=\"color:#a6e22e\">fmt<\/span>.<span style=\"color:#a6e22e\">Sprintf<\/span>(<span style=\"color:#e6db74\">&#34;%v&#34;<\/span>, <span style=\"color:#a6e22e\">i<\/span>))<\/span><\/span><span style=\"display:flex;\"><span> }<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">defer<\/span> <span style=\"color:#a6e22e\">fmt<\/span>.<span style=\"color:#a6e22e\">Println<\/span>(<span style=\"color:#e6db74\">&#34;Defer in g&#34;<\/span>, <span style=\"color:#a6e22e\">i<\/span>)<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">fmt<\/span>.<span style=\"color:#a6e22e\">Println<\/span>(<span style=\"color:#e6db74\">&#34;Printing in g&#34;<\/span>, <span style=\"color:#a6e22e\">i<\/span>)<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">g<\/span>(<span style=\"color:#a6e22e\">i<\/span> <span style=\"color:#f92672\">+<\/span> <span style=\"color:#ae81ff\">1<\/span>)<\/span><\/span><span style=\"display:flex;\"><span>}<\/span><\/span><\/code><\/pre><\/div><p>\u7a0b\u5e8f 6 \u4e2d g \u7684\u903b\u8f91\u662f\u5982\u679c <code>i&gt;3<\/code>\uff0c\u5219 panic\uff0c\u5426\u5219\u9012\u5f52\u8fdb\u884c <code>i+1<\/code>\uff0cf \u5728 <code>defer<\/code> \u4e2d\u8c03\u7528\u4e86 <code>recover<\/code>\uff0c\u5e76\u6253\u5370\u4e86 recover \u4fe1\u606f\uff0c\u7a0b\u5e8f\u7684\u8f93\u51fa\uff1a<\/p><pre tabindex=\"0\"><code>Calling g.Printing in g 0Printing in g 1Printing in g 2Printing in g 3Panicking!Defer in g 3Defer in g 2Defer in g 1Defer in g 0Recovered in f 4Returned normally from f<\/code><\/pre><p>\u5982\u679c\u53bb\u6389f\u4e2d\u7684 <code>defer<\/code> \u58f0\u660e\uff0cpanic \u4e0d\u4f1a recover\uff0c\u4e00\u5c42\u4e00\u5c42\u7684\u8fd4\u56de <code>panic<\/code>\uff0c\u76f4\u5230 goroutine \u8c03\u7528\u6808\u7684\u9876\u7aef\uff0c\u7136\u540e\u7a0b\u5e8f\u5d29\u6e83\u3002\u53bb\u6389 defer \u8bed\u53e5\u4e4b\u540e\u7684\u8f93\u51fa:<\/p><pre tabindex=\"0\"><code>Calling g.Printing in g 0Printing in g 1Printing in g 2Printing in g 3Panicking!Defer in g 3Defer in g 2Defer in g 1Defer in g 0panic: 4panic PC=0x2a9cd8[stack trace omitted]<\/code><\/pre><p><code>recover<\/code> \u8fd4\u56de\u7684\u662f <code>panic<\/code> \u7684\u503c\uff0c\u4ee5\u4e0b\u4e09\u79cd\u60c5\u51b5\uff0c<code>recover<\/code> \u7684\u503c\u662f <code>nil<\/code>\uff1a<\/p><ul><li><code>panic<\/code> \u7684\u503c\u662f <code>nil<\/code><\/li><li><code>goroutine<\/code> \u6ca1\u6709 panic<\/li><li><code>recover<\/code> \u6ca1\u6709\u76f4\u63a5\u5728 <code>defer<\/code> \u4e2d\u8c03\u7528<\/li><\/ul><p>\u524d\u4e24\u79cd\u60c5\u51b5\u597d\u7406\u89e3\uff0c\u7b2c\u4e09\u79cd\u60c5\u51b5\uff0c\u5982\u679c <code>recover<\/code> \u6ca1\u6709\u5728 <code>defer<\/code> \u4e2d\u76f4\u63a5\u8c03\u7528\uff0c\u90a3\u4e48 <code>recover<\/code> \u5c31\u4e0d\u80fd\u6355\u83b7 <code>panic<\/code>\u3002\u4e0b\u9762\u4e09\u6bb5\u4ee3\u7801\uff0c\u7a0b\u5e8f 7 \u4e2d\u7684 <code>recover()<\/code> \u53ef\u4ee5\u6b63\u5e38\u6355\u83b7 panic\uff0c\u800c\u7a0b\u5e8f 8 \u548c\u7a0b\u5e8f 9 \u5219\u4f1a panic\u3002<\/p><div class=\"highlight\"><pre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"><code class=\"language-go\" data-lang=\"go\"><span style=\"display:flex;\"><span><span style=\"color:#75715e\">\/\/ \u7a0b\u5e8f 7<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span><span style=\"color:#f92672\">package<\/span> <span style=\"color:#a6e22e\">main<\/span><\/span><\/span><span style=\"display:flex;\"><span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#f92672\">import<\/span> <span style=\"color:#e6db74\">&#34;fmt&#34;<\/span><\/span><\/span><span style=\"display:flex;\"><span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#66d9ef\">func<\/span> <span style=\"color:#a6e22e\">main<\/span>() {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">a<\/span>()<\/span><\/span><span style=\"display:flex;\"><span>}<\/span><\/span><span style=\"display:flex;\"><span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#66d9ef\">func<\/span> <span style=\"color:#a6e22e\">a<\/span>() {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">defer<\/span> <span style=\"color:#a6e22e\">r<\/span>()<\/span><\/span><span style=\"display:flex;\"><span> panic(<span style=\"color:#e6db74\">&#34;a&#34;<\/span>)<\/span><\/span><span style=\"display:flex;\"><span><\/span><\/span><span style=\"display:flex;\"><span>}<\/span><\/span><span style=\"display:flex;\"><span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#66d9ef\">func<\/span> <span style=\"color:#a6e22e\">r<\/span>() {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">if<\/span> <span style=\"color:#a6e22e\">r<\/span> <span style=\"color:#f92672\">:=<\/span> recover(); <span style=\"color:#a6e22e\">r<\/span> <span style=\"color:#f92672\">!=<\/span> <span style=\"color:#66d9ef\">nil<\/span> {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">fmt<\/span>.<span style=\"color:#a6e22e\">Println<\/span>(<span style=\"color:#a6e22e\">r<\/span>)<\/span><\/span><span style=\"display:flex;\"><span> }<\/span><\/span><span style=\"display:flex;\"><span>}<\/span><\/span><\/code><\/pre><\/div><div class=\"highlight\"><pre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"><code class=\"language-go\" data-lang=\"go\"><span style=\"display:flex;\"><span><span style=\"color:#75715e\">\/\/ \u7a0b\u5e8f 8<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span><span style=\"color:#f92672\">package<\/span> <span style=\"color:#a6e22e\">main<\/span><\/span><\/span><span style=\"display:flex;\"><span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#f92672\">import<\/span> <span style=\"color:#e6db74\">&#34;fmt&#34;<\/span><\/span><\/span><span style=\"display:flex;\"><span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#66d9ef\">func<\/span> <span style=\"color:#a6e22e\">main<\/span>() {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">a<\/span>()<\/span><\/span><span style=\"display:flex;\"><span>}<\/span><\/span><span style=\"display:flex;\"><span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#66d9ef\">func<\/span> <span style=\"color:#a6e22e\">a<\/span>() {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">defer<\/span> <span style=\"color:#66d9ef\">func<\/span>() {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">r<\/span>()<\/span><\/span><span style=\"display:flex;\"><span> }()<\/span><\/span><span style=\"display:flex;\"><span> panic(<span style=\"color:#e6db74\">&#34;a&#34;<\/span>)<\/span><\/span><span style=\"display:flex;\"><span><\/span><\/span><span style=\"display:flex;\"><span>}<\/span><\/span><span style=\"display:flex;\"><span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#66d9ef\">func<\/span> <span style=\"color:#a6e22e\">r<\/span>() {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">if<\/span> <span style=\"color:#a6e22e\">r<\/span> <span style=\"color:#f92672\">:=<\/span> recover(); <span style=\"color:#a6e22e\">r<\/span> <span style=\"color:#f92672\">!=<\/span> <span style=\"color:#66d9ef\">nil<\/span> {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">fmt<\/span>.<span style=\"color:#a6e22e\">Println<\/span>(<span style=\"color:#a6e22e\">r<\/span>)<\/span><\/span><span style=\"display:flex;\"><span> }<\/span><\/span><span style=\"display:flex;\"><span>}<\/span><\/span><\/code><\/pre><\/div><div class=\"highlight\"><pre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"><code class=\"language-go\" data-lang=\"go\"><span style=\"display:flex;\"><span><span style=\"color:#75715e\">\/\/ \u7a0b\u5e8f 9<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span><span style=\"color:#f92672\">package<\/span> <span style=\"color:#a6e22e\">main<\/span><\/span><\/span><span style=\"display:flex;\"><span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#f92672\">import<\/span> <span style=\"color:#e6db74\">&#34;fmt&#34;<\/span><\/span><\/span><span style=\"display:flex;\"><span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#66d9ef\">func<\/span> <span style=\"color:#a6e22e\">main<\/span>() {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">a<\/span>()<\/span><\/span><span style=\"display:flex;\"><span>}<\/span><\/span><span style=\"display:flex;\"><span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#66d9ef\">func<\/span> <span style=\"color:#a6e22e\">a<\/span>() {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">r<\/span>()<\/span><\/span><span style=\"display:flex;\"><span> panic(<span style=\"color:#e6db74\">&#34;a&#34;<\/span>)<\/span><\/span><span style=\"display:flex;\"><span><\/span><\/span><span style=\"display:flex;\"><span>}<\/span><\/span><span style=\"display:flex;\"><span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#66d9ef\">func<\/span> <span style=\"color:#a6e22e\">r<\/span>() {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">defer<\/span> <span style=\"color:#66d9ef\">func<\/span>() {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">if<\/span> <span style=\"color:#a6e22e\">r<\/span> <span style=\"color:#f92672\">:=<\/span> recover(); <span style=\"color:#a6e22e\">r<\/span> <span style=\"color:#f92672\">!=<\/span> <span style=\"color:#66d9ef\">nil<\/span> {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">fmt<\/span>.<span style=\"color:#a6e22e\">Println<\/span>(<span style=\"color:#a6e22e\">r<\/span>)<\/span><\/span><span style=\"display:flex;\"><span> }<\/span><\/span><span style=\"display:flex;\"><span> }()<\/span><\/span><span style=\"display:flex;\"><span>}<\/span><\/span><\/code><\/pre><\/div><h2 id=\"\u603b\u7ed3\">\u603b\u7ed3<\/h2><p>\u8fd9\u7bc7\u6587\u7ae0\u4ecb\u7ecd\u4e86 golang \u5185\u7f6e\u7684 defer\u3001panic \u548c recover \u51fd\u6570\uff0c\u6211\u4eec\u4e86\u89e3\u5230\uff1a<\/p><ul><li><code>defer<\/code> \u58f0\u660e\u65f6\u53c2\u6570\u5c31\u786e\u5b9a\u4e86\uff0c\u4e0d\u4f1a\u968f\u7740\u65b9\u6cd5\u5185\u90e8\u4ee3\u7801\u7684\u6267\u884c\u800c\u53d8\u5316\u3002<\/li><li><code>defer<\/code> \u6267\u884c\u987a\u5e8f\u662f\u540e\u8fdb\u5148\u51fa\uff08LIFO\uff09\u3002<\/li><li><code>defer<\/code> \u53ef\u4ee5\u8bfb\u53d6\u5e76\u4fee\u6539\u5916\u90e8\u51fd\u6570\u547d\u540d\u7684\u8fd4\u56de\u503c\uff08named return values\uff09\u3002<\/li><li><code>recover<\/code> \u5fc5\u987b\u5728 <code>defer<\/code> \u4e2d\uff0c\u5e76\u4e14\u662f <code>defer<\/code> \u76f4\u63a5\u8c03\u7528\u624d\u80fd\u6355\u83b7 <code>panic<\/code>\u3002<\/li><\/ul><h2 id=\"\u53c2\u8003\">\u53c2\u8003<\/h2><ol><li><a href=\"https:\/\/golang.org\/ref\/spec#Handling_panics\">https:\/\/golang.org\/ref\/spec#Handling_panics<\/a><\/li><li><a href=\"https:\/\/blog.golang.org\/defer-panic-and-recover\">https:\/\/blog.golang.org\/defer-panic-and-recover<\/a><\/li><\/ol>"},{"title":"\u7406\u89e3 golang \u8fd0\u884c\u65f6\u8c03\u5ea6","link":"https:\/\/sunpe.github.io\/posts\/2020-06-05-golang-runtime-schedule\/","pubDate":"Fri, 05 Jun 2020 22:00:00 +0800","guid":"https:\/\/sunpe.github.io\/posts\/2020-06-05-golang-runtime-schedule\/","description":"<p>\u64cd\u4f5c\u7cfb\u7edf\u7ebf\u7a0b\uff08OS thread\uff09\u5bf9\u4e8e golang \u6765\u8bf4\u592a\u91cd\u4e86\u3002\u800c\u4e14\u6700\u91cd\u8981\u7684\u662f\u64cd\u4f5c\u7cfb\u7edf\uff08OS\uff09\u65e0\u6cd5\u57fa\u4e8e golang \u6a21\u578b\u505a\u51fa\u6b63\u786e\u7684\u8c03\u5ea6\u3002\u6bd4\u5982\uff0cGC\u7684\u65f6\u5019\u8981\u6682\u505c\u6240\u6709\u7684\u7ebf\u7a0b\uff08go\u4e2d\u5bf9\u5e94\u7684\u662f groutine\uff09\uff0c \u800c\u4e14\u5185\u5b58\u8981\u5904\u4e8e\u4e00\u81f4\u7684\u72b6\u6001\uff0c\u8fd9\u9700\u8981\u7b49\u5f85\u8fd0\u884c\u4e2d\u7684\u7ebf\u7a0b\u6267\u884c\u5230\u5185\u5b58\u4e00\u81f4\u72b6\u6001\u7684\u70b9\uff08\u5b89\u5168\u70b9\uff09\u3002\u5f53\u6709\u8bb8\u591a\u7ebf\u7a0b\u65f6, \u4e3a\u4e86\u8fbe\u5230\u4e00\u81f4\u72b6\u6001, \u5c31\u9700\u8981\u7b49\u5f85\u8fd9\u4e9b\u53ef\u80fd\u5904\u4e8e\u4efb\u610f\u72b6\u6001\u7684\u7ebf\u7a0b\u8fbe\u5230\u4e00\u81f4\u72b6\u6001\u3002Golang \u7684\u8c03\u5ea6\u5668\u53ef\u4ee5\u505a\u5230\u4ec5\u5728\u5df2\u77e5\u7684\u5185\u5b58\u4e00\u81f4\u72b6\u6001\u7684\u70b9\u4e0a\u8fdb\u884c\u8c03\u5ea6\u3002<\/p><h2 id=\"golang\u8c03\u5ea6\u5668\">golang\u8c03\u5ea6\u5668<\/h2><p>\u76ee\u524d\u67093\u79cd\u5e38\u89c1\u7684\u7ebf\u7a0b\u6a21\u578b\uff0c\u4e00\u4e2a\u662fN:1\u6a21\u578b\uff0c\u5373\u51e0\u4e2a\u7528\u6237\u7ea7\u7ebf\u7a0b\u8fd0\u884c\u5728\u4e00\u4e2a os \u7ebf\u7a0b\uff0c\u8fd9\u79cd\u6a21\u578b\u7684\u4f18\u52bf\u662f\u53ef\u4ee5\u975e\u5e38\u5feb\u7684\u8fdb\u884c\u4e0a\u4e0b\u6587\u5207\u6362\uff08context switch\uff09\uff0c\u7f3a\u70b9\u662f\u4e0d\u80fd\u5145\u5206\u5229\u7528\u591a\u6838 CPU \u7684\u4f18\u52bf\uff1b\u53e6\u5916\u4e00\u4e2a\u662f 1:1 \u6a21\u578b\uff0c\u5373\u4e00\u4e2a\u7528\u6237\u7ea7\u7ebf\u7a0b\u5bf9\u5e94\u4e00\u4e2a os \u7ebf\u7a0b\uff0c\u597d\u5904\u662f\u53ef\u4ee5\u5229\u7528\u591a\u6838 CPU \u7684\u4f18\u52bf\uff0c\u7f3a\u70b9\u662f\u4e0a\u4e0b\u6587\u5207\u6362\uff08Content switch\uff09\u6210\u672c\u6bd4\u8f83\u9ad8\u3002<\/p><p>Golang\u91c7\u7528\u7b2c\u4e09\u79cd\u6a21\u578b \u2014 M:N\uff0c\u5373M\u4e2a\u7528\u6237\u7ea7\u7ebf\u7a0b\uff08goroutine\uff09\u8fd0\u884c\u5728 N \u4e2a OS \u7ebf\u7a0b\u4e0a\uff0c\u8fd9\u6837\u65e2\u53ef\u4ee5\u5feb\u901f\u7684\u8fdb\u884c\u4e0a\u4e0b\u6587\u5207\u6362\uff08context switch\uff09\uff0c\u53c8\u53ef\u4ee5\u5229\u7528\u591a\u6838 CPU \u7684\u4f18\u52bf\u3002<\/p><p>\u5982\u56fe1\u6240\u793a\uff0cGolang \u8c03\u5ea6\u5668\u4e2d\u4e3b\u8981\u6709\u4e09\u79cd\u89d2\u8272\uff1a<\/p><p><img src=\"https:\/\/sunpe.github.io\/images\/golang_schedule\/1.png\" alt=\"\">\u56fe1<\/p><p>\u4e09\u89d2\u5f62M\u4ee3\u8868 OS \u7ebf\u7a0b\uff0c\u53ef\u4ee5\u7406\u89e3\u4e3a machine \u7684\u7f29\u5199\uff0c\u7531\u7cfb\u7edf\u7ba1\u7406\u548c\u6267\u884c\uff0c\u662f runtime \u4ee3\u7801\u4e2d\u7684 M\u3002<\/p><p>\u5706\u5f62 G \u4ee3\u8868 goroutine\uff0c\u6709\u81ea\u5df1\u7684\u6808\u3001\u8ba1\u6570\u5668\uff08instruction pointer\uff09\u548c\u5176\u4ed6\u8c03\u5ea6\u9700\u8981\u7684\u91cd\u8981\u4fe1\u606f\uff0c\u50cf\u5728\u7b49\u5f85\u7684 channel \u7b49\uff0c\u662f runtime \u4ee3\u7801\u4e2d\u7684 G\u3002<\/p><p>\u6b63\u65b9\u5f62P\u4ee3\u8868\u8c03\u5ea6\u4e0a\u4e0b\u6587\uff08context\uff09\uff0c\u53ef\u4ee5\u7406\u89e3\u4e3a Processor\uff08\u5904\u7406\u5355\u5143\uff09\uff0cP \u8868\u793a\u5728\u5355\u4e2a os \u7ebf\u7a0b\u4e0a\u8fd0\u884c Go \u4ee3\u7801\uff0c\u662f\u5b9e\u73b0 N:1 \u5230 M:N \u8c03\u5ea6\u7684\u5173\u952e\uff0c\u662f runtime \u4ee3\u7801\u4e2d\u7684 P\u3002<\/p><p><img src=\"https:\/\/sunpe.github.io\/images\/golang_schedule\/2.png\" alt=\"\">\u56fe2<\/p><p>\u5982\u56fe 2 \u6240\u793a\uff0c\u6709\u4e24\u4e2a os \u7ebf\u7a0b\uff08M\uff09\uff0c\u6bcf\u4e2a M \u6709\u4e00\u4e2a context\uff08P\uff09\uff0c\u6bcf\u4e2a P \u8fd0\u884c\u4e00\u4e2a goroutine\uff08G\uff09\u3002os \u7ebf\u7a0b\uff08M\uff09\u8981\u6267\u884c goroutine\uff08G\uff09\uff0c\u5fc5\u987b\u8981\u62ff\u5230 context\uff08P\uff09\u3002P \u7684\u6570\u91cf\u53ef\u4ee5\u5728\u7a0b\u5e8f\u542f\u52a8\u65f6, \u901a\u8fc7\u73af\u5883\u53d8\u91cf GOMAXPROCS \u6216\u8005 runtime.GOMAXPROCS() \u8bbe\u7f6e\uff0c\u9ed8\u8ba4\u503c\u662f\u7cfb\u7edf\u7684\u7ebf\u7a0b\u6570\uff0c\u800c\u4e14\u5728\u7a0b\u5e8f\u6267\u884c\u671f\u95f4\u901a\u5e38\u4e0d\u4f1a\u53d8\u52a8\uff0c\u4efb\u4f55\u65f6\u523b\u53ea\u6709 GOMAXPROCS \u6570\u91cf\u7684\u7684 P \u5728\u6267\u884c go \u4ee3\u7801\u3002<\/p><p>\u7070\u8272\u7684 G \u8868\u793a\u6ca1\u5728\u8fd0\u884c\u4f46\u5904\u4e8e\u5c31\u7eea\u72b6\u6001\u7684 goroutine\uff0c\u8fd9\u4e9b goroutine \u5728 runqueues \u961f\u5217\u4e2d\u6392\u961f\u7b49\u5f85\u6267\u884c\u3002\u5f53\u4ee3\u7801\u4e2d\u8c03\u7528 go \u8868\u8fbe\u5f0f\u65f6\uff0c\u65b0\u521b\u5efa\u7684 goroutine \u4f1a\u6dfb\u52a0\u5230 runqueues \u961f\u5217\u5c3e\uff0cP \u4f1a\u4ece runqueues \u961f\u5217\u5934\u53d6\u51fa\u4e00\u4e2a G\uff0c\u5e76\u8bbe\u7f6e\u597d\u6808\u548c\u8ba1\u6570\u5668\uff08instruction pointer\uff09\uff0c\u7136\u540e\u5f00\u59cb\u8fd0\u884c goroutine\u3002\u4e3a\u4e86\u964d\u4f4e\u9501\u7684\u7ade\u4e89\uff0c\u9664\u4e86\u5168\u5c40\u7684 runqueues\uff0c\u6bcf\u4e2a P \u90fd\u6709\u81ea\u5df1\u7684 runqueue\uff08\u65e9\u671f\u7248\u672c\u7684 Golang \u8c03\u5ea6\u5668\u53ea\u6709\u4e00\u4e2a\u5168\u5c40\u7684 runqueue\uff0c\u4ee5\u81f3\u4e8e\u8c03\u5ea6\u7684\u65f6\u5019\u7ecf\u5e38\u56e0\u4e3a\u9501\u800c block\uff09\u3002<\/p><p>\u4e3a\u4ec0\u4e48\u8981\u6709 P(context)\uff0c\u76f4\u63a5\u628a runqueue \u653e\u5230 M \u4e0a\u4e0d\u662f\u633a\u597d\u5417\uff1f\u8bbe\u8ba1 P(context) \u7684\u539f\u56e0\u662f\uff0c\u8fd0\u884c\u4e2d\u7684 goroutine \u5982\u679c\u7531\u4e8e\u67d0\u79cd\u539f\u56e0 block\uff0c\u901a\u8fc7P\u53ef\u4ee5\u5c06\u5176\u79fb\u4ea4\u7ed9\u5176\u4ed6\u7ebf\u7a0b\u3002\u4f8b\u5982, \u5f53\u4e00\u4e2a\u7cfb\u7edf\u8c03\u7528 block \u4e86\uff0c\u4e5f\u5c31\u662f M \u88ab block \u4e86\uff0c\u8fd9\u65f6\u5019\u9700\u8981\u5c06 P \u4ece\u8fd9\u4e2a M \u4e0a\u79fb\u8d70\uff0c\u4ee5\u4fbf M \u53ef\u4ee5\u7ee7\u7eed\u6267\u884c\u5176\u4ed6 P\u3002\u56fe 3 \u4e2d\u5de6\u534a\u90e8\u5206\uff0cM0 \u6267\u884c G0 \u65f6\uff0c\u8c03\u7528\u4e86\u4e00\u4e2a syscall\uff0c\u800c\u88ab\u963b\u585e\u4e86\uff0c\u4e3a\u4e86\u4e0d\u5f71\u54cd\u540e\u7eed G \u7684\u8fd0\u884c\uff0cP \u5c06\u5176\u79fb\u4ea4\u7ed9 M1\uff0cM0 \u7ee7\u7eed\u6267\u884c\u5176\u4ed6 G\u3002\u5f53 G0 \u7684 syscall \u8fd4\u56de\u65f6\uff0cM1 \u5c1d\u8bd5\u83b7\u53d6 P\uff0c\u4ee5\u4fbf\u80fd\u7ee7\u7eed\u6267\u884c G0\uff0c\u5982\u679c\u83b7\u53d6\u5931\u8d25\uff0cM1 \u4f1a\u5c06 G0 \u653e\u5230\u5168\u5c40\u7684 runqueue \u4e2d\u3002<\/p><p><img src=\"https:\/\/sunpe.github.io\/images\/golang_schedule\/3.png\" alt=\"\">\u56fe3<\/p><p>\u6bcf\u5f53P\u6267\u884c\u5b8c\u81ea\u5df1\u7684 runqueue \u65f6\u90fd\u4f1a\u4ece\u5168\u5c40\u7684 runqueue \u4e2d\u83b7\u53d6\u65b0\u7684 G\uff0cP \u4e5f\u5c31\u5b9a\u65f6\u68c0\u67e5\u5168\u5c40 runqueue\uff0c\u9632\u6b62\u5168\u5c40 runqueue \u4e0a\u6709\u6c38\u8fdc\u6267\u884c\u4e0d\u5230\u7684 G\u3002\u5982\u679c Context\uff08P\uff09\u672c\u5730 runqueue \u7a7a\u4e86\uff0c\u5168\u5c40\u7684 runqueue \u4e2d\u4e5f\u6ca1\u5f85\u6267\u884c\u7684 G\uff0cP \u4f1a\u5c1d\u8bd5\u4ece\u522b\u7684 P \u7684 runqueue \u961f\u5217\u4e2d\u7a83\u53d6\uff08work steal\uff09\u4e00\u534a\u7684 groutine\uff0c\u8fd9\u6837\u5c31\u4fdd\u8bc1\u4e86\u6bcf\u4e2a P \u90fd\u6709\u4e8b\u505a\uff0c\u4e5f\u5c31\u8ba9 M \u6700\u5927\u9650\u5ea6\u7684\u5de5\u4f5c\u3002<\/p><p><img src=\"https:\/\/sunpe.github.io\/images\/golang_schedule\/4.png\" alt=\"\"><\/p><h2 id=\"\u603b\u7ed3\">\u603b\u7ed3<\/h2><p>\u8fd9\u7bc7\u6587\u7ae0\u7b80\u5355\u63cf\u8ff0\u4e86 golang \u8fd0\u884c\u65f6\u8c03\u5ea6\uff0c\u6211\u4eec\u4e86\u89e3\u5230\uff1a<\/p><ul><li>golang \u7ebf\u7a0b\u6a21\u578b\u662f M:N \u7684<\/li><li>M \u6267\u884c goroutine \u7684\u5fc5\u8981\u6761\u4ef6\u662f\u5fc5\u987b\u83b7\u53d6 processor<\/li><li>\u5982\u679c goroutine \u88ab\u963b\u585e\uff0c\u963b\u585e\u7684\u4e0d\u662f M\uff0c\u800c\u662f processor<\/li><li>\u6bcf\u4e2a P \u90fd\u6709\u81ea\u5df1\u7684 runqueues\uff0c\u9664\u6b64\u4e4b\u5916\u8fd8\u6709\u4e00\u4e2a\u5168\u5c40\u7684 runqueues<\/li><li>P \u5b9e\u73b0\u4e86 work steal<\/li><\/ul><h2 id=\"\u53c2\u8003\u8d44\u6599\">\u53c2\u8003\u8d44\u6599<\/h2><ol><li><a href=\"https:\/\/morsmachine.dk\/go-scheduler\">https:\/\/morsmachine.dk\/go-scheduler<\/a><\/li><\/ol>"},{"title":"golang \u9879\u76ee\u7ed3\u6784","link":"https:\/\/sunpe.github.io\/posts\/2020-05-22-golang-project-struct\/","pubDate":"Fri, 22 May 2020 22:00:00 +0800","guid":"https:\/\/sunpe.github.io\/posts\/2020-05-22-golang-project-struct\/","description":"<p>\u5e38\u89c1\u7684golang\u4ee3\u7801\u5e03\u5c40\u65b9\u5f0f\u901a\u5e38\u6709\u6241\u5e73\u5316\u5e03\u5c40\u548c\u6a21\u5757\u5316\u5e03\u5c40\u3002<\/p><h2 id=\"\u6241\u5e73\u5316\u5e03\u5c40\">\u6241\u5e73\u5316\u5e03\u5c40<\/h2><p>\u6241\u5e73\u5316\u5e03\u5c40\u5f88\u7b80\u5355\uff0c\u4ee3\u7801\u4e4b\u95f4\u4e0d\u5206\u5c42\uff0c\u6240\u6709\u4ee3\u7801\u653e\u5728\u540c\u4e00\u4e2a\u76ee\u5f55\u3002\u8fd9\u79cd\u5e03\u5c40\u98ce\u683c\u9002\u5408\u6bd4\u8f83\u7b80\u5355\u7684\u9879\u76ee\u3002\u6211\u4eec\u89c1\u5230\u7684\u5de5\u5177\u5305\u901a\u5e38\u5c31\u662f\u8fd9\u79cd\u5e03\u5c40\uff0c\u4f8b\u5982 <a href=\"https:\/\/github.com\/pkg\/errors\">errors<\/a> \u9879\u76ee\u7684\u7ed3\u6784\uff1a<\/p><div class=\"highlight\"><pre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"><code class=\"language-markdown\" data-lang=\"markdown\"><span style=\"display:flex;\"><span>project<\/span><\/span><span style=\"display:flex;\"><span>|<\/span><\/span><span style=\"display:flex;\"><span>|- bench_test.go<\/span><\/span><span style=\"display:flex;\"><span>|<\/span><\/span><span style=\"display:flex;\"><span>|-errors.go<\/span><\/span><span style=\"display:flex;\"><span>|<\/span><\/span><span style=\"display:flex;\"><span>|-errors_test.go<\/span><\/span><span style=\"display:flex;\"><span>|<\/span><\/span><span style=\"display:flex;\"><span>|-example_test.go<\/span><\/span><span style=\"display:flex;\"><span>|<\/span><\/span><span style=\"display:flex;\"><span>|-format_test.go<\/span><\/span><span style=\"display:flex;\"><span>|<\/span><\/span><span style=\"display:flex;\"><span>|-go113.go<\/span><\/span><span style=\"display:flex;\"><span>|<\/span><\/span><span style=\"display:flex;\"><span>|-go113_test.go<\/span><\/span><span style=\"display:flex;\"><span>|<\/span><\/span><span style=\"display:flex;\"><span>|-json_test.go<\/span><\/span><span style=\"display:flex;\"><span>|<\/span><\/span><span style=\"display:flex;\"><span>|-stack.go<\/span><\/span><span style=\"display:flex;\"><span>|<\/span><\/span><span style=\"display:flex;\"><span>|-stack_test.go<\/span><\/span><\/code><\/pre><\/div><p>\u503c\u5f97\u6ce8\u610f\u7684\u662f\uff0c\u5de5\u5177\u5305\u4e2d\u5c3d\u91cf\u4e0d\u8981\u6709\u7b2c\u4e09\u65b9\u4f9d\u8d56\uff0c\u5426\u5219\uff0c\u7ef4\u62a4\u5de5\u5177\u5305\u4e2d\u7684\u7b2c\u4e09\u65b9\u4f9d\u8d56\u4f1a\u5f88\u9ebb\u70e6\uff0c\u4e5f\u5f88\u5bb9\u6613\u7ed9\u5176\u4ed6\u9879\u76ee\u5e26\u6765\u7248\u672c\u51b2\u7a81\u7b49\u95ee\u9898\u3002<\/p><h2 id=\"\u6a21\u5757\u5316\u5e03\u5c40\">\u6a21\u5757\u5316\u5e03\u5c40<\/h2><p>\u9879\u76ee\u7a0d\u5fae\u590d\u6742\u4e00\u4e9b\u4e4b\u540e\uff0c\u6241\u5e73\u5316\u5e03\u5c40\u4f1a\u663e\u5f97\u6bd4\u8f83\u6df7\u4e71\uff0c\u6211\u4eec\u901a\u5e38\u4f1a\u6309\u529f\u80fd\u5c06\u4ee3\u7801\u653e\u5230\u4e0d\u540c\u7684\u76ee\u5f55\u4e2d\uff0c\u4e5f\u5c31\u662f\u6a21\u5757\u5316\u7684\u5e03\u5c40\u65b9\u5f0f\u3002\u4ece 1.14 \u7248\u672c\u4e4b\u540e\uff0c\u5b98\u65b9\u63a8\u8350\u4f7f\u7528 <code>[Go Modules](https:\/\/blog.golang.org\/using-go-modules)<\/code> \u7ba1\u7406\u4f9d\u8d56\uff0c\u9879\u76ee\u4e00\u822c\u4f1a\u7531 <code>cmd<\/code>\u3001 <code>internal<\/code>\u3001 <code>pkg<\/code>\u3001 <code>vendor<\/code> \u7b49\u76ee\u5f55\u7ec4\u6210\uff0c\u5f53\u7136\u8fd9\u4e0d\u662f\u5b98\u65b9\u5efa\u8bae\u7684\u9879\u76ee\u7ed3\u6784\uff0c\u53ea\u662f\u76ee\u524d\u6bd4\u8f83\u5e38\u89c1\u7684\u5e03\u5c40\u65b9\u5f0f\u3002<\/p><div class=\"highlight\"><pre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"><code class=\"language-markdown\" data-lang=\"markdown\"><span style=\"display:flex;\"><span>project<\/span><\/span><span style=\"display:flex;\"><span>|<\/span><\/span><span style=\"display:flex;\"><span>|-- cmd\/<\/span><\/span><span style=\"display:flex;\"><span>| |<\/span><\/span><span style=\"display:flex;\"><span>| |-- app1\/<\/span><\/span><span style=\"display:flex;\"><span>| | |<\/span><\/span><span style=\"display:flex;\"><span>| | |- main.go<\/span><\/span><span style=\"display:flex;\"><span>| | |<\/span><\/span><span style=\"display:flex;\"><span>| | |- handler\/<\/span><\/span><span style=\"display:flex;\"><span>| |<\/span><\/span><span style=\"display:flex;\"><span>| |-- app2\/<\/span><\/span><span style=\"display:flex;\"><span>| |<\/span><\/span><span style=\"display:flex;\"><span>| |- main.go<\/span><\/span><span style=\"display:flex;\"><span>| |<\/span><\/span><span style=\"display:flex;\"><span>| |- handler\/<\/span><\/span><span style=\"display:flex;\"><span>|<\/span><\/span><span style=\"display:flex;\"><span>|-- internal\/<\/span><\/span><span style=\"display:flex;\"><span>| |<\/span><\/span><span style=\"display:flex;\"><span>| |-- pkg<\/span><\/span><span style=\"display:flex;\"><span>| | |<\/span><\/span><span style=\"display:flex;\"><span>| | |-- data<\/span><\/span><span style=\"display:flex;\"><span>| | |<\/span><\/span><span style=\"display:flex;\"><span>| | |-- log<\/span><\/span><span style=\"display:flex;\"><span>| |<\/span><\/span><span style=\"display:flex;\"><span>| |-- router<\/span><\/span><span style=\"display:flex;\"><span>| |<\/span><\/span><span style=\"display:flex;\"><span>| |-- service<\/span><\/span><span style=\"display:flex;\"><span>|<\/span><\/span><span style=\"display:flex;\"><span>|-- pkg\/<\/span><\/span><span style=\"display:flex;\"><span>| |<\/span><\/span><span style=\"display:flex;\"><span>| |-- kit<\/span><\/span><span style=\"display:flex;\"><span>|<\/span><\/span><span style=\"display:flex;\"><span>|-- vendor\/<\/span><\/span><span style=\"display:flex;\"><span>|<\/span><\/span><span style=\"display:flex;\"><span>|-- go.mod<\/span><\/span><span style=\"display:flex;\"><span>|<\/span><\/span><span style=\"display:flex;\"><span>|-- go.sum<\/span><\/span><\/code><\/pre><\/div><h3 id=\"cmd\">cmd\/<\/h3><p><code>cmd<\/code> \u76ee\u5f55\u9879\u76ee\u4e2d\u7684\u53ef\u6267\u884c\u7a0b\u5e8f\u7684\u5165\u53e3\uff0c\u4e3b\u8981\u653e\u7f6e <code>main()<\/code> \u51fd\u6570\uff0c\u6bcf\u4e2a\u53ef\u6267\u884c\u7a0b\u5e8f\u5bf9\u5e94\u4e00\u4e2a\u5b50\u6587\u4ef6\u5939\uff0c\u6587\u4ef6\u5939\u5e94\u4ee5\u7a0b\u5e8f\u7684\u540d\u79f0\u547d\u540d\uff0c\u53ef\u4ee5\u5728\u540d\u5b57\u540e\u9762\u52a0\u5b57\u6bcd <code>d<\/code>\uff0c\u8868\u793a\u7a0b\u5e8f\u5c06\u4ee5\u5b88\u62a4\u8fdb\u7a0b\u7684\u65b9\u5f0f\u8fd0\u884c\u3002\u5e94\u7528\u7a0b\u5e8f\u4e2d\u5fc5\u987b\u5305\u542b\u4e00\u4e2a <code>main()<\/code> \u51fd\u6570\u7684\u6e90\u6587\u4ef6\uff0c\u5373 demo \u4e2d\u7684 <code>main.go<\/code>\uff0c\u6587\u4ef6\u540d\u5b57\u6700\u597d\u4e0e\u7a0b\u5e8f\u540d\u5b57\u4e00\u81f4\u3002<code>cmd<\/code> \u5305\u53ef\u80fd\u4f1a\u5bfc\u5165 <code>internal<\/code>\u3001<code>pkg<\/code> \u6216 <code>vendor<\/code> \u5305\u4e2d\u7684\u4ee3\u7801\u3002<\/p><h2 id=\"internal\">internal\/<\/h2><p><code>internal<\/code> \u76ee\u5f55\u662f\u9879\u76ee\u79c1\u6709\u7684\u4ee3\u7801\u3002 1.4 \u7248\u672c\u65b0\u589e\u4e86 <a href=\"https:\/\/golang.org\/doc\/go1.4#internalpackages\">Internal packages<\/a> \u7279\u6027\uff0c<code>internal<\/code> \u76ee\u5f55\u4e2d\u7684\u4ee3\u7801\u53ea\u80fd\u88ab <code>internal<\/code> \u76ee\u5f55\u7684\u7236\u76ee\u5f55\u4e0b\u7684\u5b50\u76ee\u5f55\u5f15\u7528\uff0c\u4e3e\u4e2a\u4f8b\u5b50 <code>...\/a\/b\/c\/internal\/d\/e\/f<\/code> \u4ec5\u4ec5\u53ef\u4ee5\u88ab <code>...\/a\/b\/c<\/code> \u4e0b\u7684\u76ee\u5f55\u5bfc\u5165\uff0c<code>...\/a\/b\/g<\/code> \u5219\u4e0d\u5141\u8bb8\u3002\u9664\u4e86 <code>internal<\/code> \u6839\u76ee\u5f55\u4e4b\u5916\uff0c\u4e5f\u53ef\u4ee5\u5728\u4efb\u4f55\u76ee\u5f55\u4e0b\u521b\u5efa <code>internal<\/code> \u76ee\u5f55\u3002<\/p><h2 id=\"pkg\">pkg\/<\/h2><p>\u653e\u5728 <code>pkg<\/code> \u76ee\u5f55\u4e0b\u7684\u4ee3\u7801\u53ef\u4ee5\u88ab\u5176\u4ed6\u9879\u76ee\u76f4\u63a5\u5bfc\u5165\u3002\u53ef\u4ee5\u7406\u89e3\u4e3a <code>internal<\/code> \u76ee\u5f55\u4e0b\u7684\u4ee3\u7801\u662f\u9879\u76ee\u7684\u79c1\u6709\u4ee3\u7801\uff0c\u800c <code>pkg<\/code> \u76ee\u5f55\u4e0b\u7684\u4ee3\u7801\u662f\u5f00\u653e\u7684\u4ee3\u7801\u3002\u5982\u679c\u9879\u76ee\u4e2d\u4e0d\u5305\u542b\u516c\u5171\u7684\u4ee3\u7801\uff0c\u5219\u53ef\u4ee5\u4e0d\u9700\u8981 <code>pkg<\/code> \u5305\u3002\u800c\u4e14\u5982\u679c\u9879\u76ee\u8db3\u591f\u5c0f\uff0c\u6216\u8005\u9879\u76ee\u53ea\u662f\u4e00\u4e2a\u5de5\u5177\u5305\uff0c\u4e5f\u5b8c\u5168\u4e0d\u9700\u8981 <code>pkg<\/code> \u5305\u3002<\/p><h3 id=\"vendor\">vendor\/<\/h3><p>\u5b58\u653e\u9879\u76ee\u4f9d\u8d56\u7684\u76ee\u5f55\uff0c\u901a\u5e38\u662f\u4f9d\u8d56\u7ba1\u7406\u5de5\u5177\u81ea\u5df1\u6765\u7ef4\u62a4\u3002\u4f8b\u5982, <code>go mod vendor<\/code> \u547d\u4ee4\u4f1a\u5c06\u9879\u76ee\u7684\u4f9d\u8d56\u653e\u5230 <code>vendor<\/code> \u76ee\u5f55\u3002<\/p><h3 id=\"\u5176\u4ed6\u76ee\u5f55\">\u5176\u4ed6\u76ee\u5f55<\/h3><p>\u4e0d\u540c\u7c7b\u578b\u7684\u9879\u76ee\u901a\u5e38\u8fd8\u5305\u62ec\u5176\u4ed6\u7684\u4e00\u4e9b\u76ee\u5f55\uff0c\u6bd4\u5982\u670d\u52a1\u578b\u9879\u76ee\u901a\u5e38\u4f1a\u6709\u4e00\u4e2a <code>api<\/code> \u76ee\u5f55\uff0cweb \u9879\u76ee\u901a\u5e38\u4f1a\u6709\u4e00\u4e2a <code>web<\/code> \u76ee\u5f55\u4ee5\u5b58\u653e\u9759\u6001\u8d44\u6e90\uff0c\u5de5\u5177\u5305\u7c7b\u578b\u7684\u9879\u76ee\u901a\u5e38\u4f1a\u5305\u542b\u4e00\u4e2a <code>examples<\/code> \u76ee\u5f55\u3002<\/p><h2 id=\"\u603b\u7ed3\">\u603b\u7ed3<\/h2><p>\u8fd9\u7bc7\u6587\u7ae0\u7b80\u5355\u7684\u63cf\u8ff0\u4e86\u5e38\u89c1\u7684 golang \u9879\u76ee\u5e03\u5c40\u65b9\u5f0f\uff0c\u5b9e\u9645\u9879\u76ee\u4e2d\uff0c\u4e0d\u4e00\u5b9a\u8981\u6309\u7167\u8fd9\u4e24\u79cd\u65b9\u5f0f\u6765\u7ec4\u7ec7\u4ee3\u7801\u7ed3\u6784\uff0c\u4e00\u5207\u4ee5\u5b9e\u9645\u9879\u76ee\u4e3a\u51c6\u3002\u5148\u8ba9\u4ee3\u7801\u80fd\u8dd1\u8d77\u6765\uff0c \u518d\u8bd5\u56fe\u8ba9\u5b83\u53d8\u5f97\u66f4\u597d\uff0c\u6700\u540e\u518d\u8bd5\u7740\u8ba9\u5b83\u53d8\u5f97\u66f4\u5feb\u3002<\/p>"},{"title":"\u6b7b\u9501\u6761\u4ef6","link":"https:\/\/sunpe.github.io\/posts\/2020-04-30-dead-lock\/","pubDate":"Thu, 30 Apr 2020 22:00:00 +0800","guid":"https:\/\/sunpe.github.io\/posts\/2020-04-30-dead-lock\/","description":"<p>\u6b7b\u9501\uff08deadlock\uff09\u662f\u6307\u4e24\u4e2a\u8fdb\u7a0b\u88ab\u76f8\u4e92\u963b\u585e\uff0c\u5e76\u4e14\u4e00\u76f4\u5904\u4e8e\u8fd9\u6837\u7684\u72b6\u6001\u3002<\/p><p>\u5927\u90e8\u5206\u6b7b\u9501\u90fd\u548c\u8d44\u6e90\u6709\u5173\uff0c\u6309\u5360\u7528\u65b9\u5f0f\u6765\u770b\uff0c\u8d44\u6e90\u5206\u4e3a\u4e24\u7c7b\uff1a\u53ef\u62a2\u5360\u8d44\u6e90\u548c\u4e0d\u53ef\u62a2\u5360\u8d44\u6e90\u3002\u53ef\u62a2\u5360\u8d44\u6e90\uff08preemptable resource\uff09\u53ef\u4ee5\u4ece\u62e5\u6709\u5b83\u7684\u8fdb\u7a0b\u4e2d\u62a2\u5360\u800c\u4e0d\u4f1a\u4ea7\u751f\u4efb\u4f55\u526f\u4f5c\u7528\uff1b\u4e0d\u53ef\u62a2\u5360\u8d44\u6e90\uff08nonpreemptable resource\uff09\u662f\u6307\u4e0d\u80fd\u4ece\u5f53\u524d\u5360\u7528\u5b83\u7684\u8fdb\u7a0b\u4e2d\u5f3a\u884c\u62a2\u5360\u7684\u8d44\u6e90\uff0c\u5fc5\u987b\u7531\u62e5\u6709\u8005\u4e3b\u52a8\u91ca\u653e\u3002<\/p><p>Coffman \u603b\u7ed3\u4e86\u53d1\u751f\u6b7b\u9501\u7684\u56db\u4e2a\u5fc5\u8981\u6761\u4ef6\uff1a<\/p><ul><li>\u76f8\u4e92\u6392\u65a5\uff0c\u5e76\u53d1\u8fdb\u7a0b\u540c\u65f6\u62e5\u6709\u8d44\u6e90\u7684\u72ec\u5360\u6743\u3002<\/li><li>\u7b49\u5f85\u6761\u4ef6\uff0c\u5e76\u53d1\u8fdb\u7a0b\u5fc5\u987b\u540c\u65f6\u62e5\u6709\u4e00\u4e2a\u8d44\u6e90\uff0c\u5e76\u7b49\u5f85\u989d\u5916\u7684\u8d44\u6e90\u3002<\/li><li>\u4e0d\u53ef\u62a2\u5360\uff0c\u5e76\u53d1\u8fdb\u7a0b\u62e5\u6709\u7684\u8d44\u6e90\u53ea\u80fd\u88ab\u8be5\u8fdb\u7a0b\u91ca\u653e\u3002<\/li><li>\u5faa\u73af\u7b49\u5f85\uff0c\u4e00\u4e2a\u5e76\u53d1\u8fdb\u7a0b\uff08P1\uff09\u5fc5\u987b\u7b49\u5f85\u4e00\u7cfb\u5217\u7684\u5176\u4ed6\u5e76\u53d1\u8fdb\u7a0b\uff08P2\uff09\u8fd9\u4e9b\u5e76\u53d1\u8fdb\u7a0b\u540c\u65f6\u4e5f\u5728\u7b49\u5f85\u8fdb\u7a0b\uff08P1\uff09<\/li><\/ul><p>\u6b7b\u9501\u53d1\u751f\u65f6\uff0c\u4e00\u5b9a\u540c\u4e8b\u6ee1\u8db3\u8fd9\u56db\u4e2a\u6761\u4ef6\uff0c\u5982\u679c\u5176\u4e2d\u67d0\u4e00\u6761\u4ef6\u4e0d\u6ee1\u8db3\uff0c\u6b7b\u9501\u5c31\u4e0d\u4f1a\u53d1\u751f\u3002<\/p>"},{"title":"\u6570\u636e\u7ed3\u6784--\u961f\u5217","link":"https:\/\/sunpe.github.io\/posts\/2020-04-17-data-struct-queue\/","pubDate":"Fri, 17 Apr 2020 22:00:00 +0800","guid":"https:\/\/sunpe.github.io\/posts\/2020-04-17-data-struct-queue\/","description":"<p>\u548c\u6808\u76f8\u4f3c\uff0c\u961f\u5217\uff08queue\uff09\u4e5f\u662f\u8868\uff0c\u6240\u4e0d\u540c\u7684\u662f\u961f\u5217\u7684\u63d2\u5165\u5728\u8868\u7684\u4e00\u7aef\u8fdb\u884c\u800c\u5220\u9664\u5219\u5728\u53e6\u4e00\u7aef\u8fdb\u884c\u3002\u4e0e\u6808\u7684\u540e\u8fdb\u5148\u51fa\uff08LIFO\uff09\u4e0d\u540c\uff0c\u961f\u5217\u4e2d\u7684\u5143\u7d20\u7279\u6027\u662f\u5148\u8fdb\u5148\u51fa\uff08FIFO\uff09\u3002<\/p><p><img src=\"https:\/\/sunpe.github.io\/images\/data_struct_queue\/1.png\" alt=\"\">\u56fe 1<\/p><p>\u961f\u5217\u7684\u57fa\u672c\u64cd\u4f5c\uff1a<\/p><ul><li>\u5165\u961f\uff0c\u5728\u8868\u7684\u672b\u7aef\uff0c\u4e5f\u53eb\u961f\u5c3e\uff08rear\uff09\uff0c\u63d2\u5165\u4e00\u4e2a\u5143\u7d20<\/li><li>\u51fa\u961f\uff0c\u5220\u9664\u6216\u8fd4\u56de\u8868\u7684\u5f00\u5934\uff0c\u4e5f\u53eb\u961f\u5934\uff08front\uff09\u7684\u5143\u7d20<\/li><\/ul><h2 id=\"\u961f\u5217\u7684\u5b9e\u73b0\">\u961f\u5217\u7684\u5b9e\u73b0<\/h2><p>\u5982\u540c\u6808\u4e00\u6837\uff0c\u5bf9\u4e8e\u961f\u5217\u800c\u8a00\uff0c\u4efb\u4f55\u8868\u7684\u5b9e\u73b0\u90fd\u662f\u5408\u6cd5\u7684\u3002\u5bf9\u4e8e\u5165\u961f\u548c\u51fa\u961f\u64cd\u4f5c\uff0c\u94fe\u8868\u548c\u6570\u7ec4\u7684\u5b9e\u73b0\u90fd\u80fd\u7ed9\u51fa O(1) \u7684\u8fd0\u884c\u65f6\u95f4\u3002<\/p><h3 id=\"\u961f\u5217\u7684\u6570\u7ec4slice\u5b9e\u73b0\">\u961f\u5217\u7684\u6570\u7ec4slice\u5b9e\u73b0<\/h3><p>\u5bf9\u4e8e\u961f\u5217\u6570\u636e\u7ed3\u6784\uff0c\u6211\u4eec\u4fdd\u7559\u4e00\u4e2a\u6570\u7ec4 []interface\u3001 \u961f\u5934\u4f4d\u7f6e front\u3001 \u961f\u5c3e\u4f4d\u7f6e rear \u4ee5\u53ca\u961f\u5217\u4e2d\u5143\u7d20\u7684\u4e2a\u6570 size. \u5982\u679c\u6709\u5143\u7d20 X \u5165\u961f\uff0c\u53ef\u4ee5\u8ba9 size \u548c rear \u52a0 1\uff0c\u7136\u540e\u8bbe\u7f6e Queue[rear]=X\u3002\u5982\u679c\u6709\u5143\u7d20\u51fa\u961f\uff0c\u9700\u8981\u8fd4\u56de Queue[front]\uff0c\u7136\u540esize\u51cf1\uff0cfront\u52a01\u3002<\/p><p><img src=\"https:\/\/sunpe.github.io\/images\/data_struct_queue\/2.png\" alt=\"\">\u56fe 2<\/p><p>\u901a\u8fc7\u6570\u7ec4\u5b9e\u73b0\u961f\u5217\u6709\u4e00\u4e2a\u6f5c\u5728\u7684\u95ee\u9898\uff0c\u7ecf\u8fc7\u51e0\u6b21\u5165\u961f\u548c\u51fa\u961f\u64cd\u4f5c\u4e4b\u540e\uff0cfront \u548c rear \u4f1a\u5230\u6570\u7ec4\u7684\u8fb9\u754c\u3002\u7b80\u5355\u7684\u89e3\u51b3\u65b9\u5f0f\u662f\uff0c\u5982\u679c front \u6216 rear \u5230\u8fbe\u6570\u7ec4\u7684\u5c3e\u7aef\uff0c\u5c31\u7ed5\u5230\u5f00\u5934\u3002\u8fd9\u79cd\u65b9\u5f0f\u53eb\u5faa\u73af\u6570\u7ec4\u5b9e\u73b0\u3002<\/p><p>\u901a\u8fc7 slice \u5b9e\u73b0\u961f\u5217\u4e5f\u9700\u8981\u9650\u5236 slice \u7684\u5bb9\u91cf\uff0c\u5728 front \u548c rear \u5230\u8fbe\u8fb9\u754c\u65f6\uff0c\u53ef\u4ee5\u91c7\u7528\u548c\u6570\u7ec4\u540c\u6837\u7684\u903b\u8f91\uff0c\u4ee5\u514d slice \u4e0d\u65ad\u6269\u5bb9\u3002<\/p><h3 id=\"\u961f\u5217\u7684\u94fe\u8868\u5b9e\u73b0\">\u961f\u5217\u7684\u94fe\u8868\u5b9e\u73b0<\/h3><p>\u548c\u6570\u7ec4\u7684\u5b9e\u73b0\u65b9\u5f0f\u7c7b\u4f3c\uff0c\u6211\u4eec\u9700\u8981\u5b9a\u4e49\u4e00\u4e2a\u94fe\u8868\uff0c\u6307\u5411\u961f\u5217\u5934\u5143\u7d20\u7684\u6307\u9488 front\uff0c\u6307\u5411\u961f\u5217\u5c3e\u5143\u7d20\u7684\u6307\u9488 rear\uff0c\u4ee5\u53ca\u961f\u5217\u5143\u7d20\u4e2a\u6570 size\u3002\u5982\u679c\u6709\u5143\u7d20 X \u5165\u961f\uff0c\u53ef\u4ee5\u5c06 X \u6dfb\u52a0\u5230\u94fe\u8868\u7684\u5c3e\u90e8\uff0c\u7136\u540e\u5c06rear \u6307\u5411 X\u3002\u5982\u679c\u5143\u7d20\u51fa\u5bf9\uff0c\u8fd4\u56de\u5e76\u5220\u9664 front \u6307\u5411\u7684\u5143\u7d20\uff0c\u7136\u540e\u5c06 front \u6307\u5411 front \u7684\u524d\u9a71\u5143\u7d20\u3002<\/p><h2 id=\"\u53c2\u8003\u8d44\u6599\">\u53c2\u8003\u8d44\u6599<\/h2><ol><li>\u6570\u636e\u7ed3\u6784\u4e0e\u7b97\u6cd5\u5206\u6790<\/li><\/ol>"},{"title":"\u6570\u636e\u7ed3\u6784--\u6808","link":"https:\/\/sunpe.github.io\/posts\/2020-04-03-data-struct-stack\/","pubDate":"Fri, 03 Apr 2020 22:00:00 +0800","guid":"https:\/\/sunpe.github.io\/posts\/2020-04-03-data-struct-stack\/","description":"<p>\u6808\uff08stack\uff09\u662f\u9650\u5236\u63d2\u5165\u548c\u5220\u9664\u53ea\u80fd\u5728\u4e00\u4e2a\u4f4d\u7f6e\u4e0a\u8fdb\u884c\u7684\u8868\uff0c\u8be5\u4f4d\u7f6e\u53eb\u8868\u7684\u672b\u7aef\uff0c\u6216\u8005\u53eb\u6808\u9876\uff08top\uff09\u3002\u7531\u4e8e\u5bf9\u6808\u4e2d\u6240\u6709\u5143\u7d20\u7684\u64cd\u4f5c\u90fd\u662f\u5728\u6808\u9876\uff0c\u6240\u4ee5\u6808\u6709\u540e\u8fdb\u5148\u51fa\uff08LIFO\uff09\u7684\u7279\u6027\u3002<\/p><p><img src=\"https:\/\/sunpe.github.io\/images\/data_struct_stack\/1.png\" alt=\"\">\u56fe 1<\/p><p>\u6808\u7684\u57fa\u672c\u64cd\u4f5c\u6709\uff1a<\/p><ul><li>\u5143\u7d20\u5165\u6808\u64cd\u4f5c <code>push<\/code><\/li><li>\u5143\u7d20\u51fa\u6808\u64cd\u4f5c <code>pop<\/code><\/li><li>\u67e5\u770b\u6808\u9876\u5143\u7d20 <code>top<\/code><\/li><\/ul><p>\u5165\u6808\u662f\u6307\u5728\u6808\u9876\u63d2\u5165\u5143\u7d20\uff0c\u51fa\u6808\u662f\u6307\u5220\u9664\u6808\u9876\u5143\u7d20\u3002<\/p><h2 id=\"\u6808\u7684\u5b9e\u73b0\">\u6808\u7684\u5b9e\u73b0<\/h2><h2 id=\"\u901a\u8fc7\u94fe\u8868\u5b9e\u73b0\">\u901a\u8fc7\u94fe\u8868\u5b9e\u73b0<\/h2><p>\u53ef\u4ee5\u4f7f\u7528\u5355\u94fe\u8868\u6765\u5b9e\u73b0\u6808\uff0c\u94fe\u8868\u7684\u524d\u7aef\u4f5c\u4e3a\u6808\u9876\uff0c\u901a\u8fc7\u5728\u94fe\u8868\u5934\u63d2\u5165\u5143\u7d20\u6765\u5b9e\u73b0 push\uff0c\u5220\u9664\u8868\u5934\u5143\u7d20\u6765\u5b9e\u73b0 pop\uff0ctop \u64cd\u4f5c\u53ea\u662f\u8fd4\u56de\u94fe\u8868\u5934\u90e8\u5143\u7d20\u7684\u6307\u3002<\/p><div class=\"highlight\"><pre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"><code class=\"language-go\" data-lang=\"go\"><span style=\"display:flex;\"><span><span style=\"color:#f92672\">import<\/span> (<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#e6db74\">&#34;container\/list&#34;<\/span><\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#e6db74\">&#34;sync&#34;<\/span><\/span><\/span><span style=\"display:flex;\"><span>)<\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#66d9ef\">type<\/span> <span style=\"color:#a6e22e\">Stack<\/span> <span style=\"color:#66d9ef\">struct<\/span> {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">sync<\/span>.<span style=\"color:#a6e22e\">RWMutex<\/span><\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">l<\/span> <span style=\"color:#f92672\">*<\/span><span style=\"color:#a6e22e\">list<\/span>.<span style=\"color:#a6e22e\">List<\/span><\/span><\/span><span style=\"display:flex;\"><span>}<\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#66d9ef\">func<\/span> <span style=\"color:#a6e22e\">New<\/span>() <span style=\"color:#f92672\">*<\/span><span style=\"color:#a6e22e\">Stack<\/span> {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">s<\/span> <span style=\"color:#f92672\">:=<\/span> <span style=\"color:#f92672\">&amp;<\/span><span style=\"color:#a6e22e\">Stack<\/span>{<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">l<\/span>: <span style=\"color:#a6e22e\">list<\/span>.<span style=\"color:#a6e22e\">New<\/span>(),<\/span><\/span><span style=\"display:flex;\"><span> }<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">return<\/span> <span style=\"color:#a6e22e\">s<\/span><\/span><\/span><span style=\"display:flex;\"><span>}<\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#66d9ef\">func<\/span> (<span style=\"color:#a6e22e\">s<\/span> <span style=\"color:#f92672\">*<\/span><span style=\"color:#a6e22e\">Stack<\/span>) <span style=\"color:#a6e22e\">Push<\/span>(<span style=\"color:#a6e22e\">v<\/span> <span style=\"color:#66d9ef\">interface<\/span>{}) {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">s<\/span>.<span style=\"color:#a6e22e\">Lock<\/span>()<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">defer<\/span> <span style=\"color:#a6e22e\">s<\/span>.<span style=\"color:#a6e22e\">Unlock<\/span>()<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">s<\/span>.<span style=\"color:#a6e22e\">l<\/span>.<span style=\"color:#a6e22e\">PushFront<\/span>(<span style=\"color:#a6e22e\">v<\/span>)<\/span><\/span><span style=\"display:flex;\"><span>}<\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#66d9ef\">func<\/span> (<span style=\"color:#a6e22e\">s<\/span> <span style=\"color:#f92672\">*<\/span><span style=\"color:#a6e22e\">Stack<\/span>) <span style=\"color:#a6e22e\">Pop<\/span>() <span style=\"color:#66d9ef\">interface<\/span>{} {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">s<\/span>.<span style=\"color:#a6e22e\">Lock<\/span>()<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">defer<\/span> <span style=\"color:#a6e22e\">s<\/span>.<span style=\"color:#a6e22e\">Unlock<\/span>()<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">ele<\/span> <span style=\"color:#f92672\">:=<\/span> <span style=\"color:#a6e22e\">s<\/span>.<span style=\"color:#a6e22e\">l<\/span>.<span style=\"color:#a6e22e\">Front<\/span>()<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">return<\/span> <span style=\"color:#a6e22e\">s<\/span>.<span style=\"color:#a6e22e\">l<\/span>.<span style=\"color:#a6e22e\">Remove<\/span>(<span style=\"color:#a6e22e\">ele<\/span>)<\/span><\/span><span style=\"display:flex;\"><span>}<\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#66d9ef\">func<\/span> (<span style=\"color:#a6e22e\">s<\/span> <span style=\"color:#f92672\">*<\/span><span style=\"color:#a6e22e\">Stack<\/span>) <span style=\"color:#a6e22e\">Top<\/span>() <span style=\"color:#66d9ef\">interface<\/span>{} {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">s<\/span>.<span style=\"color:#a6e22e\">RLock<\/span>()<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">defer<\/span> <span style=\"color:#a6e22e\">s<\/span>.<span style=\"color:#a6e22e\">RUnlock<\/span>()<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">return<\/span> <span style=\"color:#a6e22e\">s<\/span>.<span style=\"color:#a6e22e\">l<\/span>.<span style=\"color:#a6e22e\">Front<\/span>()<\/span><\/span><span style=\"display:flex;\"><span>}<\/span><\/span><\/code><\/pre><\/div><h3 id=\"\u901a\u8fc7-slice-\u5b9e\u73b0\">\u901a\u8fc7 slice \u5b9e\u73b0<\/h3><p>\u4f7f\u7528 slice \u5b9e\u73b0\u6808\u6bd4\u8f83\u7b80\u5355\uff0c\u5148\u58f0\u660e\u4e00\u4e2a\u521d\u59cb\u5bb9\u91cf\u6bd4\u8f83\u5927\u7684 slice\uff0c\u7a7a\u6808\u65f6\u6808\u9876 index(top) \u53ef\u4ee5\u8bbe\u7f6e\u4e3a -1\uff0c\u6709\u65b0\u5143\u7d20 x \u5165\u6808\u64cd\u4f5c\uff0c\u53ef\u4ee5\u5c06\u6808\u9876index(top) \u7684\u503c\u52a0 1\uff0c\u7136\u540e\u8bbe\u7f6e stack[top]=x\uff1b\u5143\u7d20\u51fa\u6808\u64cd\u4f5c\uff0c\u53ef\u4ee5\u5148\u8fd4\u56de stack[top]\uff0c\u7136\u540e\u5c06\u6808\u9876 index(top) \u7684\u503c\u51cf 1\u3002<\/p><div class=\"highlight\"><pre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"><code class=\"language-go\" data-lang=\"go\"><span style=\"display:flex;\"><span><span style=\"color:#f92672\">import<\/span> (<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#e6db74\">&#34;sync&#34;<\/span><\/span><\/span><span style=\"display:flex;\"><span>)<\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#66d9ef\">type<\/span> <span style=\"color:#a6e22e\">Stack<\/span> <span style=\"color:#66d9ef\">struct<\/span> {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">sync<\/span>.<span style=\"color:#a6e22e\">RWMutex<\/span><\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">s<\/span> []<span style=\"color:#66d9ef\">interface<\/span>{}<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">top<\/span> <span style=\"color:#66d9ef\">int<\/span><\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">c<\/span> <span style=\"color:#66d9ef\">int<\/span><\/span><\/span><span style=\"display:flex;\"><span>}<\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#66d9ef\">func<\/span> <span style=\"color:#a6e22e\">New<\/span>(<span style=\"color:#a6e22e\">capacity<\/span> <span style=\"color:#66d9ef\">int<\/span>) <span style=\"color:#f92672\">*<\/span><span style=\"color:#a6e22e\">Stack<\/span> {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">s<\/span> <span style=\"color:#f92672\">:=<\/span> <span style=\"color:#f92672\">&amp;<\/span><span style=\"color:#a6e22e\">Stack<\/span>{<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">s<\/span>: make([]<span style=\"color:#66d9ef\">interface<\/span>{}, <span style=\"color:#a6e22e\">capacity<\/span>),<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">c<\/span>: <span style=\"color:#a6e22e\">capacity<\/span>,<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">top<\/span>: <span style=\"color:#f92672\">-<\/span><span style=\"color:#ae81ff\">1<\/span>,<\/span><\/span><span style=\"display:flex;\"><span> }<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">return<\/span> <span style=\"color:#a6e22e\">s<\/span><\/span><\/span><span style=\"display:flex;\"><span>}<\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#66d9ef\">func<\/span> (<span style=\"color:#a6e22e\">s<\/span> <span style=\"color:#f92672\">*<\/span><span style=\"color:#a6e22e\">Stack<\/span>) <span style=\"color:#a6e22e\">Push<\/span>(<span style=\"color:#a6e22e\">v<\/span> <span style=\"color:#66d9ef\">interface<\/span>{}) {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">s<\/span>.<span style=\"color:#a6e22e\">Lock<\/span>()<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">defer<\/span> <span style=\"color:#a6e22e\">s<\/span>.<span style=\"color:#a6e22e\">Unlock<\/span>()<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">if<\/span> <span style=\"color:#a6e22e\">s<\/span>.<span style=\"color:#a6e22e\">top<\/span><span style=\"color:#f92672\">+<\/span><span style=\"color:#ae81ff\">1<\/span> &gt; <span style=\"color:#a6e22e\">s<\/span>.<span style=\"color:#a6e22e\">c<\/span> {<\/span><\/span><span style=\"display:flex;\"><span> panic(<span style=\"color:#e6db74\">&#34;stack over flow&#34;<\/span>)<\/span><\/span><span style=\"display:flex;\"><span> }<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">s<\/span>.<span style=\"color:#a6e22e\">top<\/span><span style=\"color:#f92672\">++<\/span><\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">s<\/span>.<span style=\"color:#a6e22e\">s<\/span>[<span style=\"color:#a6e22e\">s<\/span>.<span style=\"color:#a6e22e\">top<\/span>] = <span style=\"color:#a6e22e\">v<\/span><\/span><\/span><span style=\"display:flex;\"><span>}<\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#66d9ef\">func<\/span> (<span style=\"color:#a6e22e\">s<\/span> <span style=\"color:#f92672\">*<\/span><span style=\"color:#a6e22e\">Stack<\/span>) <span style=\"color:#a6e22e\">Pop<\/span>() <span style=\"color:#66d9ef\">interface<\/span>{} {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">s<\/span>.<span style=\"color:#a6e22e\">Lock<\/span>()<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">defer<\/span> <span style=\"color:#a6e22e\">s<\/span>.<span style=\"color:#a6e22e\">Unlock<\/span>()<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">if<\/span> <span style=\"color:#a6e22e\">s<\/span>.<span style=\"color:#a6e22e\">top<\/span> <span style=\"color:#f92672\">==<\/span> <span style=\"color:#f92672\">-<\/span><span style=\"color:#ae81ff\">1<\/span> {<\/span><\/span><span style=\"display:flex;\"><span> panic(<span style=\"color:#e6db74\">&#34;empty stack&#34;<\/span>)<\/span><\/span><span style=\"display:flex;\"><span> }<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">ele<\/span> <span style=\"color:#f92672\">:=<\/span> <span style=\"color:#a6e22e\">s<\/span>.<span style=\"color:#a6e22e\">s<\/span>[<span style=\"color:#a6e22e\">s<\/span>.<span style=\"color:#a6e22e\">top<\/span>]<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">s<\/span>.<span style=\"color:#a6e22e\">top<\/span><span style=\"color:#f92672\">--<\/span><\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">return<\/span> <span style=\"color:#a6e22e\">ele<\/span><\/span><\/span><span style=\"display:flex;\"><span>}<\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#66d9ef\">func<\/span> (<span style=\"color:#a6e22e\">s<\/span> <span style=\"color:#f92672\">*<\/span><span style=\"color:#a6e22e\">Stack<\/span>) <span style=\"color:#a6e22e\">Top<\/span>() <span style=\"color:#66d9ef\">interface<\/span>{} {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">s<\/span>.<span style=\"color:#a6e22e\">RLock<\/span>()<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">defer<\/span> <span style=\"color:#a6e22e\">s<\/span>.<span style=\"color:#a6e22e\">RUnlock<\/span>()<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">if<\/span> <span style=\"color:#a6e22e\">s<\/span>.<span style=\"color:#a6e22e\">top<\/span> <span style=\"color:#f92672\">==<\/span> <span style=\"color:#f92672\">-<\/span><span style=\"color:#ae81ff\">1<\/span> {<\/span><\/span><span style=\"display:flex;\"><span> panic(<span style=\"color:#e6db74\">&#34;empty stack&#34;<\/span>)<\/span><\/span><span style=\"display:flex;\"><span> }<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">return<\/span> <span style=\"color:#a6e22e\">s<\/span>.<span style=\"color:#a6e22e\">s<\/span>[<span style=\"color:#a6e22e\">s<\/span>.<span style=\"color:#a6e22e\">top<\/span>]<\/span><\/span><span style=\"display:flex;\"><span>}<\/span><\/span><\/code><\/pre><\/div><h2 id=\"\u603b\u7ed3\">\u603b\u7ed3<\/h2><p>\u6808\u5b9e\u73b0\u7b80\u5355\uff0c\u6548\u7387\u5f88\u9ad8\uff0c\u901a\u5e38 push \u548c pop \u90fd\u662f O(1) \u7684\u64cd\u4f5c\u3002\u9519\u8bef\u68c0\u6d4b\u548c\u7ebf\u7a0b\u5b89\u5168\u65b9\u9762\u7684\u8003\u8651\u53ef\u80fd\u4f1a\u62d6\u6162\u6808\u7684\u6267\u884c\u6548\u7387\uff0c\u5bf9\u7a7a\u6808\u7684 pop \u548c\u5bf9\u6ee1\u6808\u7684 push \u53ef\u80fd\u90fd\u4f1a\u5bfc\u81f4\u7a0b\u5e8f\u5f02\u5e38\u3002\u5728golang\u4e2d\u5b9e\u73b0\u6808\u8fd8\u6709\u4e00\u4e2a\u95ee\u9898\u662f\uff0cgolang\u76ee\u524d\u6ca1\u6709\u652f\u6301\u6cdb\u578b\uff08generic\uff09\u6216\u8005\u7c7b\u578b\u53c2\u6570\uff08type params\uff09\uff0c\u6240\u4ee5\u7f16\u5199\u901a\u7528\u7684\u6570\u636e\u7ed3\u6784\u53ea\u80fd\u4f7f\u7528 interface\uff0c\u8fd9\u6837\u5e26\u6765\u7684\u95ee\u9898\u662f\uff0c\u65e0\u6cd5\u5728\u6570\u636e\u7ed3\u6784\u7684\u5b9e\u73b0\u4e2d\u6765\u4fdd\u8bc1\u6570\u636e\u7c7b\u578b\u7684\u5b89\u5168\uff0c\u4f7f\u7528\u65f6\u9700\u8981\u591a\u52a0\u6ce8\u610f\u3002<\/p><h2 id=\"\u53c2\u8003\u8d44\u6599\">\u53c2\u8003\u8d44\u6599<\/h2><ol><li>\u6570\u636e\u7ed3\u6784\u4e0e\u7b97\u6cd5\u5206\u6790<\/li><\/ol>"},{"title":"\u6570\u636e\u7ed3\u6784--\u5217\u8868","link":"https:\/\/sunpe.github.io\/posts\/2020-03-20-data-struct-list\/","pubDate":"Fri, 20 Mar 2020 22:00:00 +0800","guid":"https:\/\/sunpe.github.io\/posts\/2020-03-20-data-struct-list\/","description":"<p>\u5f62\u5982 A1, A2, A3, \u2026 AN\u8fd9\u6837\u7684\u8868\uff0c\u8868\u5927\u5c0f\u662f N\uff0c\u5927\u5c0f\u4e3a 0 \u7684\u8868\u53eb\u7a7a\u8868\u3002\u5bf9\u4e8e\u7a7a\u8868\u4e4b\u5916\u7684\u8868 Ai+1 \u662f Ai \u7684\u540e\u7ee7\uff0cAi-1\u00a0(i&gt;=1) \u662f Ai \u7684\u524d\u9a71\u3002A1 \u662f\u8868\u7684\u7b2c\u4e00\u4e2a\u5143\u7d20\uff0cAN \u662f\u8868\u7684\u6700\u540e\u4e00\u4e2a\u5143\u7d20\uff0cA1 \u6ca1\u6709\u524d\u9a71\u5143\u7d20\uff0cAN \u4e5f\u6ca1\u6709\u540e\u7ee7\u5143\u7d20\u3002<\/p><p>\u8868\u7684\u64cd\u4f5c\u901a\u5e38\u6709\uff1a<\/p><ul><li>\u67e5\u627e\u5143\u7d20\u4f4d\u7f6e\u7684\u64cd\u4f5c<code>find<\/code><\/li><li>\u8fd4\u56de\u67d0\u4e2a\u4f4d\u7f6e\u4e0a\u7684\u5143\u7d20\u7684\u64cd\u4f5c<code>findKth<\/code><\/li><li>\u63d2\u5165\u5143\u7d20\u7684\u64cd\u4f5c<code>insert<\/code><\/li><li>\u5220\u9664\u5143\u7d20\u7684\u64cd\u4f5c<code>delete<\/code><\/li><\/ul><h2 id=\"\u8868\u7684\u5b9e\u73b0\">\u8868\u7684\u5b9e\u73b0<\/h2><h3 id=\"\u901a\u8fc7\u6570\u7ec4\u6216slice\u5b9e\u73b0\">\u901a\u8fc7\u6570\u7ec4\u6216slice\u5b9e\u73b0<\/h3><p>\u8868\u7684\u6240\u6709\u64cd\u4f5c\u90fd\u53ef\u4ee5\u57fa\u4e8e\u6570\u7ec4\u6216 slice \u6765\u5b9e\u73b0\uff0c\u6570\u7ec4\u9700\u8981\u6307\u5b9a\u6570\u7ec4\u7684\u5927\u5c0f\uff0c\u800c slice \u5e95\u5c42\u6570\u636e\u4e5f\u662f\u6570\u7ec4\uff0c\u5728\u7a7a\u95f4\u4e0a\u4e5f\u6709\u4e00\u5b9a\u7684\u5c40\u9650\u6027\uff0c\u7279\u522b\u662f\u5728\u5904\u7406\u672a\u77e5\u5927\u5c0f\u7684\u8868\u7684\u60c5\u51b5\u4e0b\u3002\u6570\u7ec4\u5b9e\u73b0\u7684\u8868\uff0c<code>find<\/code> \u64cd\u4f5c\u57fa\u4e8e\u5b9e\u73b0\u7684\u4e0d\u540c\u65f6\u95f4\u590d\u6742\u5ea6\u53ef\u80fd\u4f1a\u662f O(N) \u6216\u8005 O(logN)\uff0c<code>findKth<\/code> \u4f1a\u662f O(1) \u7684\u64cd\u4f5c\uff0c<code>insert<\/code> \u548c <code>delete<\/code> \u64cd\u4f5c\u53ef\u80fd\u4f1a\u6709\u5f88\u5927\u7684\u5f00\u9500\uff0c\u6bd4\u5982\u5728\u8868\u5934\u4f4d\u7f6e\u63d2\u5165\u65b0\u5143\u7d20\u6216\u5220\u9664\u8868\u5934\u5143\u7d20\uff0c\u9700\u8981\u8868\u4e2d\u7684\u6240\u6709\u5143\u7d20\u987a\u79fb\u4e00\u4f4d\u3002<\/p><p>\u6240\u4ee5\u57fa\u4e8e\u6570\u7ec4\u5b9e\u73b0\u7684\u8868\u9002\u5408\u4e8e\u968f\u673a\u8bfb\u7684\u60c5\u51b5\uff0c\u800c\u4e0d\u9002\u4e8e\u968f\u673a\u5199\u7684\u60c5\u51b5\u3002<\/p><h3 id=\"\u94fe\u8868\">\u94fe\u8868<\/h3><p>\u4e3a\u4e86\u907f\u514d insert \u548c delete \u7684\u5f00\u9500\uff0c\u53ef\u4ee5\u8ba9\u8868\u7684\u5143\u7d20\u4e0d\u8fde\u7eed\uff0c\u94fe\u8868\uff08linked list\uff09\u662f\u7531\u4e00\u7cfb\u5217\u4e0d\u5fc5\u5728\u5185\u5b58\u4e2d\u8fde\u7eed\u7684\u7ed3\u6784\u7ec4\u6210\uff0c\u6bcf\u4e2a\u7ed3\u6784\u5305\u542b\u8868\u7684\u5143\u7d20\u548c\u540e\u7ee7\u5143\u7d20\u7684\u6307\u9488\uff08Next\uff09\uff0c\u8868\u5c3e\u5143\u7d20\u7684 next \u6307\u9488\u662f nil\u3002<\/p><p><img src=\"https:\/\/sunpe.github.io\/images\/data_struct_list\/1.png\" alt=\"\">\u56fe 1<\/p><p>\u8fd9\u79cd\u60c5\u51b5\u4e0b\uff0cinsert \u548c delete \u64cd\u4f5c\u53ea\u9700\u8981\u4fee\u6539 next \u6307\u9488\u5c31\u53ef\u4ee5\u5b9e\u73b0\u4e86\u3002\u6bd4\u5982\u5220\u9664\u300c99\u300d\u8fd9\u4e2a\u5143\u7d20\uff0c\u53ea\u9700\u8981\u5c06\u300c12\u300d\u5143\u7d20\u7684 next \u6307\u9488\u6307\u5411\u300c37\u300d\u5143\u7d20\u5c31\u53ef\u4ee5\u4e86\uff1b\u8981\u5728\u300c99\u300d\u5143\u7d20\u548c\u300c37\u300d\u5143\u7d20\u4e2d\u95f4\u63d2\u5165\u5143\u7d20\uff0c\u5219\u9700\u8981\u5c06\u300c99\u300d\u5143\u7d20\u7684 next \u6307\u5411\u65b0\u7684\u5143\u7d20\uff0c\u5e76\u4e14\u5c06\u65b0\u5143\u7d20\u7684 next \u6307\u5411\u300c37\u300d\u3002<\/p><p>\u6709\u65f6\u5019\u9700\u8981\u5012\u5e8f\u904d\u5386\u94fe\u8868\uff0c\u5355\u94fe\u8868\u7684\u65b9\u5f0f\u663e\u5f97\u65e0\u80fd\u4e3a\u529b\uff0c\u7136\u800c\u89e3\u51b3\u65b9\u6cd5\u5374\u5f88\u7b80\u5355\uff0c\u53ea\u9700\u8981\u5728\u94fe\u8868\u7684\u5143\u7d20\u4e2d\u6dfb\u52a0\u4e00\u4e2a\u6307\u9488\u57df\uff0c\u6307\u5411\u94fe\u8868\u5143\u7d20\u7684\u524d\u9a71\u5373\u53ef\u3002\u8fd9\u6837\u5c31\u5f62\u6210\u4e86\u53cc\u5411\u94fe\u8868\uff08double linked list\uff09\u3002<\/p><p><img src=\"https:\/\/sunpe.github.io\/images\/data_struct_list\/2.png\" alt=\"\">\u56fe 2<\/p><p>\u8ba9\u94fe\u8868\u7684\u6700\u540e\u4e00\u4e2a\u94fe\u8868\u5143\u7d20\u53cd\u8fc7\u6765\u6307\u5411\u7b2c\u4e00\u4e2a\u94fe\u8868\u5143\u7d20, \u5c31\u5f62\u6210\u4e86\u5faa\u73af\u94fe\u8868.<\/p><p><img src=\"https:\/\/sunpe.github.io\/images\/data_struct_list\/3.png\" alt=\"\">\u56fe 3<\/p><p>\u540c\u6837\u7684, \u5982\u679c\u8ba9\u53cc\u5411\u5faa\u73af\u94fe\u8868\u7684\u6700\u540e\u4e00\u4e2a\u5143\u7d20\u7684\u540e\u7ee7\u6307\u9488\u6307\u5411\u7b2c\u4e00\u4e2a\u5143\u7d20, \u7b2c\u4e00\u4e2a\u5143\u7d20\u7684\u524d\u9a71\u6307\u9488\u6307\u5411\u6700\u540e\u4e00\u4e2a\u5143\u7d20, \u5c31\u5f62\u6210\u4e86\u53cc\u5411\u5faa\u73af\u94fe\u8868.<\/p><p><img src=\"https:\/\/sunpe.github.io\/images\/data_struct_list\/3.png\" alt=\"\">\u56fe 4<\/p><h2 id=\"\u94fe\u8868\u5b9e\u73b0\">\u94fe\u8868\u5b9e\u73b0<\/h2><p>golang \u7684 <code>container\/list\/List.go<\/code> \u63d0\u4f9b\u4e86\u4e00\u4e2a\u53cc\u5411\u94fe\u8868\u7684\u5b9e\u73b0\uff0c\u5982\u4e0b\u662f\u5176\u4e2d\u7684\u90e8\u5206\u4ee3\u7801\u3002<\/p><div class=\"highlight\"><pre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"><code class=\"language-go\" data-lang=\"go\"><span style=\"display:flex;\"><span><span style=\"color:#75715e\">\/\/ Copyright 2009 The Go Authors. All rights reserved.<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\">\/\/ Use of this source code is governed by a BSD-style<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\">\/\/ license that can be found in the LICENSE file.<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\">\/\/ Package list implements a doubly linked list.<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\">\/\/<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\">\/\/ To iterate over a list (where l is a *List):<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\">\/\/ for e := l.Front(); e != nil; e = e.Next() {<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\">\/\/ \/\/ do something with e.Value<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\">\/\/ }<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\">\/\/<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span><span style=\"color:#f92672\">package<\/span> <span style=\"color:#a6e22e\">list<\/span><\/span><\/span><span style=\"display:flex;\"><span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\">\/\/ Element is an element of a linked list.<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span><span style=\"color:#66d9ef\">type<\/span> <span style=\"color:#a6e22e\">Element<\/span> <span style=\"color:#66d9ef\">struct<\/span> {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#75715e\">\/\/ Next and previous pointers in the doubly-linked list of elements.<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span> <span style=\"color:#75715e\">\/\/ To simplify the implementation, internally a list l is implemented<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span> <span style=\"color:#75715e\">\/\/ as a ring, such that &amp;l.root is both the next element of the last<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span> <span style=\"color:#75715e\">\/\/ list element (l.Back()) and the previous element of the first list<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span> <span style=\"color:#75715e\">\/\/ element (l.Front()).<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span> <span style=\"color:#a6e22e\">next<\/span>, <span style=\"color:#a6e22e\">prev<\/span> <span style=\"color:#f92672\">*<\/span><span style=\"color:#a6e22e\">Element<\/span><\/span><\/span><span style=\"display:flex;\"><span><\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#75715e\">\/\/ The list to which this element belongs.<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span> <span style=\"color:#a6e22e\">list<\/span> <span style=\"color:#f92672\">*<\/span><span style=\"color:#a6e22e\">List<\/span><\/span><\/span><span style=\"display:flex;\"><span><\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#75715e\">\/\/ The value stored with this element.<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span> <span style=\"color:#a6e22e\">Value<\/span> <span style=\"color:#66d9ef\">interface<\/span>{}<\/span><\/span><span style=\"display:flex;\"><span>}<\/span><\/span><span style=\"display:flex;\"><span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\">\/\/ Next returns the next list element or nil.<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span><span style=\"color:#66d9ef\">func<\/span> (<span style=\"color:#a6e22e\">e<\/span> <span style=\"color:#f92672\">*<\/span><span style=\"color:#a6e22e\">Element<\/span>) <span style=\"color:#a6e22e\">Next<\/span>() <span style=\"color:#f92672\">*<\/span><span style=\"color:#a6e22e\">Element<\/span> {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">if<\/span> <span style=\"color:#a6e22e\">p<\/span> <span style=\"color:#f92672\">:=<\/span> <span style=\"color:#a6e22e\">e<\/span>.<span style=\"color:#a6e22e\">next<\/span>; <span style=\"color:#a6e22e\">e<\/span>.<span style=\"color:#a6e22e\">list<\/span> <span style=\"color:#f92672\">!=<\/span> <span style=\"color:#66d9ef\">nil<\/span> <span style=\"color:#f92672\">&amp;&amp;<\/span> <span style=\"color:#a6e22e\">p<\/span> <span style=\"color:#f92672\">!=<\/span> <span style=\"color:#f92672\">&amp;<\/span><span style=\"color:#a6e22e\">e<\/span>.<span style=\"color:#a6e22e\">list<\/span>.<span style=\"color:#a6e22e\">root<\/span> {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">return<\/span> <span style=\"color:#a6e22e\">p<\/span><\/span><\/span><span style=\"display:flex;\"><span> }<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">return<\/span> <span style=\"color:#66d9ef\">nil<\/span><\/span><\/span><span style=\"display:flex;\"><span>}<\/span><\/span><span style=\"display:flex;\"><span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\">\/\/ Prev returns the previous list element or nil.<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span><span style=\"color:#66d9ef\">func<\/span> (<span style=\"color:#a6e22e\">e<\/span> <span style=\"color:#f92672\">*<\/span><span style=\"color:#a6e22e\">Element<\/span>) <span style=\"color:#a6e22e\">Prev<\/span>() <span style=\"color:#f92672\">*<\/span><span style=\"color:#a6e22e\">Element<\/span> {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">if<\/span> <span style=\"color:#a6e22e\">p<\/span> <span style=\"color:#f92672\">:=<\/span> <span style=\"color:#a6e22e\">e<\/span>.<span style=\"color:#a6e22e\">prev<\/span>; <span style=\"color:#a6e22e\">e<\/span>.<span style=\"color:#a6e22e\">list<\/span> <span style=\"color:#f92672\">!=<\/span> <span style=\"color:#66d9ef\">nil<\/span> <span style=\"color:#f92672\">&amp;&amp;<\/span> <span style=\"color:#a6e22e\">p<\/span> <span style=\"color:#f92672\">!=<\/span> <span style=\"color:#f92672\">&amp;<\/span><span style=\"color:#a6e22e\">e<\/span>.<span style=\"color:#a6e22e\">list<\/span>.<span style=\"color:#a6e22e\">root<\/span> {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">return<\/span> <span style=\"color:#a6e22e\">p<\/span><\/span><\/span><span style=\"display:flex;\"><span> }<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">return<\/span> <span style=\"color:#66d9ef\">nil<\/span><\/span><\/span><span style=\"display:flex;\"><span>}<\/span><\/span><span style=\"display:flex;\"><span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\">\/\/ List represents a doubly linked list.<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\">\/\/ The zero value for List is an empty list ready to use.<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span><span style=\"color:#66d9ef\">type<\/span> <span style=\"color:#a6e22e\">List<\/span> <span style=\"color:#66d9ef\">struct<\/span> {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">root<\/span> <span style=\"color:#a6e22e\">Element<\/span> <span style=\"color:#75715e\">\/\/ sentinel list element, only &amp;root, root.prev, and root.next are used<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span> <span style=\"color:#a6e22e\">len<\/span> <span style=\"color:#66d9ef\">int<\/span> <span style=\"color:#75715e\">\/\/ current list length excluding (this) sentinel element<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span>}<\/span><\/span><span style=\"display:flex;\"><span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\">\/\/ Init initializes or clears list l.<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span><span style=\"color:#66d9ef\">func<\/span> (<span style=\"color:#a6e22e\">l<\/span> <span style=\"color:#f92672\">*<\/span><span style=\"color:#a6e22e\">List<\/span>) <span style=\"color:#a6e22e\">Init<\/span>() <span style=\"color:#f92672\">*<\/span><span style=\"color:#a6e22e\">List<\/span> {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">l<\/span>.<span style=\"color:#a6e22e\">root<\/span>.<span style=\"color:#a6e22e\">next<\/span> = <span style=\"color:#f92672\">&amp;<\/span><span style=\"color:#a6e22e\">l<\/span>.<span style=\"color:#a6e22e\">root<\/span><\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">l<\/span>.<span style=\"color:#a6e22e\">root<\/span>.<span style=\"color:#a6e22e\">prev<\/span> = <span style=\"color:#f92672\">&amp;<\/span><span style=\"color:#a6e22e\">l<\/span>.<span style=\"color:#a6e22e\">root<\/span><\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">l<\/span>.<span style=\"color:#a6e22e\">len<\/span> = <span style=\"color:#ae81ff\">0<\/span><\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">return<\/span> <span style=\"color:#a6e22e\">l<\/span><\/span><\/span><span style=\"display:flex;\"><span>}<\/span><\/span><span style=\"display:flex;\"><span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\">\/\/ New returns an initialized list.<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span><span style=\"color:#66d9ef\">func<\/span> <span style=\"color:#a6e22e\">New<\/span>() <span style=\"color:#f92672\">*<\/span><span style=\"color:#a6e22e\">List<\/span> { <span style=\"color:#66d9ef\">return<\/span> new(<span style=\"color:#a6e22e\">List<\/span>).<span style=\"color:#a6e22e\">Init<\/span>() }<\/span><\/span><span style=\"display:flex;\"><span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\">\/\/ Len returns the number of elements of list l.<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\">\/\/ The complexity is O(1).<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span><span style=\"color:#66d9ef\">func<\/span> (<span style=\"color:#a6e22e\">l<\/span> <span style=\"color:#f92672\">*<\/span><span style=\"color:#a6e22e\">List<\/span>) <span style=\"color:#a6e22e\">Len<\/span>() <span style=\"color:#66d9ef\">int<\/span> { <span style=\"color:#66d9ef\">return<\/span> <span style=\"color:#a6e22e\">l<\/span>.<span style=\"color:#a6e22e\">len<\/span> }<\/span><\/span><span style=\"display:flex;\"><span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\">\/\/ Front returns the first element of list l or nil if the list is empty.<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span><span style=\"color:#66d9ef\">func<\/span> (<span style=\"color:#a6e22e\">l<\/span> <span style=\"color:#f92672\">*<\/span><span style=\"color:#a6e22e\">List<\/span>) <span style=\"color:#a6e22e\">Front<\/span>() <span style=\"color:#f92672\">*<\/span><span style=\"color:#a6e22e\">Element<\/span> {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">if<\/span> <span style=\"color:#a6e22e\">l<\/span>.<span style=\"color:#a6e22e\">len<\/span> <span style=\"color:#f92672\">==<\/span> <span style=\"color:#ae81ff\">0<\/span> {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">return<\/span> <span style=\"color:#66d9ef\">nil<\/span><\/span><\/span><span style=\"display:flex;\"><span> }<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">return<\/span> <span style=\"color:#a6e22e\">l<\/span>.<span style=\"color:#a6e22e\">root<\/span>.<span style=\"color:#a6e22e\">next<\/span><\/span><\/span><span style=\"display:flex;\"><span>}<\/span><\/span><span style=\"display:flex;\"><span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\">\/\/ Back returns the last element of list l or nil if the list is empty.<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span><span style=\"color:#66d9ef\">func<\/span> (<span style=\"color:#a6e22e\">l<\/span> <span style=\"color:#f92672\">*<\/span><span style=\"color:#a6e22e\">List<\/span>) <span style=\"color:#a6e22e\">Back<\/span>() <span style=\"color:#f92672\">*<\/span><span style=\"color:#a6e22e\">Element<\/span> {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">if<\/span> <span style=\"color:#a6e22e\">l<\/span>.<span style=\"color:#a6e22e\">len<\/span> <span style=\"color:#f92672\">==<\/span> <span style=\"color:#ae81ff\">0<\/span> {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">return<\/span> <span style=\"color:#66d9ef\">nil<\/span><\/span><\/span><span style=\"display:flex;\"><span> }<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">return<\/span> <span style=\"color:#a6e22e\">l<\/span>.<span style=\"color:#a6e22e\">root<\/span>.<span style=\"color:#a6e22e\">prev<\/span><\/span><\/span><span style=\"display:flex;\"><span>}<\/span><\/span><span style=\"display:flex;\"><span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\">\/\/ lazyInit lazily initializes a zero List value.<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span><span style=\"color:#66d9ef\">func<\/span> (<span style=\"color:#a6e22e\">l<\/span> <span style=\"color:#f92672\">*<\/span><span style=\"color:#a6e22e\">List<\/span>) <span style=\"color:#a6e22e\">lazyInit<\/span>() {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">if<\/span> <span style=\"color:#a6e22e\">l<\/span>.<span style=\"color:#a6e22e\">root<\/span>.<span style=\"color:#a6e22e\">next<\/span> <span style=\"color:#f92672\">==<\/span> <span style=\"color:#66d9ef\">nil<\/span> {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">l<\/span>.<span style=\"color:#a6e22e\">Init<\/span>()<\/span><\/span><span style=\"display:flex;\"><span> }<\/span><\/span><span style=\"display:flex;\"><span>}<\/span><\/span><span style=\"display:flex;\"><span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\">\/\/ insert inserts e after at, increments l.len, and returns e.<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span><span style=\"color:#66d9ef\">func<\/span> (<span style=\"color:#a6e22e\">l<\/span> <span style=\"color:#f92672\">*<\/span><span style=\"color:#a6e22e\">List<\/span>) <span style=\"color:#a6e22e\">insert<\/span>(<span style=\"color:#a6e22e\">e<\/span>, <span style=\"color:#a6e22e\">at<\/span> <span style=\"color:#f92672\">*<\/span><span style=\"color:#a6e22e\">Element<\/span>) <span style=\"color:#f92672\">*<\/span><span style=\"color:#a6e22e\">Element<\/span> {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">n<\/span> <span style=\"color:#f92672\">:=<\/span> <span style=\"color:#a6e22e\">at<\/span>.<span style=\"color:#a6e22e\">next<\/span><\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">at<\/span>.<span style=\"color:#a6e22e\">next<\/span> = <span style=\"color:#a6e22e\">e<\/span><\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">e<\/span>.<span style=\"color:#a6e22e\">prev<\/span> = <span style=\"color:#a6e22e\">at<\/span><\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">e<\/span>.<span style=\"color:#a6e22e\">next<\/span> = <span style=\"color:#a6e22e\">n<\/span><\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">n<\/span>.<span style=\"color:#a6e22e\">prev<\/span> = <span style=\"color:#a6e22e\">e<\/span><\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">e<\/span>.<span style=\"color:#a6e22e\">list<\/span> = <span style=\"color:#a6e22e\">l<\/span><\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">l<\/span>.<span style=\"color:#a6e22e\">len<\/span><span style=\"color:#f92672\">++<\/span><\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">return<\/span> <span style=\"color:#a6e22e\">e<\/span><\/span><\/span><span style=\"display:flex;\"><span>}<\/span><\/span><span style=\"display:flex;\"><span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\">\/\/ insertValue is a convenience wrapper for insert(&amp;Element{Value: v}, at).<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span><span style=\"color:#66d9ef\">func<\/span> (<span style=\"color:#a6e22e\">l<\/span> <span style=\"color:#f92672\">*<\/span><span style=\"color:#a6e22e\">List<\/span>) <span style=\"color:#a6e22e\">insertValue<\/span>(<span style=\"color:#a6e22e\">v<\/span> <span style=\"color:#66d9ef\">interface<\/span>{}, <span style=\"color:#a6e22e\">at<\/span> <span style=\"color:#f92672\">*<\/span><span style=\"color:#a6e22e\">Element<\/span>) <span style=\"color:#f92672\">*<\/span><span style=\"color:#a6e22e\">Element<\/span> {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">return<\/span> <span style=\"color:#a6e22e\">l<\/span>.<span style=\"color:#a6e22e\">insert<\/span>(<span style=\"color:#f92672\">&amp;<\/span><span style=\"color:#a6e22e\">Element<\/span>{<span style=\"color:#a6e22e\">Value<\/span>: <span style=\"color:#a6e22e\">v<\/span>}, <span style=\"color:#a6e22e\">at<\/span>)<\/span><\/span><span style=\"display:flex;\"><span>}<\/span><\/span><span style=\"display:flex;\"><span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\">\/\/ remove removes e from its list, decrements l.len, and returns e.<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span><span style=\"color:#66d9ef\">func<\/span> (<span style=\"color:#a6e22e\">l<\/span> <span style=\"color:#f92672\">*<\/span><span style=\"color:#a6e22e\">List<\/span>) <span style=\"color:#a6e22e\">remove<\/span>(<span style=\"color:#a6e22e\">e<\/span> <span style=\"color:#f92672\">*<\/span><span style=\"color:#a6e22e\">Element<\/span>) <span style=\"color:#f92672\">*<\/span><span style=\"color:#a6e22e\">Element<\/span> {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">e<\/span>.<span style=\"color:#a6e22e\">prev<\/span>.<span style=\"color:#a6e22e\">next<\/span> = <span style=\"color:#a6e22e\">e<\/span>.<span style=\"color:#a6e22e\">next<\/span><\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">e<\/span>.<span style=\"color:#a6e22e\">next<\/span>.<span style=\"color:#a6e22e\">prev<\/span> = <span style=\"color:#a6e22e\">e<\/span>.<span style=\"color:#a6e22e\">prev<\/span><\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">e<\/span>.<span style=\"color:#a6e22e\">next<\/span> = <span style=\"color:#66d9ef\">nil<\/span> <span style=\"color:#75715e\">\/\/ avoid memory leaks<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span> <span style=\"color:#a6e22e\">e<\/span>.<span style=\"color:#a6e22e\">prev<\/span> = <span style=\"color:#66d9ef\">nil<\/span> <span style=\"color:#75715e\">\/\/ avoid memory leaks<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span> <span style=\"color:#a6e22e\">e<\/span>.<span style=\"color:#a6e22e\">list<\/span> = <span style=\"color:#66d9ef\">nil<\/span><\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">l<\/span>.<span style=\"color:#a6e22e\">len<\/span><span style=\"color:#f92672\">--<\/span><\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">return<\/span> <span style=\"color:#a6e22e\">e<\/span><\/span><\/span><span style=\"display:flex;\"><span>}<\/span><\/span><span style=\"display:flex;\"><span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\">\/\/ move moves e to next to at and returns e.<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span><span style=\"color:#66d9ef\">func<\/span> (<span style=\"color:#a6e22e\">l<\/span> <span style=\"color:#f92672\">*<\/span><span style=\"color:#a6e22e\">List<\/span>) <span style=\"color:#a6e22e\">move<\/span>(<span style=\"color:#a6e22e\">e<\/span>, <span style=\"color:#a6e22e\">at<\/span> <span style=\"color:#f92672\">*<\/span><span style=\"color:#a6e22e\">Element<\/span>) <span style=\"color:#f92672\">*<\/span><span style=\"color:#a6e22e\">Element<\/span> {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">if<\/span> <span style=\"color:#a6e22e\">e<\/span> <span style=\"color:#f92672\">==<\/span> <span style=\"color:#a6e22e\">at<\/span> {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">return<\/span> <span style=\"color:#a6e22e\">e<\/span><\/span><\/span><span style=\"display:flex;\"><span> }<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">e<\/span>.<span style=\"color:#a6e22e\">prev<\/span>.<span style=\"color:#a6e22e\">next<\/span> = <span style=\"color:#a6e22e\">e<\/span>.<span style=\"color:#a6e22e\">next<\/span><\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">e<\/span>.<span style=\"color:#a6e22e\">next<\/span>.<span style=\"color:#a6e22e\">prev<\/span> = <span style=\"color:#a6e22e\">e<\/span>.<span style=\"color:#a6e22e\">prev<\/span><\/span><\/span><span style=\"display:flex;\"><span><\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">n<\/span> <span style=\"color:#f92672\">:=<\/span> <span style=\"color:#a6e22e\">at<\/span>.<span style=\"color:#a6e22e\">next<\/span><\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">at<\/span>.<span style=\"color:#a6e22e\">next<\/span> = <span style=\"color:#a6e22e\">e<\/span><\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">e<\/span>.<span style=\"color:#a6e22e\">prev<\/span> = <span style=\"color:#a6e22e\">at<\/span><\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">e<\/span>.<span style=\"color:#a6e22e\">next<\/span> = <span style=\"color:#a6e22e\">n<\/span><\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">n<\/span>.<span style=\"color:#a6e22e\">prev<\/span> = <span style=\"color:#a6e22e\">e<\/span><\/span><\/span><span style=\"display:flex;\"><span><\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">return<\/span> <span style=\"color:#a6e22e\">e<\/span><\/span><\/span><span style=\"display:flex;\"><span>}<\/span><\/span><span style=\"display:flex;\"><span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\">\/\/ Remove removes e from l if e is an element of list l.<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\">\/\/ It returns the element value e.Value.<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\">\/\/ The element must not be nil.<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span><span style=\"color:#66d9ef\">func<\/span> (<span style=\"color:#a6e22e\">l<\/span> <span style=\"color:#f92672\">*<\/span><span style=\"color:#a6e22e\">List<\/span>) <span style=\"color:#a6e22e\">Remove<\/span>(<span style=\"color:#a6e22e\">e<\/span> <span style=\"color:#f92672\">*<\/span><span style=\"color:#a6e22e\">Element<\/span>) <span style=\"color:#66d9ef\">interface<\/span>{} {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">if<\/span> <span style=\"color:#a6e22e\">e<\/span>.<span style=\"color:#a6e22e\">list<\/span> <span style=\"color:#f92672\">==<\/span> <span style=\"color:#a6e22e\">l<\/span> {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#75715e\">\/\/ if e.list == l, l must have been initialized when e was inserted<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span> <span style=\"color:#75715e\">\/\/ in l or l == nil (e is a zero Element) and l.remove will crash<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span> <span style=\"color:#a6e22e\">l<\/span>.<span style=\"color:#a6e22e\">remove<\/span>(<span style=\"color:#a6e22e\">e<\/span>)<\/span><\/span><span style=\"display:flex;\"><span> }<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">return<\/span> <span style=\"color:#a6e22e\">e<\/span>.<span style=\"color:#a6e22e\">Value<\/span><\/span><\/span><span style=\"display:flex;\"><span>}<\/span><\/span><span style=\"display:flex;\"><span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\">\/\/ PushFront inserts a new element e with value v at the front of list l and returns e.<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span><span style=\"color:#66d9ef\">func<\/span> (<span style=\"color:#a6e22e\">l<\/span> <span style=\"color:#f92672\">*<\/span><span style=\"color:#a6e22e\">List<\/span>) <span style=\"color:#a6e22e\">PushFront<\/span>(<span style=\"color:#a6e22e\">v<\/span> <span style=\"color:#66d9ef\">interface<\/span>{}) <span style=\"color:#f92672\">*<\/span><span style=\"color:#a6e22e\">Element<\/span> {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">l<\/span>.<span style=\"color:#a6e22e\">lazyInit<\/span>()<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">return<\/span> <span style=\"color:#a6e22e\">l<\/span>.<span style=\"color:#a6e22e\">insertValue<\/span>(<span style=\"color:#a6e22e\">v<\/span>, <span style=\"color:#f92672\">&amp;<\/span><span style=\"color:#a6e22e\">l<\/span>.<span style=\"color:#a6e22e\">root<\/span>)<\/span><\/span><span style=\"display:flex;\"><span>}<\/span><\/span><span style=\"display:flex;\"><span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\">\/\/ PushBack inserts a new element e with value v at the back of list l and returns e.<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span><span style=\"color:#66d9ef\">func<\/span> (<span style=\"color:#a6e22e\">l<\/span> <span style=\"color:#f92672\">*<\/span><span style=\"color:#a6e22e\">List<\/span>) <span style=\"color:#a6e22e\">PushBack<\/span>(<span style=\"color:#a6e22e\">v<\/span> <span style=\"color:#66d9ef\">interface<\/span>{}) <span style=\"color:#f92672\">*<\/span><span style=\"color:#a6e22e\">Element<\/span> {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">l<\/span>.<span style=\"color:#a6e22e\">lazyInit<\/span>()<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">return<\/span> <span style=\"color:#a6e22e\">l<\/span>.<span style=\"color:#a6e22e\">insertValue<\/span>(<span style=\"color:#a6e22e\">v<\/span>, <span style=\"color:#a6e22e\">l<\/span>.<span style=\"color:#a6e22e\">root<\/span>.<span style=\"color:#a6e22e\">prev<\/span>)<\/span><\/span><span style=\"display:flex;\"><span>}<\/span><\/span><span style=\"display:flex;\"><span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\">\/\/ InsertBefore inserts a new element e with value v immediately before mark and returns e.<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\">\/\/ If mark is not an element of l, the list is not modified.<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\">\/\/ The mark must not be nil.<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span><span style=\"color:#66d9ef\">func<\/span> (<span style=\"color:#a6e22e\">l<\/span> <span style=\"color:#f92672\">*<\/span><span style=\"color:#a6e22e\">List<\/span>) <span style=\"color:#a6e22e\">InsertBefore<\/span>(<span style=\"color:#a6e22e\">v<\/span> <span style=\"color:#66d9ef\">interface<\/span>{}, <span style=\"color:#a6e22e\">mark<\/span> <span style=\"color:#f92672\">*<\/span><span style=\"color:#a6e22e\">Element<\/span>) <span style=\"color:#f92672\">*<\/span><span style=\"color:#a6e22e\">Element<\/span> {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">if<\/span> <span style=\"color:#a6e22e\">mark<\/span>.<span style=\"color:#a6e22e\">list<\/span> <span style=\"color:#f92672\">!=<\/span> <span style=\"color:#a6e22e\">l<\/span> {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">return<\/span> <span style=\"color:#66d9ef\">nil<\/span><\/span><\/span><span style=\"display:flex;\"><span> }<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#75715e\">\/\/ see comment in List.Remove about initialization of l<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span> <span style=\"color:#66d9ef\">return<\/span> <span style=\"color:#a6e22e\">l<\/span>.<span style=\"color:#a6e22e\">insertValue<\/span>(<span style=\"color:#a6e22e\">v<\/span>, <span style=\"color:#a6e22e\">mark<\/span>.<span style=\"color:#a6e22e\">prev<\/span>)<\/span><\/span><span style=\"display:flex;\"><span>}<\/span><\/span><span style=\"display:flex;\"><span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\">\/\/ InsertAfter inserts a new element e with value v immediately after mark and returns e.<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\">\/\/ If mark is not an element of l, the list is not modified.<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\">\/\/ The mark must not be nil.<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span><span style=\"color:#66d9ef\">func<\/span> (<span style=\"color:#a6e22e\">l<\/span> <span style=\"color:#f92672\">*<\/span><span style=\"color:#a6e22e\">List<\/span>) <span style=\"color:#a6e22e\">InsertAfter<\/span>(<span style=\"color:#a6e22e\">v<\/span> <span style=\"color:#66d9ef\">interface<\/span>{}, <span style=\"color:#a6e22e\">mark<\/span> <span style=\"color:#f92672\">*<\/span><span style=\"color:#a6e22e\">Element<\/span>) <span style=\"color:#f92672\">*<\/span><span style=\"color:#a6e22e\">Element<\/span> {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">if<\/span> <span style=\"color:#a6e22e\">mark<\/span>.<span style=\"color:#a6e22e\">list<\/span> <span style=\"color:#f92672\">!=<\/span> <span style=\"color:#a6e22e\">l<\/span> {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">return<\/span> <span style=\"color:#66d9ef\">nil<\/span><\/span><\/span><span style=\"display:flex;\"><span> }<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#75715e\">\/\/ see comment in List.Remove about initialization of l<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span> <span style=\"color:#66d9ef\">return<\/span> <span style=\"color:#a6e22e\">l<\/span>.<span style=\"color:#a6e22e\">insertValue<\/span>(<span style=\"color:#a6e22e\">v<\/span>, <span style=\"color:#a6e22e\">mark<\/span>)<\/span><\/span><span style=\"display:flex;\"><span>}<\/span><\/span><span style=\"display:flex;\"><span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\">\/\/ MoveToFront moves element e to the front of list l.<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\">\/\/ If e is not an element of l, the list is not modified.<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\">\/\/ The element must not be nil.<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span><span style=\"color:#66d9ef\">func<\/span> (<span style=\"color:#a6e22e\">l<\/span> <span style=\"color:#f92672\">*<\/span><span style=\"color:#a6e22e\">List<\/span>) <span style=\"color:#a6e22e\">MoveToFront<\/span>(<span style=\"color:#a6e22e\">e<\/span> <span style=\"color:#f92672\">*<\/span><span style=\"color:#a6e22e\">Element<\/span>) {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">if<\/span> <span style=\"color:#a6e22e\">e<\/span>.<span style=\"color:#a6e22e\">list<\/span> <span style=\"color:#f92672\">!=<\/span> <span style=\"color:#a6e22e\">l<\/span> <span style=\"color:#f92672\">||<\/span> <span style=\"color:#a6e22e\">l<\/span>.<span style=\"color:#a6e22e\">root<\/span>.<span style=\"color:#a6e22e\">next<\/span> <span style=\"color:#f92672\">==<\/span> <span style=\"color:#a6e22e\">e<\/span> {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">return<\/span><\/span><\/span><span style=\"display:flex;\"><span> }<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#75715e\">\/\/ see comment in List.Remove about initialization of l<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span> <span style=\"color:#a6e22e\">l<\/span>.<span style=\"color:#a6e22e\">move<\/span>(<span style=\"color:#a6e22e\">e<\/span>, <span style=\"color:#f92672\">&amp;<\/span><span style=\"color:#a6e22e\">l<\/span>.<span style=\"color:#a6e22e\">root<\/span>)<\/span><\/span><span style=\"display:flex;\"><span>}<\/span><\/span><span style=\"display:flex;\"><span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\">\/\/ MoveToBack moves element e to the back of list l.<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\">\/\/ If e is not an element of l, the list is not modified.<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\">\/\/ The element must not be nil.<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span><span style=\"color:#66d9ef\">func<\/span> (<span style=\"color:#a6e22e\">l<\/span> <span style=\"color:#f92672\">*<\/span><span style=\"color:#a6e22e\">List<\/span>) <span style=\"color:#a6e22e\">MoveToBack<\/span>(<span style=\"color:#a6e22e\">e<\/span> <span style=\"color:#f92672\">*<\/span><span style=\"color:#a6e22e\">Element<\/span>) {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">if<\/span> <span style=\"color:#a6e22e\">e<\/span>.<span style=\"color:#a6e22e\">list<\/span> <span style=\"color:#f92672\">!=<\/span> <span style=\"color:#a6e22e\">l<\/span> <span style=\"color:#f92672\">||<\/span> <span style=\"color:#a6e22e\">l<\/span>.<span style=\"color:#a6e22e\">root<\/span>.<span style=\"color:#a6e22e\">prev<\/span> <span style=\"color:#f92672\">==<\/span> <span style=\"color:#a6e22e\">e<\/span> {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">return<\/span><\/span><\/span><span style=\"display:flex;\"><span> }<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#75715e\">\/\/ see comment in List.Remove about initialization of l<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span> <span style=\"color:#a6e22e\">l<\/span>.<span style=\"color:#a6e22e\">move<\/span>(<span style=\"color:#a6e22e\">e<\/span>, <span style=\"color:#a6e22e\">l<\/span>.<span style=\"color:#a6e22e\">root<\/span>.<span style=\"color:#a6e22e\">prev<\/span>)<\/span><\/span><span style=\"display:flex;\"><span>}<\/span><\/span><span style=\"display:flex;\"><span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\">\/\/ MoveBefore moves element e to its new position before mark.<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\">\/\/ If e or mark is not an element of l, or e == mark, the list is not modified.<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\">\/\/ The element and mark must not be nil.<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span><span style=\"color:#66d9ef\">func<\/span> (<span style=\"color:#a6e22e\">l<\/span> <span style=\"color:#f92672\">*<\/span><span style=\"color:#a6e22e\">List<\/span>) <span style=\"color:#a6e22e\">MoveBefore<\/span>(<span style=\"color:#a6e22e\">e<\/span>, <span style=\"color:#a6e22e\">mark<\/span> <span style=\"color:#f92672\">*<\/span><span style=\"color:#a6e22e\">Element<\/span>) {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">if<\/span> <span style=\"color:#a6e22e\">e<\/span>.<span style=\"color:#a6e22e\">list<\/span> <span style=\"color:#f92672\">!=<\/span> <span style=\"color:#a6e22e\">l<\/span> <span style=\"color:#f92672\">||<\/span> <span style=\"color:#a6e22e\">e<\/span> <span style=\"color:#f92672\">==<\/span> <span style=\"color:#a6e22e\">mark<\/span> <span style=\"color:#f92672\">||<\/span> <span style=\"color:#a6e22e\">mark<\/span>.<span style=\"color:#a6e22e\">list<\/span> <span style=\"color:#f92672\">!=<\/span> <span style=\"color:#a6e22e\">l<\/span> {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">return<\/span><\/span><\/span><span style=\"display:flex;\"><span> }<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">l<\/span>.<span style=\"color:#a6e22e\">move<\/span>(<span style=\"color:#a6e22e\">e<\/span>, <span style=\"color:#a6e22e\">mark<\/span>.<span style=\"color:#a6e22e\">prev<\/span>)<\/span><\/span><span style=\"display:flex;\"><span>}<\/span><\/span><span style=\"display:flex;\"><span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\">\/\/ MoveAfter moves element e to its new position after mark.<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\">\/\/ If e or mark is not an element of l, or e == mark, the list is not modified.<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\">\/\/ The element and mark must not be nil.<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span><span style=\"color:#66d9ef\">func<\/span> (<span style=\"color:#a6e22e\">l<\/span> <span style=\"color:#f92672\">*<\/span><span style=\"color:#a6e22e\">List<\/span>) <span style=\"color:#a6e22e\">MoveAfter<\/span>(<span style=\"color:#a6e22e\">e<\/span>, <span style=\"color:#a6e22e\">mark<\/span> <span style=\"color:#f92672\">*<\/span><span style=\"color:#a6e22e\">Element<\/span>) {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">if<\/span> <span style=\"color:#a6e22e\">e<\/span>.<span style=\"color:#a6e22e\">list<\/span> <span style=\"color:#f92672\">!=<\/span> <span style=\"color:#a6e22e\">l<\/span> <span style=\"color:#f92672\">||<\/span> <span style=\"color:#a6e22e\">e<\/span> <span style=\"color:#f92672\">==<\/span> <span style=\"color:#a6e22e\">mark<\/span> <span style=\"color:#f92672\">||<\/span> <span style=\"color:#a6e22e\">mark<\/span>.<span style=\"color:#a6e22e\">list<\/span> <span style=\"color:#f92672\">!=<\/span> <span style=\"color:#a6e22e\">l<\/span> {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">return<\/span><\/span><\/span><span style=\"display:flex;\"><span> }<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">l<\/span>.<span style=\"color:#a6e22e\">move<\/span>(<span style=\"color:#a6e22e\">e<\/span>, <span style=\"color:#a6e22e\">mark<\/span>)<\/span><\/span><span style=\"display:flex;\"><span>}<\/span><\/span><span style=\"display:flex;\"><span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\">\/\/ PushBackList inserts a copy of an other list at the back of list l.<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\">\/\/ The lists l and other may be the same. They must not be nil.<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span><span style=\"color:#66d9ef\">func<\/span> (<span style=\"color:#a6e22e\">l<\/span> <span style=\"color:#f92672\">*<\/span><span style=\"color:#a6e22e\">List<\/span>) <span style=\"color:#a6e22e\">PushBackList<\/span>(<span style=\"color:#a6e22e\">other<\/span> <span style=\"color:#f92672\">*<\/span><span style=\"color:#a6e22e\">List<\/span>) {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">l<\/span>.<span style=\"color:#a6e22e\">lazyInit<\/span>()<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">for<\/span> <span style=\"color:#a6e22e\">i<\/span>, <span style=\"color:#a6e22e\">e<\/span> <span style=\"color:#f92672\">:=<\/span> <span style=\"color:#a6e22e\">other<\/span>.<span style=\"color:#a6e22e\">Len<\/span>(), <span style=\"color:#a6e22e\">other<\/span>.<span style=\"color:#a6e22e\">Front<\/span>(); <span style=\"color:#a6e22e\">i<\/span> &gt; <span style=\"color:#ae81ff\">0<\/span>; <span style=\"color:#a6e22e\">i<\/span>, <span style=\"color:#a6e22e\">e<\/span> = <span style=\"color:#a6e22e\">i<\/span><span style=\"color:#f92672\">-<\/span><span style=\"color:#ae81ff\">1<\/span>, <span style=\"color:#a6e22e\">e<\/span>.<span style=\"color:#a6e22e\">Next<\/span>() {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">l<\/span>.<span style=\"color:#a6e22e\">insertValue<\/span>(<span style=\"color:#a6e22e\">e<\/span>.<span style=\"color:#a6e22e\">Value<\/span>, <span style=\"color:#a6e22e\">l<\/span>.<span style=\"color:#a6e22e\">root<\/span>.<span style=\"color:#a6e22e\">prev<\/span>)<\/span><\/span><span style=\"display:flex;\"><span> }<\/span><\/span><span style=\"display:flex;\"><span>}<\/span><\/span><span style=\"display:flex;\"><span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\">\/\/ PushFrontList inserts a copy of an other list at the front of list l.<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\">\/\/ The lists l and other may be the same. They must not be nil.<\/span><\/span><\/span><span style=\"display:flex;\"><span><span style=\"color:#75715e\"><\/span><span style=\"color:#66d9ef\">func<\/span> (<span style=\"color:#a6e22e\">l<\/span> <span style=\"color:#f92672\">*<\/span><span style=\"color:#a6e22e\">List<\/span>) <span style=\"color:#a6e22e\">PushFrontList<\/span>(<span style=\"color:#a6e22e\">other<\/span> <span style=\"color:#f92672\">*<\/span><span style=\"color:#a6e22e\">List<\/span>) {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">l<\/span>.<span style=\"color:#a6e22e\">lazyInit<\/span>()<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#66d9ef\">for<\/span> <span style=\"color:#a6e22e\">i<\/span>, <span style=\"color:#a6e22e\">e<\/span> <span style=\"color:#f92672\">:=<\/span> <span style=\"color:#a6e22e\">other<\/span>.<span style=\"color:#a6e22e\">Len<\/span>(), <span style=\"color:#a6e22e\">other<\/span>.<span style=\"color:#a6e22e\">Back<\/span>(); <span style=\"color:#a6e22e\">i<\/span> &gt; <span style=\"color:#ae81ff\">0<\/span>; <span style=\"color:#a6e22e\">i<\/span>, <span style=\"color:#a6e22e\">e<\/span> = <span style=\"color:#a6e22e\">i<\/span><span style=\"color:#f92672\">-<\/span><span style=\"color:#ae81ff\">1<\/span>, <span style=\"color:#a6e22e\">e<\/span>.<span style=\"color:#a6e22e\">Prev<\/span>() {<\/span><\/span><span style=\"display:flex;\"><span> <span style=\"color:#a6e22e\">l<\/span>.<span style=\"color:#a6e22e\">insertValue<\/span>(<span style=\"color:#a6e22e\">e<\/span>.<span style=\"color:#a6e22e\">Value<\/span>, <span style=\"color:#f92672\">&amp;<\/span><span style=\"color:#a6e22e\">l<\/span>.<span style=\"color:#a6e22e\">root<\/span>)<\/span><\/span><span style=\"display:flex;\"><span> }<\/span><\/span><span style=\"display:flex;\"><span>}<\/span><\/span><\/code><\/pre><\/div><h2 id=\"\u53c2\u8003\u8d44\u6599\">\u53c2\u8003\u8d44\u6599<\/h2><ol><li>\u6570\u636e\u7ed3\u6784\u4e0e\u7b97\u6cd5\u5206\u6790<\/li><\/ol>"},{"title":"\u4f7f\u7528 Jekyll \u548c Git Page \u642d\u5efa\u4e2a\u4eba\u535a\u5ba2","link":"https:\/\/sunpe.github.io\/posts\/2020-02-29-build-blog-with-jekyll\/","pubDate":"Sat, 29 Feb 2020 22:00:00 +0800","guid":"https:\/\/sunpe.github.io\/posts\/2020-02-29-build-blog-with-jekyll\/","description":"<p>jekyll \u662f\u4e00\u4e2a\u7b80\u5355\u7684\u9759\u6001\u7f51\u7ad9\u751f\u6210\u5668\uff0c\u53ef\u4ee5\u5c06 markdown \u6587\u6863\u6216 html \u6587\u6863\u8f6c\u6362\u6210\u4e00\u4e2a\u5b8c\u6574\u7684\u53ef\u53d1\u5e03\u7684\u9759\u6001\u7f51\u7ad9\u3002\u5e76\u4e14\u5185\u7f6e GitHub Pages \u652f\u6301\u3002<\/p><p>GitHub Pages \u662f\u4e00\u9879\u9759\u6001\u7ad9\u70b9\u6258\u7ba1\u670d\u52a1\uff0c\u76f4\u63a5\u4ece GitHub \u4e0a\u7684\u4ed3\u5e93\u83b7\u53d6 HTML\u3001CSS \u548c JavaScript \u6587\u4ef6\uff0c\u53ef\u4ee5\u901a\u8fc7\u6784\u5efa\u8fc7\u7a0b\u8fd0\u884c\u6587\u4ef6\uff0c\u53d1\u5e03\u7f51\u7ad9\u3002\u76ee\u524d github \u652f\u6301 3 \u79cd\u7c7b\u578b\u7684 GitHub Pages \u7ad9\u70b9\uff1aproject\uff0cuser \u548c organization\uff0c\u5177\u4f53\u53ef\u4ee5\u53c2\u8003<a href=\"https:\/\/help.github.com\/en\/github\/working-with-github-pages\/about-github-pages\">github\u7684\u5e2e\u52a9\u6587\u6863<\/a>\u3002<\/p><h2 id=\"\u521b\u5efagit\u4ed3\u5e93\">\u521b\u5efagit\u4ed3\u5e93<\/h2><p>\u521b\u5efa\u4e2a\u4eba\u535a\u5ba2\u662f user \u7c7b\u578b\u7684 GitHub Pages \u7ad9\u70b9\u3002\u9996\u5148\u9700\u8981\u5728 github \u4e0a\u521b\u5efa repository\u3002<\/p><ol><li>\u70b9\u51fb github \u9875\u9762\u53f3\u4e0a\u89d2\u7684\u300cNew repository\u300d\u9009\u9879\u3002<\/li><\/ol><p><img src=\"https:\/\/sunpe.github.io\/images\/build_blog_with_jekyll\/1.png\" alt=\"\">\u56fe 1<\/p><ol start=\"2\"><li>\u8f93\u5165\u4ed3\u5e93\u540d\u79f0\u548c\u8bf4\u660e\uff0c\u4e2a\u4eba\u535a\u5ba2\u7684\u4ed3\u5e93\u540d\u79f0\u5fc5\u987b\u4e3a <code>&lt;user&gt;.github.io<\/code>\u3002<\/li><\/ol><p><img src=\"https:\/\/sunpe.github.io\/images\/build_blog_with_jekyll\/2.png\" alt=\"\">\u56fe 2<\/p><ol start=\"3\"><li>\u9009\u62e9\u4ed3\u5e93\u7684\u53ef\u89c1\u6027\uff0c\u4e00\u822c\u662f\u300cpublic\u300d\u3002<\/li><\/ol><p><img src=\"https:\/\/sunpe.github.io\/images\/build_blog_with_jekyll\/3.png\" alt=\"\">\u56fe 3<\/p><ol start=\"4\"><li>\u521b\u5efaReadMe\u6587\u4ef6\u3002<\/li><\/ol><p><img src=\"https:\/\/sunpe.github.io\/images\/build_blog_with_jekyll\/4.png\" alt=\"\">\u56fe 4<\/p><ol start=\"5\"><li>\u70b9\u51fb\u300cCreate repository\u300d\u6309\u94ae\uff0c\u4ed3\u5e93\u5c31\u521b\u5efa\u5b8c\u6210\u3002<\/li><\/ol><h2 id=\"\u901a\u8fc7jeykll\u521b\u5efagithub-page\">\u901a\u8fc7jeykll\u521b\u5efagithub page<\/h2><p>\u5efa\u8bae\u4f7f\u7528 Bundler \u5b89\u88c5\u548c\u8fd0\u884c Jekyll\u3002Bundler \u53ef\u7ba1\u7406 <code>Ruby gem<\/code> \u4f9d\u8d56\u9879\uff0c\u51cf\u5c11 Jekyll \u6784\u5efa\u9519\u8bef\u548c\u963b\u6b62\u73af\u5883\u76f8\u5173\u7684bug\u3002<\/p><ul><li>\u5b89\u88c5 Ruby\uff0c\u53ef\u53c2\u8003<a href=\"https:\/\/www.ruby-lang.org\/en\/documentation\/installation\/\">\u6587\u6863<\/a><\/li><li>\u5b89\u88c5 Bundler\uff0c\u53ef\u53c2\u8003<a href=\"https:\/\/bundler.io\/\">\u6587\u6863<\/a><\/li><li>\u5b89\u88c5 jekyll <code>gem install bundler jekyll<\/code><\/li><li>\u4f7f\u7528jeykll\u521b\u5efa\u7ad9\u70b9<code>jekyll new my-awesome-site<\/code>\u3002\u6267\u884c\u5b8c\u4e4b\u540e\u5728\u76ee\u5f55\u4e0b\u4f1a\u53c8\u4e00\u4e2a <code>my-awesome-site<\/code> \u76ee\u5f55\uff0c\u5305\u542b\u4e86\u6700\u57fa\u672c\u7684\u7ad9\u70b9\u6587\u4ef6\u3002\u5176\u4e2d <code>_config.yml<\/code> \u662f\u7ad9\u70b9\u914d\u7f6e\u6587\u4ef6\uff0c<code>_posts<\/code>\u662f\u6587\u7ae0\u76ee\u5f55\u3002<\/li><\/ul><pre tabindex=\"0\"><code>-----||- 404.html|- Gemfile|- _config.yml|- _posts| |-YYYY-mm-DD-welcome-to-jekyll.markdown|- about.markdown|- index.markdown<\/code><\/pre><ul><li>\u5728 <code>my-awesome-site<\/code> \u76ee\u5f55\u4f7f\u7528 <code>jekyll serve<\/code> \u547d\u4ee4\u5c31\u53ef\u4ee5\u7f16\u8bd1\u5e76\u542f\u52a8\u4e00\u4e2a\u5185\u7f6e\u7684 server\uff0c\u672c\u5730\u4f1a\u591a\u4e00\u4e2a <code>_site<\/code> \u76ee\u5f55\uff0c\u5b58\u653e\u7684\u662f\u7f16\u8bd1\u540e\u7684\u7ad9\u70b9\u6587\u4ef6\u3002\u53ef\u4ee5\u5728\u6d4f\u89c8\u5668\u8f93\u5165 <code>localhost:4000<\/code> \u9884\u89c8\u7ad9\u70b9\u4e86\u3002<\/li><li>\u5c06 <code>my-awesome-site<\/code> \u76ee\u5f55\u63d0\u4ea4\u5230 github \u4ed3\u5e93\uff08<code>_site<\/code>\u76ee\u5f55\u548c<code>Gemfile.lock<\/code>\u6587\u4ef6\u53ef\u4ee5\u4e0d\u7528\u63d0\u4ea4\uff09\uff0c\u5c31\u53ef\u4ee5\u901a\u8fc7<code>&lt;user&gt;.github.io<\/code> \u8bbf\u95ee\u9875\u9762\u4e86\u3002<\/li><\/ul><h2 id=\"\u53d1\u5e03\u6587\u7ae0\">\u53d1\u5e03\u6587\u7ae0<\/h2><p>jekyll \u521b\u5efa\u7684\u7ad9\u70b9 post \u6587\u4ef6\u540d\u683c\u5f0f\u4e3a <code>YEAR-MONTH-DAY-title.md<\/code>\uff0cpost \u6587\u4ef6\u9700\u8981\u6dfb\u52a0 matter \u5934\uff0c\u6307\u5b9a layout \u548c\u5176\u4ed6 meta \u6570\u636e\u3002\u5c06\u7f16\u5199\u597d\u7684 post \u653e\u5230 <code>_post<\/code> \u6587\u4ef6\uff0c\u91cd\u65b0\u53d1\u5e03\u7ad9\u70b9\uff0c\u5c31\u53ef\u4ee5\u770b\u5230\u65b0\u53d1\u5e03\u7684 post \u4e86\u3002<\/p><pre tabindex=\"0\"><code>---layout: posttitle: &#34;Welcome to Jekyll!&#34;---# Welcome**Hello world**, this is my first Jekyll blog post.I hope you like it!<\/code><\/pre><h2 id=\"drafts\u76ee\u5f55\">Drafts\u76ee\u5f55<\/h2><p>\u5982\u679c post \u6ca1\u5199\u5b8c\uff0c\u53ea\u60f3\u4fdd\u5b58\u8349\u7a3f\uff0c\u53ef\u4ee5\u5c06 post \u6587\u4ef6\u653e\u5728 <code>_drafts<\/code> \u76ee\u5f55\uff08\u9700\u8981\u65b0\u5efa\uff09\uff0c\u800c\u4e14\u6587\u4ef6 title \u53ef\u4ee5\u4e0d\u5e26\u65e5\u671f\u3002\u53ef\u4ee5\u5728 <code>jekyll serve<\/code> \u6216 <code>jekyll build<\/code> \u547d\u4ee4\u540e\u6dfb\u52a0 <code>--drafts<\/code> \u53c2\u6570\uff0c\u6765\u9884\u89c8\u8349\u7a3f\u3002<\/p><h2 id=\"\u66f4\u6362\u4e3b\u9898\">\u66f4\u6362\u4e3b\u9898<\/h2><p>\u901a\u8fc7 <code>jekyll new<\/code> \u521b\u5efa\u7684\u9875\u9762\u9ed8\u8ba4\u7684\u4e3b\u9898\u662f <a href=\"https:\/\/github.com\/jekyll\/minima\">Minima<\/a> \u3002\u53e6\u5916 jeykll \u6709\u5927\u91cf\u4f18\u8d28\u7684\u4e3b\u9898\uff0c\u53ef\u4ee5\u4ece\u4ee5\u4e0b\u7f51\u7ad9\u83b7\u53d6 jekyll \u4e3b\u9898\uff1a<\/p><ul><li><a href=\"https:\/\/jamstackthemes.dev\/ssg\/jekyll\/\">jamstackthemes.dev<\/a><\/li><li><a href=\"http:\/\/jekyllthemes.org\/\">jekyllthemes.org<\/a><\/li><li><a href=\"https:\/\/jekyllthemes.io\/\">jekyllthemes.io<\/a><\/li><li><a href=\"https:\/\/jekyll-themes.com\/\">jekyll-themes.com<\/a><\/li><\/ul><p>\u8be6\u7ec6\u53ef\u4ee5\u53c2\u8003<a href=\"https:\/\/jekyllrb.com\/docs\/themes\/g\">jekyll theme\u6587\u6863<\/a>\u3002<\/p><h2 id=\"\u81ea\u5b9a\u4e49\u57df\u540d\">\u81ea\u5b9a\u4e49\u57df\u540d<\/h2><p>github page \u652f\u6301\u81ea\u5b9a\u4e49\u57df\u540d\u6216\u5b50\u57df\u540d\u3002\u53ef\u4ee5\u518d\u963f\u91cc\u4e91\u6216\u817e\u8baf\u4e91\u8d2d\u4e70\u4e00\u4e2a\u81ea\u5df1\u7684\u57df\u540d\u3002\u53ef\u4ee5\u53c2\u8003<a href=\"https:\/\/help.github.com\/en\/github\/working-with-github-pages\/managing-a-custom-domain-for-your-github-pages-site\">git page\u6587\u6863<\/a>\u3002<\/p><h2 id=\"\u53c2\u8003\u8d44\u6599\">\u53c2\u8003\u8d44\u6599<\/h2><ol><li><a href=\"https:\/\/jekyllrb.com\/docs\/\">https:\/\/jekyllrb.com\/docs\/<\/a><\/li><li><a href=\"https:\/\/help.github.com\/cn\/github\/working-with-github-pages\/setting-up-a-github-pages-site-with-jekyll\">https:\/\/help.github.com\/cn\/github\/working-with-github-pages\/setting-up-a-github-pages-site-with-jekyll<\/a><\/li><\/ol>"}]}}